jaxbblockimpl.java

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

JAVA
598
字号
/*
 * 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.message.databinding.impl;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
import org.apache.axiom.om.util.StAXUtils;
import org.apache.axis2.java.security.AccessController;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.message.Message;
import org.apache.axis2.jaxws.message.attachments.JAXBAttachmentMarshaller;
import org.apache.axis2.jaxws.message.attachments.JAXBAttachmentUnmarshaller;
import org.apache.axis2.jaxws.message.databinding.JAXBBlock;
import org.apache.axis2.jaxws.message.databinding.JAXBBlockContext;
import org.apache.axis2.jaxws.message.databinding.JAXBUtils;
import org.apache.axis2.jaxws.message.databinding.XSDListUtils;
import org.apache.axis2.jaxws.message.factory.BlockFactory;
import org.apache.axis2.jaxws.message.impl.BlockImpl;
import org.apache.axis2.jaxws.utility.XMLRootElementUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.JAXBIntrospector;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.ws.WebServiceException;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.PrivilegedAction;
import java.text.ParseException;

/**
 * JAXBBlockImpl <p/> A Block containing a JAXB business object (either a JAXBElement or an object
 * with @XmlRootElement).
 */
public class JAXBBlockImpl extends BlockImpl implements JAXBBlock {

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

    private static final boolean DEBUG_ENABLED = log.isDebugEnabled();

    /**
     * Called by JAXBBlockFactory
     * 
     * @param busObject..The business object must be a JAXBElement or an object with an
     * @XMLRootElement. This is assertion is validated in the JAXBFactory.
     * @param busContext
     * @param qName QName must be non-null
     * @param factory
     */
    JAXBBlockImpl(Object busObject, JAXBBlockContext busContext, QName qName, 
                  BlockFactory factory)
            throws JAXBException {
        super(busObject, busContext, qName, factory);
    }

    /**
     * Called by JAXBBlockFactory
     * 
     * @param omelement
     * @param busContext
     * @param qName must be non-null
     * @param factory
     */
    JAXBBlockImpl(OMElement omElement, JAXBBlockContext busContext, QName qName,
            BlockFactory factory) {
        super(omElement, busContext, qName, factory);
    }

    @Override
    protected Object _getBOFromReader(XMLStreamReader reader, Object busContext)
        throws XMLStreamException, WebServiceException {
        // Get the JAXBBlockContext. All of the necessry information is recorded on it
        JAXBBlockContext ctx = (JAXBBlockContext) busContext;
        try {
            // TODO Re-evaluate Unmarshall construction w/ MTOM
            Unmarshaller u = JAXBUtils.getJAXBUnmarshaller(ctx.getJAXBContext());

            if (DEBUG_ENABLED) {
                log.debug("Adding JAXBAttachmentUnmarshaller to Unmarshaller");
            }

            Message msg = getParent();

            JAXBAttachmentUnmarshaller aum = new JAXBAttachmentUnmarshaller(msg);
            u.setAttachmentUnmarshaller(aum);

            Object jaxb = null;

            // Unmarshal into the business object.
            if (ctx.getProcessType() == null) {
                jaxb = unmarshalByElement(u, reader); // preferred and always used for
                                                        // style=document
            } else {
                jaxb =
                        unmarshalByType(u,
                                        reader,
                                        ctx.getProcessType(),
                                        ctx.isxmlList(),
                                        ctx.getConstructionType());
            }

            // Successfully unmarshalled the object
            JAXBUtils.releaseJAXBUnmarshaller(ctx.getJAXBContext(), u);
            
            // Don't close the reader.  The reader is owned by the caller, and it
            // may contain other xml instance data (other than this JAXB object)
            // reader.close();
            return jaxb;
        } catch (JAXBException je) {
            if (DEBUG_ENABLED) {
                try {
                    log.debug("JAXBContext for unmarshal failure:" + ctx.getJAXBContext());
                } catch (Exception e) {
                }
            }
            throw ExceptionFactory.makeWebServiceException(je);
        }
    }

    /**
     * @param busObj
     * @param busContext
     * @return
     * @throws XMLStreamException
     * @throws WebServiceException
     */
    private byte[] _getBytesFromBO(Object busObj, Object busContext, String encoding)
        throws XMLStreamException, WebServiceException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        XMLStreamWriter writer = StAXUtils.createXMLStreamWriter(baos, encoding);

        // Since we are writing just the xml,
        // The writer will be a normal writer.
        // All mtom objects will be inlined.
        // writer = new MTOMXMLStreamWriter(writer);

        // Write the business object to the writer
        _outputFromBO(busObj, busContext, writer);

        // Flush the writer
        writer.flush();
        writer.close();
        return baos.toByteArray();
    }


    @Override
    protected XMLStreamReader _getReaderFromBO(Object busObj, Object busContext)
        throws XMLStreamException, WebServiceException {
        ByteArrayInputStream baos =
                new ByteArrayInputStream(_getBytesFromBO(busObj, busContext, "utf-8"));
        return StAXUtils.createXMLStreamReader(baos, "utf-8");
    }

    @Override
    protected void _outputFromBO(Object busObject, Object busContext, XMLStreamWriter writer)
        throws XMLStreamException, WebServiceException {
        JAXBBlockContext ctx = (JAXBBlockContext) busContext;
        try {
            // Very easy, use the Context to get the Marshaller.
            // Use the marshaller to write the object.
            Marshaller m = JAXBUtils.getJAXBMarshaller(ctx.getJAXBContext());


            if (DEBUG_ENABLED) {
                log.debug("Adding JAXBAttachmentMarshaller to Marshaller");
            }

            Message msg = getParent();

            // Pool
            JAXBAttachmentMarshaller am = new JAXBAttachmentMarshaller(msg, writer);
            m.setAttachmentMarshaller(am);


            // Marshal the object
            if (ctx.getProcessType() == null) {
                marshalByElement(busObject, m, writer, !am.isXOPPackage());
            } else {
                marshalByType(busObject,
                              m,
                              writer,
                              ctx.getProcessType(),
                              ctx.isxmlList(),
                              ctx.getConstructionType());
            }

            // Successfully marshalled the data
            JAXBUtils.releaseJAXBMarshaller(ctx.getJAXBContext(), m);
        } catch (JAXBException je) {
            if (DEBUG_ENABLED) {
                try {
                    log.debug("JAXBContext for marshal failure:" + ctx.getJAXBContext());
                } catch (Exception e) {
                }
            }
            throw ExceptionFactory.makeWebServiceException(je);
        }
    }

    /**
     * Get the QName from the jaxb object
     * 
     * @param jaxb
     * @param jbc
     * @throws WebServiceException
     */
    private static QName getQName(Object jaxb, JAXBBlockContext ctx) throws JAXBException {
        JAXBIntrospector jbi = JAXBUtils.getJAXBIntrospector(ctx.getJAXBContext());
        QName qName = jbi.getElementName(jaxb);
        JAXBUtils.releaseJAXBIntrospector(ctx.getJAXBContext(), jbi);
        return qName;
    }

    /**
     * Preferred way to marshal objects.
     * 
     * @param b Object that can be rendered as an element and the element name is known by the
     * Marshaller
     * @param m Marshaller
     * @param writer XMLStreamWriter
     */
    private static void marshalByElement(Object b, Marshaller m, XMLStreamWriter writer,
                                         boolean optimize) throws WebServiceException {
        // Marshalling directly to the output stream is faster than marshalling through the
        // XMLStreamWriter. Take advantage of this optimization if there is an output stream.
        try {
            OutputStream os = (optimize) ? getOutputStream(writer) : null;
            if (os != null) {
                if (DEBUG_ENABLED) {
                    log.debug("Invoking marshalByElement.  Marshaling to an OutputStream. " +
                                "Object is "
                            + getDebugName(b));
                }
                writer.flush();
                m.marshal(b, os);
            } else {
                if (DEBUG_ENABLED) {
                    log.debug("Invoking marshalByElement.  Marshaling to an XMLStreamWriter. " +
                                "Object is "
                            + getDebugName(b));
                }
                m.marshal(b, writer);
            }
        } catch (Exception e) {
            throw ExceptionFactory.makeWebServiceException(e);
        }
    }

    /**
     * Preferred way to unmarshal objects
     * 
     * @param u Unmarshaller
     * @param reader XMLStreamReader
     * @return Object that represents an element
     * @throws WebServiceException
     */
    private static Object unmarshalByElement(final Unmarshaller u, final XMLStreamReader reader)
        throws WebServiceException {
        try {
            if (DEBUG_ENABLED) {
                log.debug("Invoking unMarshalByElement");
            }
            return AccessController.doPrivileged(new PrivilegedAction() {
                public Object run() {
                    try {
                        return u.unmarshal(reader);
                    } catch (Exception e) {
                        throw ExceptionFactory.makeWebServiceException(e);
                    }

⌨️ 快捷键说明

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