All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.oxm.XMLContext Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * 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.oxm;

import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.xml.namespace.QName;

import org.eclipse.persistence.core.mappings.CoreAttributeAccessor;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.oxm.Context;
import org.eclipse.persistence.internal.oxm.ConversionManager;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.XPathQName;
import org.eclipse.persistence.internal.oxm.accessor.OrmAttributeAccessor;
import org.eclipse.persistence.internal.oxm.documentpreservation.DescriptorLevelDocumentPreservationPolicy;
import org.eclipse.persistence.internal.oxm.documentpreservation.NoDocumentPreservationPolicy;
import org.eclipse.persistence.internal.oxm.mappings.CompositeCollectionMapping;
import org.eclipse.persistence.internal.oxm.mappings.CompositeObjectMapping;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.mappings.Mapping;
import org.eclipse.persistence.internal.oxm.mappings.ObjectReferenceMapping;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedGetClassLoaderForClass;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.OneToOneMapping;
import org.eclipse.persistence.oxm.documentpreservation.DocumentPreservationPolicy;
import org.eclipse.persistence.oxm.platform.SAXPlatform;
import org.eclipse.persistence.oxm.platform.XMLPlatform;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.SessionEventListener;
import org.eclipse.persistence.sessions.SessionEventManager;
import org.eclipse.persistence.sessions.factories.SessionManager;
import org.eclipse.persistence.sessions.factories.XMLSessionConfigLoader;

/**
 * 

* An XMLContext is created based on EclipseLink sessions or projects and can then * used to create instances of XMLMarshaller, XMLUnmarshaller and XMLValidator. * *

* There are constructors to create an XMLContext with a single EclipseLink project * or with a String which is a single EclipseLink session name or a ':' separated * list of EclipseLink session names. * *

* Code Sample
* * XMLContext context = new XMLContext("mySessionName");
* XMLMarshaller marshaller = context.createMarshaller();
* XMLUnmarshaller unmarshaller = context.createUnmarshaller();
* XMLValidator validator = context.createValidator();
*
* *

The XMLContext is thread-safe. If multiple threads accessing the same XMLContext object * request an XMLMarshaller, each will receive their own instance of XMLMarshaller, so any * state that the XMLMarshaller maintains will be unique to that process. The same is true * of instances of XMLUnmarshaller and XMLValidator. * * @see org.eclipse.persistence.oxm.XMLMarshaller * @see org.eclipse.persistence.oxm.XMLUnmarshaller * @see org.eclipse.persistence.oxm.XMLValidator * */ public class XMLContext extends Context { XMLContext(XMLContextState xmlContextState) { this.contextState = xmlContextState; } /** * Create a new XMLContext based on the specified session name or list of * session names * * @param sessionNames * A single session name or multiple session names separated by a : */ public XMLContext(String sessionNames) { this(sessionNames, privilegedGetClassLoaderForClass(XMLContext.class)); } /** * Create a new XMLContext based on the specified session name or list of * session names * * @param sessionNames * A single session name or multiple session names separated by a : * @param classLoader * classloader for loading sessions.xml */ public XMLContext(String sessionNames, ClassLoader classLoader) { this(sessionNames, classLoader, null); } /** * Create a new XMLContext based on passed in session names and session meta * XML. * * @param sessionNames * A single session name or multiple session names separated by * a: * @param xmlResource * path to XML file containing session meta data to initialize * and load sessions. */ public XMLContext(String sessionNames, String xmlResource) { this(sessionNames, privilegedGetClassLoaderForClass(XMLContext.class), xmlResource); } /** * Create a new XMLContext based on passed in session names, classloader and * session meta XML. * * @param sessionNames * A single session name or multiple session names separated by a : * @param classLoader * classloader for loading sessions.xml * @param xmlResource * path to XML file containing session meta data to initialize * and load sessions. */ public XMLContext(String sessionNames, ClassLoader classLoader, String xmlResource) { contextState = new XMLContextState(this, sessionNames, classLoader, xmlResource); } /** * Create a new XMLContext based on the specified project * * @param project * An EclipseLink project */ public XMLContext(Project project) { this(project, Thread.currentThread().getContextClassLoader()); } /** * Create a new XMLContext based on the specified Project and ClassLoader. * * @param project An EclipseLink project * @param classLoader The ClassLoader to be used */ public XMLContext(Project project, ClassLoader classLoader) { this (project, classLoader, (Collection) null); } /** * Create a new XMLContext based on the specified Project and ClassLoader. * * @param project An EclipseLink project * @param classLoader The ClassLoader to be used * @param sessionEventListener If non-null, this listener will be registered with the SessionEventManager * @see SessionEventListener * @see SessionEventManager */ public XMLContext(Project project, ClassLoader classLoader, SessionEventListener sessionEventListener) { Collection sessionEventListeners = new ArrayList<>(1); sessionEventListeners.add(sessionEventListener); contextState = new XMLContextState(this, project, classLoader, sessionEventListeners); } /** * Create a new XMLContext based on the specified Project and ClassLoader. * * @param project An EclipseLink project * @param classLoader The ClassLoader to be used * @param sessionEventListeners If non-null, these listeners will be registered with the SessionEventManager * @see SessionEventListener * @see SessionEventManager */ public XMLContext(Project project, ClassLoader classLoader, Collection sessionEventListeners) { contextState = new XMLContextState(this, project, classLoader, sessionEventListeners); } public XMLContext(Collection projects) { this(projects, Thread.currentThread().getContextClassLoader()); } public XMLContext(Collection projects, ClassLoader classLoader) { contextState = new XMLContextState(this, projects, classLoader); } /** * INTERNAL: Return the XMLContextState that represents the XMLContexts * stateful information. This method is provided for the benefits of layers * that build on top of the core OXM layer such as MOXy's JAXB * implementation. */ public XMLContextState getXMLContextState() { return (XMLContextState) contextState; } /** * INTERNAL: Set the stateful information for this XMLContext. Once the new * state has been set, OXM operations (marshal, unmarshal, etc) will be * based on this new state. This method is provided for the benefit of * layers that build on top of the core OXM layer such as MOXy's JAXB * */ public void setXMLContextState(XMLContextState xcs) { synchronized(this) { this.contextState = xcs; } } /** * INTERNAL: Add and initialize a new session to the list of sessions * associated with this XMLContext. */ public void addSession(DatabaseSession sessionToAdd) { getXMLContextState().addSession(sessionToAdd); } /** * Create a new XMLUnmarshaller * * @return An XMLUnmarshaller based on this XMLContext */ @Override public XMLUnmarshaller createUnmarshaller() { return new XMLUnmarshaller(this); } /** * Create a new XMLUnmarshaller *

     * {@literal Map parserFeatures = new HashMap(1);}
     * parserFeatures.put("http://apache.org/xml/features/validation/schema/normalized-value", false);
     * XMLUnmarshaller unmarshaller = xmlContext.createUnmarshaller(parserFeatures);
     * 
* @return An XMLUnmarshaller based on this XMLContext, the underlying * parser will use the passed in parser features. */ public XMLUnmarshaller createUnmarshaller(Map parserFeatures) { return new XMLUnmarshaller(this, parserFeatures); } /** * Create a new XMLBinder * @return an XMLBinder based on this XMLContext */ public XMLBinder createBinder() { return new XMLBinder(this); } /** * Create a new XMLBinder with supplied marshaller and unmarshaller instances. * @return an XMLBinder based on this XMLContext, */ public XMLBinder createBinder(XMLMarshaller marshaller, XMLUnmarshaller unmarshaller) { return new XMLBinder(this, marshaller, unmarshaller); } /** * Create a new XMLMarshaller * * @return An XMLMarshaller based on this XMLContext */ @Override public XMLMarshaller createMarshaller() { return new XMLMarshaller(this); } /** * Create a new XMLValidator * * @return An XMLValidator based on this XMLContext */ public XMLValidator createValidator() { return new XMLValidator(this); } /** * INTERNAL: Return the session corresponding to this object. Since the * object may be mapped by more that one of the projects used to create the * XML Context, this method will return the first match. * * The session will be a unit of work if document preservation is not * enabled. This method will typically be used for unmarshalling * when a non-shared cache is desired. */ public AbstractSession getReadSession(Object object) { return getSession(object); } /** * INTERNAL: * Return the session corresponding to this class. Since the class * may be mapped by more that one of the projects used to create the XML * Context, this method will return the first match. * * The session will be a unit of work if document preservation is not * enabled. This method will typically be used for unmarshalling * when a non-shared cache is desired. */ public AbstractSession getReadSession(Class clazz) { return super.getSession(clazz); } /** * INTERNAL: * Return the session corresponding to this XMLDescriptor. Since * the class may be mapped by more that one of the projects used to create * the XML Context, this method will return the first match. * * The session will be a unit of work if document preservation is not * enabled. This method will typically be used for unmarshalling * when a non-shared cache is desired. */ public AbstractSession getReadSession(XMLDescriptor xmlDescriptor) { return super.getSession(xmlDescriptor); } /** * INTERNAL: Return the EclipseLink session used to marshal. */ public List getSessions() { return getXMLContextState().getSessions(); } /** * INTERNAL: * XMLContext xmlContext = new XMLContext("path0:path1");
* DatabaseSession session = xmlContext.getSession(0); // returns session for path0
*
*/ public DatabaseSession getSession(int index) { return getXMLContextState().getSession(index); } /** * INTERNAL: Return the session corresponding to this object. Since the * object may be mapped by more that one of the projects used to create the * XML Context, this method will return the first match. */ @Override public AbstractSession getSession(Object object) { return super.getSession(object); } /** * INTERNAL: Return the session corresponding to this class. Since the class * may be mapped by more that one of the projects used to create the XML * Context, this method will return the first match. */ @Override public AbstractSession getSession(Class clazz) { return super.getSession(clazz); } /** * INTERNAL: Return the session corresponding to this XMLDescriptor. Since * the class may be mapped by more that one of the projects used to create * the XML Context, this method will return the first match. */ @Override public AbstractSession getSession(XMLDescriptor xmlDescriptor) { return super.getSession(xmlDescriptor); } /** * INTERNAL: */ public void storeXMLDescriptorByQName(XMLDescriptor xmlDescriptor) { contextState.storeDescriptorByQName(xmlDescriptor, null, null); } /** * INTERNAL: Return the XMLDescriptor with the default root mapping matching * the QName parameter. */ @Override public XMLDescriptor getDescriptor(QName qName) { return super.getDescriptor(qName); } /** * INTERNAL: Return the XMLDescriptor with the default root mapping matching * the QName parameter. */ @Override public XMLDescriptor getDescriptor(XPathQName xpathQName) { return super.getDescriptor(xpathQName); } public void addDescriptorByQName(QName qName, XMLDescriptor descriptor) { contextState.addDescriptorByQName(qName, descriptor); } /** * INTERNAL: Return the XMLDescriptor mapped to the global type matching the * XPathFragment parameter. */ @Override public XMLDescriptor getDescriptorByGlobalType(XPathFragment xPathFragment) { return super.getDescriptorByGlobalType(xPathFragment); } /** * INTERNAL: * Return the DocumentPreservationPolicy associated with this session * @param session * @return */ public DocumentPreservationPolicy getDocumentPreservationPolicy(AbstractSession session) { if (session == null) { return null; } XMLLogin login = (XMLLogin) session.getDatasourceLogin(); return login.getDocumentPreservationPolicy(); } public void setupDocumentPreservationPolicy(DatabaseSession session) { getXMLContextState().setupDocumentPreservationPolicy(session); } /** * INTERNAL: * Return true if any session held onto by this context has a document preservation * policy that requires unmarshalling from a Node. */ @Override public boolean hasDocumentPreservation() { return getXMLContextState().hasDocumentPreservation(); } /** * ADVANCED: * Adjust the OXM metadata to take into account ORM mapping metadata, */ public void applyORMMetadata(AbstractSession ormSession) { //Iterate over the ORM descriptors and check for matching OXM descriptors Iterator ormDescriptors = ormSession.getDescriptors().values().iterator(); while(ormDescriptors.hasNext()) { ClassDescriptor ormDescriptor = (ClassDescriptor)ormDescriptors.next(); Class javaClass = ormDescriptor.getJavaClass(); AbstractSession oxmSession = null; try { oxmSession = this.getSession(javaClass); } catch(XMLMarshalException ex) { //if we couldn't find a session for this class, we //don't have an OX descriptor for it. } if(oxmSession != null) { ClassDescriptor oxmDescriptor = oxmSession.getDescriptor(javaClass); //If we have an oxmDescriptor for this ORM descriptor, iterate over //mappings, and update the required OXM mappings attribute accessors Iterator ormMappings = ormDescriptor.getMappings().iterator(); while(ormMappings.hasNext()) { DatabaseMapping ormMapping = ormMappings.next(); Mapping oxmMapping = (Mapping) oxmDescriptor.getMappingForAttributeName(ormMapping.getAttributeName()); if(oxmMapping != null) { CoreAttributeAccessor oxmAccessor = oxmMapping.getAttributeAccessor(); OrmAttributeAccessor newAccessor = new OrmAttributeAccessor(ormMapping.getAttributeAccessor(), oxmAccessor); if(ormMapping.isOneToOneMapping() && ((OneToOneMapping)ormMapping).usesIndirection()) { newAccessor.setValueHolderProperty(true); } newAccessor.setChangeTracking(ormDescriptor.getObjectChangePolicy().isAttributeChangeTrackingPolicy()); oxmMapping.setAttributeAccessor(newAccessor); //check to see if we need to deal with containerAccessor CoreAttributeAccessor containerAccessor = null; Class containerClass = null; if(oxmMapping.isAbstractCompositeObjectMapping()) { containerAccessor = ((CompositeObjectMapping)oxmMapping).getInverseReferenceMapping().getAttributeAccessor(); containerClass = ((CompositeObjectMapping)oxmMapping).getReferenceClass(); } else if(oxmMapping.isAbstractCompositeCollectionMapping()) { containerAccessor = ((CompositeCollectionMapping)oxmMapping).getInverseReferenceMapping().getAttributeAccessor(); containerClass = ((CompositeCollectionMapping)oxmMapping).getReferenceClass(); } if(containerAccessor != null) { ClassDescriptor containerDescriptor = ormSession.getDescriptor(containerClass); if(containerDescriptor != null) { DatabaseMapping ormContainerMapping = containerDescriptor.getMappingForAttributeName(containerAccessor.getAttributeName()); if(ormContainerMapping != null) { //Check for indirection on the container mapping OrmAttributeAccessor ormAccessor = new OrmAttributeAccessor(ormContainerMapping.getAttributeAccessor(), containerAccessor); ormAccessor.setChangeTracking(containerDescriptor.getObjectChangePolicy().isAttributeChangeTrackingPolicy()); ormAccessor.setValueHolderProperty(ormContainerMapping instanceof OneToOneMapping && ((OneToOneMapping)ormContainerMapping).usesIndirection()); if(oxmMapping.isAbstractCompositeObjectMapping()) { ((CompositeObjectMapping)oxmMapping).getInverseReferenceMapping().setAttributeAccessor(ormAccessor); } else if(oxmMapping.isAbstractCompositeCollectionMapping()) { ((CompositeCollectionMapping)oxmMapping).getInverseReferenceMapping().setAttributeAccessor(ormAccessor); } } } } } } Iterator oxmMappingsIterator = oxmDescriptor.getMappings().iterator(); while(oxmMappingsIterator.hasNext()) { //iterate over the oxm mappings. Any ReferenceMappings that have a //collection as a backpointer, check to see if the container policy //needs to be matched with the ORM project DatabaseMapping nextMapping = oxmMappingsIterator.next(); if(nextMapping instanceof ObjectReferenceMapping) { ObjectReferenceMapping refMapping = (ObjectReferenceMapping)nextMapping; if(refMapping.getInverseReferenceMapping().getAttributeAccessor() != null && refMapping.getInverseReferenceMapping().getContainerPolicy() != null) { ClassDescriptor refDescriptor = ormSession.getClassDescriptor(refMapping.getReferenceClass()); if(refDescriptor != null) { DatabaseMapping backpointerMapping =refDescriptor.getMappingForAttributeName(refMapping.getInverseReferenceMapping().getAttributeName()); if(backpointerMapping != null && backpointerMapping.isCollectionMapping()) { refMapping.getInverseReferenceMapping().getContainerPolicy().setContainerClass(backpointerMapping.getContainerPolicy().getContainerClass()); } } } } } } } } /** *

Query the object model based on the corresponding XML document. The following pairings are equivalent:

* * Return the Customer's ID *
 Integer id = xmlContext.getValueByXPath(customer, "@id", null, Integer.class);
     * Integer id = customer.getId();
* * Return the Customer's Name *
 String name = xmlContext.getValueByXPath(customer, "ns:personal-info/ns:name/text()", null, String.class);
     * String name = customer.getName();
* * Return the Customer's Address *
 Address address = xmlContext.getValueByXPath(customer, "ns:contact-info/ns:address", aNamespaceResolver, Address.class);
     * Address address = customer.getAddress();
* * Return all the Customer's PhoneNumbers *
 List phoneNumbers = xmlContext.getValueByXPath(customer, "ns:contact-info/ns:phone-number", aNamespaceResolver, List.class);
     * List phoneNumbers = customer.getPhoneNumbers();
* * Return the Customer's second PhoneNumber *
 PhoneNumber phoneNumber = xmlContext.getValueByXPath(customer, "ns:contact-info/ns:phone-number[2]", aNamespaceResolver, PhoneNumber.class);
     * PhoneNumber phoneNumber = customer.getPhoneNumbers().get(1);
* * Return the base object *
 Customer customer = xmlContext.getValueByXPath(customer, ".", aNamespaceResolver, Customer.class);
     * Customer customer = customer;
     * 
* * @param The return type of this method corresponds to the returnType parameter. * @param object The XPath will be executed relative to this object. * @param xPath The XPath statement * @param namespaceResolver A NamespaceResolver containing the prefix/URI pairings from the XPath statement. * @param returnType The return type. * @return The object corresponding to the XPath or null if no result was found. */ @Override public T getValueByXPath(Object object, String xPath, NamespaceResolver namespaceResolver, Class returnType) { return super.getValueByXPath(object, xPath, namespaceResolver, returnType); } /** *

Set values in the object model based on the corresponding XML document. The following pairings are equivalent:

* * Set the Customer's ID *
 xmlContext.setValueByXPath(customer, "@id", null, Integer.valueOf(123));
     * customer.setId(Integer.valueOf(123));
* * Set the Customer's Name *
 xmlContext.setValueByXPath(customer, "ns:personal-info/ns:name/text()", aNamespaceResolver, "Jane Doe");
     * customer.setName("Jane Doe");
* * Set the Customer's Address *
 xmlContext.setValueByXPath(customer, "ns:contact-info/ns:address", aNamespaceResolver, anAddress);
     * customer.setAddress(anAddress);
* * Set the Customer's PhoneNumbers *
 xmlContext.setValueByXPath(customer, "ns:contact-info/ns:phone-number", aNamespaceResolver, phoneNumbers);
     * customer.setPhoneNumbers(phoneNumbers);
* * Set the Customer's second PhoneNumber *
 xmlContext.setValueByXPath(customer, "ns:contact-info/ns:phone-number[2]", aNamespaceResolver, aPhoneNumber);
     * customer.getPhoneNumbers().get(1);
* * @param object The XPath will be executed relative to this object. * @param xPath The XPath statement * @param namespaceResolver A NamespaceResolver containing the prefix/URI pairings from the XPath statement. * @param value The value to be set. */ @Override public void setValueByXPath(Object object, String xPath, NamespaceResolver namespaceResolver, Object value) { super.setValueByXPath(object, xPath, namespaceResolver, value); } /** * Create a new object instance for a given XML namespace and name. * * @param namespace * The namespace of the complex type to create a new Java instance of. * @param typeName * The XML type name to create a new Java instance of. * @param isGlobalType * True if the object to be created represents a global type, false if it * represents a global element. * * @return * An instance of the Java class mapped to the indicated XML type, or null * if no result was found. */ public Object createByQualifiedName(String namespace, String typeName, boolean isGlobalType) throws IllegalArgumentException { QName qName = new QName(namespace, typeName); XMLDescriptor d = null; if (!isGlobalType) { d = getDescriptor(qName); } else { XPathFragment frag = new XPathFragment(); frag.setNamespaceURI(namespace); frag.setLocalName(typeName); d = getDescriptorByGlobalType(frag); } if (d == null) { return null; } return d.getInstantiationPolicy().buildNewInstance(); } /** * Create a new object instance for a given XPath, relative to the parentObject. * * @param * The return type of this method corresponds to the returnType parameter. * @param parentObject * The XPath will be executed relative to this object. * @param xPath * The XPath statement. * @param namespaceResolver * A NamespaceResolver containing the prefix/URI pairings from the XPath statement. * @param returnType * The return type. * * @return * An instance of the Java class mapped to the supplied XML type, or null * if no result was found. */ @Override public T createByXPath(Object parentObject, String xPath, NamespaceResolver namespaceResolver, Class returnType) { return super.createByXPath(parentObject, xPath, namespaceResolver, returnType); } private static class XMLContextState extends ContextState { private List sessions; private boolean hasDocumentPreservation = false; protected XMLContextState(XMLContext xmlContext, Collection projects, ClassLoader classLoader) { this.context = xmlContext; sessions = new ArrayList(projects.size()); Iterator iterator = projects.iterator(); while (iterator.hasNext()) { Project project = iterator.next(); preLogin(project, classLoader); DatabaseSession session = project.createDatabaseSession(); // turn logging for this session off and leave the global // session up // Note: setting level to SEVERE or WARNING will printout // stacktraces for expected exceptions session.setLogLevel(SessionLog.OFF); // don't turn off global static logging // AbstractSessionLog.getLog().log(AbstractSessionLog.INFO, // "ox_turn_global_logging_off", getClass()); // AbstractSessionLog.getLog().setLevel(AbstractSessionLog.OFF); setupSession(session); sessions.add(session); storeDescriptorsByQName(session); } } private XMLContextState(XMLContext xmlContext, String sessionNames, ClassLoader classLoader, String xmlResource) { super(); this.context = xmlContext; XMLSessionConfigLoader loader = null; if (xmlResource != null) { loader = new XMLSessionConfigLoader(xmlResource); } else { loader = new XMLSessionConfigLoader(); } descriptorsByQName = new HashMap(); descriptorsByGlobalType = new HashMap(); StringTokenizer st = new StringTokenizer(sessionNames, ":"); sessions = new ArrayList(st.countTokens()); int index = 0; while (st.hasMoreTokens()) { sessions.add(buildSession(st.nextToken(), classLoader, loader)); index++; } for (int x = index - 1; x >= 0; x--) { storeDescriptorsByQName(sessions.get(x)); } } protected XMLContextState(XMLContext xmlContext, Project project, ClassLoader classLoader, Collection sessionEventListeners) { super(xmlContext, project, classLoader, sessionEventListeners); } /** * INTERNAL: Add and initialize a new session to the list of sessions * associated with this XMLContext. */ private void addSession(DatabaseSession sessionToAdd) { if ((sessionToAdd.getDatasourceLogin() == null) || !(sessionToAdd.getDatasourceLogin().getDatasourcePlatform() instanceof XMLPlatform)) { XMLPlatform platform = new SAXPlatform(); sessionToAdd.setLogin(new XMLLogin(platform)); } DatabaseSession session = sessionToAdd.getProject().createDatabaseSession(); if (sessionToAdd.getEventManager().hasListeners()) { List listeners = sessionToAdd.getEventManager().getListeners(); int listenersSize = listeners.size(); for (int x = 0; x < listenersSize; x++) { session.getEventManager().addListener(listeners.get(x)); } } session.setExceptionHandler(sessionToAdd.getExceptionHandler()); session.setLogLevel(SessionLog.OFF); setupSession(session); if(null == sessions) { sessions = new ArrayList<>(); } if(null != this.session) { sessions.add(this.session); } sessions.add(session); storeDescriptorsByQName(session); } @Override protected void setupSession(DatabaseSession session) { session.setLogLevel(SessionLog.OFF); session.login(); setupDocumentPreservationPolicy(session); } private DatabaseSession buildSession(String sessionName, ClassLoader classLoader, XMLSessionConfigLoader sessionLoader) throws XMLMarshalException { DatabaseSession dbSession; if (classLoader != null) { dbSession = (DatabaseSession) SessionManager.getManager().getSession(sessionLoader, sessionName, classLoader, false, true); } else { dbSession = (DatabaseSession) SessionManager.getManager().getSession(sessionLoader, sessionName, privilegedGetClassLoaderForClass(this.getClass()), false, false, false); } if ((dbSession.getDatasourceLogin() == null) || !(dbSession.getDatasourceLogin().getDatasourcePlatform() instanceof XMLPlatform)) { XMLPlatform platform = new SAXPlatform(); dbSession.setLogin(new XMLLogin(platform)); } DatabaseSession session = dbSession.getProject().createDatabaseSession(); if (dbSession.getEventManager().hasListeners()) { List listeners = dbSession.getEventManager().getListeners(); int listenersSize = listeners.size(); for (int x = 0; x < listenersSize; x++) { session.getEventManager().addListener(listeners.get(x)); } } session.setExceptionHandler(dbSession.getExceptionHandler()); session.setLogLevel(SessionLog.OFF); setupDocumentPreservationPolicy(session); session.login(); return session; } @Override protected DatabaseSession getSession() { if(null == sessions) { return super.getSession(); } return sessions.get(0); } /** * INTERNAL: Return the session corresponding to this class. Since the class * may be mapped by more that one of the projects used to create the XML * Context, this method will return the first match. */ @Override protected AbstractSession getSession(Class clazz) { if (null == clazz) { return null; } if (null == sessions) { return super.getSession(clazz); } for (int x = 0, numberOfSessions = sessions.size(); x < numberOfSessions; x++) { AbstractSession next = ((AbstractSession) sessions.get(x)); if (next.getDescriptor(clazz) != null) { return next; } } throw XMLMarshalException.descriptorNotFoundInProject(clazz.getName()); } /** * INTERNAL: Return the session corresponding to this XMLDescriptor. Since * the class may be mapped by more that one of the projects used to create * the XML Context, this method will return the first match. */ @Override protected AbstractSession getSession(XMLDescriptor xmlDescriptor) { if (null == xmlDescriptor) { return null; } if(null == sessions) { return super.getSession(xmlDescriptor); } for (int x = 0, numberOfSessions = sessions.size(); x < numberOfSessions; x++) { AbstractSession next = ((AbstractSession) sessions.get(x)); if (next.getProject().getOrderedDescriptors().contains(xmlDescriptor)) { return next; } } throw XMLMarshalException.descriptorNotFoundInProject(xmlDescriptor.getJavaClass().getName()); } private List getSessions() { if(null == sessions) { return Collections.singletonList(session); } return sessions; } /** * INTERNAL: * XMLContext xmlContext = new XMLContext("path0:path1");
* DatabaseSession session = xmlContext.getSession(0); // returns session for path0
*
*/ private DatabaseSession getSession(int index) { if (null == sessions) { return session; } return sessions.get(index); } /** * INTERNAL: Return the session corresponding to this object. Since the * object may be mapped by more that one of the projects used to create the * XML Context, this method will return the first match. */ @Override protected AbstractSession getSession(Object object) { if (null == object) { return null; } if (null == sessions) { return super.getSession(object); } for (int x = 0, numberOfSessions = sessions.size(); x < numberOfSessions; x++) { AbstractSession next = ((AbstractSession) sessions.get(x)); if (next.getDescriptor(object) != null) { return next; } } throw XMLMarshalException.descriptorNotFoundInProject(object.getClass().getName()); } /** * INTERNAL: * Return true if any session held onto by this context has a document preservation * policy that requires unmarshalling from a Node. */ private boolean hasDocumentPreservation() { return this.hasDocumentPreservation; } @Override protected void preLogin(Project project, ClassLoader classLoader) { if ((project.getDatasourceLogin() == null) || !(project.getDatasourceLogin().getDatasourcePlatform() instanceof XMLPlatform)) { XMLPlatform platform = new SAXPlatform(); platform.getConversionManager().setLoader(classLoader); project.setLogin(new XMLLogin(platform)); } } private void setupDocumentPreservationPolicy(DatabaseSession session) { XMLLogin login = (XMLLogin) session.getDatasourceLogin(); if (login.getDocumentPreservationPolicy() == null) { Iterator iterator = session.getProject().getOrderedDescriptors().iterator(); while (iterator.hasNext()) { Descriptor xmlDescriptor = (Descriptor) iterator.next(); if (xmlDescriptor.shouldPreserveDocument()) { login.setDocumentPreservationPolicy(new DescriptorLevelDocumentPreservationPolicy()); break; } } } if (login.getDocumentPreservationPolicy() == null) { login.setDocumentPreservationPolicy(new NoDocumentPreservationPolicy()); } login.getDocumentPreservationPolicy().initialize(context); if (login.getDocumentPreservationPolicy().shouldPreserveDocument() && !hasDocumentPreservation) { hasDocumentPreservation = true; } } } @Override protected XMLField createField(String path) { if(null == path) { return new XMLField(); } return new XMLField(path); } /** * Returns descriptors from all sessions. * * @return descriptors from all sessions */ public List getDescriptors() { List descriptors = new ArrayList<>(); List sessions = getSessions(); for (Session session : sessions) { List orderedDescriptors = (List) session.getProject().getOrderedDescriptors(); for (Descriptor xDesc : orderedDescriptors) { descriptors.add(xDesc); } } return descriptors; } /** * Returns conversion manager from session datasource platform. * * @return conversion manager */ public ConversionManager getOxmConversionManager() { return (org.eclipse.persistence.internal.oxm.ConversionManager) getSession().getDatasourcePlatform().getConversionManager(); } /** * Returns descriptor for given object. * * @param object * @return descriptor for given object */ public Descriptor getDescriptorForObject(Object object) { Session session = getSession(object); if (null != session && null != session.getDescriptor(object)) { return (Descriptor)session.getDescriptor(object); } return null; } private static ClassLoader privilegedGetClassLoaderForClass(final Class clazz) { if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) { try { return AccessController.doPrivileged(new PrivilegedGetClassLoaderForClass(clazz)); } catch (PrivilegedActionException ex) { throw (RuntimeException) ex.getCause(); } } return PrivilegedAccessHelper.getClassLoaderForClass(clazz); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy