blob: ec8c1ea543aa1222176f8df32daa75fdb65b6920 [file] [log] [blame]
/*
* 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.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>
* &nbsp; the naming convention for the <code>sessions.xml</code> files can be overriden by the
* <b>optional</b> <code>&lt;sessions-file&gt;</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>
* &lt;?xml version="1.0" encoding="UTF-8"?&gt;
* &lt;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"
* &gt;
* &lt;eclipselink:name&gt;example&lt;/eclipselink:name&gt;
* 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>
* &lt;eclipselink:class-mapping-descriptor xsi:type="eclipselink:relational-class-mapping-descriptor"&gt;
* &lt;eclipselink:class&gt;some.package.SomeClass&lt;/eclipselink:class&gt;
* &lt;eclipselink:alias&gt;SomeAlias&lt;/eclipselink:alias&gt;
* ...
* &lt;eclipselink:class-mapping-descriptor xsi:type="eclipselink:xml-class-mapping-descriptor"&gt;
* &lt;eclipselink:class&gt;some.package.SomeClass&lt;/eclipselink:class&gt;
* &lt;eclipselink:alias&gt;SomeAlias&lt;/eclipselink:alias&gt;
* </pre>
* </li>
* </ul>
* An example <code><b>eclipselink-dbws.xml</b></code> descriptor file:
* <pre>
* &lt;?xml version="1.0" encoding="UTF-8"?&gt;
* &lt;dbws
* xmlns:xsd="http://www.w3.org/2001/XMLSchema"
* xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
* &gt;
* &lt;name&gt;example&lt;/name&gt;
* &lt;sessions-file&gt;example-dbws-sessions.xml&lt;/sessions-file&gt;
* &lt;query&gt;
* &lt;name&gt;countEmployees&lt;/name&gt;
* &lt;result&gt;
* &lt;type&gt;xsd:int&lt;/type&gt;
* &lt;simple-xml-format&gt;
* &lt;simple-xml-format-tag&gt;employee-info&lt;/simple-xml-format-tag&gt;
* &lt;simple-xml-tag&gt;aggregate-info&lt;/simple-xml-tag&gt;
* &lt;/simple-xml-format&gt;
* &lt;/result&gt;
* &lt;sql&gt;&lt;![CDATA[select count(*) from EMP]]&gt;&lt;/sql&gt;
* &lt;/query&gt;
* &lt;query&gt;
* &lt;name&gt;findAllEmployees&lt;/name&gt;
* &lt;result isCollection="true"&gt;
* &lt;type&gt;empType&lt;/type&gt;
* &lt;/result&gt;
* &lt;sql&gt;&lt;![CDATA[select * from EMP]]&gt;&lt;/sql&gt;
* &lt;/query&gt;
* &lt;/dbws&gt;
* </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;
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;
// 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<>();
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<>();
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 = 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;
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;
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:
*/
public void buildDescriptorIndex() {
for (Iterator<ClassDescriptor> 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<>(); }
@Override
public List<String> getManagedClassNames() { return new ArrayList<>(); }
@Override
public DataSource getJtaDataSource() { return null; }
@Override
public List<URL> getJarFileUrls() { return new ArrayList<>(); }
@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; }
}
}