org.eclipse.persistence.sdo.helper.delegates.SDOXMLHelperDelegate Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* Copyright (c) 1998, 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:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.sdo.helper.delegates;
import commonj.sdo.DataObject;
import commonj.sdo.Property;
import commonj.sdo.helper.HelperContext;
import commonj.sdo.helper.XMLDocument;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.WeakHashMap;
import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.eclipse.persistence.sdo.SDOConstants;
import org.eclipse.persistence.sdo.SDOType;
import org.eclipse.persistence.sdo.SDOXMLDocument;
import org.eclipse.persistence.sdo.helper.SDOUnmappedContentHandler;
import org.eclipse.persistence.sdo.helper.SDOClassLoader;
import org.eclipse.persistence.sdo.helper.SDOMarshalListener;
import org.eclipse.persistence.sdo.helper.SDOTypeHelper;
import org.eclipse.persistence.sdo.helper.SDOUnmarshalListener;
import org.eclipse.persistence.sdo.helper.SDOXMLHelper;
import org.eclipse.persistence.sdo.types.SDOPropertyType;
import org.eclipse.persistence.sdo.types.SDOTypeType;
import org.eclipse.persistence.exceptions.SDOException;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLLogin;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.oxm.attachment.XMLAttachmentMarshaller;
import org.eclipse.persistence.oxm.attachment.XMLAttachmentUnmarshaller;
import org.eclipse.persistence.oxm.record.ContentHandlerRecord;
import org.eclipse.persistence.oxm.record.FormattedWriterRecord;
import org.eclipse.persistence.oxm.record.NodeRecord;
import org.eclipse.persistence.oxm.record.WriterRecord;
import org.eclipse.persistence.sessions.Project;
import org.xml.sax.InputSource;
/**
* Purpose: Helper to XML documents into DataObects and DataObjects into XML documents.
*
Responsibilities:
* - Load methods create commonj.sdo.XMLDocument objects from XML (unmarshal)
*
- Save methods create XML from commonj.sdo.XMLDocument and commonj.sdo.DataObject objects (marshal)
*
*/
public class SDOXMLHelperDelegate implements SDOXMLHelper {
private SDOClassLoader loader;
private XMLContext xmlContext;
private Map xmlMarshallerMap;
private Map xmlUnmarshallerMap;
private Project topLinkProject;
// hold the context containing all helpers so that we can preserve inter-helper relationships
private HelperContext aHelperContext;
public SDOXMLHelperDelegate(HelperContext aContext) {
this(aContext, Thread.currentThread().getContextClassLoader());
}
public SDOXMLHelperDelegate(HelperContext aContext, ClassLoader aClassLoader) {
aHelperContext = aContext;
// This ClassLoader is internal to SDO so no inter servlet-ejb container context issues should arise
loader = new SDOClassLoader(aClassLoader, aContext);
// WeakHashMap needs to be synchronized to prevent endless loop under the heavy load
xmlMarshallerMap = Collections.synchronizedMap(new WeakHashMap());
xmlUnmarshallerMap = Collections.synchronizedMap(new WeakHashMap());
}
/**
* The specified TimeZone will be used for all String to date object
* conversions. By default the TimeZone from the JVM is used.
*/
@Override
public void setTimeZone(TimeZone timeZone) {
getXmlConversionManager().setTimeZone(timeZone);
}
/**
* By setting this flag to true the marshalled date objects marshalled to
* the XML schema types time and dateTime will be qualified by a time zone.
* By default time information is not time zone qualified.
*/
@Override
public void setTimeZoneQualified(boolean timeZoneQualified) {
getXmlConversionManager().setTimeZoneQualified(timeZoneQualified);
}
/**
* Creates and returns an XMLDocument from the input String.
* By default does not perform XSD validation.
* Same as
* load(new StringReader(inputString), null, null);
*
* @param inputString specifies the String to read from
* @return the new XMLDocument loaded
* @throws RuntimeException for errors in XML parsing or
* implementation-specific validation.
*/
@Override
public XMLDocument load(String inputString) {
StringReader reader = new StringReader(inputString);
try {
return load(reader, null, null);
} catch (IOException ioException) {
ioException.printStackTrace();
return null;
}
}
/**
* Creates and returns an XMLDocument from the inputStream.
* The InputStream will be closed after reading.
* By default does not perform XSD validation.
* Same as
* load(inputStream, null, null);
*
* @param inputStream specifies the InputStream to read from
* @return the new XMLDocument loaded
* @throws IOException for stream exceptions.
* @throws RuntimeException for errors in XML parsing or
* implementation-specific validation.
*/
@Override
public XMLDocument load(InputStream inputStream) throws IOException {
return load(inputStream, null, null);
}
/**
* Creates and returns an XMLDocument from the inputStream.
* The InputStream will be closed after reading.
* By default does not perform XSD validation.
* @param inputStream specifies the InputStream to read from
* @param locationURI specifies the URI of the document for relative schema locations
* @param options implementation-specific options.
* @return the new XMLDocument loaded
* @throws IOException for stream exceptions.
* @throws RuntimeException for errors in XML parsing or
* implementation-specific validation.
*/
@Override
public XMLDocument load(InputStream inputStream, String locationURI, Object options) throws IOException {
InputSource inputSource = new InputSource(inputStream);
return load(inputSource, locationURI, options);
}
/**
* Creates and returns an XMLDocument from the inputSource.
* The InputSource will be closed after reading.
* By default does not perform XSD validation.
* @param inputSource specifies the InputSource to read from
* @param locationURI specifies the URI of the document for relative schema locations
* @param options implementation-specific options.
* @return the new XMLDocument loaded
* @throws IOException for stream exceptions.
* @throws RuntimeException for errors in XML parsing or
* implementation-specific validation.
*/
@Override
public XMLDocument load(InputSource inputSource, String locationURI, Object options) throws IOException {
// get XMLUnmarshaller once - as we may create a new instance if this helper isDirty=true
XMLUnmarshaller anXMLUnmarshaller = getXmlUnmarshaller(options);
Object unmarshalledObject = null;
if (options == null) {
try {
unmarshalledObject = anXMLUnmarshaller.unmarshal(inputSource);
} catch(XMLMarshalException xmlException){
handleXMLMarshalException(xmlException);
}
} else {
try {
DataObject optionsDataObject = (DataObject)options;
try {
SDOType theType = (SDOType)optionsDataObject.get(SDOConstants.TYPE_LOAD_OPTION);
try{
if (theType != null) {
if(theType.isDataType()) {
theType = (SDOType)((SDOTypeHelper)this.aHelperContext.getTypeHelper()).getWrappersHashMap().get(theType.getQName());
}
if(theType != null) {
unmarshalledObject = anXMLUnmarshaller.unmarshal(inputSource, theType.getImplClass());
} else {
unmarshalledObject = anXMLUnmarshaller.unmarshal(inputSource);
}
}else{
unmarshalledObject = anXMLUnmarshaller.unmarshal(inputSource);
}
} catch(XMLMarshalException xmlException){
handleXMLMarshalException(xmlException);
}
} catch (ClassCastException ccException) {
throw SDOException.typePropertyMustBeAType(ccException);
}
} catch (ClassCastException ccException) {
throw SDOException.optionsMustBeADataObject(ccException, SDOConstants.ORACLE_SDO_URL ,SDOConstants.XMLHELPER_LOAD_OPTIONS);
}
}
if (unmarshalledObject instanceof XMLRoot) {
XMLRoot xmlRoot = (XMLRoot)unmarshalledObject;
XMLDocument xmlDocument = createDocument((DataObject)((XMLRoot)unmarshalledObject).getObject(), ((XMLRoot)unmarshalledObject).getNamespaceURI(), ((XMLRoot)unmarshalledObject).getLocalName());
if(xmlRoot.getEncoding() != null) {
xmlDocument.setEncoding(xmlRoot.getEncoding());
}
if(xmlRoot.getXMLVersion() != null) {
xmlDocument.setXMLVersion(xmlRoot.getXMLVersion());
}
xmlDocument.setSchemaLocation(xmlRoot.getSchemaLocation());
xmlDocument.setNoNamespaceSchemaLocation(xmlRoot.getNoNamespaceSchemaLocation());
return xmlDocument;
} else if (unmarshalledObject instanceof DataObject) {
String localName = ((SDOType)((DataObject)unmarshalledObject).getType()).getXmlDescriptor().getDefaultRootElement();
if (localName == null) {
localName = ((SDOType)((DataObject)unmarshalledObject).getType()).getXsdLocalName();
}
return createDocument((DataObject)unmarshalledObject, ((DataObject)unmarshalledObject).getType().getURI(), localName);
} else if (unmarshalledObject instanceof XMLDocument) {
return (XMLDocument)unmarshalledObject;
}
return null;
}
/**
* Creates and returns an XMLDocument from the inputReader.
* The InputStream will be closed after reading.
* By default does not perform XSD validation.
* @param inputReader specifies the Reader to read from
* @param locationURI specifies the URI of the document for relative schema locations
* @param options implementation-specific options.
* @return the new XMLDocument loaded
* @throws IOException for stream exceptions.
* @throws RuntimeException for errors in XML parsing or
* implementation-specific validation.
*/
@Override
public XMLDocument load(Reader inputReader, String locationURI, Object options) throws IOException {
InputSource inputSource = new InputSource(inputReader);
return load(inputSource, locationURI, options);
}
@Override
public XMLDocument load(Source source, String locationURI, Object options) throws IOException {
// get XMLUnmarshaller once - as we may create a new instance if this helper isDirty=true
XMLUnmarshaller anXMLUnmarshaller = getXmlUnmarshaller(options);
Object unmarshalledObject = null;
if (options == null) {
try {
unmarshalledObject = anXMLUnmarshaller.unmarshal(source);
} catch(XMLMarshalException xmlException){
handleXMLMarshalException(xmlException);
}
} else {
try {
DataObject optionsDataObject = (DataObject)options;
try {
SDOType theType = (SDOType)optionsDataObject.get(SDOConstants.TYPE_LOAD_OPTION);
try{
if (theType != null) {
if(theType.isDataType()) {
theType = (SDOType)((SDOTypeHelper)this.aHelperContext.getTypeHelper()).getWrappersHashMap().get(theType.getQName());
}
if(theType != null) {
unmarshalledObject = anXMLUnmarshaller.unmarshal(source, theType.getImplClass());
} else {
unmarshalledObject = anXMLUnmarshaller.unmarshal(source);
}
}else{
unmarshalledObject = anXMLUnmarshaller.unmarshal(source);
}
} catch(XMLMarshalException xmlException){
handleXMLMarshalException(xmlException);
}
} catch (ClassCastException ccException) {
throw SDOException.typePropertyMustBeAType(ccException);
}
} catch (ClassCastException ccException) {
throw SDOException.optionsMustBeADataObject(ccException, SDOConstants.ORACLE_SDO_URL ,SDOConstants.XMLHELPER_LOAD_OPTIONS);
}
}
if (unmarshalledObject instanceof XMLRoot) {
XMLRoot xmlRoot = (XMLRoot)unmarshalledObject;
XMLDocument xmlDocument = createDocument((DataObject)((XMLRoot)unmarshalledObject).getObject(), ((XMLRoot)unmarshalledObject).getNamespaceURI(), ((XMLRoot)unmarshalledObject).getLocalName());
if(xmlRoot.getEncoding() != null) {
xmlDocument.setEncoding(xmlRoot.getEncoding());
}
if(xmlRoot.getXMLVersion() != null) {
xmlDocument.setXMLVersion(xmlRoot.getXMLVersion());
}
xmlDocument.setSchemaLocation(xmlRoot.getSchemaLocation());
xmlDocument.setNoNamespaceSchemaLocation(xmlRoot.getNoNamespaceSchemaLocation());
return xmlDocument;
} else if (unmarshalledObject instanceof DataObject) {
DataObject unmarshalledDataObject = (DataObject)unmarshalledObject;
String localName = ((SDOType)((DataObject)unmarshalledObject).getType()).getXmlDescriptor().getDefaultRootElement();
if (localName == null) {
localName = ((SDOType)((DataObject)unmarshalledObject).getType()).getXsdLocalName();
}
return createDocument(unmarshalledDataObject, unmarshalledDataObject.getType().getURI(), localName);
} else if (unmarshalledObject instanceof XMLDocument) {
return (XMLDocument)unmarshalledObject;
}
return null;
}
/**
* Returns the DataObject saved as an XML document with the specified root element.
* Same as
* StringWriter stringWriter = new StringWriter();
* save(createDocument(dataObject, rootElementURI, rootElementName),
* stringWriter, null);
* stringWriter.toString();
*
* @param dataObject specifies DataObject to be saved
* @param rootElementURI the Target Namespace URI of the root XML element
* @param rootElementName the Name of the root XML element
* @return the saved XML document as a string
* @throws IllegalArgumentException if the dataObject tree
* is not closed or has no container.
*/
@Override
public String save(DataObject dataObject, String rootElementURI, String rootElementName) {
try {
StringWriter writer = new StringWriter();
save(dataObject, rootElementURI, rootElementName, writer, getXmlMarshaller(null));
return writer.toString();
} catch (XMLMarshalException e) {
throw SDOException.xmlMarshalExceptionOccurred(e, rootElementURI, rootElementName);
}
}
/**
* Saves the DataObject as an XML document with the specified root element.
* Same as
* save(createDocument(dataObject, rootElementURI, rootElementName),
* outputStream, null);
*
* @param dataObject specifies DataObject to be saved
* @param rootElementURI the Target Namespace URI of the root XML element
* @param rootElementName the Name of the root XML element
* @param outputStream specifies the OutputStream to write to.
* @throws IOException for stream exceptions.
* @throws IllegalArgumentException if the dataObject tree
* is not closed or has no container.
*/
@Override
public void save(DataObject dataObject, String rootElementURI, String rootElementName, OutputStream outputStream) throws XMLMarshalException, IOException {
XMLMarshaller xmlMarshaller = getXmlMarshaller(null);
OutputStreamWriter writer = new OutputStreamWriter(outputStream, xmlMarshaller.getEncoding());
save(dataObject, rootElementURI, rootElementName, writer, xmlMarshaller);
}
@Override
public void serialize(XMLDocument xmlDocument, OutputStream outputStream, Object options) throws IOException {
XMLMarshaller xmlMarshaller = getXmlMarshaller();
XMLAttachmentMarshaller attachmentMarshaller = xmlMarshaller.getAttachmentMarshaller();
//temporarily null out the attachment marshaller as it should not be used during serialization
xmlMarshaller.setAttachmentMarshaller(null);
OutputStreamWriter writer = new OutputStreamWriter(outputStream, xmlMarshaller.getEncoding());
save(xmlDocument, writer, xmlMarshaller);
xmlMarshaller.setAttachmentMarshaller(attachmentMarshaller);
}
/**
* Serializes an XMLDocument as an XML document into the outputStream.
* If the DataObject's Type was defined by an XSD, the serialization
* will follow the XSD.
* Otherwise the serialization will follow the format as if an XSD
* were generated as defined by the SDO specification.
* The OutputStream will be flushed after writing.
* Does not perform validation to ensure compliance with an XSD.
* @param xmlDocument specifies XMLDocument to be saved
* @param outputStream specifies the OutputStream to write to.
* @param options implementation-specific options.
* @throws IOException for stream exceptions.
* @throws IllegalArgumentException if the dataObject tree
* is not closed or has no container.
*/
@Override
public void save(XMLDocument xmlDocument, OutputStream outputStream, Object options) throws IOException {
if (xmlDocument == null) {
throw new IllegalArgumentException(SDOException.cannotPerformOperationWithNullInputParameter("save", "xmlDocument"));
}
XMLMarshaller xmlMarshaller = getXmlMarshaller(options);
String encoding = xmlMarshaller.getEncoding();
if(xmlDocument.getEncoding() != null) {
encoding = xmlDocument.getEncoding();
}
OutputStreamWriter writer = new OutputStreamWriter(outputStream, encoding);
save(xmlDocument, writer, xmlMarshaller);
}
/**
* Serializes an XMLDocument as an XML document into the outputWriter.
* If the DataObject's Type was defined by an XSD, the serialization
* will follow the XSD.
* Otherwise the serialization will follow the format as if an XSD
* were generated as defined by the SDO specification.
* The OutputStream will be flushed after writing.
* Does not perform validation to ensure compliance with an XSD.
* @param xmlDocument specifies XMLDocument to be saved
* @param outputWriter specifies the Writer to write to.
* @param options implementation-specific options.
* @throws IOException for stream exceptions.
* @throws IllegalArgumentException if the dataObject tree
* is not closed or has no container.
*/
@Override
public void save(XMLDocument xmlDocument, Writer outputWriter, Object options) throws IOException {
save(xmlDocument, outputWriter, getXmlMarshaller(options));
}
private void save(XMLDocument xmlDocument, Writer outputWriter, XMLMarshaller anXMLMarshaller) throws IOException {
if (xmlDocument == null) {
throw new IllegalArgumentException(SDOException.cannotPerformOperationWithNullInputParameter("save", "xmlDocument"));
}
// Ask the SDOXMLDocument if we should include the XML declaration in the resulting XML
anXMLMarshaller.setFragment(!xmlDocument.isXMLDeclaration());
anXMLMarshaller.setEncoding(xmlDocument.getEncoding());
anXMLMarshaller.setSchemaLocation(xmlDocument.getSchemaLocation());
anXMLMarshaller.setNoNamespaceSchemaLocation(xmlDocument.getNoNamespaceSchemaLocation());
WriterRecord writerRecord;
if(anXMLMarshaller.isFormattedOutput()) {
writerRecord = new FormattedWriterRecord();
} else {
writerRecord = new WriterRecord();
}
writerRecord.setWriter(outputWriter);
writerRecord.setMarshaller(anXMLMarshaller);
SDOMarshalListener listener = ((SDOMarshalListener)anXMLMarshaller.getMarshalListener());
listener.setMarshalledObject(xmlDocument.getRootObject());
listener.setMarshalledObjectRootQName(new QName(xmlDocument.getRootElementURI(), xmlDocument.getRootElementName()));
listener.setRootMarshalRecord(writerRecord);
try{
anXMLMarshaller.marshal(xmlDocument, writerRecord);
writerRecord.flush();
}catch(XMLMarshalException xme){
if(xme.getErrorCode() == XMLMarshalException.DESCRIPTOR_NOT_FOUND_IN_PROJECT){
if(aHelperContext != ((SDOType)xmlDocument.getRootObject().getType()).getHelperContext()){
throw SDOException.dataObjectNotFromHelperContext();
}
}
} finally{
listener.setMarshalledObject(null);
listener.setMarshalledObjectRootQName(null);
listener.setRootMarshalRecord(null);
}
outputWriter.flush();
}
@Override
public void save(XMLDocument xmlDocument, Result result, Object options) throws IOException {
if (xmlDocument == null) {
throw new IllegalArgumentException(SDOException.cannotPerformOperationWithNullInputParameter("save", "xmlDocument"));
}
if (result instanceof StreamResult) {
StreamResult streamResult = (StreamResult)result;
Writer writer = streamResult.getWriter();
if (null == writer) {
save(xmlDocument, streamResult.getOutputStream(), options);
} else {
save(xmlDocument, writer, options);
}
} else {
// get XMLMarshaller once - as we may create a new instance if this helper isDirty=true
XMLMarshaller anXMLMarshaller = getXmlMarshaller(options);
// Ask the SDOXMLDocument if we should include the XML declaration in the resulting XML
anXMLMarshaller.setFragment(!xmlDocument.isXMLDeclaration());
anXMLMarshaller.setEncoding(xmlDocument.getEncoding());
anXMLMarshaller.setSchemaLocation(xmlDocument.getSchemaLocation());
anXMLMarshaller.setNoNamespaceSchemaLocation(xmlDocument.getNoNamespaceSchemaLocation());
SDOMarshalListener listener = ((SDOMarshalListener)anXMLMarshaller.getMarshalListener());
listener.setMarshalledObject(xmlDocument.getRootObject());
listener.setMarshalledObjectRootQName(new QName(xmlDocument.getRootElementURI(), xmlDocument.getRootElementName()));
if(result instanceof SAXResult) {
ContentHandlerRecord marshalRecord = new ContentHandlerRecord();
marshalRecord.setContentHandler(((SAXResult)result).getHandler());
marshalRecord.setMarshaller(anXMLMarshaller);
listener.setRootMarshalRecord(marshalRecord);
anXMLMarshaller.marshal(xmlDocument, marshalRecord);
marshalRecord.flush();
} else if(result instanceof DOMResult) {
NodeRecord marshalRecord = new NodeRecord();
marshalRecord.setDOM(((DOMResult)result).getNode());
marshalRecord.setMarshaller(anXMLMarshaller);
listener.setRootMarshalRecord(marshalRecord);
anXMLMarshaller.marshal(xmlDocument, marshalRecord);
marshalRecord.flush();
} else {
StringWriter writer = new StringWriter();
this.save(xmlDocument, writer, options);
String xml = writer.toString();
StreamSource source = new StreamSource(new java.io.StringReader(xml));
anXMLMarshaller.getTransformer().transform(source, result);
}
listener.setMarshalledObject(null);
listener.setMarshalledObjectRootQName(null);
listener.setRootMarshalRecord(null);
}
}
/**
* Creates an XMLDocument with the specified XML rootElement for the DataObject.
* @param dataObject specifies DataObject to be saved
* @param rootElementURI the Target Namespace URI of the root XML element
* @param rootElementName the Name of the root XML element
* @return XMLDocument a new XMLDocument set with the specified parameters.
*/
@Override
public XMLDocument createDocument(DataObject dataObject, String rootElementURI, String rootElementName) {
SDOXMLDocument document = new SDOXMLDocument();
document.setRootObject(dataObject);
document.setRootElementURI(rootElementURI);
if (rootElementName != null) {
document.setRootElementName(rootElementName);
}
Property globalProp = getHelperContext().getXSDHelper().getGlobalProperty(rootElementURI, rootElementName, true);
if (null != globalProp) {
document.setSchemaType(((SDOType) globalProp.getType()).getXsdType());
}
document.setEncoding(SDOXMLDocument.DEFAULT_XML_ENCODING);
document.setXMLVersion(SDOXMLDocument.DEFAULT_XML_VERSION);
return document;
}
/**
* INTERNAL:
* Saves the DataObject as an XML document with the specified root element.
* Same as
* save(createDocument(dataObject, rootElementURI, rootElementName),
* writer, null);
*
* @param rootObject specifies DataObject to be saved
* @param rootElementURI the Target Namespace URI of the root XML element
* @param rootElementName the Name of the root XML element
* @param writer specifies the Writer to write to.
* @throws IllegalArgumentException if the dataObject tree
* is not closed or has no container.
*/
private void save(DataObject rootObject, String rootElementURI, String rootElementName, Writer writer, XMLMarshaller anXMLMarshaller) throws XMLMarshalException {
SDOXMLDocument xmlDocument = (SDOXMLDocument)createDocument(rootObject, rootElementURI, rootElementName);
// Ask the SDOXMLDocument if we should include the XML declaration in the resulting XML
anXMLMarshaller.setFragment(!xmlDocument.isXMLDeclaration());
WriterRecord writerRecord;
if(anXMLMarshaller.isFormattedOutput()) {
writerRecord = new FormattedWriterRecord();
} else {
writerRecord = new WriterRecord();
}
writerRecord.setWriter(writer);
writerRecord.setMarshaller(anXMLMarshaller);
SDOMarshalListener listener = ((SDOMarshalListener)anXMLMarshaller.getMarshalListener());
listener.setMarshalledObject(rootObject);
listener.setMarshalledObjectRootQName(new QName(rootElementURI, rootElementName));
listener.setRootMarshalRecord(writerRecord);
try{
anXMLMarshaller.marshal(xmlDocument, writerRecord);
writerRecord.flush();
}catch(XMLMarshalException xme){
if(xme.getErrorCode() == XMLMarshalException.DESCRIPTOR_NOT_FOUND_IN_PROJECT){
if(aHelperContext != ((SDOType)rootObject.getType()).getHelperContext()){
throw SDOException.dataObjectNotFromHelperContext();
}
}
}finally{
listener.setMarshalledObject(null);
listener.setMarshalledObjectRootQName(null);
listener.setRootMarshalRecord(null);
}
try {
writer.flush();
} catch(IOException ex) {
throw XMLMarshalException.marshalException(ex);
}
}
@Override
public void setLoader(SDOClassLoader loader) {
this.loader = loader;
getXmlConversionManager().setLoader(this.loader);
}
@Override
public SDOClassLoader getLoader() {
return loader;
}
@Override
public void setXmlContext(XMLContext xmlContext) {
this.xmlContext = xmlContext;
}
@Override
public synchronized XMLContext getXmlContext() {
if (xmlContext == null) {
xmlContext = new XMLContext(getTopLinkProject());
XMLConversionManager xmlConversionManager = getXmlConversionManager();
xmlConversionManager.setLoader(this.loader);
xmlConversionManager.setTimeZone(TimeZone.getTimeZone("GMT"));
xmlConversionManager.setTimeZoneQualified(true);
}
return xmlContext;
}
@Override
public void initializeDescriptor(XMLDescriptor descriptor){
AbstractSession theSession = (AbstractSession)getXmlContext().getSession();
//do initialization for new descriptor;
descriptor.preInitialize(theSession);
descriptor.initialize(theSession);
descriptor.postInitialize(theSession);
descriptor.getObjectBuilder().initializePrimaryKey(theSession);
getXmlContext().storeXMLDescriptorByQName(descriptor);
}
@Override
public void addDescriptors(List types) {
for (int i = 0; i < types.size(); i++) {
SDOType nextType = (SDOType)types.get(i);
if (!nextType.isDataType() && nextType.isFinalized()){
XMLDescriptor nextDescriptor = nextType.getXmlDescriptor();
getTopLinkProject().addDescriptor(nextDescriptor);
}
}
for (int i = 0; i < types.size(); i++) {
SDOType nextType = (SDOType)types.get(i);
if (!nextType.isDataType() && nextType.isFinalized()){
XMLDescriptor nextDescriptor = nextType.getXmlDescriptor();
initializeDescriptor(nextDescriptor);
}
}
}
@Override
public void setTopLinkProject(Project toplinkProject) {
this.topLinkProject = toplinkProject;
this.xmlContext = null;
this.xmlMarshallerMap.clear();
this.xmlUnmarshallerMap.clear();
}
@Override
public Project getTopLinkProject() {
if (topLinkProject == null) {
topLinkProject = new Project();
XMLLogin xmlLogin = new XMLLogin();
xmlLogin.setEqualNamespaceResolvers(false);
topLinkProject.setDatasourceLogin(xmlLogin);
// 200606_changeSummary
NamespaceResolver nr = new NamespaceResolver();
SDOTypeHelper sdoTypeHelper = (SDOTypeHelper) aHelperContext.getTypeHelper();
String sdoPrefix = sdoTypeHelper.getPrefix(SDOConstants.SDO_URL);
nr.put(sdoPrefix, SDOConstants.SDO_URL);
SDOType changeSummaryType = (SDOType) sdoTypeHelper.getType(SDOConstants.SDO_URL, SDOConstants.CHANGESUMMARY);
changeSummaryType.getXmlDescriptor().setNamespaceResolver(nr);
topLinkProject.addDescriptor(changeSummaryType.getXmlDescriptor());
SDOType openSequencedType = (SDOType) aHelperContext.getTypeHelper().getType(SDOConstants.ORACLE_SDO_URL, "OpenSequencedType");
topLinkProject.addDescriptor(openSequencedType.getXmlDescriptor());
SDOTypeType typeType = (SDOTypeType)aHelperContext.getTypeHelper().getType(SDOConstants.SDO_URL, SDOConstants.TYPE);
typeType.getXmlDescriptor().setNamespaceResolver(nr);
if(!typeType.isInitialized()) {
typeType.initializeMappings();
}
topLinkProject.addDescriptor(typeType.getXmlDescriptor());
SDOPropertyType propertyType = (SDOPropertyType)aHelperContext.getTypeHelper().getType(SDOConstants.SDO_URL, SDOConstants.PROPERTY);
if(!propertyType.isInitialized()) {
propertyType.initializeMappings();
}
topLinkProject.addDescriptor(propertyType.getXmlDescriptor());
((SDOTypeHelper)aHelperContext.getTypeHelper()).addWrappersToProject(topLinkProject);
}
return topLinkProject;
}
@Override
public void setXmlMarshaller(XMLMarshaller xmlMarshaller) {
this.xmlMarshallerMap.put(Thread.currentThread(), xmlMarshaller);
}
@Override
public XMLMarshaller getXmlMarshaller() {
XMLMarshaller marshaller = xmlMarshallerMap.get(Thread.currentThread());
if (marshaller == null) {
marshaller = getXmlContext().createMarshaller();
marshaller.setMarshalListener(new SDOMarshalListener(marshaller, (SDOTypeHelper) aHelperContext.getTypeHelper()));
xmlMarshallerMap.put(Thread.currentThread(), marshaller);
}
XMLContext context = getXmlContext();
if (marshaller.getXMLContext() != context) {
marshaller.setXMLContext(context);
}
return marshaller;
}
private XMLMarshaller getXmlMarshaller(Object options) {
XMLMarshaller xmlMarshaller = getXmlMarshaller().clone();
if(null == options) {
return xmlMarshaller;
}
try {
DataObject optionsDO = (DataObject) options;
if(optionsDO.isSet(SDOConstants.ATTACHMENT_MARSHALLER_OPTION)) {
xmlMarshaller.setAttachmentMarshaller((XMLAttachmentMarshaller)optionsDO.get(SDOConstants.ATTACHMENT_MARSHALLER_OPTION));
}
xmlMarshaller.setMarshalListener(new SDOMarshalListener(xmlMarshaller, (SDOTypeHelper) aHelperContext.getTypeHelper()));
return xmlMarshaller;
} catch(ClassCastException ccException) {
throw SDOException.optionsMustBeADataObject(ccException, SDOConstants.ORACLE_SDO_URL ,SDOConstants.XMLHELPER_LOAD_OPTIONS);
}
}
@Override
public void setXmlUnmarshaller(XMLUnmarshaller xmlUnmarshaller) {
this.xmlUnmarshallerMap.put(Thread.currentThread(), xmlUnmarshaller);
}
@Override
public XMLUnmarshaller getXmlUnmarshaller() {
XMLUnmarshaller unmarshaller = xmlUnmarshallerMap.get(Thread.currentThread());
if (null == unmarshaller) {
unmarshaller = getXmlContext().createUnmarshaller();
unmarshaller.getProperties().put(SDOConstants.SDO_HELPER_CONTEXT, aHelperContext);
unmarshaller.setUnmappedContentHandlerClass(SDOUnmappedContentHandler.class);
unmarshaller.setUnmarshalListener(new SDOUnmarshalListener(aHelperContext));
unmarshaller.setResultAlwaysXMLRoot(true);
xmlUnmarshallerMap.put(Thread.currentThread(), unmarshaller);
}
XMLContext context = getXmlContext();
if (unmarshaller.getXMLContext() != context) {
unmarshaller.setXMLContext(context);
}
return unmarshaller;
}
private XMLUnmarshaller getXmlUnmarshaller(Object options) {
XMLUnmarshaller xmlUnmarshaller = getXmlUnmarshaller().clone();
if(null == options) {
return xmlUnmarshaller;
}
try {
DataObject optionsDO = (DataObject) options;
if(optionsDO.isSet(SDOConstants.ATTACHMENT_UNMARSHALLER_OPTION)) {
xmlUnmarshaller.setAttachmentUnmarshaller((XMLAttachmentUnmarshaller)optionsDO.get(SDOConstants.ATTACHMENT_UNMARSHALLER_OPTION));
}
return xmlUnmarshaller;
} catch(ClassCastException ccException) {
throw SDOException.optionsMustBeADataObject(ccException, SDOConstants.ORACLE_SDO_URL ,SDOConstants.XMLHELPER_LOAD_OPTIONS);
}
}
@Override
public void reset() {
setTopLinkProject(null);
setXmlContext(null);
this.xmlMarshallerMap.clear();
this.xmlUnmarshallerMap.clear();
setLoader(new SDOClassLoader(getClass().getClassLoader(), aHelperContext));
}
@Override
public HelperContext getHelperContext() {
return aHelperContext;
}
@Override
public void setHelperContext(HelperContext helperContext) {
aHelperContext = helperContext;
}
private void handleXMLMarshalException(XMLMarshalException xmlException) throws IOException {
if(xmlException.getErrorCode() == XMLMarshalException.NO_DESCRIPTOR_WITH_MATCHING_ROOT_ELEMENT || xmlException.getErrorCode() == XMLMarshalException.DESCRIPTOR_NOT_FOUND_IN_PROJECT){
throw SDOException.globalPropertyNotFound();
} else if (xmlException.getCause() instanceof IOException) {
throw (IOException) xmlException.getCause();
} else{
throw xmlException;
}
}
@Override
public XMLConversionManager getXmlConversionManager() {
return (XMLConversionManager) getXmlContext().getSession().getDatasourceLogin().getDatasourcePlatform().getConversionManager();
}
}