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

org.eclipse.persistence.sessions.factories.XMLSessionConfigLoader Maven / Gradle / Ivy

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

import java.io.File;
import java.net.URL;
import java.util.Map;
import java.util.Vector;

import org.eclipse.persistence.exceptions.SessionLoaderException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
import org.eclipse.persistence.internal.sessions.factories.PersistenceEntityResolver;
import org.eclipse.persistence.internal.sessions.factories.SessionsFactory;
import org.eclipse.persistence.internal.sessions.factories.XMLSessionConfigProject_11_1_1;
import org.eclipse.persistence.internal.sessions.factories.XMLSessionConfigToplinkProject;
import org.eclipse.persistence.internal.sessions.factories.model.SessionConfigs;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.platform.xml.XMLParser;
import org.eclipse.persistence.platform.xml.XMLPlatform;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.Session;
import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

/**
 * Provide a mechanism for loading Session configuration XML files.
 * This is used by the SessionManager to define how to find and load a Session from a sessions XML file.
 * The sessions XML file is typically deployed in the applications jar (ejb-jar) and named sessions.xml in the /META-INF directory.
 * Several loading options are provided,
 * 
    *
  • resourceName : The resource path and file name to the sessions XML file, * default is /sessions.xml or /META-INF/sessions.xml. (ensure "/" is used, not "\"). * A file path can also be provided, although a resource is typically used. *
  • shouldLogin : Define if the loaded session should be connected, default true. *
  • shouldRefresh : Define if the loaded session should be refreshed from the file, * (this old session will be disconnected) default false. *
  • classLoader : Define the class loader that should be used to find the resource. * This loader will also be used as the loaded session's class loader. This should be the application's class loader. * Default is the ConversionManager loader, which is thread-based. *
  • shouldCheckClassLoader : Defines if the session will be refreshed from the file if the class loader requesting the load, * is different than the loaded session's class loader. This can be used to handle re-deployment. *
* * @since TopLink 10.1.3 * @author Guy Pelletier */ public class XMLSessionConfigLoader { protected String resourceName; /** Stores the resource path to provide a better error message if the load fails. */ protected String resourcePath = DEFAULT_RESOURCE_NAME; /** Stores the name of the Session in the sessions XML file desired to be loaded. */ protected String sessionName = "default"; /** Define if the loaded session should be connected, default true. */ protected boolean shouldLogin = true; /** Define if the loaded session should be refreshed from the file. */ protected boolean shouldRefresh = false; /** Define the class loader that should be used to find the resource. */ protected ClassLoader classLoader; /** Defines if the session will be refreshed from the file if the class loader requesting the load is different than the loaded session's class loader. */ protected boolean shouldCheckClassLoader = false; /** Stores any exceptions that occurred to provide all the exceptions up front if the load fails. */ protected Vector exceptionStore; /** Used to store the entity resolver to validate the XML schema when parsing. */ protected PersistenceEntityResolver entityResolver; public static final String ECLIPSELINK_SESSIONS_SCHEMA = "org/eclipse/persistence/eclipselink_sessions_2.1.xsd"; protected static final String DEFAULT_RESOURCE_NAME = "sessions.xml"; protected static final String DEFAULT_RESOURCE_NAME_IN_META_INF = "META-INF/sessions.xml"; /** Cache the creation and initialization of the Session XML mapping project. */ protected static final Project project = new XMLSessionConfigProject_11_1_1(); /** Cache the creation and initialization of the Session XML mapping project. */ protected static Project getProject() { return project; } /** * PUBLIC: * This constructor is used when the file resource named 'sessions.xml' will * be parsed for configuration. */ public XMLSessionConfigLoader() { this(DEFAULT_RESOURCE_NAME); } /** * PUBLIC: * This constructor is used when passing in the resource name of the * configuration file that should be parsed */ public XMLSessionConfigLoader(String resourceName) { this.resourceName = resourceName; this.exceptionStore = new Vector<>(); this.entityResolver = new PersistenceEntityResolver(); this.classLoader = ConversionManager.getDefaultManager().getLoader(); } /** * INTERNAL: * Will return the the resource name with full path of the resource file. */ public String getResourcePath() { return this.resourcePath; } /** * INTERNAL: */ public Vector getExceptionStore() { return this.exceptionStore; } /** * PUBLIC: * Returns the resource name we are trying to load. */ public String getResourceName() { return this.resourceName; } /** * PUBLIC: * Set the resource name we are trying to load. */ public void setResourceName(String resourceName) { this.resourceName = resourceName; } /** * PUBLIC: * Returns the name of the Session in the sessions XML file desired to be loaded. */ public String getSessionName() { return this.sessionName; } /** * PUBLIC: * Set the name of the Session in the sessions XML file desired to be loaded. */ public void setSessionName(String sessionName) { this.sessionName = sessionName; } /** * PUBLIC: * Return if the loaded session should be connected. */ public boolean shouldLogin() { return shouldLogin; } /** * PUBLIC: * Set if the loaded session should be connected. */ public void setShouldLogin(boolean shouldLogin) { this.shouldLogin = shouldLogin; } /** * PUBLIC: * Return if the loaded session should be refreshed from the file. */ public boolean shouldRefresh() { return shouldRefresh; } /** * PUBLIC: * Set if the loaded session should be refreshed from the file. */ public void setShouldRefresh(boolean shouldRefresh) { this.shouldRefresh = shouldRefresh; } /** * PUBLIC: * Return if the session will be refreshed from the file if the class loader requesting the load is different than the loaded session's class loader. */ public boolean shouldCheckClassLoader() { return shouldCheckClassLoader; } /** * PUBLIC: * Set if the session will be refreshed from the file if the class loader requesting the load is different than the loaded session's class loader. */ public void setShouldCheckClassLoader(boolean shouldCheckClassLoader) { this.shouldCheckClassLoader = shouldCheckClassLoader; } /** * PUBLIC: * Return the class loader that should be used to find the resource. */ public ClassLoader getClassLoader() { return classLoader; } /** * PUBLIC: * Set the class loader that should be used to find the resource. */ public void setClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; } /** * INTERNAL: * This method instantiates the parser and builds the document based on the * schema. If the document is loaded without errors, then the configs are * converted to sessions and stored on the session manager and true is * returned to indicate success. */ public boolean load(SessionManager sessionManager, ClassLoader loader) { Document document = loadDocument(loader); if(getExceptionStore().isEmpty()){ if (document.getDocumentElement().getTagName().equals("sessions")) { return buildSessionConfigs(sessionManager,loader,document,getProject()); } }else{ //upon this time, we knew this could be either toplink sessions.xml or invalid eclipse session.xml. if(document.getDocumentElement().getTagName().equals("toplink-sessions")){ return buildSessionConfigs(sessionManager,loader,document,new XMLSessionConfigToplinkProject()); }else{ // Throw the exceptions we encountered throw SessionLoaderException.finalException(getExceptionStore()); } } // 9.0.4 session.xml, return false to indicate we should load with the XMLLoader return false; } private boolean buildSessionConfigs(SessionManager sessionManager, ClassLoader loader,Document document, Project project){ // No errors occurred, unmasrshal the document which will return a // SessionConfigs containing 0 or more SessionConfigs and send // them through the factory to create actual Sessions XMLContext context = new XMLContext(project); XMLUnmarshaller unmarshaller = context.createUnmarshaller(); SessionConfigs configs = (SessionConfigs)unmarshaller.unmarshal(document); SessionsFactory factory = new SessionsFactory(); Map sessions = factory.buildSessionConfigs(configs, loader); for (Map.Entry entry: sessions.entrySet()) { // Only add the session if missing. if (!sessionManager.getSessions().containsKey(entry.getKey())) { sessionManager.addSession(entry.getKey(), entry.getValue()); } } return true; } /** * INTERNAL: * This method is to be used to load config objects for the Mapping Workbench * only. Do not call this method. */ public SessionConfigs loadConfigsForMappingWorkbench(ClassLoader loader) { return loadConfigsForMappingWorkbench(loader, true); } /** * INTERNAL: * This method is to be used to load config objects for the Mapping Workbench * only. Do not call this method. */ public SessionConfigs loadConfigsForMappingWorkbench(ClassLoader loader, boolean validate) { Document document = loadDocument(loader, validate); if (getExceptionStore().isEmpty()) { if (document.getDocumentElement().getTagName().equals("sessions")) { // No errors occurred, unmarshal the document which will return a // SessionConfigs containing 0 or more SessionConfigs XMLContext context = new XMLContext(getProject()); XMLUnmarshaller unmarshaller = context.createUnmarshaller(); return (SessionConfigs)unmarshaller.unmarshal(document); }else{ // 9.0.4 session.xml or invalid xml format. throw SessionLoaderException.InvalidSessionXML(); } } else { if (document.getDocumentElement().getTagName().equals("toplink-sessions")) { // No errors occurred, unmarshal the document which will return a // SessionConfigs containing 0 or more SessionConfigs XMLContext context = new XMLContext(new XMLSessionConfigToplinkProject()); XMLUnmarshaller unmarshaller = context.createUnmarshaller(); return (SessionConfigs)unmarshaller.unmarshal(document); }else{ // Throw the exceptions we encountered throw SessionLoaderException.finalException(getExceptionStore()); } } } /** * INTERNAL: * Load a session.xml document. The error handler will capture all the * errors and allow for a document to be returned. */ protected Document loadDocument(ClassLoader loader) { return loadDocument(loader, SessionManager.shouldUseSchemaValidation()); } /** * INTERNAL: * Load a session.xml document. The error handler will capture all the * errors and allow for a document to be returned. */ protected Document loadDocument(ClassLoader loader, boolean validate) { URL inURL = loader.getResource(this.resourceName); // Also allow a file reference. File inFile = new File(this.resourceName); if (inURL == null) { // If loading the default resource name and it is not found, // look in the META-INF directory. if (this.resourceName.equals(DEFAULT_RESOURCE_NAME)) { inURL = loader.getResource(DEFAULT_RESOURCE_NAME_IN_META_INF); } if ((inURL == null) && (!inFile.exists())) { throw ValidationException.noSessionsXMLFound(this.resourceName); } } if (inURL == null) { this.resourcePath = inFile.getAbsolutePath(); } else { // Stored the loaded resource path, used in exception string if the // resource is not found or if there are errors in the resource. this.resourcePath = inURL.getPath(); } XMLPlatform xmlPlatform = XMLPlatformFactory.getInstance().getXMLPlatform(); XMLParser parser = xmlPlatform.newXMLParser(); if (validate) { parser.setValidationMode(XMLParser.SCHEMA_VALIDATION); } else { parser.setValidationMode(XMLParser.NONVALIDATING); } parser.setWhitespacePreserving(false); parser.setXMLSchema(loader.getResource(ECLIPSELINK_SESSIONS_SCHEMA)); parser.setEntityResolver(this.entityResolver); parser.setErrorHandler(new XMLSessionConfigLoaderErrorHandler()); if (inURL == null) { return parser.parse(inFile); } else { return parser.parse(inURL); } } /** * INTERNAL: *

Purpose: Provide a mechanism to swallow all parsing errors * * @see ErrorHandler * @since TopLink 10.1.3 * @author Guy Pelletier */ public class XMLSessionConfigLoaderErrorHandler implements ErrorHandler { @Override public void warning(SAXParseException e) throws SAXException { getExceptionStore().add(SessionLoaderException.failedToParseXML(ExceptionLocalization.buildMessage("parsing_warning"), e.getLineNumber(), e.getColumnNumber(), e)); } @Override public void error(SAXParseException e) throws SAXException { getExceptionStore().add(e); } @Override public void fatalError(SAXParseException e) throws SAXException { getExceptionStore().add(e); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy