Java tutorial
/* * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. * * [Additional notices, if required by prior licensing conditions] * */ package org.apache.coyote.tomcat5; import java.util.Iterator; import java.util.Set; import javax.management.MBeanServer; import javax.management.MBeanServerNotification; import javax.management.Notification; import javax.management.NotificationListener; import javax.management.ObjectInstance; import javax.management.ObjectName; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.modeler.Registry; import org.apache.tomcat.util.http.mapper.Mapper; import org.apache.tomcat.util.res.StringManager; /** * Mapper listener. * * @author Remy Maucherat * @author Costin Manolache */ public class MapperListener implements NotificationListener { private static Log log = LogFactory.getLog(MapperListener.class); // ----------------------------------------------------- Instance Variables /** * Associated mapper. */ protected Mapper mapper = null; /** * MBean server. */ protected MBeanServer mBeanServer = null; /** * The string manager for this package. */ private StringManager sm = StringManager.getManager(Constants.Package); // It should be null - and fail if not set private String domain = "*"; private String engine = "*"; // ----------------------------------------------------------- Constructors /** * Create mapper listener. */ public MapperListener(Mapper mapper) { this.mapper = mapper; } // --------------------------------------------------------- Public Methods public String getDomain() { return domain; } public void setDomain(String domain) { this.domain = domain; } public String getEngine() { return engine; } public void setEngine(String engine) { this.engine = engine; } /** * Initialize associated mapper. */ public void init() { try { mBeanServer = Registry.getServer(); registerEngine(); // Query hosts String onStr = domain + ":type=Host,*"; ObjectName objectName = new ObjectName(onStr); Set set = mBeanServer.queryMBeans(objectName, null); Iterator iterator = set.iterator(); while (iterator.hasNext()) { ObjectInstance oi = (ObjectInstance) iterator.next(); registerHost(oi.getObjectName()); } // Query contexts onStr = "*:j2eeType=WebModule,*"; objectName = new ObjectName(onStr); set = mBeanServer.queryMBeans(objectName, null); iterator = set.iterator(); while (iterator.hasNext()) { ObjectInstance oi = (ObjectInstance) iterator.next(); registerContext(oi.getObjectName()); } // Query wrappers onStr = "*:j2eeType=Servlet,*"; objectName = new ObjectName(onStr); set = mBeanServer.queryMBeans(objectName, null); iterator = set.iterator(); while (iterator.hasNext()) { ObjectInstance oi = (ObjectInstance) iterator.next(); registerWrapper(oi.getObjectName()); } onStr = "JMImplementation:type=MBeanServerDelegate"; objectName = new ObjectName(onStr); mBeanServer.addNotificationListener(objectName, this, null, null); } catch (Exception e) { log.warn("Error registering contexts", e); } } // ------------------------------------------- NotificationListener Methods public void handleNotification(Notification notification, java.lang.Object handback) { if (notification instanceof MBeanServerNotification) { ObjectName objectName = ((MBeanServerNotification) notification).getMBeanName(); String j2eeType = objectName.getKeyProperty("j2eeType"); String engineName = null; if (j2eeType != null) { if ((j2eeType.equals("WebModule")) || (j2eeType.equals("Servlet"))) { if (mBeanServer.isRegistered(objectName)) { try { engineName = (String) mBeanServer.getAttribute(objectName, "engineName"); } catch (Exception e) { // Ignore } } } } // At deployment time, engineName is always = null. if ((!"*".equals(domain)) && (!domain.equals(objectName.getDomain())) && ((!domain.equals(engineName)) && (engineName != null))) { return; } log.debug("Handle " + objectName); if (notification.getType().equals(MBeanServerNotification.REGISTRATION_NOTIFICATION)) { String type = objectName.getKeyProperty("type"); if ("Host".equals(type)) { try { registerHost(objectName); } catch (Exception e) { log.warn("Error registering Host " + objectName, e); } } if (j2eeType != null) { if (j2eeType.equals("WebModule")) { try { registerContext(objectName); } catch (Throwable t) { log.warn("Error registering Context " + objectName, t); } } else if (j2eeType.equals("Servlet")) { try { registerWrapper(objectName); } catch (Throwable t) { log.warn("Error registering Wrapper " + objectName, t); } } } } else if (notification.getType().equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) { String type = objectName.getKeyProperty("type"); if ("Host".equals(type)) { try { unregisterHost(objectName); } catch (Exception e) { log.warn("Error unregistering Host " + objectName, e); } } if (j2eeType != null) { if (j2eeType.equals("WebModule")) { try { unregisterContext(objectName); } catch (Throwable t) { log.warn("Error unregistering webapp " + objectName, t); } } } } } } // ------------------------------------------------------ Protected Methods private void registerEngine() throws Exception { ObjectName engineName = new ObjectName(domain + ":type=Engine"); if (!mBeanServer.isRegistered(engineName)) return; String defaultHost = (String) mBeanServer.getAttribute(engineName, "defaultHost"); // This should probablt be called later if (defaultHost != null) { mapper.setDefaultHostName(defaultHost); } } /** * Register host. */ private void registerHost(ObjectName objectName) throws Exception { String name = objectName.getKeyProperty("host"); if (name != null) { String[] aliases = (String[]) mBeanServer.invoke(objectName, "findAliases", null, null); mapper.addHost(name, aliases, objectName); } } /** * Unregister host. */ private void unregisterHost(ObjectName objectName) throws Exception { String name = objectName.getKeyProperty("host"); mapper.removeHost(name); } /** * Register context. */ private void registerContext(ObjectName objectName) throws Exception { String name = objectName.getKeyProperty("name"); // If the domain is the same with ours or the engine // name attribute is the same... - then it's ours String targetDomain = objectName.getDomain(); if (!domain.equals(targetDomain)) { try { targetDomain = (String) mBeanServer.getAttribute(objectName, "engineName"); } catch (Exception e) { // Ignore } if (!domain.equals(targetDomain)) { // not ours return; } } String hostName = null; String contextName = null; if (name.startsWith("//")) { name = name.substring(2); } int slash = name.indexOf("/"); if (slash != -1) { hostName = name.substring(0, slash); contextName = name.substring(slash); } else { return; } // Special case for the root context if (contextName.equals("/")) { contextName = ""; } log.debug(sm.getString("mapperListener.registerContext", contextName)); Object context = mBeanServer.invoke(objectName, "findMappingObject", null, null); //mBeanServer.getAttribute(objectName, "mappingObject"); javax.naming.Context resources = (javax.naming.Context) mBeanServer.invoke(objectName, "findStaticResources", null, null); //mBeanServer.getAttribute(objectName, "staticResources"); String[] welcomeFiles = (String[]) mBeanServer.getAttribute(objectName, "welcomeFiles"); mapper.addContext(hostName, contextName, context, welcomeFiles, resources); } /** * Unregister context. */ private void unregisterContext(ObjectName objectName) throws Exception { String name = objectName.getKeyProperty("name"); // If the domain is the same with ours or the engine // name attribute is the same... - then it's ours String targetDomain = objectName.getDomain(); if (!domain.equals(targetDomain)) { try { targetDomain = (String) mBeanServer.getAttribute(objectName, "engineName"); } catch (Exception e) { // Ignore } if (!domain.equals(targetDomain)) { // not ours return; } } String hostName = null; String contextName = null; if (name.startsWith("//")) { name = name.substring(2); } int slash = name.indexOf("/"); if (slash != -1) { hostName = name.substring(0, slash); contextName = name.substring(slash); } else { return; } // Special case for the root context if (contextName.equals("/")) { contextName = ""; } log.debug(sm.getString("mapperListener.unregisterContext", contextName)); mapper.removeContext(hostName, contextName); } /** * Register wrapper. */ private void registerWrapper(ObjectName objectName) throws Exception { // If the domain is the same with ours or the engine // name attribute is the same... - then it's ours String targetDomain = objectName.getDomain(); if (!domain.equals(targetDomain)) { try { targetDomain = (String) mBeanServer.getAttribute(objectName, "engineName"); } catch (Exception e) { // Ignore } if (!domain.equals(targetDomain)) { // not ours return; } } String wrapperName = objectName.getKeyProperty("name"); String name = objectName.getKeyProperty("WebModule"); String hostName = null; String contextName = null; if (name.startsWith("//")) { name = name.substring(2); } int slash = name.indexOf("/"); if (slash != -1) { hostName = name.substring(0, slash); contextName = name.substring(slash); } else { return; } // Special case for the root context if (contextName.equals("/")) { contextName = ""; } log.debug(sm.getString("mapperListener.registerWrapper", wrapperName, contextName)); String[] mappings = (String[]) mBeanServer.invoke(objectName, "findMappings", null, null); Object wrapper = mBeanServer.invoke(objectName, "findMappingObject", null, null); for (int i = 0; i < mappings.length; i++) { mapper.addWrapper(hostName, contextName, mappings[i], wrapper); } } }