You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by di...@apache.org on 2005/06/17 20:34:50 UTC
cvs commit: ws-axis/java/src/org/apache/axis/providers/java RPCProvider.java
dims 2005/06/17 11:34:50
Modified: java/src/org/apache/axis/providers/java RPCProvider.java
Log:
Fix for AXIS-2061 - Refactored RPCProvider
Revision Changes Path
1.122 +130 -121 ws-axis/java/src/org/apache/axis/providers/java/RPCProvider.java
Index: RPCProvider.java
===================================================================
RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/providers/java/RPCProvider.java,v
retrieving revision 1.121
retrieving revision 1.122
diff -u -r1.121 -r1.122
--- RPCProvider.java 2 May 2005 11:39:36 -0000 1.121
+++ RPCProvider.java 17 Jun 2005 18:34:50 -0000 1.122
@@ -74,75 +74,8 @@
SOAPService service = msgContext.getService();
ServiceDesc serviceDesc = service.getServiceDescription();
- OperationDesc operation = msgContext.getOperation();
-
- Vector bodies = reqEnv.getBodyElements();
- if (log.isDebugEnabled()) {
- log.debug(Messages.getMessage("bodyElems00", "" + bodies.size()));
- if(bodies.size()>0){
- log.debug(Messages.getMessage("bodyIs00", "" + bodies.get(0)));
- }
- }
-
- RPCElement body = null;
-
- // Find the first "root" body element, which is the RPC call.
- for (int bNum = 0; body == null && bNum < bodies.size(); bNum++) {
- // If this is a regular old SOAPBodyElement, and it's a root,
- // we're probably a non-wrapped doc/lit service. In this case,
- // we deserialize the element, and create an RPCElement "wrapper"
- // around it which points to the correct method.
- // FIXME : There should be a cleaner way to do this...
- if (!(bodies.get(bNum) instanceof RPCElement)) {
- SOAPBodyElement bodyEl = (SOAPBodyElement) bodies.get(bNum);
- // igors: better check if bodyEl.getID() != null
- // to make sure this loop does not step on SOAP-ENC objects
- // that follow the parameters! FIXME?
- if (bodyEl.isRoot() && operation != null && bodyEl.getID() == null) {
- ParameterDesc param = operation.getParameter(bNum);
- // at least do not step on non-existent parameters!
- if (param != null) {
- Object val = bodyEl.getValueAsType(param.getTypeQName());
- body = new RPCElement("",
- operation.getName(),
- new Object[]{val});
- }
- }
- } else {
- body = (RPCElement) bodies.get(bNum);
- }
- }
-
- // special case code for a document style operation with no
- // arguments (which is a strange thing to have, but whatever)
- if (body == null) {
- // throw an error if this isn't a document style service
- if (!(serviceDesc.getStyle().equals(Style.DOCUMENT))) {
- throw new Exception(Messages.getMessage("noBody00"));
- }
-
- // look for a method in the service that has no arguments,
- // use the first one we find.
- ArrayList ops = serviceDesc.getOperations();
- for (Iterator iterator = ops.iterator(); iterator.hasNext();) {
- OperationDesc desc = (OperationDesc) iterator.next();
- if (desc.getNumInParams() == 0) {
- // found one with no parameters, use it
- msgContext.setOperation(desc);
- // create an empty element
- body = new RPCElement(desc.getName());
- // stop looking
- break;
- }
- }
-
- // If we still didn't find anything, report no body error.
- if (body == null) {
- throw new Exception(Messages.getMessage("noBody00"));
- }
- }
+ RPCElement body = getBody(reqEnv, msgContext);
- String methodName = body.getMethodName();
Vector args = null;
try {
args = body.getParams();
@@ -152,45 +85,15 @@
throw e;
}
int numArgs = args.size();
-
- // This may have changed, so get it again...
- // FIXME (there should be a cleaner way to do this)
- operation = msgContext.getOperation();
-
- if (operation == null) {
- QName qname = new QName(body.getNamespaceURI(),
- body.getName());
- operation = serviceDesc.getOperationByElementQName(qname);
+ OperationDesc operation = getOperationDesc(msgContext, body);
- if (operation == null) {
- SOAPConstants soapConstants = msgContext == null ?
- SOAPConstants.SOAP11_CONSTANTS :
- msgContext.getSOAPConstants();
- if (soapConstants == SOAPConstants.SOAP12_CONSTANTS) {
- AxisFault fault =
- new AxisFault(Constants.FAULT_SOAP12_SENDER,
- Messages.getMessage("noSuchOperation",
- methodName),
- null,
- null);
- fault.addFaultSubCode(Constants.FAULT_SUBCODE_PROC_NOT_PRESENT);
- throw new SAXException(fault);
- } else {
- throw new AxisFault(Constants.FAULT_CLIENT, Messages.getMessage("noSuchOperation", methodName),
- null, null);
- }
- } else {
- msgContext.setOperation(operation);
- }
- }
-
// Create the array we'll use to hold the actual parameter
// values. We know how big to make it from the metadata.
Object[] argValues = new Object[operation.getNumParams()];
// A place to keep track of the out params (INOUTs and OUTs)
ArrayList outs = new ArrayList();
-
+
// Put the values contained in the RPCParams into an array
// suitable for passing to java.lang.reflect.Method.invoke()
// Make sure we respect parameter ordering if we know about it
@@ -199,10 +102,10 @@
for (int i = 0; i < numArgs; i++) {
RPCParam rpcParam = (RPCParam) args.get(i);
Object value = rpcParam.getObjectValue();
-
+
// first check the type on the paramter
ParameterDesc paramDesc = rpcParam.getParamDesc();
-
+
// if we found some type info try to make sure the value type is
// correct. For instance, if we deserialized a xsd:dateTime in
// to a Calendar and the service takes a Date, we need to convert
@@ -210,7 +113,7 @@
// Get the type in the signature (java type or its holder)
Class sigType = paramDesc.getJavaType();
-
+
// Convert the value into the expected type in the signature
value = JavaUtils.convert(value, sigType);
@@ -219,7 +122,7 @@
outs.add(rpcParam);
}
}
-
+
// Put the value (possibly converted) in the argument array
// make sure to use the parameter order if we have it
if (paramDesc == null || paramDesc.getOrder() == -1) {
@@ -233,7 +136,7 @@
"" + argValues[i]));
}
}
-
+
// See if any subclasses want a crack at faulting on a bad operation
// FIXME : Does this make sense here???
String allowedMethods = (String) service.getOption("allowedMethods");
@@ -242,7 +145,7 @@
// Now create any out holders we need to pass in
int count = numArgs;
for (int i = 0; i < argValues.length; i++) {
-
+
// We are interested only in OUT/INOUT
ParameterDesc param = operation.getParameter(i);
if(param.getMode() == ParameterDesc.IN)
@@ -252,7 +155,7 @@
if (holderClass != null &&
Holder.class.isAssignableFrom(holderClass)) {
int index = count;
- // Use the parameter order if specified or just stick them to the end.
+ // Use the parameter order if specified or just stick them to the end.
if (param.getOrder() != -1) {
index = param.getOrder();
} else {
@@ -276,7 +179,7 @@
operation.getName()));
}
}
-
+
// OK! Now we can invoke the method
Object objRes = null;
try {
@@ -303,20 +206,127 @@
new String[]{methodSig, argClasses}),
e);
}
-
- /** If this is a one-way operation, there is nothing more to do.
- */
- if (OperationType.ONE_WAY.equals(operation.getMep()))
+ /** If this is a one-way operation, there is nothing more to do.
+ */
+ if (OperationType.ONE_WAY.equals(operation.getMep()))
return;
-
- /* Now put the result in the result SOAPEnvelope */
- /*************************************************/
+
+ RPCElement resBody = createResponseBody(body, msgContext, operation, serviceDesc, objRes, resEnv, outs);
+ resEnv.addBodyElement(resBody);
+ }
+
+ private RPCElement getBody(SOAPEnvelope reqEnv, MessageContext msgContext) throws Exception {
+ SOAPService service = msgContext.getService();
+ ServiceDesc serviceDesc = service.getServiceDescription();
+ OperationDesc operation = msgContext.getOperation();
+ Vector bodies = reqEnv.getBodyElements();
+ if (log.isDebugEnabled()) {
+ log.debug(Messages.getMessage("bodyElems00", "" + bodies.size()));
+ if(bodies.size()>0){
+ log.debug(Messages.getMessage("bodyIs00", "" + bodies.get(0)));
+ }
+ }
+ RPCElement body = null; // Find the first "root" body element, which is the RPC call.
+ for (int bNum = 0; body == null && bNum < bodies.size(); bNum++) {
+ // If this is a regular old SOAPBodyElement, and it's a root,
+ // we're probably a non-wrapped doc/lit service. In this case,
+ // we deserialize the element, and create an RPCElement "wrapper"
+ // around it which points to the correct method.
+ // FIXME : There should be a cleaner way to do this...
+ if (!(bodies.get(bNum) instanceof RPCElement)) {
+ SOAPBodyElement bodyEl = (SOAPBodyElement) bodies.get(bNum);
+ // igors: better check if bodyEl.getID() != null
+ // to make sure this loop does not step on SOAP-ENC objects
+ // that follow the parameters! FIXME?
+ if (bodyEl.isRoot() && operation != null && bodyEl.getID() == null) {
+ ParameterDesc param = operation.getParameter(bNum);
+ // at least do not step on non-existent parameters!
+ if (param != null) {
+ Object val = bodyEl.getValueAsType(param.getTypeQName());
+ body = new RPCElement("",
+ operation.getName(),
+ new Object[]{val});
+ }
+ }
+ } else {
+ body = (RPCElement) bodies.get(bNum);
+ }
+ } // special case code for a document style operation with no
+ // arguments (which is a strange thing to have, but whatever)
+ if (body == null) {
+ // throw an error if this isn't a document style service
+ if (!(serviceDesc.getStyle().equals(Style.DOCUMENT))) {
+ throw new Exception(Messages.getMessage("noBody00"));
+ }
+
+ // look for a method in the service that has no arguments,
+ // use the first one we find.
+ ArrayList ops = serviceDesc.getOperations();
+ for (Iterator iterator = ops.iterator(); iterator.hasNext();) {
+ OperationDesc desc = (OperationDesc) iterator.next();
+ if (desc.getNumInParams() == 0) {
+ // found one with no parameters, use it
+ msgContext.setOperation(desc);
+ // create an empty element
+ body = new RPCElement(desc.getName());
+ // stop looking
+ break;
+ }
+ }
+
+ // If we still didn't find anything, report no body error.
+ if (body == null) {
+ throw new Exception(Messages.getMessage("noBody00"));
+ }
+ }
+ return body;
+ }
+
+ private OperationDesc getOperationDesc(MessageContext msgContext, RPCElement body) throws SAXException, AxisFault {
+ SOAPService service = msgContext.getService();
+ ServiceDesc serviceDesc = service.getServiceDescription();
+ String methodName = body.getMethodName();
+
+ // FIXME (there should be a cleaner way to do this)
+ OperationDesc operation = msgContext.getOperation();
+ if (operation == null) {
+ QName qname = new QName(body.getNamespaceURI(),
+ body.getName());
+ operation = serviceDesc.getOperationByElementQName(qname);
+
+ if (operation == null) {
+ SOAPConstants soapConstants = msgContext == null ?
+ SOAPConstants.SOAP11_CONSTANTS :
+ msgContext.getSOAPConstants();
+ if (soapConstants == SOAPConstants.SOAP12_CONSTANTS) {
+ AxisFault fault =
+ new AxisFault(Constants.FAULT_SOAP12_SENDER,
+ Messages.getMessage("noSuchOperation",
+ methodName),
+ null,
+ null);
+ fault.addFaultSubCode(Constants.FAULT_SUBCODE_PROC_NOT_PRESENT);
+ throw new SAXException(fault);
+ } else {
+ throw new AxisFault(Constants.FAULT_CLIENT, Messages.getMessage("noSuchOperation", methodName),
+ null, null);
+ }
+ } else {
+ msgContext.setOperation(operation);
+ }
+ }
+ return operation;
+ }
+
+ protected RPCElement createResponseBody(RPCElement body, MessageContext msgContext, OperationDesc operation, ServiceDesc serviceDesc, Object objRes, SOAPEnvelope resEnv, ArrayList outs) throws Exception
+ {
+ String methodName = body.getMethodName();
+ /* Now put the result in the result SOAPEnvelope */
RPCElement resBody = new RPCElement(methodName + "Response");
resBody.setPrefix(body.getPrefix());
resBody.setNamespaceURI(body.getNamespaceURI());
resBody.setEncodingStyle(msgContext.getEncodingStyle());
-
try {
// Return first
if (operation.getMethod().getReturnType() != Void.TYPE) {
@@ -324,13 +334,13 @@
if (returnQName == null) {
String nsp = body.getNamespaceURI();
if(nsp == null || nsp.length()==0) {
- nsp = serviceDesc.getDefaultNamespace();
+ nsp = serviceDesc.getDefaultNamespace();
}
returnQName = new QName(msgContext.isEncoded() ? "" :
nsp,
methodName + "Return");
}
-
+
RPCParam param = new RPCParam(returnQName, objRes);
param.setParamDesc(operation.getReturnParamDesc());
@@ -348,7 +358,7 @@
}
}
-
+
// Then any other out params
if (!outs.isEmpty()) {
for (Iterator i = outs.iterator(); i.hasNext();) {
@@ -369,8 +379,7 @@
} catch (Exception e) {
throw e;
}
-
- resEnv.addBodyElement(resBody);
+ return resBody;
}
/**