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 2007/04/26 07:19:33 UTC
svn commit: r532615 [4/13] - in /webservices/axis2/branches/java/1_2/modules:
jaxws-api/src/javax/xml/ws/handler/soap/ jaxws-api/src/javax/xml/ws/soap/
jaxws/ jaxws/src/org/apache/axis2/jaxws/
jaxws/src/org/apache/axis2/jaxws/binding/ jaxws/src/org/apa...
Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerInvokerUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerInvokerUtils.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerInvokerUtils.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerInvokerUtils.java Wed Apr 25 22:19:23 2007
@@ -25,6 +25,7 @@
import org.apache.axis2.jaxws.core.MessageContext;
import org.apache.axis2.jaxws.description.EndpointDescription;
import org.apache.axis2.jaxws.message.Message;
+import org.apache.axis2.jaxws.message.Protocol;
import org.apache.axis2.jaxws.message.factory.MessageFactory;
import org.apache.axis2.jaxws.registry.FactoryRegistry;
import org.apache.axis2.jaxws.server.endpoint.lifecycle.impl.EndpointLifecycleManagerImpl;
@@ -33,7 +34,7 @@
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
-import java.util.ArrayList;
+import java.util.List;
public class HandlerInvokerUtils {
@@ -43,34 +44,24 @@
* @param requestMsgCtx
*/
public static boolean invokeInboundHandlers(MessageContext msgCtx,
- EndpointDescription endpointDesc,
- HandlerChainProcessor.MEP mep, boolean isOneWay) {
+ List<Handler> handlers, EndpointDescription endpointDesc, HandlerChainProcessor.MEP mep, boolean isOneWay) {
- HandlerResolverImpl hResolver = new HandlerResolverImpl(endpointDesc);
- ArrayList<Handler> handlers = hResolver.getHandlerChain(endpointDesc.getPortInfo());
-
- int numHandlers = handlers.size();
-
- javax.xml.ws.handler.MessageContext handlerMessageContext = null;
- if (numHandlers > 0) {
- handlerMessageContext = findOrCreateMessageContext(msgCtx);
- } else {
- return true;
- }
-
- // TODO remove this. Handlers will have already been instantiated when
- // we start using the handlerresolver to get our list.
- //ArrayList<Handler> handlerInstances = createHandlerInstances(endpointDesc);
-
- HandlerChainProcessor processor = new HandlerChainProcessor(
- handlers);
+ String bindingProto = null;
+ if (mep.equals(HandlerChainProcessor.MEP.REQUEST)) // inbound request; must be on the server
+ bindingProto = endpointDesc.getBindingType();
+ else // inbound response; must be on the client
+ bindingProto = endpointDesc.getClientBindingID();
+ Protocol proto = Protocol.getProtocolForBinding(bindingProto);
+
+ HandlerChainProcessor processor = new HandlerChainProcessor(handlers, proto);
// if not one-way, expect a response
+ boolean success = true;
try {
if (msgCtx.getMessage().isFault()) {
- processor.processFault(handlerMessageContext,
+ processor.processFault(msgCtx,
HandlerChainProcessor.Direction.IN);
} else {
- handlerMessageContext = processor.processChain(handlerMessageContext,
+ success = processor.processChain(msgCtx,
HandlerChainProcessor.Direction.IN,
mep,
!isOneWay);
@@ -81,18 +72,14 @@
* we are in the client inbound case. Make sure the message
* context and message are transformed.
*/
- HandlerChainProcessor.convertToFaultMessage(handlerMessageContext, re);
- addConvertedFaultMsgToCtx(msgCtx, handlerMessageContext);
+ HandlerChainProcessor.convertToFaultMessage(msgCtx, re, proto);
return false;
}
-
- if (handlerMessageContext.get(javax.xml.ws.handler.MessageContext.MESSAGE_OUTBOUND_PROPERTY)
- .equals(true)
- && mep.equals(HandlerChainProcessor.MEP.REQUEST)) {
+
+ if (!success && mep.equals(HandlerChainProcessor.MEP.REQUEST)) {
// uh-oh. We've changed directions on the server inbound handler processing,
// This means we're now on an outbound flow, and the endpoint will not
// be called. Be sure to mark the context and message as such.
- addConvertedFaultMsgToCtx(msgCtx, handlerMessageContext);
return false;
}
return true;
@@ -105,40 +92,27 @@
* @param msgCtx
*/
public static boolean invokeOutboundHandlers(MessageContext msgCtx,
- EndpointDescription endpointDesc,
- HandlerChainProcessor.MEP mep, boolean isOneWay) {
-
- //ArrayList<String> handlers = endpointDesc.getHandlerList();
-
- // TODO you may need to hard-code add some handlers until we
- // actually have useful code under EndpointDescription.getHandlerList()
-
- HandlerResolverImpl hResolver = new HandlerResolverImpl(endpointDesc);
- ArrayList<Handler> handlers = hResolver.getHandlerChain(endpointDesc.getPortInfo());
-
- int numHandlers = handlers.size();
-
- javax.xml.ws.handler.MessageContext handlerMessageContext = null;
- if (numHandlers > 0) {
- handlerMessageContext = findOrCreateMessageContext(msgCtx);
- } else {
+ List<Handler> handlers, EndpointDescription endpointDesc, HandlerChainProcessor.MEP mep, boolean isOneWay) {
+
+ if (handlers == null)
return true;
- }
-
- // TODO probably don't want to make the newInstances here -- use
- // RuntimeDescription instead?
- // make instances of all the handlers
- //ArrayList<Handler> handlerInstances = createHandlerInstances(endpointDesc);
- HandlerChainProcessor processor = new HandlerChainProcessor(
- handlers);
+ String bindingProto = null;
+ if (mep.equals(HandlerChainProcessor.MEP.REQUEST)) // outbound request; must be on the client
+ bindingProto = endpointDesc.getClientBindingID();
+ else // outbound response; must be on the server
+ bindingProto = endpointDesc.getBindingType();
+ Protocol proto = Protocol.getProtocolForBinding(bindingProto);
+
+ HandlerChainProcessor processor = new HandlerChainProcessor(handlers, proto);
// if not one-way, expect a response
+ boolean success = true;
try {
if (msgCtx.getMessage().isFault()) {
- processor.processFault(handlerMessageContext,
+ processor.processFault(msgCtx,
HandlerChainProcessor.Direction.OUT);
} else {
- handlerMessageContext = processor.processChain(handlerMessageContext,
+ success = processor.processChain(msgCtx,
HandlerChainProcessor.Direction.OUT,
mep, !isOneWay);
}
@@ -148,90 +122,18 @@
* we are in the server outbound case. Make sure the message
* context and message are transformed.
*/
- HandlerChainProcessor.convertToFaultMessage(handlerMessageContext, re);
- addConvertedFaultMsgToCtx(msgCtx, handlerMessageContext);
+ HandlerChainProcessor.convertToFaultMessage(msgCtx, re, proto);
return false;
}
- if (handlerMessageContext.get(javax.xml.ws.handler.MessageContext.MESSAGE_OUTBOUND_PROPERTY)
- .equals(false)
- && mep.equals(HandlerChainProcessor.MEP.REQUEST)) {
+ if (!success && mep.equals(HandlerChainProcessor.MEP.REQUEST)) {
// uh-oh. We've changed directions on the client outbound handler processing,
// This means we're now on an inbound flow, and the service will not
// be called. Be sure to mark the context and message as such.
- addConvertedFaultMsgToCtx(msgCtx, handlerMessageContext);
return false;
}
return true;
}
-
- /**
- * Find or Create Handler Message Context
- *
- * @param mc
- * @return javax.xml.ws.handler.MessageContext
- */
- private static javax.xml.ws.handler.MessageContext findOrCreateMessageContext(
- MessageContext mc) {
- // See if a soap message context is already present on the WebServiceContext
- javax.xml.ws.handler.MessageContext handlerMessageContext = null;
- ServiceContext serviceContext = mc.getAxisMessageContext().getServiceContext();
- WebServiceContext ws = (WebServiceContext)serviceContext
- .getProperty(EndpointLifecycleManagerImpl.WEBSERVICE_MESSAGE_CONTEXT);
- if (ws != null) {
- handlerMessageContext = ws.getMessageContext();
- }
- if (handlerMessageContext == null) {
- handlerMessageContext = createSOAPMessageContext(mc);
- }
- return handlerMessageContext;
- }
-
- /**
- * @param mc
- * @return new SOAPMessageContext
- */
- private static javax.xml.ws.handler.MessageContext createSOAPMessageContext(MessageContext mc) {
- SoapMessageContext soapMessageContext =
- (SoapMessageContext)MessageContextFactory.createSoapMessageContext(mc);
- ContextUtils.addProperties(soapMessageContext, mc);
- return soapMessageContext;
- }
-
-
- private static void addConvertedFaultMsgToCtx(MessageContext msgCtx,
- javax.xml.ws.handler.MessageContext handlerMsgCtx) {
- try {
- Message msg = ((MessageFactory)FactoryRegistry.getFactory(MessageFactory.class))
- .createFrom(((SOAPMessageContext)handlerMsgCtx).getMessage());
- msgCtx.setMessage(msg);
- } catch (XMLStreamException e) {
- // TODO log it
- throw ExceptionFactory.makeWebServiceException(e);
- }
- }
-
- // TODO method is for TEST only. instances will be created elsewhere
- /*
- private static ArrayList<Handler> createHandlerInstances(EndpointDescription ed) {
- // TODO remove this. Handlers will have already been instantiated when
- // we start using the handlerresolver to get our list.
-
- List<String> handlers = ed.getHandlerList();
- int numHandlers = handlers.size();
-
- ArrayList<Handler> handlerInstances = new ArrayList<Handler>();
- try {
- for (int i = 0; i < numHandlers; i++) {
- handlerInstances.add((Handler) Class.forName(handlers.get(i)).newInstance());
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return handlerInstances;
- }
- */
-
+
}
Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerResolverImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerResolverImpl.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerResolverImpl.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerResolverImpl.java Wed Apr 25 22:19:23 2007
@@ -18,16 +18,25 @@
*/
package org.apache.axis2.jaxws.handler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
import org.apache.axis2.java.security.AccessController;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.description.EndpointDescription;
+import org.apache.axis2.jaxws.description.ServiceDescription;
import org.apache.axis2.jaxws.description.xml.handler.HandlerChainType;
import org.apache.axis2.jaxws.description.xml.handler.HandlerChainsType;
import org.apache.axis2.jaxws.description.xml.handler.HandlerType;
import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.jaxws.runtime.description.injection.ResourceInjectionServiceRuntimeDescription;
+import org.apache.axis2.jaxws.runtime.description.injection.impl.ResourceInjectionServiceRuntimeDescriptionBuilder;
+import org.apache.axis2.jaxws.server.endpoint.lifecycle.EndpointLifecycleException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import javax.xml.namespace.QName;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.HandlerResolver;
@@ -52,6 +61,15 @@
public class HandlerResolverImpl implements HandlerResolver {
+ // TODO should probably use constants defined elsewhere
+ static final Map<String, String> protocolBindingsMap = new HashMap<String, String>(5);
+ static {
+ protocolBindingsMap.put("##SOAP11_HTTP", "http://schemas.xmlsoap.org/wsdl/soap/http");
+ protocolBindingsMap.put("##SOAP11_HTTP_MTOM", "http://schemas.xmlsoap.org/wsdl/soap/http?mtom=true");
+ protocolBindingsMap.put("##SOAP12_HTTP", "http://www.w3.org/2003/05/soap/bindings/HTTP/");
+ protocolBindingsMap.put("##SOAP12_HTTP_MTOM", "http://www.w3.org/2003/05/soap/bindings/HTTP/?mtom=true");
+ protocolBindingsMap.put("##XML_HTTP", "http://www.w3.org/2004/08/wsdl/http");
+ }
private static Log log = LogFactory.getLog(HandlerResolverImpl.class);
/*
* TODO: is there any value/reason in caching the list we collect from the
@@ -77,45 +95,89 @@
* available per port. Ports are stored under the ServiceDelegate
* as PortData objects.
*
- * The resolveHandlers method is responsible for instantiating each Handler,
- * running the annotated PostConstruct method, sorting the list, resolving the list,
- * and returning it
+ * The resolveHandlers method is responsible for instantiating each Handler,
+ * running the annotated PostConstruct method, resolving the list,
+ * and returning it. We do not sort here.
*/
private ArrayList<Handler> resolveHandlers(PortInfo portinfo) throws WebServiceException {
+ /*
+
+ A sample XML file for the handler-chains:
+
+ <jws:handler-chains xmlns:jws="http://java.sun.com/xml/ns/javaee">
+ <jws:handler-chain>
+ <jws:protocol-bindings>##XML_HTTP</jws:protocol-bindings>
+ <jws:handler>
+ <jws:handler-name>MyHandler</jws:handler-name>
+ <jws:handler-class>org.apache.axis2.jaxws.MyHandler</jws:handler-class>
+ </jws:handler>
+ </jws:handler-chain>
+ <jws:handler-chain>
+ <jws:port-name-pattern>jws:Foo*</jws:port-name-pattern>
+ <jws:handler>
+ <jws:handler-name>MyHandler</jws:handler-name>
+ <jws:handler-class>org.apache.axis2.jaxws.MyHandler</jws:handler-class>
+ </jws:handler>
+ </jws:handler-chain>
+ <jws:handler-chain>
+ <jws:service-name-pattern>jws:Bar</jws:service-name-pattern>
+ <jws:handler>
+ <jws:handler-name>MyHandler</jws:handler-name>
+ <jws:handler-class>org.apache.axis2.jaxws.MyHandler</jws:handler-class>
+ </jws:handler>
+ </jws:handler-chain>
+ </jws:handler-chains>
+
+ Couple of things I'm not sure about...
+ 1) if the protocol-binding, port-name-pattern, and service-name-pattern all
+ match the PortInfo object, does MyHandler get added three times? Probably would get added 3 times.
+ 2) I assume the asterisk "*" is a wildcard. Can the asterisk only occur on the local part of the qname?
+ 3) Can there be more than one service-name-pattern or port-name-pattern, just like for protocol-bindings?
+ 4) How many protocol-bindings are there? ##XML_HTTP ##SOAP11_HTTP ##SOAP12_HTTP ##SOAP11_HTTP_MTOM ##SOAP12_HTTP_MTOM
+ They are separated by spaces
+ */
// our implementation already has a reference to the EndpointDescription,
- // which is where one might bet the portinfo object. We still have the
+ // which is where one might get the portinfo object. We still have the
// passed-in variable, however, due to the spec
ArrayList handlers = new ArrayList<Handler>();
- ArrayList logicalHandlers = new ArrayList<Handler>();
- ArrayList protocolHandlers = new ArrayList<Handler>();
-
- /*
- * TODO: the list returned by getHandlerList() eventually will contain
- * more information than just a list of strings. We will need to
- * do a better job checking that the return value (a HandlerDescription
- * object?) matches up with the PortInfo object before we add it to the
- * chain.
- */
+ /*
+ * TODO: do a better job checking that the return value matches up
+ * with the PortInfo object before we add it to the chain.
+ */
+
HandlerChainsType handlerCT = endpointDesc.getHandlerChain();
Iterator it = handlerCT == null ? null : handlerCT.getHandlerChain().iterator();
while ((it != null) && (it.hasNext())) {
- List<HandlerType> handlerTypeList = ((HandlerChainType)it.next()).getHandler();
+ HandlerChainType handlerChainType = ((HandlerChainType)it.next());
+
+ // if !match, continue (to next chain)
+ if (!(chainResolvesToPort(handlerChainType, portinfo)))
+ continue;
+
+ List<HandlerType> handlerTypeList = handlerChainType.getHandler();
Iterator ht = handlerTypeList.iterator();
while (ht.hasNext()) {
+
+ HandlerType handlerType = (HandlerType)ht.next();
+
+ // TODO must do better job comparing the handlerType with the PortInfo param
+ // to see if the current iterator handler is intended for this service.
+
// TODO review: need to check for null getHandlerClass() return?
// or will schema not allow it?
- String portHandler = ((HandlerType)ht.next()).getHandlerClass().getValue();
- Handler handlerClass;
+ String portHandler = handlerType.getHandlerClass().getValue();
+ Handler handler;
// instantiate portHandler class
try {
- // TODO: ok to use system classloader?
- handlerClass = (Handler)loadClass(portHandler).newInstance();
- callHandlerPostConstruct(handlerClass.getClass());
+ // TODO: review: ok to use system classloader?
+ handler = (Handler) loadClass(portHandler).newInstance();
+ // TODO: must also do resource injection according to JAXWS 9.3.1
+ callHandlerPostConstruct(handler, endpointDesc.getServiceDescription());
} catch (ClassNotFoundException e) {
// TODO: should we just ignore this problem?
// TODO: NLS log and throw
@@ -131,35 +193,32 @@
}
// 9.2.1.2 sort them by Logical, then SOAP
- if (LogicalHandler.class.isAssignableFrom(handlerClass.getClass()))
- logicalHandlers.add((LogicalHandler)handlerClass);
- else if (SOAPHandler.class.isAssignableFrom(handlerClass.getClass()))
+ if (LogicalHandler.class.isAssignableFrom(handler.getClass()))
+ handlers.add((LogicalHandler) handler);
+ else if (SOAPHandler.class.isAssignableFrom(handler.getClass()))
// instanceof ProtocolHandler
- protocolHandlers.add((SOAPHandler)handlerClass);
- else if (Handler.class.isAssignableFrom(handlerClass.getClass())) {
+ handlers.add((SOAPHandler) handler);
+ else if (Handler.class.isAssignableFrom(handler.getClass())) {
// TODO: NLS better error message
throw ExceptionFactory.makeWebServiceException(Messages
- .getMessage("handlerChainErr1", handlerClass
- .getClass().getName()));
+ .getMessage("handlerChainErr1", handler
+ .getClass().getName()));
} else {
// TODO: NLS better error message
throw ExceptionFactory.makeWebServiceException(Messages
- .getMessage("handlerChainErr2", handlerClass
- .getClass().getName()));
+ .getMessage("handlerChainErr2", handler
+ .getClass().getName()));
}
}
}
- handlers.addAll(logicalHandlers);
- handlers.addAll(protocolHandlers);
return handlers;
}
private static Class loadClass(String clazz) throws ClassNotFoundException {
try {
- // TODO: review: necessary to use static method getSystemClassLoader in this class?
- return forName(clazz, true, ClassLoader.getSystemClassLoader());
+ return forName(clazz, true, getContextClassLoader());
} catch (ClassNotFoundException e) {
throw e;
}
@@ -194,14 +253,14 @@
/** @return ClassLoader */
- private static ClassLoader getSystemClassLoader() {
+ private static ClassLoader getContextClassLoader() {
// NOTE: This method must remain private because it uses AccessController
ClassLoader cl = null;
try {
cl = (ClassLoader)AccessController.doPrivileged(
new PrivilegedExceptionAction() {
public Object run() throws ClassNotFoundException {
- return ClassLoader.getSystemClassLoader();
+ return Thread.currentThread().getContextClassLoader();
}
}
);
@@ -209,24 +268,127 @@
if (log.isDebugEnabled()) {
log.debug("Exception thrown from AccessController: " + e);
}
- throw (RuntimeException)e.getException();
+ throw ExceptionFactory.makeWebServiceException(e.getException());
}
return cl;
}
-
- private static void callHandlerPostConstruct(Class handlerClass) {
- // TODO implement -- copy or make utils from ResourceInjectionServiceRuntimeDescriptionBuilder
+ private static void callHandlerPostConstruct(Handler handler, ServiceDescription serviceDesc) throws WebServiceException {
+ ResourceInjectionServiceRuntimeDescription resInj = ResourceInjectionServiceRuntimeDescriptionBuilder.create(serviceDesc, handler.getClass());
+ if (resInj != null) {
+ Method pcMethod = resInj.getPostConstructMethod();
+ if (pcMethod != null) {
+ if(log.isDebugEnabled()){
+ log.debug("Invoking Method with @PostConstruct annotation");
+ }
+ invokeMethod(handler, pcMethod, null);
+ if(log.isDebugEnabled()){
+ log.debug("Completed invoke on Method with @PostConstruct annotation");
+ }
+ }
+ }
}
/*
* Helper method to destroy all instantiated Handlers once the runtime
* is done with them.
- */
- public static void destroyHandlers(List<Handler> handlers) {
- // TODO implement -- copy or make utils from ResourceInjectionServiceRuntimeDescriptionBuilder
- // CALL the PreDestroy annotated method for each handler
+ */
+ private static void callHandlerPreDestroy(Handler handler, ServiceDescription serviceDesc) throws WebServiceException {
+ ResourceInjectionServiceRuntimeDescription resInj = ResourceInjectionServiceRuntimeDescriptionBuilder.create(serviceDesc, handler.getClass());
+ if (resInj != null) {
+ Method pcMethod = resInj.getPreDestroyMethod();
+ if (pcMethod != null) {
+ if(log.isDebugEnabled()){
+ log.debug("Invoking Method with @PostConstruct annotation");
+ }
+ invokeMethod(handler, pcMethod, null);
+ if(log.isDebugEnabled()){
+ log.debug("Completed invoke on Method with @PostConstruct annotation");
+ }
+ }
+ }
+ }
+
+ private static void invokeMethod(Handler handlerInstance, Method m, Object[] params) throws WebServiceException{
+ try{
+ m.invoke(handlerInstance, params);
+ }catch(InvocationTargetException e){
+ // TODO perhaps a "HandlerLifecycleException" would be better?
+ throw ExceptionFactory.makeWebServiceException(e);
+ }catch(IllegalAccessException e){
+ // TODO perhaps a "HandlerLifecycleException" would be better?
+ throw ExceptionFactory.makeWebServiceException(e);
+ }
+ }
+
+ private static boolean chainResolvesToPort(HandlerChainType handlerChainType, PortInfo portinfo) {
+
+ List<String> protocolBindings = handlerChainType.getProtocolBindings();
+ if (protocolBindings != null) {
+ boolean match = true;
+ for (Iterator<String> it = protocolBindings.iterator() ; it.hasNext();) {
+ match = false; // default to false in the protocol bindings until we find a match
+ String protocolBinding = it.next();
+ protocolBinding = protocolBinding.startsWith("##") ? protocolBindingsMap.get(protocolBinding) : protocolBinding;
+ // if the protocolBindingsMap returns null, it would mean someone has some nonsense ##binding
+ if ((protocolBinding != null) && (protocolBinding.equals(portinfo.getBindingID()))) {
+ match = true;
+ break;
+ }
+ }
+ if (match == false) {
+ // we've checked all the protocolBindings, but didn't find a match, no need to continue
+ return match;
+ }
+ }
+
+ /*
+ * need to figure out how to get the namespace declaration out of the port-name-pattern and service-name-pattern
+ */
+
+ if (!doesPatternMatch(portinfo.getPortName(), handlerChainType.getPortNamePattern())) {
+ // we've checked the port-name-pattern, and didn't find a match, no need to continue
+ return false;
+ }
+
+ if (!doesPatternMatch(portinfo.getServiceName(), handlerChainType.getServiceNamePattern())) {
+ // we've checked the service-name-pattern, and didn't find a match, no need to continue
+ return false;
+ }
+
+ return true;
+ }
+
+ /*
+ * A comparison routing to check service-name-pattern and port-name-pattern. These patterns may be of
+ * the form:
+ *
+ * 1) namespace:localpart
+ * 2) namespace:localpart*
+ * 3) namespace:* (not sure about this one)
+ * 4) * (which is equivalent to not specifying a pattern, therefore always matching)
+ *
+ * I've not seen any examples where the wildcard may be placed mid-string or on the namespace, such as:
+ *
+ * namespace:local*part
+ * *:localpart
+ *
+ */
+ private static boolean doesPatternMatch(QName portInfoQName, QName pattern) {
+ if (pattern == null)
+ return true;
+ String portInfoString = portInfoQName.toString();
+ String patternString = pattern.toString();
+ if (patternString.equals("*"))
+ return true;
+ if (patternString.contains("*")) {
+ patternString = patternString.substring(0, patternString.length() - 1);
+ return portInfoString.startsWith(patternString);
+ }
+ return portInfoString.equals(patternString);
+
}
+
}
Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/LogicalMessageContext.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/LogicalMessageContext.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/LogicalMessageContext.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/LogicalMessageContext.java Wed Apr 25 22:19:23 2007
@@ -19,6 +19,7 @@
package org.apache.axis2.jaxws.handler;
import org.apache.axis2.jaxws.core.MessageContext;
+import org.apache.axis2.jaxws.message.Message;
import javax.xml.ws.LogicalMessage;
@@ -29,6 +30,8 @@
public class LogicalMessageContext extends ProtectedMessageContext
implements javax.xml.ws.handler.LogicalMessageContext {
+ private LogicalMessage message;
+
public LogicalMessageContext() {
super();
}
@@ -38,10 +41,10 @@
}
public LogicalMessage getMessage() {
- return null;
- }
-
- public LogicalMessage getSource() {
- return null;
+ if (message == null) {
+ Message msg = getMessageObject();
+ message = new LogicalMessageImpl(msg);
+ }
+ return message;
}
}
Added: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/LogicalMessageImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/LogicalMessageImpl.java?view=auto&rev=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/LogicalMessageImpl.java (added)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/LogicalMessageImpl.java Wed Apr 25 22:19:23 2007
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.axis2.jaxws.handler;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.LogicalMessage;
+import javax.xml.ws.WebServiceException;
+
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.message.Block;
+import org.apache.axis2.jaxws.message.Message;
+import org.apache.axis2.jaxws.message.databinding.JAXBBlockContext;
+import org.apache.axis2.jaxws.message.factory.BlockFactory;
+import org.apache.axis2.jaxws.message.factory.JAXBBlockFactory;
+import org.apache.axis2.jaxws.message.factory.SourceBlockFactory;
+import org.apache.axis2.jaxws.registry.FactoryRegistry;
+
+public class LogicalMessageImpl implements LogicalMessage {
+
+ private Message message;
+
+ public LogicalMessageImpl(Message m) {
+ message = m;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see javax.xml.ws.LogicalMessage#getPayload()
+ */
+ public Source getPayload() {
+ BlockFactory factory = (SourceBlockFactory) FactoryRegistry.getFactory(SourceBlockFactory.class);
+ Source payload = (Source) _getPayload(null, factory);
+ return payload;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see javax.xml.ws.LogicalMessage#getPayload(javax.xml.bind.JAXBContext)
+ */
+ public Object getPayload(JAXBContext context) {
+ BlockFactory factory = (JAXBBlockFactory) FactoryRegistry.getFactory(JAXBBlockFactory.class);
+ JAXBBlockContext jbc = new JAXBBlockContext(context);
+ Object payload = _getPayload(jbc, factory);
+ return payload;
+ }
+
+ private Object _getPayload(Object context, BlockFactory factory) {
+ Object payload = null;
+ try {
+ Block block = message.getBodyBlock(context, factory);
+ Object content = block.getBusinessObject(true);
+
+ // For now, we have to create a new Block from the original content
+ // and set that back on the message. The Block is not currently
+ // able to create a copy of itself just yet.
+ Payloads payloads = createPayloads(content);
+
+ Block cacheBlock = factory.createFrom(payloads.CACHE_PAYLOAD, context, block.getQName());
+ message.setBodyBlock(cacheBlock);
+
+ payload = payloads.HANDLER_PAYLOAD;
+ } catch (XMLStreamException e) {
+ throw ExceptionFactory.makeWebServiceException(e);
+ }
+
+ return payload;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see javax.xml.ws.LogicalMessage#setPayload(java.lang.Object, javax.xml.bind.JAXBContext)
+ */
+ public void setPayload(Object obj, JAXBContext context) {
+ BlockFactory factory = (JAXBBlockFactory) FactoryRegistry.getFactory(JAXBBlockFactory.class);
+ JAXBBlockContext jbc = new JAXBBlockContext(context);
+ _setPayload(obj, jbc, factory);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see javax.xml.ws.LogicalMessage#setPayload(javax.xml.transform.Source)
+ */
+ public void setPayload(Source source) {
+ BlockFactory factory = (SourceBlockFactory) FactoryRegistry.getFactory(SourceBlockFactory.class);
+ _setPayload(source, null, factory);
+ }
+
+ private void _setPayload(Object object, Object context, BlockFactory factory) {
+ Block block = factory.createFrom(object, context, null);
+
+ if (message != null) {
+ message.setBodyBlock(block);
+ }
+ }
+
+ private Payloads createPayloads(Object content) {
+ if (content == null) {
+ return null;
+ }
+
+ Payloads payloads = new Payloads();
+
+ if (Source.class.isAssignableFrom(content.getClass())) {
+ try {
+ Transformer trans = TransformerFactory.newInstance().newTransformer();
+
+ // First we have to get the content out of the original
+ // Source object so we can build the cache from there.
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ StreamResult result = new StreamResult(baos);
+
+ Source source = (Source) content;
+ trans.transform(source, result);
+ trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ byte[] bytes = baos.toByteArray();
+
+ // Given that we've consumed the original Source object,
+ // we need to create another one with the original content
+ // and assign it back.
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+ payloads.HANDLER_PAYLOAD = new StreamSource(bais);
+
+ // We need a different byte[] for the cache so that we're not just
+ // building two Source objects that point to the same array.
+ byte[] cacheBytes = new byte[bytes.length];
+ System.arraycopy(bytes, 0, cacheBytes, 0, bytes.length);
+
+ // Now build the Soure object for the cache.
+ ByteArrayInputStream cacheBais = new ByteArrayInputStream(cacheBytes);
+ payloads.CACHE_PAYLOAD = new StreamSource(cacheBais);
+ } catch (TransformerConfigurationException e) {
+ throw ExceptionFactory.makeWebServiceException(e);
+ } catch (TransformerFactoryConfigurationError e) {
+ throw ExceptionFactory.makeWebServiceException(e);
+ } catch (TransformerException e) {
+ throw ExceptionFactory.makeWebServiceException(e);
+ }
+ } else {
+ // no cache implemented yet
+ payloads.HANDLER_PAYLOAD = content;
+ payloads.CACHE_PAYLOAD = content;
+ }
+
+ return payloads;
+ }
+
+ /*
+ * A simple holder for the different payload objects.
+ */
+ class Payloads {
+ Object HANDLER_PAYLOAD; // The payload object that will be returned to the handler
+ Object CACHE_PAYLOAD; // The payload object that will be used for the cache
+ }
+
+}
\ No newline at end of file
Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/SoapMessageContext.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/SoapMessageContext.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/SoapMessageContext.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/handler/SoapMessageContext.java Wed Apr 25 22:19:23 2007
@@ -56,7 +56,7 @@
return msg.getAsSOAPMessage();
}
- public Set<URI> getRoles() {
+ public Set<String> getRoles() {
return null;
}
Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitBareMethodMarshaller.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitBareMethodMarshaller.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitBareMethodMarshaller.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitBareMethodMarshaller.java Wed Apr 25 22:19:23 2007
@@ -30,12 +30,15 @@
import org.apache.axis2.jaxws.message.factory.MessageFactory;
import org.apache.axis2.jaxws.registry.FactoryRegistry;
import org.apache.axis2.jaxws.runtime.description.marshal.MarshalServiceRuntimeDescription;
+import org.apache.axis2.jaxws.utility.ConvertUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.xml.namespace.QName;
import javax.xml.ws.WebServiceException;
+import java.lang.reflect.Array;
import java.util.List;
+import java.util.ArrayList;
import java.util.TreeSet;
public class DocLitBareMethodMarshaller implements MethodMarshaller {
@@ -78,6 +81,7 @@
// Get the return value.
Class returnType = operationDesc.getResultActualType();
Object returnValue = null;
+ boolean hasReturnInBody = false;
if (returnType != void.class) {
// If the webresult is in the header, we need the name of the header so that we can find it.
Element returnElement = null;
@@ -85,21 +89,20 @@
returnElement =
MethodMarshallerUtils.getReturnElement(packages, message, null, true,
operationDesc.getResultTargetNamespace(),
- operationDesc.getResultName());
+ operationDesc.getResultName(),
+ MethodMarshallerUtils.numOutputBodyParams(pds) > 0);
+
} else {
returnElement = MethodMarshallerUtils
- .getReturnElement(packages, message, null, false, null, null);
+ .getReturnElement(packages, message, null, false, null, null,
+ MethodMarshallerUtils.numOutputBodyParams(pds) > 0);
+ hasReturnInBody = true;
}
- //TODO should we allow null if the return is a header?
- //Validate input parameters for operation and make sure no input parameters are null.
- //As per JAXWS Specification section 3.6.2.3 if a null value is passes as an argument
- //to a method then an implementation MUST throw WebServiceException.
returnValue = returnElement.getTypeValue();
- if (returnValue == null) {
- throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
- "NullParamErr1", "Return", operationDesc.getJavaMethodName(),
- "doc/lit"));
+ if (ConvertUtils.isConvertable(returnValue, returnType)) {
+ returnValue = ConvertUtils.convert(returnValue, returnType);
}
+
}
// Unmarshall the ParamValues from the Message
@@ -107,6 +110,7 @@
message,
packages,
false, // output
+ hasReturnInBody,
null); // always unmarshal with "by element" mode
// Populate the response Holders
@@ -148,26 +152,12 @@
message,
packages,
true, // input
+ false,
null); // always unmarshal using "by element" mode
// Build the signature arguments
Object[] sigArguments = MethodMarshallerUtils.createRequestSignatureArgs(pds, pvList);
- // TODO This needs more work. We need to check inside holders of input params. We also
- // may want to exclude header params from this check
- //Validate input parameters for operation and make sure no input parameters are null.
- //As per JAXWS Specification section 3.6.2.3 if a null value is passes as an argument
- //to a method then an implementation MUST throw WebServiceException.
- if (sigArguments != null) {
- for (Object argument : sigArguments) {
- if (argument == null) {
- throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
- "NullParamErr1", "Input", operationDesc.getJavaMethodName(),
- "doc/lit"));
-
- }
- }
- }
return sigArguments;
} catch (Exception e) {
throw ExceptionFactory.makeWebServiceException(e);
@@ -219,23 +209,28 @@
// Put the return object onto the message
Class returnType = operationDesc.getResultActualType();
if (returnType != void.class) {
- // TODO should we allow null if the return is a header?
- //Validate input parameters for operation and make sure no input parameters are null.
- //As per JAXWS Specification section 3.6.2.3 if a null value is passes as an argument
- //to a method then an implementation MUST throw WebServiceException.
- if (returnObject == null) {
- throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
- "NullParamErr1", "Return", operationDesc.getJavaMethodName(),
- "doc/lit"));
-
- }
Element returnElement = null;
QName returnQName = new QName(operationDesc.getResultTargetNamespace(),
operationDesc.getResultName());
if (marshalDesc.getAnnotationDesc(returnType).hasXmlRootElement()) {
returnElement = new Element(returnObject, returnQName);
} else {
- returnElement = new Element(returnObject, returnQName, returnType);
+ /* when a schema defines a SimpleType with xsd list jaxws tooling generates art-effects with array rather than a java.util.List
+ * However the ObjectFactory definition uses a List and thus marshalling fails. Lets convert the Arrays to List.
+ */
+ if(operationDesc.isListType()){
+ List list= new ArrayList();
+ if(returnType.isArray()){
+ for(int count = 0; count < Array.getLength(returnObject); count++){
+ Object obj = Array.get(returnObject, count);
+ list.add(obj);
+ }
+ returnElement = new Element(list, returnQName, List.class);
+ }
+ }
+ else{
+ returnElement = new Element(returnObject, returnQName, returnType);
+ }
}
MethodMarshallerUtils.toMessage(returnElement, returnType,
marshalDesc, m,
Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitBareMinimalMethodMarshaller.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitBareMinimalMethodMarshaller.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitBareMinimalMethodMarshaller.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitBareMinimalMethodMarshaller.java Wed Apr 25 22:19:23 2007
@@ -30,6 +30,7 @@
import org.apache.axis2.jaxws.message.factory.MessageFactory;
import org.apache.axis2.jaxws.registry.FactoryRegistry;
import org.apache.axis2.jaxws.runtime.description.marshal.MarshalServiceRuntimeDescription;
+import org.apache.axis2.jaxws.utility.ConvertUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -84,10 +85,11 @@
// Get the return value.
Class returnType = operationDesc.getResultActualType();
Object returnValue = null;
+ boolean hasReturnInBody = false;
if (returnType != void.class) {
// Use "byJavaType" unmarshalling if necessary
Class byJavaType = null;
- if (MethodMarshallerUtils.isJAXBBasicType(returnType)) {
+ if (MethodMarshallerUtils.isNotJAXBRootElement(returnType, marshalDesc)) {
byJavaType = returnType;
}
// If the webresult is in the header, we need the name of the header so that we can find it.
@@ -96,21 +98,23 @@
returnElement = MethodMarshallerUtils
.getReturnElement(packages, message, byJavaType, true,
operationDesc.getResultTargetNamespace(),
- operationDesc.getResultName());
+ operationDesc.getResultName(),
+ MethodMarshallerUtils.numOutputBodyParams(pds) > 0);
+
} else {
returnElement = MethodMarshallerUtils
- .getReturnElement(packages, message, byJavaType, false, null, null);
+ .getReturnElement(packages, message, byJavaType, false, null, null,
+ MethodMarshallerUtils.numOutputBodyParams(pds) > 0);
+ hasReturnInBody = true;
}
//TODO should we allow null if the return is a header?
//Validate input parameters for operation and make sure no input parameters are null.
//As per JAXWS Specification section 3.6.2.3 if a null value is passes as an argument
//to a method then an implementation MUST throw WebServiceException.
returnValue = returnElement.getTypeValue();
- if (returnValue == null) {
- throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
- "NullParamErr1", "Return", operationDesc.getJavaMethodName(),
- "doc/lit"));
- }
+ if (ConvertUtils.isConvertable(returnValue, returnType)) {
+ returnValue = ConvertUtils.convert(returnValue, returnType);
+ }
}
// We want to use "by Java Type" unmarshalling for
@@ -119,7 +123,7 @@
for (int i = 0; i < pds.length; i++) {
ParameterDescription pd = pds[i];
Class type = pd.getParameterActualType();
- if (MethodMarshallerUtils.isJAXBBasicType(type)) {
+ if (MethodMarshallerUtils.isNotJAXBRootElement(type, marshalDesc)) {
javaTypes[i] = type;
}
}
@@ -129,6 +133,7 @@
message,
packages,
false, // output
+ hasReturnInBody,
javaTypes); // byJavaType unmarshalling
// Populate the response Holders
@@ -171,15 +176,10 @@
for (int i = 0; i < pds.length; i++) {
ParameterDescription pd = pds[i];
Class type = pd.getParameterActualType();
- // If it is a JAXB basic type or it has no annotations
- if (MethodMarshallerUtils.isJAXBBasicType(type)) {
+ // If it is not a JAXB Root Element
+ if (MethodMarshallerUtils.isNotJAXBRootElement(type, marshalDesc)) {
javaTypes[i] = type;
- } else {
- Annotation annos[] = type.getAnnotations();
- if (annos == null || annos.length == 0) {
- javaTypes[i] = type;
- }
- }
+ }
}
// Unmarshal the ParamValues from the message
@@ -187,26 +187,11 @@
message,
packages,
true, // input
+ false,
javaTypes); // never unmarshal by type for doc/lit bare
// Build the signature arguments
Object[] sigArguments = MethodMarshallerUtils.createRequestSignatureArgs(pds, pvList);
-
- // TODO This needs more work. We need to check inside holders of input params. We also
- // may want to exclude header params from this check
- //Validate input parameters for operation and make sure no input parameters are null.
- //As per JAXWS Specification section 3.6.2.3 if a null value is passes as an argument
- //to a method then an implementation MUST throw WebServiceException.
- if (sigArguments != null) {
- for (Object argument : sigArguments) {
- if (argument == null) {
- throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
- "NullParamErr1", "Input", operationDesc.getJavaMethodName(),
- "doc/lit"));
-
- }
- }
- }
return sigArguments;
} catch (Exception e) {
throw ExceptionFactory.makeWebServiceException(e);
@@ -258,20 +243,10 @@
// Put the return object onto the message
Class returnType = operationDesc.getResultActualType();
if (returnType != void.class) {
- // TODO should we allow null if the return is a header?
- //Validate input parameters for operation and make sure no input parameters are null.
- //As per JAXWS Specification section 3.6.2.3 if a null value is passes as an argument
- //to a method then an implementation MUST throw WebServiceException.
- if (returnObject == null) {
- throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
- "NullParamErr1", "Return", operationDesc.getJavaMethodName(),
- "doc/lit"));
-
- }
// Use byJavaType marshalling if necessary
Class byJavaType = null;
- if (MethodMarshallerUtils.isJAXBBasicType(returnType)) {
+ if (MethodMarshallerUtils.isNotJAXBRootElement(returnType, marshalDesc)) {
byJavaType = returnType;
}
@@ -301,7 +276,7 @@
for (PDElement pde : pdeList) {
ParameterDescription pd = pde.getParam();
Class type = pd.getParameterActualType();
- if (MethodMarshallerUtils.isJAXBBasicType(type)) {
+ if (MethodMarshallerUtils.isNotJAXBRootElement(type, marshalDesc)) {
pde.setByJavaTypeClass(type);
}
}
@@ -343,27 +318,6 @@
MethodMarshallerUtils.getMarshalDesc(endpointDesc);
TreeSet<String> packages = marshalDesc.getPackages();
- // TODO This needs more work. We need to check inside holders of input params. We also
- // may want to exclude header params from this check
- //Validate input parameters for operation and make sure no input parameters are null.
- //As per JAXWS Specification section 3.6.2.3 if a null value is passes as an argument
- //to a method then an implementation MUST throw WebServiceException.
- if (pds.length > 0) {
- if (signatureArguments == null) {
- throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
- "NullParamErr1", "Input", operationDesc.getJavaMethodName(),
- "doc/lit"));
- }
- if (signatureArguments != null) {
- for (Object argument : signatureArguments) {
- if (argument == null) {
- throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
- "NullParamErr1", "Input", operationDesc.getJavaMethodName(),
- "doc/lit"));
- }
- }
- }
- }
// Create the message
MessageFactory mf = (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
Message m = mf.create(protocol);
@@ -382,7 +336,7 @@
for (PDElement pde : pdeList) {
ParameterDescription pd = pde.getParam();
Class type = pd.getParameterActualType();
- if (MethodMarshallerUtils.isJAXBBasicType(type)) {
+ if (MethodMarshallerUtils.isNotJAXBRootElement(type, marshalDesc)) {
pde.setByJavaTypeClass(type);
}
}
Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMethodMarshaller.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMethodMarshaller.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMethodMarshaller.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMethodMarshaller.java Wed Apr 25 22:19:23 2007
@@ -313,7 +313,7 @@
ParameterDescription[] pds = operationDesc.getParameterDescriptions();
// Create the message
- MessageFactory mf = (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
+ MessageFactory mf = marshalDesc.getMessageFactory();
Message m = mf.create(protocol);
// In usage=WRAPPED, there will be a single block in the body.
@@ -412,7 +412,7 @@
ParameterDescription[] pds = operationDesc.getParameterDescriptions();
// Create the message
- MessageFactory mf = (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
+ MessageFactory mf = marshalDesc.getMessageFactory();
Message m = mf.create(protocol);
// In usage=WRAPPED, there will be a single block in the body.
Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMinimalMethodMarshaller.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMinimalMethodMarshaller.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMinimalMethodMarshaller.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedMinimalMethodMarshaller.java Wed Apr 25 22:19:23 2007
@@ -193,6 +193,7 @@
message,
packages,
true, // input
+ false,
javaTypes); // sigh...unmarshal by type because there is no wrapper
// Build the signature arguments
@@ -379,6 +380,7 @@
// Get the return value.
Class returnType = operationDesc.getResultActualType();
Object returnValue = null;
+ boolean hasReturnInBody = false;
if (returnType != void.class) {
// If the webresult is in the header, we need the name of the header so that we can find it.
Element returnElement = null;
@@ -390,7 +392,9 @@
true, // is a header
operationDesc.getResultTargetNamespace(),
// header ns
- operationDesc.getResultPartName()); // header local part
+ operationDesc.getResultPartName(), // header local part
+ MethodMarshallerUtils.numOutputBodyParams(pds) > 0);
+
} else {
returnElement = MethodMarshallerUtils.getReturnElement(packages,
message,
@@ -398,7 +402,10 @@
// Force Unmarshal by type
false,
null,
- null);
+ null,
+ MethodMarshallerUtils.numOutputBodyParams(pds) > 0);
+ hasReturnInBody = true;
+
}
returnValue = returnElement.getTypeValue();
// TODO should we allow null if the return is a header?
@@ -426,6 +433,7 @@
message,
packages,
false, // output
+ hasReturnInBody,
javaTypes); // unmarshal by type
// TODO Should we check for null output body values? Should we check for null output header values ?
Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedPlusMethodMarshaller.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedPlusMethodMarshaller.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedPlusMethodMarshaller.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/DocLitWrappedPlusMethodMarshaller.java Wed Apr 25 22:19:23 2007
@@ -220,7 +220,7 @@
if (blkContext.getConstructionType() != JAXBUtils.CONSTRUCTION_TYPE
.BY_CONTEXT_PATH) {
Class actualType = pd.getParameterActualType();
- if (MethodMarshallerUtils.isJAXBBasicType(actualType)) {
+ if (MethodMarshallerUtils.isNotJAXBRootElement(actualType, marshalDesc)) {
blkContext.setProcessType(actualType);
}
}
@@ -249,7 +249,8 @@
Element returnElement =
MethodMarshallerUtils.getReturnElement(packages, message, null, true,
operationDesc.getResultTargetNamespace(),
- operationDesc.getResultPartName());
+ operationDesc.getResultPartName(),
+ false);
returnValue = returnElement.getTypeValue();
}
// returnValue may be incompatible with JAX-WS signature
@@ -372,7 +373,7 @@
if (blkContext.getConstructionType() != JAXBUtils.CONSTRUCTION_TYPE
.BY_CONTEXT_PATH) {
Class actualType = pd.getParameterActualType();
- if (MethodMarshallerUtils.isJAXBBasicType(actualType)) {
+ if (MethodMarshallerUtils.isNotJAXBRootElement(actualType, marshalDesc)) {
blkContext.setProcessType(actualType);
} else {
Annotation annos[] = actualType.getAnnotations();
@@ -504,7 +505,7 @@
}
Class byJavaType =
- MethodMarshallerUtils.isJAXBBasicType(returnType) ? returnType : null;
+ MethodMarshallerUtils.isNotJAXBRootElement(returnType, marshalDesc) ? returnType : null;
MethodMarshallerUtils.toMessage(returnElement, returnType,
marshalDesc, m,
@@ -543,7 +544,7 @@
// Use "by java type" marshalling if necessary
for (PDElement pde : headerPDEList) {
Class actualType = pde.getParam().getParameterActualType();
- if (MethodMarshallerUtils.isJAXBBasicType(actualType)) {
+ if (MethodMarshallerUtils.isNotJAXBRootElement(actualType, marshalDesc)) {
pde.setByJavaTypeClass(actualType);
}
}
@@ -658,7 +659,7 @@
// Use "by java type" marshalling if necessary
for (PDElement pde : headerPDEList) {
Class actualType = pde.getParam().getParameterActualType();
- if (MethodMarshallerUtils.isJAXBBasicType(actualType)) {
+ if (MethodMarshallerUtils.isNotJAXBRootElement(actualType, marshalDesc)) {
pde.setByJavaTypeClass(actualType);
}
}
Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/MethodMarshallerUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/MethodMarshallerUtils.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/MethodMarshallerUtils.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/MethodMarshallerUtils.java Wed Apr 25 22:19:23 2007
@@ -33,9 +33,11 @@
import org.apache.axis2.jaxws.message.XMLFaultReason;
import org.apache.axis2.jaxws.message.databinding.JAXBBlockContext;
import org.apache.axis2.jaxws.message.databinding.JAXBUtils;
+import org.apache.axis2.jaxws.message.databinding.XSDListUtils;
import org.apache.axis2.jaxws.message.factory.JAXBBlockFactory;
import org.apache.axis2.jaxws.message.util.XMLFaultUtils;
import org.apache.axis2.jaxws.registry.FactoryRegistry;
+import org.apache.axis2.jaxws.runtime.description.marshal.AnnotationDesc;
import org.apache.axis2.jaxws.runtime.description.marshal.FaultBeanDesc;
import org.apache.axis2.jaxws.runtime.description.marshal.MarshalServiceRuntimeDescription;
import org.apache.axis2.jaxws.runtime.description.marshal.MarshalServiceRuntimeDescriptionFactory;
@@ -57,6 +59,7 @@
import javax.xml.ws.ProtocolException;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.soap.SOAPFaultException;
+import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -65,7 +68,9 @@
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Calendar;
+import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
@@ -146,7 +151,24 @@
// Create an Element rendering
Element element = null;
if (!marshalDesc.getAnnotationDesc(formalType).hasXmlRootElement()) {
- element = new Element(value, qName, formalType);
+ /* when a schema defines a SimpleType with xsd list jaxws tooling generates art-effects with array rather than a java.util.List
+ * However the ObjectFactory definition uses a List and thus marshalling fails. Lets convert the Arrays to List and recreate
+ * the JAXBElements for the same.
+ */
+ if(pd.isListType()){
+
+ List<Object> list= new ArrayList<Object>();
+ if(formalType.isArray()){
+ for(int count = 0; count < Array.getLength(value); count++){
+ Object obj = Array.get(value, count);
+ list.add(obj);
+ }
+ element = new Element(list, qName, List.class);
+ }
+ }
+ else{
+ element = new Element(value, qName, formalType);
+ }
} else {
element = new Element(value, qName);
}
@@ -162,20 +184,21 @@
/**
* Return the list of PDElements that is unmarshalled from the wire
- *
- * @param params ParameterDescription for this operation
- * @param message Message
- * @param packages set of packages needed to unmarshal objects for this operation
- * @param isInput indicates if input or output params (input on server, output on
- * client)
- * @param unmarshalByJavaType in most scenarios this is null. Only use this in the scenarios
- * that require unmarshalling by java type
+ *
+ * @param params ParameterDescription for this operation
+ * @param message Message
+ * @param packages set of packages needed to unmarshal objects for this operation
+ * @param isInput indicates if input or output params (input on server, output on client)
+ * @param hasReturnInBody if isInput=false, then this parameter indicates whether a
+ * return value is expected in the body.
+ * @param unmarshalByJavaType in most scenarios this is null. Only use this in the scenarios that require unmarshalling by java type
* @return ParamValues
*/
static List<PDElement> getPDElements(ParameterDescription[] params,
Message message,
TreeSet<String> packages,
boolean isInput,
+ boolean hasReturnInBody,
Class[] unmarshalByJavaType) throws XMLStreamException {
List<PDElement> pdeList = new ArrayList<PDElement>();
@@ -194,7 +217,11 @@
}
}
- int index = 0;
+ if (!isInput && hasReturnInBody) {
+ totalBodyBlocks++;
+ }
+
+ int index = (!isInput && hasReturnInBody) ? 1 : 0;
for (int i = 0; i < params.length; i++) {
ParameterDescription pd = params[i];
@@ -409,7 +436,7 @@
block);
} else {
// Body block
- if (totalBodyBlocks <= 1) {
+ if (totalBodyBlocks < 1) {
// If there is only one block, use the following "more performant" method
message.setBodyBlock(block);
} else {
@@ -469,6 +496,7 @@
* @param isHeader
* @param headerNS (only needed if isHeader)
* @param headerLocalPart (only needed if isHeader)
+ * @param hasOutputBodyParams (true if the method has out or inout params other than the return value)
* @return Element
* @throws WebService
* @throws XMLStreamException
@@ -478,7 +506,9 @@
Class unmarshalByJavaTypeClass, // normally null
boolean isHeader,
String headerNS,
- String headerLocalPart)
+ String headerLocalPart,
+ boolean hasOutputBodyParams)
+
throws WebServiceException, XMLStreamException {
// The return object is the first block in the body
@@ -490,7 +520,13 @@
if (isHeader) {
block = message.getHeaderBlock(headerNS, headerLocalPart, context, factory);
} else {
- block = message.getBodyBlock(context, factory);
+ if (hasOutputBodyParams) {
+ block = message.getBodyBlock(0, context, factory);
+ } else {
+ // If there is only 1 block, we can use the get body block method
+ // that streams the whole block content.
+ block = message.getBodyBlock(context, factory);
+ }
}
// Get the business object. We want to return the object that represents the type.
@@ -517,6 +553,7 @@
log.debug("Marshal Throwable =" + throwable.getClass().getName());
log.debug(" rootCause =" + t.getClass().getName());
log.debug(" exception=" + t.toString());
+ log.debug(" stack=" + stackToString(t));
}
XMLFault xmlfault = null;
@@ -570,7 +607,7 @@
if (faultBeanObject == t ||
(context.getConstructionType() != JAXBUtils.CONSTRUCTION_TYPE
.BY_CONTEXT_PATH &&
- isJAXBBasicType(faultBeanObject.getClass()))) {
+ isNotJAXBRootElement(faultBeanObject.getClass(), marshalDesc))) {
context.setProcessType(faultBeanObject.getClass());
}
@@ -789,7 +826,7 @@
// Use "by java type" marshalling if necessary
if (blockContext.getConstructionType() != JAXBUtils.CONSTRUCTION_TYPE.BY_CONTEXT_PATH &&
- isJAXBBasicType(faultBeanFormalClass)) {
+ isNotJAXBRootElement(faultBeanFormalClass, marshalDesc)) {
blockContext.setProcessType(faultBeanFormalClass);
}
@@ -823,6 +860,25 @@
return exception;
}
+
+ /**
+ * @param pds
+ * @return Number of inout or out parameters
+ */
+ static int numOutputBodyParams(ParameterDescription[] pds) {
+ int count = 0;
+ for (int i=0; i<pds.length; i++) {
+ // TODO Need to change this to also detect not attachment
+ if (!pds[i].isHeader()) {
+ if (pds[i].getMode() == Mode.INOUT ||
+ pds[i].getMode() == Mode.OUT) {
+ count++;
+ }
+ }
+ }
+ return count;
+ }
+
/**
* @param value
@@ -854,8 +910,7 @@
static <T> Holder<T> createHolder(Class paramType, T value)
throws IllegalAccessException, InstantiationException, ClassNotFoundException {
if (Holder.class.isAssignableFrom(paramType)) {
- Class holderClazz = loadClass(paramType.getName());
- Holder<T> holder = (Holder<T>)holderClazz.newInstance();
+ Holder holder = (Holder) paramType.newInstance();
holder.value = value;
return holder;
}
@@ -1037,11 +1092,11 @@
* This probably should be available from the ParameterDescription
*
* @param cls
+ * @param marshalDesc
* @return true if primitive, wrapper, java.lang.String. Calendar (or GregorianCalendar),
* BigInteger etc or anything other java type that is mapped by the basic schema types
*/
- static boolean isJAXBBasicType(Class cls) {
- // TODO : Others ? Look at default JAXBContext
+ static boolean isNotJAXBRootElement(Class cls, MarshalServiceRuntimeDescription marshalDesc) {
if (cls == String.class ||
cls.isPrimitive() ||
cls == Calendar.class ||
@@ -1053,8 +1108,25 @@
return true;
}
- return false;
-
-
+ AnnotationDesc aDesc = marshalDesc.getAnnotationDesc(cls);
+ if (aDesc != null) {
+ // XmlRootElementName returns null if @XmlRootElement is not specified
+ return (aDesc.getXmlRootElementName() == null);
+ }
+ return true;
+ }
+
+ /**
+ * Get a string containing the stack of the specified exception
+ * @param e
+ * @return
+ */
+ public static String stackToString(Throwable e) {
+ java.io.StringWriter sw= new java.io.StringWriter();
+ java.io.BufferedWriter bw = new java.io.BufferedWriter(sw);
+ java.io.PrintWriter pw= new java.io.PrintWriter(bw);
+ e.printStackTrace(pw);
+ pw.close();
+ return sw.getBuffer().toString();
}
}
Modified: webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/RPCLitMethodMarshaller.java
URL: http://svn.apache.org/viewvc/webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/RPCLitMethodMarshaller.java?view=diff&rev=532615&r1=532614&r2=532615
==============================================================================
--- webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/RPCLitMethodMarshaller.java (original)
+++ webservices/axis2/branches/java/1_2/modules/jaxws/src/org/apache/axis2/jaxws/marshaller/impl/alt/RPCLitMethodMarshaller.java Wed Apr 25 22:19:23 2007
@@ -131,7 +131,7 @@
ParameterDescription pd = pde.getParam();
Class type = pd.getParameterActualType();
if (!pd.isHeader() ||
- MethodMarshallerUtils.isJAXBBasicType(type)) {
+ MethodMarshallerUtils.isNotJAXBRootElement(type, marshalDesc)) {
pde.setByJavaTypeClass(type);
}
}
@@ -188,7 +188,7 @@
ParameterDescription pd = pds[i];
Class type = pd.getParameterActualType();
if (!pd.isHeader() ||
- MethodMarshallerUtils.isJAXBBasicType(type)) {
+ MethodMarshallerUtils.isNotJAXBRootElement(type, marshalDesc)) {
javaTypes[i] = type;
}
}
@@ -198,6 +198,7 @@
message,
packages,
true, // input
+ false,
javaTypes); // unmarshal by type
// Build the signature arguments
@@ -316,7 +317,7 @@
// Use marshalling by java type if necessary
Class byJavaType = null;
if (!operationDesc.isResultHeader() ||
- MethodMarshallerUtils.isJAXBBasicType(returnType)) {
+ MethodMarshallerUtils.isNotJAXBRootElement(returnType, marshalDesc)) {
byJavaType = returnType;
}
MethodMarshallerUtils.toMessage(returnElement,
@@ -342,7 +343,7 @@
ParameterDescription pd = pde.getParam();
Class type = pd.getParameterActualType();
if (!pd.isHeader() ||
- MethodMarshallerUtils.isJAXBBasicType(type)) {
+ MethodMarshallerUtils.isNotJAXBRootElement(type, marshalDesc)) {
pde.setByJavaTypeClass(type);
}
}
@@ -397,23 +398,28 @@
// Get the return value.
Class returnType = operationDesc.getResultActualType();
Object returnValue = null;
+ boolean hasReturnInBody = false;
if (returnType != void.class) {
// If the webresult is in the header, we need the name of the header so that we can find it.
Element returnElement = null;
// Use "byJavaType" unmarshalling if necessary
Class byJavaType = null;
if (!operationDesc.isResultHeader() ||
- MethodMarshallerUtils.isJAXBBasicType(returnType)) {
+ MethodMarshallerUtils.isNotJAXBRootElement(returnType, marshalDesc)) {
byJavaType = returnType;
}
if (operationDesc.isResultHeader()) {
returnElement = MethodMarshallerUtils
.getReturnElement(packages, message, byJavaType, true,
operationDesc.getResultTargetNamespace(),
- operationDesc.getResultPartName());
+ operationDesc.getResultPartName(),
+ MethodMarshallerUtils.numOutputBodyParams(pds) > 0);
+
} else {
returnElement = MethodMarshallerUtils
- .getReturnElement(packages, message, byJavaType, false, null, null);
+ .getReturnElement(packages, message, byJavaType, false, null, null,
+ MethodMarshallerUtils.numOutputBodyParams(pds) > 0);
+ hasReturnInBody = true;
}
returnValue = returnElement.getTypeValue();
// TODO should we allow null if the return is a header?
@@ -434,7 +440,7 @@
ParameterDescription pd = pds[i];
Class type = pd.getParameterActualType();
if (!pd.isHeader() ||
- MethodMarshallerUtils.isJAXBBasicType(type)) {
+ MethodMarshallerUtils.isNotJAXBRootElement(type, marshalDesc)) {
javaTypes[i] = type;
}
}
@@ -444,6 +450,7 @@
message,
packages,
false, // output
+ hasReturnInBody,
javaTypes); // unmarshal by type
// TODO Should we check for null output body values? Should we check for null output header values ?
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org