packagesetbuilder.java

来自「开源的axis2框架的源码。用于开发WEBSERVER」· Java 代码 · 共 518 行 · 第 1/2 页

JAVA
518
字号
/*
 * 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.runtime.description.marshal.impl;

import org.apache.axis2.java.security.AccessController;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.description.EndpointDescription;
import org.apache.axis2.jaxws.description.EndpointDescriptionJava;
import org.apache.axis2.jaxws.description.EndpointInterfaceDescription;
import org.apache.axis2.jaxws.description.FaultDescription;
import org.apache.axis2.jaxws.description.OperationDescription;
import org.apache.axis2.jaxws.description.ParameterDescription;
import org.apache.axis2.jaxws.description.ServiceDescription;
import org.apache.axis2.jaxws.description.ServiceDescriptionWSDL;
import org.apache.axis2.jaxws.runtime.description.marshal.AnnotationDesc;
import org.apache.axis2.jaxws.runtime.description.marshal.FaultBeanDesc;
import org.apache.axis2.jaxws.runtime.description.marshal.MarshalServiceRuntimeDescription;
import org.apache.axis2.jaxws.util.WSDL4JWrapper;
import org.apache.axis2.jaxws.util.WSDLWrapper;
import org.apache.axis2.jaxws.utility.ClassUtils;
import org.apache.axis2.jaxws.utility.JavaUtils;
import org.apache.axis2.jaxws.wsdl.SchemaReader;
import org.apache.axis2.jaxws.wsdl.SchemaReaderException;
import org.apache.axis2.jaxws.wsdl.impl.SchemaReaderImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.wsdl.Definition;
import javax.wsdl.WSDLException;
import javax.xml.bind.JAXBElement;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Collection;
import java.util.Set;
import java.util.TreeSet;

/**
 * In order to marshal or unmarshal the user data, we need to know the set of packages involved.
 * The set of packages is used to construct an appropriate JAXBContext object during the
 * marshalling/unmarshalling.
 * <p/>
 * There are two ways to get this data.
 * <p/>
 * Schema Walk (preferred):  Get the list of packages by walking the schemas that are referenced by
 * the wsdl (or generated wsdl).  Each schema represents a different package.  The package is
 * obtained using the jaxb customization or JAXB default ns<->package rule.
 * <p/>
 * Annotation Walk(secondary) : Walk the list of Endpoints, Operations, Parameters, etc. and build a
 * list of packages by looking at the classes involved.
 * <p/>
 * The Schema Walk is faster and more complete, but relies on the presence of the schema or wsdl.
 * <p/>
 * The Annotation Walk is slower and is not complete.  For example, the annotation walk may not
 * discover the packages for derived types that are defined in a different schema than the formal
 * parameter types.
 */
public class PackageSetBuilder {

    private static Log log = LogFactory.getLog(PackageSetBuilder.class);

    /** This is a static utility class.  The constructor is intentionally private */
    private PackageSetBuilder() {
    }

    /**
     * Walks the schemas of the serviceDesc's wsdl (or generated wsdl) to determine the list of
     * packages. This is the preferred algorithm for discovering the package set.
     *
     * @param serviceDesc ServiceDescription
     * @return Set of Packages
     */
    public static TreeSet<String> getPackagesFromSchema(ServiceDescription serviceDesc) {

        TreeSet<String> set = new TreeSet<String>();
        //If we are on client side we will get wsdl definition from ServiceDescription. If we are on server side we will have to
        //read wsdlLocation from @WebService Annotation.
        ServiceDescriptionWSDL sdw = (ServiceDescriptionWSDL)serviceDesc;
        Definition wsdlDefinition = sdw.getWSDLDefinition();
        Collection<EndpointDescription> endpointDescs = serviceDesc.getEndpointDescriptions_AsCollection();
        if (endpointDescs != null) {
            for (EndpointDescription ed:endpointDescs) {

                if (wsdlDefinition == null) {
                    // TODO I don't think we should be trying to load the wsdlDefinition here.

                    //Let see if we can get wsdl definition from endpoint @WebService annotation.
                    if (ed instanceof EndpointDescriptionJava) {
                        String wsdlLocation =
                                ((EndpointDescriptionJava)ed).getAnnoWebServiceWSDLLocation();
                        wsdlDefinition = getWSDLDefinition(wsdlLocation);
                    }
                }
                //So at this point either we got wsdl definition from ServiceDescription (which means we are running this code
                //on client side) or we got it from the @WebService annotation (which means we are running this code on server side)
                if (wsdlDefinition != null) {
                    SchemaReader sr = new SchemaReaderImpl();
                    try {
                        Set<String> pkgSet = sr.readPackagesFromSchema(wsdlDefinition);
                        set.addAll(pkgSet);
                    } catch (SchemaReaderException e) {
                        ExceptionFactory.makeWebServiceException(e);
                    }
                }
            }
        }
        return set;
    }

    /**
     * @param serviceDescription ServiceDescription
     * @return Set of Packages
     */
    public static TreeSet<String> getPackagesFromAnnotations(ServiceDescription serviceDesc,
                                                             MarshalServiceRuntimeDescription msrd) {
        TreeSet<String> set = new TreeSet<String>();
        Collection<EndpointDescription> endpointDescs = serviceDesc.getEndpointDescriptions_AsCollection();
        
        // Build a set of packages from all of the endpoints
        if (endpointDescs != null) {
            for (EndpointDescription endpointDesc: endpointDescs) {
                set.addAll(getPackagesFromAnnotations(endpointDesc, msrd));
            }
        }
        return set;
    }

    /**
     * @param endpointDesc EndpointDescription
     * @return Set of Packages
     */
    private static TreeSet<String> getPackagesFromAnnotations(EndpointDescription endpointDesc,
                                                              MarshalServiceRuntimeDescription msrd) {
        EndpointInterfaceDescription endpointInterfaceDesc =
                endpointDesc.getEndpointInterfaceDescription();
        if (endpointInterfaceDesc == null) {
            return new TreeSet<String>();
        } else {
            return getPackagesFromAnnotations(endpointInterfaceDesc, msrd);
        }
    }

    /**
     * @param endpointInterfaceDescription EndpointInterfaceDescription
     * @return Set of Packages
     */
    private static TreeSet<String> getPackagesFromAnnotations(
            EndpointInterfaceDescription endpointInterfaceDesc,
            MarshalServiceRuntimeDescription msrd) {
        TreeSet<String> set = new TreeSet<String>();
        OperationDescription[] opDescs = endpointInterfaceDesc.getOperations();

        // Build a set of packages from all of the opertions
        if (opDescs != null) {
            for (int i = 0; i < opDescs.length; i++) {
                getPackagesFromAnnotations(opDescs[i], set, msrd);
            }
        }
        return set;
    }

    /**
     * Update the package set with the packages referenced by this OperationDesc
     *
     * @param opDesc OperationDescription
     * @param set    Set<Package> that is updated
     */
    private static void getPackagesFromAnnotations(OperationDescription opDesc, TreeSet<String> set,
                                                   MarshalServiceRuntimeDescription msrd) {

        // Walk the parameter information
        ParameterDescription[] parameterDescs = opDesc.getParameterDescriptions();
        if (parameterDescs != null) {
            for (int i = 0; i < parameterDescs.length; i++) {
                getPackagesFromAnnotations(parameterDescs[i], set, msrd);
            }
        }

        // Walk the fault information
        FaultDescription[] faultDescs = opDesc.getFaultDescriptions();
        if (faultDescs != null) {
            for (int i = 0; i < faultDescs.length; i++) {
                getPackagesFromAnnotations(faultDescs[i], set, msrd);
            }
        }

        // Also consider the request and response wrappers
        String pkg = getPackageFromClassName(msrd.getRequestWrapperClassName(opDesc));
        if (log.isDebugEnabled()) {
            log.debug("Package from Request Wrapper annotation = " + pkg);
        }
        if (pkg != null) {
            set.add(pkg);
        }
        pkg = getPackageFromClassName(msrd.getResponseWrapperClassName(opDesc));
        if (log.isDebugEnabled()) {
            log.debug("Package from Response Wrapper annotation = " + pkg);
        }
        if (pkg != null) {
            set.add(pkg);
        }

        // Finally consider the result type
        Class cls = opDesc.getResultActualType();
        if (cls != null && cls != void.class && cls != Void.class) {
            Package returnTypePkg = cls.getPackage();
            if (log.isDebugEnabled()) {
                log.debug("Package from Return Type = " + pkg);
            }
            if (returnTypePkg != null) {
                pkg = returnTypePkg.getName();
                set.add(pkg);
            }
        }
    }

    /**
     * Update the package set with the packages referenced by this ParameterDescription
     *
     * @param paramDesc ParameterDesc
     * @param set       Set<Package> that is updated
     */
    private static void getPackagesFromAnnotations(ParameterDescription paramDesc,
                                                   TreeSet<String> set,
                                                   MarshalServiceRuntimeDescription msrd) {

        // Get the type that defines the actual data.  (this is never a holder )
        Class paramClass = paramDesc.getParameterActualType();

        if (paramClass != null) {
            setTypeAndElementPackages(paramClass, paramDesc.getTargetNamespace(),
                                      paramDesc.getPartName(), set, msrd);
        }

    }

    /**
     * Update the package set with the packages referenced by this FaultDescription
     *

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?