/*
 * 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.datasource.jaxb;

import org.apache.axiom.om.OMException;
import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.java.security.AccessController;
import org.apache.axis2.jaxws.message.databinding.JAXBUtils;
import org.apache.axis2.jaxws.message.util.XMLStreamWriterWithOS;
import org.apache.axis2.jaxws.spi.Constants;
import org.apache.axis2.jaxws.utility.JavaUtils;
import org.apache.axis2.jaxws.utility.XMLRootElementUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.attachment.AttachmentMarshaller;
import javax.xml.bind.attachment.AttachmentUnmarshaller;
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.Holder;
import javax.xml.ws.WebServiceException;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.PrivilegedAction;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;

/*
 * To marshal or unmarshal a JAXB object, the JAXBContext is necessary.
 * In addition, access to the MessageContext and other context objects may be necessary
 * to get classloader information, store attachments etc.
 * 
 * The JAXBDSContext bundles all of this information together.
 */
public class JAXBDSContext {

    private static final Log log = LogFactory.getLog(JAXBDSContext.class);
    public static final boolean DEBUG_ENABLED = log.isDebugEnabled();

    private TreeSet<String> contextPackages;  // List of packages needed by the context
    private String contextPackagesKey;        // Unique key that represents the set of packages
    
    private JAXBContext customerJAXBContext;      // JAXBContext provided by the customer api
    //  JAXBContext loaded by the engine.  It is weakref'd to allow GC
    private WeakReference<JAXBContext> autoJAXBContext = null;   
    private JAXBUtils.CONSTRUCTION_TYPE       // How the JAXBContext is constructed
            constructionType = JAXBUtils.CONSTRUCTION_TYPE.UNKNOWN;
    private MessageContext msgContext;    

    // There are two modes of marshalling and unmarshalling: 
    //   "by java type" and "by schema element".
    // The prefered mode is "by schema element" because it is safe and xml-centric.
    // However there are some circumstances when "by schema element" is not available.
    //    Examples: RPC Lit processing (the wire element is defined by a wsdl:part...not schema)
    //              Doc/Lit Bare "Minimal" Processing (JAXB ObjectFactories are missing...
    //                   and thus we must use "by type" for primitives/String)
    // Please don't use "by java type" processing to get around errors.
    private Class processType = null;
    private boolean isxmlList =false;
    
    private String webServiceNamespace;

    /**
     * Full Constructor JAXBDSContext (most performant)
     *
     * @param packages Set of packages needed by the JAXBContext.
     */
    public JAXBDSContext(TreeSet<String> packages, String packagesKey) {
        this.contextPackages = packages;
        this.contextPackagesKey = packagesKey;
    }

    /**
     * Slightly slower constructor
     *
     * @param packages
     */
    public JAXBDSContext(TreeSet<String> packages) {
        this(packages, packages.toString());
    }

    /**
     * Normal Constructor JAXBBlockContext
     *
     * @param contextPackage
     * @deprecated
     */
    public JAXBDSContext(String contextPackage) {
        this.contextPackages = new TreeSet();
        this.contextPackages.add(contextPackage);
        this.contextPackagesKey = this.contextPackages.toString();
    }

    /**
     * "Dispatch" Constructor 
     * Use this full constructor when the JAXBContent is provided by the
     * customer.
     *
     * @param jaxbContext
     */
    public JAXBDSContext(JAXBContext jaxbContext) {
        this.customerJAXBContext = jaxbContext;
    }

    /** @return Class representing type of the element */
    public TreeSet<String> getContextPackages() {
        return contextPackages;
    }
    
    public JAXBContext getJAXBContext() throws JAXBException {
        return getJAXBContext(null);
    }

    /**
     * @return get the JAXBContext
     * @throws JAXBException
     */
    public JAXBContext getJAXBContext(ClassLoader cl) throws JAXBException {
        if (customerJAXBContext != null) {
            return customerJAXBContext;
        }
        
        // Get the weakly cached JAXBContext
        JAXBContext jc = null;
        if (autoJAXBContext != null) {
            jc = autoJAXBContext.get();
        }
        
        if (jc == null) {
            if (log.isDebugEnabled()) {
                log.debug(
                        "A JAXBContext did not exist, creating a new one with the context packages.");
            }
            Holder<JAXBUtils.CONSTRUCTION_TYPE> constructType =
                    new Holder<JAXBUtils.CONSTRUCTION_TYPE>();
            Map<String, Object> properties = null;
            
            /*
             * We set the default namespace to the web service namespace to fix an
             * obscur bug.
             * 
             * If the class representing a JAXB data object does not define a namespace
             * (via an annotation like @XmlType or via ObjectFactory or schema gen information)
             * then the namespace information is defaulted.
             * 
             * The xjc tool defaults the namespace information to unqualified.
             * However the wsimport tool defaults the namespace to the namespace of the
             * webservice.
             * 
             * To "workaround" this issue, a default namespace equal to the webservice
             * namespace is set on the JAXB marshaller.  This has the effect of changing the
             * "unqualified namespaces" into the namespace used by the webservice.
             * 
             */
            if (this.webServiceNamespace != null) {
                properties = new HashMap<String, Object>();
                properties.put(JAXBUtils.DEFAULT_NAMESPACE_REMAP, this.webServiceNamespace);
            }
            jc = JAXBUtils.getJAXBContext(contextPackages, constructType, 
                                          contextPackagesKey, cl, properties);
            constructionType = constructType.value;
            autoJAXBContext = new WeakReference<JAXBContext>(jc);
        } else {
            if (log.isDebugEnabled()) {
                log.debug("Using an existing JAXBContext");
            }
        }
        return jc;
    }

    public void setWebServiceNamespace(String namespace) {
        this.webServiceNamespace = namespace;
    }
    
    /** @return RPC Declared Type */
    public Class getProcessType() {
        return processType;
    }

    /**
     * Set RPC Declared Type.  The use of use this property if the message is style=document is
     * discouraged.
     *
     * @param type
     */
    public void setProcessType(Class type) {
        processType = type;
    }

    public JAXBUtils.CONSTRUCTION_TYPE getConstructionType() {
        return constructionType;
    }

    public boolean isxmlList() {
        return isxmlList;
    }

    public void setIsxmlList(boolean isxmlList) {
        this.isxmlList = isxmlList;
    }
    
    public MessageContext getMessageContext() {
        return msgContext;
    }

    public void setMessageContext(MessageContext messageContext) {
        this.msgContext = messageContext;
    }
    
    public ClassLoader getClassLoader() {
        MessageContext context = getMessageContext();
        if (context != null) {
            return (ClassLoader) context.getProperty(Constants.CACHE_CLASSLOADER);
        }
        return null;
    }
    
    /**
     * Create an AttachmentMarshaller to marshal MTOM/SWA Attachments
     * @param writer
     * @return
     */
    protected AttachmentMarshaller createAttachmentMarshaller(XMLStreamWriter writer) {
        return new JAXBAttachmentMarshaller(getMessageContext(), writer);
    }
    
    /**
     * Create an Attachment unmarshaller for unmarshalling MTOM/SWA Attachments
     * @return AttachmentUnmarshaller
     */
    protected AttachmentUnmarshaller createAttachmentUnmarshaller(XMLStreamReader reader) {
        return new JAXBAttachmentUnmarshaller(getMessageContext(), reader);
    }

    /**
     * Unmarshal the xml into a JAXB object
     * @param reader
     * @return
     * @throws JAXBException
     */
    public Object unmarshal(XMLStreamReader reader) throws JAXBException {

        // There may be a preferred classloader that should be used
        ClassLoader cl = getClassLoader();
        
        Unmarshaller u = JAXBUtils.getJAXBUnmarshaller(getJAXBContext(cl));

        
        // Create an attachment unmarshaller
        AttachmentUnmarshaller aum = createAttachmentUnmarshaller(reader);

        if (aum != null) {
            if (DEBUG_ENABLED) {
                log.debug("Adding JAXBAttachmentUnmarshaller to Unmarshaller");
            } 
            u.setAttachmentUnmarshaller(aum);
        }

        Object jaxb = null;

        // Unmarshal into the business object.
        if (getProcessType() == null) {
            jaxb = unmarshalByElement(u, reader);   // preferred and always used for
                                                    // style=document
        } else {
            jaxb = unmarshalByType(u,
                                   reader,
                                   getProcessType(),
                                   isxmlList(),
                                   getConstructionType());
        }

        // Successfully unmarshalled the object
        JAXBUtils.releaseJAXBUnmarshaller(getJAXBContext(cl), 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;
    }
    
    /**
     * Marshal the jaxb object
     * @param obj
     * @param writer
     * @param am AttachmentMarshaller, optional Attachment
     */
    public void marshal(Object obj, 
                        XMLStreamWriter writer) throws JAXBException {
            // There may be a preferred classloader that should be used
            ClassLoader cl = getClassLoader();
            
            
            // Very easy, use the Context to get the Marshaller.
            // Use the marshaller to write the object.
            Marshaller m = JAXBUtils.getJAXBMarshaller(getJAXBContext(cl));
            
            AttachmentMarshaller am = createAttachmentMarshaller(writer);
            if (am != null) {
                if (DEBUG_ENABLED) {
                    log.debug("Adding JAXBAttachmentMarshaller to Marshaller");
                }
                m.setAttachmentMarshaller(am);
            }


            // Marshal the object
            if (getProcessType() == null) {
                marshalByElement(obj, 
                                 m, 
                                 writer, 
                                 true);
                                 //!am.isXOPPackage());
            } else {
                marshalByType(obj,
                              m,
                              writer,
                              getProcessType(),
                              isxmlList(),
                              getConstructionType());
            }

            // Successfully marshalled the data
            JAXBUtils.releaseJAXBMarshaller(getJAXBContext(cl), m);
    }
    
    
    /**
     * 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(final Object b, final Marshaller m, 
                                         final XMLStreamWriter writer,
                                         final boolean optimize) {
        AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                // 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 {
                    if (!optimize) {
                        log.trace(JavaUtils.stackToString());
                        getOutputStream(writer);
                    }
                    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 (OMException e) {
                    throw e;
                }
                catch (Throwable t) {
                    throw new OMException(t);
                }
                return null;
            }});
    }
    
    private static String getDebugName(Object o) {
        return (o == null) ? "null" : o.getClass().getCanonicalName();
    }

    /**
     * If the writer is backed by an OutputStream, then return the OutputStream
     * @param writer
     * @return OutputStream or null
     */
    private static OutputStream getOutputStream(XMLStreamWriter writer) throws XMLStreamException {
        if (log.isDebugEnabled()) {
            log.debug("XMLStreamWriter is " + writer);
        }
        OutputStream os = null;
        if (writer.getClass() == MTOMXMLStreamWriter.class) {
            os = ((MTOMXMLStreamWriter) writer).getOutputStream();
            if (log.isDebugEnabled()) {
                log.debug("OutputStream accessible from MTOMXMLStreamWriter is " + os);
            }
        }
        if (writer.getClass() == XMLStreamWriterWithOS.class) {
            os = ((XMLStreamWriterWithOS) writer).getOutputStream();
            if (log.isDebugEnabled()) {
                log.debug("OutputStream accessible from XMLStreamWriterWithOS is " + os);
            }
        }
        return os;
    }
    
    /**
     * The root element being read is defined by schema/JAXB; however its contents are known by
     * schema/JAXB. Therefore we use unmarshal by the declared type (This method is used to
     * unmarshal rpc elements)
     * 
     * @param u Unmarshaller
     * @param reader XMLStreamReader
     * @param type Class
     * @return Object
     * @throws WebServiceException
     */
    public static Object unmarshalByType(final Unmarshaller u, final XMLStreamReader reader,
                                          final Class type, final boolean isList,
                                          final JAXBUtils.CONSTRUCTION_TYPE ctype)
        throws WebServiceException {

        if (DEBUG_ENABLED) {
            log.debug("Invoking unmarshalByType.");
        }

        return AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                try {
                    // Unfortunately RPC is type based. Thus a
                    // declared type must be used to unmarshal the xml.
                    Object jaxb;
                   
                    if (!isList) {
                        // case: We are not unmarshalling an xsd:list but an Array.

                        if (type.isArray()) {
                            // If the context is created using package
                            // we will not have common arrays or type array in the context
                            // but there is not much we can do about it so seralize it as
                            // usual
                            if (ctype == JAXBUtils.CONSTRUCTION_TYPE.BY_CONTEXT_PATH) {
                                jaxb = u.unmarshal(reader, type);
                            }
                            // list on client array on server, Can happen only in start from java
                            // case.
                            else if ((ctype == JAXBUtils.CONSTRUCTION_TYPE.BY_CLASS_ARRAY)) {

                                // The type could be any Object or primitive
                                // I will first unmarshall the xmldata to a String[]
                                // Then use the unmarshalled jaxbElement to create
                                // proper type Object Array.
                                
                                jaxb = unmarshalArray(reader, u, type);
                                
                            } else {
                                
                                jaxb = u.unmarshal(reader, type);
                                
                            }

                        } else if (type.isEnum()) {
                            // When JAXBContext is created using a context path, it will not 
                            // include Enum classes.
                            // These classes have @XmlEnum annotation but not @XmlType/@XmlElement,
                            // so the user will see MarshallingEx, class not known to ctxt.
                            // 
                            // This is a jax-b defect, for now this fix is in place to pass CTS.
                            // This only fixes the
                            // situation where the enum is the top-level object (e.g., message-part
                            // in rpc-lit scenario)
                            //
                            // Sample of what enum looks like:
                            // @XmlEnum public enum EnumString {
                            // @XmlEnumValue("String1") STRING_1("String1"),
                            // @XmlEnumValue("String2") STRING_2("String2");
                            //
                            // public static getValue(String){} <-- resolves a "value" to an emum
                            // object
                            // ... }
                            if (DEBUG_ENABLED) {
                                log.debug("unmarshalByType. Unmarshalling " + type.getName()
                                        + " as Enum");
                            }

                            JAXBElement<String> enumValue = u.unmarshal(reader, String.class);

                            if (enumValue != null) {
                                Method m =
                                        type.getMethod("fromValue", new Class[] { String.class });
                                jaxb = m.invoke(null, new Object[] { enumValue.getValue() });
                            } else {
                                jaxb = null;
                            }
                        }
                        //Normal case: We are not unmarshalling a xsd:list or Array
                        else {
                            jaxb = u.unmarshal(reader, type);
                        }

                    } else {
                        // If this is an xsd:list, we need to return the appropriate
                        // list or array (see NOTE above)
                        // First unmarshal as a String
                        //Second convert the String into a list or array
                        
                        jaxb = unmarshalAsListOrArray(reader, u, type);
                        
                    }
                    return jaxb;
                } catch (OMException e) {
                    throw e;
                } catch (Throwable t) {
                    throw new OMException(t);
                }
            }
        });
    }

    private static Object unmarshalArray(final XMLStreamReader reader, 
                                         final Unmarshaller u, 
                                         Class type)
       throws Exception {
        try {
            if (DEBUG_ENABLED) {
                log.debug("Invoking unmarshalArray");
            }
            Object jaxb = AccessController.doPrivileged(new PrivilegedAction() {
                public Object run() {
                    try {
                        return u.unmarshal(reader, String[].class);
                    } catch (OMException e) {
                        throw e;
                    } catch (Throwable t) {
                        throw new OMException(t);
                    }
                }
            });

            Object typeObj = getTypeEnabledObject(jaxb);

            // Now convert String Array in to the required Type Array.
            if (typeObj instanceof String[]) {
                String[] strArray = (String[]) typeObj;
                Object obj = XSDListUtils.fromStringArray(strArray, type);
                QName qName =
                    XMLRootElementUtil.getXmlRootElementQNameFromObject(jaxb);
                jaxb = new JAXBElement(qName, type, obj);
            }

            return jaxb;
        } catch (OMException e) {
            throw e;
        } catch (Throwable t) {
            throw new OMException(t);
        }
    }
   
    /**
     * convert the String into a list or array
     * @param <T>
     * @param jaxb
     * @param type
     * @return
     * @throws IllegalAccessException
     * @throws ParseException
     * @throws NoSuchMethodException
     * @throws InstantiationException
     * @throws DatatypeConfigurationException
     * @throws InvocationTargetException
     */
    public static Object unmarshalAsListOrArray(final XMLStreamReader reader, 
                                                final Unmarshaller u, 
                                                 Class type)
        throws IllegalAccessException, ParseException,NoSuchMethodException,
        InstantiationException,
        DatatypeConfigurationException,InvocationTargetException,JAXBException {
        
        
            if (DEBUG_ENABLED) {
                log.debug("Invoking unmarshaArray");
            }
            
            // If this is an xsd:list, we need to return the appropriate
            // list or array (see NOTE above)
            // First unmarshal as a String
            Object jaxb = null;
            try {
                jaxb = AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        try {
                            return u.unmarshal(reader, String.class);
                        } catch (OMException e) {
                            throw e;
                        } catch (Throwable t) {
                            throw new OMException(t);
                        }
                    }
                });
            } catch (OMException e) {
                throw e;
            } catch (Throwable t) {
                throw new OMException(t);
            }
            //Second convert the String into a list or array
            if (getTypeEnabledObject(jaxb) instanceof String) {
                QName qName = XMLRootElementUtil.getXmlRootElementQNameFromObject(jaxb);
                Object obj = XSDListUtils.fromXSDListString((String) getTypeEnabledObject(jaxb), type);
                return new JAXBElement(qName, type, obj);
            } else {
                return jaxb;
            }

    }

    /**
     * Return type enabled object
     *
     * @param obj type or element enabled object
     * @return type enabled object
     */
    static Object getTypeEnabledObject(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj instanceof JAXBElement) {
            return ((JAXBElement) obj).getValue();
        }
        return obj;
    }

    /**
     * Marshal objects by type
     * 
     * @param b Object that can be rendered as an element, but the element name is not known to the
     * schema (i.e. rpc)
     * @param m Marshaller
     * @param writer XMLStreamWriter
     * @param type
     */
    private static void marshalByType(final Object b, final Marshaller m,
                                      final XMLStreamWriter writer, final Class type,
                                      final boolean isList, final JAXBUtils.CONSTRUCTION_TYPE ctype)
        throws WebServiceException {
        AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                try {

                    // NOTE
                    // Example:
                    // <xsd:simpleType name="LongList">
                    // <xsd:list>
                    // <xsd:simpleType>
                    // <xsd:restriction base="xsd:unsignedInt"/>
                    // </xsd:simpleType>
                    // </xsd:list>
                    // </xsd:simpleType>
                    // <element name="myLong" nillable="true" type="impl:LongList"/>
                    //
                    // LongList will be represented as an int[]
                    // On the wire myLong will be represented as a list of integers
                    // with intervening whitespace
                    // <myLong>1 2 3</myLong>
                    //
                    // Unfortunately, we are trying to marshal by type. Therefore
                    // we want to marshal an element (foo) that is unknown to schema.
                    // If we use the normal marshal code, the wire will look like
                    // this (which is incorrect):
                    // <foo><item>1</item><item>2</item><item>3</item></foo>
                    //
                    // The solution is to detect this situation and marshal the
                    // String instead. Then we get the correct wire format:
                    // <foo>1 2 3</foo>
                    Object jbo = b;
                    if (isList) {
                        if (DEBUG_ENABLED) {
                            log.debug("marshalling type which is a List or Array");
                        }
                        
                        // This code assumes that the JAXBContext does not understand
                        // the array or list. In such cases, the contents are converted
                        // to a String and passed directly.
                        
                        if (ctype == JAXBUtils.CONSTRUCTION_TYPE.BY_CONTEXT_PATH) {
                            QName qName = XMLRootElementUtil.getXmlRootElementQNameFromObject(b);
                            String text = XSDListUtils.toXSDListString(getTypeEnabledObject(b));
                            if (DEBUG_ENABLED) {
                                log.debug("marshalling [context path approach] " +
                                                "with xmllist text = " + text);
                            }
                            jbo = new JAXBElement(qName, String.class, text);
                        } else if (ctype == JAXBUtils.CONSTRUCTION_TYPE.BY_CLASS_ARRAY) {
                            // Some versions of JAXB have array/list processing built in.
                            // This code is a safeguard because apparently some versions
                            // of JAXB don't.
                            QName qName = XMLRootElementUtil.getXmlRootElementQNameFromObject(b);
                            String text = XSDListUtils.toXSDListString(getTypeEnabledObject(b));
                            if (DEBUG_ENABLED) {
                                log.debug("marshalling [class array approach] " +
                                                "with xmllist text = " + text);
                            }
                            jbo = new JAXBElement(qName, String.class, text); 
                        }
                    }

                    // When JAXBContext is created using a context path, it will not include Enum
                    // classes.
                    // These classes have @XmlEnum annotation but not @XmlType/@XmlElement, so the
                    // user will see MarshallingEx, class not known to ctxt.
                    // 
                    // This is a jax-b defect, for now this fix is in place to pass CTS. This only
                    // fixes the
                    // situation where the enum is the top-level object (e.g., message-part in
                    // rpc-lit scenario)
                    //
                    // Sample of what enum looks like:
                    // @XmlEnum public enum EnumString {
                    // @XmlEnumValue("String1") STRING_1("String1"),
                    // @XmlEnumValue("String2") STRING_2("String2");
                    // ... }
                    if (type.isEnum()) {
                        if (b != null) {
                            if (DEBUG_ENABLED) {
                                log.debug("marshalByType. Marshaling " + type.getName()
                                        + " as Enum");
                            }
                            JAXBElement jbe = (JAXBElement) b;
                            String value = XMLRootElementUtil.getEnumValue((Enum) jbe.getValue());

                            jbo = new JAXBElement(jbe.getName(), String.class, value);
                        }
                    }

                    if (DEBUG_ENABLED) {
                        log.debug("Invoking marshalByType.  " +
                                        "Marshaling to an XMLStreamWriter. Object is "
                                + getDebugName(b));
                    }
                    
                    /// TODO 
                    // For the cases like enum and list, should we 
                    // intercept exceptions and try a different approach ?
                    m.marshal(jbo, writer);

                } catch (OMException e) {
                    throw e;
                } catch (Throwable t) {
                    throw new OMException(t);
                }
                return null;
            }
        });
    }

    /**
     * Preferred way to unmarshal objects
     * 
     * @param u Unmarshaller
     * @param reader XMLStreamReader
     * @return Object that represents an element
     * @throws WebServiceException
     */
    public 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 (OMException e) {
                        throw e;
                    } catch (Throwable t) {
                        throw new OMException(t);
                    }
                }
            });

        } catch (OMException e) {
            throw e;
        } catch (Throwable t) {
            throw new OMException(t);
        }
    }

}
