Java does not support methods with output parameters. Such parameters must be handled by structures called holders or wrappers.
HolderGenerator is a simple tool for the creation of typed holders. See In-Out Parameters for more information about parameters in WSO2 SOA Enablement Server.
HolderGenerator is included in the Core-Tools component. It is accessible through the HolderGenerator script in the bin subdirectory of the WSO2 SOA Enablement Server distribution.
To see the usefulness of holders, consider a Java method which increases an instance of the integer i by 1:
public void increase(int i) { i++; }
You try to call the method:
int i = 1; increase(i);
This does not work. After the call is done, i still has the same value, 1. This is because Java does not support output parameters. Instead of a method call, you could use a value holder and modify the increase method accordingly:
public class IHolder { int i; }
public void increase(IHolder iholder) { iholder.i++; }
IHolder iholder = new IHolder(); iholder.i = 1; increase(iholder);
Calling the increase method on iholder will correctly increase the value of i to 2.
WSO2 SOA Enablement Server fully supports two types of holders.
The first type is the JAX-RPC holder. JAX-RPC is a Java standard for higher-level calling of Web services. It contains implementations of holders for all the primitive types and other frequently used data types, like String and QName.
The second holder a user can create is custom-made. A custom holder must implement the appropriate interfaces from the WSO2 SOA Enablement Server public API. These interfaces are held in the types package:
org.idoox.wasp.types.Holder Holds input/output parameters
org.idoox.wasp.types.InOutHolder Holds input/output parameters (inherits from Holder)
org.idoox.wasp.types.OutHolder Holds output parameter, included only in response message
A type that implements one of the org.idoox.wasp.types.Holder interfaces, or is recognized to be a JAX-RPC holder, gets special support in WSO2 SOA Enablement Server. Such a parameter is generated as input/output into the appropriate operation in WSDL. Finally, when invoking a service, corresponding serializers and deserializers can be directly chosen for two-way value passing.
The HolderGenerator tool creates a class implementing the org.idoox.wasp.types.Holder interface. By default, the created class is named ObjectHolder; no package is defined.
Three methods are implemented from the Holder interface:
Object getObjectValue()
Returns Holder value
void setObjectValue(Object objectValue)
Sets Holder value
Class getValueClass()
Returns the class of the object in the Holder
The created holder defines another two methods that support the data type of the value in the Holder. Through these methods, the requisite type casting can be eliminated. These methods are:
<data type of value> getValue()
Returns the data type of the value in the Holder
void setValue(<data type of value> value)
Sets the data type of the value in the Holder
When the user tries to generate a holder that already exists, a message with a reference to the full class name is printed to the command line and no file is created.
HolderGenerator can be invoked simply by running HolderGenerator.bat or ./HolderGenerator.
HolderGenerator [ optional_parameters ...] <type>
In the preceding synopsis, <type> is the full qualified name of the value being held, such as java.lang.String.
Options:
Full class name to generate.
Output directory to save .java file in.
Overwrites existing file, when a file with same path as the file being generated exists already. This prevents "File already exists"-type errors.
Type of holder to generate. Type can be either "out" or "inout". Default is "inout".
Prints a list of these options to the screen.
If you use HolderGenerator with a predefined type, only a message is printed. For example, the command HolderGenerator int produces the following message:
You do not need to generate new holder, use JAX-RPC holder instead. Full class name: javax.xml.rpc.holders.IntegerHolder
This message means that you should directly use the javax.xml.rpc.holders.IntHolder class.
To create a holder for a DOM Document, type on the command line HolderGenerator org.w3c.dom.Document. You will get the following message:
Holder has been successfully generated: DocumentHolder.java
The file DocumentHolder.java (shown in Example 193) will be created, configured with a held value of the type org.w3c.dom.Document.
Example 193. DocumentHolder
// Copyright WSO2 Inc. All rights reserved. // Use is subject to license terms. public class DocumentHolder implements org.idoox.wasp.types.Holder { public org.w3c.dom.Document value; public Object getObjectValue() { return value; } public void setObjectValue(Object objectValue) { value = (org.w3c.dom.Document) objectValue; } public org.w3c.dom.Document getValue() { return value; } public void setValue(org.w3c.dom.Document value) { this.value = value; } public Class getValueClass() { return org.w3c.dom.Document.class; } }
If you would like to place the previous holder in the package org.pkg with the class name MyDocHolder, use the -c parameter:
HolderGenerator -c org.pkg.MyDocHolder org.w3c.dom.Document
You should get the following message on screen:
Holder has been successfully generated: MyDocHolder.java
This command produces a class named MyDocHolder in the required package:
// Copyright WSO2 Inc. All rights reserved. // Use is subject to license terms. package example.holderGenerator; public class MyDocHolder implements org.idoox.wasp.types.Holder { public org.w3c.dom.Document value; public DocumentHolder() { } public DocumentHolder(org.w3c.dom.Document value) { this.value = value; } public Object getObjectValue() { return value; } public void setObjectValue(Object objectValue) { value = (org.w3c.dom.Document) objectValue; } public org.w3c.dom.Document getValue() { return value; } public void setValue(org.w3c.dom.Document value) { this.value = value; } public Class getValueClass() { return org.w3c.dom.Document.class; } }