C.4 J2SE™ Specific Conventions

29.198-013GPPOpen Service Access (OSA) Application Programming Interface (API)Part 1: OverviewRelease 9TS

The UML interfaces are represented by Java™ public interfaces; those interfaces that inherit from other interfaces are represented in Java™ as extending that interface. The Java™ realisations of OSA/Parlay SCFs use an Event Listener design pattern while the Framework uses the Callback pattern.

This annex provides the information on realisation of the Java™ developer API including:

  • How Java™ APIs are realised from Parlay UML
  • Where the listener pattern is used, new classes to be generated from the UML
  • Changes required to data types and methods to support correlation using object references
  • Use of hierarchical exceptions

C.4.1 Removal of "Tp" Prefix

The UML data types labelled with the prefix “Tp” are represented in Java™ without this prefix.

Example 18:

UML

Java™ Realisation

TpCallAppInfo

CallAppInfo

In the case of name collisions between data types and interfaces as with IpTerminalCapabilities and IpService the UML data types labelled with the prefix “Tp” are represented in Java™ with an alternative prefix “Type”.

Example 19:

UML

Java™ Realisation

IpTerminalCapabilities

TerminalCapabilities

TpTerminalCapabilities

TypeTerminalCapabilities

The above example is based in conjunction with C.4.3 Removal of "Ip" Prefix.

C.4.2 Constants

The UML constants labelled with the prefix “P_” are represented in Java™ without this prefix.

Example 20:

UML Constant

Java™ Constant

P_NO_CALLBACK_ADDRESS_SET

NO_CALLBACK_ADDRESS_SET

C.4.3 Removal of "Ip" prefix

The "Ip" prefix is removed in the Java™ realisation of UML interfaces.

Example 21:

UML

Java™

IpCallControlManager

CallControlManager

C.4.4 Mapping of IpInterface

IpInterface interface is represented by the CsapiInterface interface. This is a ‘marker’ interface, in that it contains no methods, but provides a common interface for related interfaces to inherit from. All interfaces to be serializable; this can be done by CsapiInterface extending Serializable.

Example 22:

package org.csapi.jr.se;

public interface CsapiInterface extends Serializable{

}

C.4.5 Mapping of IpService

IpService interface is represented by the Java™ Service interface. This provides a common interface for related interfaces to inherit from.

Example 23:

Service Interface:

package org.csapi.jr.se;

public interface Service extends CsapiInterface {

public final static int IN_SERVICE_STATE=0 ;

public final static int OUT_OF_SERVICE_STATE=1;

void addServiceStateChangeListener(ServiceStateChangeListener listener)

int getServiceState();

void removeServiceStateChangeListener( ServiceStateChangeListener listener) ;

}

Listener interface:

package org.csapi.jr.se;

public interface ServiceStateChangeListener extends java.util.EventListener {

void onOutOfService(OutOfServiceEvent event);

}

Event class:

package org.csapi.jr.se;

public class OutOfServiceEvent extends jav.util.EventObject {

public OutOfServiceEvent(java.lang.Object source){

super(source)

}

}

C.4.6 Mapping of UML Operations

The UML operations are represented in Java™ as methods.

Exceptions that can be raised by UML operations are represented in Java™ with the throws clause and the Java™ Realisation of the UML Exceptions.

UML “in” parameters, represented by “in ” preceding the parameter type are represented in Java™ without this clause.

Example 24:

public void managerResumed ();

public CsapiInterface obtainInterface (InterfaceName interfaceName) throws InvalidInterfaceNameException;

public Service createServiceManager (ClientAppID application, ServicePropertyList serviceProperties, ServiceInstanceID serviceInstanceID);

The above example method signatures are based on generic mapping of interfaces, exceptions and data types.

C.4.7 Mapping of TpSessionID

The UML TpSessionID data types will be hidden in the J2SE™ APIs (and optionally supported by the underlying Java™ implementation). Consequently, the TpSessionIDSet data type and IpService.setCallbackWithSessionID() method are superfluous. Also, structures with only TpSessionID and interface references (e.g. TpCallIdentifier) are no longer necessary and references to these structures should be replaced by just the reference to the interface. For data types that contain TpSessionID the Java™ API Realisation object replaces theTpSessionID.

The following figure shows how Java™ API Realisation objects relate to Parlay UML objects and sessions. How this is realised in the adaptors is implementation dependent.

C.4.8 Mapping of TpAssignmentID to the creation of an Activity object

The UML TpAssignmentID data types, which differentiate between multiple parallel asynchronous method invocations (activities) on the same (“parent”) interface, are deleted and replaced with createXxx methods (one for each parallel asynchronous activity) that create (“child”) activity interfaces. Where this would result in method names of the pattern createCreateXxx, this should be changed to method names with the pattern createXxx. Associated listeners would then remove the Create prefix from their name. These activity interfaces, in addition to possibly supporting other methods, will support one of the previously mentioned multiple parallel asynchronous method invocations. Hence, the Java™ API realisation creates multiple (activity) objects and invokes a single request per object rather than creating a single object and invoking multiple requests on that object, each request being differentiated using the TpAssignmentID value. The results of the asynchronous method invocation will be handled by the activity interface’s listener interface. To create the activity interface, the original IpXxx interface (to be named Xxx) will replace its parallel supporting asynchronous method invocations, yyyYyyReq, with createYyyYyy methods that take no parameters but returns the activity interface, YyyYyy. Where this would result in method names of the pattern createCreateXxx, this should be changed to method names with the pattern createXxx. Associated listeners would then remove the Create prefix from their name. The activity interface will extend Activity interface (see next rule), have a simple FSM, the addYyyYyyListener, removeYyyYyyListener and the asynchronous method that previously supported a parallel capability (typically named yyyYyyReq, but also yyyYyyStop).

An Activity interface, packaged in org.csapi.jr.se, is added as a parent to all activity interfaces. An application may add listeners of type ActivityStateChangeListener to an Activity if it wishes be explicitly informed when the activity becomes invalid.

The YyyYyyListener activity listener interfaces will extend java.util.EventListener. The asynchronous methods of previously named IpAppXxx, typically labelled yyyYyyRes and yyyYyyErr but also yyyYyy, will be renamed onYyyYyyRes and onYyyYyyErr but also onYyyYyy. Each method will have an event parameter, typically labelled YyyYyyResEvent and YyyYyyErrEvent, but also YyyYyyEvent. Events will be classes that extend java.util.EventObject and contain a public constructor (with multiple parameters – one per class carried by the event) and a number of public getter methods (one per “gettable” class carried by the event). As a result of adding activity listener interfaces, this may cause the requirement for the original IpAppXxx to disappear, since the yyyYyyRes and yyyYyyErr methods will effectively be ported to the activity listener interfaces.

For data types that contain TpAssignmentID the activity object replaces the TpAssignmentID.

Example 25:

Activity Interface:

package org.csapi.jr.se;

public interface Activity extends CsapiInterface {

public final static int IDLE_STATE = 0;

public final static int ACTIVE_STATE = 1;

public final static int INVALID_STATE = 2;

public int getState();

public void addActivityStateChangeListener(ActivityStateChangeListener listener);

public void removeActivityStateChageListener(ActivityStateChangeListener listener);

}

Activity Listener Interface and Event class:

package org.csapi.jr.se;

public interface ActivityStateChangeListener {

onInvalidStateEvent (InvalidActivityEvent event)

}

public class InvalidActivityEvent extends java.util.EventObject {

public InvalidActivityEvent(java.lang.Object source){

super(source)

}

}

Parent interface:

package org.csapi.jr.se.mmm.ul;

public interface UserLocation extends org.csapi.jr.se.Service {

public LocationReport createLocationReport();

public ExtendedLocationReport createExtendedLocationReport();

public PeriodicLocationReporting createPeriodicLocationReporting();

}

Child Interface:

package org.csapi.jr.se.mm.ul;

public interface LocationReport extends org.csapi.jr.se.Activity {

public void addLocationReportListener(LocationReportListener listener)

public void removeLocationReportListener(LocationReportListener listener)

public void locationReportReq(Address[] users) throws …

}

Listener Interface:

package org.csapi.jr.se.mm.ul;

public interface LocationReportListener extends java.util.EventListener {

public void onLocationReportResEvent(LocationReportResEvent event);

public void onLocationReportErrEvent(LocationReportErrEvent event);

}

Event classes:

package org.csapi.jr.se.mmm.ul;

public class LocationReportResEvent extends java.util.EventObject{

// with a public UserLocation[] constructor and a public getter

// method for the parameter of the event

}

public classLocationReportErrEvent extends java.util.EventObject {

// with a public MobilityError and MobilityDiagnostic constructor

// and two public getter methods, one for each of the parameters

// of the event

}

The Finite State Model for the Activity interface is given below:

This interface specifies an activity, which might be provided by a service. An activity has three states: "idle", "active" and "invalid". The initial state is "idle" and here the listeners should be registered. It performs in the "active" state. It enters the "invalid" state when it has fulfilled its task or a fatal error occurred. In special cases state transition from "idle" to "invalid" is possible.

An example activity interface FSM is given below for a single activity request with a single response:

An example activity interface FSM is given below for a single activity request with repeating responses:

C.4.9 Callback Rule

The UML callback design pattern for all callbacks that return a type is represented in Java™ with the callback design pattern. The UML callback design pattern for all callbacks that return void is represented in Java™ with the event listener design pattern.

The UML client-to-service interfaces with the IpAppXxxx naming convention are represented in Java™ with the XxxxListener naming convention.

The IpService.setCallback method can be deleted; the interfaces that inherited the setCallback method now have associated addXxxxListener and removeXxxxListener methods. According to the TpSessionID mapping, IpService.setCallbackWithSessionID() method is deleted.

The XxxxListener listener interfaces will extend java.util.EventListener. The asynchronous methods of previously named IpAppXxxx, typically labelled yyyyYyyyRes and yyyyYyyyyErr but also yyyyYyyy, will be renamed onYyyyYyyyRes and onYyyyYyyyErr but also onYyyyYyyy. Each method will have an event parameter, typically labelled YyyyYyyyResEvent and YyyyYyyyErrEvent, but also YyyyYyyyEvent. Events will be classes that extend java.util.EventObject and contain a private constructor (with multiple parameters – one per class carried by the event) and a number of public getter methods (one per “gettable” class carried by the event). Events are read-only and serializable.

Example 26:

Listener Interface:

package org.csapi.jr.se.cc.mpccs;

MultiPartyCallListener extends java.util.EventListener{

public void onGetInfoResEvent(GetInfoResEvent event)

public void onGetInfoErrEvent(GetInfoErrEvent event)

public void onSuperviseResEvent(SuperviseResEvent event)

public void onSuperviseErrEvent(SuperviseErrEvent event)

public void onCallEndedEvent(CallEndedEvent event)

public void onCreateAndRouteCallLegErrEvent(CreateAndRouteCallLegErrEvent event)

}

MultiPartyCall Interface additional methods:

public void addMultiPartyCallListener(MultiPartyCallListener multiPartyCallListener);

public void removeMultiPartyCallListener(MultiPartyCallListener multiPartyCallListener);

C.4.10 Factory Rule

The following Factory class allows applications to obtain proprietary peer API objects. The term "peer" is Java™ nomenclature for a particular platform-specific implementation of a Java™ interface.

Example 27:

package org.csapi.jr.se.fw;

import org.csapi.jr.se.PeerUnavailableException;

import org.csapi.jr.se.InvalidArgumentException;

import org.csapi.jr.se.ResourcesUnavailableException;

import org.csapi.jr.se.fw.access.tsm.Initial;

import java.util.*;

public class InitialFactory {

private static InitialFactory myFactory;

private static String className = null;

private static String lang = "en";

private static String cntry = "US";

private InitialFactory() {

}

public synchronized Initial createInitial(String initialPeerReference) throws PeerUnavailableException, ResourcesUnavailableException, InvalidArgumentException {

Locale currentLocale;

ResourceBundle messages;

String tryMessage;

try {

currentLocale = new Locale(lang, cntry);

messages = ResourceBundle.getBundle("InitialFactoryBundle", currentLocale);

// Validate all used values before using them later

// avoiding error text exception to hide the real exception

tryMessage = messages.getString("InitialPeerReferenceNull");

tryMessage = messages.getString("InitialInstFailure");

tryMessage = message.getString("DestroyInitialFailure");

}

catch (Exception e) {

throw new ResourcesUnavailableException ("Localisation failed to be initialized");

}

if (initialPeerReference == null) {

String errmsg = messages.getString("InitialPeerReferenceNull");

throw new InvalidArgumentException (errmsg);

}

try {

Class c = Class.forName (getImplementationClassName ());

if(initialPeerReference.equals(“”)){

// Creates a new instance of the Object class

// using default constructor

return (Initial)c.newInstance ();

}

Class[] paramTypes = {initialPeerReference.getClass()};

java.lang.reflect.Constructor ctor =

c.getConstructor(paramTypes);

Object[] params = {initialPeerReference};

return (Initial) ctor.newInstance(params);

} catch (Exception e) {

String errmsg = messages.getString("InitialInstFailure");

throw new PeerUnavailableException (errmsg);

}

}

public synchronized static InitialFactory getInstance() {

if (myFactory == null) {

myFactory = new InitialFactory ();

}

return myFactory;

}

public String getImplementationClassName () {

return className;

}

public static void setImplementationClassName (String className) {

this.className = className;

}

public synchronized static void setLocale(String language, String country) {

if (language == null) {

lang = "en";

}

else {

lang = language;

}

if (country == null) {

cntry = "US";

}

else {

cntry = country;

}

}

public void destroyInitial(Initial initialInstance) {

if (initialInstance == null) {

return;

}

try {

delete initialInstance;

} catch (Exception e) {

String errmsg = messages.getString("DestroyInitialFailure");

throw new RuntimeException(errmsg);

}

}

}

C.4.11 J2SE™ Specific Exceptions

Exceptions in this section are only applicable within a J2SE™ environment.

C.4.11.1 PeerUnavailableException

PeerUnavailableException indicates failure to access an implementation of the Initial interface.

Example 28:

public class PeerUnavailableException extends java.lang.Exception {

private Throwable _cause = null;

public PeerUnavailableException () {

super();

}

public PeerUnavailableException (String message) {

super(message);

}

public PeerUnavailableException (String message, Throwable cause) {

super(message);

_cause = cause;

}

public PeerUnavailableException (Throwable cause) {

_cause = cause;

}

public Throwable getCause() {

return _cause;

}

}

C.4.11.2 IllegalStateException

IllegalStateException exception signals that a method has been invoked at an illegal or inappropriate time.

Example 29:

package org.csapi.jr.se;

public class IllegalStateException extends java.lang.Exception {

private int _state;

private java.lang.Object _object;

public IllegalStateException(Object object, int state) {

super();

_object = object;

_state = state;

}

public Illegal StateException(Object object, int state, String s) {

super(s);

_object = object;

_state = state;

}

public Object getObject() {

return _object;

}

public int getState() {

return _state;

}

}

C.4.12 User Interaction Specific Rules

C.4.12.1 Interfaces representing UML IpUI and IpUICall Rule

The following mappings take account of the fact that when the TpAssignmentID rule is applied the Java™ interfaces representing UML IpUICall does not extend the Java™ interfaces representing UML IpUI.

Java™ UIGeneric replaces the UML IpUI. Methods common to both the Java™ UIGeneric and Java™ UICall are pulled up into a super-interface called UI. UML IpAppUI and IpAppUiCall interfaces are replaced by a UIListener interface.

C.4.12.2 Naming Collisions of IpUI and IpUICall Rule

Naming collisions that arise through IpUI and IpUICall methods e.g. XXX, having the same name will be dealt with by prefixing the Call Related UI activities by “CallRelated”. Methods to create the activity will become createCallRelatedXXX() and events will become CallRelatedXXXEvent.

C.4.12.3 Naming Collisions of IpUICall and IpUIAdminManager Rule

Naming collisions that arise through IpUICall and IpUIAdminManager methods, e.g. XXX, having the same name will be dealt with by prefixing the UI Admin activities by “AdminRelated”. Methods to create the activity will become createAdminRelatedXXX() and events will become AdminRelatedXXXEvent.