methodmarshallerutils.java

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

JAVA
1,273
字号
                            // You must use this method if there are more than one body block
                            // This method may cause OM expansion
                            block = message.getBodyBlock(index, context, factory);
                        } else {
                            // Use this method if you know there is only one body block.
                            // This method prevents OM expansion.
                            block = message.getBodyBlock(context, factory);
                        }
                        index++;
                    }
                    
                    Element element = new Element(block.getBusinessObject(true), 
                                                  block.getQName());
                    PDElement pde =
                        new PDElement(pd, element, unmarshalByJavaType == null ? null
                                : unmarshalByJavaType[i]);
                    pdeList.add(pde);
                } else {
                    // Attachment Processing
                    if (attachmentDesc.getAttachmentType() == AttachmentType.SWA) {
                        String cid = message.getAttachmentID(swaIndex);
                        DataHandler dh = message.getDataHandler(cid);
                        Attachment attachment = new Attachment(dh, cid);
                        PDElement pde = new PDElement(pd, null, null, attachment);
                        pdeList.add(pde);
                        swaIndex++;
                    } else {
                        // TODO NLS and clean this up
                        throw ExceptionFactory.makeWebServiceException("SWAREF and MTOM " +
                                        "attachment parameters are not supported " +
                                        "in this style/use.");
                    }
                }
            }
        }

        return pdeList;
    }

    /**
     * Creates the request signature arguments (server) from a list
     * of element eabled object (PDEements)
     * @param pds ParameterDescriptions for this Operation
     * @param pvList Element enabled object
     * @return Signature Args
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws ClassNotFoundException
     */
    static Object[] createRequestSignatureArgs(ParameterDescription[] pds, 
                                               List<PDElement> pdeList)
    throws InstantiationException, IOException,
    IllegalAccessException,
    ClassNotFoundException {
        Object[] args = new Object[pds.length];
        int pdeIndex = 0;
        for (int i = 0; i < args.length; i++) {
            // Get the paramValue
            PDElement pde = (pdeIndex < pdeList.size()) ? pdeList.get(pdeIndex) : null;
            ParameterDescription pd = pds[i];
            if (pde == null ||
                    pde.getParam() != pd) {
                // We have a ParameterDesc but there is not an equivalent PDElement. 
                // Provide the default
                if (pd.isHolderType()) {
                    args[i] = createHolder(pd.getParameterType(), null);
                } else {
                    args[i] = null;
                }
            } else {

                // We have a matching paramValue.  Get the type object that represents the type
                Object value = null;
                if (pde.getAttachment() != null) {
                    value = pde.getAttachment().getDataHandler();
                } else {
                    value = pde.getElement().getTypeValue();
                }
                pdeIndex++;

                // Now that we have the type, there may be a mismatch
                // between the type (as defined by JAXB) and the formal
                // parameter (as defined by JAXWS).  Frequently this occurs
                // with respect to T[] versus List<T>.  
                // Use the convert utility to silently do any conversions
                if (ConvertUtils.isConvertable(value, pd.getParameterActualType())) {
                    value = ConvertUtils.convert(value, pd.getParameterActualType());
                } else {
                    String objectClass = (value == null) ? "null" : value.getClass().getName();
                    throw ExceptionFactory.makeWebServiceException(
                            Messages.getMessage("convertProblem", objectClass,
                                                pd.getParameterActualType().getName()));
                }

                // The signature may want a holder representation
                if (pd.isHolderType()) {
                    args[i] = createHolder(pd.getParameterType(), value);
                } else {
                    args[i] = value;
                }
            }

        }
        return args;
    }

    /**
     * Update the signature arguments on the client with the unmarshalled element enabled objects
     * (pvList)
     *
     * @param pds           ParameterDescriptions
     * @param pdeList       Element Enabled objects
     * @param signatureArgs Signature Arguments (the out/inout holders are updated)
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws ClassNotFoundException
     */
    static void updateResponseSignatureArgs(ParameterDescription[] pds, List<PDElement> pdeList,
                                            Object[] signatureArgs)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        int pdeIndex = 0;

        // Each ParameterDescriptor has a correspondinging signatureArg from the 
        // the initial client call.  The pvList contains the response values from the message.
        // Walk the ParameterDescriptor/SignatureArg list and populate the holders with 
        // the match PDElement
        for (int i = 0; i < pds.length; i++) {
            // Get the param value
            PDElement pde = (pdeIndex < pdeList.size()) ? pdeList.get(pdeIndex) : null;
            ParameterDescription pd = pds[i];
            if (pde != null && pde.getParam() == pd) {
                // We have a matching paramValue.  Get the value that represents the type
                Object value = null;
                if (pde.getAttachment() == null) {
                    value = pde.getElement().getTypeValue();
                } else {
                    value = pde.getAttachment().getDataHandler();
                }
                pdeIndex++;

                // Now that we have the type, there may be a mismatch
                // between the type (as defined by JAXB) and the formal
                // parameter (as defined by JAXWS).  Frequently this occurs
                // with respect to T[] versus List<T>.  
                // Use the convert utility to silently do any conversions
                if (ConvertUtils.isConvertable(value, pd.getParameterActualType())) {
                    value = ConvertUtils.convert(value, pd.getParameterActualType());
                } else {
                    String objectClass = (value == null) ? "null" : value.getClass().getName();
                    throw ExceptionFactory.makeWebServiceException(
                            Messages.getMessage("convertProblem", objectClass,
                                                pd.getParameterActualType().getName()));
                }

                // TODO Assert that this ParameterDescriptor must represent
                // an OUT or INOUT and must have a non-null holder object to 
                // store the value
                if (isHolder(signatureArgs[i])) {
                    ((Holder)signatureArgs[i]).value = value;
                }
            }
        }
    }

    /**
     * Marshal the element enabled objects (pvList) to the Message
     *
     * @param pdeList  element enabled objects
     * @param message  Message
     * @param packages Packages needed to do a JAXB Marshal
     * @throws MessageException
     */
    static void toMessage(List<PDElement> pdeList,
                          Message message,
                          TreeSet<String> packages) throws WebServiceException {

        int totalBodyBlocks = 0;
        for (int i = 0; i < pdeList.size(); i++) {
            PDElement pde = pdeList.get(i);
            if (!pde.getParam().isHeader() &&
                 pde.getElement() != null) { // Element is null for SWARef attachment
                totalBodyBlocks++;
            }
        }

        int index = message.getNumBodyBlocks();
        for (int i = 0; i < pdeList.size(); i++) {
            PDElement pde = pdeList.get(i);

            // Create JAXBContext
            JAXBBlockContext context = new JAXBBlockContext(packages);

            Attachment attachment = pde.getAttachment();
            if (attachment == null) {
                // Normal Flow: Not an attachment
                
                
                // Marshal by type only if necessary
                if (pde.getByJavaTypeClass() != null) {
                    context.setProcessType(pde.getByJavaTypeClass());
                    if(pde.getParam()!=null){
                        context.setIsxmlList(pde.getParam().isListType());
                    }
                }
                // Create a JAXBBlock out of the value.
                // (Note that the PDElement.getValue always returns an object
                // that has an element rendering...ie. it is either a JAXBElement o
                // has @XmlRootElement defined
                Block block =
                    factory.createFrom(pde.getElement().getElementValue(),
                                       context,
                                       pde.getElement().getQName());
                
                if (pde.getParam().isHeader()) {
                    // Header block
                    QName qname = block.getQName();
                    message.setHeaderBlock(qname.getNamespaceURI(), qname.getLocalPart(), block);
                } else {
                    // Body block
                    if (totalBodyBlocks < 1) {
                        // If there is only one block, use the following "more performant" method
                        message.setBodyBlock(block);
                    } else {
                        message.setBodyBlock(index, block);
                    }
                    index++;
                }
            } else {
                // The parameter is an attachment
                AttachmentType type = pde.getParam().
                   getAttachmentDescription().getAttachmentType();
                if (type == AttachmentType.SWA) {
                    // All we need to do is set the data handler on the message.  
                    // For SWA attachments, the message does not reference the attachment.
                    message.addDataHandler(attachment.getDataHandler(), 
                                           attachment.getContentID());
                    message.setDoingSWA(true);
                } else {
                    // TODO NLS and cleanup
                    throw ExceptionFactory.
                       makeWebServiceException("SWAREF and MTOM attachment parameters " +
                                "are not supported in this style/use.");
                }
            }
        }
    }

    /**
     * Marshals the return object to the message (used on server to marshal return object)
     *
     * @param returnElement              element
     * @param returnType
     * @param marshalDesc
     * @param message
     * @param marshalByJavaTypeClass..we must do this for RPC...discouraged otherwise
     * @param isHeader
     * @throws MessageException
     */
    static void toMessage(Element returnElement,
                          Class returnType,
                          boolean isList,
                          MarshalServiceRuntimeDescription marshalDesc,
                          Message message,
                          Class marshalByJavaTypeClass,
                          boolean isHeader)
            throws WebServiceException {

        // Create the JAXBBlockContext
        // RPC uses type marshalling, so recored the rpcType
        JAXBBlockContext context = new JAXBBlockContext(marshalDesc.getPackages());
        if (marshalByJavaTypeClass != null) {
            context.setProcessType(marshalByJavaTypeClass);
            context.setIsxmlList(isList);
        }

        //  Create a JAXBBlock out of the value.
        Block block = factory.createFrom(returnElement.getElementValue(),
                                         context,
                                         returnElement.getQName());

        if (isHeader) {
            message.setHeaderBlock(returnElement.getQName().getNamespaceURI(),
                                   returnElement.getQName().getLocalPart(), block);
        } else {
            message.setBodyBlock(block);
        }
    }

    /**
     * Unmarshal the return object from the message
     *
     * @param packages
     * @param message
     * @param unmarshalByJavaTypeClass Used only to indicate unmarshaling by type...only necessary
     *                                 in some scenarios
     * @param isHeader
     * @param headerNS                 (only needed if isHeader)
     * @param headerLocalPart          (only needed if isHeader)
     * @param hasOutputBodyParams (true if the method has out or inout params other 
     * than the return value)
     * @return Element
     * @throws WebService
     * @throws XMLStreamException
     */
    static Element getReturnElement(TreeSet<String> packages,
                                    Message message,
                                    Class unmarshalByJavaTypeClass,  // normally null
                                    boolean isList,
                                    boolean isHeader,
                                    String headerNS,
                                    String headerLocalPart,
                                    boolean hasOutputBodyParams)

            throws WebServiceException, XMLStreamException {

        // The return object is the first block in the body
        JAXBBlockContext context = new JAXBBlockContext(packages);
        if (unmarshalByJavaTypeClass != null && !isHeader) {
            context.setProcessType(unmarshalByJavaTypeClass);

⌨️ 快捷键说明

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