All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.webservices.WsUtil Maven / Gradle / Ivy

The newest version!
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2016 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package org.glassfish.webservices;

import com.sun.enterprise.v3.admin.AdminAdapter;
import com.sun.enterprise.v3.admin.adapter.AdminConsoleAdapter;
import org.glassfish.deployment.common.ModuleDescriptor;
import org.glassfish.grizzly.config.dom.NetworkListener;
import com.sun.xml.ws.api.server.SDDocumentSource;
import com.sun.xml.ws.api.WSBinding;
import com.sun.xml.ws.api.BindingID;
import com.sun.enterprise.deployment.*;
import com.sun.enterprise.deployment.util.DOLUtils;
import com.sun.enterprise.deployment.web.UserDataConstraint;
import com.sun.enterprise.deployment.web.SecurityConstraint;
import com.sun.enterprise.container.common.spi.util.InjectionException;
import com.sun.enterprise.container.common.spi.util.InjectionManager;
import com.sun.enterprise.config.serverbeans.Config;
import com.sun.enterprise.util.LocalStringManagerImpl;

import jakarta.servlet.http.*;
import javax.xml.namespace.QName;
import java.util.*;
import java.net.*;
import java.util.logging.Logger;
import java.util.logging.Level;
import javax.xml.parsers.*;
import jakarta.xml.ws.soap.SOAPBinding;
import jakarta.xml.ws.handler.Handler;
import jakarta.xml.ws.http.HTTPBinding;
import jakarta.xml.soap.*;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import jakarta.servlet.http.HttpServletResponse;

import org.glassfish.web.deployment.util.WebServerInfo;
import org.glassfish.web.deployment.util.VirtualServerInfo;
import org.glassfish.web.util.HtmlEntityEncoder;
import org.w3c.dom.*;
import org.w3c.dom.Node;

import java.io.*;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.MessageFormat;

import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.glassfish.api.admin.ServerEnvironment;


/**
 * Web service related utilities.
 *
 * @author Kenneth Saks
 */
public class WsUtil {

    // proprietary property for enabling logging of stub requests/responses
    public static final String CLIENT_TRANSPORT_LOG_PROPERTY =
      "com.sun.enterprise.webservice.client.transport.log";

    // xslt processing parameters for final wsdl transformation
    public static final String ENDPOINT_ADDRESS_PARAM_NAME =
        "endpointAddressParam";

    public final String WSDL_IMPORT_NAMESPACE_PARAM_NAME = 
        "wsdlImportNamespaceParam";
    public static final String WSDL_IMPORT_LOCATION_PARAM_NAME = 
        "wsdlImportLocationParam";
    public static final String WSDL_INCLUDE_LOCATION_PARAM_NAME = 
        "wsdlIncludeLocationParam";

    public final String SCHEMA_IMPORT_NAMESPACE_PARAM_NAME = 
        "schemaImportNamespaceParam";
    public static final String SCHEMA_IMPORT_LOCATION_PARAM_NAME = 
        "schemaImportLocationParam";    
    public static final String SCHEMA_INCLUDE_LOCATION_PARAM_NAME = 
        "schemaIncludeLocationParam";    

    private Config config = null;
    private List networkListeners = null;

    public WsUtil() {
        config = WebServiceContractImpl.getInstance().getConfig();
    }

    private static final Logger logger = LogUtils.getLogger();

    /**
     * Serve up the FINAL wsdl associated with this web service.
     * @return true for success, false for failure
     */
    public boolean handleGet(HttpServletRequest request, 
                             HttpServletResponse response, 
                             WebServiceEndpoint endpoint) throws IOException {

        MimeHeaders headers = getHeaders(request);
        if( hasSomeTextXmlContent(headers) ) {
            String message = MessageFormat.format(logger.getResourceBundle().getString(LogUtils.GET_RECEIVED),
                    endpoint.getEndpointName(), endpoint.getEndpointAddressUri());

            writeInvalidMethodType(response, message);
            
            logger.info(message);
            
            return false;
        }
        
        URL wsdlUrl = null;

        String requestUriRaw = request.getRequestURI();
        String requestUri    = (requestUriRaw.charAt(0) == '/') ?
            requestUriRaw.substring(1) : requestUriRaw;
        String queryString = request.getQueryString();

        WebService webService = endpoint.getWebService();

        if( queryString == null ) {

            // Get portion of request uri representing location within a module
            String wsdlPath = endpoint.getWsdlContentPath(requestUri);

            if( wsdlPath != null) {
                ModuleDescriptor module =
                    webService.getBundleDescriptor().getModuleDescriptor();

                if( wsdlPath.equals(webService.getWsdlFileUri())){
                    // If the request is for the main wsdl document, return
                    // the final wsdl instead of the wsdl from the module.
                    wsdlUrl = webService.getWsdlFileUrl();
                } else if( isWsdlContent(wsdlPath, 
                                         webService.getBundleDescriptor()) ) {
                    // For relative document imports. These documents do not
                    // require modification during deployment, so serve them
                    // up directly from the packaged module.  isWsdlContent()
                    // check ensures we don't serve up arbitrary content from
                    // the module.
                    URL finalWsdlUrl = webService.getWsdlFileUrl();
                    String finalWsdlPath = finalWsdlUrl.getPath();
                    // remove the final wsdl uri from the above path
                    String wsdlDirPath = finalWsdlPath.substring(0, finalWsdlPath.length()-webService.getWsdlFileUri().length());
                    File wsdlDir = new File(wsdlDirPath);
                    File wsdlFile = new File(wsdlDir, wsdlPath.replace('/', File.separatorChar));
                    try {
                        wsdlUrl = wsdlFile.toURL();
                    } catch(MalformedURLException mue) {
                        String msg = MessageFormat.format(
                                logger.getResourceBundle().getString(LogUtils.FAILURE_SERVING_WSDL),
                                webService.getName());
                        logger.log(Level.INFO, msg, mue);
                    } 
                        
                }
            }

        } else if( queryString.equalsIgnoreCase("WSDL") ) {
            wsdlUrl = webService.getWsdlFileUrl();
        }

        boolean success = false;
        if( wsdlUrl != null ) {
            
            InputStream is = null;
            try {
                response.setContentType("text/xml");
                response.setStatus(HttpServletResponse.SC_OK);
                // if the requested file is the main wsdl document, we are going
                // to reprocess it through the XML transformer to change the final
                // endpoint URL correct for this particular web server instance.
                // This is necessary in the case of SE/EE installations where
                // the application can be running on different machines and ports
                // than the one they were deployed on (DAS).
                if (wsdlUrl.toURI().equals(webService.getWsdlFileUrl().toURI())) {
                    // get the application module ID
                    try {
                        
                        WebServerInfo wsi = getWebServerInfoForDAS();
                        URL url = webService.getWsdlFileUrl();
                        File originalWsdlFile = new File(url.getPath()+"__orig");
                        if(!originalWsdlFile.exists()) {
                            originalWsdlFile = new File(url.getPath());
                        }
                        generateFinalWsdl(originalWsdlFile.toURL(), webService, wsi, response.getOutputStream());
                    } catch(Exception e) {
                        // if this fail, we revert to service the untouched 
                        // repository item.
                        URLConnection urlCon = wsdlUrl.openConnection();
                        urlCon.setUseCaches(false);
                        is = urlCon.getInputStream();                    
                        copyIsToOs(is, response.getOutputStream());
                    }
                } else {
                    // Copy bytes into output. Disable caches to avoid jar URL
                    // caching problem.
                    URLConnection urlCon = wsdlUrl.openConnection();
                    urlCon.setUseCaches(false);
                    is = urlCon.getInputStream();                    
                    copyIsToOs(is, response.getOutputStream());
                }
                success = true;
                if( logger.isLoggable(Level.FINE) ) {
                    logger.log(Level.FINE, LogUtils.SERVING_FINAL_WSDL,
                            new Object[] {wsdlUrl, request.getRequestURL() + (queryString != null ? ("?"+queryString) : "")});
                }
            } catch(Exception e) {
                String msg = MessageFormat.format(
                                logger.getResourceBundle().getString(LogUtils.FAILURE_SERVING_WSDL),
                                webService.getName());
                logger.log(Level.INFO, msg, e);
            } finally {
                if(is != null) {
                    try {
                        is.close();
                    } catch(IOException ex) {}
                }
            }
        }

        if( !success ) {
            String message = MessageFormat.format(
                    logger.getResourceBundle().getString(LogUtils.INVALID_WSDL_REQUEST),
                    request.getRequestURL() + (queryString != null ? ("?"+queryString) : ""),
                    webService.getName()
                    );
            logger.info(message);

            writeInvalidMethodType(response, message);
        }
        
        return success;
    }

    private void copyIsToOs(InputStream is, OutputStream os) throws IOException {
        byte[] buf = new byte[4096];
        int len = 0;
        while (len != -1) {
            try {
                len = is.read(buf, 0, buf.length);
            } catch (EOFException eof){
                break;
            }

            if(len != -1) {
                os.write(buf, 0, len);
            }
        }
        os.flush();
        is.close();
        os.close();
    }

    /**
     * All wsdl files and wsdl imported files live under a well-known
     * wsdl directory. 
     * @param uri module uri
     */
    public boolean isWsdlContent(String uri, BundleDescriptor bundle) {
        String wsdlDir = getWsdlDir(bundle);
        return (uri != null) && uri.startsWith(wsdlDir);
    }

    /**
     * @return module-specific dedicated wsdl directory 
     */
    public String getWsdlDir(BundleDescriptor bundle) {
        boolean isWar = bundle.getModuleType().equals(DOLUtils.warType());
        return isWar ? "WEB-INF/wsdl" : "META-INF/wsdl";
    }

    

    /**
     * Collect all relative imports from a web service's main wsdl document.
     *
     *@param wsdlRelativeImports outupt param in which wsdl relative imports 
     * will be added
     *
     *@param schemaRelativeImports outupt param in which schema relative 
     * imports will be added
     */
    private void parseRelativeImports(URL wsdlFileUrl, 
                                      Collection wsdlRelativeImports,
                                      Collection wsdlIncludes,
                                      Collection schemaRelativeImports,
                                       Collection schemaIncludes) {
        // We will use our little parser rather than using JAXRPC's heavy weight WSDL parser
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        //Validation is not needed as we don't want to be too strict in processing wsdls that could be generated by buggy tools.
        factory.setExpandEntityReferences(false);
        try {
            factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
        } catch (ParserConfigurationException pce) {
            logger.log(Level.FINE, LogUtils.PARSER_UNSUPPORTED_FEATURE,
                    new Object[] {factory.getClass().getName(),
                        "http://apache.org/xml/features/disallow-doctype-decl"
                    });
        }
        InputStream is = null;
        try {
            DocumentBuilder builder = factory.newDocumentBuilder();
            is = wsdlFileUrl.openStream();
            Document document = builder.parse(is);
            procesSchemaImports(document, schemaRelativeImports);
            procesWsdlImports(document, wsdlRelativeImports);
            procesSchemaIncludes(document, schemaIncludes);
            procesWsdlIncludes(document, wsdlIncludes);
        } catch (SAXParseException spe) {
            // Error generated by the parser
            logger.log(Level.SEVERE, LogUtils.PARSING_ERROR,
                    new Object[] {spe.getLineNumber() ,spe.getSystemId()});
            // Use the contained exception, if any
            Exception x = spe;
            if (spe.getException() != null) {
                x = spe.getException();
            }
            logger.log(Level.SEVERE, LogUtils.ERROR_OCCURED, x);
        } catch (Exception sxe) {
            logger.log(Level.SEVERE, LogUtils.WSDL_PARSING_ERROR, sxe);
        } finally {
            try {
                if(is != null) {
                    is.close();
                }
            } catch (IOException io) {}
        }
    }

    private void addImportsAndIncludes(NodeList list, Collection result,
                        String namespace, String location) throws SAXException,
                        ParserConfigurationException, IOException, SAXParseException {
        for(int i=0; i1) {
            for (Iterator wsIter = webServices.iterator();wsIter.hasNext();) {
                WebService aWS = (WebService) wsIter.next();
                if (webService.getName().equals(aWS.getName())) {
                    continue;
                }
                // this is another web service defined in the same bundle.
                // let's check if it points to the same WSDL file
                if ((webService.getWsdlFileUri() != null) &&
                     (aWS.getWsdlFileUri() != null) &&
                     (webService.getWsdlFileUri().equals(aWS.getWsdlFileUri()))) {
                    endpointsCopy.addAll(aWS.getEndpoints());
                } else if ((webService.getWsdlFileUrl() != null) &&
                     (aWS.getWsdlFileUrl() != null) &&
                     ((webService.getWsdlFileUrl().toString())
                        .equals(aWS.getWsdlFileUrl().toString()))) {
                    endpointsCopy.addAll(aWS.getEndpoints());
                }
            }
        }

        
        // Load the wsdl file bytes with caching turned off.  This is
        // to avoid a jar url consistency problem that can arise if we
        // overwrite the module file later on in deployment.
        InputStream wsdlInputStream = new BufferedInputStream(wsdlFileUrl.openStream());
        Source XsltWsdlDocument = new StreamSource(wsdlInputStream);
        Templates templates = createTemplatesFor
            (endpointsCopy, wsdlRelativeImports, wsdlIncludes, 
                schemaRelativeImports, schemaIncludes);
                                                 
        Transformer transformer = templates.newTransformer();


        // WSDL is associated with webservice, but url is endpoint-specific,
        // so let WebService choose which endpoint to use.
        WebServiceEndpoint endpointForImport = 
            webService.pickEndpointForRelativeImports();
        URL root= wsi.getWebServerRootURL(endpointForImport.isSecure());
        URL finalWsdlUrl = endpointForImport.composeFinalWsdlUrl(root);
        
        int wsdlImportNum = 0;
        for(Iterator iter = wsdlRelativeImports.iterator(); iter.hasNext();){
            Import next = (Import) iter.next();
            transformer.setParameter
                (WSDL_IMPORT_NAMESPACE_PARAM_NAME + wsdlImportNum, 
                 next.getNamespace());
            
            // Convert each relative import into an absolute import, using
            // the final wsdl's Url as the context
            URL relativeUrl  = new URL(finalWsdlUrl, next.getLocation());
            transformer.setParameter
                (WSDL_IMPORT_LOCATION_PARAM_NAME + wsdlImportNum, relativeUrl);
            
            wsdlImportNum++;
        }

        int schemaImportNum = 0;
        for(Iterator iter = schemaRelativeImports.iterator(); iter.hasNext();){
            Import next = (Import) iter.next();
            transformer.setParameter
                (SCHEMA_IMPORT_NAMESPACE_PARAM_NAME + schemaImportNum, 
                 next.getNamespace());
            
            // Convert each relative import into an absolute import, using
            // the final wsdl's Url as the context
            URL relativeUrl  = new URL(finalWsdlUrl, next.getLocation());
            transformer.setParameter
                (SCHEMA_IMPORT_LOCATION_PARAM_NAME + schemaImportNum, 
                 relativeUrl);
            
            schemaImportNum++;
        }        

        int wsdlIncludeNum = 0;
        for(Iterator iter = wsdlIncludes.iterator(); iter.hasNext();){
            Import next = (Import) iter.next();
            URL relativeUrl  = new URL(finalWsdlUrl, next.getLocation());
            transformer.setParameter
                (WSDL_INCLUDE_LOCATION_PARAM_NAME + wsdlIncludeNum, relativeUrl);            
            wsdlIncludeNum++;
        }

        int schemaIncludeNum = 0;
        for(Iterator iter = schemaIncludes.iterator(); iter.hasNext();){
            Import next = (Import) iter.next();
            URL relativeUrl  = new URL(finalWsdlUrl, next.getLocation());
            transformer.setParameter
                (SCHEMA_INCLUDE_LOCATION_PARAM_NAME + schemaIncludeNum, 
                 relativeUrl);            
            schemaIncludeNum++;
        }        

        int endpointNum = 0;
        for(Iterator iter = endpointsCopy.iterator(); iter.hasNext();) {
            WebServiceEndpoint next = (WebServiceEndpoint) iter.next();

            // Get a URL for the root of the webserver, where the host portion
            // is a canonical host name.  Since this will be used to compose the
            // endpoint address that is written into WSDL, it's better to use
            // hostname as opposed to IP address.
            // The protocol and port will be based on whether the endpoint 
            // has a transport guarantee of INTEGRAL or CONFIDENTIAL.
            // If yes, https will be used.  Otherwise, http will be used.
            URL rootURL = wsi.getWebServerRootURL(next.isSecure());

            URL actualAddress = next.composeEndpointAddress(rootURL);

            transformer.setParameter(ENDPOINT_ADDRESS_PARAM_NAME + endpointNum, 
                                     actualAddress.toExternalForm());

            String endpointType = next.implementedByEjbComponent() ?
                "EJB" : "Servlet";
            logger.log(Level.INFO, LogUtils.ENDPOINT_REGISTRATION,
                    new Object[] {"[" + endpointType + "] " + next.getEndpointName(), actualAddress});

            endpointNum++;
        }

        transformer.transform(XsltWsdlDocument, new StreamResult(outputStream));
        wsdlInputStream.close();
        outputStream.close();

        return;
    }

   /**
     * Accessing wsdl URL might involve file system access, so wrap
     * operation in a doPrivileged block.
     */
    public URL privilegedGetServiceRefWsdl
        (ServiceReferenceDescriptor desc) throws Exception {
        URL wsdlFileURL;
        try {
            final ServiceReferenceDescriptor serviceRef = desc;
            wsdlFileURL = (URL) java.security.AccessController.doPrivileged
                (new java.security.PrivilegedExceptionAction() {
                        public java.lang.Object run() throws Exception {
                            URL retVal;
                            if(serviceRef.hasWsdlOverride()) {
                                retVal = serviceRef.getWsdlOverride();
                            } else {
                                // Upon server restart, wsdlfileURL can be null
                                // check that and return value from wsdlFileURI
                                if(serviceRef.getWsdlFileUrl() != null) {
                                    retVal = serviceRef.getWsdlFileUrl();
                                } else {
                                    if(serviceRef.getWsdlFileUri().startsWith("http")) {
                                        retVal = new URL(serviceRef.getWsdlFileUri());
                                    } else {
                                        if ((serviceRef.getWsdlFileUri().startsWith("WEB-INF")|| serviceRef.getWsdlFileUri().startsWith("META-INF"))) {

                                            //This can be the case when the toURL fails
                                            //because in its implementation it looks for user.dir
                                            // which sometimes can vary based on where vm is launched
                                            // so in this case
                                            //resolve from application path
                                            WebServiceContractImpl wscImpl  = WebServiceContractImpl.getInstance();
                                            ServerEnvironment se = wscImpl.getServerEnvironment();

                                            File appFile = new File(se.getApplicationRepositoryPath(),serviceRef.getBundleDescriptor().getApplication().getAppName());
                                            if (appFile.exists()) {
                                                File wsdlFile = new File(appFile, serviceRef.getWsdlFileUri());
                                                retVal = wsdlFile.toURI().toURL();
                                                if (!wsdlFile.exists()) {
                                                    // try the module path for example when we are in an EAR file
                                                    wsdlFile = new File(serviceRef.getBundleDescriptor().getRawModuleID(), serviceRef.getWsdlFileUri());
                                                    if (!wsdlFile.exists()) {
                                                        // finally try to load via classloader
                                                        retVal = Thread.currentThread().getContextClassLoader().getResource(serviceRef.getWsdlFileUri());
                                                    } else {
                                                        retVal = wsdlFile.toURI().toURL();
                                                    }
                                                }
                                            } else {
                                               //Fix for 6853656 and 6868695
                                               //In case of appclients the wsdl will be in the classpath
                                               //This will work for launches using the appclient command and
                                               // for Java Web Start launches
                                                
                                               retVal = Thread.currentThread().getContextClassLoader().getResource(serviceRef.getWsdlFileUri()) ;
                                            }
                                        }else {
                                            retVal = new File(serviceRef.getWsdlFileUri()).toURI().toURL();
                                        }
                                    }
                                }
                            }
                            return retVal;
                        }
                    });
        } catch(PrivilegedActionException pae) {
            logger.log(Level.WARNING, LogUtils.EXCEPTION_THROWN, pae);
            Exception e = new Exception();
            e.initCause(pae.getCause());
            throw e;
        }
        return wsdlFileURL;
    }

    public boolean isJAXWSbasedService(WebService ws) {

        if(ws.isJaxWSBased() != null) {
            //already verified
            return ws.isJaxWSBased();
        }

        boolean jaxwsEndPtFound = false;
        boolean jaxrpcEndPtFound = false;

        String declaredType = ws.getType();
        if(declaredType != null) {
            if(declaredType.equals("JAXWS")) {
                jaxwsEndPtFound = true;
            } else if(declaredType.equals("JAXRPC")) {
                jaxrpcEndPtFound = true;
            } else {
                logger.log(Level.SEVERE, LogUtils.WS_TYPE_ERROR, new Object[] {ws.getDescription(), declaredType});
            }
        }
        //Verify that all the endpoints are of the same type 
        for (WebServiceEndpoint endpoint : ws.getEndpoints()) {
            if (endpoint.getLinkName() == null) {
                String msg = MessageFormat.format(
                        logger.getResourceBundle().getString(LogUtils.UNRESOLVED_LINK),
                        new Object[] {endpoint.getEndpointName(), endpoint.getLinkName()});
                    logger.log(Level.SEVERE, msg);
                    throw new RuntimeException(msg);
            }
            String implClassName = null;
            if (endpoint.implementedByEjbComponent()) {
                if (endpoint.getEjbComponentImpl() != null) {
                    implClassName = endpoint.getEjbComponentImpl().getEjbClassName();
                }
            } else {
                if (endpoint.getWebComponentImpl() != null) {
                    implClassName = endpoint.getWebComponentImpl().getWebComponentImplementation();
                }
            }
            if (implClassName == null || "".equals(implClassName.trim())) {
                String msg = MessageFormat.format(
                        logger.getResourceBundle().getString(LogUtils.MISSING_IMPLEMENTATION_CLASS),
                        endpoint.getEndpointName());
                logger.log(Level.SEVERE, msg);
                throw new RuntimeException(msg);
            }
            Class implClass;
            try {
                implClass = Thread.currentThread().getContextClassLoader().loadClass(implClassName);
            } catch(Exception e) {
                String msg = MessageFormat.format(
                        logger.getResourceBundle().getString(LogUtils.CANNOT_LOAD_IMPLCLASS),
                        implClassName);
                logger.log(Level.SEVERE, msg);
                throw new RuntimeException(msg);
            }
            if (implClass!=null) {
                if(implClass.getAnnotation(jakarta.xml.ws.WebServiceProvider.class) != null) {
                    // if we already found a jaxrpcendpoint, flag error since we do not support jaxws+jaxrpc endpoint
                    // in the same service
                    if(jaxrpcEndPtFound) {
                        logger.log(Level.SEVERE, LogUtils.JAXWS_JAXRPC_ERROR, implClassName);
                        continue;
                    }
                    //This is a JAXWS endpoint with @WebServiceProvider
                    //Do not run wsgen for this endpoint
                    jaxwsEndPtFound = true;
                    continue;
                }
                if(implClass.getAnnotation(jakarta.jws.WebService.class) != null) {
                    // if we already found a jaxrpcendpoint, flag error since we do not support jaxws+jaxrpc endpoint
                    // in the same service
                    if(jaxrpcEndPtFound) {
                        logger.log(Level.SEVERE, LogUtils.JAXWS_JAXRPC_ERROR, implClassName);
                        continue;
                    }
                    // This is a JAXWS endpoint with @WebService;
                    jaxwsEndPtFound = true;
                    continue;
                }
                if (JAXWSServlet.class.isAssignableFrom(implClass)) {
                     // if we already found a jaxrpcendpoint, flag error since we do not support jaxws+jaxrpc endpoint
                    // in the same service
                    if(jaxrpcEndPtFound) {
                        logger.log(Level.SEVERE, LogUtils.JAXWS_JAXRPC_ERROR, implClassName);
                        continue;
                    }
                    // This is a JAXWS endpoint with @WebService;
                    jaxwsEndPtFound = true;
                    continue;
                } else {
                    // this is a jaxrpc endpoint
                    // if we already found a jaxws endpoint, flag error since we do not support jaxws+jaxrpc endpoint
                    // in the same service
                    if(jaxwsEndPtFound) {
                        logger.log(Level.SEVERE, LogUtils.JAXWS_JAXRPC_ERROR, implClassName);
                        continue;
                    }
                    // Set spec version to 1.1 to indicate later the wscompile should be run
                    // We do this here so that jaxrpc endpoint having J2EE1.4 or JavaEE5
                    // descriptors will work properly
                    jaxrpcEndPtFound = true;
                    ws.getWebServicesDescriptor().setSpecVersion("1.1");
                }
            }
        }

        if(jaxwsEndPtFound) {
            ws.setJaxWSBased(true);
            ws.setType("JAX-WS");
        } else {
            ws.setJaxWSBased(false);
            ws.setType("JAX-RPC");
        }
        return jaxwsEndPtFound;
    }

    /**
     * Create an xslt template for transforming the packaged webservice
     * WSDL to a final WSDL.
     */
    private Templates createTemplatesFor(Collection endpoints,
                                         Collection wsdlRelativeImports,
                                         Collection wsdlIncludes,
                                         Collection schemaRelativeImports,
                                         Collection schemaIncludes) throws Exception {

        // create the stylesheet
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        OutputStreamWriter writer = new OutputStreamWriter(bos, "UTF-8");

        writer.write("\n");

        int wsdlImportNum = 0;
        for(Iterator iter = wsdlRelativeImports.iterator(); iter.hasNext();) {

            Import next = (Import) iter.next();
            String importNamespaceParam =
                WSDL_IMPORT_NAMESPACE_PARAM_NAME + wsdlImportNum;
            String importLocationParam =
                WSDL_IMPORT_LOCATION_PARAM_NAME + wsdlImportNum;
            writer.write("\n");
            writer.write("\n");

            writer.write("\n");
            writer.write("");
            writer.write("");
            writer.write("");
            writer.write("");
            writer.write("");
            writer.write("");
            writer.write("");

            wsdlImportNum++;
        }

        int wsdlIncludeNum = 0;
        for(Iterator iter = wsdlIncludes.iterator(); iter.hasNext();) {

            Import next = (Import) iter.next();
            String importLocationParam =
                WSDL_INCLUDE_LOCATION_PARAM_NAME + wsdlIncludeNum;
            writer.write("\n");

            writer.write("\n");
            writer.write("");
            writer.write("");
            writer.write("");
            writer.write("");
            writer.write("");

            wsdlIncludeNum++;
        }

        int schemaImportNum = 0;
        for(Iterator iter = schemaRelativeImports.iterator(); iter.hasNext();) {

            Import next = (Import) iter.next();
            String importNamespaceParam =
                SCHEMA_IMPORT_NAMESPACE_PARAM_NAME + schemaImportNum;
            String importLocationParam =
                SCHEMA_IMPORT_LOCATION_PARAM_NAME + schemaImportNum;
            writer.write("\n");
            writer.write("\n");

            writer.write("\n");
            writer.write("");
            writer.write("");
            writer.write("");
            writer.write("");
            writer.write("");
            writer.write("");
            writer.write("");

            schemaImportNum++;
        }

        int schemaIncludeNum = 0;
        for(Iterator iter = schemaIncludes.iterator(); iter.hasNext();) {

            Import next = (Import) iter.next();
            String importLocationParam =
                SCHEMA_INCLUDE_LOCATION_PARAM_NAME + schemaIncludeNum;
            writer.write("\n");

            writer.write("\n");
            writer.write("");
            writer.write("");
            writer.write("");
            writer.write("");
            writer.write("");

            schemaIncludeNum++;
        }

        int endpointNum = 0;
        for(Iterator iter = endpoints.iterator(); iter.hasNext();) {
            WebServiceEndpoint endpoint = (WebServiceEndpoint) iter.next();

            if( !endpoint.hasWsdlPort() ) {
                throw new Exception("No WSDL port specified for endpoint " +
                                    endpoint.getEndpointName());
            }
            if( !endpoint.hasServiceName() ) {
                throw new Exception("Runtime settings error.  Cannot find " +
                                    "service name for endpoint " +
                                    endpoint.getEndpointName());
            }

            String actualAddressParam =
                ENDPOINT_ADDRESS_PARAM_NAME + endpointNum;

            writer.write("\n");

            writer.write("\n");

            writer.write("");
            writer.write("<"+endpoint.getSoapAddressPrefix()+":address>");
            writer.write("");

            endpointNum++;
        }

        writer.write("\n");
        writer.write("\n");
        writer.close();
        byte[] stylesheet = bos.toByteArray();

        if( logger.isLoggable(Level.FINE) ) {
            logger.fine(new String(stylesheet));
        }

        Source stylesheetSource =
            new StreamSource(new ByteArrayInputStream(stylesheet));
        TransformerFactory transformerFactory= TransformerFactory.newInstance();
        Templates templates = transformerFactory.newTemplates(stylesheetSource);

        return templates;
    }

    public static void raiseException(HttpServletResponse resp, String binding, String faultString) {
        
        resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

        if (HTTPBinding.HTTP_BINDING.equals(binding)) {
            resp.setContentType("text/xml");
            try {
                PrintWriter writer = new PrintWriter(resp.getOutputStream());
                writer.println("" + faultString + "");
            } catch(IOException ioe) {
                logger.log(Level.WARNING, LogUtils.CANNOT_WRITE_HTTPXML, ioe.getMessage());
            }
        } else {
            String protocol;
            if (SOAPBinding.SOAP12HTTP_BINDING.equals(binding)) {
                protocol = jakarta.xml.soap.SOAPConstants.SOAP_1_2_PROTOCOL;
            } else {
                protocol = jakarta.xml.soap.SOAPConstants.SOAP_1_1_PROTOCOL;
            }
            SOAPMessage fault = WsUtil.getSOAPFault(protocol, faultString);
            
            if (fault!=null) {
                resp.setContentType("text/xml");
                try {
                    fault.writeTo(resp.getOutputStream());
                } catch(Exception ex) {
                    logger.log(Level.WARNING, LogUtils.CANNOT_WRITE_SOAPFAULT, ex);
                }
            }
        }
    }
    
    public static SOAPMessage getSOAPFault(String protocol, String faultString) {

        if (protocol==null) {
            protocol = jakarta.xml.soap.SOAPConstants.SOAP_1_1_PROTOCOL;
        }
        try {
            MessageFactory factory = MessageFactory.newInstance(protocol);
            if (factory==null) {
                factory = MessageFactory.newInstance();
            }
            SOAPMessage message = factory.createMessage();
            SOAPBody body = message.getSOAPBody();
            SOAPFault fault = body.addFault();
            fault.setFaultString(faultString);
            SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
            String envelopeNamespace = envelope.getNamespaceURI();
            QName faultCode = new QName(envelopeNamespace, "Server", "env");
            fault.setFaultCode(faultCode);
            return message;
        } catch(SOAPException e) {
            logger.log(Level.WARNING, LogUtils.CANNOT_CREATE_SOAPFAULT, faultString);
        }
        return null;
    }

    void writeInvalidContentType(HttpServletResponse response)
        throws SOAPException, IOException {
        //bad client content-type
        response.setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE); 
        
        setContentTypeAndFlush(response);
    }

    void writeInvalidMethodType(HttpServletResponse response, 
                                String message) throws IOException {
        response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("");
        out.println("");
        
        out.println("Invalid Method Type");
        out.println("");
        out.println("");
        out.println(HtmlEntityEncoder.encodeXSS(message));
        out.println("");
        out.println("");
        
    }

    /*
     * Used to send back the message after a 4XX response code has been set
     */
    private void setContentTypeAndFlush(HttpServletResponse response) 
        throws IOException {
        response.setContentType("text/xml");
        response.flushBuffer(); // prevent html message in response
        response.getWriter().close();
    }
    
    boolean hasSomeTextXmlContent(MimeHeaders headers) {
        return ( hasTextXmlContentType(headers) &&
                 (getContentLength(headers) > 0) );
    }
    
    private int getContentLength(MimeHeaders headers) {
        String[] contentLength = headers.getHeader("Content-Length");

        int length = 0;

        if ((contentLength != null) && (contentLength.length > 0)) {
            length = Integer.parseInt(contentLength[0]);
        }

        return length;
    }

    boolean hasTextXmlContentType(MimeHeaders headers) {
        
        String[] contentTypes = headers.getHeader("Content-Type");
        if ((contentTypes != null) && (contentTypes.length >= 1)){
            if (contentTypes[0].indexOf("text/xml") != -1){
                return true;
            }
        }
        return false;
    }

    MimeHeaders getHeaders(HttpServletRequest request) {
        Enumeration e = request.getHeaderNames();
        MimeHeaders headers = new MimeHeaders();

        while (e.hasMoreElements()) {
            String headerName = (String)e.nextElement();
            String headerValue = request.getHeader(headerName);
            headers.addHeader(headerName, headerValue);
        }

        return headers;
    } 
    
    public WebServerInfo getWebServerInfoForDAS() {
        WebServerInfo wsi = new WebServerInfo();

        if(this.networkListeners == null) {
            List adminPorts = new ArrayList();

            for (org.glassfish.api.container.Adapter subAdapter :
            	WebServiceContractImpl.getInstance().getAdapters()) {
                if (subAdapter instanceof AdminAdapter) {
                    AdminAdapter aa = (AdminAdapter) subAdapter;
                    adminPorts.add(aa.getListenPort());
                } else if (subAdapter instanceof AdminConsoleAdapter) {
                    AdminConsoleAdapter aca = (AdminConsoleAdapter) subAdapter;
                    adminPorts.add(aca.getListenPort());
                }
            }

            for (NetworkListener nl : config.getNetworkConfig().getNetworkListeners().getNetworkListener()) {

                if(!adminPorts.contains(Integer.valueOf(nl.getPort()))) { // get rid of admin ports
                    if(networkListeners == null)
                        networkListeners = new ArrayList();

                    networkListeners.add(nl);
                }
            }
        }

        //Fix for issue 13107490
        if ((networkListeners!=null)  && (! networkListeners.isEmpty()))  {
            for(NetworkListener listener : networkListeners) {
                String host = listener.getAddress();
                if(listener.getAddress().equals("0.0.0.0"))
                    try {
                        host = InetAddress.getLocalHost().getHostName();
                    } catch (UnknownHostException e) {
                        host="localhost"; //fallback
                    }

                if(listener.findHttpProtocol().getSecurityEnabled().equals("false"))
                    wsi.setHttpVS(new VirtualServerInfo("http", host, Integer.parseInt(listener.getPort())));
                else if(listener.findHttpProtocol().getSecurityEnabled().equals("true"))
                    wsi.setHttpsVS(new VirtualServerInfo("https", host, Integer.parseInt(listener.getPort())));
            }
        } else {
            wsi.setHttpVS(new VirtualServerInfo("http", "localhost", 0));
            wsi.setHttpsVS(new VirtualServerInfo("https", "localhost", 0));
        }
        return wsi;
    }

    /**
     * @return the default Logger implementation for this package
     */
    public static Logger getDefaultLogger() {
        return logger;
    }    

    // resources...
    static LocalStringManagerImpl localStrings = 
        new LocalStringManagerImpl(WsUtil.class);
    
    public static LocalStringManagerImpl getDefaultStringManager() {
        return localStrings;
    }

    public void validateEjbEndpoint(WebServiceEndpoint ejbEndpoint) {
        EjbDescriptor ejbDescriptor = ejbEndpoint.getEjbComponentImpl();
        BundleDescriptor bundle = ejbDescriptor.getEjbBundleDescriptor();
        WebServicesDescriptor webServices = bundle.getWebServices();
        Collection endpoints = 
            webServices.getEndpointsImplementedBy(ejbDescriptor);
        if( endpoints.size() == 1 ) {
            if( ejbDescriptor.hasWebServiceEndpointInterface() ) {
                if(!ejbEndpoint.getServiceEndpointInterface().equals
                   (ejbDescriptor.getWebServiceEndpointInterfaceName())) {
                    String msg = "Ejb " + ejbDescriptor.getName() + 
                        " service endpoint interface does not match " +
                        " port component " + ejbEndpoint.getEndpointName();
                    throw new IllegalStateException(msg);
                }
            } else {
                String msg = "Ejb " + ejbDescriptor.getName() + 
                    " must declare  interface";
                throw new IllegalStateException(msg);
            }
        } else if( endpoints.size() > 1 ) {
            String msg = "Ejb " + ejbDescriptor.getName() + 
                " implements " + endpoints.size() + " web service endpoints " +
                " but must only implement 1";
            throw new IllegalStateException(msg);
        }
    }

    public void updateServletEndpointRuntime(WebServiceEndpoint endpoint) {
 
        // Copy the value of the servlet impl bean class into
        // the runtime information.  This way, we'll still 
        // remember it after the servlet-class element has been 
        // replaced with the name of the container's servlet class.
        endpoint.saveServletImplClass();

        WebComponentDescriptor webComp = 
            (WebComponentDescriptor) endpoint.getWebComponentImpl();

        WebBundleDescriptor bundle = webComp.getWebBundleDescriptor();
        WebServicesDescriptor webServices = bundle.getWebServices();
        Collection endpoints = 
            webServices.getEndpointsImplementedBy(webComp);

        if( endpoints.size() > 1 ) {
            String msg = "Servlet " + endpoint.getWebComponentLink() + 
                " implements " + endpoints.size() + " web service endpoints " +
                " but must only implement 1";
            throw new IllegalStateException(msg);
        }

        if( endpoint.getEndpointAddressUri() == null ) {
            Set urlPatterns = webComp.getUrlPatternsSet();
            if( urlPatterns.size() == 1 ) {

                // Set endpoint-address-uri runtime info to uri.
                // Final endpoint address will still be relative to context roo

                String uri = (String) urlPatterns.iterator().next();
                endpoint.setEndpointAddressUri(uri);

                // Set transport guarantee in runtime info if transport 
                // guarantee is INTEGRAL or CONDIFIDENTIAL for any 
                // security constraint with this url-pattern.
                Collection constraints = 
                    bundle.getSecurityConstraintsForUrlPattern(uri);
                for(Iterator i = constraints.iterator(); i.hasNext();) {
                    SecurityConstraint next = (SecurityConstraint) i.next();
                        
                    UserDataConstraint dataConstraint = 
                        next.getUserDataConstraint();
                    String guarantee = (dataConstraint != null) ?
                        dataConstraint.getTransportGuarantee() : null;

                    if( (guarantee != null) && 
                        ( guarantee.equals
                          (UserDataConstraint.INTEGRAL_TRANSPORT) || 
                          guarantee.equals
                          (UserDataConstraint.CONFIDENTIAL_TRANSPORT) ) ) {
                        endpoint.setTransportGuarantee(guarantee);
                        break;
                    }
                }
            } else {
                String msg = "Endpoint " + endpoint.getEndpointName() +
                    " has not been assigned an endpoint address " +
                    " and is associated with servlet " + 
                    webComp.getCanonicalName() + " , which has " +
                    urlPatterns.size() + " url patterns"; 
                throw new IllegalStateException(msg);
            } 
        }
    }    
   


    /*public void downloadFile(URL httpUrl, File toFile) throws Exception {
        InputStream is = null;
        FileOutputStream os = null;
        try {
            if(!toFile.createNewFile()) {
                throw new Exception("Unable to create new File " + toFile.getAbsolutePath());
            }
            is = httpUrl.openStream();

            os = new FileOutputStream(toFile, true);
            int readCount;
            byte[] buffer = new byte[10240]; // Read 10KB at a time
            while(true) {
                readCount = is.read(buffer, 0, 10240);
                if(readCount != -1) {
                    os.write(buffer, 0, readCount);
                } else {
                    break;
                }
            }
        } finally {
            if(is != null) {
                is.close();
            }
            if(os != null) {
                os.flush();
                os.close();
            }
        }
    }   */
    
    public Collection getWsdlsAndSchemas(File pkgedWsdl) throws Exception {
         
        ArrayList cumulative =  new ArrayList();
        getWsdlsAndSchemas(pkgedWsdl, cumulative);
	 
        //if there are circular imports of wsdls, the original wsdl might
        //be in this Collection of imported metadata documents.  If so, remove it.
        URL id = pkgedWsdl.toURL();
        SDDocumentSource toRemove = null;
        
        for (SDDocumentSource source: cumulative) {
            if ((id.toString()).equals(source.getSystemId().toString())) {
                toRemove = source;
            }
        }       
        if (toRemove != null) {
            cumulative.remove(toRemove);
        }
        
        return cumulative;
    }

    /**
     * This implementation is similar to #getWsdlsAndSchemas(File pkgedWsdl, except that this works on URL which makes
     * it easy when the wsdl is loaded from the archive. 
     * @param pkgedWsdl URL
     * @return
     * @throws Exception
     */
    public Collection getWsdlsAndSchemas(URL pkgedWsdl) throws Exception {

        ArrayList cumulative =  new ArrayList();
        getWsdlsAndSchemas(pkgedWsdl, cumulative);

        //if there are circular imports of wsdls, the original wsdl might
        //be in this Collection of imported metadata documents.  If so, remove it.
        SDDocumentSource toRemove = null;

        for (SDDocumentSource source: cumulative) {
            if ((pkgedWsdl.toString()).equals(source.getSystemId().toString())) {
                toRemove = source;
            }
        }
        if (toRemove != null) {
            cumulative.remove(toRemove);
        }

        return cumulative;
    }

    private void getWsdlsAndSchemas(URL wsdlRoot, ArrayList cumulative) throws Exception {

        // Get a list of wsdl and schema relative imports in this wsdl
        Collection wsdlRelativeImports = new HashSet();
        Collection schemaRelativeImports = new HashSet();
        Collection wsdlIncludes = new HashSet();
        Collection schemaIncludes = new HashSet();

        parseRelativeImports(wsdlRoot, wsdlRelativeImports, wsdlIncludes,
                schemaRelativeImports, schemaIncludes);

        wsdlRelativeImports.addAll(wsdlIncludes);
        schemaRelativeImports.addAll(schemaIncludes);


        // List of all schema relative imports
        for(Import next : schemaRelativeImports) {
            addFileAndDecendents(wsdlRoot.toURI().resolve(new URI(null, next.getLocation(), null).toASCIIString()).toURL(), cumulative);
        }
        // List of all wsdl relative imports
        for(Import next : wsdlRelativeImports) {
            addFileAndDecendents(wsdlRoot.toURI().resolve(new URI(null, next.getLocation(), null).toASCIIString()).toURL(), cumulative);
        }
    }

    /*
     * Add the File and wsdls and schemas imported by it to a list of metadata
     * documents used to initialize an endpoint.  Canonicalize the paths and check
     * whether the documents have already been added to the list.
     */
    private void addFileAndDecendents(URL fileUrl,
            ArrayList cumulative) throws Exception {

        //make sure we have not processed this file before
        boolean alreadyProcessed = false;

        for (SDDocumentSource source: cumulative) {
            if ((fileUrl.toString()).equals(source.getSystemId().toString())) {
                alreadyProcessed = true;
                break;
            }
        }
        if (!alreadyProcessed) {
            cumulative.add(0, SDDocumentSource.create(fileUrl));
            getWsdlsAndSchemas(fileUrl, cumulative);
        }

    }

    public void getWsdlsAndSchemas(File wsdl, 
                                   ArrayList cumulative) throws Exception {
        
        // Get a list of wsdl and schema relative imports in this wsdl
        Collection wsdlRelativeImports = new HashSet();
        Collection schemaRelativeImports = new HashSet();
        Collection wsdlIncludes = new HashSet();
        Collection schemaIncludes = new HashSet();
        String wsdlRoot = wsdl.getParent();

        parseRelativeImports(wsdl.toURL(), wsdlRelativeImports, wsdlIncludes,
                schemaRelativeImports, schemaIncludes);
        
        wsdlRelativeImports.addAll(wsdlIncludes);
        schemaRelativeImports.addAll(schemaIncludes);
      

        // List of all schema relative imports
        for(Import next : schemaRelativeImports) {
            String location = next.getLocation();
            location = location.replaceAll("/", "\\"+File.separator);
            File file = new File(wsdlRoot + File.separator + location)
                    .getCanonicalFile();
            addFileAndDecendents(file, cumulative);
        }
        // List of all wsdl relative imports
        for(Import next : wsdlRelativeImports) {
            String location = next.getLocation();
            location = location.replaceAll("/", "\\"+File.separator);

            File currentWsdlFile = new File(wsdlRoot+File.separator+location)
                    .getCanonicalFile();
            addFileAndDecendents(currentWsdlFile,  cumulative);
        }
    }

    /*
     * Add the File and wsdls and schemas imported by it to a list of metadata
     * documents used to initialize an endpoint.  Canonicalize the paths and check
     * whether the documents have already been added to the list.
     */
    private void addFileAndDecendents(File file,
            ArrayList cumulative) throws Exception {

        try {
            //JAX-WS has trouble with "..'s" in paths here
            file = file.getCanonicalFile();
        } catch (IOException e) {
            //hope JAX-WS can deal with the original path
        }

        //make sure we have not processed this file before
        URL id = file.toURL();
        boolean alreadyProcessed = false;

        for (SDDocumentSource source: cumulative) {
            if ((id.toString()).equals(source.getSystemId().toString())) {
                alreadyProcessed = true;
                break;
            }
        }
        if (!alreadyProcessed) {
            cumulative.add(0, SDDocumentSource.create(id));
            getWsdlsAndSchemas(file, cumulative);
        }

    }
    

    /*
     * Calls @PostConstruct method in the implementor
     */
    public void doPostConstruct(Class impl, Object implObj) {
        invokeServiceMethod(jakarta.annotation.PostConstruct.class, impl,
                implObj);
    }
    
    /*
     * Calls @PreDestroy method in the implementor
     */
    public void doPreDestroy(WebServiceEndpoint ep, ClassLoader loader) {
        // Call @PreDestroy in endpoint, if any
        try {
            Class impl = Class.forName(ep.getServletImplClass(),
                                true, loader);
            invokeServiceMethod(jakarta.annotation.PreDestroy.class, impl,
                    impl.newInstance());
        } catch (Throwable ex) {
            String msg = MessageFormat.format(
                    logger.getResourceBundle().getString(LogUtils.CLASS_NOT_FOUND_IN_PREDESTROY),
                    ep.getServletImplClass());
            logger.log(Level.SEVERE, msg, ex);
        }
                                                                                
        // Call @PreDestroy in the handlers if any
        if(!ep.hasHandlerChain()) {
            return;
        }
        for(Iterator hc = ep.getHandlerChain().iterator();
                                hc.hasNext();) {
            WebServiceHandlerChain thisHc = hc.next();
            for(Iterator h = thisHc.getHandlers().iterator(); 
                                    h.hasNext();) {
                WebServiceHandler thisHandler = h.next();
                try {
                    Class handlerClass = Class.forName(thisHandler.getHandlerClass(),
                                            true, loader);
                    invokeServiceMethod(jakarta.annotation.PreDestroy.class, handlerClass,
                            handlerClass.newInstance());
                } catch (Throwable ex) {
                    String msg = MessageFormat.format(
                            logger.getResourceBundle().getString(LogUtils.HANDLER_NOT_FOUND_IN_PREDESTROY),
                            thisHandler.getHandlerClass());
                    logger.log(Level.SEVERE, msg, ex);
                }
            }
        }        
    }

    
    /*
     * Calls the PostConstruct / PreDestroy method
     */
    private void invokeServiceMethod(Class annType, Class impl, final Object implObj) {
        Method[] methods = impl.getDeclaredMethods();
        // Only one method can have @PostConstruct / @PreDestroy
        // Call the first method with this annotation and return
        for(final Method method : methods) {
            if (method.getAnnotation(annType) != null) {
                try {
                    AccessController.doPrivileged(new PrivilegedExceptionAction() {
                        public Object run() throws IllegalAccessException,
                                InvocationTargetException {
                            if (!method.isAccessible()) {
                                method.setAccessible(true);
                            }
                            method.invoke(implObj, new Object[] {});
                            return null;
                        }
                    });
                } catch(Throwable e) {
                    // Should we log or throw an exception
                    logger.log(Level.SEVERE, LogUtils.FAILURE_CALLING_POST_PRE, e);
                }
                break;
            } 
        }
    }
    
    private boolean matchQNamePatterns(QName cfgQName, QName givenPattern) {
        if (givenPattern.getNamespaceURI().equals(cfgQName.getNamespaceURI())) {
            String expr = givenPattern.getLocalPart().replaceAll("\\*",  ".*");
            return java.util.regex.Pattern.matches(expr, cfgQName.getLocalPart());
        }
        return false;        
    }

    private boolean patternsMatch(WebServiceHandlerChain hc, QName svcName,
                                    QName portName, String bindingId) {
        // If service name pattern in handler chain does not match the service name
        // for this endpoint, skip handler processing
        if(hc.getServiceNamePattern() != null && svcName != null) {
            QName svcPattern = QName.valueOf(hc.getServiceNamePattern());
            if(!matchQNamePatterns(svcName, svcPattern)) {
                return false;
            }
        }

        // If port name pattern in handler chain does not match the port name
        // for this endpoint, skip handler processing
        if(hc.getPortNamePattern() != null && portName != null) {
            QName portPattern = QName.valueOf(hc.getPortNamePattern());
            if(!matchQNamePatterns(portName, portPattern)) {
                return false;
            }
        }

        // Check if the binding protocol for this endpoint is present
        // as part of the protocol-bindings list
        if(hc.getProtocolBindings() != null && bindingId != null) {
            String givenBindings = hc.getProtocolBindings();
            if( (bindingId.equals(HTTPBinding.HTTP_BINDING)) &&
                ((givenBindings.indexOf(HTTPBinding.HTTP_BINDING) != -1) ||
                 (givenBindings.indexOf(WebServiceEndpoint.XML_TOKEN) != -1))) {
                return true;
            }
            if( (bindingId.equals(SOAPBinding.SOAP11HTTP_BINDING)) &&
                ((givenBindings.indexOf(SOAPBinding.SOAP11HTTP_BINDING) != -1) ||
                 (givenBindings.indexOf(WebServiceEndpoint.SOAP11_TOKEN) != -1))) {
                return true;
            }
            if( (bindingId.equals(SOAPBinding.SOAP12HTTP_BINDING)) &&
                ((givenBindings.indexOf(SOAPBinding.SOAP12HTTP_BINDING) != -1) ||
                 (givenBindings.indexOf(WebServiceEndpoint.SOAP12_TOKEN) != -1))) {
                return true;
            }
            if( (bindingId.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING)) &&
                ((givenBindings.indexOf(SOAPBinding.SOAP11HTTP_MTOM_BINDING) != -1) ||
                 (givenBindings.indexOf(WebServiceEndpoint.SOAP11_MTOM_TOKEN) != -1))) {
                return true;
            }
            if( (bindingId.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING)) &&
                ((givenBindings.indexOf(SOAPBinding.SOAP12HTTP_MTOM_BINDING) != -1) ||
                 (givenBindings.indexOf(WebServiceEndpoint.SOAP12_MTOM_TOKEN) != -1))) {
                return true;
            }
        }
        return true;
    }
     
    private List processConfiguredHandlers(List handlersList, Set roles) {
        List handlerChain = new ArrayList();
        for(WebServiceHandler h : handlersList) {
            Handler handler = null;

            ClassLoader loader = Thread.currentThread().getContextClassLoader();
            // Get Handler Class instance
            Class handlerClass;
            try {
                handlerClass = Class.forName(h.getHandlerClass(), true, loader);
            } catch (Throwable t) {
                String msg = MessageFormat.format(
                        logger.getResourceBundle().getString(LogUtils.HANDLER_UNABLE_TO_ADD),
                        h.getHandlerClass());
                logger.log(Level.SEVERE, msg, t);
                
                continue;
            }
            
            // perform injection
            try {          
                WebServiceContractImpl wscImpl = WebServiceContractImpl.getInstance();
                InjectionManager injManager = wscImpl.getInjectionManager(); 
                //PostConstruct is invoked by createManagedObject as well
                handler = (Handler) injManager.createManagedObject(handlerClass);
            } catch(InjectionException e) {
                logger.log(Level.SEVERE, LogUtils.HANDLER_INJECTION_FAILED,
                        new Object[] {h.getHandlerClass(), e.getMessage()});
                continue;
            }
            
            // Add soap-roles
            Collection rolesColl = h.getSoapRoles();
            roles.addAll(rolesColl);
            
            // Add this handler to the mail list
            handlerChain.add(handler);
        }
        return handlerChain;
    }            
    
    public void configureJAXWSServiceHandlers(WebServiceEndpoint ep, 
            String bindingId, WSBinding bindingObj) {
        // No handler chains; do nothing
        if(!ep.hasHandlerChain()) {
            return;
        }
        LinkedList handlerChainList = ep.getHandlerChain();
        List finalHandlerList = new ArrayList();
        Set roles = new HashSet();
        for(Iterator i = handlerChainList.iterator(); i.hasNext();) {
            WebServiceHandlerChain hc = i.next();
            // Apply the serviceName / portName / bindings filter to ensure
            // that the handlers are for this endpoint
            if(!patternsMatch(hc, ep.getServiceName(), ep.getWsdlPort(), bindingId)) {
                continue;
            }
            // OK - this handler has to be configured for this endpoint
            // Iterate through all handlers that have been configured
            List handlerInfo = processConfiguredHandlers(hc.getHandlers(), roles);
            finalHandlerList.addAll(handlerInfo);
        }
        // Processing of all handlers over; 
        // set final list of handler in RuntimeEndpointInfo
        bindingObj.setHandlerChain(finalHandlerList);
        // Set soap roles for soap bindings only
        if(bindingObj instanceof jakarta.xml.ws.soap.SOAPBinding) {
            ((jakarta.xml.ws.soap.SOAPBinding)bindingObj).setRoles(roles);
        }        
    }

    public void configureJAXWSClientHandlers(jakarta.xml.ws.Service svcClass, ServiceReferenceDescriptor desc) {

        // Create a resolver and get all ports for the Service

        HandlerResolverImpl resolver = new HandlerResolverImpl();

        Set roles = new HashSet();
        
        Iterator ports = svcClass.getPorts();

        // Set handler chain for each port of this service
        while(ports.hasNext()) {
            QName nextPort = ports.next();
            LinkedList handlerChainList = desc.getHandlerChain();
            for(Iterator i = handlerChainList.iterator(); i.hasNext();) {
                WebServiceHandlerChain hc = i.next();
                // Apply the serviceName / portName filter to ensure
                // that the handlers are for this service and this port
                if(!patternsMatch(hc, desc.getServiceName(), nextPort, null)) {
                    continue;
                }
                // Decide for what all protocols this handler should be applied
                ArrayList protocols = new ArrayList();
                if(hc.getProtocolBindings() == null) {
                    // No protocol bindings given in descriptor; apply this handler
                    // for all protocols
                    protocols.add(HTTPBinding.HTTP_BINDING);
                    protocols.add(SOAPBinding.SOAP11HTTP_BINDING);
                    protocols.add(SOAPBinding.SOAP12HTTP_BINDING);
                    protocols.add(SOAPBinding.SOAP11HTTP_MTOM_BINDING);
                    protocols.add(SOAPBinding.SOAP12HTTP_MTOM_BINDING);
                } else {
                    // protocols specified; handlers are for only these protocols
                    String specifiedProtocols = hc.getProtocolBindings();
                    if((specifiedProtocols.indexOf(HTTPBinding.HTTP_BINDING) != -1) ||
                         (specifiedProtocols.indexOf(WebServiceEndpoint.XML_TOKEN) != -1)) {
                        protocols.add(HTTPBinding.HTTP_BINDING);
                    }
                    if((specifiedProtocols.indexOf(SOAPBinding.SOAP11HTTP_BINDING) != -1) ||
                         (specifiedProtocols.indexOf(WebServiceEndpoint.SOAP11_TOKEN) != -1)) {
                        protocols.add(SOAPBinding.SOAP11HTTP_BINDING);
                    }
                    if((specifiedProtocols.indexOf(SOAPBinding.SOAP12HTTP_BINDING) != -1) ||
                         (specifiedProtocols.indexOf(WebServiceEndpoint.SOAP12_TOKEN) != -1)) {
                        protocols.add(SOAPBinding.SOAP12HTTP_BINDING);
                    }                    
                    if((specifiedProtocols.indexOf(SOAPBinding.SOAP11HTTP_MTOM_BINDING) != -1) ||
                         (specifiedProtocols.indexOf(WebServiceEndpoint.SOAP11_MTOM_TOKEN) != -1)) {
                        protocols.add(SOAPBinding.SOAP11HTTP_MTOM_BINDING);
                    }
                    if((specifiedProtocols.indexOf(SOAPBinding.SOAP12HTTP_MTOM_BINDING) != -1) ||
                         (specifiedProtocols.indexOf(WebServiceEndpoint.SOAP12_MTOM_TOKEN) != -1)) {
                        protocols.add(SOAPBinding.SOAP12HTTP_MTOM_BINDING);
                    }                    
                }
                // Iterate through all handlers that have been configured
                List handlersList = hc.getHandlers();
                // From this list, remove those handlers that have port-name that is different
                // than the current port
                for(WebServiceHandler thisOne : handlersList) {
                    Collection portNames = thisOne.getPortNames();
                    if(!portNames.isEmpty() && 
                        !portNames.contains(nextPort.getLocalPart())) {
                        handlersList.remove(thisOne);
                    }
                }
                // Now you have the handlers that need to be added; process them
                List handlerInfo = processConfiguredHandlers(handlersList, roles);
                // Now you have the handler list; Set it in resolver;
                // one set for each protocol
                for(Iterator s = protocols.iterator(); s.hasNext();) {
                    jakarta.xml.ws.handler.PortInfo portInfo;
                    portInfo = new PortInfoImpl(BindingID.parse(s.next()),
                                    nextPort, desc.getServiceName());
                    resolver.setHandlerChain(portInfo, handlerInfo);
                }
            }
        }
        // Now that processing of all handlers is over, set HandlerResolver for 
	// the service

        svcClass.setHandlerResolver(resolver);
        
        //XXX TODO : What to do with soap roles on client side ?
    }

    /* This util is to implement the jaxws table that defines how MTOM is set
    *  
    *   BindingType                        -  enable-mtom in DD  - final MTOM value
    *
    *   SOAPXX_BINDING                            none                        false
    *   SOAPXX_BINDING                            false                         false
    *   SOAPXX_BINDING                            true                          true
    *   SOAPXX_MTOM_BINDING               none                         true
    *   SOAPXX_MTOM_BINDING               false                         false
    *   SOAPXX_MTOM_BINDING               true                          true
    */
    public boolean getMtom(WebServiceEndpoint ep) {
        String currentBinding = ep.getProtocolBinding();
        if((ep.getMtomEnabled() == null) &&
            (SOAPBinding.SOAP11HTTP_MTOM_BINDING.equals(currentBinding) ||
             SOAPBinding.SOAP12HTTP_MTOM_BINDING.equals(currentBinding))) {
            return true;
        }
        if(( Boolean.valueOf(ep.getMtomEnabled())).booleanValue() && 
            (SOAPBinding.SOAP11HTTP_BINDING.equals(currentBinding) ||
             SOAPBinding.SOAP12HTTP_BINDING.equals(currentBinding) ||
             SOAPBinding.SOAP11HTTP_MTOM_BINDING.equals(currentBinding) ||
             SOAPBinding.SOAP12HTTP_MTOM_BINDING.equals(currentBinding))) {
            return true;
        }
        return false;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy