/*
 * Copyright (c) 2003, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package jakarta.xml.bind;

import jakarta.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.adapters.XmlAdapter;
import jakarta.xml.bind.attachment.AttachmentMarshaller;
import javax.xml.validation.Schema;
import java.io.File;

/**
 * <p>
 * The {@code Marshaller} class is responsible for governing the process
 * of serializing Java content trees back into XML data.  It provides the basic
 * marshalling methods:
 *
 * <p>
 * <i>Assume the following setup code for all following code fragments:</i>
 * <blockquote>
 *    <pre>
 *       JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
 *       Unmarshaller u = jc.createUnmarshaller();
 *       Object element = u.unmarshal( new File( "foo.xml" ) );
 *       Marshaller m = jc.createMarshaller();
 *    </pre>
 * </blockquote>
 *
 * <p>
 * Marshalling to a File:
 * <blockquote>
 *    <pre>
 *       OutputStream os = new FileOutputStream( "nosferatu.xml" );
 *       m.marshal( element, os );
 *    </pre>
 * </blockquote>
 *
 * <p>
 * Marshalling to a SAX ContentHandler:
 * <blockquote>
 *    <pre>
 *       // assume MyContentHandler instanceof ContentHandler
 *       m.marshal( element, new MyContentHandler() );
 *    </pre>
 * </blockquote>
 *
 * <p>
 * Marshalling to a DOM Node:
 * <blockquote>
 *    <pre>
 *       DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 *       dbf.setNamespaceAware(true);
 *       DocumentBuilder db = dbf.newDocumentBuilder();
 *       Document doc = db.newDocument();
 *
 *       m.marshal( element, doc );
 *    </pre>
 * </blockquote>
 *
 * <p>
 * Marshalling to a java.io.OutputStream:
 * <blockquote>
 *    <pre>
 *       m.marshal( element, System.out );
 *    </pre>
 * </blockquote>
 *
 * <p>
 * Marshalling to a java.io.Writer:
 * <blockquote>
 *    <pre>
 *       m.marshal( element, new PrintWriter( System.out ) );
 *    </pre>
 * </blockquote>
 *
 * <p>
 * Marshalling to a javax.xml.transform.SAXResult:
 * <blockquote>
 *    <pre>
 *       // assume MyContentHandler instanceof ContentHandler
 *       SAXResult result = new SAXResult( new MyContentHandler() );
 *
 *       m.marshal( element, result );
 *    </pre>
 * </blockquote>
 *
 * <p>
 * Marshalling to a javax.xml.transform.DOMResult:
 * <blockquote>
 *    <pre>
 *       DOMResult result = new DOMResult();
 *
 *       m.marshal( element, result );
 *    </pre>
 * </blockquote>
 *
 * <p>
 * Marshalling to a javax.xml.transform.StreamResult:
 * <blockquote>
 *    <pre>
 *       StreamResult result = new StreamResult( System.out );
 *
 *       m.marshal( element, result );
 *    </pre>
 * </blockquote>
 *
 * <p>
 * Marshalling to a javax.xml.stream.XMLStreamWriter:
 * <blockquote>
 *    <pre>
 *       XMLStreamWriter xmlStreamWriter =
 *           XMLOutputFactory.newInstance().createXMLStreamWriter( ... );
 *
 *       m.marshal( element, xmlStreamWriter );
 *    </pre>
 * </blockquote>
 *
 * <p>
 * Marshalling to a javax.xml.stream.XMLEventWriter:
 * <blockquote>
 *    <pre>
 *       XMLEventWriter xmlEventWriter =
 *           XMLOutputFactory.newInstance().createXMLEventWriter( ... );
 *
 *       m.marshal( element, xmlEventWriter );
 *    </pre>
 * </blockquote>
 *
 * <p>
 * <a id="elementMarshalling"></a>
 * <b>Marshalling content tree rooted by a Jakarta XML Binding element</b><br>
 * <blockquote>
 * The first parameter of the overloaded
 * {@code Marshaller.marshal(java.lang.Object, ...)} methods must be a
 * Jakarta XML Binding element as computed by
 * {@link JAXBIntrospector#isElement(java.lang.Object)};
 * otherwise, a {@code Marshaller.marshal} method must throw a
 * {@link MarshalException}. There exist two mechanisms
 * to enable marshalling an instance that is not a Jakarta XML Binding element.
 * One method is to wrap the instance as a value of a {@link JAXBElement},
 * and pass the wrapper element as the first parameter to
 * a {@code Marshaller.marshal} method. For java to schema binding, it
 * is also possible to simply annotate the instance's class with
 * &#64;{@link XmlRootElement}.
 * </blockquote>
 *
 * <p>
 * <b>Encoding</b><br>
 * <blockquote>
 * By default, the Marshaller will use UTF-8 encoding when generating XML data
 * to a {@code java.io.OutputStream}, or a {@code java.io.Writer}.  Use the
 * {@link #setProperty(String,Object) setProperty} API to change the output
 * encoding used during these marshal operations.  Client applications are
 * expected to supply a valid character encoding name as defined in the
 * <a href="http://www.w3.org/TR/2000/REC-xml-20001006#charencoding">W3C XML 1.0
 * Recommendation</a> and supported by your Java Platform.
 * </blockquote>
 *
 * <p>
 * <b>Validation and Well-Formedness</b><br>
 * <blockquote>
 * <p>
 * Client applications are not required to validate the Java content tree prior
 * to calling any of the marshal API's.  Furthermore, there is no requirement
 * that the Java content tree be valid with respect to its original schema in
 * order to marshal it back into XML data.  Different Jakarta XML Binding Providers will
 * support marshalling invalid Java content trees at varying levels, however
 * all Jakarta XML Binding Providers must be able to marshal a valid content tree back to
 * XML data.  A Jakarta XML Binding Provider must throw a {@code MarshalException} when it
 * is unable to complete the marshal operation due to invalid content.  Some
 * Jakarta XML Binding Providers will fully allow marshalling invalid content, others will fail
 * on the first validation error.
 * <p>
 * Even when schema validation is not explictly enabled for the marshal operation,
 * it is possible that certain types of validation events will be detected
 * during the operation.  Validation events will be reported to the registered
 * event handler.  If the client application has not registered an event handler
 * prior to invoking one of the marshal API's, then events will be delivered to
 * a default event handler which will terminate the marshal operation after
 * encountering the first error or fatal error. Note that for Jakarta XML Binding and
 * later versions, {@link jakarta.xml.bind.helpers.DefaultValidationEventHandler} is
 * no longer used.
 *
 * </blockquote>
 *
 * <p>
 * <a id="supportedProps"></a>
 * <b>Supported Properties</b><br>
 * <blockquote>
 * <p>
 * All Jakarta XML Binding Providers are required to support the following set of properties.
 * Some providers may support additional properties.
 * <dl>
 *   <dt>{@code jaxb.encoding} - value must be a java.lang.String</dt>
 *   <dd>The output encoding to use when marshalling the XML data.  The
 * 		 Marshaller will use "UTF-8" by default if this property is not
 *  	 specified.</dd>
 *   <dt>{@code jaxb.formatted.output} - value must be a java.lang.Boolean</dt>
 *   <dd>This property controls whether or not the Marshaller will format
 * 	 the resulting XML data with line breaks and indentation.  A
 *       true value for this property indicates human readable indented
 *       xml data, while a false value indicates unformatted xml data.
 *       The Marshaller will default to false (unformatted) if this
 *       property is not specified.</dd>
 *   <dt>{@code jaxb.schemaLocation} - value must be a java.lang.String</dt>
 *   <dd>This property allows the client application to specify an
 *       xsi:schemaLocation attribute in the generated XML data.  The format of
 *       the schemaLocation attribute value is discussed in an easy to
 *       understand, non-normative form in
 *       <a href="http://www.w3.org/TR/xmlschema-0/#schemaLocation">Section 5.6
 *       of the W3C XML Schema Part 0: Primer</a> and specified in
 *       <a href="http://www.w3.org/TR/xmlschema-1/#Instance_Document_Constructions">
 *       Section 2.6 of the W3C XML Schema Part 1: Structures</a>.</dd>
 *   <dt>{@code jaxb.noNamespaceSchemaLocation} - value must be a java.lang.String</dt>
 *   <dd>This property allows the client application to specify an
 *       xsi:noNamespaceSchemaLocation attribute in the generated XML
 *       data.  The format of the schemaLocation attribute value is discussed in
 *       an easy to understand, non-normative form in
 *       <a href="http://www.w3.org/TR/xmlschema-0/#schemaLocation">Section 5.6
 *       of the W3C XML Schema Part 0: Primer</a> and specified in
 *       <a href="http://www.w3.org/TR/xmlschema-1/#Instance_Document_Constructions">
 *       Section 2.6 of the W3C XML Schema Part 1: Structures</a>.</dd>
 *   <dt>{@code jaxb.fragment} - value must be a java.lang.Boolean</dt>
 *   <dd>This property determines whether or not document level events will be
 *       generated by the Marshaller.  If the property is not specified, the
 *       default is {@code false}. This property has different implications depending
 *       on which marshal api you are using - when this property is set to true:<br>
 *       <ul>
 *         <li>{@link #marshal(Object,org.xml.sax.ContentHandler) marshal(Object,ContentHandler)} - the Marshaller won't
 *             invoke {@link org.xml.sax.ContentHandler#startDocument()} and
 *             {@link org.xml.sax.ContentHandler#endDocument()}.</li>
 *         <li>{@link #marshal(Object,org.w3c.dom.Node) marshal(Object,Node)} - the property has no effect on this
 *             API.</li>
 *         <li>{@link #marshal(Object,java.io.OutputStream) marshal(Object,OutputStream)} - the Marshaller won't
 *             generate an xml declaration.</li>
 *         <li>{@link #marshal(Object,java.io.Writer) marshal(Object,Writer)} - the Marshaller won't
 *             generate an xml declaration.</li>
 *         <li>{@link #marshal(Object,javax.xml.transform.Result) marshal(Object,Result)} - depends on the kind of
 *             Result object, see semantics for Node, ContentHandler, and Stream APIs</li>
 *         <li>{@link #marshal(Object,javax.xml.stream.XMLEventWriter) marshal(Object,XMLEventWriter)} - the
 *             Marshaller will not generate {@link javax.xml.stream.events.XMLEvent#START_DOCUMENT} and
 *             {@link javax.xml.stream.events.XMLEvent#END_DOCUMENT} events.</li>
 *         <li>{@link #marshal(Object,javax.xml.stream.XMLStreamWriter) marshal(Object,XMLStreamWriter)} - the
 *             Marshaller will not generate {@link javax.xml.stream.events.XMLEvent#START_DOCUMENT} and
 *             {@link javax.xml.stream.events.XMLEvent#END_DOCUMENT} events.</li>
 *       </ul>
 *   </dd>
 * </dl>
 * </blockquote>
 *
 * <p>
 * <a id="marshalEventCallback"></a>
 * <b>Marshal Event Callbacks</b><br>
 * <blockquote>
 * "The {@link Marshaller} provides two styles of callback mechanisms
 * that allow application specific processing during key points in the
 * unmarshalling process.  In 'class defined' event callbacks, application
 * specific code placed in Jakarta XML Binding mapped classes is triggered during
 * marshalling.  'External listeners' allow for centralized processing
 * of marshal events in one callback method rather than by type event callbacks.
 *
 * <p>
 * Class defined event callback methods allow any Jakarta XML Binding mapped class to specify
 * its own specific callback methods by defining methods with the following method signatures:
 * <blockquote>
 * <pre>
 *   // Invoked by Marshaller after it has created an instance of this object.
 *   boolean beforeMarshal(Marshaller);
 *
 *   // Invoked by Marshaller after it has marshalled all properties of this object.
 *   void afterMarshal(Marshaller);
 * </pre>
 * </blockquote>
 * The class defined event callback methods should be used when the callback method requires
 * access to non-public methods and/or fields of the class.
 * <p>
 * The external listener callback mechanism enables the registration of a {@link Listener}
 * instance with a {@link Marshaller#setListener(Listener)}. The external listener receives all callback events,
 * allowing for more centralized processing than per class defined callback methods.
 * <p>
 * The 'class defined' and external listener event callback methods are independent of each other,
 * both can be called for one event. The invocation ordering when both listener callback methods exist is
 * defined in {@link Listener#beforeMarshal(Object)} and {@link Listener#afterMarshal(Object)}.
 * <p>
 * An event callback method throwing an exception terminates the current marshal process.
 * </blockquote>
 *
 * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems, Inc.</li><li>Ryan Shoemaker, Sun Microsystems, Inc.</li><li>Joe Fialli, Sun Microsystems, Inc.</li></ul>
 * @see JAXBContext
 * @see Unmarshaller
 * @since 1.6, JAXB 1.0
 */
public interface Marshaller {

    /**
     * The name of the property used to specify the output encoding in
     * the marshalled XML data.
     */
    String JAXB_ENCODING =
        "jaxb.encoding";

    /**
     * The name of the property used to specify whether or not the marshalled
     * XML data is formatted with linefeeds and indentation.
     */
    String JAXB_FORMATTED_OUTPUT =
        "jaxb.formatted.output";

    /**
     * The name of the property used to specify the xsi:schemaLocation
     * attribute value to place in the marshalled XML output.
     */
    String JAXB_SCHEMA_LOCATION =
        "jaxb.schemaLocation";

    /**
     * The name of the property used to specify the
     * xsi:noNamespaceSchemaLocation attribute value to place in the marshalled
     * XML output.
     */
    String JAXB_NO_NAMESPACE_SCHEMA_LOCATION =
        "jaxb.noNamespaceSchemaLocation";

    /**
     * The name of the property used to specify whether or not the marshaller
     * will generate document level events (ie calling startDocument or endDocument).
     */
    String JAXB_FRAGMENT =
        "jaxb.fragment";

    /**
     * Marshal the content tree rooted at {@code jaxbElement} into the specified
     * {@code javax.xml.transform.Result}.
     *
     * <p>
     * All Jakarta XML Binding Providers must at least support
     * {@link javax.xml.transform.dom.DOMResult},
     * {@link javax.xml.transform.sax.SAXResult}, and
     * {@link javax.xml.transform.stream.StreamResult}. It can
     * support other derived classes of {@code Result} as well.
     *
     * @param jaxbElement
     *      The root of content tree to be marshalled.
     * @param result
     *      XML will be sent to this Result
     *
     * @throws JAXBException
     *      If any unexpected problem occurs during the marshalling.
     * @throws MarshalException
     *      If the {@link ValidationEventHandler ValidationEventHandler}
     *      returns false from its {@code handleEvent} method or the
     *      {@code Marshaller} is unable to marshal {@code jaxbElement} (or any
     *      object reachable from {@code jaxbElement}).  See <a href="#elementMarshalling">
     *      Marshalling a Jakarta XML Binding element</a>.
     * @throws IllegalArgumentException
     *      If any of the method parameters are null
     */
    void marshal(Object jaxbElement, javax.xml.transform.Result result)
        throws JAXBException;

    /**
     * Marshal the content tree rooted at {@code jaxbElement} into an output stream.
     *
     * @param jaxbElement
     *      The root of content tree to be marshalled.
     * @param os
     *      XML will be added to this stream.
     *
     * @throws JAXBException
     *      If any unexpected problem occurs during the marshalling.
     * @throws MarshalException
     *      If the {@link ValidationEventHandler ValidationEventHandler}
     *      returns false from its {@code handleEvent} method or the
     *      {@code Marshaller} is unable to marshal {@code jaxbElement} (or any
     *      object reachable from {@code jaxbElement}).  See <a href="#elementMarshalling">
     *      Marshalling a Jakarta XML Binding element</a>.
     * @throws IllegalArgumentException
     *      If any of the method parameters are null
     */
    void marshal(Object jaxbElement, java.io.OutputStream os)
        throws JAXBException;

    /**
     * Marshal the content tree rooted at {@code jaxbElement} into a file.
     *
     * @param jaxbElement
     *      The root of content tree to be marshalled.
     * @param output
     *      File to be written. If this file already exists, it will be overwritten.
     *
     * @throws JAXBException
     *      If any unexpected problem occurs during the marshalling.
     * @throws MarshalException
     *      If the {@link ValidationEventHandler ValidationEventHandler}
     *      returns false from its {@code handleEvent} method or the
     *      {@code Marshaller} is unable to marshal {@code jaxbElement} (or any
     *      object reachable from {@code jaxbElement}).  See <a href="#elementMarshalling">
     *      Marshalling a Jakarta XML Binding element</a>.
     * @throws IllegalArgumentException
     *      If any of the method parameters are null
     * @since 1.6, JAXB 2.1
     */
    void marshal(Object jaxbElement, File output)
        throws JAXBException;

    /**
     * Marshal the content tree rooted at {@code jaxbElement} into a Writer.
     *
     * @param jaxbElement
     *      The root of content tree to be marshalled.
     * @param writer
     *      XML will be sent to this writer.
     *
     * @throws JAXBException
     *      If any unexpected problem occurs during the marshalling.
     * @throws MarshalException
     *      If the {@link ValidationEventHandler ValidationEventHandler}
     *      returns false from its {@code handleEvent} method or the
     *      {@code Marshaller} is unable to marshal {@code jaxbElement} (or any
     *      object reachable from {@code jaxbElement}).  See <a href="#elementMarshalling">
     *      Marshalling a Jakarta XML Binding element</a>.
     * @throws IllegalArgumentException
     *      If any of the method parameters are null
     */
    void marshal(Object jaxbElement, java.io.Writer writer)
        throws JAXBException;

    /**
     * Marshal the content tree rooted at {@code jaxbElement} into SAX2 events.
     *
     * @param jaxbElement
     *      The root of content tree to be marshalled.
     * @param handler
     *      XML will be sent to this handler as SAX2 events.
     *
     * @throws JAXBException
     *      If any unexpected problem occurs during the marshalling.
     * @throws MarshalException
     *      If the {@link ValidationEventHandler ValidationEventHandler}
     *      returns false from its {@code handleEvent} method or the
     *      {@code Marshaller} is unable to marshal {@code jaxbElement} (or any
     *      object reachable from {@code jaxbElement}).  See <a href="#elementMarshalling">
     *      Marshalling a Jakarta XML Binding element</a>.
     * @throws IllegalArgumentException
     *      If any of the method parameters are null
     */
    void marshal(Object jaxbElement, org.xml.sax.ContentHandler handler)
        throws JAXBException;

    /**
     * Marshal the content tree rooted at {@code jaxbElement} into a DOM tree.
     *
     * @param jaxbElement
     *      The content tree to be marshalled.
     * @param node
     *      DOM nodes will be added as children of this node.
     *      This parameter must be a Node that accepts children
     *      ({@link org.w3c.dom.Document},
     *      {@link  org.w3c.dom.DocumentFragment}, or
     *      {@link  org.w3c.dom.Element})
     *
     * @throws JAXBException
     *      If any unexpected problem occurs during the marshalling.
     * @throws MarshalException
     *      If the {@link ValidationEventHandler ValidationEventHandler}
     *      returns false from its {@code handleEvent} method or the
     *      {@code Marshaller} is unable to marshal {@code jaxbElement} (or any
     *      object reachable from {@code jaxbElement}).  See <a href="#elementMarshalling">
     *      Marshalling a Jakarta XML Binding element</a>.
     * @throws IllegalArgumentException
     *      If any of the method parameters are null
     */
    void marshal(Object jaxbElement, org.w3c.dom.Node node)
        throws JAXBException;

    /**
     * Marshal the content tree rooted at {@code jaxbElement} into a
     * {@link javax.xml.stream.XMLStreamWriter}.
     *
     * @param jaxbElement
     *      The content tree to be marshalled.
     * @param writer
     *      XML will be sent to this writer.
     *
     * @throws JAXBException
     *      If any unexpected problem occurs during the marshalling.
     * @throws MarshalException
     *      If the {@link ValidationEventHandler ValidationEventHandler}
     *      returns false from its {@code handleEvent} method or the
     *      {@code Marshaller} is unable to marshal {@code jaxbElement} (or any
     *      object reachable from {@code jaxbElement}).  See <a href="#elementMarshalling">
     *      Marshalling a Jakarta XML Binding element</a>.
     * @throws IllegalArgumentException
     *      If any of the method parameters are null
     * @since 1.6, JAXB 2.0
     */
    void marshal(Object jaxbElement, javax.xml.stream.XMLStreamWriter writer)
        throws JAXBException;

    /**
     * Marshal the content tree rooted at {@code jaxbElement} into a
     * {@link javax.xml.stream.XMLEventWriter}.
     *
     * @param jaxbElement
     *      The content tree rooted at jaxbElement to be marshalled.
     * @param writer
     *      XML will be sent to this writer.
     *
     * @throws JAXBException
     *      If any unexpected problem occurs during the marshalling.
     * @throws MarshalException
     *      If the {@link ValidationEventHandler ValidationEventHandler}
     *      returns false from its {@code handleEvent} method or the
     *      {@code Marshaller} is unable to marshal {@code jaxbElement} (or any
     *      object reachable from {@code jaxbElement}).  See <a href="#elementMarshalling">
     *      Marshalling a Jakarta XML Binding element</a>.
     * @throws IllegalArgumentException
     *      If any of the method parameters are null
     * @since 1.6, JAXB 2.0
     */
    void marshal(Object jaxbElement, javax.xml.stream.XMLEventWriter writer)
        throws JAXBException;

    /**
     * Get a DOM tree view of the content tree(Optional).
     *
     * If the returned DOM tree is updated, these changes are also
     * visible in the content tree.
     * Use {@link #marshal(Object, org.w3c.dom.Node)} to force
     * a deep copy of the content tree to a DOM representation.
     *
     * @param contentTree - Jakarta XML Binding Java representation of XML content
     *
     * @return the DOM tree view of the contentTree
     *
     * @throws UnsupportedOperationException
     *      If the Jakarta XML Binding provider implementation does not support a
     *      DOM view of the content tree
     *
     * @throws IllegalArgumentException
     *      If any of the method parameters are null
     *
     * @throws JAXBException
     *      If any unexpected problem occurs
     *
     */
    org.w3c.dom.Node getNode(java.lang.Object contentTree)
        throws JAXBException;

    /**
     * Set the particular property in the underlying implementation of
     * {@code Marshaller}.  This method can only be used to set one of
     * the standard Jakarta XML Binding defined properties above or a provider specific
     * property.  Attempting to set an undefined property will result in
     * a PropertyException being thrown.  See <a href="#supportedProps">
     * Supported Properties</a>.
     *
     * @param name the name of the property to be set. This value can either
     *              be specified using one of the constant fields or a user
     *              supplied string.
     * @param value the value of the property to be set
     *
     * @throws PropertyException when there is an error processing the given
     *                            property or value
     * @throws IllegalArgumentException
     *      If the name parameter is null
     */
    void setProperty(String name, Object value)
        throws PropertyException;

    /**
     * Get the particular property in the underlying implementation of
     * {@code Marshaller}.  This method can only be used to get one of
     * the standard Jakarta XML Binding defined properties above or a provider specific
     * property.  Attempting to get an undefined property will result in
     * a PropertyException being thrown.  See <a href="#supportedProps">
     * Supported Properties</a>.
     *
     * @param name the name of the property to retrieve
     * @return the value of the requested property
     *
     * @throws PropertyException
     *      when there is an error retrieving the given property or value
     *      property name
     * @throws IllegalArgumentException
     *      If the name parameter is null
     */
    Object getProperty(String name) throws PropertyException;

    /**
     * Allow an application to register a validation event handler.
     * <p>
     * The validation event handler will be called by the Jakarta XML Binding Provider if any
     * validation errors are encountered during calls to any of the marshal
     * API's.  If the client application does not register a validation event
     * handler before invoking one of the marshal methods, then validation
     * events will be handled by the default event handler which will terminate
     * the marshal operation after the first error or fatal error is encountered.
     * <p>
     * Calling this method with a null parameter will cause the Marshaller
     * to revert back to the default default event handler.
     *
     * @param handler the validation event handler
     * @throws JAXBException if an error was encountered while setting the
     *         event handler
     */
    void setEventHandler(ValidationEventHandler handler)
        throws JAXBException;

    /**
     * Return the current event handler or the default event handler if one
     * hasn't been set.
     *
     * @return the current ValidationEventHandler or the default event handler
     *         if it hasn't been set
     * @throws JAXBException if an error was encountered while getting the
     *         current event handler
     */
    ValidationEventHandler getEventHandler()
        throws JAXBException;



    /**
     * Associates a configured instance of {@link XmlAdapter} with this marshaller.
     *
     * <p>
     * This is a convenience method that invokes {@code setAdapter(adapter.getClass(),adapter);}.
     *
     * @param adapter
     *      The instance of the adapter to be used. If null, it will un-register
     *      the current adapter set for this type.
     *
     * @param <A> the type of the adapter
     *
     * @see #setAdapter(Class,XmlAdapter)
     * @throws IllegalArgumentException
     *      if the adapter parameter is null.
     * @throws UnsupportedOperationException
     *      if invoked agains a JAXB 1.0 implementation.
     * @since 1.6, JAXB 2.0
     */
    <A extends XmlAdapter<?, ?>> void setAdapter(A adapter);

    /**
     * Associates a configured instance of {@link XmlAdapter} with this marshaller.
     *
     * <p>
     * Every marshaller internally maintains a
     * {@link java.util.Map}&lt;{@link Class},{@link XmlAdapter}&gt;,
     * which it uses for marshalling classes whose fields/methods are annotated
     * with {@link jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter}.
     *
     * <p>
     * This method allows applications to use a configured instance of {@link XmlAdapter}.
     * When an instance of an adapter is not given, a marshaller will create
     * one by invoking its default constructor.
     *
     * @param type
     *      The type of the adapter. The specified instance will be used when
     *      {@link jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter#value()}
     *      refers to this type.
     * @param adapter
     *      The instance of the adapter to be used. If null, it will un-register
     *      the current adapter set for this type.
     * @param <A> the type of the adapter
     *
     * @throws IllegalArgumentException
     *      if the type parameter is null.
     * @throws UnsupportedOperationException
     *      if invoked agains a JAXB 1.0 implementation.
     * @since 1.6, JAXB 2.0
     */
    <A extends XmlAdapter<?, ?>> void setAdapter(Class<A> type, A adapter);

    /**
     * Gets the adapter associated with the specified type.
     * This is the reverse operation of the {@link #setAdapter} method.
     *
     * @param type
     *      The type of the adapter. The specified instance will be used when
     *      {@link jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter#value()}
     *      refers to this type.
     *
     * @param <A> the type of the adapter
     *
     * @return
     *      The adapter associated with the specified type.
     *
     * @throws IllegalArgumentException
     *      if the type parameter is null.
     * @throws UnsupportedOperationException
     *      if invoked agains a JAXB 1.0 implementation.
     * @since 1.6, JAXB 2.0
     */
    <A extends XmlAdapter<?, ?>> A getAdapter(Class<A> type);


    /**
     * Associate a context that enables binary data within an XML document
     * to be transmitted as XML-binary optimized attachment.
     * The attachment is referenced from the XML document content model
     * by content-id URIs(cid) references stored within the xml document.
     *
     * @param am the attachment marshaller to be set
     *
     * @throws IllegalStateException if attempt to concurrently call this
     *                               method during a marshal operation.
     */
    void setAttachmentMarshaller(AttachmentMarshaller am);

    AttachmentMarshaller getAttachmentMarshaller();

    /**
     * Specify the JAXP {@link javax.xml.validation.Schema Schema}
     * object that should be used to validate subsequent marshal operations
     * against.  Passing null into this method will disable validation.
     *
     * <p>
     * This method allows the caller to validate the marshalled XML as it's marshalled.
     *
     * <p>
     * Initially this property is set to {@code null}.
     *
     * @param schema Schema object to validate marshal operations against or null to disable validation
     * @throws UnsupportedOperationException could be thrown if this method is
     *         invoked on an Marshaller created from a JAXBContext referencing
     *         JAXB 1.0 mapped classes
     * @since 1.6, JAXB 2.0
     */
    void setSchema(Schema schema);

    /**
     * Get the JAXP {@link javax.xml.validation.Schema Schema} object
     * being used to perform marshal-time validation.  If there is no
     * Schema set on the marshaller, then this method will return null
     * indicating that marshal-time validation will not be performed.
     *
     * @return the Schema object being used to perform marshal-time
     *      validation or null if not present.
     * @throws UnsupportedOperationException could be thrown if this method is
     *         invoked on an Marshaller created from a JAXBContext referencing
     *         JAXB 1.0 mapped classes
     * @since 1.6, JAXB 2.0
     */
    Schema getSchema();

    /**
     * <p>
     * Register an instance of an implementation of this class with a {@link Marshaller} to externally listen
     * for marshal events.
     * </p>
     * <p>
     * This class enables pre and post processing of each marshalled object.
     * The event callbacks are called when marshalling from an instance that maps to an xml element or
     * complex type definition. The event callbacks are not called when marshalling from an instance of a
     * Java datatype that represents a simple type definition.
     * </p>
     * <p>
     * External listener is one of two different mechanisms for defining marshal event callbacks.
     * See <a href="Marshaller.html#marshalEventCallback">Marshal Event Callbacks</a> for an overview.
     *
     * @see Marshaller#setListener(Listener)
     * @see Marshaller#getListener()
     * @since 1.6, JAXB 2.0
     */
    abstract class Listener {

        /**
         * Do-nothing constructor for the derived classes.
         */
        protected Listener() {
        }

        /**
         * <p>
         * Callback method invoked before marshalling from {@code source} to XML.
         * </p>
         * <p>
         * This method is invoked just before marshalling process starts to marshal {@code source}.
         * Note that if the class of {@code source} defines its own {@code beforeMarshal} method,
         * the class specific callback method is invoked just before this method is invoked.
         *
         * @param source instance of Jakarta XML Binding mapped class prior to marshalling from it.
         */
        public void beforeMarshal(Object source) {
        }

        /**
         * <p>
         * Callback method invoked after marshalling {@code source} to XML.
         * </p>
         * <p>
         * This method is invoked after {@code source} and all its descendants have been marshalled.
         * Note that if the class of {@code source} defines its own {@code afterMarshal} method,
         * the class specific callback method is invoked just before this method is invoked.
         *
         * @param source instance of Jakarta XML Binding mapped class after marshalling it.
         */
        public void afterMarshal(Object source) {
        }
    }

    /**
     * <p>
     * Register marshal event callback {@link Listener} with this {@link Marshaller}.
     *
     * <p>
     * There is only one Listener per Marshaller. Setting a Listener replaces the previous set Listener.
     * One can unregister current Listener by setting listener to {@code null}.
     *
     * @param listener an instance of a class that implements {@link Listener}
     * @since 1.6, JAXB 2.0
     */
    void setListener(Listener listener);

    /**
     * <p>Return {@link Listener} registered with this {@link Marshaller}.
     *
     * @return registered {@link Listener} or {@code null}
     *         if no Listener is registered with this Marshaller.
     * @since 1.6, JAXB 2.0
     */
    Listener getListener();
}
