/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2010-2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.web.servlet; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.Properties; import javax.servlet.ServletContext; import javax.servlet.ServletException; import org.opennms.core.resource.Vault; import org.opennms.core.resource.db.DbConnectionFactory; import org.opennms.core.utils.ThreadCategory; import org.opennms.netmgt.config.DataSourceFactory; /** * Encapsulates all initialization and configuration needed by the OpenNMS * servlets and JSPs. * * @author <A HREF="mailto:larry@opennms.org">Lawrence Karnowski </A> * @author <A HREF="http://www.opennms.org/">OpenNMS </A> * @author <A HREF="mailto:larry@opennms.org">Lawrence Karnowski </A> * @author <A HREF="http://www.opennms.org/">OpenNMS </A> * @version $Id: $ */ public class ServletInitializer extends Object { /** * A reference to the factory we set in {@link Vault Vault}during * {@link #init init}so we can destroy it in {@link #destroy destroy}. * * <p> * Maybe there's a better way to do this then storing a reference? Should we * just add a method to <code>Vault</code>? * </p> * * <p> * This reference also serves as a flag to determine whether or not this * class has been initialized yet. If it is null, the class has not yet been * initialized. * </p> */ protected static DbConnectionFactory factory; /** * Private, empty constructor so that this class cannot be instantiated * outside of itself. */ private ServletInitializer() { } /** * Initialize servlet and JSP configuration on the first invocation of this * method. All other invocations are ignored. This method is synchronized to * ensure only the first invocation performs the initialization. * * <p> * Call this method in the <code>init</code> method of your servlet or * JSP. It will read the servlet initialization parameters from the * <code>ServletConfig</code> and <code>ServletContext</code> and * OpenNMS configuration files. * </p> * * @param context * the <code>ServletContext</code> instance in which your * servlet is running * @throws javax.servlet.ServletException if any. */ public synchronized static void init(ServletContext context) throws ServletException { if (context == null) { throw new IllegalArgumentException("Cannot take null parameters."); } /* * All ThreadCategory instances in the WebUI should use this as their * category prefix */ ThreadCategory.setPrefix("OpenNMS.WEB"); if (factory == null) { Properties properties = new Properties(System.getProperties()); try { /* * First, check if opennms.home is set, if so, we already have properties * because we're in Jetty. */ if (properties.getProperty("opennms.home") == null) { // If not, load properties from configuration.properties loadPropertiesFromContextResource(context, properties, "/WEB-INF/configuration.properties"); // Make sure that we now have opennms.home set if (properties.getProperty("opennms.home") == null) { throw new ServletException("The opennms.home context parameter must be set."); } } } catch (IOException e) { throw new ServletException("Could not load configuration.properties", e); } String homeDir = properties.getProperty("opennms.home"); /* * Now that we've got opennms.home, load $OPENNMS_HOME/etc/opennms.properties * in case it isn't--but if anything is already set, we don't override it. */ Properties opennmsProperties = new Properties(); try { loadPropertiesFromFile(opennmsProperties, homeDir + File.separator + "etc" + File.separator + "opennms.properties"); } catch (IOException e) { throw new ServletException("Could not load opennms.properties", e); } try { loadPropertiesFromContextResource(context, opennmsProperties, "/WEB-INF/version.properties"); } catch (IOException e) { throw new ServletException("Could not load version.properties", e); } for (Enumeration<Object> opennmsKeys = opennmsProperties.keys(); opennmsKeys.hasMoreElements(); ) { Object key = opennmsKeys.nextElement(); if (!properties.containsKey(key)) { properties.put(key, opennmsProperties.get(key)); } } Enumeration<?> initParamNames = context.getInitParameterNames(); while (initParamNames.hasMoreElements()) { String name = (String) initParamNames.nextElement(); properties.put(name, context.getInitParameter(name)); } Vault.setProperties(properties); Vault.setHomeDir(homeDir); try { DataSourceFactory.init(); } catch (Throwable e) { throw new ServletException("Could not initialize data source factory: " + e, e); } // This is done inside "Vault.getDataSource" to ensure that "Vault" could be used by "IfLabel" - See Bug 4117 // Vault.setDataSource(DataSourceFactory.getInstance()); } } private static void loadPropertiesFromFile(Properties opennmsProperties, String propertiesFile) throws FileNotFoundException, ServletException, IOException { InputStream configurationStream = new FileInputStream(propertiesFile); if (configurationStream == null) { throw new ServletException("Could not load properties from file '" + propertiesFile + "'"); } else { opennmsProperties.load(configurationStream); configurationStream.close(); } } private static void loadPropertiesFromContextResource(ServletContext context, Properties properties, String propertiesResource) throws ServletException, IOException { InputStream configurationStream = context.getResourceAsStream(propertiesResource); if (configurationStream == null) { throw new ServletException("Could not load properties from resource '" + propertiesResource + "'"); } else { properties.load(configurationStream); configurationStream.close(); } } /** * Releases all shared resources on the first invocation of this method. All * other invocations are ignored. This method is synchronized to ensure only * the first invocation performs the destruction. * * <p> * Call this method in the <code>destroy</code> method of your servlet or * JSP. * </p> * * @param context * the <code>ServletContext</code> instance in which your * servlet is running * @throws javax.servlet.ServletException if any. */ public synchronized static void destroy(ServletContext context) throws ServletException { try { if (factory != null) { factory.destroy(); factory = null; } } catch (Throwable e) { throw new ServletException("Could not destroy the database connection factory", e); } } /** * Return the absolute pathname of where OpenNMS's configuration can be * found. * * @deprecated Use {@link Vault#getHomeDir Vault.getHomeDir}instead. * @return a {@link java.lang.String} object. */ public static String getHomeDir() { return (Vault.getHomeDir()); } }