--- old/src/java.xml.bind/share/classes/com/sun/xml/internal/bind/v2/runtime/XMLSerializer.java 2018-01-30 20:33:35.000000000 -0500
+++ /dev/null 2018-01-30 20:33:35.000000000 -0500
@@ -1,1077 +0,0 @@
-/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.xml.internal.bind.v2.runtime;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import javax.activation.MimeType;
-import javax.xml.bind.DatatypeConverter;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.ValidationEvent;
-import javax.xml.bind.ValidationEventHandler;
-import javax.xml.bind.ValidationEventLocator;
-import javax.xml.bind.annotation.DomHandler;
-import javax.xml.bind.annotation.XmlNs;
-import javax.xml.bind.attachment.AttachmentMarshaller;
-import javax.xml.bind.helpers.NotIdentifiableEventImpl;
-import javax.xml.bind.helpers.ValidationEventImpl;
-import javax.xml.bind.helpers.ValidationEventLocatorImpl;
-import javax.xml.namespace.QName;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.sax.SAXResult;
-
-import com.sun.istack.internal.SAXException2;
-import com.sun.xml.internal.bind.CycleRecoverable;
-import com.sun.xml.internal.bind.api.AccessorException;
-import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;
-import com.sun.xml.internal.bind.util.ValidationEventLocatorExImpl;
-import com.sun.xml.internal.bind.v2.WellKnownNamespace;
-import com.sun.xml.internal.bind.v2.model.runtime.RuntimeBuiltinLeafInfo;
-import com.sun.xml.internal.bind.v2.runtime.output.MTOMXmlOutput;
-import com.sun.xml.internal.bind.v2.runtime.output.NamespaceContextImpl;
-import com.sun.xml.internal.bind.v2.runtime.output.Pcdata;
-import com.sun.xml.internal.bind.v2.runtime.output.XmlOutput;
-import com.sun.xml.internal.bind.v2.runtime.property.Property;
-import com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data;
-import com.sun.xml.internal.bind.v2.runtime.unmarshaller.IntData;
-import com.sun.xml.internal.bind.v2.util.CollisionCheckStack;
-
-import org.xml.sax.SAXException;
-
-/**
- * Receives XML serialization event and writes to {@link XmlOutput}.
- *
- *
- * This object coordinates the overall marshalling efforts across different
- * content-tree objects and different target formats.
- *
- *
- * The following CFG gives the proper sequence of method invocation.
- *
- *
- * MARSHALLING := ELEMENT
- * ELEMENT := "startElement" NSDECL* "endNamespaceDecls"
- * ATTRIBUTE* "endAttributes" BODY "endElement"
- *
- * NSDECL := "declareNamespace"
- *
- * ATTRIBUTE := "attribute"
- * ATTVALUES := "text"*
- *
- *
- * BODY := ( "text" | ELEMENT )*
- *
- *
- *
- * A marshalling of one element consists of two stages. The first stage is
- * for marshalling attributes and collecting namespace declarations.
- * The second stage is for marshalling characters/child elements of that element.
- *
- *
- * Observe that multiple invocation of "text" is allowed.
- *
- *
- * Also observe that the namespace declarations are allowed only between
- * "startElement" and "endAttributes".
- *
- *
Exceptions in marshaller
- *
- * {@link IOException}, {@link SAXException}, and {@link XMLStreamException}
- * are thrown from {@link XmlOutput}. They are always considered fatal, and
- * therefore caught only by {@link MarshallerImpl}.
- *
- * {@link AccessorException} can be thrown when an access to a property/field
- * fails, and this is considered as a recoverable error, so it's caught everywhere.
- *
- * @author Kohsuke Kawaguchi
- */
-public final class XMLSerializer extends Coordinator {
- public final JAXBContextImpl grammar;
-
- /** The XML printer. */
- private XmlOutput out;
-
- public final NameList nameList;
-
- public final int[] knownUri2prefixIndexMap;
-
- private final NamespaceContextImpl nsContext;
-
- private NamespaceContextImpl.Element nse;
-
- // Introduced based on Jersey requirements - to be able to retrieve marshalled name
- ThreadLocal currentProperty = new ThreadLocal();
-
- /**
- * Set to true if a text is already written,
- * and we need to print ' ' for additional text methods.
- */
- private boolean textHasAlreadyPrinted = false;
-
- /**
- * Set to false once we see the start tag of the root element.
- */
- private boolean seenRoot = false;
-
- /** Marshaller object to which this object belongs. */
- private final MarshallerImpl marshaller;
-
- /** Objects referenced through IDREF. */
- private final Set idReferencedObjects = new HashSet();
-
- /** Objects with ID. */
- private final Set objectsWithId = new HashSet();
-
- /**
- * Used to detect cycles in the object.
- * Also used to learn what's being marshalled.
- */
- private final CollisionCheckStack cycleDetectionStack = new CollisionCheckStack();
-
- /** Optional attributes to go with root element. */
- private String schemaLocation;
- private String noNsSchemaLocation;
-
- /** Lazily created identitiy transformer. */
- private Transformer identityTransformer;
-
- /** Lazily created. */
- private ContentHandlerAdaptor contentHandlerAdapter;
-
- private boolean fragment;
-
- /**
- * Cached instance of {@link Base64Data}.
- */
- private Base64Data base64Data;
-
- /**
- * Cached instance of {@link IntData}.
- */
- private final IntData intData = new IntData();
-
- public AttachmentMarshaller attachmentMarshaller;
-
- /*package*/ XMLSerializer( MarshallerImpl _owner ) {
- this.marshaller = _owner;
- this.grammar = marshaller.context;
- nsContext = new NamespaceContextImpl(this);
- nameList = marshaller.context.nameList;
- knownUri2prefixIndexMap = new int[nameList.namespaceURIs.length];
- }
-
- /**
- * Gets the cached instance of {@link Base64Data}.
- *
- * @deprecated
- * {@link Base64Data} is no longer cached, so that
- * XMLStreamWriterEx impl can retain the data, like JAX-WS does.
- */
- public Base64Data getCachedBase64DataInstance() {
- return new Base64Data();
- }
-
- /**
- * Gets the ID value from an identifiable object.
- */
- private String getIdFromObject(Object identifiableObject) throws SAXException, JAXBException {
- return grammar.getBeanInfo(identifiableObject,true).getId(identifiableObject,this);
- }
-
- private void handleMissingObjectError(String fieldName) throws SAXException, IOException, XMLStreamException {
- reportMissingObjectError(fieldName);
- // as a marshaller, we should be robust, so we'll continue to marshal
- // this document by skipping this missing object.
- endNamespaceDecls(null);
- endAttributes();
- }
-
-
- public void reportError( ValidationEvent ve ) throws SAXException {
- ValidationEventHandler handler;
-
- try {
- handler = marshaller.getEventHandler();
- } catch( JAXBException e ) {
- throw new SAXException2(e);
- }
-
- if(!handler.handleEvent(ve)) {
- if(ve.getLinkedException() instanceof Exception)
- throw new SAXException2((Exception)ve.getLinkedException());
- else
- throw new SAXException2(ve.getMessage());
- }
- }
-
- /**
- * Report an error found as an exception.
- *
- * @param fieldName
- * the name of the property being processed when an error is found.
- */
- public final void reportError(String fieldName, Throwable t) throws SAXException {
- ValidationEvent ve = new ValidationEventImpl(ValidationEvent.ERROR,
- t.getMessage(), getCurrentLocation(fieldName), t);
- reportError(ve);
- }
-
- public void startElement(Name tagName, Object outerPeer) {
- startElement();
- nse.setTagName(tagName,outerPeer);
- }
-
- public void startElement(String nsUri, String localName, String preferredPrefix, Object outerPeer) {
- startElement();
- int idx = nsContext.declareNsUri(nsUri, preferredPrefix, false);
- nse.setTagName(idx,localName,outerPeer);
- }
-
- /**
- * Variation of {@link #startElement(String, String, String, Object)} that forces
- * a specific prefix. Needed to preserve the prefix when marshalling DOM.
- */
- public void startElementForce(String nsUri, String localName, String forcedPrefix, Object outerPeer) {
- startElement();
- int idx = nsContext.force(nsUri, forcedPrefix);
- nse.setTagName(idx,localName,outerPeer);
- }
-
- public void endNamespaceDecls(Object innerPeer) throws IOException, XMLStreamException {
- nsContext.collectionMode = false;
- nse.startElement(out,innerPeer);
- }
-
- /**
- * Switches to the "marshal child texts/elements" mode.
- * This method has to be called after the 1st pass is completed.
- */
- public void endAttributes() throws SAXException, IOException, XMLStreamException {
- if(!seenRoot) {
- seenRoot = true;
- if(schemaLocation!=null || noNsSchemaLocation!=null) {
- int p = nsContext.getPrefixIndex(WellKnownNamespace.XML_SCHEMA_INSTANCE);
- if(schemaLocation!=null)
- out.attribute(p,"schemaLocation",schemaLocation);
- if(noNsSchemaLocation!=null)
- out.attribute(p,"noNamespaceSchemaLocation",noNsSchemaLocation);
- }
- }
-
- out.endStartTag();
- }
-
- /**
- * Ends marshalling of an element.
- * Pops the internal stack.
- */
- public void endElement() throws SAXException, IOException, XMLStreamException {
- nse.endElement(out);
- nse = nse.pop();
- textHasAlreadyPrinted = false;
- }
-
- public void leafElement( Name tagName, String data, String fieldName ) throws SAXException, IOException, XMLStreamException {
- if(seenRoot) {
- textHasAlreadyPrinted = false;
- nse = nse.push();
- out.beginStartTag(tagName);
- out.endStartTag();
- if(data != null)
- try {
- out.text(data,false);
- } catch (IllegalArgumentException e) {
- throw new IllegalArgumentException(Messages.ILLEGAL_CONTENT.format(fieldName, e.getMessage()));
- }
- out.endTag(tagName);
- nse = nse.pop();
- } else {
- // root element has additional processing like xsi:schemaLocation,
- // so we need to go the slow way
- startElement(tagName,null);
- endNamespaceDecls(null);
- endAttributes();
- try {
- out.text(data, false);
- } catch (IllegalArgumentException e) {
- throw new IllegalArgumentException(Messages.ILLEGAL_CONTENT.format(fieldName, e.getMessage()));
- }
- endElement();
- }
- }
-
- public void leafElement( Name tagName, Pcdata data, String fieldName ) throws SAXException, IOException, XMLStreamException {
- if(seenRoot) {
- textHasAlreadyPrinted = false;
- nse = nse.push();
- out.beginStartTag(tagName);
- out.endStartTag();
- if(data != null)
- out.text(data,false);
- out.endTag(tagName);
- nse = nse.pop();
- } else {
- // root element has additional processing like xsi:schemaLocation,
- // so we need to go the slow way
- startElement(tagName,null);
- endNamespaceDecls(null);
- endAttributes();
- out.text(data,false);
- endElement();
- }
- }
-
- public void leafElement( Name tagName, int data, String fieldName ) throws SAXException, IOException, XMLStreamException {
- intData.reset(data);
- leafElement(tagName,intData,fieldName);
- }
-
- /**
- * Marshalls text.
- *
- *
- * This method can be called after the {@link #endAttributes()}
- * method to marshal texts inside elements.
- * If the method is called more than once, those texts are considered
- * as separated by whitespaces. For example,
- *
- *
- * c.startElement("","foo");
- * c.endAttributes();
- * c.text("abc");
- * c.text("def");
- * c.startElement("","bar");
- * c.endAttributes();
- * c.endElement();
- * c.text("ghi");
- * c.endElement();
- *
- *
- * will generate {@code abc def ghi }.
- */
- public void text( String text, String fieldName ) throws SAXException, IOException, XMLStreamException {
- // If the assertion fails, it must be a bug of xjc.
- // right now, we are not expecting the text method to be called.
- if(text==null) {
- reportMissingObjectError(fieldName);
- return;
- }
-
- out.text(text,textHasAlreadyPrinted);
- textHasAlreadyPrinted = true;
- }
-
- /**
- * The {@link #text(String, String)} method that takes {@link Pcdata}.
- */
- public void text( Pcdata text, String fieldName ) throws SAXException, IOException, XMLStreamException {
- // If the assertion fails, it must be a bug of xjc.
- // right now, we are not expecting the text method to be called.
- if(text==null) {
- reportMissingObjectError(fieldName);
- return;
- }
-
- out.text(text,textHasAlreadyPrinted);
- textHasAlreadyPrinted = true;
- }
-
- public void attribute(String uri, String local, String value) throws SAXException {
- int prefix;
- if(uri.length()==0) {
- // default namespace. don't need prefix
- prefix = -1;
- } else {
- prefix = nsContext.getPrefixIndex(uri);
- }
-
- try {
- out.attribute(prefix,local,value);
- } catch (IOException e) {
- throw new SAXException2(e);
- } catch (XMLStreamException e) {
- throw new SAXException2(e);
- }
- }
-
- public void attribute(Name name, CharSequence value) throws IOException, XMLStreamException {
- // TODO: consider having the version that takes Pcdata.
- // it's common for an element to have int attributes
- out.attribute(name,value.toString());
- }
-
- public NamespaceContext2 getNamespaceContext() {
- return nsContext;
- }
-
-
- public String onID( Object owner, String value ) {
- objectsWithId.add(owner);
- return value;
- }
-
- public String onIDREF( Object obj ) throws SAXException {
- String id;
- try {
- id = getIdFromObject(obj);
- } catch (JAXBException e) {
- reportError(null,e);
- return null; // recover by returning null
- }
- idReferencedObjects.add(obj);
- if(id==null) {
- reportError( new NotIdentifiableEventImpl(
- ValidationEvent.ERROR,
- Messages.NOT_IDENTIFIABLE.format(),
- new ValidationEventLocatorImpl(obj) ) );
- }
- return id;
- }
-
-
- // TODO: think about the exception handling.
- // I suppose we don't want to use SAXException. -kk
-
- public void childAsRoot(Object obj) throws JAXBException, IOException, SAXException, XMLStreamException {
- final JaxBeanInfo beanInfo = grammar.getBeanInfo(obj, true);
-
- // since the same object will be reported to childAsRoot or
- // childAsXsiType, don't make it a part of the collision check.
- // but we do need to push it so that getXMIMEContentType will work.
- cycleDetectionStack.pushNocheck(obj);
-
- final boolean lookForLifecycleMethods = beanInfo.lookForLifecycleMethods();
- if (lookForLifecycleMethods) {
- fireBeforeMarshalEvents(beanInfo, obj);
- }
-
- beanInfo.serializeRoot(obj,this);
-
- if (lookForLifecycleMethods) {
- fireAfterMarshalEvents(beanInfo, obj);
- }
-
- cycleDetectionStack.pop();
- }
-
- /**
- * Pushes the object to {@link #cycleDetectionStack} and also
- * detect any cycles.
- *
- * When a cycle is found, this method tries to recover from it.
- *
- * @return
- * the object that should be marshalled instead of the given {@code obj},
- * or null if the error is found and we need to avoid marshalling this object
- * to prevent infinite recursion. When this method returns null, the error
- * has already been reported.
- */
- private Object pushObject(Object obj, String fieldName) throws SAXException {
- if(!cycleDetectionStack.push(obj))
- return obj;
-
- // allow the object to nominate its replacement
- if(obj instanceof CycleRecoverable) {
- obj = ((CycleRecoverable)obj).onCycleDetected(new CycleRecoverable.Context(){
- public Marshaller getMarshaller() {
- return marshaller;
- }
- });
- if(obj!=null) {
- // object nominated its replacement.
- // we still need to make sure that the nominated.
- // this may cause inifinite recursion on its own.
- cycleDetectionStack.pop();
- return pushObject(obj,fieldName);
- } else
- return null;
- }
-
- // cycle detected and no one is catching the error.
- reportError(new ValidationEventImpl(
- ValidationEvent.ERROR,
- Messages.CYCLE_IN_MARSHALLER.format(cycleDetectionStack.getCycleString()),
- getCurrentLocation(fieldName),
- null));
- return null;
- }
-
- /**
- * The equivalent of:
- *
- *
- * childAsURIs(child, fieldName);
- * endNamespaceDecls();
- * childAsAttributes(child, fieldName);
- * endAttributes();
- * childAsBody(child, fieldName);
- *
- *
- * This produces the given child object as the sole content of
- * an element.
- * Used to reduce the code size in the generated marshaller.
- */
- public final void childAsSoleContent( Object child, String fieldName) throws SAXException, IOException, XMLStreamException {
- if(child==null) {
- handleMissingObjectError(fieldName);
- } else {
- child = pushObject(child,fieldName);
- if(child==null) {
- // error recovery
- endNamespaceDecls(null);
- endAttributes();
- cycleDetectionStack.pop();
- }
-
- JaxBeanInfo beanInfo;
- try {
- beanInfo = grammar.getBeanInfo(child,true);
- } catch (JAXBException e) {
- reportError(fieldName,e);
- // recover by ignore
- endNamespaceDecls(null);
- endAttributes();
- cycleDetectionStack.pop();
- return;
- }
-
- final boolean lookForLifecycleMethods = beanInfo.lookForLifecycleMethods();
- if (lookForLifecycleMethods) {
- fireBeforeMarshalEvents(beanInfo, child);
- }
-
- beanInfo.serializeURIs(child,this);
- endNamespaceDecls(child);
- beanInfo.serializeAttributes(child,this);
- endAttributes();
- beanInfo.serializeBody(child,this);
-
- if (lookForLifecycleMethods) {
- fireAfterMarshalEvents(beanInfo, child);
- }
-
- cycleDetectionStack.pop();
- }
- }
-
-
- // the version of childAsXXX where it produces @xsi:type if the expected type name
- // and the actual type name differs.
-
- /**
- * This method is called when a type child object is found.
- *
- *
- * This method produces events of the following form:
- *
- * NSDECL* "endNamespaceDecls" ATTRIBUTE* "endAttributes" BODY
- *
- * optionally including @xsi:type if necessary.
- *
- * @param child
- * Object to be marshalled. The {@link JaxBeanInfo} for
- * this object must return a type name.
- * @param expected
- * Expected type of the object.
- * @param fieldName
- * property name of the parent objeect from which 'o' comes.
- * Used as a part of the error message in case anything goes wrong
- * with 'o'.
- */
- public final void childAsXsiType( Object child, String fieldName, JaxBeanInfo expected, boolean nillable) throws SAXException, IOException, XMLStreamException {
- if(child==null) {
- handleMissingObjectError(fieldName);
- } else {
- child = pushObject(child,fieldName);
- if(child==null) { // error recovery
- endNamespaceDecls(null);
- endAttributes();
- return;
- }
-
- boolean asExpected = child.getClass()==expected.jaxbType;
- JaxBeanInfo actual = expected;
- QName actualTypeName = null;
-
- if((asExpected) && (actual.lookForLifecycleMethods())) {
- fireBeforeMarshalEvents(actual, child);
- }
-
- if(!asExpected) {
- try {
- actual = grammar.getBeanInfo(child,true);
- if (actual.lookForLifecycleMethods()) {
- fireBeforeMarshalEvents(actual, child);
- }
- } catch (JAXBException e) {
- reportError(fieldName,e);
- endNamespaceDecls(null);
- endAttributes();
- return; // recover by ignore
- }
- if(actual==expected)
- asExpected = true;
- else {
- actualTypeName = actual.getTypeName(child);
- if(actualTypeName==null) {
- reportError(new ValidationEventImpl(
- ValidationEvent.ERROR,
- Messages.SUBSTITUTED_BY_ANONYMOUS_TYPE.format(
- expected.jaxbType.getName(),
- child.getClass().getName(),
- actual.jaxbType.getName()),
- getCurrentLocation(fieldName)));
- // recover by not printing @xsi:type
- } else {
- getNamespaceContext().declareNamespace(WellKnownNamespace.XML_SCHEMA_INSTANCE,"xsi",true);
- getNamespaceContext().declareNamespace(actualTypeName.getNamespaceURI(),null,false);
- }
- }
- }
- actual.serializeURIs(child,this);
-
- if (nillable) {
- getNamespaceContext().declareNamespace(WellKnownNamespace.XML_SCHEMA_INSTANCE,"xsi",true);
- }
-
- endNamespaceDecls(child);
- if(!asExpected) {
- attribute(WellKnownNamespace.XML_SCHEMA_INSTANCE,"type",
- DatatypeConverter.printQName(actualTypeName,getNamespaceContext()));
- }
-
- actual.serializeAttributes(child,this);
- boolean nilDefined = actual.isNilIncluded();
- if ((nillable) && (!nilDefined)) {
- attribute(WellKnownNamespace.XML_SCHEMA_INSTANCE,"nil","true");
- }
-
- endAttributes();
- actual.serializeBody(child,this);
-
- if (actual.lookForLifecycleMethods()) {
- fireAfterMarshalEvents(actual, child);
- }
-
- cycleDetectionStack.pop();
- }
- }
-
- /**
- * Invoke the afterMarshal api on the external listener (if it exists) and on the bean embedded
- * afterMarshal api(if it exists).
- *
- * This method is called only after the callee has determined that beanInfo.lookForLifecycleMethods == true.
- *
- * @param beanInfo
- * @param currentTarget
- */
- private void fireAfterMarshalEvents(final JaxBeanInfo beanInfo, Object currentTarget) {
- // first invoke bean embedded listener
- if (beanInfo.hasAfterMarshalMethod()) {
- Method m = beanInfo.getLifecycleMethods().afterMarshal;
- fireMarshalEvent(currentTarget, m);
- }
-
- // then invoke external listener before bean embedded listener
- Marshaller.Listener externalListener = marshaller.getListener();
- if (externalListener != null) {
- externalListener.afterMarshal(currentTarget);
- }
-
- }
-
- /**
- * Invoke the beforeMarshal api on the external listener (if it exists) and on the bean embedded
- * beforeMarshal api(if it exists).
- *
- * This method is called only after the callee has determined that beanInfo.lookForLifecycleMethods == true.
- *
- * @param beanInfo
- * @param currentTarget
- */
- private void fireBeforeMarshalEvents(final JaxBeanInfo beanInfo, Object currentTarget) {
- // first invoke bean embedded listener
- if (beanInfo.hasBeforeMarshalMethod()) {
- Method m = beanInfo.getLifecycleMethods().beforeMarshal;
- fireMarshalEvent(currentTarget, m);
- }
-
- // then invoke external listener
- Marshaller.Listener externalListener = marshaller.getListener();
- if (externalListener != null) {
- externalListener.beforeMarshal(currentTarget);
- }
- }
-
- private void fireMarshalEvent(Object target, Method m) {
- try {
- m.invoke(target, marshaller);
- } catch (Exception e) {
- // this really only happens if there is a bug in the ri
- throw new IllegalStateException(e);
- }
- }
-
- public void attWildcardAsURIs(Map attributes, String fieldName) {
- if(attributes==null) return;
- for( Map.Entry e : attributes.entrySet() ) {
- QName n = e.getKey();
- String nsUri = n.getNamespaceURI();
- if(nsUri.length()>0) {
- String p = n.getPrefix();
- if(p.length()==0) p=null;
- nsContext.declareNsUri(nsUri, p, true);
- }
- }
- }
-
- public void attWildcardAsAttributes(Map attributes, String fieldName) throws SAXException {
- if(attributes==null) return;
- for( Map.Entry e : attributes.entrySet() ) {
- QName n = e.getKey();
- attribute(n.getNamespaceURI(),n.getLocalPart(),e.getValue());
- }
- }
-
- /**
- * Short for the following call sequence:
- *
- *
- getNamespaceContext().declareNamespace(WellKnownNamespace.XML_SCHEMA_INSTANCE,"xsi",true);
- endNamespaceDecls();
- attribute(WellKnownNamespace.XML_SCHEMA_INSTANCE,"nil","true");
- endAttributes();
- *
- */
- public final void writeXsiNilTrue() throws SAXException, IOException, XMLStreamException {
- getNamespaceContext().declareNamespace(WellKnownNamespace.XML_SCHEMA_INSTANCE,"xsi",true);
- endNamespaceDecls(null);
- attribute(WellKnownNamespace.XML_SCHEMA_INSTANCE,"nil","true");
- endAttributes();
- }
-
- public void writeDom(E element, DomHandler domHandler, Object parentBean, String fieldName) throws SAXException {
- Source source = domHandler.marshal(element,this);
- if(contentHandlerAdapter==null)
- contentHandlerAdapter = new ContentHandlerAdaptor(this);
- try {
- getIdentityTransformer().transform(source,new SAXResult(contentHandlerAdapter));
- } catch (TransformerException e) {
- reportError(fieldName,e);
- }
- }
-
- public Transformer getIdentityTransformer() {
- if (identityTransformer==null)
- identityTransformer = JAXBContextImpl.createTransformer(grammar.disableSecurityProcessing);
- return identityTransformer;
- }
-
- public void setPrefixMapper(NamespacePrefixMapper prefixMapper) {
- nsContext.setPrefixMapper(prefixMapper);
- }
-
- /**
- * Reset this object to write to the specified output.
- *
- * @param schemaLocation
- * if non-null, this value is printed on the root element as xsi:schemaLocation
- * @param noNsSchemaLocation
- * Similar to 'schemaLocation' but this one works for xsi:noNamespaceSchemaLocation
- */
- public void startDocument(XmlOutput out,boolean fragment,String schemaLocation,String noNsSchemaLocation) throws IOException, SAXException, XMLStreamException {
- pushCoordinator();
- nsContext.reset();
- nse = nsContext.getCurrent();
- if(attachmentMarshaller!=null && attachmentMarshaller.isXOPPackage())
- out = new MTOMXmlOutput(out);
- this.out = out;
- objectsWithId.clear();
- idReferencedObjects.clear();
- textHasAlreadyPrinted = false;
- seenRoot = false;
- this.schemaLocation = schemaLocation;
- this.noNsSchemaLocation = noNsSchemaLocation;
- this.fragment = fragment;
- this.inlineBinaryFlag = false;
- this.expectedMimeType = null;
- cycleDetectionStack.reset();
-
- out.startDocument(this,fragment,knownUri2prefixIndexMap,nsContext);
- }
-
- public void endDocument() throws IOException, SAXException, XMLStreamException {
- out.endDocument(fragment);
- }
-
- public void close() {
- out = null;
- clearCurrentProperty();
- popCoordinator();
- }
-
- /**
- * This method can be called after {@link #startDocument} is called
- * but before the marshalling begins, to set the currently in-scope namespace
- * bindings.
- *
- *
- * This method is useful to avoid redundant namespace declarations when
- * the marshalling is producing a sub-document.
- */
- public void addInscopeBinding(String nsUri,String prefix) {
- nsContext.put(nsUri,prefix);
- }
-
- /**
- * Gets the MIME type with which the binary content shall be printed.
- *
- *
- * This method shall be used from those {@link RuntimeBuiltinLeafInfo} that are
- * bound to base64Binary.
- *
- * @see JAXBContextImpl#getXMIMEContentType(Object)
- */
- public String getXMIMEContentType() {
- // xmime:contentType takes precedence
- String v = grammar.getXMIMEContentType(cycleDetectionStack.peek());
- if(v!=null) return v;
-
- // then look for the current in-scope @XmlMimeType
- if(expectedMimeType!=null)
- return expectedMimeType.toString();
-
- return null;
- }
-
- private void startElement() {
- nse = nse.push();
-
- if( !seenRoot ) {
-
- if (grammar.getXmlNsSet() != null) {
- for(XmlNs xmlNs : grammar.getXmlNsSet())
- nsContext.declareNsUri(
- xmlNs.namespaceURI(),
- xmlNs.prefix() == null ? "" : xmlNs.prefix(),
- xmlNs.prefix() != null);
- }
-
- // seenRoot set to true in endAttributes
- // first declare all known URIs
- String[] knownUris = nameList.namespaceURIs;
- for( int i=0; i
- * When we are marshalling a property with an effective {@link XmlSchemaType},
- * this field is set to hold the QName of that type. The {@link Transducer} that
- * actually converts a Java object into XML can look this property to decide
- * how to marshal the value.
- */
- private QName schemaType;
-
- public QName setSchemaType(QName st) {
- QName old = schemaType;
- schemaType = st;
- return old;
- }
-
- public QName getSchemaType() {
- return schemaType;
- }
-
- public void setObjectIdentityCycleDetection(boolean val) {
- cycleDetectionStack.setUseIdentity(val);
- }
- public boolean getObjectIdentityCycleDetection() {
- return cycleDetectionStack.getUseIdentity();
- }
-
- void reconcileID() throws SAXException {
- // find objects that were not a part of the object graph
- idReferencedObjects.removeAll(objectsWithId);
-
- for( Object idObj : idReferencedObjects ) {
- try {
- String id = getIdFromObject(idObj);
- reportError( new NotIdentifiableEventImpl(
- ValidationEvent.ERROR,
- Messages.DANGLING_IDREF.format(id),
- new ValidationEventLocatorImpl(idObj) ) );
- } catch (JAXBException e) {
- // this error should have been reported already. just ignore here.
- }
- }
-
- // clear the garbage
- idReferencedObjects.clear();
- objectsWithId.clear();
- }
-
- public boolean handleError(Exception e) {
- return handleError(e,cycleDetectionStack.peek(),null);
- }
-
- public boolean handleError(Exception e,Object source,String fieldName) {
- return handleEvent(
- new ValidationEventImpl(
- ValidationEvent.ERROR,
- e.getMessage(),
- new ValidationEventLocatorExImpl(source,fieldName),
- e));
- }
-
- public boolean handleEvent(ValidationEvent event) {
- try {
- return marshaller.getEventHandler().handleEvent(event);
- } catch (JAXBException e) {
- // impossible
- throw new Error(e);
- }
- }
-
- private void reportMissingObjectError(String fieldName) throws SAXException {
- reportError(new ValidationEventImpl(
- ValidationEvent.ERROR,
- Messages.MISSING_OBJECT.format(fieldName),
- getCurrentLocation(fieldName),
- new NullPointerException() ));
- }
-
- /**
- * Called when a referenced object doesn't have an ID.
- */
- public void errorMissingId(Object obj) throws SAXException {
- reportError( new ValidationEventImpl(
- ValidationEvent.ERROR,
- Messages.MISSING_ID.format(obj),
- new ValidationEventLocatorImpl(obj)) );
- }
-
- public ValidationEventLocator getCurrentLocation(String fieldName) {
- return new ValidationEventLocatorExImpl(cycleDetectionStack.peek(),fieldName);
- }
-
- protected ValidationEventLocator getLocation() {
- return getCurrentLocation(null);
- }
-
- /**
- * May return null when the property hasn't been set.
- * Introduced based on Jersey requirements.
- */
- public Property getCurrentProperty() {
- return currentProperty.get();
- }
-
- /**
- * Takes care of cleaning the currentProperty. Must be called from the same thread that created the XMLSerializer.
- */
- public void clearCurrentProperty() {
- if (currentProperty != null) {
- currentProperty.remove();
- }
- }
-
- /**
- * When called from within the realm of the marshaller, this method
- * returns the current {@link XMLSerializer} in charge.
- */
- public static XMLSerializer getInstance() {
- return (XMLSerializer)Coordinator._getInstance();
- }
-}