blob: 5554797663699f250498a551505391f976cbc66f [file] [log] [blame]
/*
* Copyright (c) 2014, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Blaise Doughan - 2.5 - initial implementation
package org.eclipse.persistence.internal.oxm;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.validation.Schema;
import org.eclipse.persistence.core.queries.CoreAttributeGroup;
import org.eclipse.persistence.core.sessions.CoreSession;
import org.eclipse.persistence.exceptions.EclipseLinkException;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.core.helper.CoreClassConstants;
import org.eclipse.persistence.internal.core.sessions.CoreAbstractSession;
import org.eclipse.persistence.internal.localization.JAXBLocalization;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.Field;
import org.eclipse.persistence.internal.oxm.record.AbstractMarshalRecord;
import org.eclipse.persistence.internal.oxm.record.ExtendedResult;
import org.eclipse.persistence.internal.oxm.record.namespaces.PrefixMapperNamespaceResolver;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.oxm.JSONWithPadding;
import org.eclipse.persistence.oxm.attachment.XMLAttachmentMarshaller;
import org.eclipse.persistence.oxm.record.ContentHandlerRecord;
import org.eclipse.persistence.oxm.record.FormattedOutputStreamRecord;
import org.eclipse.persistence.oxm.record.FormattedWriterRecord;
import org.eclipse.persistence.oxm.record.JSONFormattedWriterRecord;
import org.eclipse.persistence.oxm.record.JSONWriterRecord;
import org.eclipse.persistence.oxm.record.MarshalRecord;
import org.eclipse.persistence.oxm.record.NodeRecord;
import org.eclipse.persistence.oxm.record.OutputStreamRecord;
import org.eclipse.persistence.oxm.record.ValidatingMarshalRecord;
import org.eclipse.persistence.oxm.record.WriterRecord;
import org.eclipse.persistence.oxm.schema.XMLSchemaReference;
import org.eclipse.persistence.platform.xml.XMLPlatform;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.eclipse.persistence.platform.xml.XMLTransformer;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
import org.xml.sax.ext.LexicalHandler;
public abstract class XMLMarshaller<
ABSTRACT_SESSION extends CoreAbstractSession,
CHARACTER_ESCAPE_HANDLER extends CharacterEscapeHandler,
CONTEXT extends Context<ABSTRACT_SESSION, DESCRIPTOR, ?, ?, ?, SESSION, ?>,
DESCRIPTOR extends Descriptor<?, ?, ?, ?, ?, ?, ?, ?, ?, ?>,
MARSHALLER_LISTENER extends Marshaller.Listener,
MEDIA_TYPE extends MediaType,
NAMESPACE_PREFIX_MAPPER extends NamespacePrefixMapper,
OBJECT_BUILDER extends ObjectBuilder<?, ABSTRACT_SESSION, ?, XMLMarshaller>,
SESSION extends CoreSession> extends Marshaller<CHARACTER_ESCAPE_HANDLER, CONTEXT, MARSHALLER_LISTENER, MEDIA_TYPE, NAMESPACE_PREFIX_MAPPER> {
protected final static String DEFAULT_XML_VERSION = "1.0";
private static final String STAX_RESULT_CLASS_NAME = "javax.xml.transform.stax.StAXResult";
private static final String GET_XML_STREAM_WRITER_METHOD_NAME = "getXMLStreamWriter";
private static final String GET_XML_EVENT_WRITER_METHOD_NAME = "getXMLEventWriter";
private static final String XML_STREAM_WRITER_RECORD_CLASS_NAME = "org.eclipse.persistence.oxm.record.XMLStreamWriterRecord";
private static final String XML_EVENT_WRITER_RECORD_CLASS_NAME = "org.eclipse.persistence.oxm.record.XMLEventWriterRecord";
private static final String XML_STREAM_WRITER_CLASS_NAME = "javax.xml.stream.XMLStreamWriter";
private static final String XML_EVENT_WRITER_CLASS_NAME = "javax.xml.stream.XMLEventWriter";
private static final String DOM_TO_STREAM_WRITER_CLASS_NAME = "org.eclipse.persistence.internal.oxm.record.DomToXMLStreamWriter";
private static final String DOM_TO_EVENT_WRITER_CLASS_NAME = "org.eclipse.persistence.internal.oxm.record.DomToXMLEventWriter";
private static final String WRITE_TO_STREAM_METHOD_NAME = "writeToStream";
private static final String WRITE_TO_EVENT_WRITER_METHOD_NAME = "writeToEventWriter";
protected static Class staxResultClass;
protected static Method staxResultGetStreamWriterMethod;
protected static Method staxResultGetEventWriterMethod;
private static Constructor xmlStreamWriterRecordConstructor;
private static Constructor xmlEventWriterRecordConstructor;
protected static Method writeToStreamMethod;
protected static Method writeToEventWriterMethod;
protected static Class domToStreamWriterClass;
protected static Class domToEventWriterClass;
static {
try {
staxResultClass = PrivilegedAccessHelper.getClassForName(STAX_RESULT_CLASS_NAME);
if(staxResultClass != null) {
staxResultGetStreamWriterMethod = PrivilegedAccessHelper.getDeclaredMethod(staxResultClass, GET_XML_STREAM_WRITER_METHOD_NAME, new Class[]{});
staxResultGetEventWriterMethod = PrivilegedAccessHelper.getDeclaredMethod(staxResultClass, GET_XML_EVENT_WRITER_METHOD_NAME, new Class[]{});
}
Class streamWriterRecordClass = PrivilegedAccessHelper.getClassForName(XML_STREAM_WRITER_RECORD_CLASS_NAME);
Class streamWriterClass = PrivilegedAccessHelper.getClassForName(XML_STREAM_WRITER_CLASS_NAME);
xmlStreamWriterRecordConstructor = PrivilegedAccessHelper.getConstructorFor(streamWriterRecordClass, new Class[]{streamWriterClass}, true);
Class eventWriterRecordClass = PrivilegedAccessHelper.getClassForName(XML_EVENT_WRITER_RECORD_CLASS_NAME);
Class eventWriterClass = PrivilegedAccessHelper.getClassForName(XML_EVENT_WRITER_CLASS_NAME);
xmlEventWriterRecordConstructor = PrivilegedAccessHelper.getConstructorFor(eventWriterRecordClass, new Class[]{eventWriterClass}, true);
domToStreamWriterClass = PrivilegedAccessHelper.getClassForName(DOM_TO_STREAM_WRITER_CLASS_NAME);
writeToStreamMethod = PrivilegedAccessHelper.getMethod(domToStreamWriterClass, WRITE_TO_STREAM_METHOD_NAME, new Class[] {CoreClassConstants.NODE, CoreClassConstants.STRING, CoreClassConstants.STRING, streamWriterClass}, true);
domToEventWriterClass = PrivilegedAccessHelper.getClassForName(DOM_TO_EVENT_WRITER_CLASS_NAME);
writeToEventWriterMethod = PrivilegedAccessHelper.getMethod(domToEventWriterClass, WRITE_TO_EVENT_WRITER_METHOD_NAME, new Class[] {CoreClassConstants.NODE, CoreClassConstants.STRING, CoreClassConstants.STRING, eventWriterClass}, true);
} catch (Exception ex) {
// Do nothing
}
}
protected XMLAttachmentMarshaller attachmentMarshaller;
private String attributePrefix;
private boolean fragment;
private boolean includeRoot = true;
private boolean marshalEmptyCollections = true;
protected MEDIA_TYPE mediaType;
private char namespaceSeparator;
private String noNamespaceSchemaLocation;
private boolean reduceAnyArrays;
private Schema schema;
private String schemaLocation;
protected XMLTransformer transformer;
private String valueWrapper;
private boolean wrapperAsCollectionName = false;
private String xmlHeader;
private Object marshalAttributeGroup;
private Boolean logPayload;
protected XMLMarshaller(CONTEXT context) {
super(context);
this.includeRoot = true;
this.marshalEmptyCollections = true;
this.namespaceSeparator = Constants.DOT;
this.reduceAnyArrays = false;
this.valueWrapper = Constants.VALUE_WRAPPER;
}
/**
* Copy constructor
*/
protected XMLMarshaller(XMLMarshaller xmlMarshaller) {
super(xmlMarshaller);
attachmentMarshaller = xmlMarshaller.getAttachmentMarshaller();
attributePrefix = xmlMarshaller.getAttributePrefix();
fragment = xmlMarshaller.isFragment();
includeRoot = xmlMarshaller.isIncludeRoot();
marshalEmptyCollections = xmlMarshaller.isMarshalEmptyCollections();
mediaType = (MEDIA_TYPE) xmlMarshaller.mediaType;
namespaceSeparator = xmlMarshaller.getNamespaceSeparator();
noNamespaceSchemaLocation = xmlMarshaller.getNoNamespaceSchemaLocation();
reduceAnyArrays = xmlMarshaller.isReduceAnyArrays();
if(null != xmlMarshaller.getSchema()) {
setSchema(xmlMarshaller.getSchema());
}
schemaLocation = xmlMarshaller.getSchemaLocation();
valueWrapper = xmlMarshaller.getValueWrapper();
wrapperAsCollectionName = xmlMarshaller.isWrapperAsCollectionName();
xmlHeader = xmlMarshaller.getXmlHeader();
}
protected void addDescriptorNamespacesToXMLRecord(DESCRIPTOR xmlDescriptor, AbstractMarshalRecord record) {
if (null == xmlDescriptor) {
return;
}
copyNamespaces(xmlDescriptor.getNamespaceResolver(), record.getNamespaceResolver());
}
private XPathFragment buildRootFragment(Object object, DESCRIPTOR descriptor, boolean isXMLRoot, MarshalRecord marshalRecord) {
XPathFragment rootFragment = null;
if (isXMLRoot) {
String xmlRootUri = ((Root) object).getNamespaceURI();
String xmlRootLocalName = ((Root) object).getLocalName();
rootFragment = new XPathFragment();
rootFragment.setLocalName(xmlRootLocalName);
rootFragment.setNamespaceURI(xmlRootUri);
rootFragment.setNamespaceAware(marshalRecord.isNamespaceAware());
rootFragment.setNamespaceSeparator(marshalRecord.getNamespaceSeparator());
if (xmlRootUri != null) {
if (descriptor != null) {
String xmlRootPrefix = marshalRecord.getNamespaceResolver().resolveNamespaceURI(xmlRootUri);
if (xmlRootPrefix == null && !(xmlRootUri.equals(marshalRecord.getNamespaceResolver().getDefaultNamespaceURI()))) {
xmlRootPrefix = marshalRecord.getNamespaceResolver().generatePrefix();
marshalRecord.getNamespaceResolver().put(xmlRootPrefix, xmlRootUri);
}
if(xmlRootPrefix == null) {
rootFragment.setXPath(xmlRootLocalName);
} else {
rootFragment.setPrefix(xmlRootPrefix);
}
} else {
if(marshalRecord.isNamespaceAware()){
String xmlRootPrefix = "ns0";
marshalRecord.getNamespaceResolver().put(xmlRootPrefix, xmlRootUri);
rootFragment.setXPath(xmlRootPrefix + marshalRecord.getNamespaceSeparator() + xmlRootLocalName);
}else{
rootFragment.setXPath(xmlRootLocalName);
}
}
}
} else {
Field defaultRootField = descriptor.getDefaultRootElementField();
if(defaultRootField != null){
rootFragment = defaultRootField.getXPathFragment();
}
}
return rootFragment;
}
protected void copyNamespaces(NamespaceResolver source, NamespaceResolver target) {
if (null != source && null != target) {
if(source.hasPrefixesToNamespaces()) {
target.getPrefixesToNamespaces().putAll(source.getPrefixesToNamespaces());
}
target.setDefaultNamespaceURI(source.getDefaultNamespaceURI());
}
}
@Override
public XMLAttachmentMarshaller getAttachmentMarshaller() {
return this.attachmentMarshaller;
}
/**
* Value that will be used to prefix attributes.
* Ignored marshalling XML.
* @since 2.4
*/
public String getAttributePrefix() {
return attributePrefix;
}
/**
* INTERNAL:
* Return the descriptor for the root object.
*/
protected DESCRIPTOR getDescriptor(Class clazz, ABSTRACT_SESSION session) throws XMLMarshalException {
DESCRIPTOR descriptor = (DESCRIPTOR) session.getDescriptor(clazz);
if (descriptor == null) {
throw XMLMarshalException.descriptorNotFoundInProject(clazz.getName());
}
return descriptor;
}
/**
* INTERNAL:
* Return the descriptor for the root object.
*/
public DESCRIPTOR getDescriptor(Object object) throws XMLMarshalException {
DESCRIPTOR descriptor = (DESCRIPTOR) context.getSession(object).getDescriptor(object);
if (descriptor == null) {
throw XMLMarshalException.descriptorNotFoundInProject(object.getClass().getName());
}
return descriptor;
}
/**
* INTERNAL:
* Return the descriptor for the root object.
*/
protected DESCRIPTOR getDescriptor(Object object, ABSTRACT_SESSION session) throws XMLMarshalException {
DESCRIPTOR descriptor = (DESCRIPTOR) session.getDescriptor(object);
if (descriptor == null) {
throw XMLMarshalException.descriptorNotFoundInProject(object.getClass().getName());
}
return descriptor;
}
protected DESCRIPTOR getDescriptor(Object object, boolean isXMLRoot) {
if (isXMLRoot) {
return getDescriptor((Root) object);
} else {
return getDescriptor(object);
}
}
protected DESCRIPTOR getDescriptor(Root object) throws XMLMarshalException {
DESCRIPTOR descriptor = null;
try {
ABSTRACT_SESSION session = context.getSession(object.getObject());
if(null == session) {
return null;
}
descriptor = (DESCRIPTOR) session.getDescriptor(object.getObject());
} catch (XMLMarshalException marshalException) {
if ((descriptor == null) && isSimpleXMLRoot(object)) {
return null;
}
throw marshalException;
}
if (descriptor == null) {
throw XMLMarshalException.descriptorNotFoundInProject(object.getClass().getName());
}
return descriptor;
}
protected DESCRIPTOR getDescriptor(Root object, ABSTRACT_SESSION session) throws XMLMarshalException {
DESCRIPTOR descriptor = null;
try {
if(null == session) {
return null;
}
descriptor = (DESCRIPTOR) session.getDescriptor(object.getObject());
} catch (XMLMarshalException marshalException) {
if ((descriptor == null) && isSimpleXMLRoot(object)) {
return null;
}
throw marshalException;
}
if (descriptor == null) {
throw XMLMarshalException.descriptorNotFoundInProject(object.getClass().getName());
}
return descriptor;
}
protected Node getNode(Object object, Node parentNode, ABSTRACT_SESSION session, DESCRIPTOR descriptor, boolean isRoot) {
if(isRoot) {
object = ((Root) object).getObject();
if(object instanceof Node) {
return (Node) object;
}
}
return null;
}
/**
* Get the no namespace schema location set on this XMLMarshaller
* @return the no namespace schema location specified on this XMLMarshaller
*/
public String getNoNamespaceSchemaLocation() {
return noNamespaceSchemaLocation;
}
public Schema getSchema() {
return schema;
}
/**
* INTERNAL
* @return the transformer instance for this marshaller
*/
@Override
public XMLTransformer getTransformer() {
if(null == transformer) {
XMLPlatform xmlPlatform = XMLPlatformFactory.getInstance().getXMLPlatform();
transformer = xmlPlatform.newXMLTransformer();
transformer.setEncoding(getEncoding());
transformer.setFormattedOutput(isFormattedOutput());
transformer.setFragment(fragment);
}
return transformer;
}
/**
* Name of the property to marshal/unmarshal as a wrapper on the text() mappings
* Ignored marshalling XML.
* @since 2.4
*/
public String getValueWrapper() {
return valueWrapper;
}
/**
* Get this Marshaller's XML Header.
* @since 2.4
*/
public String getXmlHeader() {
return xmlHeader;
}
/**
* Get the schema location set on this XMLMarshaller
* @return the schema location specified on this XMLMarshaller
*/
public String getSchemaLocation() {
return schemaLocation;
}
/**
* INTERNAL
* @return true if the media type is application/json, else false.
* @since EclipseLink 2.6.0
*/
@Override
public boolean isApplicationJSON() {
return null != mediaType && mediaType.isApplicationJSON();
}
/**
* INTERNAL
* @return true if the media type is application/xml, else false.
* @since EclipseLink 2.6.0
*/
@Override
public boolean isApplicationXML() {
return null == mediaType || mediaType.isApplicationXML();
}
/**
* PUBLIC:
* Returns if this should marshal to a fragment. If true an XML header string is not written out.
* @return if this should marshal to a fragment or not
*/
public boolean isFragment() {
return isApplicationXML() && fragment;
}
/**
* Determine if the @XMLRootElement should be marshalled when present.
* Ignored marshalling XML.
* @since 2.4
*/
@Override
public boolean isIncludeRoot() {
if(isApplicationJSON()){
return includeRoot;
}
return true;
}
/**
* Property to determine if size 1 any collections should be treated as collections
* Ignored marshalling XML.
*/
@Override
public boolean isReduceAnyArrays() {
return reduceAnyArrays;
}
/**
* Get the namespace separator used during marshal operations.
* If mediaType is application/json '.' is the default
* Ignored marshalling XML.
* @since 2.4
*/
public char getNamespaceSeparator() {
return namespaceSeparator;
}
/**
* Name of the property to determine if empty collections should be marshalled as []
* Ignored marshalling XML.
* @since 2.4
*/
public boolean isMarshalEmptyCollections() {
return marshalEmptyCollections;
}
@Override
public boolean isWrapperAsCollectionName() {
return wrapperAsCollectionName;
}
protected boolean isSimpleXMLRoot(Root xmlRoot) {
Class xmlRootObjectClass = xmlRoot.getObject().getClass();
ConversionManager conversionManager = (ConversionManager) context.getSession().getDatasourcePlatform().getConversionManager();
if (conversionManager.schemaType(xmlRootObjectClass) != null || CoreClassConstants.List_Class.isAssignableFrom(xmlRootObjectClass) || CoreClassConstants.XML_GREGORIAN_CALENDAR.isAssignableFrom(xmlRootObjectClass) || CoreClassConstants.DURATION.isAssignableFrom(xmlRootObjectClass)) {
return true;
} else if(xmlRoot.getObject() instanceof org.w3c.dom.Node) {
return true;
}
return false;
}
/**
* PUBLIC:
* Convert the given object to XML and update the given contentHandler with that XML Document
* @param object the object to marshal
* @param contentHandler the contentHandler which the specified object should be marshalled to
* @throws XMLMarshalException if an error occurred during marshalling
*/
public void marshal(Object object, ContentHandler contentHandler) throws XMLMarshalException {
if (contentHandler instanceof LexicalHandler) {
marshal(object, contentHandler, (LexicalHandler)contentHandler);
} else {
marshal(object, contentHandler, null);
}
}
/**
* PUBLIC:
* Convert the given object to XML and update the given contentHandler with that XML Document
* @param object the object to marshal
* @param contentHandler the contentHandler which the specified object should be marshalled to
* @throws XMLMarshalException if an error occurred during marshalling
*/
public void marshal(Object object, ContentHandler contentHandler, LexicalHandler lexicalHandler) throws XMLMarshalException {
if(object instanceof JSONWithPadding && !isApplicationJSON()){
object = ((JSONWithPadding)object).getObject();
}
if ((object == null) || (contentHandler == null)) {
throw XMLMarshalException.nullArgumentException();
}
ABSTRACT_SESSION session = null;
DESCRIPTOR xmlDescriptor = null;
boolean isXMLRoot = (object instanceof Root);
if(isXMLRoot){
try{
session = context.getSession(((Root)object).getObject());
if(session != null){
xmlDescriptor = getDescriptor(((Root)object).getObject(), session);
}
}catch (XMLMarshalException marshalException) {
if (!isSimpleXMLRoot((Root) object)) {
throw marshalException;
}
}
}else{
Class objectClass = object.getClass();
session = context.getSession(objectClass);
xmlDescriptor = getDescriptor(objectClass, session);
}
ContentHandlerRecord contentHandlerRecord = new ContentHandlerRecord();
contentHandlerRecord.setMarshaller(this);
contentHandlerRecord.setContentHandler(contentHandler);
contentHandlerRecord.setLexicalHandler(lexicalHandler);
marshal(object, contentHandlerRecord, session, xmlDescriptor,isXMLRoot);
}
/**
* Convert the given object to XML and update the given marshal record with
* that XML Document.
* @param object the object to marshal
* @param marshalRecord the marshalRecord to marshal the object to
*/
public void marshal(Object object, MarshalRecord marshalRecord) {
if(object instanceof JSONWithPadding && !isApplicationJSON()){
object = ((JSONWithPadding)object).getObject();
}
if ((object == null) || (marshalRecord == null)) {
throw XMLMarshalException.nullArgumentException();
}
boolean isXMLRoot = (object instanceof Root);
ABSTRACT_SESSION session = null;
DESCRIPTOR xmlDescriptor = null;
if(isXMLRoot){
try{
session = context.getSession(((Root)object).getObject());
if(session != null){
xmlDescriptor = getDescriptor(((Root)object).getObject(), session);
}
}catch (XMLMarshalException marshalException) {
if (!isSimpleXMLRoot((Root) object)) {
throw marshalException;
}
}
}else{
Class objectClass = object.getClass();
session = context.getSession(objectClass);
xmlDescriptor = getDescriptor(objectClass, session);
}
marshal(object, marshalRecord, session, xmlDescriptor, isXMLRoot);
}
/**
* Convert the given object to XML and update the given marshal record with
* that XML Document.
* @param object the object to marshal
* @param marshalRecord the marshalRecord to marshal the object to
* @param descriptor the XMLDescriptor for the object being marshalled
*/
protected void marshal(Object object, MarshalRecord marshalRecord, ABSTRACT_SESSION session, DESCRIPTOR descriptor, boolean isXMLRoot) {
SessionLog logger = AbstractSessionLog.getLog();
if (logger.shouldLog(SessionLog.FINE, SessionLog.MOXY)) {
logger.log(SessionLog.FINE, SessionLog.MOXY, "moxy_start_marshalling", new Object[] { (object!= null)?object.getClass().getName():"N/A", this.mediaType});
}
if (object != null && logPayload != null && this.isLogPayload()) {
AbstractSessionLog.getLog().log(SessionLog.FINEST, SessionLog.MOXY, object.toString(), new Object[0], false);
}
if(null != schema) {
marshalRecord = new ValidatingMarshalRecord(marshalRecord, this);
}
if (this.attachmentMarshaller != null) {
marshalRecord.setXOPPackage(this.attachmentMarshaller.isXOPPackage());
}
marshalRecord.setMarshaller(this);
Root root = null;
if(isXMLRoot) {
root = (Root) object;
}
Node node = getNode(object, marshalRecord.getDOM(), session, descriptor, isXMLRoot);
if(this.mapper == null) {
if(null == node) {
addDescriptorNamespacesToXMLRecord(descriptor, marshalRecord);
}
} else {
if(descriptor == null || null != node){
marshalRecord.setNamespaceResolver(new PrefixMapperNamespaceResolver(mapper, null));
}else{
marshalRecord.setNamespaceResolver(new PrefixMapperNamespaceResolver(mapper, descriptor.getNamespaceResolver()));
}
marshalRecord.setCustomNamespaceMapper(true);
}
if(this.getMarshalAttributeGroup() != null) {
if(marshalAttributeGroup.getClass() == CoreClassConstants.STRING) {
CoreAttributeGroup group = descriptor.getAttributeGroup((String)marshalAttributeGroup);
if(group != null) {
marshalRecord.pushAttributeGroup(group);
} else {
throw XMLMarshalException.invalidAttributeGroupName((String)marshalAttributeGroup, descriptor.getJavaClassName());
}
} else if(marshalAttributeGroup instanceof CoreAttributeGroup) {
marshalRecord.pushAttributeGroup((CoreAttributeGroup)marshalAttributeGroup);
} else {
//Error case
}
}
NamespaceResolver nr = marshalRecord.getNamespaceResolver();
if(node != null) {
if(isXMLRoot) {
if (isFragment()) {
marshalRecord.node(node, null, root.getNamespaceURI(), root.getLocalName());
} else {
String encoding = root.getEncoding();
if(null == encoding) {
encoding = Constants.DEFAULT_XML_ENCODING;
}
String version = root.getXMLVersion();
if(null == version) {
version = DEFAULT_XML_VERSION;
}
marshalRecord.startDocument(encoding, version);
marshalRecord.node(node, marshalRecord.getNamespaceResolver(), root.getNamespaceURI(), root.getLocalName());
marshalRecord.endDocument();
}
} else {
marshalRecord.node(node, nr);
}
marshalRecord.flush();
return;
}
if(isXMLRoot){
if(descriptor != null){
marshalRecord.beforeContainmentMarshal(root.getObject());
}
}else{
marshalRecord.beforeContainmentMarshal(object);
}
if (!isFragment()) {
String encoding = getEncoding();
String version = DEFAULT_XML_VERSION;
if (!isXMLRoot && descriptor!= null) {
marshalRecord.setLeafElementType(descriptor.getDefaultRootElementType());
} else {
if (root.getEncoding() != null) {
encoding = root.getEncoding();
}
if (root.getXMLVersion() != null) {
version = root.getXMLVersion();
}
}
marshalRecord.startDocument(encoding, version);
}
if (getXmlHeader() != null) {
marshalRecord.writeHeader();
}
if(isXMLRoot) {
if(root.getObject() instanceof Node) {
marshalRecord.node((Node)root.getObject(), new NamespaceResolver(), root.getNamespaceURI(), root.getLocalName());
marshalRecord.endDocument();
return;
}
}
XPathFragment rootFragment = buildRootFragment(object, descriptor, isXMLRoot, marshalRecord);
String schemaLocation = getSchemaLocation();
String noNsSchemaLocation = getNoNamespaceSchemaLocation();
boolean isNil = false;
if (isXMLRoot) {
object = root.getObject();
if (root.getSchemaLocation() != null) {
schemaLocation = root.getSchemaLocation();
}
if (root.getNoNamespaceSchemaLocation() != null) {
noNsSchemaLocation = root.getNoNamespaceSchemaLocation();
}
marshalRecord.setLeafElementType(root.getSchemaType());
isNil = root.isNil();
}
String xsiPrefix = null;
if ((null != getSchemaLocation()) || (null != getNoNamespaceSchemaLocation()) || (isNil)) {
xsiPrefix = nr.resolveNamespaceURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
if (null == xsiPrefix) {
xsiPrefix = Constants.SCHEMA_INSTANCE_PREFIX;
nr.put(Constants.SCHEMA_INSTANCE_PREFIX, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
}
}
OBJECT_BUILDER treeObjectBuilder = null;
if (descriptor != null) {
treeObjectBuilder = (OBJECT_BUILDER) descriptor.getObjectBuilder();
}
if(session == null){
session = (ABSTRACT_SESSION) context.getSession();
}
marshalRecord.setSession(session);
if (null != rootFragment && !(rootFragment.getLocalName().equals(Constants.EMPTY_STRING))) {
marshalRecord.startPrefixMappings(nr);
if (!isXMLRoot && descriptor != null && descriptor.getNamespaceResolver() == null && rootFragment.hasNamespace()) {
// throw an exception if the name has a : in it but the namespaceresolver is null
throw XMLMarshalException.namespaceResolverNotSpecified(rootFragment.getShortName());
}
if(isIncludeRoot()){
marshalRecord.openStartElement(rootFragment, nr);
}
if (null != schemaLocation) {
marshalRecord.attributeWithoutQName(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_LOCATION, xsiPrefix, schemaLocation);
}
if (null != noNsSchemaLocation) {
marshalRecord.attributeWithoutQName(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.NO_NS_SCHEMA_LOCATION, xsiPrefix, noNsSchemaLocation);
}
if (isNil) {
marshalRecord.nilSimple(nr);
}
marshalRecord.namespaceDeclarations(nr);
if (descriptor != null && !isNil) {
marshalRecord.addXsiTypeAndClassIndicatorIfRequired(descriptor, null, descriptor.getDefaultRootElementField(), root, object, isXMLRoot, true);
treeObjectBuilder.marshalAttributes(marshalRecord, object, session);
}
if(isIncludeRoot()) {
marshalRecord.closeStartElement();
}
}else{
//no rootfragment
marshalRecord.marshalWithoutRootElement(treeObjectBuilder,object, descriptor, root, isXMLRoot);
}
if (treeObjectBuilder != null && !isNil) {
treeObjectBuilder.buildRow(marshalRecord, object, session, this, rootFragment);
} else if (isXMLRoot) {
if(object != null && !isNil) {
if(root.getDeclaredType() != null && root.getObject() != null && root.getDeclaredType() != root.getObject().getClass()) {
QName type = marshalRecord.getConversionManager().schemaType(object.getClass());
if(type != null) {
xsiPrefix = nr.resolveNamespaceURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
if (null == xsiPrefix) {
xsiPrefix = Constants.SCHEMA_INSTANCE_PREFIX;
marshalRecord.namespaceDeclaration(xsiPrefix, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
}
marshalRecord.namespaceDeclaration(Constants.SCHEMA_PREFIX, javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
String typeValue = type.getLocalPart();
if(marshalRecord.isNamespaceAware() && (mediaType.isApplicationXML() || getJsonTypeConfiguration().useXsdTypesWithPrefix())){
typeValue = Constants.SCHEMA_PREFIX + marshalRecord.getNamespaceSeparator() + typeValue;
}
marshalRecord.attribute(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_TYPE_ATTRIBUTE, xsiPrefix + Constants.COLON + Constants.SCHEMA_TYPE_ATTRIBUTE, typeValue);
}
}
marshalRecord.characters(root.getSchemaType(), object, null, false);
}
}
if (null != rootFragment && !(rootFragment.getLocalName().equals(Constants.EMPTY_STRING)) && isIncludeRoot()) {
marshalRecord.endElement(rootFragment, nr);
marshalRecord.endPrefixMappings(nr);
}
if (!isFragment() ) {
marshalRecord.endDocument();
}
if(isXMLRoot){
if(descriptor != null){
marshalRecord.afterContainmentMarshal(null, root.getObject());
}
}else{
marshalRecord.afterContainmentMarshal(null, object);
}
marshalRecord.flush();
}
/**
* PUBLIC:
* @param object the object to marshal
* @param node the node which the specified object should be marshalled to
* @throws XMLMarshalException if an error occurred during marshalling
*/
public void marshal(Object object, Node node) throws XMLMarshalException {
if(object instanceof JSONWithPadding && !isApplicationJSON()){
object = ((JSONWithPadding)object).getObject();
}
if ((object == null) || (node == null)) {
throw XMLMarshalException.nullArgumentException();
}
ABSTRACT_SESSION session = null;
DESCRIPTOR xmlDescriptor = null;
boolean isXMLRoot = (object instanceof Root);
if(isXMLRoot){
try{
session = context.getSession(((Root)object).getObject());
if(session != null){
xmlDescriptor = getDescriptor(((Root)object).getObject(), session);
}
}catch (XMLMarshalException marshalException) {
if (!isSimpleXMLRoot((Root) object)) {
throw marshalException;
}
}
}else{
Class objectClass = object.getClass();
session = context.getSession(objectClass);
xmlDescriptor = getDescriptor(objectClass, session);
}
NodeRecord contentHandlerRecord = new NodeRecord(node);
contentHandlerRecord.setMarshaller(this);
if (!isXMLRoot) {
if ((null == xmlDescriptor.getDefaultRootElement()) && (node.getNodeType() == Node.ELEMENT_NODE) && (xmlDescriptor.getSchemaReference() != null) && (xmlDescriptor.getSchemaReference().getType() == XMLSchemaReference.COMPLEX_TYPE)) {
Attr typeAttr = ((Element) node).getAttributeNodeNS(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, Constants.SCHEMA_TYPE_ATTRIBUTE);
if (typeAttr == null) {
NamespaceResolver namespaceResolver = xmlDescriptor.getNonNullNamespaceResolver();
String xsiPrefix = namespaceResolver.resolveNamespaceURI(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
if (null == xsiPrefix) {
xsiPrefix = namespaceResolver.generatePrefix(Constants.SCHEMA_INSTANCE_PREFIX);
}
String value = xmlDescriptor.getSchemaReference().getSchemaContext();
((Element) node).setAttributeNS(javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI, javax.xml.XMLConstants.XMLNS_ATTRIBUTE + Constants.COLON + xsiPrefix, javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI);
((Element) node).setAttributeNS(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, xsiPrefix + Constants.COLON + Constants.SCHEMA_TYPE_ATTRIBUTE, value);
} else {
String value = xmlDescriptor.getSchemaReference().getSchemaContext();
typeAttr.setValue(value);
}
}
}
marshal(object, contentHandlerRecord, session, xmlDescriptor,isXMLRoot);
}
/**
* PUBLIC:
* Convert the given object to XML and update the given outputStream with that XML Document
* @param object the object to marshal
* @param outputStream the outputStream to marshal the object to
* @throws XMLMarshalException if an error occurred during marshalling
*/
public void marshal(Object object, OutputStream outputStream) throws XMLMarshalException {
marshal (object, outputStream, null, null);
}
private void marshal(Object object, OutputStream outputStream, ABSTRACT_SESSION session, DESCRIPTOR xmlDescriptor) throws XMLMarshalException {
if ((object == null) || (outputStream == null)) {
throw XMLMarshalException.nullArgumentException();
}
boolean isXMLRoot = false;
String version = DEFAULT_XML_VERSION;
String encoding = getEncoding();
String callbackName = null;
if(object instanceof JSONWithPadding){
callbackName = ((JSONWithPadding)object).getCallbackName();
object = ((JSONWithPadding)object).getObject();
if(object == null){
throw XMLMarshalException.nullArgumentException();
}
}
if (object instanceof Root) {
isXMLRoot = true;
Root xroot = (Root) object;
encoding = xroot.getEncoding() != null ? xroot.getEncoding() : encoding;
}
if(!encoding.equals(Constants.DEFAULT_XML_ENCODING)) {
try {
OutputStreamWriter writer = new OutputStreamWriter(outputStream, encoding);
marshal(object, writer, session, xmlDescriptor);
writer.flush();
} catch(EclipseLinkException e) {
throw e;
} catch(Exception e) {
throw XMLMarshalException.marshalException(e);
}
return;
}
MarshalRecord marshalRecord;
if (isFormattedOutput()) {
if(isApplicationJSON()) {
marshalRecord = new JSONFormattedWriterRecord(outputStream, callbackName);
} else {
marshalRecord = new FormattedOutputStreamRecord();
((FormattedOutputStreamRecord)marshalRecord).setOutputStream(outputStream);
}
} else {
if(isApplicationJSON()) {
marshalRecord = new JSONWriterRecord(outputStream, callbackName);
} else {
marshalRecord = new OutputStreamRecord();
((OutputStreamRecord)marshalRecord).setOutputStream(outputStream);
}
}
marshalStreamOrWriter(object, marshalRecord, session, xmlDescriptor, isXMLRoot);
}
/**
* PUBLIC:
* Convert the given object to XML and update the given result with that XML Document
* @param object the object to marshal
* @param result the result to marshal the object to
* @throws XMLMarshalException if an error occurred during marshalling
*/
public void marshal(Object object, Result result) throws XMLMarshalException {
if ((object == null) || (result == null)) {
throw XMLMarshalException.nullArgumentException();
}
DESCRIPTOR xmlDescriptor = null;
ABSTRACT_SESSION session = null;
boolean isXMLRoot = (object instanceof Root);
if(isXMLRoot){
try{
session = context.getSession(((Root)object).getObject());
if(session != null){
xmlDescriptor = getDescriptor(((Root)object).getObject(), session);
}
}catch (XMLMarshalException marshalException) {
if (!isSimpleXMLRoot((Root) object)) {
throw marshalException;
}
}
}else{
Class objectClass = object.getClass();
session = context.getSession(objectClass);
xmlDescriptor = getDescriptor(objectClass, session);
}
//if this is a simple xml root, the session and descriptor will be null
if (result instanceof StreamResult) {
StreamResult streamResult = (StreamResult) result;
Writer writer = streamResult.getWriter();
if (writer != null) {
marshal(object, writer, session, xmlDescriptor);
} else if (streamResult.getOutputStream() != null) {
marshal(object, streamResult.getOutputStream(), session, xmlDescriptor);
} else {
try {
File f;
try {
f = new File(new URL(streamResult.getSystemId()).toURI());
} catch(MalformedURLException malformedURLException) {
try {
f = new File(streamResult.getSystemId());
} catch(Exception e) {
throw malformedURLException;
}
}
writer = new FileWriter(f);
try {
marshal(object, writer, session, xmlDescriptor);
} finally {
writer.close();
}
} catch (Exception e) {
throw XMLMarshalException.marshalException(e);
}
}
}else if (result instanceof DOMResult) {
DOMResult domResult = (DOMResult) result;
// handle case where the node is null
if (domResult.getNode() == null) {
domResult.setNode(this.objectToXML(object));
} else {
marshal(object, domResult.getNode());
}
} else if (result instanceof SAXResult) {
SAXResult saxResult = (SAXResult) result;
marshal(object, saxResult.getHandler());
} else if (result instanceof ExtendedResult){
marshal(object, ((ExtendedResult)result).createRecord(), session, xmlDescriptor, isXMLRoot);
}else {
if (result.getClass().equals(staxResultClass)) {
try {
Object xmlStreamWriter = PrivilegedAccessHelper.invokeMethod(staxResultGetStreamWriterMethod, result);
if (xmlStreamWriter != null) {
MarshalRecord record = (MarshalRecord)PrivilegedAccessHelper.invokeConstructor(xmlStreamWriterRecordConstructor, new Object[]{xmlStreamWriter});
record.setMarshaller(this);
marshal(object, record, session, xmlDescriptor, isXMLRoot);
return;
} else {
Object xmlEventWriter = PrivilegedAccessHelper.invokeMethod(staxResultGetEventWriterMethod, result);
if(xmlEventWriter != null) {
MarshalRecord record = (MarshalRecord)PrivilegedAccessHelper.invokeConstructor(xmlEventWriterRecordConstructor, new Object[]{xmlEventWriter});
record.setMarshaller(this);
marshal(object, record, session, xmlDescriptor, isXMLRoot);
return;
}
}
} catch(EclipseLinkException e) {
throw e;
} catch (Exception e) {
throw XMLMarshalException.marshalException(e);
}
}
java.io.StringWriter writer = new java.io.StringWriter();
marshal(object, writer);
javax.xml.transform.stream.StreamSource source = new javax.xml.transform.stream.StreamSource(new java.io.StringReader(writer.toString()));
getTransformer().transform(source, result);
}
return;
}
/**
* PUBLIC:
* Convert the given object to XML and update the given writer with that XML Document
* @param object the object to marshal
* @param writer the writer to marshal the object to
* @throws XMLMarshalException if an error occurred during marshalling
*/
public void marshal(Object object, Writer writer) throws XMLMarshalException {
marshal(object, writer, null, null);
}
private void marshal(Object object, Writer writer, ABSTRACT_SESSION session, DESCRIPTOR xmlDescriptor) throws XMLMarshalException {
if ((object == null) || (writer == null)) {
throw XMLMarshalException.nullArgumentException();
}
boolean isXMLRoot = false;
String version = DEFAULT_XML_VERSION;
String encoding = getEncoding();
String callbackName = null;
if(object instanceof JSONWithPadding){
callbackName = ((JSONWithPadding)object).getCallbackName();
object = ((JSONWithPadding)object).getObject();
if(object == null){
throw XMLMarshalException.nullArgumentException();
}
}
if (object instanceof Root) {
isXMLRoot = true;
Root xroot = (Root) object;
version = xroot.getXMLVersion() != null ? xroot.getXMLVersion() : version;
encoding = xroot.getEncoding() != null ? xroot.getEncoding() : encoding;
}
MarshalRecord marshalRecord;
writer = wrapWriter(writer);
if (isFormattedOutput()) {
if(isApplicationJSON()) {
marshalRecord = new JSONFormattedWriterRecord(writer, callbackName);
} else {
marshalRecord = new FormattedWriterRecord();
((FormattedWriterRecord) marshalRecord).setWriter(writer);
}
} else {
if(isApplicationJSON()) {
marshalRecord = new JSONWriterRecord(writer, callbackName);
} else {
marshalRecord = new WriterRecord();
((WriterRecord) marshalRecord).setWriter(writer);
}
}
marshalStreamOrWriter(object, marshalRecord, session, xmlDescriptor, isXMLRoot);
}
private void marshalStreamOrWriter(Object object, MarshalRecord marshalRecord, ABSTRACT_SESSION session, DESCRIPTOR descriptor, boolean isXMLRoot) {
marshalRecord.setMarshaller(this);
if(isXMLRoot){
if(session == null || descriptor == null){
try{
session = context.getSession(((Root)object).getObject());
if(session != null){
descriptor = getDescriptor(((Root)object).getObject(), session);
} else if (descriptor == null) {
descriptor = context.getDescriptor(new QName(((Root)object).getNamespaceURI(),((Root)object).getLocalName()));
}
}catch (XMLMarshalException marshalException) {
if (!isSimpleXMLRoot((Root) object)) {
throw marshalException;
}
}
}
}else{
Class objectClass = object.getClass();
if(object instanceof Collection) {
int valueSize = ((Collection)object).size();
if(marshalRecord.getMarshaller().isApplicationJSON() && (valueSize > 1 || !marshalRecord.getMarshaller().isReduceAnyArrays())) {
marshalRecord.startCollection();
}
String valueWrapper;
for(Object o : (Collection) object) {
if (o == null) {
valueWrapper = this.getValueWrapper();
if (isApplicationJSON()) {
this.setValueWrapper("");
marshalRecord.setMarshaller(this);
}
marshalRecord.nilSimple(null);
this.setValueWrapper(valueWrapper);
} else {
if (isApplicationJSON() && o != null && (o.getClass() == CoreClassConstants.STRING || o.getClass() == CoreClassConstants.BOOLEAN || CoreClassConstants.NUMBER.isAssignableFrom(o.getClass()))) {
if (marshalRecord.getSession() == null) {
marshalRecord.setSession((ABSTRACT_SESSION) this.getContext().getSession());
}
valueWrapper = this.getValueWrapper();
this.setValueWrapper("");
marshalRecord.setMarshaller(this);
marshalRecord.characters(null, o, null, false);
this.setValueWrapper(valueWrapper);
} else {
marshal(o, marshalRecord);
}
}
}
if(marshalRecord.getMarshaller().isApplicationJSON() && (valueSize > 1 || !marshalRecord.getMarshaller().isReduceAnyArrays())) {
marshalRecord.endCollection();
}
marshalRecord.flush();
return;
} else if(objectClass.isArray()) {
int arrayLength = Array.getLength(object);
if(marshalRecord.getMarshaller().isApplicationJSON() && (arrayLength > 1 || !marshalRecord.getMarshaller().isReduceAnyArrays())) {
marshalRecord.startCollection();
}
for(int x=0; x<arrayLength; x++) {
marshal(Array.get(object, x), marshalRecord);
}
if(marshalRecord.getMarshaller().isApplicationJSON() && (arrayLength > 1 || !marshalRecord.getMarshaller().isReduceAnyArrays())) {
marshalRecord.endCollection();
}
marshalRecord.flush();
return;
}
if(session == null || descriptor == null){
session = context.getSession(objectClass);
descriptor = getDescriptor(objectClass, session);
}
}
marshal(object, marshalRecord, session, descriptor, isXMLRoot);
marshalRecord.flush();
}
/**
* INTERNAL:
* Wrap Writer in a BufferedWriter only if its write() operations may be costly
* (such as FileWriters and OutputStreamWriters).
*/
private Writer wrapWriter(Writer writer) {
if (writer instanceof OutputStreamWriter || writer instanceof FileWriter) {
return new BufferedWriter(writer);
}
return writer;
}
/**
* PUBLIC:
* Convert the given object to an XML Document
* @param object the object to marshal
* @return the document which the specified object has been marshalled to
* @throws XMLMarshalException if an error occurred during marshalling
*/
public Document objectToXML(Object object) throws XMLMarshalException {
boolean isXMLRoot = (object instanceof Root);
DESCRIPTOR xmlDescriptor = getDescriptor(object, isXMLRoot);
return objectToXML(object, xmlDescriptor, isXMLRoot);
}
/**
* INTERNAL:
* Convert the given object to an XML Document
* @param object the object to marshal
* @return the document which the specified object has been marshalled to
* @param descriptor the XMLDescriptor for the object being marshalled
* @throws XMLMarshalException if an error occurred during marshalling
*/
protected Document objectToXML(Object object, DESCRIPTOR descriptor, boolean isXMLRoot) throws XMLMarshalException {
ABSTRACT_SESSION session = context.getSession(descriptor);
MarshalRecord marshalRecord = new NodeRecord();
marshalRecord.setMarshaller(this);
marshal(object, marshalRecord, session, descriptor, isXMLRoot);
return marshalRecord.getDocument();
}
/**
* INTERNAL:
* Like ObjectToXML but is may also return a document fragment instead of a document in the
* case of a non-root object.
*/
protected Node objectToXMLNode(Object object, ABSTRACT_SESSION session, DESCRIPTOR descriptor, boolean isXMLRoot) throws XMLMarshalException {
return objectToXMLNode(object, null, session, descriptor, isXMLRoot);
}
protected Node objectToXMLNode(Object object, Node rootNode, ABSTRACT_SESSION session, DESCRIPTOR descriptor, boolean isXMLRoot) throws XMLMarshalException {
MarshalRecord marshalRecord = new NodeRecord();
marshalRecord.setMarshaller(this);
marshalRecord.getNamespaceResolver().setDOM(rootNode);
marshal(object, marshalRecord, session, descriptor, isXMLRoot);
return marshalRecord.getDocument();
}
public void setAttachmentMarshaller(XMLAttachmentMarshaller atm) {
this.attachmentMarshaller = atm;
}
/**
* Value that will be used to prefix attributes.
* Ignored marshalling XML.
* @since 2.4
*/
public void setAttributePrefix(String attributePrefix) {
this.attributePrefix = attributePrefix;
}
/**
* Set the encoding on this XMLMarshaller
* If the encoding is not set the default UTF-8 will be used
* @param newEncoding the encoding to set on this XMLMarshaller
*/
@Override
public void setEncoding(String newEncoding) {
super.setEncoding(newEncoding);
if(null != transformer) {
transformer.setEncoding(newEncoding);
}
}
/**
* Set if this XMLMarshaller should format the XML
* By default this is set to true and the XML marshalled will be formatted.
* @param shouldFormat if this XMLMarshaller should format the XML
*/
@Override
public void setFormattedOutput(boolean shouldFormat) {
super.setFormattedOutput(shouldFormat);
if(null != transformer) {
transformer.setFormattedOutput(shouldFormat);
}
}
/**
* PUBLIC:
* Set if this should marshal to a fragment. If true an XML header string is not written out.
* @param fragment if this should marshal to a fragment or not
*/
public void setFragment(boolean fragment) {
this.fragment = fragment;
if(null != transformer) {
transformer.setFragment(fragment);
}
}
/**
* Determine if the {@code @XMLRootElement} should be marshalled when present.
* Ignored marshalling XML.
* @since 2.4
*/
public void setIncludeRoot(boolean includeRoot) {
this.includeRoot = includeRoot;
}
/**
* Name of the property to determine if empty collections should be marshalled as []
* Ignored marshalling XML.
* @since 2.4
*/
public void setMarshalEmptyCollections(Boolean marshalEmptyCollections) {
this.marshalEmptyCollections = marshalEmptyCollections;
}
/**
* Set the MediaType for this xmlMarshaller.
* See org.eclipse.persistence.oxm.MediaType for the media types supported by EclipseLink MOXy
*/
public void setMediaType(MEDIA_TYPE mediaType) {
this.mediaType = mediaType;
}
/**
* Set the namespace separator used during marshal operations.
* If mediaType is application/json '.' is the default
* Ignored marshalling XML.
* @since 2.4
*/
public void setNamespaceSeparator(char namespaceSeparator) {
this.namespaceSeparator = namespaceSeparator;
}
/**
* Set the no namespace schema location on this XMLMarshaller
* @param newNoNamespaceSchemaLocation no namespace schema location to be seton this XMLMarshaller
*/
public void setNoNamespaceSchemaLocation(String newNoNamespaceSchemaLocation) {
noNamespaceSchemaLocation = newNoNamespaceSchemaLocation;
}
/**
* Property to determine if size 1 any collections should be treated as collections
* Ignored marshalling XML.
*/
public void setReduceAnyArrays(boolean reduceAnyArrays) {
this.reduceAnyArrays = reduceAnyArrays;
}
public void setSchema(Schema schema) {
this.schema = schema;
}
/**
* Set the schema location on this XMLMarshaller
* @param newSchemaLocation the schema location to be seton this XMLMarshaller
*/
public void setSchemaLocation(String newSchemaLocation) {
schemaLocation = newSchemaLocation;
}
public void setWrapperAsCollectionName(boolean wrapperAsCollectionName) {
this.wrapperAsCollectionName = wrapperAsCollectionName;
}
/**
* Name of the property to marshal/unmarshal as a wrapper on the text() mappings
* Ignored marshalling XML.
* @since 2.4
*/
public void setValueWrapper(String valueWrapper) {
this.valueWrapper = valueWrapper;
}
/**
* <p>
* Set this Marshaller's XML Header. This header string will appear after
* the XML processing instruction (&lt;?xml ...&gt;), but before the start
* of the document's data.
* </p>
*
* <p>
* This feature is only supported when marshalling to Stream, Writer,
* or StreamResult.
* </p>
* @since 2.4
*/
public void setXmlHeader(String xmlHeader) {
this.xmlHeader = xmlHeader;
}
public void setMarshalAttributeGroup(Object group) {
this.marshalAttributeGroup = group;
}
public Object getMarshalAttributeGroup() {
return this.marshalAttributeGroup;
}
public Boolean isLogPayload() {
return logPayload;
}
public void setLogPayload(Boolean logPayload) {
this.logPayload = logPayload;
}
}