geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From xuhaih...@apache.org
Subject svn commit: r1150977 [5/5] - in /geronimo/bundles/trunk/axis2: ./ src/main/java/org/apache/axis2/handlers/ src/main/java/org/apache/axis2/handlers/addressing/ src/main/java/org/apache/axis2/jaxws/ src/main/java/org/apache/axis2/jaxws/addressing/factory...
Date Tue, 26 Jul 2011 03:06:02 GMT
Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/description/impl/ServiceDescriptionImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/server/endpoint/EndpointImpl.java
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/server/endpoint/EndpointImpl.java?rev=1150977&view=auto
==============================================================================
--- geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/server/endpoint/EndpointImpl.java (added)
+++ geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/server/endpoint/EndpointImpl.java Tue Jul 26 03:06:00 2011
@@ -0,0 +1,322 @@
+/*
+ * 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.server.endpoint;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.engine.AxisConfiguration;
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.addressing.util.EndpointReferenceUtils;
+import org.apache.axis2.jaxws.binding.BindingUtils;
+import org.apache.axis2.jaxws.description.DescriptionFactory;
+import org.apache.axis2.jaxws.description.EndpointDescription;
+import org.apache.axis2.jaxws.description.ServiceDescription;
+import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.transport.http.HTTPWorkerFactory;
+import org.apache.axis2.transport.http.server.SimpleHttpServer;
+import org.apache.axis2.transport.http.server.WorkerFactory;
+import org.w3c.dom.Element;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.Source;
+import javax.xml.ws.Binding;
+import javax.xml.ws.EndpointReference;
+import javax.xml.ws.EndpointContext;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.wsaddressing.W3CEndpointReference;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+public class EndpointImpl extends javax.xml.ws.Endpoint {
+
+    private boolean published;
+    private Object implementor;
+    private EndpointDescription endpointDesc;
+    private Binding binding;
+    private SimpleHttpServer server;
+    private List<Source> metadata;
+    private Map<String, Object> properties;
+    private Executor executor;
+    private EndpointContext endpointCntx;
+
+    public EndpointImpl(Object o) {
+        implementor = o;
+        initialize();
+    }
+
+    public EndpointImpl(Object o, Binding bnd, EndpointDescription ed) {
+        implementor = o;
+        endpointDesc = ed;
+        initialize();
+    }
+
+    private void initialize() {
+        if (implementor == null) {
+        	
+            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("initErr"));
+        }
+        
+        // If we don't have the necessary metadata, let's go ahead and
+        // create it.
+        if (endpointDesc == null) {        
+            ServiceDescription sd = DescriptionFactory.createServiceDescription(implementor.getClass());
+            endpointDesc = sd.getEndpointDescriptions_AsCollection().iterator().next();
+        }
+        
+        if (endpointDesc != null && binding == null) {
+            binding = BindingUtils.createBinding(endpointDesc);
+        }
+        
+        published = false;
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.Endpoint#getMetadata()
+    */
+    public List<Source> getMetadata() {
+        return this.metadata;
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.Endpoint#setMetadata(java.util.List)
+    */
+    public void setMetadata(List<Source> list) {
+        this.metadata = list;
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.Endpoint#getProperties()
+    */
+    public Map<String, Object> getProperties() {
+        return this.properties;
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.Endpoint#setProperties(java.util.Map)
+    */
+    public void setProperties(Map<String, Object> properties) {
+        this.properties = properties;
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.Endpoint#getBinding()
+    */
+    public Binding getBinding() {
+        return binding;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.xml.ws.Endpoint#getExecutor()
+     */
+    public Executor getExecutor() {
+        return this.executor;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.xml.ws.Endpoint#getImplementor()
+     */
+    public Object getImplementor() {
+        return implementor;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.xml.ws.Endpoint#setEndpointContext(javax.xml.ws.EndpointContext)
+     */
+    public void setEndpointContext(EndpointContext ctxt) {
+         this.endpointCntx = ctxt;
+     }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.xml.ws.Endpoint#isPublished()
+     */
+    public boolean isPublished() {
+        return published;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.xml.ws.Endpoint#publish(java.lang.Object)
+     */
+    public void publish(Object obj) {
+        if (isPublishDisabled()) {
+            throw new UnsupportedOperationException("Endpoint publish not allowed in managed environment");
+        }
+
+    }
+
+    /**
+     * Answer if the Endpoint.publish methods have been disabled.  Per JSR-109 Section 5.3.3, the use of 
+     * Endpoint.publish in a managed environment is non portable, and a managed environment may choose
+     * to disable dynamic publishing of endpoints.  The default is that publishing is NOT disabled, unless
+     * the property is set to true.  
+     * @return true if publishing of enpdoints is disabled, false otherwise.  False is the default.
+     */
+    private boolean isPublishDisabled() {
+        boolean publishDisabled = false;
+        if (endpointDesc != null) {
+            ConfigurationContext cfgCtx = endpointDesc.getServiceDescription().getAxisConfigContext();
+            AxisConfiguration axisConfig = cfgCtx.getAxisConfiguration();
+            Parameter parameter = axisConfig.getParameter(org.apache.axis2.jaxws.Constants.DISABLE_ENDPOINT_PUBLISH_METHODS);
+            String flagValue = null;
+            if (parameter != null) {
+                flagValue = (String) parameter.getValue();
+            }
+    
+            if (flagValue != null) {
+                if ("false".equalsIgnoreCase(flagValue)) {
+                    publishDisabled = false;
+                } else if ("true".equalsIgnoreCase(flagValue)) {
+                    publishDisabled = true;
+                }
+            }
+        }
+        return publishDisabled;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.xml.ws.Endpoint#publish(java.lang.String)
+     */
+    public void publish(String s) {
+        if (isPublishDisabled()) {
+            throw new UnsupportedOperationException("Endpoint publish not allowed in managed environment");
+        }
+        int port = -1;
+        String address = s;
+        try {
+            URI uri = new URI(s);
+            port = uri.getPort();
+        } catch (URISyntaxException e) {
+        }
+        // Default to 8080
+        if(port == -1){
+            port = 8080;
+            address = s + ":" + port;
+        }
+        ConfigurationContext ctx = endpointDesc.getServiceDescription().getAxisConfigContext();
+        if (endpointDesc.getEndpointAddress() == null)
+            endpointDesc.setEndpointAddress(address);
+        
+        try {
+            // For some reason the AxisService has not been added to the ConfigurationContext
+            // at this point, so we need to do it for the service to be available.
+            AxisService svc = endpointDesc.getAxisService();
+            ctx.getAxisConfiguration().addService(svc);
+        } catch (AxisFault e) {
+            throw ExceptionFactory.makeWebServiceException(e);
+        }        
+
+        // Remove the default "axis2" context root.
+        ctx.setContextRoot("/");
+                    
+        WorkerFactory wf = new HTTPWorkerFactory();
+
+        try {
+            server = new SimpleHttpServer(ctx, wf, port);
+            server.init();            
+            server.start();
+        } catch (IOException e) {
+            throw ExceptionFactory.makeWebServiceException(e);
+        }
+
+        published = true;      
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.xml.ws.Endpoint#setExecutor(java.util.concurrent.Executor)
+     */
+    public void setExecutor(Executor executor) {
+        this.executor = executor;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.xml.ws.Endpoint#stop()
+     */
+    public void stop() {
+        try {
+            if(server != null) {
+                server.destroy();
+            }
+        } catch (Exception e) {
+            throw ExceptionFactory.makeWebServiceException(e);
+        }
+    }
+
+    @Override
+    public <T extends EndpointReference> T getEndpointReference(Class<T> clazz, Element... referenceParameters) {
+        if (!isPublished()) {
+            throw new WebServiceException("Endpoint is not published");
+        }
+        
+        if (!BindingUtils.isSOAPBinding(binding.getBindingID())) {
+            throw new UnsupportedOperationException("This method is unsupported for the binding: " + binding.getBindingID());
+        }
+        
+        EndpointReference jaxwsEPR = null;
+        String addressingNamespace = EndpointReferenceUtils.getAddressingNamespace(clazz);
+        String address = endpointDesc.getEndpointAddress();
+        QName serviceName = endpointDesc.getServiceQName();
+        QName portName = endpointDesc.getPortQName();
+
+        String wsdlLocation = null;
+        if (metadata != null) {
+            Source wsdlSource = metadata.get(0);
+            if (wsdlSource != null) {   
+                wsdlLocation = wsdlSource.getSystemId();
+            }
+        }
+        
+        org.apache.axis2.addressing.EndpointReference axis2EPR =
+        	EndpointReferenceUtils.createAxis2EndpointReference(address, serviceName, portName, wsdlLocation, addressingNamespace);
+        
+        try {
+            EndpointReferenceUtils.addReferenceParameters(axis2EPR, referenceParameters);
+            jaxwsEPR = EndpointReferenceUtils.convertFromAxis2(axis2EPR, addressingNamespace);
+        }
+        catch (Exception e) {
+            throw ExceptionFactory.
+              makeWebServiceException(Messages.getMessage("endpointRefCreationError"), e);
+        }
+
+        return clazz.cast(jaxwsEPR);
+    }
+
+    @Override
+    public EndpointReference getEndpointReference(Element... referenceParameters) {
+        return getEndpointReference(W3CEndpointReference.class, referenceParameters);
+    }
+}

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/server/endpoint/EndpointImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/server/endpoint/EndpointImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/server/endpoint/EndpointImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/spi/ServiceDelegate.java
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/spi/ServiceDelegate.java?rev=1150977&view=auto
==============================================================================
--- geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/spi/ServiceDelegate.java (added)
+++ geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/spi/ServiceDelegate.java Tue Jul 26 03:06:00 2011
@@ -0,0 +1,1022 @@
+/*
+ * 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;
+
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Proxy;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Iterator;
+import java.util.concurrent.Executor;
+
+import javax.activation.DataSource;
+import javax.xml.bind.JAXBContext;
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.transform.Source;
+import javax.xml.ws.Dispatch;
+import javax.xml.ws.EndpointReference;
+import javax.xml.ws.Service;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.WebServiceFeature;
+import javax.xml.ws.Service.Mode;
+import javax.xml.ws.handler.HandlerResolver;
+
+import org.apache.axiom.om.OMElement;
+import org.apache.axis2.client.ServiceClient;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.java.security.AccessController;
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.addressing.util.EndpointReferenceUtils;
+import org.apache.axis2.jaxws.client.PropertyMigrator;
+import org.apache.axis2.jaxws.client.dispatch.JAXBDispatch;
+import org.apache.axis2.jaxws.client.dispatch.XMLDispatch;
+import org.apache.axis2.jaxws.client.proxy.JAXWSProxyHandler;
+import org.apache.axis2.jaxws.context.listener.ProviderOMContextListener;
+import org.apache.axis2.jaxws.description.DescriptionFactory;
+import org.apache.axis2.jaxws.description.EndpointDescription;
+import org.apache.axis2.jaxws.description.ServiceDescription;
+import org.apache.axis2.jaxws.description.ServiceDescriptionWSDL;
+import org.apache.axis2.jaxws.description.builder.DescriptionBuilderComposite;
+import org.apache.axis2.jaxws.handler.HandlerResolverImpl;
+import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.jaxws.registry.FactoryRegistry;
+import org.apache.axis2.jaxws.spi.migrator.ApplicationContextMigratorUtil;
+import org.apache.axis2.jaxws.util.WSDLWrapper;
+import org.apache.axis2.jaxws.utility.ExecutorFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * The ServiceDelegate serves as the backing implementation for all of the methods in the {@link
+ * javax.xml.ws.Service} API.  This is the plug point for the client implementation.
+ */
+public class ServiceDelegate extends javax.xml.ws.spi.ServiceDelegate {
+    private static final Log log = LogFactory.getLog(ServiceDelegate.class);
+    private static ThreadLocal<DescriptionBuilderComposite> sparseServiceCompositeThreadLocal = new ThreadLocal<DescriptionBuilderComposite>();
+    private static ThreadLocal<DescriptionBuilderComposite> sparsePortCompositeThreadLocal = new ThreadLocal<DescriptionBuilderComposite>();
+    
+    private Executor executor;
+
+    private ServiceDescription serviceDescription;
+    private QName serviceQname;
+    private ServiceClient serviceClient = null;
+
+    private HandlerResolver handlerResolver = null;
+    
+    /**
+     * NON-STANDARD SPI! Set any metadata to be used on the creation of the NEXT Service by this thread.
+     * NOTE that this uses ThreadLocal to store the metadata, and that ThreadLocal is cleared after it is
+     * used to create a Service.  That means:
+     * 1) The thread that sets the metadata to use MUST be the thread that creates the Service
+     * 2) Creation of the Service should be the very next thing the thread does
+     * 3) The metadata will be set to null when the Service is created, so to create another 
+     *    service with the same metadata, it will need to be set again prior to creating the
+     *    service
+     * 4) The metadata can be set prior to creating both generic Service and generated Service 
+     *    instances.      
+     * 
+     * This allows creating a generic Service (javax.xml.ws.Service) or a generated Service
+     * (subclass of javax.xml.ws.Service) specifying additional metadata via a
+     * sparse composite.  This can be used by a runtime to create a Service for a requester using
+     * additional metadata such as might come from a deployment descriptor or from resource
+     * injection processing of @Resource or @WebServiceRef(s) annotations.  Additional metadata
+     * may include things like @WebServiceClient.wsdlLocation or a @HandlerChain specification.
+     * 
+     *    @see javax.xml.ws.Service#create(QName)
+     *    @see javax.xml.ws.Service#create(URL, QName)
+     * 
+     * @param composite Additional metadata (if any) to be used in creation of the service
+     */
+    static public void setServiceMetadata(DescriptionBuilderComposite composite) {
+        sparseServiceCompositeThreadLocal.set(composite);
+    }
+    
+    /**
+     * NON-STANDARD SPI! Returns the composite that will be used on the creation of the next 
+     * Service by this thread.
+     * 
+     * @see #setServiceMetadata(DescriptionBuilderComposite)
+     * 
+     * @return composite that will be used on the creation of the next Service by this thread, or null
+     *         if no composite is to be used.
+     */
+    static DescriptionBuilderComposite getServiceMetadata() {
+        return sparseServiceCompositeThreadLocal.get();
+    }
+    
+    /**
+     * Remove any composite so that creation of the next Service by this thread will NOT be 
+     * affected by any additional metadata.
+     * 
+     * @see #setServiceMetadata(DescriptionBuilderComposite)
+     * 
+     */
+    static void resetServiceMetadata() {
+        sparseServiceCompositeThreadLocal.set(null);
+    }
+    
+    /**
+     * NON-STANDARD SPI! Set any metadata to be used on the creation of the NEXT Port by this thread.
+     * NOTE that this uses ThreadLocal to store the metadata, and that ThreadLocal is cleared after it is
+     * used to create a Port.  That means:
+     * 1) The thread that sets the metadata to use MUST be the thread that creates the Port
+     * 2) Creation of the Port should be the very next thing the thread does
+     * 3) The metadata will be set to null when the Port is created, so to create another 
+     *    Port with the same metadata, it will need to be set again prior to creating the
+     *    Port
+     * 4) The metadata can be set prior to creating Port which specifies a QName via 
+     *    Service.getPort(QName, Class) or one that only specifies the SEI class via 
+     *    Service.getPort(Class)
+     * 5) Metadata can not be specified for dynamic ports, i.e. those added via 
+     *    Service.addPort(...).
+     * 6) Metadata can not be specfied when creating a dispatch client, i.e. via 
+     *    Service.createDispatch(...)
+     * 7) The Service used to create the port can be the generic service or a generated 
+     *    service.      
+     * 
+     * This allows creating Port specifying additional metadata via a sparse composite.  
+     * This can be used by a runtime to create a Port for a requester using
+     * additional metadata such as might come from a deployment descriptor or from resource
+     * injection processing.  Additional metadata might include things like 
+     * a @HandlerChain specification.
+     * 
+     *    @see javax.xml.ws.Service#getPort(Class)
+     *    @see javax.xml.ws.Service#getPort(QName, Class)
+     * 
+     * @param composite Additional metadata (if any) to be used in creation of the port
+     */
+    static public void setPortMetadata(DescriptionBuilderComposite composite) {
+        sparsePortCompositeThreadLocal.set(composite);
+    }
+
+    /**
+     * NON-STANDARD SPI! Returns the composite that will be used on the creation of the next 
+     * Port by this thread.
+     * 
+     * @see #setPortMetadata(DescriptionBuilderComposite)
+     * 
+     * @return composite that will be used on the creation of the next Port by this thread, or null
+     *         if no composite is to be used.
+     */
+    static DescriptionBuilderComposite getPortMetadata() {
+        return sparsePortCompositeThreadLocal.get();
+    }
+    
+    /**
+     * Remove any composite so that creation of the next Port by this thread will NOT be 
+     * affected by any additional metadata.
+     * 
+     * @see #setPortMetadata(DescriptionBuilderComposite)
+     * 
+     */
+    static void resetPortMetadata() {
+       sparsePortCompositeThreadLocal.set(null);
+    }
+    
+    public ServiceDelegate(URL url, QName qname, Class clazz, WebServiceFeature... features) throws WebServiceException {
+        super();
+        this.serviceQname = qname;
+
+        if (!isValidServiceName()) {
+            throw ExceptionFactory
+                    .makeWebServiceException(Messages.getMessage("serviceDelegateConstruct0", ""));
+        }
+        
+        if ((features != null) && (features.length != 0)) {
+          throw ExceptionFactory
+                  .makeWebServiceException(Messages.getMessage("serviceDelegateConstruct2", serviceQname.toString()));
+        }
+        
+        // Get any metadata that is to be used to build up this service, then reset it so it isn't used
+        // to create any other services.
+        DescriptionBuilderComposite sparseComposite = getServiceMetadata();
+        resetServiceMetadata();
+        if (sparseComposite != null) {
+            serviceDescription = DescriptionFactory.createServiceDescription(url, serviceQname, clazz, sparseComposite, this);
+        } else {
+            serviceDescription = DescriptionFactory.createServiceDescription(url, serviceQname, clazz);
+        }
+        // TODO: This check should be done when the Service Description is created above; that should throw this exception.
+        // That is because we (following the behavior of the RI) require the WSDL be fully specified (not partial) on the client
+        if (isValidWSDLLocation()) {
+            if (!isServiceDefined(serviceQname)) {
+                throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
+                        "serviceDelegateConstruct0", serviceQname.toString(), url.toString()));
+            }
+        }
+        
+        //TODO: Is this the best place for this code?
+        ConfigurationContext context = serviceDescription.getAxisConfigContext();
+
+        // Register the necessary ApplicationContextMigrators
+        ApplicationContextMigratorUtil.addApplicationContextMigrator(context,
+                Constants.APPLICATION_CONTEXT_MIGRATOR_LIST_ID, new PropertyMigrator());
+    }
+    
+    //================================================
+    // JAX-WS API methods
+    //================================================
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.spi.ServiceDelegate#addPort(javax.xml.namespace.QName, java.lang.String, java.lang.String)
+    */
+    // Creates a DISPATCH ONLY port.  Per JAXWS Sec 4.1 javax.xm..ws.Service, p. 49, ports added via addPort method
+    // are only suitibale for creating Distpach instances.
+    public void addPort(QName portName, String bindingId, String endpointAddress)
+            throws WebServiceException {
+        verifyServiceDescriptionActive();
+        if (log.isDebugEnabled()) {
+            log.debug("Calling addPort : ("
+                      + portName + "," + bindingId + "," + endpointAddress + ")");
+        }
+    	if(endpointAddress!=null && endpointAddress.trim().length()==0){
+    		ExceptionFactory.makeWebServiceException(Messages.getMessage("addPortErr1", (portName!=null)?portName.getLocalPart():"", endpointAddress));
+    	}
+        EndpointDescription endpointDesc =
+                DescriptionFactory.updateEndpoint(serviceDescription, null, portName,
+                                                  DescriptionFactory.UpdateType.ADD_PORT, this, bindingId, endpointAddress);
+        // TODO: Need to set endpointAddress and set or check bindingId on the EndpointDesc
+        endpointDesc.setEndpointAddress(endpointAddress);
+        endpointDesc.setClientBindingID(bindingId);
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.spi.ServiceDelegate#createDispatch(javax.xml.namespace.QName, java.lang.Class, javax.xml.ws.Service.Mode)
+    */
+    public <T> Dispatch<T> createDispatch(QName portName, Class<T> type, Mode mode)
+            throws WebServiceException {
+        return createDispatch(portName, type, mode, (WebServiceFeature[]) null);
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.spi.ServiceDelegate#createDispatch(javax.xml.namespace.QName, javax.xml.bind.JAXBContext, javax.xml.ws.Service.Mode)
+    */
+    public Dispatch<java.lang.Object> createDispatch(QName portName, JAXBContext context, Mode mode) {
+        return createDispatch(portName, context, mode, (WebServiceFeature[]) null);
+    }
+
+    @Override
+    public <T> Dispatch<T> createDispatch(EndpointReference jaxwsEPR, Class<T> type, Mode mode, WebServiceFeature... features) {
+        if (log.isDebugEnabled()) {
+            log.debug("Create Dispatch with epr: " + jaxwsEPR);
+        }
+        
+        verifyServiceDescriptionActive();
+        if (jaxwsEPR == null) {
+            throw ExceptionFactory
+                    .makeWebServiceException(Messages.getMessage("dispatchNoEndpointReference"));
+        }
+        
+        if (!isValidDispatchType(type)) {
+            throw ExceptionFactory
+                    .makeWebServiceException(Messages.getMessage("dispatchInvalidType"));
+        }
+        
+        if (!isValidDispatchTypeWithMode(type, mode)) {
+            throw ExceptionFactory
+                    .makeWebServiceException(Messages.getMessage("dispatchInvalidTypeWithMode"));
+        }
+        
+        org.apache.axis2.addressing.EndpointReference axis2EPR =
+            EndpointReferenceUtils.createAxis2EndpointReference("");
+        String addressingNamespace = null;
+        
+        try {
+            addressingNamespace = EndpointReferenceUtils.convertToAxis2(axis2EPR, jaxwsEPR);
+        }
+        catch (Exception e) {
+            throw ExceptionFactory.
+               makeWebServiceException(Messages.getMessage("invalidEndpointReference", 
+                                                           e.toString()));
+        }
+        
+        EndpointDescription endpointDesc =
+                DescriptionFactory.updateEndpoint(serviceDescription, null, axis2EPR,
+                                                  addressingNamespace,
+                                                  DescriptionFactory.UpdateType.CREATE_DISPATCH,
+                                                  this);
+        if (endpointDesc == null) {
+            throw ExceptionFactory.makeWebServiceException(
+                   Messages.getMessage("endpointDescriptionConstructionFailure", 
+                    jaxwsEPR.toString())); 
+        }
+
+        XMLDispatch<T> dispatch = new XMLDispatch<T>(this, endpointDesc, axis2EPR, addressingNamespace, features);
+
+        if (mode != null) {
+            dispatch.setMode(mode);
+        } else {
+            dispatch.setMode(Service.Mode.PAYLOAD);
+        }
+
+        if (serviceClient == null)
+            serviceClient = getServiceClient(endpointDesc.getPortQName());
+        
+        if(type == OMElement.class) {
+            if (log.isDebugEnabled()) {
+                log.debug("This a Dispatch<OMElement>. The custom builder is installed.");
+            }
+            ProviderOMContextListener.create(serviceClient.getServiceContext());
+        }
+
+        dispatch.setServiceClient(serviceClient);
+        dispatch.setType(type);
+        return dispatch;
+    }
+
+    @Override
+    public Dispatch<Object> createDispatch(EndpointReference jaxwsEPR, JAXBContext context, Mode mode, WebServiceFeature... features) {
+        if (log.isDebugEnabled()) {
+            log.debug("Create Dispatch with epr 2: " + jaxwsEPR);
+        }
+        verifyServiceDescriptionActive();
+        if (jaxwsEPR == null) {
+            throw ExceptionFactory
+                    .makeWebServiceException(Messages.getMessage("dispatchNoEndpointReference"));
+        }
+        
+        org.apache.axis2.addressing.EndpointReference axis2EPR =
+            EndpointReferenceUtils.createAxis2EndpointReference("");
+        String addressingNamespace = null;
+        
+        try {
+            addressingNamespace = EndpointReferenceUtils.convertToAxis2(axis2EPR, jaxwsEPR);
+        }
+        catch (Exception e) {
+            throw ExceptionFactory.
+                makeWebServiceException(Messages.getMessage("invalidEndpointReference", 
+                                                            e.toString()));
+        }
+        
+        EndpointDescription endpointDesc =
+                DescriptionFactory.updateEndpoint(serviceDescription, null, axis2EPR,
+                                                  addressingNamespace,
+                                                  DescriptionFactory.UpdateType.CREATE_DISPATCH,
+                                                  this);
+        if (endpointDesc == null) {
+            throw ExceptionFactory.
+              makeWebServiceException(Messages.getMessage("endpointDescriptionConstructionFailure", 
+                                      jaxwsEPR.toString())); 
+        }
+
+        JAXBDispatch<Object> dispatch = new JAXBDispatch(this, endpointDesc, axis2EPR, addressingNamespace, features);
+
+        if (mode != null) {
+            dispatch.setMode(mode);
+        } else {
+            dispatch.setMode(Service.Mode.PAYLOAD);
+        }
+
+        if (serviceClient == null)
+            serviceClient = getServiceClient(endpointDesc.getPortQName());
+
+        dispatch.setJAXBContext(context);
+        dispatch.setServiceClient(serviceClient);
+
+        return dispatch;
+    }
+
+    @Override
+    public <T> Dispatch<T> createDispatch(QName portName, Class<T> type, Mode mode, WebServiceFeature... features) {
+        
+        if (log.isDebugEnabled()) {
+            log.debug("Create Dispatch with portName: " + portName);
+        }
+        verifyServiceDescriptionActive();
+        if (portName == null) {
+            throw ExceptionFactory
+                    .makeWebServiceException(Messages.getMessage("createDispatchFail0"));
+        }
+        
+        if (!isValidDispatchType(type)) {
+            throw ExceptionFactory
+                    .makeWebServiceException(Messages.getMessage("dispatchInvalidType"));
+        }
+
+        if (!isValidDispatchTypeWithMode(type, mode)) {
+            throw ExceptionFactory
+                    .makeWebServiceException(Messages.getMessage("dispatchInvalidTypeWithMode"));
+        }
+
+        EndpointDescription endpointDesc =
+                DescriptionFactory.updateEndpoint(serviceDescription, 
+                								  null, 
+                                                  portName,
+                                                  DescriptionFactory.UpdateType.CREATE_DISPATCH,
+                                                  this);
+
+        if (endpointDesc == null) {
+            throw ExceptionFactory.makeWebServiceException(
+                    Messages.getMessage("createDispatchFail2", portName.toString()));
+        }
+
+        XMLDispatch<T> dispatch = new XMLDispatch<T>(this, endpointDesc, features);
+
+        if (mode != null) {
+            dispatch.setMode(mode);
+        } else {
+            dispatch.setMode(Service.Mode.PAYLOAD);
+        }
+
+        if (serviceClient == null)
+            serviceClient = getServiceClient(portName);
+
+        if(type == OMElement.class) {
+            if (log.isDebugEnabled()) {
+                log.debug("This a Dispatch<OMElement>. The custom builder is installed.");
+            }
+            ProviderOMContextListener.create(serviceClient.getServiceContext());
+        }
+        dispatch.setServiceClient(serviceClient);
+        dispatch.setType(type);
+        return dispatch;
+    }
+
+    @Override
+    public Dispatch<Object> createDispatch(QName portName, JAXBContext context, Mode mode, WebServiceFeature... features) {
+        if (log.isDebugEnabled()) {
+            log.debug("Create Dispatch with jaxbcontext and portName: " + portName);
+        }
+        
+        verifyServiceDescriptionActive();
+        if (portName == null) {
+            throw ExceptionFactory
+                    .makeWebServiceException(Messages.getMessage("createDispatchFail0"));
+        }
+
+        EndpointDescription endpointDesc =
+                DescriptionFactory.updateEndpoint(serviceDescription, 
+                								  null, 
+                                                  portName,
+                                                  DescriptionFactory.UpdateType.CREATE_DISPATCH,
+                                                  this);
+
+        if (endpointDesc == null) {
+            throw ExceptionFactory.makeWebServiceException(
+                    Messages.getMessage("createDispatchFail2", portName.toString()));
+        }
+
+        JAXBDispatch<Object> dispatch = new JAXBDispatch(this, endpointDesc, features);
+
+        if (mode != null) {
+            dispatch.setMode(mode);
+        } else {
+            dispatch.setMode(Service.Mode.PAYLOAD);
+        }
+
+        if (serviceClient == null)
+            serviceClient = getServiceClient(portName);
+
+        dispatch.setJAXBContext(context);
+        dispatch.setServiceClient(serviceClient);
+
+        return dispatch;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see javax.xml.ws.spi.ServiceDelegate#getPort(java.lang.Class)
+     */
+    public <T> T getPort(Class<T> sei) throws WebServiceException {
+        return getPort((QName) null, sei, (WebServiceFeature[]) null);
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.spi.ServiceDelegate#getPort(javax.xml.namespace.QName, java.lang.Class)
+    */
+    public <T> T getPort(QName portName, Class<T> sei) throws WebServiceException {
+        return getPort(portName, sei, (WebServiceFeature[]) null);
+    }
+
+    @Override
+    public <T> T getPort(Class<T> sei, WebServiceFeature... features) {
+      return getPort((QName) null, sei, features);
+    }
+
+    @Override
+    public <T> T getPort(EndpointReference jaxwsEPR, Class<T> sei, WebServiceFeature... features) {
+        /* TODO Check to see if WSDL Location is provided.
+         * if not check WebService annotation's WSDLLocation
+         * if both are not provided then throw exception.
+         * (JLB): I'm not sure lack of WSDL should cause an exception
+         */
+        
+        if (log.isTraceEnabled()) {
+            log.trace("getPort: jaxwsEPR = " + jaxwsEPR);
+        }
+
+        if (!isValidWSDLLocation()) {
+            //TODO: Should I throw Exception if no WSDL
+            //throw ExceptionFactory.makeWebServiceException("WSLD Not found");
+        }
+        
+        if (jaxwsEPR == null) {
+            throw ExceptionFactory.
+               makeWebServiceException(Messages.getMessage("dispatchNoEndpointReference2"));
+        }
+        
+        if (sei == null) {
+            throw ExceptionFactory.makeWebServiceException(
+                    Messages.getMessage("getPortInvalidSEI", jaxwsEPR.toString(), "null"));
+        }
+        
+        org.apache.axis2.addressing.EndpointReference axis2EPR =
+            EndpointReferenceUtils.createAxis2EndpointReference("");
+        String addressingNamespace = null;
+        
+        try {
+            addressingNamespace = EndpointReferenceUtils.convertToAxis2(axis2EPR, jaxwsEPR);
+        }
+        catch (Exception e) {
+            throw ExceptionFactory.
+              makeWebServiceException(Messages.getMessage("invalidEndpointReference", 
+                                                          e.toString()));
+        }
+        
+        if (log.isTraceEnabled()) {
+            log.trace("getPort: Converted jaxwsEPR to axis2EPR = " + axis2EPR);
+        }
+
+        return getPort(axis2EPR, addressingNamespace, sei, features);
+    }
+
+    @Override
+    public <T> T getPort(QName portName, Class<T> sei, WebServiceFeature... features) {
+        verifyServiceDescriptionActive();
+        /* TODO Check to see if WSDL Location is provided.
+         * if not check WebService annotation's WSDLLocation
+         * if both are not provided then throw exception.
+         * (JLB): I'm not sure lack of WSDL should cause an exception
+         */
+
+
+        if (!isValidWSDLLocation()) {
+            //TODO: Should I throw Exception if no WSDL
+            //throw ExceptionFactory.makeWebServiceException("WSLD Not found");
+        }
+        if (sei == null) {
+            throw ExceptionFactory.makeWebServiceException(
+                    Messages.getMessage("getPortInvalidSEI", portName.toString(), "null"));
+        }
+
+        DescriptionBuilderComposite sparseComposite = getPortMetadata();
+        resetPortMetadata();
+        EndpointDescription endpointDesc = null;
+        if (sparseComposite != null) {
+            endpointDesc =
+                DescriptionFactory.updateEndpoint(serviceDescription, sei, portName,
+                                                  DescriptionFactory.UpdateType.GET_PORT,
+                                                  sparseComposite, this);
+        }
+        else {
+            endpointDesc =
+                DescriptionFactory.updateEndpoint(serviceDescription, sei, portName,
+                                                  DescriptionFactory.UpdateType.GET_PORT,
+                                                  null, this);
+            
+        }
+        if (endpointDesc == null) {
+            throw ExceptionFactory.makeWebServiceException(
+            		Messages.getMessage("portErr",portName.toString()));
+        }
+
+        String[] interfacesNames = 
+            new String [] {sei.getName(), org.apache.axis2.jaxws.spi.BindingProvider.class.getName()};
+        
+        // As required by java.lang.reflect.Proxy, ensure that the interfaces
+        // for the proxy are loadable by the same class loader. 
+        Class[] interfaces = null;
+        // First, let's try loading the interfaces with the SEI classLoader
+        ClassLoader classLoader = getClassLoader(sei);
+        try {
+            interfaces = loadClasses(classLoader, interfacesNames);
+        } catch (ClassNotFoundException e1) {
+            // Let's try with context classLoader now
+            classLoader = getContextClassLoader();
+            try {
+                interfaces = loadClasses(classLoader, interfacesNames);
+            } catch (ClassNotFoundException e2) {
+                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("portErr1"), e2);
+            }
+        }
+
+        JAXWSProxyHandler proxyHandler = new JAXWSProxyHandler(this, interfaces[0], endpointDesc, features);
+        Object proxyClass = Proxy.newProxyInstance(classLoader, interfaces, proxyHandler);
+        return sei.cast(proxyClass);
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.spi.ServiceDelegate#getExecutor()
+    */
+    public Executor getExecutor() {
+        //FIXME: Use client provider executor too.
+        if (executor == null) {
+            executor = getDefaultExecutor();
+        }
+        return executor;
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.spi.ServiceDelegate#getHandlerResolver()
+    */
+    public HandlerResolver getHandlerResolver() {
+        verifyServiceDescriptionActive();
+        if (handlerResolver == null) {
+            handlerResolver = new HandlerResolverImpl(serviceDescription, this);
+        }
+        return handlerResolver;
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.spi.ServiceDelegate#getPorts()
+    */
+    public Iterator<QName> getPorts() {
+        verifyServiceDescriptionActive();
+        return getServiceDescription().getPorts(this).iterator();
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.spi.ServiceDelegate#getServiceName()
+    */
+    public QName getServiceName() {
+        return serviceQname;
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.spi.ServiceDelegate#getWSDLDocumentLocation()
+    */
+    public URL getWSDLDocumentLocation() {
+        verifyServiceDescriptionActive();
+        try {
+            String wsdlLocation = ((ServiceDescriptionWSDL) serviceDescription).getWSDLLocation();
+            if(wsdlLocation == null) {
+                return null;
+            }
+            return new URL(wsdlLocation);
+        } catch (MalformedURLException e) {
+            throw ExceptionFactory
+                    .makeWebServiceException(e);
+        }
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.spi.ServiceDelegate#setExecutor(java.util.concurrent.Executor)
+    */
+    public void setExecutor(Executor e) {
+        if (e == null) {
+            throw ExceptionFactory
+                    .makeWebServiceException(Messages.getMessage("cannotSetExcutorToNull"));
+        }
+
+        executor = e;
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see javax.xml.ws.spi.ServiceDelegate#setHandlerResolver(javax.xml.ws.handler.HandlerResolver)
+    */
+    public void setHandlerResolver(HandlerResolver handlerresolver) {
+        this.handlerResolver = handlerresolver;
+    }
+
+    //================================================
+    // Internal public APIs
+    //================================================
+
+    /** Get the ServiceDescription tree that this ServiceDelegate */
+    public ServiceDescription getServiceDescription() {
+        return serviceDescription;
+    }
+
+    //TODO Change when ServiceDescription has to return ServiceClient or OperationClient
+
+    /**
+     * 
+     */
+    public ServiceClient getServiceClient(QName portQName) throws WebServiceException {
+        verifyServiceDescriptionActive();
+        return serviceDescription.getServiceClient(portQName, this);
+    }
+    
+    public <T> T getPort(org.apache.axis2.addressing.EndpointReference axis2EPR, String addressingNamespace, Class<T> sei, WebServiceFeature... features) {
+        verifyServiceDescriptionActive();
+        DescriptionBuilderComposite sparseComposite = getPortMetadata();
+        resetPortMetadata();
+        EndpointDescription endpointDesc = null;
+        
+        if (sparseComposite != null) {
+            endpointDesc =
+                DescriptionFactory.updateEndpoint(serviceDescription, sei, axis2EPR,
+                                                  addressingNamespace,
+                                                  DescriptionFactory.UpdateType.GET_PORT,
+                                                  sparseComposite, this);
+
+        }
+        else {
+            endpointDesc =
+                DescriptionFactory.updateEndpoint(serviceDescription, sei, axis2EPR,
+                                                  addressingNamespace,
+                                                  DescriptionFactory.UpdateType.GET_PORT,
+                                                  null, this);
+        }
+        
+        if (endpointDesc == null) {
+            throw ExceptionFactory.makeWebServiceException(
+                    Messages.getMessage("serviceDelegateNoPort", axis2EPR.toString()));
+                                                           
+        }
+
+        String[] interfacesNames = 
+            new String [] {sei.getName(), org.apache.axis2.jaxws.spi.BindingProvider.class.getName()};
+        
+        // As required by java.lang.reflect.Proxy, ensure that the interfaces
+        // for the proxy are loadable by the same class loader. 
+        Class[] interfaces = null;
+        // First, let's try loading the interfaces with the SEI classLoader
+        ClassLoader classLoader = getClassLoader(sei);
+        try {
+            interfaces = loadClasses(classLoader, interfacesNames);
+        } catch (ClassNotFoundException e1) {
+            // Let's try with context classLoader now
+            classLoader = getContextClassLoader();
+            try {
+                interfaces = loadClasses(classLoader, interfacesNames);
+            } catch (ClassNotFoundException e2) {
+                throw ExceptionFactory.makeWebServiceException(
+                     Messages.getMessage("serviceDelegateProxyError", e2.getMessage()));
+            }
+        }
+
+        JAXWSProxyHandler proxyHandler = new JAXWSProxyHandler(this, interfaces[0], endpointDesc, axis2EPR, addressingNamespace, features);
+        Object proxyClass = Proxy.newProxyInstance(classLoader, interfaces, proxyHandler);
+        return sei.cast(proxyClass);        
+    }
+
+    //================================================
+    // Impl methods
+    //================================================
+
+    //TODO: Need to make the default number of threads configurable
+    private Executor getDefaultExecutor() {
+    	ExecutorFactory executorFactory = (ExecutorFactory) FactoryRegistry.getFactory(
+    			ExecutorFactory.class);
+        return executorFactory.getExecutorInstance(ExecutorFactory.CLIENT_EXECUTOR);
+    }
+
+    private boolean isValidServiceName() {
+        return serviceQname != null && !"".equals(serviceQname.toString().trim());
+    }
+
+    private boolean isValidWSDLLocation() {
+        URL wsdlLocation = getWSDLDocumentLocation();
+        return wsdlLocation != null && !"".equals(wsdlLocation.toString().trim());
+    }
+
+    // TODO: Remove this method and put the WSDLWrapper methods on the ServiceDescriptor directly
+    private WSDLWrapper getWSDLWrapper() {
+        verifyServiceDescriptionActive();
+        return ((ServiceDescriptionWSDL)serviceDescription).getWSDLWrapper();
+    }
+
+    private boolean isServiceDefined(QName serviceName) {
+        return getWSDLWrapper().getService(serviceName) != null;
+    }
+
+    private boolean isValidDispatchType(Class clazz) {
+        return clazz != null && (clazz == String.class ||
+                clazz == Source.class ||
+                clazz == DataSource.class ||
+                clazz == SOAPMessage.class ||
+                clazz == OMElement.class);
+    }
+
+    private boolean isValidDispatchTypeWithMode(Class clazz, Mode mode) {
+
+    	if (clazz != null && !(clazz == SOAPMessage.class && mode.equals(Service.Mode.PAYLOAD))) {
+    			return true;
+    	} else {
+    		return false;
+    	}
+  
+    }
+
+    /** @return ClassLoader */
+    private static ClassLoader getClassLoader(final Class cls) {
+        // 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 cls.getClassLoader();
+                        }
+                    }
+            );
+        } catch (PrivilegedActionException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("Exception thrown from AccessController: " + e);
+            }
+            throw ExceptionFactory.makeWebServiceException(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;
+    }
+    
+    /**
+     * 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 {
+                            return Class.forName(className, initialize, classLoader);
+                        }
+                    }
+            );
+        } catch (PrivilegedActionException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("Exception thrown from AccessController: " + e);
+            }
+            throw (ClassNotFoundException)e.getException();
+        }
+
+        return cl;
+    }
+    
+    private static Class[] loadClasses(ClassLoader classLoader, String[] classNames)
+        throws ClassNotFoundException {
+        Class[] classes = new Class[classNames.length];
+        for (int i = 0; i < classNames.length; i++) {
+            classes[i] = forName(classNames[i], true, classLoader);
+        }
+        return classes;
+    }
+    
+    /**
+     * PROPRIETARY METHOD TO RELEASE RESOUCES.  USE OF THIS METHOD IS NOT JAX-WS COMPLIANT 
+     * AND IS NON-PORTABLE!  
+     * 
+     * This method can be called by client code to try to release
+     * resources associated with the Service instance parameter.  These resources include
+     * the JAX-WS metadata objects (e.g. ServiceDescription, EndpointDescription) and the
+     * associated Axis2 objects (e.g. AxisService and realted objects).  Note that these 
+     * resources can be shared across multiple service delegates, and so they will not actually 
+     * be released until the last service delegate using them is closed.
+     * 
+     * Note that it is not necessary to call this method since the service delegate finalizer
+     * will also release the resources as appropriate.  However, finalizers are not necessarily run
+     * in a timely fashion and the timing varies across JVMs.  To predictibly release resources
+     * to prevent large memory requirements and/or OutOfMemory errors, this proprietary release 
+     * method can be called.
+     * 
+     * @param service Instance of the Service for which resources may be released.
+     */
+    public static void releaseService(Service service) {
+        // Find the ServiceDelegate corresponding to the service to be closed
+        // This is the back way around since there is no close on the Service
+        ServiceDelegate serviceDelegate = getServiceDelegateForService(service);
+        serviceDelegate.releaseServiceResources();
+    }
+    
+    private static ServiceDelegate getServiceDelegateForService(Service service) {
+        // Need to get to the private Service._delegate
+        ServiceDelegate returnServiceDelegate = null;
+        try {
+            try {
+                Field serviceDelgateField = service.getClass().getDeclaredField("delegate");
+                serviceDelgateField.setAccessible(true);
+                returnServiceDelegate = (ServiceDelegate) serviceDelgateField.get(service);
+            } catch (NoSuchFieldException e) {
+                // This may be a generated service subclass, so get the delegate from the superclass
+                Field serviceDelegateField = service.getClass().getSuperclass().getDeclaredField("delegate");
+                serviceDelegateField.setAccessible(true);
+                returnServiceDelegate = (ServiceDelegate) serviceDelegateField.get(service);
+            } 
+        } catch (SecurityException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("Attempt to get service delegate for service caught exception.", e);
+            }
+            throw ExceptionFactory.makeWebServiceException(e);
+        } catch (IllegalAccessException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("Attempt to get service delegate for service caught exception.", e);
+            }
+            throw ExceptionFactory.makeWebServiceException(e);
+        } catch (NoSuchFieldException e) {
+            if (log.isDebugEnabled()) {
+                log.debug("Attempt to get service delegate for service caught exception.", e);
+            }
+            throw ExceptionFactory.makeWebServiceException(e);
+        }
+        return returnServiceDelegate;
+
+    }
+    
+    /**
+     * This can be called from the proprietary static release method (which can be called via 
+     * client code), or it can be called by the finalizer.  This method tries to release resources 
+     * associated with the ServiceDelegate.  Note that since other ServiceDelegates can share these 
+     * resources (e.g. ServiceDescription, EndpointDescription, AxisService), the resources may 
+     * not be releaseed until the last ServiceDelegate using them issues a close.
+     */
+    private void releaseServiceResources() {
+        if (log.isDebugEnabled()) {
+            log.debug("ServiceDelegate.releaseServiceResouces entry");
+        }
+        // This can be called indirectly by client code or by the finalizer.  If it hasn't been
+        // called yet, have the endpointDescriptions release resources.
+        if (serviceDescription != null) {
+            serviceDescription.releaseResources(this);
+            serviceDescription = null;
+        }
+    }
+
+    /**
+     * Verify that there is an associated serviceDescription for this delegate.  If not, a
+     * webServiceException will be thrown.  A serviceDelegate may have a null serviceDescription
+     * if the client code issues the proprietary method call relealseServiceResources. 
+     */
+    private void verifyServiceDescriptionActive() {
+        if (serviceDescription == null) {
+            // TODO: This should be NLS'd
+            throw ExceptionFactory.makeWebServiceException("Attempt to use Service after it was released");
+        }
+    }
+    
+    protected void finalize() throws Throwable {
+        if (log.isDebugEnabled()) {
+            log.debug("ServiceDelegate.finalize entered for " + this);
+        }
+        try {
+            releaseServiceResources();
+        } catch (Exception e) {
+            if (log.isDebugEnabled()) {
+                log.debug("ServiceDelgate Finalizer caught exception", e);
+            }
+        } finally {
+            super.finalize();
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("ServiceDelegate.finalize exited");
+        }
+    }   
+}

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/spi/ServiceDelegate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/spi/ServiceDelegate.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/spi/ServiceDelegate.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message