OperationImplpublic class OperationImpl extends Operation The OperationImpl class is an implementation
of the javax.microedition.xml.rpc.Operation
class, corresponding to a wsdl:operation defined for a
target service endpoint. |
Fields Summary |
---|
private static String[] | cookiesHTTP Sessions are implemented through the use of cookies.
Since a "session" would involve likely more than one Operation,
the set of cookies for all known sessions is made static across
all Operations. The cookies array is implemented like the properties
array - as a set of tuples. The first value being the endpoint
address which started the session, the second value being the
cookie for the session (i.e., cookie 0 is represented by the
endpoint at index 0, and the cookie string at index 1). | private static int | cookieIndexThe index of the next available entry in the cookie set.
Since cookies are tuples, the algorithm (cookieIndex / 2)
will yield the number of properties stored in the set. | private String[] | propertiesThe set of properties set by the setProperty
method. Each property is a tuple, represented by two sequential
entries in the array (i.e., property 0 is represented by the
key at index 0, and the value at index 1) | private int | propertyIndexThe index of the next available entry in the property set.
Since properties are tuples, the algorithm (propertyIndex / 2)
will yield the number of properties stored in the set. | private SOAPEncoder | encoderThe Encoder to use when encoding communications to
Web Services | private SOAPDecoder | decoderThe Decoder to use when decoding communications from
Web Services | private QName | nameThe QName of this operation | private Element | inputTypeThe Type of the input parameter to this Operation | private Element | returnTypeThe Type of the output parameter to this Operation | private FaultDetailHandler | faultHandlerThe handler to provide the decoding information for
custom fault details | private boolean | resourceMovedA flag indicating the the object was moved (i.e. 3xx HTTP response
was received) and we have to retry the operation using a new location |
Constructors Summary |
---|
public OperationImpl(QName name, Element input, Element output)Default constructor matches that of Operation
this.name = name;
this.inputType = input;
this.returnType = output;
this.encoder = new SOAPEncoder();
this.decoder = new SOAPDecoder();
| public OperationImpl(QName name, Element input, Element output, FaultDetailHandler faultDetailHandler)Default constructor matches that of Operation
this.name = name;
this.inputType = input;
this.returnType = output;
this.faultHandler = faultDetailHandler;
this.encoder = new SOAPEncoder();
this.decoder = new SOAPDecoder();
|
Methods Summary |
---|
private static synchronized void | addSessionCookie(java.lang.String endpoint, java.lang.String cookie)Adds a cookie to identify this session.
Please refer to the section 13.2 of the JAX-RPC 1.1 spec.
if (endpoint == null || cookie == null) {
return;
}
// We strip off everything after the name=value info
int i = cookie.indexOf(";");
if (i > 0) {
cookie = cookie.substring(0, i);
}
// Before appending, check to see if we are modifying
// a previous key/value pair
if (cookies != null) {
for (i = 0; i < cookieIndex; i += 2) {
if (cookies[i].equals(endpoint)) {
cookies[i + 1] = cookie;
return;
}
}
}
// If cookies not instantiated yet, start out with '
// room to hold 5 cookies (5 * 2 entries = 10)
if (cookies == null) {
cookies = new String[10];
// If cookies is full, re-size with room for another
// 5 cookies
} else if (cookieIndex == cookies.length) {
String[] newCookies = new String[cookies.length + 10];
System.arraycopy(cookies, 0, newCookies, 0, cookies.length);
cookies = null;
cookies = newCookies;
}
cookies[cookieIndex++] = endpoint;
cookies[cookieIndex++] = cookie;
// cookieIndex is left pointing at the next available
// entry in the cookie list
| private java.lang.String | getProperty(java.lang.String key)Internal utility method to retrieve a property value
from the property set
if (properties != null) {
for (int i = 0; i < (properties.length - 2); i += 2) {
if (properties[i] == null) {
return null;
}
if (properties[i].equals(key)) {
return properties[i + 1];
}
}
}
return null;
| private static synchronized java.lang.String | getSessionCookie(java.lang.String endpoint)Look through the set of session cookies, and return the
one that matches the current endpoint address of this
Operation, if any.
if (cookies != null) {
for (int i = 0; i < (cookies.length - 2); i += 2) {
if (cookies[i] == null) {
return null;
}
if (cookies[i].equals(endpoint)) {
return cookies[i + 1];
}
}
}
return null;
| public java.lang.Object | invoke(java.lang.Object params)Invokes the wsdl:operation defined by this
Operation and returns the result.
HttpConnection http = null;
OutputStream ostream = null;
InputStream istream = null;
Object result = null;
int attempts = 0;
// Maximal number of "Object moved" http responses that we will handle
final int maxAttempts = Constants.MAX_REDIRECT_ATTEMPTS;
try {
do {
// This flag will be set to 'true' by setupResStream() method
// if code 3xx is returned by the http connection.
resourceMoved = false;
// open stream to service endpoint
http = (HttpConnection)Connector.open(
getProperty(Stub.ENDPOINT_ADDRESS_PROPERTY));
ostream = setupReqStream(http);
// IMPL NOTE: encoding should be either UTF-8 or UTF-16
encoder.encode(params, inputType, ostream, null);
if (ostream != null) {
ostream.close();
}
istream = setupResStream(http);
if (returnType != null && istream != null) {
result = decoder.decode(returnType,
istream,
http.getEncoding(),
http.getLength());
}
if (http != null) {
http.close();
}
if (istream != null) {
istream.close();
}
} while (resourceMoved && (attempts++ < maxAttempts));
if (resourceMoved) {
throw new JAXRPCException("Too many redirections");
}
return result;
} catch (Throwable t) {
// Debug Line
if (ostream != null) {
try {
ostream.close();
} catch (Throwable t2) { }
}
if (istream != null) {
try {
istream.close();
} catch (Throwable t3) { }
}
if (http != null) {
try {
http.close();
} catch (Throwable t1) { }
}
// Re-throw whatever error/exception occurs as a new
// JAXRPCException
if (t instanceof JAXRPCException) {
throw (JAXRPCException)t;
} else {
if (t instanceof MarshalException ||
t instanceof ServerException ||
t instanceof FaultDetailException) {
throw new JAXRPCException(t);
} else {
throw new JAXRPCException(t.toString());
}
}
}
| public void | setProperty(java.lang.String name, java.lang.String value)Sets the property name to the value,
value .
// disallow any null key or value data
if (name == null || value == null) {
throw new IllegalArgumentException();
} else if (
!name.equals(Stub.ENDPOINT_ADDRESS_PROPERTY) &&
!name.equals(Stub.PASSWORD_PROPERTY) &&
!name.equals(Stub.USERNAME_PROPERTY) &&
!name.equals(Stub.SESSION_MAINTAIN_PROPERTY) &&
!name.equals(Operation.SOAPACTION_URI_PROPERTY))
{
throw new IllegalArgumentException();
}
// Before appending, check to see if we are modifying
// a previous key/value pair
if (properties != null) {
for (int i = 0; i < propertyIndex; i += 2) {
if (properties[i].equals(name)) {
properties[i + 1] = value;
return;
}
}
}
// If properties not instantiated yet, start out with '
// room to hold 5 properties (5 * 2 entries = 10)
if (properties == null) {
properties = new String[10];
// If properties is full, re-size with room for another
// 5 properties
} else if (propertyIndex == properties.length) {
String[] newProps = new String[properties.length + 10];
System.arraycopy(properties, 0, newProps, 0, properties.length);
properties = null;
properties = newProps;
}
properties[propertyIndex++] = name;
properties[propertyIndex++] = value;
// propertyIndex is left pointing at the next available
// entry in the property list
| protected java.io.OutputStream | setupReqStream(HttpConnection http)Method to configure the HTTP request stream.
This method will do whatever mechanics are necessary to
utilize the HTTP connection object to return an output
stream to be utilized to send the HTTP request.
http.setRequestMethod(HttpConnection.POST);
http.setRequestProperty("User-Agent",
"Profile/MIDP-1.0 Configuration/CLDC-1.0");
http.setRequestProperty("Content-Language", "en-US");
http.setRequestProperty("Content-Type", "text/xml");
String soapAction = getProperty(Operation.SOAPACTION_URI_PROPERTY);
if (soapAction == null || "".equals(soapAction)) {
soapAction = "\"\"";
} else {
if (!soapAction.startsWith("\"")) {
soapAction = "\"" + soapAction;
}
if (!soapAction.endsWith("\"")) {
soapAction = soapAction + "\"";
}
}
http.setRequestProperty("SOAPAction", soapAction);
String useSession = getProperty(Stub.SESSION_MAINTAIN_PROPERTY);
if (useSession != null && useSession.toLowerCase().equals("true")) {
String cookie = getSessionCookie(
getProperty(Stub.ENDPOINT_ADDRESS_PROPERTY));
if (cookie != null) {
http.setRequestProperty("Cookie", cookie);
}
}
String s1 = getProperty(Stub.USERNAME_PROPERTY);
String s2 = getProperty(Stub.PASSWORD_PROPERTY);
if (s1 != null && s2 != null) {
byte[] encodeData = (s1 + ":" + s2).getBytes();
http.setRequestProperty("Authorization", "Basic " +
Base64.encode(encodeData, 0, encodeData.length));
}
return http.openOutputStream();
| protected java.io.InputStream | setupResStream(HttpConnection http)Method to configure the HTTP response stream.
This method will do whatever mechanics are necessary to
utilize the HTTP connection object to return an input
stream to the HTTP response.
int response = http.getResponseCode();
if (response == HttpConnection.HTTP_MOVED_PERM ||
response == HttpConnection.HTTP_MOVED_TEMP) {
// Resource was moved, get a new location and retry the operation
String newLocation = http.getHeaderField("Location");
setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, newLocation);
resourceMoved = true;
return null;
}
InputStream input = http.openInputStream();
if (response == HttpConnection.HTTP_OK) {
// Catch any session cookie if one was set
String useSession = getProperty(Stub.SESSION_MAINTAIN_PROPERTY);
if (useSession != null && useSession.toLowerCase().equals("true"))
{
String cookie = http.getHeaderField("Set-Cookie");
if (cookie != null) {
addSessionCookie(
getProperty(Stub.ENDPOINT_ADDRESS_PROPERTY), cookie);
}
}
return input;
} else {
Object detail = decoder.decodeFault(faultHandler,
input,
http.getEncoding(),
http.getLength());
if (detail instanceof String) {
if (((String)detail).indexOf("DataEncodingUnknown") != -1) {
throw new MarshalException((String)detail);
} else {
throw new ServerException((String)detail);
}
} else {
Object[] wrapper = (Object[])detail;
String message = (String)wrapper[0];
QName name = (QName)wrapper[1];
detail = wrapper[2];
throw new JAXRPCException(message,
new FaultDetailException(name, detail));
}
}
|
|