3790 lines · 147.7 KB · Java
RawDownload
/* * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.management.relation; import static com.sun.jmx.defaults.JmxProperties.RELATION_LOGGER;import static com.sun.jmx.mbeanserver.Util.cast; import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.concurrent.atomic.AtomicLong;import java.util.logging.Level; import javax.management.Attribute;import javax.management.AttributeNotFoundException;import javax.management.InstanceNotFoundException;import javax.management.InvalidAttributeValueException;import javax.management.MBeanException;import javax.management.MBeanNotificationInfo;import javax.management.MBeanRegistration;import javax.management.MBeanServer;import javax.management.MBeanServerDelegate;import javax.management.MBeanServerNotification;import javax.management.Notification;import javax.management.NotificationBroadcasterSupport;import javax.management.NotificationListener;import javax.management.ObjectName;import javax.management.ReflectionException; /** * The Relation Service is in charge of creating and deleting relation types * and relations, of handling the consistency and of providing query * mechanisms. * <P>It implements the NotificationBroadcaster by extending * NotificationBroadcasterSupport to send notifications when a relation is * removed from it. * <P>It implements the NotificationListener interface to be able to receive * notifications concerning unregistration of MBeans referenced in relation * roles and of relation MBeans. * <P>It implements the MBeanRegistration interface to be able to retrieve * its ObjectName and MBean Server. * * @since 1.5 */public class RelationService extends NotificationBroadcasterSupport    implements RelationServiceMBean, MBeanRegistration, NotificationListener {     //    // Private members    //     // Map associating:    //      <relation id> -> <RelationSupport object/ObjectName>    // depending if the relation has been created using createRelation()    // method (so internally handled) or is an MBean added as a relation by the    // user    private Map<String,Object> myRelId2ObjMap = new HashMap<String,Object>();     // Map associating:    //      <relation id> -> <relation type name>    private Map<String,String> myRelId2RelTypeMap = new HashMap<String,String>();     // Map associating:    //      <relation MBean Object Name> -> <relation id>    private Map<ObjectName,String> myRelMBeanObjName2RelIdMap =        new HashMap<ObjectName,String>();     // Map associating:    //       <relation type name> -> <RelationType object>    private Map<String,RelationType> myRelType2ObjMap =        new HashMap<String,RelationType>();     // Map associating:    //       <relation type name> -> ArrayList of <relation id>    // to list all the relations of a given type    private Map<String,List<String>> myRelType2RelIdsMap =        new HashMap<String,List<String>>();     // Map associating:    //       <ObjectName> -> HashMap    // the value HashMap mapping:    //       <relation id> -> ArrayList of <role name>    // to track where a given MBean is referenced.    private final Map<ObjectName,Map<String,List<String>>>        myRefedMBeanObjName2RelIdsMap =            new HashMap<ObjectName,Map<String,List<String>>>();     // Flag to indicate if, when a notification is received for the    // unregistration of an MBean referenced in a relation, if an immediate    // "purge" of the relations (look for the relations no    // longer valid) has to be performed , or if that will be performed only    // when the purgeRelations method will be explicitly called.    // true is immediate purge.    private boolean myPurgeFlag = true;     // Internal counter to provide sequence numbers for notifications sent by:    // - the Relation Service    // - a relation handled by the Relation Service    private final AtomicLong atomicSeqNo = new AtomicLong();     // ObjectName used to register the Relation Service in the MBean Server    private ObjectName myObjName = null;     // MBean Server where the Relation Service is registered    private MBeanServer myMBeanServer = null;     // Filter registered in the MBean Server with the Relation Service to be    // informed of referenced MBean unregistrations    private MBeanServerNotificationFilter myUnregNtfFilter = null;     // List of unregistration notifications received (storage used if purge    // of relations when unregistering a referenced MBean is not immediate but    // on user request)    private List<MBeanServerNotification> myUnregNtfList =        new ArrayList<MBeanServerNotification>();     //    // Constructor    //     /**     * Constructor.     *     * @param immediatePurgeFlag  flag to indicate when a notification is     * received for the unregistration of an MBean referenced in a relation, if     * an immediate "purge" of the relations (look for the relations no     * longer valid) has to be performed , or if that will be performed only     * when the purgeRelations method will be explicitly called.     * <P>true is immediate purge.     */    public RelationService(boolean immediatePurgeFlag) {         RELATION_LOGGER.entering(RelationService.class.getName(),                "RelationService");         setPurgeFlag(immediatePurgeFlag);         RELATION_LOGGER.exiting(RelationService.class.getName(),                "RelationService");        return;    }     /**     * Checks if the Relation Service is active.     * Current condition is that the Relation Service must be registered in the     * MBean Server     *     * @exception RelationServiceNotRegisteredException  if it is not     * registered     */    public void isActive()        throws RelationServiceNotRegisteredException {        if (myMBeanServer == null) {            // MBean Server not set by preRegister(): relation service not            // registered            String excMsg =                "Relation Service not registered in the MBean Server.";            throw new RelationServiceNotRegisteredException(excMsg);        }        return;    }     //    // MBeanRegistration interface    //     // Pre-registration: retrieves its ObjectName and MBean Server    //    // No exception thrown.    public ObjectName preRegister(MBeanServer server,                                  ObjectName name)        throws Exception {         myMBeanServer = server;        myObjName = name;        return name;    }     // Post-registration: does nothing    public void postRegister(Boolean registrationDone) {        return;    }     // Pre-unregistration: does nothing    public void preDeregister()        throws Exception {        return;    }     // Post-unregistration: does nothing    public void postDeregister() {        return;    }     //    // Accessors    //     /**     * Returns the flag to indicate if when a notification is received for the     * unregistration of an MBean referenced in a relation, if an immediate     * "purge" of the relations (look for the relations no longer valid)     * has to be performed , or if that will be performed only when the     * purgeRelations method will be explicitly called.     * <P>true is immediate purge.     *     * @return true if purges are automatic.     *     * @see #setPurgeFlag     */    public boolean getPurgeFlag() {        return myPurgeFlag;    }     /**     * Sets the flag to indicate if when a notification is received for the     * unregistration of an MBean referenced in a relation, if an immediate     * "purge" of the relations (look for the relations no longer valid)     * has to be performed , or if that will be performed only when the     * purgeRelations method will be explicitly called.     * <P>true is immediate purge.     *     * @param purgeFlag  flag     *     * @see #getPurgeFlag     */    public void setPurgeFlag(boolean purgeFlag) {         myPurgeFlag = purgeFlag;        return;    }     //    // Relation type handling    //     /**     * Creates a relation type (a RelationTypeSupport object) with given     * role infos (provided by the RoleInfo objects), and adds it in the     * Relation Service.     *     * @param relationTypeName  name of the relation type     * @param roleInfoArray  array of role infos     *     * @exception IllegalArgumentException  if null parameter     * @exception InvalidRelationTypeException  If:     * <P>- there is already a relation type with that name     * <P>- the same name has been used for two different role infos     * <P>- no role info provided     * <P>- one null role info provided     */    public void createRelationType(String relationTypeName,                                   RoleInfo[] roleInfoArray)        throws IllegalArgumentException,               InvalidRelationTypeException {         if (relationTypeName == null || roleInfoArray == null) {            String excMsg = "Invalid parameter.";            throw new IllegalArgumentException(excMsg);        }         RELATION_LOGGER.entering(RelationService.class.getName(),                "createRelationType", relationTypeName);         // Can throw an InvalidRelationTypeException        RelationType relType =            new RelationTypeSupport(relationTypeName, roleInfoArray);         addRelationTypeInt(relType);         RELATION_LOGGER.exiting(RelationService.class.getName(),                "createRelationType");        return;    }     /**     * Adds given object as a relation type. The object is expected to     * implement the RelationType interface.     *     * @param relationTypeObj  relation type object (implementing the     * RelationType interface)     *     * @exception IllegalArgumentException  if null parameter or if     * {@link RelationType#getRelationTypeName     * relationTypeObj.getRelationTypeName()} returns null.     * @exception InvalidRelationTypeException  if:     * <P>- the same name has been used for two different roles     * <P>- no role info provided     * <P>- one null role info provided     * <P>- there is already a relation type with that name     */    public void addRelationType(RelationType relationTypeObj)        throws IllegalArgumentException,               InvalidRelationTypeException {         if (relationTypeObj == null) {            String excMsg = "Invalid parameter.";            throw new IllegalArgumentException(excMsg);        }         RELATION_LOGGER.entering(RelationService.class.getName(),                "addRelationType");         // Checks the role infos        List<RoleInfo> roleInfoList = relationTypeObj.getRoleInfos();        if (roleInfoList == null) {            String excMsg = "No role info provided.";            throw new InvalidRelationTypeException(excMsg);        }         RoleInfo[] roleInfoArray = new RoleInfo[roleInfoList.size()];        int i = 0;        for (RoleInfo currRoleInfo : roleInfoList) {            roleInfoArray[i] = currRoleInfo;            i++;        }        // Can throw InvalidRelationTypeException        RelationTypeSupport.checkRoleInfos(roleInfoArray);         addRelationTypeInt(relationTypeObj);         RELATION_LOGGER.exiting(RelationService.class.getName(),                "addRelationType");        return;     }     /**     * Retrieves names of all known relation types.     *     * @return ArrayList of relation type names (Strings)     */    public List<String> getAllRelationTypeNames() {        ArrayList<String> result;        synchronized(myRelType2ObjMap) {            result = new ArrayList<String>(myRelType2ObjMap.keySet());        }        return result;    }     /**     * Retrieves list of role infos (RoleInfo objects) of a given relation     * type.     *     * @param relationTypeName  name of relation type     *     * @return ArrayList of RoleInfo.     *     * @exception IllegalArgumentException  if null parameter     * @exception RelationTypeNotFoundException  if there is no relation type     * with that name.     */    public List<RoleInfo> getRoleInfos(String relationTypeName)        throws IllegalArgumentException,               RelationTypeNotFoundException {         if (relationTypeName == null) {            String excMsg = "Invalid parameter.";            throw new IllegalArgumentException(excMsg);        }         RELATION_LOGGER.entering(RelationService.class.getName(),                "getRoleInfos", relationTypeName);         // Can throw a RelationTypeNotFoundException        RelationType relType = getRelationType(relationTypeName);         RELATION_LOGGER.exiting(RelationService.class.getName(),                "getRoleInfos");        return relType.getRoleInfos();    }     /**     * Retrieves role info for given role name of a given relation type.     *     * @param relationTypeName  name of relation type     * @param roleInfoName  name of role     *     * @return RoleInfo object.     *     * @exception IllegalArgumentException  if null parameter     * @exception RelationTypeNotFoundException  if the relation type is not     * known in the Relation Service     * @exception RoleInfoNotFoundException  if the role is not part of the     * relation type.     */    public RoleInfo getRoleInfo(String relationTypeName,                                String roleInfoName)        throws IllegalArgumentException,               RelationTypeNotFoundException,               RoleInfoNotFoundException {         if (relationTypeName == null || roleInfoName == null) {            String excMsg = "Invalid parameter.";            throw new IllegalArgumentException(excMsg);        }         RELATION_LOGGER.entering(RelationService.class.getName(),                "getRoleInfo", new Object[] {relationTypeName, roleInfoName});         // Can throw a RelationTypeNotFoundException        RelationType relType = getRelationType(relationTypeName);         // Can throw a RoleInfoNotFoundException        RoleInfo roleInfo = relType.getRoleInfo(roleInfoName);         RELATION_LOGGER.exiting(RelationService.class.getName(),                "getRoleInfo");        return roleInfo;    }     /**     * Removes given relation type from Relation Service.     * <P>The relation objects of that type will be removed from the     * Relation Service.     *     * @param relationTypeName  name of the relation type to be removed     *     * @exception RelationServiceNotRegisteredException  if the Relation     * Service is not registered in the MBean Server     * @exception IllegalArgumentException  if null parameter     * @exception RelationTypeNotFoundException  If there is no relation type     * with that name     */    public void removeRelationType(String relationTypeName)        throws RelationServiceNotRegisteredException,               IllegalArgumentException,               RelationTypeNotFoundException {         // Can throw RelationServiceNotRegisteredException        isActive();         if (relationTypeName == null) {            String excMsg = "Invalid parameter.";            throw new IllegalArgumentException(excMsg);        }         RELATION_LOGGER.entering(RelationService.class.getName(),                "removeRelationType", relationTypeName);         // Checks if the relation type to be removed exists        // Can throw a RelationTypeNotFoundException        RelationType relType = getRelationType(relationTypeName);         // Retrieves the relation ids for relations of that type        List<String> relIdList = null;        synchronized(myRelType2RelIdsMap) {            // Note: take a copy of the list as it is a part of a map that            //       will be updated by removeRelation() below.            List<String> relIdList1 =                myRelType2RelIdsMap.get(relationTypeName);            if (relIdList1 != null) {                relIdList = new ArrayList<String>(relIdList1);            }        }         // Removes the relation type from all maps        synchronized(myRelType2ObjMap) {            myRelType2ObjMap.remove(relationTypeName);        }        synchronized(myRelType2RelIdsMap) {            myRelType2RelIdsMap.remove(relationTypeName);        }         // Removes all relations of that type        if (relIdList != null) {            for (String currRelId : relIdList) {                // Note: will remove it from myRelId2RelTypeMap :)                //                // Can throw RelationServiceNotRegisteredException (detected                // above)                // Shall not throw a RelationNotFoundException                try {                    removeRelation(currRelId);

Lines 1–500 of 3790.