/** * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.aries.blueprint.web; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.aries.blueprint.NamespaceHandler; import org.apache.aries.blueprint.Namespaces; import org.apache.aries.blueprint.container.BlueprintContainerImpl; import org.apache.aries.blueprint.container.SimpleNamespaceHandlerSet; import org.apache.aries.blueprint.parser.NamespaceHandlerSet; /** * Initialises all the blueprint XML files called <code>META-INF/blueprint.xml</code> on the classpath */ public class BlueprintContextListener implements ServletContextListener { public static final String CONTAINER_ATTRIBUTE = "org.apache.aries.blueprint.container"; public static final String CONTEXT_LOCATION = "blueprintLocation"; public static final String DEFAULT_CONTEXT_LOCATION = "META-INF/blueprint.xml"; public static final String NAMESPACE_HANDLERS_PARAMETER = "blueprintNamespaceHandlers"; public static final String NAMESPACE_HANDLERS_LOCATION = "META-INF/blueprint.handlers"; public static final String PROPERTIES = "blueprintProperties"; public void contextInitialized(ServletContextEvent event) { ServletContext servletContext = event.getServletContext(); String location = servletContext.getInitParameter(CONTEXT_LOCATION); if (location == null) { location = DEFAULT_CONTEXT_LOCATION; } List<URL> resourcePaths = new ArrayList<URL>(); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); try { Enumeration<URL> resources = classLoader.getResources(location); while (resources.hasMoreElements()) { resourcePaths.add(resources.nextElement()); } servletContext.log("Loading Blueprint contexts " + resourcePaths); Map<String, String> properties = new HashMap<String, String>(); String propLocations = servletContext.getInitParameter(PROPERTIES); if (propLocations != null) { for (String propLoc : propLocations.split(",")) { Enumeration<URL> propUrl = classLoader.getResources(propLoc); while (propUrl.hasMoreElements()) { URL url = propUrl.nextElement(); InputStream is = url.openStream(); try { Properties props = new Properties(); props.load(is); Enumeration names = props.propertyNames(); while (names.hasMoreElements()) { String key = names.nextElement().toString(); properties.put(key, props.getProperty(key)); } } finally { is.close(); } } } } NamespaceHandlerSet nsHandlerSet = getNamespaceHandlerSet(servletContext, classLoader); BlueprintContainerImpl container = new BlueprintContainerImpl(classLoader, resourcePaths, properties, nsHandlerSet, true); servletContext.setAttribute(CONTAINER_ATTRIBUTE, container); } catch (Exception e) { servletContext.log("Failed to startup blueprint container. " + e, e); } } protected NamespaceHandlerSet getNamespaceHandlerSet(ServletContext servletContext, ClassLoader tccl) { NamespaceHandlerSet nsSet = getNamespaceHandlerSetFromParameter(servletContext, tccl); if (nsSet != null) { return nsSet; } return getNamespaceHandlerSetFromLocation(servletContext, tccl); } protected NamespaceHandlerSet getNamespaceHandlerSetFromParameter(ServletContext servletContext, ClassLoader tccl) { String handlersProp = servletContext.getInitParameter(NAMESPACE_HANDLERS_PARAMETER); if (handlersProp == null) { return null; } return getNamespaceHandlerSetFromClassNames(servletContext, tccl, Arrays.asList(handlersProp.split(","))); } protected NamespaceHandlerSet getNamespaceHandlerSetFromLocation(ServletContext servletContext, ClassLoader tccl) { List<String> handlerClassNames = new LinkedList<String>(); try { Enumeration<URL> resources = tccl.getResources(NAMESPACE_HANDLERS_LOCATION); while (resources.hasMoreElements()) { URL resource = resources.nextElement(); BufferedReader br = new BufferedReader(new InputStreamReader(resource.openStream())); try { for (String line = br.readLine(); line != null; line = br.readLine()) { String trimmedLine = line.trim(); if (trimmedLine.isEmpty() || trimmedLine.startsWith("#")) { continue; } handlerClassNames.add(trimmedLine); } } finally { br.close(); } } } catch (IOException ex) { throw new RuntimeException("Failed to load namespace handler resources", ex); } if (!handlerClassNames.isEmpty()) { return getNamespaceHandlerSetFromClassNames(servletContext, tccl, handlerClassNames); } else { return null; } } protected NamespaceHandlerSet getNamespaceHandlerSetFromClassNames(ServletContext servletContext, ClassLoader tccl, List<String> handlerClassNames) { SimpleNamespaceHandlerSet nsSet = new SimpleNamespaceHandlerSet(); for (String name : handlerClassNames) { String trimmedName = name.trim(); Object instance = null; try { instance = tccl.loadClass(trimmedName).newInstance(); } catch (Exception ex) { throw new RuntimeException("Failed to load NamespaceHandler: " + trimmedName, ex); } if (!(instance instanceof NamespaceHandler)) { throw new RuntimeException("Invalid NamespaceHandler: " + trimmedName); } NamespaceHandler nsHandler = (NamespaceHandler)instance; Namespaces namespaces = nsHandler.getClass().getAnnotation(Namespaces.class); if (namespaces != null) { for (String ns : namespaces.value()) { nsSet.addNamespace(URI.create(ns), nsHandler.getSchemaLocation(ns), nsHandler); } } } return nsSet; } public void contextDestroyed(ServletContextEvent event) { ServletContext servletContext = event.getServletContext(); Object container = servletContext.getAttribute(CONTAINER_ATTRIBUTE); if (container instanceof BlueprintContainerImpl) { BlueprintContainerImpl blueprint = (BlueprintContainerImpl) container; blueprint.destroy(); } } }