Developer's-Panther WebSphere |
This chapter describes how client screens in your Panther application can access Enterprise JavaBeans. A series of C functions, also callable in JPL and through Panther's Java interface, are available for interacting with all Panther service components.
Creating Client Screens |
Client screens are the part of the application accessed by users. They can include fields for data, push buttons for performing actions, selection groups for assembling options, option menus for listing choices. These and other user interface options are described in Using the Editors.
Refer to "Creating a New Screen" in Using the Editors for steps on creating a new screen.
Specifying the WebSphere Server |
You need to specify the machine running WebSphere. At runtime, the value is derived from the provider_url
application property. If the SMPROVIDERURL environment variable is set, this property is initialized with this value. However, you can also set this property programmatically. List the server machine's host name and port number (iiop
://hostName
:portNumber
).
If you specify the value in JPL, remember to use double colons. For example, the following JPL command would set the property back to its default value:
@app()->provider_url="iiop:://localhost::900"
Specifying the Component System |
Before instantiating a component, you must first specify which type of service components are currently in use with the current_component_system
property: PV_SERVER_EJB
for EJBs or PV_SERVER_COM
for COM components.
Instantiating an EJB |
After the component system is specified, you instantiate a component by calling sm_obj_create. It takes a string parameter, the name of the component.
This function returns an object ID for the specified component or PR_E_OBJECT
if it fails. Using this object ID, you can access the component's properties and methods.
In the horoscope sample, when a user submits the screen, the following JPL procedure specifies the component system and instantiates the EJB:
proc submit()
{
vars id,res
@app()->current_component_system = PV_SERVER_EJB
id = sm_obj_create("fortuneEJB")
if (id<=0)
{
msg emsg "Can't create EJB"
return
}
res = sm_obj_call \
(id,"newFortune",birthdayText,resultTextBox)
if (res<0)
msg emsg "Method failed"
call sm_obj_delete_id(id)
return
}
Destroying EJB Components |
After invoking and working with the methods or properties of a component, you should destroy the component by calling sm_obj_delete_id. This function takes one parameter: the object ID for the component you wish to destroy. Otherwise, the component will continue to exist until the application terminates (or goes from test to edit mode).
Accessing the Component's Methods |
To access EJB methods, you need to know the component's parameters and call the function sm_obj_call. The syntax in JPL is as follows:
ret = sm_obj_call (objid, methodName, parm1, parm2, ....)
The function's first parameter objid is the object ID of the component whose method you wish to use. The second parameter methodName
is the name of the method you are calling. The rest of the parameters (parm1, parm2, ....
) are a comma-separated list of the parameters to the method itself.
EJBs can take three kinds of parameters: in
parameters, out
parameters and in/out
parameters. Parameters can be passed as literal strings or using the property API syntax. For out
and in/out
parameters, Panther assigns the returning values to the variables, fields or properties originally specified.
For example, a component called Employee
supports a method called NewEmployee
, which takes three parameters in the following order:
out
parameter–EmpId
, which places its return value in a field on the client screen.
in/out
parameter–Emanate
, which derives its input value from a field on the client screen.
in
parameter–StartDate
, which derives its input value from a field on the client screen.
You can invoke In addition to the out NewEmployee
method with the following JPL:
vars id, ret
@app()->current_component_system=PV_SERVER_EJB
id = sm_obj_create ("Employee")
ret = sm_obj_call (id, "NewEmployee", \
EmpId, Emanate, StartDate)parameters
, this method call returns a value. ret
contains the return value for the method.
Accessing the Component's Properties |
Properties in EJBs can contain application state information. You can use the sm_obj_set_property and sm_obj_get_property functions to access properties. The following example sets a property on the component associated with the id
variable:
ret = sm_obj_set_property(id, "PropName", "PropSetting")
Designating an Error Handler |
You can define an error handler for method invocations, such as in the following example:
call sm_obj_onerror ("ErrorHandlerName")
The string passed to sm_obj_onerror is the name of a function that you want to designate as the error handler. If an operation (method call, property access, or object invocation) generates a negative exception code, the error handler function is called. The specified function is passed three parameters: the error number in decimal format, the error number in hexadecimal format, and a description of the error.
(On the server side, methods can also return exception codes using the JPL verb raise_exception or its C equivalent sm_raise_exception.)
Writing a Java Event Handler |
Instead of using JPL, you can use Java to implement the client processing. In the screen's Java Tag property, enter the name of the screen's Java event handler.
For more information about Java event handlers, refer to Chapter 21, "Java Event Handlers and Objects," in the Application Development Guide.
In the following sample which instantiates and destroys the component, the client screen calling this event handler has a Java Tag of ClientScreen
.
import com.prolifics.jni.*;
public class ClientScreen extends ScreenHandlerAdapter{
public void screenEntry(ScreenInterface s, int context){
FieldInterface id = s.getField("id");
FieldInterface id1=s.getField("id1");
CFunctionsInterface cFuncs = s.getCFunctions();
ApplicationInterface appface=s.getApplication();
ScreenInterface tscr=appface.getScreen();
int a=appface.set_int
(Constants.PR_CURRENT_COMPONENT_SYSTEM,
Constants.PV_SERVER_EJB);
id1.itofield(a);
id.itofield(cFuncs.sm_obj_create("cStrings"));
}
public void screenExit(ScreenInterface s, int context){
CFunctionsInterface cFuncs = s.getCFunctions();
FieldInterface id = s.getField("id");
cFuncs.sm_obj_delete_id(id.intval());
On this client screen, a button event handler for the Search push button calls the method and gets the number of returned rows. The push button calling this event handler has a Java Tag of SearchButtonHandler
.
import com.prolifics.jni.*;
public class SearchButtonHandler extends ButtonHandlerAdapter{
public int buttonValidate
(FieldInterface f, int item, int context){
ScreenInterface s = f.getScreen();
FieldInterface idField = s.getField("id");
FieldInterface rowField = s.getField("RowCount");
FieldInterface searchField = s.getField("search");
FieldInterface
companyNameField = s.getField("CompanyName");
CFunctionsInterface cFuncs = f.getCFunctions();
companyNameField.putfield(1,searchField.getfield());
int id = idField.intval();
String i = cFuncs.sm_obj_call("(" + id + ",
'GetCustomer',CompanyName,CustomerID,Phone)");
String st = cFuncs.sm_obj_get_property
( id, "RowCount");
rowField.putfield(st);
return id;
}
}
Saving Client Screens |
Client screens are stored in an application library available to the client executable. The default name of the application library is client.lib
.
Refer to "Saving an Application Component" in Using the Editors for information about saving screens to application libraries.
Sample Client Screen |
Although simple in appearance, this screen contains the fields and push buttons needed to operate the client part of an application and illustrates the concepts described in this chapter.
However, apart from the component system specification, nothing in the client interface indicates that it is calling an Enterprise JavaBean. In fact, the same code could be used to call a COM component. The component system specification determines which type of component gets instantiated.
Figure 7-1 This client screen allows users to look up company names and telephone numbers.
The unnamed JPL procedure creates the variable which will hold the object ID of the EJB. During screen entry, the EJB is instantiated.
vars id
proc enter
{
@app()->current_component_system=PV_SERVER_EJB
id = sm_obj_create("Customers")
}
On exiting the screen, the EJB is destroyed.
proc exit
{
call sm_obj_delete_id(id)
}
This JPL procedure calls the EJB's GetCustomer
method and gets the value of the RowCount
property:
proc do_search
{
vars error
CompanyName[1] = search
error = sm_obj_call (id, "GetCustomer", \
CompanyName, CustomerID, Phone)
rowcount = sm_obj_get_property (id, "RowCount")
}
The Panther distribution contains additional EJB samples. For a full description, refer to Appendix B, "Sample Applications."