| /* |
| * Copyright (c) 1998, 2020 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.internal.xr; |
| |
| import static org.eclipse.persistence.internal.helper.ClassConstants.APBYTE; |
| import static org.eclipse.persistence.internal.oxm.Constants.ANY; |
| import static org.eclipse.persistence.internal.oxm.Constants.ANY_QNAME; |
| import static org.eclipse.persistence.internal.xr.Util.ALL_QUERYNAME; |
| import static org.eclipse.persistence.internal.xr.Util.COLON_CHAR; |
| import static org.eclipse.persistence.internal.xr.Util.DASH_STR; |
| import static org.eclipse.persistence.internal.xr.Util.DBWS_OR_SESSION_NAME_SUFFIX; |
| import static org.eclipse.persistence.internal.xr.Util.DBWS_OX_SESSION_NAME_SUFFIX; |
| import static org.eclipse.persistence.internal.xr.Util.DBWS_SESSIONS_XML; |
| import static org.eclipse.persistence.internal.xr.Util.META_INF_PATHS; |
| import static org.eclipse.persistence.internal.xr.Util.PK_QUERYNAME; |
| import static org.eclipse.persistence.internal.xr.Util.SLASH_CHAR; |
| import static org.eclipse.persistence.internal.xr.Util.TARGET_NAMESPACE_PREFIX; |
| import static org.eclipse.persistence.internal.xr.Util.TYPE_STR; |
| import static org.eclipse.persistence.internal.xr.Util.UNDERSCORE_STR; |
| |
| //javase imports |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| import java.io.Reader; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.Vector; |
| |
| import jakarta.persistence.SharedCacheMode; |
| import jakarta.persistence.ValidationMode; |
| import jakarta.persistence.spi.ClassTransformer; |
| import jakarta.persistence.spi.PersistenceUnitInfo; |
| import jakarta.persistence.spi.PersistenceUnitTransactionType; |
| import javax.sql.DataSource; |
| //java eXtension imports |
| import jakarta.xml.bind.JAXBContext; |
| import jakarta.xml.bind.JAXBElement; |
| import jakarta.xml.bind.JAXBException; |
| import jakarta.xml.bind.Unmarshaller; |
| import javax.xml.namespace.QName; |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.transform.Transformer; |
| import javax.xml.transform.TransformerConfigurationException; |
| import javax.xml.transform.TransformerFactory; |
| import javax.xml.transform.stream.StreamSource; |
| |
| //EclipseLink imports |
| import org.eclipse.persistence.descriptors.ClassDescriptor; |
| import org.eclipse.persistence.exceptions.DBWSException; |
| import org.eclipse.persistence.exceptions.XMLMarshalException; |
| import org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor; |
| import org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor; |
| import org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappings; |
| import org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappingsReader; |
| import org.eclipse.persistence.internal.oxm.schema.SchemaModelProject; |
| import org.eclipse.persistence.internal.oxm.schema.model.Schema; |
| import org.eclipse.persistence.internal.xr.sxf.SimpleXMLFormatProject; |
| import org.eclipse.persistence.jaxb.JAXBContextProperties; |
| import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext; |
| import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory; |
| import org.eclipse.persistence.jaxb.metadata.MetadataSource; |
| import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings; |
| import org.eclipse.persistence.logging.SessionLog; |
| import org.eclipse.persistence.mappings.DatabaseMapping; |
| 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.XMLUnmarshaller; |
| import org.eclipse.persistence.oxm.mappings.XMLBinaryDataMapping; |
| import org.eclipse.persistence.oxm.schema.XMLSchemaReference; |
| import org.eclipse.persistence.queries.DatabaseQuery; |
| import org.eclipse.persistence.sessions.DatabaseSession; |
| import org.eclipse.persistence.sessions.Project; |
| import org.eclipse.persistence.sessions.Session; |
| import org.eclipse.persistence.sessions.factories.SessionManager; |
| import org.eclipse.persistence.sessions.server.ServerSession; |
| |
| /** |
| * <p><b>INTERNAL</b>: helper class that knows how to build a {@link XRServiceAdapter} (a.k.a DBWS). An |
| * <code>XRService</code> requires the following resources: |
| * <ul> |
| * <li>metadata in the form of a descriptor file called <code><b>eclipselink-dbws.xml</b></code><br> |
| * </li> |
| * <li>an XML Schema Definition (<code>.xsd</code>) file called <code><b>eclipselink-dbws-schema.xsd</b></code> |
| * </li> |
| * <li>a TopLink <code>sessions.xml</code> file called <code><b>eclipselink-dbws-sessions.xml</b></code><br> |
| * the naming convention for the <code>sessions.xml</code> files can be overriden by the |
| * <b>optional</b> <code><sessions-file></code> entry in the <code>eclipselink-dbws.xml</code> |
| * descriptor file. |
| * </li> |
| * <li>EclipseLink metadata in the form of a EclipseLink {@link Project} (either deployment XML or Java classes). |
| * <p>A typical <code>XRService</code> requires two projects: one to represent the O-R side, the other to |
| * represent the O-X side.<br> |
| * The O-R and O-X <code>Projects</code> metadata must have:<br> |
| * i) identical case-sensitive <code>Project</code> names:<pre> |
| * <?xml version="1.0" encoding="UTF-8"?> |
| * <eclipselink:object-persistence version="Eclipse Persistence Services ..." |
| * xmlns:xsd="http://www.w3.org/2001/XMLSchema" |
| * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| * xmlns:eclipselink="http://xmlns.oracle.com/ias/xsds/eclipselink" |
| * > |
| * <eclipselink:name>example</eclipselink:name> |
| * or |
| * ... |
| * import org.eclipse.persistence.sessions.Project; |
| * public class SomeORProject extends Project { |
| * public SomeORProject () { |
| * setName("Example"); |
| * ... |
| * } |
| * public class SomeOXProject extends Project { |
| * public SomeOXProject () { |
| * setName("Example"); |
| * ... |
| * } |
| * </pre> |
| * ii) identical case-sensitive aliases for {@link ClassDescriptor Descriptors} that are common |
| * between the projects: |
| * <pre> |
| * <eclipselink:class-mapping-descriptor xsi:type="eclipselink:relational-class-mapping-descriptor"> |
| * <eclipselink:class>some.package.SomeClass</eclipselink:class> |
| * <eclipselink:alias>SomeAlias</eclipselink:alias> |
| * ... |
| * <eclipselink:class-mapping-descriptor xsi:type="eclipselink:xml-class-mapping-descriptor"> |
| * <eclipselink:class>some.package.SomeClass</eclipselink:class> |
| * <eclipselink:alias>SomeAlias</eclipselink:alias> |
| * </pre> |
| * </li> |
| * </ul> |
| * An example <code><b>eclipselink-dbws.xml</b></code> descriptor file: |
| * <pre> |
| * <?xml version="1.0" encoding="UTF-8"?> |
| * <dbws |
| * xmlns:xsd="http://www.w3.org/2001/XMLSchema" |
| * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| * > |
| * <name>example</name> |
| * <sessions-file>example-dbws-sessions.xml</sessions-file> |
| * <query> |
| * <name>countEmployees</name> |
| * <result> |
| * <type>xsd:int</type> |
| * <simple-xml-format> |
| * <simple-xml-format-tag>employee-info</simple-xml-format-tag> |
| * <simple-xml-tag>aggregate-info</simple-xml-tag> |
| * </simple-xml-format> |
| * </result> |
| * <sql><![CDATA[select count(*) from EMP]]></sql> |
| * </query> |
| * <query> |
| * <name>findAllEmployees</name> |
| * <result isCollection="true"> |
| * <type>empType</type> |
| * </result> |
| * <sql><![CDATA[select * from EMP]]></sql> |
| * </query> |
| * </dbws> |
| * </pre> |
| */ |
| public class XRServiceFactory { |
| public XRServiceAdapter xrService; |
| public ClassLoader parentClassLoader; |
| public InputStream xrSchemaStream; |
| |
| static final String XMLNS_STR = "xmlns"; |
| static final String XML_BINDINGS_STR = "xml-bindings"; |
| static final String ORM_MAPPINGS_STR = "orm-mappings"; |
| static final String DOM_PLATFORM_CLASSNAME = "org.eclipse.persistence.oxm.platform.DOMPlatform"; |
| static final String OXM_PROCESSING_EX = "An exception occurred processing OXM metadata"; |
| static final String ORM_PROCESSING_EX = "An exception occurred processing ORM metadata"; |
| static final String OXM_PROCESSING_SCH = "An exception occurred processing schema definitions"; |
| static final String OX_PRJ_SUFFIX = "-dbws-ox"; |
| static final String OR_PRJ_SUFFIX = "-dbws-or"; |
| static final String DEFAULT_PROJECT_NAME = "org.eclipse.persistence.sessions.Project"; |
| static final String COLLECTION_WRAPPER_STR = UNDERSCORE_STR + org.eclipse.persistence.internal.xr.Util.COLLECTION_WRAPPER_STR; |
| static final String SIMPLE_XML_FORMAT_STR = "simple-xml-format"; |
| |
| public XRServiceFactory() { |
| super(); |
| } |
| |
| public XRServiceAdapter buildService() { |
| initializeService(parentClassLoader, xrSchemaStream); |
| return xrService; |
| } |
| |
| public XRServiceAdapter buildService(XRServiceModel xrServiceModel) { |
| xrService = new XRServiceAdapter(); |
| xrService.setName(xrServiceModel.getName()); |
| xrService.setSessionsFile(xrServiceModel.getSessionsFile()); |
| xrService.setOperations(xrServiceModel.getOperations()); |
| initializeService(parentClassLoader, xrSchemaStream); |
| return xrService; |
| } |
| |
| /** |
| * <p><b>INTERNAL</b>: Initialize the various components (of the <code>XRService</code>} |
| * (O-R Project, O-X Project, Schema definitions, auto-generated classes, etc.) |
| * @param parentClassLoader the parent <code>ClassLoader</code> for the auto-generated classes. |
| * @param xrSchemaStream stream resource for the <code>XRService</code>'s <code>.xsd</code> file. |
| */ |
| public void initializeService(ClassLoader parentClassLoader, InputStream xrSchemaStream) { |
| this.parentClassLoader = parentClassLoader; |
| this.xrSchemaStream = xrSchemaStream; |
| loadXMLSchema(xrSchemaStream); |
| logoutSessions(); |
| buildSessions(); |
| customizeSession(xrService.orSession, xrService.oxSession); |
| buildDescriptorIndex(); |
| validateOperations(); |
| initializeOperations(); |
| loginSessions(); |
| } |
| |
| @SuppressWarnings("unused") |
| public void customizeSession(Session orSession, Session oxSession) { |
| } |
| |
| /** |
| * <p>INTERNAL: |
| * Read and unmarshal <code>XRService</code>'s <code>.xsd</code> file. |
| * @param xrSchemaStream Stream resource for the <code>XRService</code>'s <code>.xsd</code> file. |
| */ |
| public void loadXMLSchema(InputStream xrSchemaStream) { |
| SchemaModelProject schemaProject = new SchemaModelProject(); |
| XMLContext xmlContext = new XMLContext(schemaProject); |
| XMLUnmarshaller unmarshaller = xmlContext.createUnmarshaller(); |
| Schema schema; |
| try { |
| schema = (Schema)unmarshaller.unmarshal(xrSchemaStream); |
| } catch (XMLMarshalException e) { |
| xmlContext.getSession().getSessionLog().log( |
| SessionLog.WARNING, SessionLog.DBWS, "dbws_xml_schema_read_error", e.getLocalizedMessage()); |
| throw new DBWSException(OXM_PROCESSING_SCH, e); |
| } |
| NamespaceResolver nr = schema.getNamespaceResolver(); |
| String targetNamespace = schema.getTargetNamespace(); |
| nr.put(TARGET_NAMESPACE_PREFIX, targetNamespace); |
| xrService.schema = schema; |
| xrService.schemaNamespace = targetNamespace; |
| } |
| |
| /** |
| * <p>INTERNAL: |
| * Create a Project using ORM metadata. The given classloader is expected |
| * to successfully load 'META-INF/eclipselink-dbws-or.xml'. |
| * @param xrdecl {@link ClassLoader} used to search for {@code eclipselink-dbws-or.xml}. |
| * @param session ORM session. |
| */ |
| protected Project loadORMetadata(final XRDynamicClassLoader xrdecl, final ServerSession session) { |
| Project orProject = null; |
| String searchPath = null; |
| InputStream inStream = null; |
| |
| // try "META-INF/" and "/META-INF/" |
| for (String prefix : META_INF_PATHS) { |
| searchPath = prefix + Util.DBWS_OR_XML; |
| inStream = xrdecl.getResourceAsStream(searchPath); |
| if (inStream != null) { |
| break; |
| } |
| } |
| |
| try { |
| if (inStream != null) { |
| MetadataProcessor processor = new MetadataProcessor(new XRPersistenceUnitInfo(xrdecl), |
| session, xrdecl, false, true, false, false, false, null, null); |
| processor.setMetadataSource(new JPAMetadataSource(xrdecl, new InputStreamReader(inStream))); |
| PersistenceUnitProcessor.processORMetadata(processor, true, PersistenceUnitProcessor.Mode.ALL); |
| processor.addNamedQueries(); |
| orProject = processor.getProject().getProject(); |
| orProject.setName(xrService.getName().concat(OR_PRJ_SUFFIX)); |
| } |
| } catch (Exception pupex) { |
| /* could be legacy project, or none set, so just log */ |
| session.log(SessionLog.FINE, SessionLog.DBWS, "dbws_orm_metadata_read_error", pupex.getLocalizedMessage()); |
| } |
| return orProject; |
| } |
| |
| /** |
| * <p>INTERNAL: |
| * Create a Project using OXM metadata. The given classloader is expected |
| * to successfully load 'META-INF/eclipselink-dbws-ox.xml'. |
| * @param xrdecl {@link ClassLoader} used to search for {@code eclipselink-dbws-ox.xml}. |
| * @param session OXM session (only for logging). |
| */ |
| protected Project loadOXMetadata(final ClassLoader xrdecl, final Session session) { |
| Project oxProject = null; |
| InputStream inStream = null; |
| String searchPath = null; |
| |
| // try "META-INF/" and "/META-INF/" |
| for (String prefix : META_INF_PATHS) { |
| searchPath = prefix + Util.DBWS_OX_XML; |
| inStream = xrdecl.getResourceAsStream(searchPath); |
| if (inStream != null) { |
| break; |
| } |
| } |
| if (inStream != null) { |
| Map<String, OXMMetadataSource> metadataMap = null; |
| StreamSource xml = new StreamSource(inStream); |
| try { |
| JAXBContext jc = JAXBContext.newInstance(XmlBindingsModel.class); |
| Unmarshaller unmarshaller = jc.createUnmarshaller(); |
| |
| JAXBElement<XmlBindingsModel> jaxbElt = unmarshaller.unmarshal(xml, XmlBindingsModel.class); |
| XmlBindingsModel model = jaxbElt.getValue(); |
| if (model.getBindingsList() != null) { |
| metadataMap = new HashMap<String, OXMMetadataSource>(); |
| for (XmlBindings xmlBindings : model.getBindingsList()) { |
| metadataMap.put(xmlBindings.getPackageName(), new OXMMetadataSource(xmlBindings)); |
| } |
| } |
| } catch (JAXBException jaxbex) { |
| /* could be legacy project, or none set, so just log */ |
| session.getSessionLog().log( |
| SessionLog.FINE, SessionLog.DBWS, "dbws_oxm_metadata_read_error", jaxbex.getLocalizedMessage()); |
| return null; |
| } |
| |
| if (metadataMap != null) { |
| Map<String, Map<String, OXMMetadataSource>> properties = new HashMap<String, Map<String, OXMMetadataSource>>(); |
| properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, metadataMap); |
| try { |
| DynamicJAXBContext jCtx = DynamicJAXBContextFactory.createContextFromOXM(xrdecl, properties); |
| oxProject = jCtx.getXMLContext().getSession(0).getProject(); |
| oxProject.setName(xrService.getName().concat(OX_PRJ_SUFFIX)); |
| } catch (JAXBException e) { |
| throw new DBWSException(OXM_PROCESSING_EX, e); |
| } |
| } |
| } |
| return oxProject; |
| } |
| |
| /** |
| * <p>INTERNAL: |
| * |
| * Perform any post-load descriptor modifications, such as altering attribute classification |
| * on a given mapping, or converting class names to classes. In addition, JAXB and JPA |
| * Embeddables will have the descriptor alias set to the class name (w/o package), which |
| * will contain an upper case first character, meaning that the OR/OX descriptors will |
| * have to be aligned in some cases. |
| */ |
| protected static void prepareDescriptors(Project oxProject, Project orProject, XRDynamicClassLoader xrdcl) { |
| // step one: remove default dummy alias descriptor (i.e. alias = "") |
| if (orProject.getAliasDescriptors() != null) { |
| orProject.getAliasDescriptors().remove(""); |
| } |
| |
| // step two: align OR/OX alias names, handle JAXB DataHandler issue, and convert OR class names to classes |
| if (oxProject.getAliasDescriptors() != null) { |
| for (Object alias : oxProject.getAliasDescriptors().keySet()) { |
| if (alias.equals(SIMPLE_XML_FORMAT_STR)) { |
| continue; |
| } |
| // workaround for JAXB validation: JAXB expects a DataHandler in the |
| // object model for SwaRef, whereas we want to work with a byte[] |
| XMLDescriptor xdesc = (XMLDescriptor) oxProject.getAliasDescriptors().get(alias); |
| for (DatabaseMapping mapping : xdesc.getMappings()) { |
| if (mapping instanceof XMLBinaryDataMapping) { |
| ((XMLBinaryDataMapping) mapping).setAttributeClassification(APBYTE); |
| ((XMLBinaryDataMapping) mapping).setAttributeClassificationName(APBYTE.getName()); |
| } |
| } |
| // convert class names to classes on the associated OR descriptor |
| ClassDescriptor odesc = (ClassDescriptor) orProject.getAliasDescriptors().get(alias); |
| if (odesc != null) { // shouldn't be null... |
| // step three: align OR alias and ordered descriptors (alias names and mappings) |
| ClassDescriptor orderedDescriptor = getDescriptorForClassName(orProject, odesc.getJavaClassName()); |
| if (orderedDescriptor != null) { |
| orderedDescriptor.setAlias(alias.toString()); |
| //orderedDescriptor.setJavaClass(odesc.getJavaClass()); |
| orderedDescriptor.setJavaClassName(odesc.getJavaClassName()); |
| // need to convert class names to classes such that reference classes, etc are setup |
| orderedDescriptor.convertClassNamesToClasses(xrdcl); |
| // replace the incomplete descriptor in the alias map with this one |
| orProject.addAlias(orderedDescriptor.getAlias(), orderedDescriptor); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Returns a ClassDescriptor from the given project with the matching javaClassName, |
| * or null if not found. |
| */ |
| protected static ClassDescriptor getDescriptorForClassName(Project project, String javaClassName) { |
| for (ClassDescriptor cd : project.getOrderedDescriptors()) { |
| if (cd != null && cd.getJavaClassName().equals(javaClassName)) { |
| return cd; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * <p>INTERNAL: |
| */ |
| @SuppressWarnings("rawtypes") |
| public void buildSessions() { |
| XRDynamicClassLoader projectLoader = new XRDynamicClassLoader(parentClassLoader); |
| |
| SessionManager sessionManager = SessionManager.getManager(); |
| boolean found = false; |
| String sessionsFile = xrService.sessionsFile == null ? DBWS_SESSIONS_XML : xrService.sessionsFile; |
| for (String prefix : META_INF_PATHS) { |
| String searchPath = prefix + sessionsFile; |
| XRSessionConfigLoader loader = new XRSessionConfigLoader(searchPath); |
| loader.setShouldLogin(false); |
| try { |
| found = loader.load(sessionManager, projectLoader); |
| } catch (RuntimeException e) { /* ignore */ |
| } |
| if (found) { |
| break; |
| } |
| } |
| if (!found) { |
| throw DBWSException.couldNotLocateFile(DBWS_SESSIONS_XML); |
| } |
| |
| // make sure the OR/OX sessions were loaded successfully |
| Map sessions = sessionManager.getSessions(); |
| String orSessionKey = xrService.name + DASH_STR + DBWS_OR_SESSION_NAME_SUFFIX; |
| if (!sessions.containsKey(orSessionKey)) { |
| throw DBWSException.couldNotLocateORSessionForService(xrService.name); |
| } |
| String oxSessionKey = xrService.name + DASH_STR + DBWS_OX_SESSION_NAME_SUFFIX; |
| if (!sessions.containsKey(oxSessionKey)) { |
| throw DBWSException.couldNotLocateOXSessionForService(xrService.name); |
| } |
| xrService.orSession = (Session) sessions.get(orSessionKey); |
| xrService.oxSession = (Session) sessions.get(oxSessionKey); |
| |
| // load OX project via xml-bindings |
| Project oxProject = null; |
| if ((oxProject = loadOXMetadata(projectLoader, xrService.oxSession)) == null) { |
| // at this point we may have a legacy deployment XML project, or none set |
| oxProject = xrService.oxSession.getProject(); |
| // check to see if it's a default Project |
| if (oxProject.getName().length() == 0) { |
| // default to SimpleXMLFormat |
| oxProject = new SimpleXMLFormatProject(); |
| } |
| } |
| ((XMLLogin) oxProject.getDatasourceLogin()).setPlatformClassName(DOM_PLATFORM_CLASSNAME); |
| ((XMLLogin) oxProject.getDatasourceLogin()).setEqualNamespaceResolvers(false); |
| |
| // load OR project via entity-mappings |
| Project orProject = null; |
| if ((orProject = loadORMetadata(projectLoader, (ServerSession) xrService.orSession)) == null) { |
| // at this point we may have a legacy deployment XML project, or none set |
| orProject = xrService.orSession.getProject(); |
| updateFindQueryNames(orProject); |
| } |
| |
| prepareDescriptors(oxProject, orProject, projectLoader); |
| ProjectHelper.fixOROXAccessors(orProject, oxProject); |
| |
| xrService.xmlContext = new XMLContext(oxProject); |
| xrService.oxSession = xrService.xmlContext.getSession(0); |
| } |
| |
| /** |
| * <p>INTERNAL: |
| */ |
| public void loginSessions() { |
| ((DatabaseSession)xrService.orSession).login(); |
| // the oxSession is already logged-in... |
| } |
| |
| /** |
| * <p>INTERNAL: |
| */ |
| @SuppressWarnings("rawtypes") |
| public void buildDescriptorIndex() { |
| for (Iterator i = xrService.oxSession.getProject().getOrderedDescriptors().iterator(); |
| i.hasNext();) { |
| XMLDescriptor xd = (XMLDescriptor)i.next(); |
| XMLSchemaReference schemaReference = xd.getSchemaReference(); |
| if (schemaReference != null && schemaReference.getType() == XMLSchemaReference.COMPLEX_TYPE) { |
| String context = schemaReference.getSchemaContext(); |
| if (context != null && context.lastIndexOf(SLASH_CHAR) == 0) { |
| String elementNameNS = context.substring(1); |
| QName elementName = resolveName(elementNameNS, xd.getNamespaceResolver()); |
| if (elementName == null) { |
| continue; |
| } |
| xrService.descriptorsByQName.put(elementName, xd); |
| } |
| } |
| } |
| } |
| |
| /** |
| * <p>INTERNAL: |
| */ |
| public void validateOperations() { |
| for (Operation operation : xrService.getOperationsList()) { |
| operation.validate(xrService); |
| } |
| } |
| |
| /** |
| * <p>INTERNAL: |
| */ |
| public void initializeOperations() { |
| for (Operation operation : xrService.getOperationsList()) { |
| operation.initialize(xrService); |
| } |
| } |
| |
| /** |
| * <p>INTERNAL: |
| */ |
| protected void logoutSessions() { |
| SessionManager manager = SessionManager.getManager(); |
| @SuppressWarnings("rawtypes") |
| Map sessions = manager.getSessions(); |
| String orSessionName = xrService.name + DASH_STR + DBWS_OR_SESSION_NAME_SUFFIX; |
| Session orSession = (Session)sessions.remove(orSessionName); |
| if (orSession != null && orSession.isConnected()) { |
| ((DatabaseSession)orSession).logout(); |
| } |
| String oxSessionName = xrService.name + DASH_STR + DBWS_OX_SESSION_NAME_SUFFIX; |
| sessions.remove(oxSessionName); |
| xrService.orSession = null; |
| xrService.oxSession = null; |
| } |
| |
| /** |
| * <p>INTERNAL: |
| * |
| */ |
| protected QName resolveName(String name, NamespaceResolver ns) { |
| if (ns == null) { |
| return null; |
| } |
| if (ANY.equals(name)) { |
| return ANY_QNAME; |
| } |
| int index = name.indexOf(COLON_CHAR); |
| if (index != -1) { |
| String uri = ns.resolveNamespacePrefix(name.substring(0, index)); |
| return new QName(uri, name.substring(index + 1)); |
| } |
| if (ns.getDefaultNamespaceURI() != null) { |
| return new QName(ns.getDefaultNamespaceURI(), name); |
| } |
| String uri = ns.resolveNamespacePrefix(XMLNS_STR); |
| return new QName(uri, name); |
| } |
| |
| public static DocumentBuilder getDocumentBuilder() { |
| DocumentBuilder db = null; |
| try { |
| DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); |
| dbf.setNamespaceAware(true); |
| db = dbf.newDocumentBuilder(); |
| } |
| catch (ParserConfigurationException e) { |
| /* extremely rare, safe to ignore */ |
| } |
| return db; |
| } |
| |
| public static Transformer getTransformer() { |
| Transformer transformer = null; |
| try { |
| TransformerFactory tf = TransformerFactory.newInstance(); |
| transformer = tf.newTransformer(); |
| } |
| catch (TransformerConfigurationException e) { |
| /* extremely rare, safe to ignore */ |
| } |
| return transformer; |
| } |
| |
| /** |
| * <p>INTERNAL: |
| * |
| * Legacy projects have 'findAll' and 'findByPrimaryKey' queries, whereas we now |
| * expect these to have the descriptor alias appended (preceded with underscore), |
| * + 'Type'. For example, if we have an Employee descriptor, the find queries |
| * would be: 'findAll_employeeType' and 'findByPrimaryKey_employeeType'. |
| * |
| */ |
| @SuppressWarnings("rawtypes") |
| protected static void updateFindQueryNames(Project orProject) { |
| for (ClassDescriptor orDesc : orProject.getDescriptors().values()) { |
| Vector queries = orDesc.getQueryManager().getAllQueries(); |
| for (int i=0; i<queries.size(); i++) { |
| DatabaseQuery query = (DatabaseQuery) queries.get(i); |
| String qName = query.getName(); |
| String END_PART = UNDERSCORE_STR + query.getDescriptor().getAlias() + TYPE_STR; |
| if ((PK_QUERYNAME.equals(qName) || ALL_QUERYNAME.equals(qName)) && !qName.endsWith(END_PART)) { |
| orDesc.getQueryManager().addQuery(qName + END_PART, query); |
| } |
| } |
| } |
| } |
| |
| // Made static final for performance reasons. |
| /** |
| * <p>INTERNAL: |
| * |
| * Implementation of MetadataSource to allow passing XmlBindings |
| * to the DynamicJAXBContextFactory |
| * |
| */ |
| public static final class OXMMetadataSource implements MetadataSource { |
| XmlBindings xmlbindings; |
| |
| public OXMMetadataSource(XmlBindings bindings) { |
| xmlbindings = bindings; |
| } |
| |
| @Override |
| public XmlBindings getXmlBindings(Map<String, ?> properties, ClassLoader classLoader) { |
| return xmlbindings; |
| } |
| } |
| |
| // Made static final for performance reasons. |
| /** |
| * <p>INTERNAL: |
| * |
| * Implementation of MetadataSource to allow passing JPA metadata to the |
| * MetadataProcessor. |
| * |
| */ |
| public static final class JPAMetadataSource implements org.eclipse.persistence.jpa.metadata.MetadataSource { |
| XRDynamicClassLoader xrdecl; |
| Reader reader; |
| |
| public JPAMetadataSource(XRDynamicClassLoader loader, Reader reader) { |
| xrdecl = loader; |
| this.reader = reader; |
| } |
| |
| @Override |
| public Map<String, Object> getPropertyOverrides(Map<String, Object> properties, ClassLoader classLoader, SessionLog log) { |
| return null; |
| } |
| |
| @Override |
| public XMLEntityMappings getEntityMappings(Map<String, Object> properties, ClassLoader classLoader, SessionLog log) { |
| return XMLEntityMappingsReader.read(ORM_MAPPINGS_STR, reader, xrdecl, null); |
| } |
| } |
| |
| // Made static final for performance reasons. |
| /** |
| * <p>INTERNAL: |
| * |
| * PersistenceUnitInfo implementation to allow creation of a MetadataProcessor |
| * instance. Other than an XRDynamicClassLoader instance, all methods return |
| * null, empty lists, etc. |
| * |
| */ |
| public static final class XRPersistenceUnitInfo implements PersistenceUnitInfo { |
| XRDynamicClassLoader xrdecl; |
| public XRPersistenceUnitInfo(XRDynamicClassLoader loader) { |
| xrdecl = loader; |
| } |
| @Override |
| public PersistenceUnitTransactionType getTransactionType() { return null; } |
| @Override |
| public Properties getProperties() { return new Properties(); } |
| @Override |
| public URL getPersistenceUnitRootUrl() { return null; } |
| @Override |
| public String getPersistenceUnitName() { return null; } |
| @Override |
| public String getPersistenceProviderClassName() { return null; } |
| @Override |
| public DataSource getNonJtaDataSource() { return null; } |
| @Override |
| public ClassLoader getNewTempClassLoader() { return xrdecl; } |
| @Override |
| public List<String> getMappingFileNames() { return new ArrayList<String>(); } |
| @Override |
| public List<String> getManagedClassNames() { return new ArrayList<String>(); } |
| @Override |
| public DataSource getJtaDataSource() { return null; } |
| @Override |
| public List<URL> getJarFileUrls() { return new ArrayList<URL>(); } |
| @Override |
| public ClassLoader getClassLoader() { return xrdecl; } |
| @Override |
| public boolean excludeUnlistedClasses() { return false; } |
| @Override |
| public void addTransformer(ClassTransformer arg0) { } |
| @Override |
| public SharedCacheMode getSharedCacheMode() { return null; } |
| @Override |
| public ValidationMode getValidationMode() { return null; } |
| @Override |
| public String getPersistenceXMLSchemaVersion() { return null; } |
| } |
| } |