/* * RHQ Management Platform * Copyright (C) 2005-2014 Red Hat, Inc. * All rights reserved. * * This program 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 version 2 of the License. * * This program 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 this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.enterprise.gui.startup; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.Properties; import java.util.logging.LogManager; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.configuration.PropertyDynamicType; import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.gui.configuration.helper.PropertyRenderingUtility; import org.rhq.enterprise.gui.configuration.DatabaseDynamicPropertyRetriever; import org.rhq.enterprise.gui.legacy.AttrConstants; import org.rhq.enterprise.gui.legacy.Constants; import org.rhq.enterprise.server.util.LookupUtil; /** * This is a servlet context listener defined in web.xml that loads several files and puts data in the servlet context: * * <ul> * <li>the <code>/WEB-INF/rhq-server-internals.properties</code> properties which configures things like how to * connect to EJBs</li> * <li>configures a user's default preferences, for those users that have no persisted preferences already</li> * <li>the build version number</li> * <li>taglib properties</li> * </ul> */ public final class Configurator implements ServletContextListener { private static final Log LOG = LogFactory.getLog(Configurator.class.getName()); private static final String SERVER_INTERNALS_FILE = "/WEB-INF/rhq-server-internals.properties"; private static final String DEFAULT_USER_PREFERENCES_FILE = "/WEB-INF/DefaultUserPreferences.properties"; private static final String TAGLIB_PROPERTIES_FILE = "/WEB-INF/taglib.properties"; private static final String LOGGING_PROPERTIES_RESOURCE = "logging.properties"; // If any name in the server internals properties file starts with this, it defines a system property. // Therefore, the name/value will not go into the servlet context, but will be a system property. private static final String SYSPROP_KEY = "org.jboss.on.sysprop"; /** * Creates a new {@link Configurator} object. */ public Configurator() { } /** * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) */ @Override public void contextInitialized(ServletContextEvent sce) { ServletContext ctx = sce.getServletContext(); loadConfig(ctx); loadPreferences(ctx); loadTablePreferences(ctx); loadBuildVersion(ctx); loadJavaLoggingConfiguration(); registerDynamicPropertyRetrievers(); } /** * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) */ @Override public void contextDestroyed(ServletContextEvent sce) { } /** * Load the internals properties file and configures the web application. All properties in the file are exposed as * servlet context attributes. */ private void loadConfig(ServletContext ctx) { Properties props; try { props = loadProperties(ctx, SERVER_INTERNALS_FILE); } catch (Exception e) { LOG.error("unable to load server internals file [" + SERVER_INTERNALS_FILE + "]", e); return; } if (props == null) { if (LOG.isDebugEnabled()) { LOG.debug("server internals file [" + SERVER_INTERNALS_FILE + "] does not exist"); } return; } Enumeration names = props.propertyNames(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); // this is not currently used, but is interesting, it lets you define system properties in rhq-server-internals.properties if (name.startsWith(SYSPROP_KEY)) { System.setProperty(name, props.getProperty(name)); } else { ctx.setAttribute(name, props.getProperty(name)); } } if (LOG.isDebugEnabled()) { LOG.debug("loaded server internals [" + SERVER_INTERNALS_FILE + "]"); } } /** * There is a single properties file in the web application that defines the default user properties. That * properties file is loaded in and stored in the servlet context so a user that logs in but doesn't have * preferences set yet can obtain these default settings. */ private void loadPreferences(ServletContext ctx) { try { Configuration userPrefs = new Configuration(); Properties userProps = loadProperties(ctx, DEFAULT_USER_PREFERENCES_FILE); Enumeration keys = userProps.keys(); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); userPrefs.put(new PropertySimple(key, userProps.getProperty(key))); } ctx.setAttribute(Constants.DEF_USER_PREFS, userPrefs); } catch (Exception e) { LOG.error("failed to load user preferences at [" + DEFAULT_USER_PREFERENCES_FILE + "]: ", e); } } /** * The table tag GUI component needs the taglib definitions. This loads those definitions. */ private void loadTablePreferences(ServletContext ctx) { try { Properties tableProps = loadProperties(ctx, TAGLIB_PROPERTIES_FILE); ctx.setAttribute(Constants.PROPS_TAGLIB_NAME, tableProps); } catch (Exception e) { LOG.error("failed to load the taglib properties at [" + TAGLIB_PROPERTIES_FILE + "]: ", e); } } /** * Determines the internal build/version number and puts it in a context attribute. */ private void loadBuildVersion(ServletContext servletContext) { String version = LookupUtil.getCoreServer().getVersion(); servletContext.setAttribute(AttrConstants.RHQ_VERSION_ATTR, version); } /** * Load the specified properties file and return the properties. * * @param context the <code>ServletContext</code> * @param filename the fully qualifed name of the properties file * * @return the contents of the properties file * * @throws Exception if a problem occurs while loading the file */ private Properties loadProperties(ServletContext context, String filename) throws Exception { Properties props = new Properties(); InputStream is = context.getResourceAsStream(filename); if (is != null) { props.load(is); is.close(); } return props; } private void loadJavaLoggingConfiguration() { InputStream loggingPropertiesStream = Configurator.class.getClassLoader().getResourceAsStream( LOGGING_PROPERTIES_RESOURCE); if (loggingPropertiesStream != null) { try { LogManager.getLogManager().readConfiguration(loggingPropertiesStream); } catch (IOException e) { LOG.error("Failed to load '" + LOGGING_PROPERTIES_RESOURCE + "' from webapp classloader."); } } } private void registerDynamicPropertyRetrievers() { // Configures the configuration rendering to be able to support database backed dynamic configuration properties PropertyRenderingUtility.putDynamicPropertyRetriever(PropertyDynamicType.DATABASE, new DatabaseDynamicPropertyRetriever()); } }