Adapter for Enterprise JavaBeans 6.5 SP3 | webMethods Adapter for Enterprise JavaBeans Documentation | webMethods Adapter for Enterprise JavaBeans Installation and User’s Documentation | Creating Flows for Adapter for Enterprise Javabeans Services | Working with Different Object Types | Creating Java Services to Use with Objects | Example 1
 
Example 1
The goal of this example is to write a flow that executes the buy method. Note that the buy signature contains two user-defined classes: TradeResult and StockOrder. The first example focuses primarily on StockOrder. In the flow, you need to create an instance of StockOrder with the appropriate attributes and then pass it to an InvokeEJB 2.1 or InvokeEJB 3.0 adapter service instance configured to execute the buy method. The easiest way to do this is to create a Java coded service that is specifically designed to accept input from the user at run time, create a StockOrder with those inputs, and then insert the StockOrder into the pipeline.
When creating the Java service, Designer automatically generated the public signature of the Java service, and its lone input argument is an instance of com.wm.data.IData.This is the pipeline referred to earlier.
Now look at the public interface of the StockOrder class:
package examples.ejb20.testbeans.stateless.ComplexTrader;
import java.io.Serializable;

/**
* This class represents a buy/sell order for a single security.
*/

public final class StockOrder implements Serializable
{
// Order duration constants...
public static final int DAY = 0; // Good for the Day
public static final int GTC = 1; // Good 'Til Cancelled

// Order type constants (only long positions allowed)...
public static final int MARKET = 0; // Execute at current market price
public static final int LIMIT = 1; // For buys; execute at limit price or
lower
public static final int STOP = 2; // For sells; execute at stop price or
higher
public static final int STOPLIMIT = 3; // For sells; execute at no less that
stop, no more than limit
public static final int ALLORNONE = 4; // Execute entire order at market or
none of it
public static final int FILLORKILL = 5; // Execute entire order immediately at
market or none of it

// Constructors
/**
* This constructor used for STOPLIMIT order types.
*/
public StockOrder(String symbol, int quantity, int duration, int type, double
stop, double limit);

/**
* This constructor used for LIMIT, STOP order types.
*/
public StockOrder(String symbol, int quantity, int duration, int type, double
price);

/**
* This constructor used for MARKET, ALLORNONE, FILLORKILL orders.
*/
public StockOrder(String symbol, int quantity, int duration, int type);

// "Getters"…
public String getSecurity();
public int getNumberUnits();
public int getOrderDuration();
public int getOrderType();
public double getPrice();
public double getStopPrice();
public double getLimitPrice();
}
This class is used for both “buy” and “sell” orders. Essentially, you create and initialize a StockOrder object by calling one of its three constructors. The constructor used determines if the order is a market order, a stop order, a limit order, or a stop-limit order (see the embedded comments for descriptions of these terms in the public interface above).
For this example, assume that you want to execute a “buy” order, but do not want to pay more than a certain amount per share. In this case you would need to create the StockOrder object using the second constructor:
public StockOrder(String symbol, int quantity, int duration, int type, double
price);
You can see how to construct the StockOrder, but where do the actual values come from? You could simply generate them within the BuildLimitOrder service itself, but this is not very flexible. A better approach is to define an input signature for the service that allows the caller to provide the values that will be passed to the StockOrder constructor.
In addition to the InVals structured document declared as the input signature of BuildLimitOrder, a single Object definition, order, is declared in the output signature. The content of InVals consists of four String types: symbol, quality, duration, and price. These types correspond to four of the five arguments required by the StockOrder constructor. (The missing constructor argument, type, will be provided within the implementation of BuildLimitOrder itself.) Note, however, that the respective types of these parameters do not correspond in all cases (for example, the ‘price' constructor type is a primitive double). The easiest approach is to treat all the inputs as strings and simply perform the necessary type transformations within the service's implementation.
The following code is a complete implementation of the BuildLimitOrder service:
public static final void BuildLimitOrder (IData pipeline) throws
ServiceException {
String _symbol = null;
int _quantity = 0;
int _duration = 99;
double _price = -99.99D;
  
// Get access to nested 'InVals' pipeline...
IDataCursor idc0 = pipeline.getCursor();
idc0.first();
IData inVals = (IData)idc0.getValue();

// Enumerate the contents of 'InVals'...
IDataCursor idc1 = inVals.getCursor();
while (idc1.next())
{
// Process the 'symbol' input value...
String key = idc1.getKey();
if (key.equals("symbol"))
_symbol = (String)idc1.getValue();

// Process the 'quantity' input value...
else if (key.equals("quantity"))
{
String tmp = (String)idc1.getValue();
try
{
// Need to convert to int
_quantity = Integer.parseInt(tmp);
}
catch (NumberFormatException e) {}
}

// Process the 'duration' input value...
else if (key.equals("duration"))
{
// Convert string value to its enumerated counterpart
String tmp = (String)idc1.getValue();
if (tmp.equalsIgnoreCase("DAY"))
_duration = StockOrder.DAY;
 else if (tmp.equalsIgnoreCase("GTC"))
  _duration = StockOrder.GTC;
else
_duration = 999;
}

// Process the 'price' input value...
else if (key.equals("price"))
{
String tmp = (String)idc1.getValue();
try
{
// Need to convert to double
_price = Double.parseDouble(tmp);
}
catch (NumberFormatException e){}
}
}
idc1.destroy();
  
// Create a new LIMIT StockOrder...
StockOrder so = new StockOrder(_symbol, _quantity, _duration,
StockOrder.LIMIT, _price);

// Insert it in the outbound pipeline...
idc0.insertAfter("order", so);
idc0.destroy();
}
In the code that deals with the pipeline, note how when accessing elements in the input or output signature, it refers explicitly to the configured names of these elements (for example, “quantity”, “price”, “order”). This is one approach that can be taken. It is also possible to access items in the pipeline without referring to them by name. For a complete explanation of how to use the com.wm.data.IData and com.wm.data.IDataCursor classes, see the Javadocs provided in Designer and the webMethods Service Development Help for your release.
You can see the final, completed BuildLimitOrder service in the figures below.
When you save the BuildLimitOrder service, Designer will compile it and report any errors it finds. When you have addressed all errors you can run the service standalone and debug it in Designer. After the BuildLimitOrder service is in place and tested you can add it to a flow service.
The next figures show a simple flow service named LimitedBuy that combines the new coded service, BuildLimitOrder, with the previously configured CreateEJB 2.1 or FetchEJB 3.0 adapter service (Trader) and a corresponding InvokeEJB 2.1 or InvokeEJB 3.0 adapter service (BuyComplexStock) instances.
Note that the input signature for the LimitedBuy flow mimics that of the BuildLimitOrder coded service. This allows you to map the values provided to the flow service at run time to the input signature of BuildLimitOrder.
Because the GetComplexTrader adapter service has no input signature, its inbound pipeline is simple. The signature of the BuyComplexStock adapter service is more complex. To fulfill its input signature, the output of BuildLimitOrder (the order Object) is mapped to the OrderDetail input Object. The mapping of the first element of Results to EJB passes the actual EJB into the BuyComplexStock adapter service as discussed earlier. These mappings are shown in the figure below.