Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » connector » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */ 
   17   package org.apache.catalina.connector;
   18   
   19   import java.util.Iterator;
   20   import java.util.Set;
   21   
   22   import javax.management.MBeanServer;
   23   import javax.management.MBeanServerNotification;
   24   import javax.management.Notification;
   25   import javax.management.NotificationListener;
   26   import javax.management.ObjectInstance;
   27   import javax.management.ObjectName;
   28   
   29   import org.apache.juli.logging.Log;
   30   import org.apache.juli.logging.LogFactory;
   31   
   32   
   33   import org.apache.tomcat.util.http.mapper.Mapper;
   34   import org.apache.tomcat.util.modeler.Registry;
   35   
   36   import org.apache.tomcat.util.res.StringManager;
   37   
   38   
   39   /**
   40    * Mapper listener.
   41    *
   42    * @author Remy Maucherat
   43    * @author Costin Manolache
   44    */
   45   public class MapperListener
   46       implements NotificationListener 
   47    {
   48       private static Log log = LogFactory.getLog(MapperListener.class);
   49   
   50   
   51       // ----------------------------------------------------- Instance Variables
   52       /**
   53        * Associated mapper.
   54        */
   55       protected Mapper mapper = null;
   56   
   57       /**
   58        * MBean server.
   59        */
   60       protected MBeanServer mBeanServer = null;
   61   
   62   
   63       /**
   64        * The string manager for this package.
   65        */
   66       private StringManager sm =
   67           StringManager.getManager(Constants.Package);
   68   
   69       // It should be null - and fail if not set
   70       private String domain="*";
   71       private String engine="*";
   72   
   73       // ----------------------------------------------------------- Constructors
   74   
   75   
   76       /**
   77        * Create mapper listener.
   78        */
   79       public MapperListener(Mapper mapper) {
   80           this.mapper = mapper;
   81       }
   82   
   83   
   84       // --------------------------------------------------------- Public Methods
   85   
   86       public String getDomain() {
   87           return domain;
   88       }
   89   
   90       public void setDomain(String domain) {
   91           this.domain = domain;
   92       }
   93   
   94       public String getEngine() {
   95           return engine;
   96       }
   97   
   98       public void setEngine(String engine) {
   99           this.engine = engine;
  100       }
  101   
  102       /**
  103        * Initialize associated mapper.
  104        */
  105       public void init() {
  106   
  107           try {
  108   
  109               mBeanServer = Registry.getRegistry(null, null).getMBeanServer();
  110   
  111               registerEngine();
  112   
  113               // Query hosts
  114               String onStr = domain + ":type=Host,*";
  115               ObjectName objectName = new ObjectName(onStr);
  116               Set set = mBeanServer.queryMBeans(objectName, null);
  117               Iterator iterator = set.iterator();
  118               while (iterator.hasNext()) {
  119                   ObjectInstance oi = (ObjectInstance) iterator.next();
  120                   registerHost(oi.getObjectName());
  121               }
  122   
  123   
  124               // Query contexts
  125               onStr = "*:j2eeType=WebModule,*";
  126               objectName = new ObjectName(onStr);
  127               set = mBeanServer.queryMBeans(objectName, null);
  128               iterator = set.iterator();
  129               while (iterator.hasNext()) {
  130                   ObjectInstance oi = (ObjectInstance) iterator.next();
  131                   registerContext(oi.getObjectName());
  132               }
  133   
  134               // Query wrappers
  135               onStr = "*:j2eeType=Servlet,*";
  136               objectName = new ObjectName(onStr);
  137               set = mBeanServer.queryMBeans(objectName, null);
  138               iterator = set.iterator();
  139               while (iterator.hasNext()) {
  140                   ObjectInstance oi = (ObjectInstance) iterator.next();
  141                   registerWrapper(oi.getObjectName());
  142               }
  143   
  144               onStr = "JMImplementation:type=MBeanServerDelegate";
  145               objectName = new ObjectName(onStr);
  146               mBeanServer.addNotificationListener(objectName, this, null, null);
  147   
  148           } catch (Exception e) {
  149               log.warn("Error registering contexts",e);
  150           }
  151   
  152       }
  153   
  154       /**
  155        * unregister this from JMImplementation:type=MBeanServerDelegate
  156        */
  157       public void destroy() {
  158           try {
  159   
  160               ObjectName objectName = new ObjectName(
  161                       "JMImplementation:type=MBeanServerDelegate");
  162               mBeanServer.removeNotificationListener(objectName, this);
  163           } catch (Exception e) {
  164               log.warn("Error unregistering MBeanServerDelegate", e);
  165           }
  166       }
  167   
  168       // ------------------------------------------- NotificationListener Methods
  169   
  170   
  171       public void handleNotification(Notification notification,
  172                                      java.lang.Object handback) {
  173   
  174           if (notification instanceof MBeanServerNotification) {
  175               ObjectName objectName = 
  176                   ((MBeanServerNotification) notification).getMBeanName();
  177               String j2eeType = objectName.getKeyProperty("j2eeType");
  178               String engineName = null;
  179               if (j2eeType != null) {
  180                   if ((j2eeType.equals("WebModule")) || 
  181                       (j2eeType.equals("Servlet"))) {
  182                       if (mBeanServer.isRegistered(objectName)) {
  183                           try {
  184                               engineName = (String)
  185                                   mBeanServer.getAttribute(objectName, "engineName");
  186                           } catch (Exception e) {
  187                               // Ignore  
  188                           }
  189                       }
  190                   }
  191               }
  192   
  193               // At deployment time, engineName is always = null.
  194               if ( (!"*".equals(domain)) &&
  195                    ( !domain.equals(objectName.getDomain()) ) &&
  196                    ( (!domain.equals(engineName) ) &&
  197                      (engineName != null) ) )  {
  198                   return;
  199               }
  200               if(log.isDebugEnabled())
  201                   log.debug( "Handle " + objectName  + " type : " + notification.getType());    
  202               if (notification.getType().equals
  203                   (MBeanServerNotification.REGISTRATION_NOTIFICATION)) {
  204                   String type=objectName.getKeyProperty("type");
  205                   if( "Host".equals( type ) && domain.equals(objectName.getDomain())) {
  206                       try {
  207                           registerHost(objectName);
  208                       } catch (Exception e) {
  209                           log.warn("Error registering Host " + objectName, e);  
  210                       }
  211                   }
  212       
  213                   if (j2eeType != null) {
  214                       if (j2eeType.equals("WebModule")) {
  215                           try {
  216                               registerContext(objectName);
  217                           } catch (Throwable t) {
  218                               log.warn("Error registering Context " + objectName,t);
  219                           }
  220                       } else if (j2eeType.equals("Servlet")) {
  221                           try {
  222                               registerWrapper(objectName);
  223                           } catch (Throwable t) {
  224                               log.warn("Error registering Wrapper " + objectName,t);
  225                           }
  226                       }
  227                   }
  228               } else if (notification.getType().equals
  229                          (MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
  230                   String type=objectName.getKeyProperty("type");
  231                   if( "Host".equals( type )&& domain.equals(objectName.getDomain())) {
  232                       try {
  233                           unregisterHost(objectName);
  234                       } catch (Exception e) {
  235                           log.warn("Error unregistering Host " + objectName,e);  
  236                       }
  237                   }
  238    
  239                   if (j2eeType != null) {
  240                       if (j2eeType.equals("WebModule")) {
  241                           try {
  242                               unregisterContext(objectName);
  243                           } catch (Throwable t) {
  244                               log.warn("Error unregistering webapp " + objectName,t);
  245                           }
  246                       }
  247                   }
  248               }
  249           }
  250   
  251       }
  252   
  253   
  254       // ------------------------------------------------------ Protected Methods
  255   
  256       private void registerEngine()
  257           throws Exception
  258       {
  259           ObjectName engineName = new ObjectName
  260               (domain + ":type=Engine");
  261           if ( ! mBeanServer.isRegistered(engineName)) return;
  262           String defaultHost = 
  263               (String) mBeanServer.getAttribute(engineName, "defaultHost");
  264           ObjectName hostName = new ObjectName
  265               (domain + ":type=Host," + "host=" + defaultHost);
  266           if (!mBeanServer.isRegistered(hostName)) {
  267   
  268               // Get the hosts' list
  269               String onStr = domain + ":type=Host,*";
  270               ObjectName objectName = new ObjectName(onStr);
  271               Set set = mBeanServer.queryMBeans(objectName, null);
  272               Iterator iterator = set.iterator();
  273               String[] aliases;
  274               boolean isRegisteredWithAlias = false;
  275               
  276               while (iterator.hasNext()) {
  277   
  278                   if (isRegisteredWithAlias) break;
  279               
  280                   ObjectInstance oi = (ObjectInstance) iterator.next();
  281                   hostName = oi.getObjectName();
  282                   aliases = (String[])
  283                       mBeanServer.invoke(hostName, "findAliases", null, null);
  284   
  285                   for (int i=0; i < aliases.length; i++){
  286                       if (aliases[i].equalsIgnoreCase(defaultHost)){
  287                           isRegisteredWithAlias = true;
  288                           break;
  289                       }
  290                   }
  291               }
  292               
  293               if (!isRegisteredWithAlias && log.isWarnEnabled())
  294                   log.warn(sm.getString("mapperListener.unknownDefaultHost", defaultHost));
  295           }
  296           // This should probablt be called later 
  297           if( defaultHost != null ) {
  298               mapper.setDefaultHostName(defaultHost);
  299           }
  300       }
  301   
  302       /**
  303        * Register host.
  304        */
  305       private void registerHost(ObjectName objectName)
  306           throws Exception {
  307           String name=objectName.getKeyProperty("host");
  308           if( name != null ) {        
  309               String[] aliases = (String[])
  310                   mBeanServer.invoke(objectName, "findAliases", null, null);
  311               mapper.addHost(name, aliases, objectName);
  312               if(log.isDebugEnabled())
  313                   log.debug(sm.getString
  314                        ("mapperListener.registerHost", name, domain));
  315   
  316           }
  317       }
  318   
  319   
  320       /**
  321        * Unregister host.
  322        */
  323       private void unregisterHost(ObjectName objectName)
  324           throws Exception {
  325           String name=objectName.getKeyProperty("host");
  326           mapper.removeHost(name);
  327           if(log.isDebugEnabled())
  328               log.debug(sm.getString
  329                    ("mapperListener.unregisterHost", name, domain));
  330       }
  331   
  332   
  333       /**
  334        * Register context.
  335        */
  336       private void registerContext(ObjectName objectName)
  337           throws Exception {
  338   
  339           String name = objectName.getKeyProperty("name");
  340           
  341           // If the domain is the same with ours or the engine 
  342           // name attribute is the same... - then it's ours
  343           String targetDomain=objectName.getDomain();
  344           if( ! domain.equals( targetDomain )) {
  345               try {
  346                   targetDomain = (String) mBeanServer.getAttribute
  347                       (objectName, "engineName");
  348               } catch (Exception e) {
  349                   // Ignore
  350               }
  351               if( ! domain.equals( targetDomain )) {
  352                   // not ours
  353                   return;
  354               }
  355           }
  356   
  357           String hostName = null;
  358           String contextName = null;
  359           if (name.startsWith("//")) {
  360               name = name.substring(2);
  361           }
  362           int slash = name.indexOf("/");
  363           if (slash != -1) {
  364               hostName = name.substring(0, slash);
  365               contextName = name.substring(slash);
  366           } else {
  367               return;
  368           }
  369           // Special case for the root context
  370           if (contextName.equals("/")) {
  371               contextName = "";
  372           }
  373   
  374           if(log.isDebugEnabled())
  375                log.debug(sm.getString
  376                     ("mapperListener.registerContext", contextName));
  377   
  378           Object context = 
  379               mBeanServer.invoke(objectName, "findMappingObject", null, null);
  380               //mBeanServer.getAttribute(objectName, "mappingObject");
  381           javax.naming.Context resources = (javax.naming.Context)
  382               mBeanServer.invoke(objectName, "findStaticResources", null, null);
  383               //mBeanServer.getAttribute(objectName, "staticResources");
  384           String[] welcomeFiles = (String[])
  385               mBeanServer.getAttribute(objectName, "welcomeFiles");
  386   
  387           mapper.addContext(hostName, contextName, context, 
  388                             welcomeFiles, resources);
  389   
  390       }
  391   
  392   
  393       /**
  394        * Unregister context.
  395        */
  396       private void unregisterContext(ObjectName objectName)
  397           throws Exception {
  398   
  399           String name = objectName.getKeyProperty("name");
  400   
  401           // If the domain is the same with ours or the engine 
  402           // name attribute is the same... - then it's ours
  403           String targetDomain=objectName.getDomain();
  404           if( ! domain.equals( targetDomain )) {
  405               try {
  406                   targetDomain = (String) mBeanServer.getAttribute
  407                       (objectName, "engineName");
  408               } catch (Exception e) {
  409                   // Ignore
  410               }
  411               if( ! domain.equals( targetDomain )) {
  412                   // not ours
  413                   return;
  414               }
  415           }
  416   
  417           String hostName = null;
  418           String contextName = null;
  419           if (name.startsWith("//")) {
  420               name = name.substring(2);
  421           }
  422           int slash = name.indexOf("/");
  423           if (slash != -1) {
  424               hostName = name.substring(0, slash);
  425               contextName = name.substring(slash);
  426           } else {
  427               return;
  428           }
  429           // Special case for the root context
  430           if (contextName.equals("/")) {
  431               contextName = "";
  432           }
  433           if(log.isDebugEnabled())
  434               log.debug(sm.getString
  435                     ("mapperListener.unregisterContext", contextName));
  436   
  437           mapper.removeContext(hostName, contextName);
  438   
  439       }
  440   
  441   
  442       /**
  443        * Register wrapper.
  444        */
  445       private void registerWrapper(ObjectName objectName)
  446           throws Exception {
  447       
  448           // If the domain is the same with ours or the engine 
  449           // name attribute is the same... - then it's ours
  450           String targetDomain=objectName.getDomain();
  451           if( ! domain.equals( targetDomain )) {
  452               try {
  453                   targetDomain=(String) mBeanServer.getAttribute(objectName, "engineName");
  454               } catch (Exception e) {
  455                   // Ignore
  456               }
  457               if( ! domain.equals( targetDomain )) {
  458                   // not ours
  459                   return;
  460               }
  461               
  462           }
  463   
  464           String wrapperName = objectName.getKeyProperty("name");
  465           String name = objectName.getKeyProperty("WebModule");
  466   
  467           String hostName = null;
  468           String contextName = null;
  469           if (name.startsWith("//")) {
  470               name = name.substring(2);
  471           }
  472           int slash = name.indexOf("/");
  473           if (slash != -1) {
  474               hostName = name.substring(0, slash);
  475               contextName = name.substring(slash);
  476           } else {
  477               return;
  478           }
  479           // Special case for the root context
  480           if (contextName.equals("/")) {
  481               contextName = "";
  482           }
  483           if(log.isDebugEnabled())
  484               log.debug(sm.getString
  485                     ("mapperListener.registerWrapper", 
  486                      wrapperName, contextName));
  487   
  488           String[] mappings = (String[])
  489               mBeanServer.invoke(objectName, "findMappings", null, null);
  490           Object wrapper = 
  491               mBeanServer.invoke(objectName, "findMappingObject", null, null);
  492   
  493           for (int i = 0; i < mappings.length; i++) {
  494               boolean jspWildCard = (wrapperName.equals("jsp")
  495                                      && mappings[i].endsWith("/*"));
  496               mapper.addWrapper(hostName, contextName, mappings[i], wrapper,
  497                                 jspWildCard);
  498           }
  499   
  500       }
  501   
  502   
  503   
  504   
  505   }

Save This Page
Home » apache-tomcat-6.0.16-src » org.apache » catalina » connector » [javadoc | source]