/*
 * 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 = 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 = 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; }
    }
}
