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 pr...@apache.org on 2007/11/19 14:12:21 UTC

svn commit: r596288 - in /webservices/axis2/trunk/java/modules: jaxws/src/org/apache/axis2/jaxws/handler/ jaxws/src/org/apache/axis2/jaxws/spi/handler/ jaxws/test-resources/configuration/ jaxws/test-resources/configuration/handlers/ jaxws/test/org/apac...

Author: pradine
Date: Mon Nov 19 05:12:20 2007
New Revision: 596288

URL: http://svn.apache.org/viewvc?rev=596288&view=rev
Log:
Refactor code to provide a second HandlerResolver implementation that does not depend on the annotations provided by the JAX-WS metadata hierarchy to configure it.

Added:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/BaseHandlerResolver.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/HandlerResolverImpl.java
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/LifecycleManager.java
    webservices/axis2/trunk/java/modules/jaxws/test-resources/configuration/
    webservices/axis2/trunk/java/modules/jaxws/test-resources/configuration/handlers/
    webservices/axis2/trunk/java/modules/jaxws/test-resources/configuration/handlers/handler.xml
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/DummyLogicalHandler.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/DummySOAPHandler.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/HandlerResolverTests.java
Modified:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerResolverImpl.java
    webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/DescriptionUtils.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointDescriptionImpl.java
    webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerResolverImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerResolverImpl.java?rev=596288&r1=596287&r2=596288&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerResolverImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/handler/HandlerResolverImpl.java Mon Nov 19 05:12:20 2007
@@ -18,8 +18,6 @@
  */
 package org.apache.axis2.jaxws.handler;
 
-import org.apache.axis2.client.OperationClient;
-import org.apache.axis2.java.security.AccessController;
 import org.apache.axis2.jaxws.ExceptionFactory;
 import org.apache.axis2.jaxws.core.MessageContext;
 import org.apache.axis2.jaxws.description.EndpointDescription;
@@ -31,28 +29,21 @@
 import org.apache.axis2.jaxws.handler.lifecycle.factory.HandlerLifecycleManagerFactory;
 import org.apache.axis2.jaxws.i18n.Messages;
 import org.apache.axis2.jaxws.registry.FactoryRegistry;
-import org.apache.axis2.jaxws.runtime.description.injection.ResourceInjectionServiceRuntimeDescription;
-import org.apache.axis2.jaxws.runtime.description.injection.impl.ResourceInjectionServiceRuntimeDescriptionBuilder;
+import org.apache.axis2.jaxws.spi.handler.BaseHandlerResolver;
+import org.apache.axis2.util.LoggingControl;
 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;
 import javax.xml.ws.handler.LogicalHandler;
 import javax.xml.ws.handler.PortInfo;
 import javax.xml.ws.handler.soap.SOAPHandler;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
+
 /* 
  * This class should be created by the ServiceDelegate.
  * HandlerResolverImpl.getHandlerChain(PortInfo) will be called by the
@@ -63,17 +54,8 @@
  * starting each Handler's lifecycle according to JAX-WS spec 9.3.1
  */
 
-public class HandlerResolverImpl implements HandlerResolver {
+public class HandlerResolverImpl extends BaseHandlerResolver {
 
-    // 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
@@ -91,7 +73,7 @@
         this.serviceDesc = sd;
     }
 
-    public ArrayList<Handler> getHandlerChain(PortInfo portinfo) {
+    public List<Handler> getHandlerChain(PortInfo portinfo) {
         // TODO:  would check and/or build cache here if implemented later
         return resolveHandlers(portinfo);
     }
@@ -154,7 +136,7 @@
          * with the PortInfo object before we add it to the chain.
          */
         
-        HandlerChainsType handlerCT = serviceDesc.getHandlerChain();  
+        handlerChainsType = serviceDesc.getHandlerChain();  
         // if there's a handlerChain on the serviceDesc, it means the WSDL defined an import for a HandlerChain.
         // the spec indicates that if a handlerchain also appears on the SEI on the client.
         EndpointDescription ed = null;
@@ -164,12 +146,12 @@
         
         if (ed != null) {
             HandlerChainsType handlerCT_fromEndpointDesc = ed.getHandlerChain();
-            if (handlerCT == null) {
-                handlerCT = handlerCT_fromEndpointDesc;
+            if (handlerChainsType == null) {
+                handlerChainsType = handlerCT_fromEndpointDesc;
             } 
         }
 
-        Iterator it = handlerCT == null ? null : handlerCT.getHandlerChain().iterator();
+        Iterator it = handlerChainsType == null ? null : handlerChainsType.getHandlerChain().iterator();
 
         while ((it != null) && (it.hasNext())) {
             HandlerChainType handlerChainType = ((HandlerChainType)it.next());
@@ -205,6 +187,11 @@
                     // TODO: NLS log and throw
                     throw ExceptionFactory.makeWebServiceException(e);
                 }
+                
+                //TODO NLS
+                if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled())
+                    log.debug("Successfully instantiated the class: " + handler.getClass());
+                
                 // 9.2.1.2 sort them by Logical, then SOAP
                 if (LogicalHandler.class.isAssignableFrom(handler.getClass()))
                     handlers.add((LogicalHandler) handler);
@@ -233,143 +220,4 @@
                 .getFactory(HandlerLifecycleManagerFactory.class);
         return elmf.createHandlerLifecycleManager();
     }
-    
-    private static Class loadClass(String clazz) throws ClassNotFoundException {
-        try {
-            return forName(clazz, true, getContextClassLoader());
-        } catch (ClassNotFoundException e) {
-            throw e;
-        }
-    }
-
-    /**
-     * Return the class for this name
-     *
-     * @return Class
-     */
-    private static Class forName(final String className, final boolean initialize,
-                                 final ClassLoader classLoader) throws ClassNotFoundException {
-        // NOTE: This method must remain protected because it uses AccessController
-        Class cl = null;
-        try {
-            cl = (Class)AccessController.doPrivileged(
-                    new PrivilegedExceptionAction() {
-                        public Object run() throws ClassNotFoundException {
-                        	try{
-                        		if (log.isDebugEnabled()) {
-        	                        log.debug("HandlerResolverImpl attempting to load Class: "+className);
-        	                    }
-                        		return Class.forName(className, initialize, classLoader);
-                        	} catch (Throwable e) {
-        	                    // TODO Should the exception be swallowed ?
-        	                    if (log.isDebugEnabled()) {
-        	                        log.debug("HandlerResolverImpl cannot load the following class Throwable Exception Occured: " + className);
-        	                    }
-        	                    throw new ClassNotFoundException("HandlerResolverImpl cannot load the following class Throwable Exception Occured:" + className);
-        	                }
-                        }
-                    }
-            );
-        } catch (PrivilegedActionException e) {
-            if (log.isDebugEnabled()) {
-                log.debug("Exception thrown from AccessController: " + e);
-            }
-            throw (ClassNotFoundException)e.getException();
-        }
-
-        return cl;
-    }
-
-
-    /** @return ClassLoader */
-    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 Thread.currentThread().getContextClassLoader();
-                        }
-                    }
-            );
-        } catch (PrivilegedActionException e) {
-            if (log.isDebugEnabled()) {
-                log.debug("Exception thrown from AccessController: " + e);
-            }
-            throw ExceptionFactory.makeWebServiceException(e.getException());
-        }
-
-        return cl;
-    }
-
-   
-    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);
-        
-    }
-    
 }

Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/BaseHandlerResolver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/BaseHandlerResolver.java?rev=596288&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/BaseHandlerResolver.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/BaseHandlerResolver.java Mon Nov 19 05:12:20 2007
@@ -0,0 +1,215 @@
+/*
+ * 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.spi.handler;
+
+import java.io.InputStream;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.handler.HandlerResolver;
+import javax.xml.ws.handler.PortInfo;
+
+import org.apache.axis2.java.security.AccessController;
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.description.impl.DescriptionUtils;
+import org.apache.axis2.jaxws.description.xml.handler.HandlerChainType;
+import org.apache.axis2.jaxws.description.xml.handler.HandlerChainsType;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This class can be subclassed to produce different implementations of {@link HandlerResolver}
+ *
+ */
+public abstract class BaseHandlerResolver implements HandlerResolver {
+
+    private static Log log = LogFactory.getLog(BaseHandlerResolver.class);
+
+    // TODO should probably use constants defined elsewhere
+    protected static final Map<String, String> protocolBindingsMap =
+        new HashMap<String, String>(5);
+
+    protected HandlerChainsType handlerChainsType;
+    
+    protected BaseHandlerResolver() {
+    }
+    
+    protected BaseHandlerResolver(String file) {
+        ClassLoader classLoader = this.getClass().getClassLoader();
+        String className = this.getClass().getName();
+        InputStream is =
+            DescriptionUtils.openHandlerConfigStream(file, className, classLoader);
+        
+        if(is == null) {
+            log.warn("Unable to load handlers from file: " + file);                    
+        } else {
+            handlerChainsType = DescriptionUtils.loadHandlerChains(is, classLoader);
+        }
+    }
+    
+    protected static boolean chainResolvesToPort(HandlerChainType hct, PortInfo portinfo) {
+        
+        List<String> protocolBindings = hct.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(), hct.getPortNamePattern())) {
+                // we've checked the port-name-pattern, and didn't find a match, no need to continue
+                return false;
+        }
+        
+        if (!doesPatternMatch(portinfo.getServiceName(), hct.getServiceNamePattern())) {
+                // we've checked the service-name-pattern, and didn't find a match, no need to continue
+                return false;
+        }
+
+        return true;
+    }
+    
+    protected static Class loadClass(String clazz) throws ClassNotFoundException {
+        try {
+            return forName(clazz, true, getContextClassLoader());
+        } catch (ClassNotFoundException e) {
+            throw e;
+        }
+    }
+    
+    /*
+     * 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);
+        
+    }
+
+    /**
+     * Return the class for this name
+     *
+     * @return Class
+     */
+    private static Class forName(final String className, final boolean initialize,
+                                 final ClassLoader classLoader) throws ClassNotFoundException {
+        // NOTE: This method must remain protected because it uses AccessController
+        Class cl = null;
+        try {
+            cl = (Class)AccessController.doPrivileged(
+                    new PrivilegedExceptionAction() {
+                        public Object run() throws ClassNotFoundException {
+                            try{
+                                if (log.isDebugEnabled()) {
+                                    log.debug("HandlerResolverImpl attempting to load Class: "+className);
+                                }
+                                return Class.forName(className, initialize, classLoader);
+                            } catch (Throwable e) {
+                                // TODO Should the exception be swallowed ?
+                                if (log.isDebugEnabled()) {
+                                    log.debug("HandlerResolverImpl cannot load the following class Throwable Exception Occured: " + className);
+                                }
+                                throw new ClassNotFoundException("HandlerResolverImpl cannot load the following class Throwable Exception Occured:" + className);
+                            }
+                        }
+                    }
+            );
+        } catch (PrivilegedActionException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("Exception thrown from AccessController: " + e);
+            }
+            throw (ClassNotFoundException)e.getException();
+        }
+
+        return cl;
+    }
+
+
+    /** @return ClassLoader */
+    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 Thread.currentThread().getContextClassLoader();
+                        }
+                    }
+            );
+        } catch (PrivilegedActionException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("Exception thrown from AccessController: " + e);
+            }
+            throw ExceptionFactory.makeWebServiceException(e.getException());
+        }
+
+        return cl;
+    }
+    
+    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");
+    }
+}

Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/HandlerResolverImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/HandlerResolverImpl.java?rev=596288&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/HandlerResolverImpl.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/HandlerResolverImpl.java Mon Nov 19 05:12:20 2007
@@ -0,0 +1,170 @@
+/*
+ * 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.spi.handler;
+
+import java.io.File;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.ws.handler.Handler;
+import javax.xml.ws.handler.HandlerResolver;
+import javax.xml.ws.handler.LogicalHandler;
+import javax.xml.ws.handler.PortInfo;
+import javax.xml.ws.handler.soap.SOAPHandler;
+
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.description.xml.handler.HandlerChainType;
+import org.apache.axis2.jaxws.description.xml.handler.HandlerType;
+import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.jaxws.lifecycle.LifecycleException;
+import org.apache.axis2.util.LoggingControl;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This is an implementation of {@link HandlerResolver} that can be used with a JAX-WS client
+ * to set the handler list.
+ *
+ * @see javax.xml.ws.Service#setHandlerResolver(HandlerResolver)
+ */
+public class HandlerResolverImpl extends BaseHandlerResolver {
+
+    private static Log log = LogFactory.getLog(HandlerResolverImpl.class);
+
+    /**
+     * Constructor
+     * 
+     * @param filePath the path to the handler configuration file in URI format
+     */
+    public HandlerResolverImpl(String filePath) {
+        super(filePath);
+    }
+    
+    /**
+     * Constructor
+     * 
+     * @param fileURI the <code>URI</code> of the handler configuration file
+     */
+    public HandlerResolverImpl(URI fileURI) {
+        this(fileURI.toString());
+    }
+    
+    /**
+     * Constructor
+     * 
+     * @param file the handler configuration file
+     */
+    public HandlerResolverImpl(File file) {
+        this(file.toURI());
+    }
+    
+    /*
+     *  (non-Javadoc)
+     * @see javax.xml.ws.handler.HandlerResolver#getHandlerChain(javax.xml.ws.handler.PortInfo)
+     */
+    public List<Handler> getHandlerChain(PortInfo portinfo) {
+        ArrayList<Handler> handlers = new ArrayList<Handler>();
+        Iterator it = handlerChainsType == null ? null : handlerChainsType.getHandlerChain().iterator();
+
+        while ((it != null) && (it.hasNext())) {
+            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.getHandlerClass().getValue();
+                Handler handler = null;
+                    
+                //  instantiate portHandler class 
+                try {
+                    handler = createHandlerInstance(loadClass(portHandler));
+                } catch (Exception e) {
+                    // TODO: should we just ignore this problem?
+                    // TODO: NLS log and throw
+                    throw ExceptionFactory.makeWebServiceException(e);
+                }
+                
+                //TODO NLS
+                if (LoggingControl.debugLoggingAllowed && log.isDebugEnabled())
+                    log.debug("Successfully instantiated the class: " + handler.getClass());
+                
+                // 9.2.1.2 sort them by Logical, then SOAP
+                if (LogicalHandler.class.isAssignableFrom(handler.getClass()))
+                    handlers.add((LogicalHandler) handler);
+                else if (SOAPHandler.class.isAssignableFrom(handler.getClass()))
+                    // instanceof ProtocolHandler
+                    handlers.add((SOAPHandler) handler);
+                else if (Handler.class.isAssignableFrom(handler.getClass())) {
+                    // TODO: NLS better error message
+                    throw ExceptionFactory.makeWebServiceException(Messages
+                            .getMessage("handlerChainErr1", handler
+                                    .getClass().getName()));
+                } else {
+                    // TODO: NLS better error message
+                    throw ExceptionFactory.makeWebServiceException(Messages
+                            .getMessage("handlerChainErr2", handler
+                                    .getClass().getName()));
+                }
+            }
+        }
+
+        return handlers;
+    }
+    
+    //Create an instance of the handler class and perform appropriate lifecycle activities
+    //to it.
+    private Handler createHandlerInstance(Class handlerClass) throws LifecycleException {
+        //TODO NLS
+        if (handlerClass == null) {
+            throw ExceptionFactory.makeWebServiceException("Handler class must be passed");
+        }
+        
+        //Resource injection not supported.
+        
+        Object object = null;
+        
+        try {
+            object = handlerClass.newInstance();
+        } catch (InstantiationException e) {
+            throw ExceptionFactory.makeWebServiceException(e);
+        } catch (IllegalAccessException e) {
+            throw ExceptionFactory.makeWebServiceException(e);
+        }
+                
+        //Invoke PostConstruct
+        LifecycleManager manager = new LifecycleManager(object);
+        manager.invokePostConstruct();
+        
+        return (Handler) object;
+    }
+}

Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/LifecycleManager.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/LifecycleManager.java?rev=596288&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/LifecycleManager.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/LifecycleManager.java Mon Nov 19 05:12:20 2007
@@ -0,0 +1,106 @@
+/*
+ * 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.spi.handler;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Method;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+import org.apache.axis2.java.security.AccessController;
+import org.apache.axis2.jaxws.lifecycle.BaseLifecycleManager;
+
+public class LifecycleManager extends BaseLifecycleManager {
+
+    public LifecycleManager(Object instance) {
+        this.instance = instance;
+    }
+
+    protected Method getPostConstructMethod() {
+        if (instance != null) {
+            List<Method> methods = getMethods(instance.getClass());
+            for (Method method : methods) {
+                if (getAnnotation(method,PostConstruct.class) != null) {
+                    return method;
+                }
+            }
+        }
+        return null;
+    }
+
+    protected Method getPreDestroyMethod() {
+        if (instance != null) {
+            List<Method> methods = getMethods(instance.getClass());
+            for (Method method : methods) {
+                if (getAnnotation(method,PreDestroy.class) != null) {
+                    return method;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Gets all of the methods in this class and the super classes
+     *
+     * @param beanClass
+     * @return
+     */
+    private List<Method> getMethods(final Class beanClass) {
+        // This class must remain private due to Java 2 Security concerns
+        List<Method> methods;
+        methods = (List<Method>)AccessController.doPrivileged(
+                new PrivilegedAction() {
+                    public Object run() {
+                        List<Method> methods = new ArrayList<Method>();
+                        Class cls = beanClass;
+                        while (cls != null) {
+                            Method[] methodArray = cls.getDeclaredMethods();
+                            for (Method method : methodArray) {
+                                methods.add(method);
+                            }
+                            cls = cls.getSuperclass();
+                        }
+                        return methods;
+                    }
+                }
+        );
+
+        return methods;
+    }
+    
+    /**
+     * Get an annotation.  This is wrappered to avoid a Java2Security violation.
+     * @param cls Class that contains annotation 
+     * @param annotation Class of requrested Annotation
+     * @return annotation or null
+     */
+    private static Annotation getAnnotation(final AnnotatedElement element, final Class annotation) {
+        return (Annotation) AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run() {
+                return element.getAnnotation(annotation);
+            }
+        });
+    }
+}

Added: webservices/axis2/trunk/java/modules/jaxws/test-resources/configuration/handlers/handler.xml
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test-resources/configuration/handlers/handler.xml?rev=596288&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test-resources/configuration/handlers/handler.xml (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test-resources/configuration/handlers/handler.xml Mon Nov 19 05:12:20 2007
@@ -0,0 +1,28 @@
+<!--
+  ~ 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.
+  -->
+<jws:handler-chains xmlns:jws="http://java.sun.com/xml/ns/javaee">
+  <jws:handler-chain>
+    <jws:handler>
+      <jws:handler-class>org.apache.axis2.jaxws.spi.handler.DummySOAPHandler</jws:handler-class>
+    </jws:handler>
+    <jws:handler>
+      <jws:handler-class>org.apache.axis2.jaxws.spi.handler.DummyLogicalHandler</jws:handler-class>
+    </jws:handler>
+  </jws:handler-chain>
+</jws:handler-chains>
\ No newline at end of file

Modified: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java?rev=596288&r1=596287&r2=596288&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/framework/JAXWSTest.java Mon Nov 19 05:12:20 2007
@@ -89,6 +89,7 @@
 import org.apache.axis2.jaxws.sample.WrapTests;
 import org.apache.axis2.jaxws.security.BasicAuthSecurityTests;
 import org.apache.axis2.jaxws.spi.BindingProviderTests;
+import org.apache.axis2.jaxws.spi.handler.HandlerResolverTests;
 import org.apache.axis2.jaxws.wsdl.schemareader.SchemaReaderTests;
 import org.apache.axis2.jaxws.xmlhttp.clientTests.dispatch.datasource.DispatchXMessageDataSource;
 import org.apache.axis2.jaxws.xmlhttp.clientTests.dispatch.jaxb.DispatchXPayloadJAXB;
@@ -146,6 +147,7 @@
         suite.addTestSuite(LogicalMessageContextTests.class);
         suite.addTestSuite(CompositeMessageContextTests.class);
         suite.addTestSuite(HandlerChainProcessorTests.class);
+        suite.addTestSuite(HandlerResolverTests.class);
         
         // ------ Message Tests ------
         suite.addTestSuite(JaxwsMessageBundleTests.class);

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/DummyLogicalHandler.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/DummyLogicalHandler.java?rev=596288&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/DummyLogicalHandler.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/DummyLogicalHandler.java Mon Nov 19 05:12:20 2007
@@ -0,0 +1,37 @@
+/*
+ * 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.spi.handler;
+
+import javax.xml.ws.handler.LogicalHandler;
+import javax.xml.ws.handler.LogicalMessageContext;
+import javax.xml.ws.handler.MessageContext;
+
+public class DummyLogicalHandler implements LogicalHandler<LogicalMessageContext> {
+
+	public boolean handleMessage(LogicalMessageContext context) {
+		return true;
+	}
+
+	public boolean handleFault(LogicalMessageContext messagecontext) {
+		return false;
+	}
+
+	public void close(MessageContext messagecontext){
+	}
+}

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/DummySOAPHandler.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/DummySOAPHandler.java?rev=596288&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/DummySOAPHandler.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/DummySOAPHandler.java Mon Nov 19 05:12:20 2007
@@ -0,0 +1,43 @@
+/*
+ * 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.spi.handler;
+
+import java.util.Set;
+
+import javax.xml.ws.handler.MessageContext;
+import javax.xml.ws.handler.soap.SOAPHandler;
+import javax.xml.ws.handler.soap.SOAPMessageContext;
+
+public class DummySOAPHandler implements SOAPHandler<SOAPMessageContext> {
+
+	public Set getHeaders() {
+		return null;
+	}
+
+	public boolean handleMessage(SOAPMessageContext context) {
+		return true;
+	}
+
+	public boolean handleFault(SOAPMessageContext messagecontext) {
+		return false;
+	}
+
+	public void close(MessageContext messagecontext){
+	}
+}

Added: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/HandlerResolverTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/HandlerResolverTests.java?rev=596288&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/HandlerResolverTests.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/spi/handler/HandlerResolverTests.java Mon Nov 19 05:12:20 2007
@@ -0,0 +1,58 @@
+/*
+ * 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.spi.handler;
+
+import java.io.File;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.handler.Handler;
+import javax.xml.ws.handler.HandlerResolver;
+import javax.xml.ws.handler.PortInfo;
+import javax.xml.ws.soap.SOAPBinding;
+
+import junit.framework.TestCase;
+
+public class HandlerResolverTests extends TestCase {
+    private String testResourceDir = System.getProperty("basedir", ".") + "/" + "test-resources";
+
+    public void testHandlerResolver() {
+        String path = "/configuration/handlers/handler.xml";
+        File file = new File(testResourceDir, path);
+        HandlerResolver resolver = new HandlerResolverImpl(file);
+        PortInfo pi = new DummyPortInfo();
+        List<Handler> list = resolver.getHandlerChain(pi);
+        assertEquals(2, list.size());
+    }
+    
+    public class DummyPortInfo implements PortInfo {
+
+        public String getBindingID() {
+            return SOAPBinding.SOAP11HTTP_BINDING;
+        }
+
+        public QName getPortName() {
+            return new QName("http://www.apache.org/test/namespace", "DummyPort");
+        }
+
+        public QName getServiceName() {
+            return new QName("http://www.apache.org/test/namespace", "DummyService");
+        }
+    }
+}

Modified: webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/DescriptionUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/DescriptionUtils.java?rev=596288&r1=596287&r2=596288&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/DescriptionUtils.java (original)
+++ webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/DescriptionUtils.java Mon Nov 19 05:12:20 2007
@@ -364,12 +364,11 @@
         }
     }
     
-    public static HandlerChainsType loadHandlerChains(InputStream is) {
+    public static HandlerChainsType loadHandlerChains(InputStream is, ClassLoader classLoader) {
         try {
             // All the classes we need should be part of this package
             JAXBContext jc = JAXBContext
-                    .newInstance("org.apache.axis2.jaxws.description.xml.handler",
-                                 EndpointDescriptionImpl.class.getClassLoader());
+                    .newInstance("org.apache.axis2.jaxws.description.xml.handler", classLoader);
 
             Unmarshaller u = jc.createUnmarshaller();
 
@@ -379,7 +378,7 @@
         } catch (Exception e) {
             throw ExceptionFactory
                     .makeWebServiceException(
-                            "EndpointDescriptionImpl: loadHandlerList: thrown when attempting to unmarshall JAXB content");
+                            "DescriptionUtils: loadHandlerList: thrown when attempting to unmarshall JAXB content");
         }       
     }
     

Modified: webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointDescriptionImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointDescriptionImpl.java?rev=596288&r1=596287&r2=596288&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointDescriptionImpl.java (original)
+++ webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/EndpointDescriptionImpl.java Mon Nov 19 05:12:20 2007
@@ -1304,7 +1304,8 @@
                 if(is == null) {
                     log.warn("Unable to load handlers from file: " + handlerFileName);                    
                 } else {
-                    handlerChainsType = DescriptionUtils.loadHandlerChains(is);
+                    handlerChainsType =
+                        DescriptionUtils.loadHandlerChains(is, this.getClass().getClassLoader());
                 }
             }
             else if(handlerChainSource != null) {
@@ -1312,7 +1313,8 @@
             	if(log.isDebugEnabled()) {
             		log.debug("Loading handlers from provided source");
             	}
-            	handlerChainsType = DescriptionUtils.loadHandlerChains(handlerChainSource);
+            	handlerChainsType = DescriptionUtils.loadHandlerChains(handlerChainSource,
+                                                          this.getClass().getClassLoader());
             }
         }
         return handlerChainsType;

Modified: webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java?rev=596288&r1=596287&r2=596288&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java (original)
+++ webservices/axis2/trunk/java/modules/metadata/src/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java Mon Nov 19 05:12:20 2007
@@ -1402,20 +1402,12 @@
                                                                  className,
                                                                  classLoader);
 
-                try {
-
-                    // All the classes we need should be part of this package
-                    JAXBContext jc =
-                            JAXBContext.newInstance("org.apache.axis2.jaxws.description.xml.handler",
-                                                    this.getClass().getClassLoader());
-
-                    Unmarshaller u = jc.createUnmarshaller();
-
-                    JAXBElement<?> o = (JAXBElement<?>) u.unmarshal(is);
-                    handlerChainsType = (HandlerChainsType) o.getValue();
-
-                } catch (Exception e) {
-                    throw ExceptionFactory.makeWebServiceException(Messages.getMessage("handlerChainErr"),e);
+                if(is == null) {
+                    log.warn("Unable to load handlers from file: " + handlerFileName);
+                }
+                else {
+                    handlerChainsType =
+                        DescriptionUtils.loadHandlerChains(is, this.getClass().getClassLoader());
                 }
             }
         }



---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org