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

com.sun.xml.ws.assembler.MetroConfigLoader Maven / Gradle / Ivy

There is a newer version: 4.0.3
Show newest version
/*
 * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package com.sun.xml.ws.assembler;

import com.sun.istack.NotNull;
import com.sun.istack.logging.Logger;
import com.sun.xml.ws.api.ResourceLoader;
import com.sun.xml.ws.api.server.Container;
import com.sun.xml.ws.resources.TubelineassemblyMessages;
import com.sun.xml.ws.runtime.config.MetroConfig;
import com.sun.xml.ws.runtime.config.TubeFactoryList;
import com.sun.xml.ws.runtime.config.TubelineDefinition;
import com.sun.xml.ws.runtime.config.TubelineMapping;
import com.sun.xml.ws.util.xml.XmlUtil;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.ws.WebServiceException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.logging.Level;

/**
 * This class is responsible for locating and loading Metro configuration files
 * (both application jaxws-tubes.xml and default jaxws-tubes-default.xml).
 * 
* Once the configuration is loaded the class is able to resolve which tubeline * configuration belongs to each endpoint or endpoint client. This information is * then used in {@link TubelineAssemblyController} to construct the list of * {@link TubeCreator} objects that are used in the actual tubeline construction. * * @author Marek Potociar */ // TODO Move the logic of this class directly into MetroConfig class. class MetroConfigLoader { private static final String JAXWS_TUBES_JDK_XML_RESOURCE = "jaxws-tubes-default.xml"; private static final Logger LOGGER = Logger.getLogger(MetroConfigLoader.class); private MetroConfigName defaultTubesConfigNames; private static interface TubeFactoryListResolver { TubeFactoryList getFactories(TubelineDefinition td); } private static final TubeFactoryListResolver ENDPOINT_SIDE_RESOLVER = new TubeFactoryListResolver() { public TubeFactoryList getFactories(TubelineDefinition td) { return (td != null) ? td.getEndpointSide() : null; } }; private static final TubeFactoryListResolver CLIENT_SIDE_RESOLVER = new TubeFactoryListResolver() { public TubeFactoryList getFactories(TubelineDefinition td) { return (td != null) ? td.getClientSide() : null; } }; // private MetroConfig defaultConfig; private URL defaultConfigUrl; private MetroConfig appConfig; private URL appConfigUrl; MetroConfigLoader(Container container, MetroConfigName defaultTubesConfigNames) { this.defaultTubesConfigNames = defaultTubesConfigNames; ResourceLoader spiResourceLoader = null; if (container != null) { spiResourceLoader = container.getSPI(ResourceLoader.class); } // if spi resource can't load resource, default (MetroConfigUrlLoader) is used; // it searches the classpath, so it would be most probably used // when using jaxws- or metro-defaults from jaxws libraries init(container, spiResourceLoader, new MetroConfigUrlLoader(container)); } private void init(Container container, ResourceLoader... loaders) { String appFileName = null; String defaultFileName = null; if (container != null) { MetroConfigName mcn = container.getSPI(MetroConfigName.class); if (mcn != null) { appFileName = mcn.getAppFileName(); defaultFileName = mcn.getDefaultFileName(); } } if (appFileName == null) { appFileName = defaultTubesConfigNames.getAppFileName(); } if (defaultFileName == null) { defaultFileName = defaultTubesConfigNames.getDefaultFileName(); } this.defaultConfigUrl = locateResource(defaultFileName, loaders); if (defaultConfigUrl != null) { LOGGER.config(TubelineassemblyMessages.MASM_0002_DEFAULT_CFG_FILE_LOCATED(defaultFileName, defaultConfigUrl)); } this.defaultConfig = MetroConfigLoader.loadMetroConfig(defaultConfigUrl); if (defaultConfig == null) { throw LOGGER.logSevereException(new IllegalStateException(TubelineassemblyMessages.MASM_0003_DEFAULT_CFG_FILE_NOT_LOADED(defaultFileName))); } if (defaultConfig.getTubelines() == null) { throw LOGGER.logSevereException(new IllegalStateException(TubelineassemblyMessages.MASM_0004_NO_TUBELINES_SECTION_IN_DEFAULT_CFG_FILE(defaultFileName))); } if (defaultConfig.getTubelines().getDefault() == null) { throw LOGGER.logSevereException(new IllegalStateException(TubelineassemblyMessages.MASM_0005_NO_DEFAULT_TUBELINE_IN_DEFAULT_CFG_FILE(defaultFileName))); } this.appConfigUrl = locateResource(appFileName, loaders); if (appConfigUrl != null) { LOGGER.config(TubelineassemblyMessages.MASM_0006_APP_CFG_FILE_LOCATED(appConfigUrl)); this.appConfig = MetroConfigLoader.loadMetroConfig(appConfigUrl); } else { LOGGER.config(TubelineassemblyMessages.MASM_0007_APP_CFG_FILE_NOT_FOUND()); this.appConfig = null; } } TubeFactoryList getEndpointSideTubeFactories(URI endpointReference) { return getTubeFactories(endpointReference, ENDPOINT_SIDE_RESOLVER); } TubeFactoryList getClientSideTubeFactories(URI endpointReference) { return getTubeFactories(endpointReference, CLIENT_SIDE_RESOLVER); } private TubeFactoryList getTubeFactories(URI endpointReference, TubeFactoryListResolver resolver) { if (appConfig != null && appConfig.getTubelines() != null) { for (TubelineMapping mapping : appConfig.getTubelines().getTubelineMappings()) { if (mapping.getEndpointRef().equals(endpointReference.toString())) { TubeFactoryList list = resolver.getFactories(getTubeline(appConfig, resolveReference(mapping.getTubelineRef()))); if (list != null) { return list; } else { break; } } } if (appConfig.getTubelines().getDefault() != null) { TubeFactoryList list = resolver.getFactories(getTubeline(appConfig, resolveReference(appConfig.getTubelines().getDefault()))); if (list != null) { return list; } } } for (TubelineMapping mapping : defaultConfig.getTubelines().getTubelineMappings()) { if (mapping.getEndpointRef().equals(endpointReference.toString())) { TubeFactoryList list = resolver.getFactories(getTubeline(defaultConfig, resolveReference(mapping.getTubelineRef()))); if (list != null) { return list; } else { break; } } } return resolver.getFactories(getTubeline(defaultConfig, resolveReference(defaultConfig.getTubelines().getDefault()))); } TubelineDefinition getTubeline(MetroConfig config, URI tubelineDefinitionUri) { if (config != null && config.getTubelines() != null) { for (TubelineDefinition td : config.getTubelines().getTubelineDefinitions()) { if (td.getName().equals(tubelineDefinitionUri.getFragment())) { return td; } } } return null; } private static URI resolveReference(String reference) { try { return new URI(reference); } catch (URISyntaxException ex) { throw LOGGER.logSevereException(new WebServiceException(TubelineassemblyMessages.MASM_0008_INVALID_URI_REFERENCE(reference), ex)); } } private static URL locateResource(String resource, ResourceLoader loader) { if (loader == null) return null; try { return loader.getResource(resource); } catch (MalformedURLException ex) { LOGGER.severe(TubelineassemblyMessages.MASM_0009_CANNOT_FORM_VALID_URL(resource), ex); } return null; } private static URL locateResource(String resource, ResourceLoader[] loaders) { for (ResourceLoader loader : loaders) { URL url = locateResource(resource, loader); if (url != null) { return url; } } return null; } private static MetroConfig loadMetroConfig(@NotNull URL resourceUrl) { try (InputStream is = getConfigInputStream(resourceUrl)) { JAXBContext jaxbContext = createJAXBContext(); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); XMLInputFactory factory = XmlUtil.newXMLInputFactory(true); JAXBElement configElement = unmarshaller.unmarshal(factory.createXMLStreamReader(is), MetroConfig.class); return configElement.getValue(); } catch (Exception e) { String message = TubelineassemblyMessages.MASM_0010_ERROR_READING_CFG_FILE_FROM_LOCATION( resourceUrl != null ? resourceUrl.toString() : null); InternalError error = new InternalError(message); LOGGER.logException(error, e, Level.SEVERE); throw error; } } private static InputStream getConfigInputStream(URL resourceUrl) throws IOException { InputStream is; if (resourceUrl != null) { is = resourceUrl.openStream(); } else { is = MetroConfigLoader.class.getResourceAsStream(JAXWS_TUBES_JDK_XML_RESOURCE); if (is == null) throw LOGGER.logSevereException( new IllegalStateException( TubelineassemblyMessages.MASM_0001_DEFAULT_CFG_FILE_NOT_FOUND(JAXWS_TUBES_JDK_XML_RESOURCE))); } return is; } private static JAXBContext createJAXBContext() throws Exception { if (isJDKInternal()) { // since jdk classes are repackaged, extra privilege is necessary to create JAXBContext return AccessController.doPrivileged( new PrivilegedExceptionAction() { @Override public JAXBContext run() throws Exception { return JAXBContext.newInstance(MetroConfig.class.getPackage().getName()); } }); } else { // usage from JAX-WS/Metro/Glassfish return JAXBContext.newInstance(MetroConfig.class.getPackage().getName()); } } private static boolean isJDKInternal() { // avoid "string repackaging" return MetroConfigLoader.class.getName().startsWith("com." + "sun.xml.internal.ws"); } private static class MetroConfigUrlLoader extends ResourceLoader { Container container; // TODO remove the field together with the code path using it (see below) ResourceLoader parentLoader; MetroConfigUrlLoader(ResourceLoader parentLoader) { this.parentLoader = parentLoader; } MetroConfigUrlLoader(Container container) { this((container != null) ? container.getSPI(ResourceLoader.class) : null); this.container = container; } @Override public URL getResource(String resource) throws MalformedURLException { LOGGER.entering(resource); URL resourceUrl = null; try { if (parentLoader != null) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine(TubelineassemblyMessages.MASM_0011_LOADING_RESOURCE(resource, parentLoader)); } resourceUrl = parentLoader.getResource(resource); } if (resourceUrl == null) { resourceUrl = loadViaClassLoaders("META-INF/" + resource); } if (resourceUrl == null && container != null) { // TODO: we should remove this code path, the config file should be loaded using ResourceLoader only resourceUrl = loadFromServletContext(resource); } return resourceUrl; } finally { LOGGER.exiting(resourceUrl); } } private static URL loadViaClassLoaders(final String resource) { URL resourceUrl = tryLoadFromClassLoader(resource, Thread.currentThread().getContextClassLoader()); if (resourceUrl == null) { resourceUrl = tryLoadFromClassLoader(resource, MetroConfigLoader.class.getClassLoader()); if (resourceUrl == null) { return ClassLoader.getSystemResource(resource); } } return resourceUrl; } private static URL tryLoadFromClassLoader(final String resource, final ClassLoader loader) { return (loader != null) ? loader.getResource(resource) : null; } private URL loadFromServletContext(String resource) throws RuntimeException { Object context = null; try { final Class contextClass = Class.forName("javax.servlet.ServletContext"); context = container.getSPI(contextClass); if (context != null) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine(TubelineassemblyMessages.MASM_0012_LOADING_VIA_SERVLET_CONTEXT(resource, context)); } try { final Method method = context.getClass().getMethod("getResource", String.class); method.setAccessible(true); final Object result = method.invoke(context, "/WEB-INF/" + resource); return URL.class.cast(result); } catch (Exception e) { throw LOGGER.logSevereException(new RuntimeException(TubelineassemblyMessages.MASM_0013_ERROR_INVOKING_SERVLET_CONTEXT_METHOD("getResource()")), e); } } } catch (ClassNotFoundException e) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine(TubelineassemblyMessages.MASM_0014_UNABLE_TO_LOAD_CLASS("javax.servlet.ServletContext")); } } return null; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy