methodmarshallerutils.java

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

JAVA
1,273
字号
/*
 * 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.marshaller.impl.alt;

import org.apache.axis2.java.security.AccessController;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.description.AttachmentDescription;
import org.apache.axis2.jaxws.description.AttachmentType;
import org.apache.axis2.jaxws.description.EndpointDescription;
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.i18n.Messages;
import org.apache.axis2.jaxws.message.Block;
import org.apache.axis2.jaxws.message.Message;
import org.apache.axis2.jaxws.message.Protocol;
import org.apache.axis2.jaxws.message.XMLFault;
import org.apache.axis2.jaxws.message.XMLFaultReason;
import org.apache.axis2.jaxws.message.databinding.JAXBBlockContext;
import org.apache.axis2.jaxws.message.databinding.JAXBUtils;
import org.apache.axis2.jaxws.message.factory.JAXBBlockFactory;
import org.apache.axis2.jaxws.message.util.XMLFaultUtils;
import org.apache.axis2.jaxws.registry.FactoryRegistry;
import org.apache.axis2.jaxws.runtime.description.marshal.AnnotationDesc;
import org.apache.axis2.jaxws.runtime.description.marshal.FaultBeanDesc;
import org.apache.axis2.jaxws.runtime.description.marshal.MarshalServiceRuntimeDescription;
import org.apache.axis2.jaxws.runtime.description.marshal.MarshalServiceRuntimeDescriptionFactory;
import org.apache.axis2.jaxws.utility.ClassUtils;
import org.apache.axis2.jaxws.utility.ConvertUtils;
import org.apache.axis2.jaxws.utility.SAAJFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.activation.DataHandler;
import javax.jws.WebService;
import javax.jws.WebParam.Mode;
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPFault;
import javax.xml.stream.XMLStreamException;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Holder;
import javax.xml.ws.ProtocolException;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.soap.SOAPFaultException;

import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TreeSet;

/** Static Utilty Classes used by the MethodMarshaller implementations in the alt package. */
public class MethodMarshallerUtils {

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

    private static JAXBBlockFactory factory =
            (JAXBBlockFactory)FactoryRegistry.getFactory(JAXBBlockFactory.class);

    /** Intentionally Private.  This is a static utility class */
    private MethodMarshallerUtils() {
    }

    /**
     * Returns the list of PDElements that need to be marshalled onto the wire
     *
     * @param marshalDesc
     * @param params          ParameterDescription for this operation
     * @param sigArguments    arguments
     * @param isInput         indicates if input or output  params(input args on client, 
     *                        output args on server)
     * @param isDocLitWrapped
     * @param isRPC
     * @return PDElements
     */
    static List<PDElement> getPDElements(MarshalServiceRuntimeDescription marshalDesc,
                                         ParameterDescription[] params,
                                         Object[] sigArguments,
                                         boolean isInput,
                                         boolean isDocLitWrapped,
                                         boolean isRPC) {
        List<PDElement> pdeList = new ArrayList<PDElement>();

        int index = 0;
        for (int i = 0; i < params.length; i++) {
            ParameterDescription pd = params[i];

            if (pd.getMode() == Mode.IN && isInput ||
                    pd.getMode() == Mode.INOUT ||
                    pd.getMode() == Mode.OUT && !isInput) {

                // Get the matching signature argument
                Object value = sigArguments[i];

                // Don't consider async handlers, they are are not represented on the wire,
                // thus they don't have a PDElement
                if (isAsyncHandler(value)) {
                    continue;
                }

                // Convert from Holder into value
                if (isHolder(value)) {
                    value = ((Holder)value).value;
                }

                // Get the formal type representing the value
                Class formalType = pd.getParameterActualType();

                // The namespace and local name are obtained differently depending on 
                // the style/use and header
                QName qName = null;
                if (pd.isHeader()) {
                    // Headers (even rpc) are marshalled with the name defined by the 
                    // element= attribute on the wsd:part
                    qName = new QName(pd.getTargetNamespace(), pd.getParameterName());
                } else if (isDocLitWrapped) {
                    // For doc/lit wrapped, the localName comes from the PartName
                    qName = new QName(pd.getTargetNamespace(), pd.getPartName());
                } else if (isRPC) {
                    // Per WSI-BP, the namespace uri is unqualified
                    qName = new QName(pd.getPartName());
                } else {
                    qName = new QName(pd.getTargetNamespace(), pd.getParameterName());
                }

                // Create an Element rendering
                Element element = null;
                AttachmentDescription attachmentDesc = pd.getAttachmentDescription();
                if (attachmentDesc != null) {
                    PDElement pde = createPDElementForAttachment(pd, qName, value, formalType);
                    pdeList.add(pde);
                } else {
                    if (!marshalDesc.getAnnotationDesc(formalType).hasXmlRootElement()) {
                        /* when a schema defines a SimpleType with xsd list jaxws tooling 
                         * generates artifacts with array rather than a java.util.List
                         * However the ObjectFactory definition uses a List and thus 
                         * marshalling fails. Lets convert the Arrays to List and recreate
                         * the JAXBElements for the same.
                         */
                        if (pd.isListType()) {
                            
                            List<Object> list = new ArrayList<Object>();
                            if (formalType.isArray()) {
                                for (int count = 0; count < Array.getLength(value); count++) {
                                    Object obj = Array.get(value, count);
                                    list.add(obj);
                                }

                            }
                            element = new Element(list, qName, List.class);
                        } else {
                            element = new Element(value, qName, formalType);
                        }
                      }
                    else{
                        element = new Element(value, qName);
                    }
                    // The object is now ready for marshalling
                    PDElement pde = new PDElement(pd, element, null);
                    pdeList.add(pde);
                }
            }
        }

        return pdeList;
    }
    
    /**
     * @param pd
     * @param qName
     * @param value
     * @param formalType
     * @return
     */
    private static PDElement createPDElementForAttachment(ParameterDescription pd, 
                                                          QName qName, 
                                                          Object value, 
                                                          Class formalType) {
        PDElement pde;
        if (log.isDebugEnabled()) {
            log.debug("Creating a PDElement for an attachment value: " + 
                      ((value == null)? "null":value.getClass().getName()));
            log.debug("ParameterDescription = " + pd.toString());
        }
        AttachmentDescription attachmentDesc = pd.getAttachmentDescription();
        
        AttachmentType attachmentType = attachmentDesc.getAttachmentType();
        if (attachmentType == AttachmentType.SWA) {
            // Create an Attachment object with the signature value
            Attachment attachment = new Attachment(value, 
                                                   formalType, 
                                                   attachmentDesc);  
            pde = new PDElement(pd, 
                    null, // For SWA Attachments, there is no element reference to the attachment
                    null, 
                    attachment);
        } else {
            // TODO NLS and clean this up
            throw ExceptionFactory.
            makeWebServiceException("SWAREF and MTOM attachment parameters are not " +
                        "supported in this style/use.");
        }
        return pde;
    }

    /**
     * Return the list of PDElements that is unmarshalled from the wire
     * 
     * @param params ParameterDescription for this operation
     * @param message Message
     * @param packages set of packages needed to unmarshal objects for this operation
     * @param isInput indicates if input or output  params (input on server, output on client)
     * @param hasReturnInBody if isInput=false, then this parameter indicates whether a 
     * return value is expected in the body.
     * @param unmarshalByJavaType in most scenarios this is null.  
     * Only use this in the scenarios that require unmarshalling by java type
     * @return ParamValues
     */
    static List<PDElement> getPDElements(ParameterDescription[] params,
                                         Message message,
                                         TreeSet<String> packages,
                                         boolean isInput,
                                         boolean hasReturnInBody, 
                                         Class[] unmarshalByJavaType) throws XMLStreamException {

        List<PDElement> pdeList = new ArrayList<PDElement>();

        // Count 
        int totalBodyBlocks = 0;
        for (int i = 0; i < params.length; i++) {
            ParameterDescription pd = params[i];

            if (pd.getMode() == Mode.IN && isInput ||
                    pd.getMode() == Mode.INOUT ||
                    pd.getMode() == Mode.OUT && !isInput) {
                if (!pd.isHeader() && !isSWAAttachment(pd)) {
                    totalBodyBlocks++;
                }
            }
        }

        if (!isInput && hasReturnInBody) {
            totalBodyBlocks++;
        }
            
        int index = (!isInput && hasReturnInBody) ? 1 : 0;
        // TODO What if return is an swa attachment, then this should start
        // at 1 not 0.
        int swaIndex = 0;
        for (int i = 0; i < params.length; i++) {
            ParameterDescription pd = params[i];

            if (pd.getMode() == Mode.IN && isInput ||
                    pd.getMode() == Mode.INOUT ||
                    pd.getMode() == Mode.OUT && !isInput) {

                // Don't consider async handlers, they are are not represented on the wire,
                // thus they don't have a PDElement
                // TODO
                //if (isAsyncHandler(param)) {
                //    continue;
                //}

                Block block = null;
                JAXBBlockContext context = new JAXBBlockContext(packages);

                AttachmentDescription attachmentDesc = pd.getAttachmentDescription();
                if (attachmentDesc == null) {
                    
                    // Normal Processing: Not an Attachment
                    // Trigger unmarshal by java type if necessary
                    if (unmarshalByJavaType != null && unmarshalByJavaType[i] != null) {
                        context.setProcessType(unmarshalByJavaType[i]);
                        context.setIsxmlList(pd.isListType());
                    }
                    
                    // Unmarshal the object into a JAXB object or JAXBElement
                    if (pd.isHeader()) {
                        
                        // Get the Block from the header
                        // NOTE The parameter name is always used to get the header 
                        // element...even if the style is RPC.
                        String localName = pd.getParameterName();
                        block = message.getHeaderBlock(pd.getTargetNamespace(),
                                                       localName,
                                                       context,
                                                       factory);
                    } else {
                        if (totalBodyBlocks > 1) {

⌨️ 快捷键说明

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