⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 registry.java

📁 业界著名的tomcat服务器的最新6.0的源代码。
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*
 * 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.tomcat.util.modeler;


import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import javax.management.DynamicMBean;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.modeler.modules.ModelerSource;

/*
   Issues:
   - exceptions - too many "throws Exception"
   - double check the interfaces 
   - start removing the use of the experimental methods in tomcat, then remove
     the methods ( before 1.1 final )
   - is the security enough to prevent Registry beeing used to avoid the permission
    checks in the mbean server ?
*/ 

/**
 * Registry for modeler MBeans. 
 *
 * This is the main entry point into modeler. It provides methods to create
 * and manipulate model mbeans and simplify their use.
 *
 * Starting with version 1.1, this is no longer a singleton and the static
 * methods are strongly deprecated. In a container environment we can expect
 * different applications to use different registries.
 * 
 * This class is itself an mbean.
 * 
 * IMPORTANT: public methods not marked with @since x.x are experimental or 
 * internal. Should not be used.  
 * 
 * @author Craig R. McClanahan
 * @author Costin Manolache
 */
public class Registry implements RegistryMBean, MBeanRegistration  {
    /**
     * The Log instance to which we will write our log messages.
     */
    private static Log log = LogFactory.getLog(Registry.class);

    // Support for the factory methods
    
    /** Will be used to isolate different apps and enhance security.
     */
    private static HashMap perLoaderRegistries=null;

    /**
     * The registry instance created by our factory method the first time
     * it is called.
     */
    private static Registry registry = null;

    // Per registy fields
    
    /**
     * The <code>MBeanServer</code> instance that we will use to register
     * management beans.
     */
    private MBeanServer server = null;

    /**
     * The set of ManagedBean instances for the beans this registry
     * knows about, keyed by name.
     */
    private HashMap descriptors = new HashMap();

    /** List of managed byeans, keyed by class name
     */
    private HashMap descriptorsByClass = new HashMap();

    // map to avoid duplicated searching or loading descriptors 
    private HashMap searchedPaths=new HashMap();
    
    private Object guard;

    // Id - small ints to use array access. No reset on stop()
    // Used for notifications
    private Hashtable idDomains=new Hashtable();
    private Hashtable ids=new Hashtable();

    
    // ----------------------------------------------------------- Constructors

    /**
     */
     public Registry() {
        super();
    }

    // -------------------- Static methods  --------------------
    // Factories
    
    /**
     * Factory method to create (if necessary) and return our
     * <code>Registry</code> instance.
     *
     * Use this method to obtain a Registry - all other static methods
     * are deprecated and shouldn't be used.
     *
     * The current version uses a static - future versions could use
     * the thread class loader.
     * 
     * @param key Support for application isolation. If null, the context class
     * loader will be used ( if setUseContextClassLoader is called ) or the 
     * default registry is returned. 
     * @param guard Prevent access to the registry by untrusted components
     *
     * @since 1.1
     */
    public synchronized static Registry getRegistry(Object key, Object guard) {
        Registry localRegistry;
        if( perLoaderRegistries!=null ) {
            if( key==null ) 
                key=Thread.currentThread().getContextClassLoader();
            if( key != null ) {
                localRegistry=(Registry)perLoaderRegistries.get(key);
                if( localRegistry == null ) {
                    localRegistry=new Registry();
//                    localRegistry.key=key;
                    localRegistry.guard=guard;
                    perLoaderRegistries.put( key, localRegistry );
                    return localRegistry;
                }
                if( localRegistry.guard != null &&
                        localRegistry.guard != guard ) {
                    return null; // XXX Should I throw a permission ex ? 
                }
                return localRegistry;
            }
        }

        // static 
        if (registry == null) {
            registry = new Registry();
        }
        if( registry.guard != null &&
                registry.guard != guard ) {
            return null;
        }
        return (registry);
    }
    
    /** 
     * Allow containers to isolate apps. Can be called only once.
     * It  is highly recommended you call this method if using Registry in
     * a container environment. The default is false for backward compatibility
     * 
     * @param enable
     * @since 1.1
     */
    public static void setUseContextClassLoader( boolean enable ) {
        if( enable ) {
            perLoaderRegistries=new HashMap();
        }
    }
    
    // -------------------- Generic methods  --------------------

    /** Lifecycle method - clean up the registry metadata.
     *  Called from resetMetadata().
     * 
     * @since 1.1
     */ 
    public void stop() {
        descriptorsByClass = new HashMap();
        descriptors = new HashMap();
        searchedPaths=new HashMap();
    }
    
    /** 
     * Load an extended mlet file. The source can be an URL, File or
     * InputStream. 
     * 
     * All mbeans will be instantiated, registered and the attributes will be 
     * set. The result is a list of ObjectNames.
     *
     * @param source InputStream or URL of the file
     * @param cl ClassLoader to be used to load the mbeans, or null to use the
     *        default JMX mechanism ( i.e. all registered loaders )
     * @return List of ObjectName for the loaded mbeans
     * @throws Exception
     * 
     * @since 1.1
     */ 
    public List loadMBeans( Object source, ClassLoader cl )
            throws Exception
    {
        return load("MbeansSource", source, null );
    }    


    /** Load descriptors. The source can be a File or URL or InputStream for the 
     * descriptors file. In the case of File and URL, if the extension is ".ser"
     * a serialized version will be loaded. 
     * 
     * This method should be used to explicitely load metadata - but this is not
     * required in most cases. The registerComponent() method will find metadata
     * in the same pacakge.
     * 
     * @param source
     */ 
    public void loadMetadata(Object source ) throws Exception {
        loadDescriptors( null, source, null );
    }

    /** Register a bean by creating a modeler mbean and adding it to the 
     * MBeanServer.
     * 
     * If metadata is not loaded, we'll look up and read a file named
     * "mbeans-descriptors.ser" or "mbeans-descriptors.xml" in the same package
     * or parent.
     *
     * If the bean is an instance of DynamicMBean. it's metadata will be converted
     * to a model mbean and we'll wrap it - so modeler services will be supported
     *
     * If the metadata is still not found, introspection will be used to extract
     * it automatically. 
     * 
     * If an mbean is already registered under this name, it'll be first
     * unregistered.
     * 
     * If the component implements MBeanRegistration, the methods will be called.
     * If the method has a method "setRegistry" that takes a RegistryMBean as
     * parameter, it'll be called with the current registry.
     * 
     *
     * @param bean Object to be registered
     * @param oname Name used for registration
     * @param type The type of the mbean, as declared in mbeans-descriptors. If
     * null, the name of the class will be used. This can be used as a hint or
     * by subclasses.
     *
     * @since 1.1
     */ 
    public void registerComponent(Object bean, String oname, String type)
           throws Exception
    {
        registerComponent(bean, new ObjectName(oname), type);        
    }    

    /** Unregister a component. We'll first check if it is registered,
     * and mask all errors. This is mostly a helper.
     * 
     * @param oname
     * 
     * @since 1.1
     */ 
    public void unregisterComponent( String oname ) {
        try {
            unregisterComponent(new ObjectName(oname));
        } catch (MalformedObjectNameException e) {
            log.info("Error creating object name " + e );
        }
    }    
    

    /** Invoke a operation on a list of mbeans. Can be used to implement
     * lifecycle operations.
     *
     * @param mbeans list of ObjectName on which we'll invoke the operations
     * @param operation  Name of the operation ( init, start, stop, etc)
     * @param failFirst  If false, exceptions will be ignored
     * @throws Exception
     * @since 1.1
     */
    public void invoke( List mbeans, String operation, boolean failFirst )
            throws Exception
    {
        if( mbeans==null ) {
            return;
        }
        Iterator itr=mbeans.iterator();
        while(itr.hasNext()) {
            Object current=itr.next();
            ObjectName oN=null;
            try {
                if( current instanceof ObjectName) {
                    oN=(ObjectName)current;
                }
                if( current instanceof String ) {
                    oN=new ObjectName( (String)current );
                }
                if( oN==null ) {
                    continue;
                }
                if( getMethodInfo(oN, operation) == null) {
                    continue;
                }
                getMBeanServer().invoke(oN, operation,
                        new Object[] {}, new String[] {});

            } catch( Exception t ) {
                if( failFirst ) throw t;
                log.info("Error initializing " + current + " " + t.toString());
            }
        }
    }

    // -------------------- ID registry --------------------

    /** Return an int ID for faster access. Will be used for notifications
     * and for other operations we want to optimize. 
     *
     * @param domain Namespace 
     * @param name  Type of the notification
     * @return  An unique id for the domain:name combination
     * @since 1.1

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -