RelationSupport.java :  » 6.0-JDK-Core » management » javax » management » relation » Java Open Source

Java Open Source » 6.0 JDK Core » management 
management » javax » management » relation » RelationSupport.java
/*
 * Copyright 2000-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package javax.management.relation;



import java.util.ArrayList;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.List;

import static com.sun.jmx.defaults.JmxProperties.RELATION_LOGGER;
import static com.sun.jmx.mbeanserver.Util.cast;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.ReflectionException;

/**
 * A RelationSupport object is used internally by the Relation Service to
 * represent simple relations (only roles, no properties or methods), with an
 * unlimited number of roles, of any relation type. As internal representation,
 * it is not exposed to the user.
 * <P>RelationSupport class conforms to the design patterns of standard MBean. So
 * the user can decide to instantiate a RelationSupport object himself as
 * a MBean (as it follows the MBean design patterns), to register it in the
 * MBean Server, and then to add it in the Relation Service.
 * <P>The user can also, when creating his own MBean relation class, have it
 * extending RelationSupport, to retrieve the implementations of required
 * interfaces (see below).
 * <P>It is also possible to have in a user relation MBean class a member
 * being a RelationSupport object, and to implement the required interfaces by
 * delegating all to this member.
 * <P> RelationSupport implements the Relation interface (to be handled by the
 * Relation Service).
 * <P>It implements also the MBeanRegistration interface to be able to retrieve
 * the MBean Server where it is registered (if registered as a MBean) to access
 * to its Relation Service.
 *
 * @since 1.5
 */
public class RelationSupport
    implements RelationSupportMBean, MBeanRegistration {

    //
    // Private members
    //

    // Relation identifier (expected to be unique in the Relation Service where
    // the RelationSupport object will be added)
    private String myRelId = null;

    // ObjectName of the Relation Service where the relation will be added
    // REQUIRED if the RelationSupport is created by the user to be registered as
    // a MBean, as it will have to access the Relation Service via the MBean
    // Server to perform the check regarding the relation type.
    // Is null if current object is directly created by the Relation Service,
    // as the object will directly access it.
    private ObjectName myRelServiceName = null;

    // Reference to the MBean Server where the Relation Service is
    // registered
    // REQUIRED if the RelationSupport is created by the user to be registered as
    // a MBean, as it will have to access the Relation Service via the MBean
    // Server to perform the check regarding the relation type.
    // If the Relationbase object is created by the Relation Service (use of
    // createRelation() method), this is null as not needed, direct access to
    // the Relation Service.
    // If the Relationbase object is created by the user and registered as a
    // MBean, this is set by the preRegister() method below.
    private MBeanServer myRelServiceMBeanServer = null;

    // Relation type name (must be known in the Relation Service where the
    // relation will be added)
    private String myRelTypeName = null;

    // Role map, mapping <role-name> -> <Role>
    // Initialized by role list in the constructor, then updated:
    // - if the relation is a MBean, via setRole() and setRoles() methods, or
    //   via Relation Service setRole() and setRoles() methods
    // - if the relation is internal to the Relation Service, via
    //   setRoleInt() and setRolesInt() methods.
    private Map<String,Role> myRoleName2ValueMap = new HashMap<String,Role>();

    // Flag to indicate if the object has been added in the Relation Service
    private Boolean myInRelServFlg = null;

    //
    // Constructors
    //

    /**
     * Creates a {@code RelationSupport} object.
     * <P>This constructor has to be used when the RelationSupport object will
     * be registered as a MBean by the user, or when creating a user relation
     * MBean whose class extends RelationSupport.
     * <P>Nothing is done at the Relation Service level, i.e.
     * the {@code RelationSupport} object is not added to the
     * {@code RelationService} and no checks are performed to
     * see if the provided values are correct.
     * The object is always created, EXCEPT if:
     * <P>- any of the required parameters is {@code null}.
     * <P>- the same name is used for two roles.
     * <P>To be handled as a relation, the {@code RelationSupport} object has
     * to be added to the Relation Service using the Relation Service method
     * addRelation().
     *
     * @param relationId  relation identifier, to identify the relation in the
     * Relation Service.
     * <P>Expected to be unique in the given Relation Service.
     * @param relationServiceName  ObjectName of the Relation Service where
     * the relation will be registered.
     * <P>This parameter is required as it is the Relation Service that is
     * aware of the definition of the relation type of the given relation,
     * so that will be able to check update operations (set).
     * @param relationTypeName  Name of relation type.
     * <P>Expected to have been created in the given Relation Service.
     * @param list  list of roles (Role objects) to initialize the
     * relation. Can be {@code null}.
     * <P>Expected to conform to relation info in associated relation type.
     *
     * @exception InvalidRoleValueException  if the same name is used for two
     * roles.
     * @exception IllegalArgumentException  if any of the required parameters
     * (relation id, relation service ObjectName, or relation type name) is
     * {@code null}.
     */
    public RelationSupport(String relationId,
      ObjectName relationServiceName,
      String relationTypeName,
      RoleList list)
  throws InvalidRoleValueException,
               IllegalArgumentException {

  super();

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "RelationSupport");

  // Can throw InvalidRoleValueException and IllegalArgumentException
  initMembers(relationId,
        relationServiceName,
        null,
        relationTypeName,
        list);

        RELATION_LOGGER.exiting(RelationSupport.class.getName(),
                "RelationSupport");
    }

    /**
     * Creates a {@code RelationSupport} object.
     * <P>This constructor has to be used when the user relation MBean
     * implements the interfaces expected to be supported by a relation by
     * delegating to a RelationSupport object.
     * <P>This object needs to know the Relation Service expected to handle the
     * relation. So it has to know the MBean Server where the Relation Service
     * is registered.
     * <P>According to a limitation, a relation MBean must be registered in the
     * same MBean Server as the Relation Service expected to handle it. So the
     * user relation MBean has to be created and registered, and then the
     * wrapped RelationSupport object can be created within the identified MBean
     * Server.
     * <P>Nothing is done at the Relation Service level, i.e.
     * the {@code RelationSupport} object is not added to the
     * {@code RelationService} and no checks are performed to
     * see if the provided values are correct.
     * The object is always created, EXCEPT if:
     * <P>- any of the required parameters is {@code null}.
     * <P>- the same name is used for two roles.
     * <P>To be handled as a relation, the {@code RelationSupport} object has
     * to be added to the Relation Service using the Relation Service method
     * addRelation().
     *
     * @param relationId  relation identifier, to identify the relation in the
     * Relation Service.
     * <P>Expected to be unique in the given Relation Service.
     * @param relationServiceName  ObjectName of the Relation Service where
     * the relation will be registered.
     * <P>This parameter is required as it is the Relation Service that is
     * aware of the definition of the relation type of the given relation,
     * so that will be able to check update operations (set).
     * @param relationServiceMBeanServer  MBean Server where the wrapping MBean
     * is or will be registered.
     * <P>Expected to be the MBean Server where the Relation Service is or will
     * be registered.
     * @param relationTypeName  Name of relation type.
     * <P>Expected to have been created in the given Relation Service.
     * @param list  list of roles (Role objects) to initialize the
     * relation. Can be {@code null}.
     * <P>Expected to conform to relation info in associated relation type.
     *
     * @exception InvalidRoleValueException  if the same name is used for two
     * roles.
     * @exception IllegalArgumentException  if any of the required parameters
     * (relation id, relation service ObjectName, relation service MBeanServer,
     * or relation type name) is {@code null}.
     */
    public RelationSupport(String relationId,
      ObjectName relationServiceName,
      MBeanServer relationServiceMBeanServer,
      String relationTypeName,
      RoleList list)
  throws InvalidRoleValueException,
               IllegalArgumentException {

  super();

  if (relationServiceMBeanServer == null) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "RelationSupport");

  // Can throw InvalidRoleValueException and
  // IllegalArgumentException
  initMembers(relationId,
        relationServiceName,
        relationServiceMBeanServer,
        relationTypeName,
        list);

        RELATION_LOGGER.exiting(RelationSupport.class.getName(),
                "RelationSupport");
    }

    //
    // Relation Interface
    //

    /**
     * Retrieves role value for given role name.
     * <P>Checks if the role exists and is readable according to the relation
     * type.
     *
     * @param roleName  name of role
     *
     * @return the ArrayList of ObjectName objects being the role value
     *
     * @exception IllegalArgumentException  if null role name
     * @exception RoleNotFoundException  if:
     * <P>- there is no role with given name
     * <P>- the role is not readable.
     * @exception RelationServiceNotRegisteredException  if the Relation
     * Service is not registered in the MBean Server
     *
     * @see #setRole
     */
    public List<ObjectName> getRole(String roleName)
  throws IllegalArgumentException,
         RoleNotFoundException,
         RelationServiceNotRegisteredException {

  if (roleName == null) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "getRole", roleName);

  // Can throw RoleNotFoundException and
  // RelationServiceNotRegisteredException
  List<ObjectName> result = cast(
      getRoleInt(roleName, false, null, false));

        RELATION_LOGGER.exiting(RelationSupport.class.getName(), "getRole");
  return result;
    }

    /**
     * Retrieves values of roles with given names.
     * <P>Checks for each role if it exists and is readable according to the
     * relation type.
     *
     * @param roleNameArray  array of names of roles to be retrieved
     *
     * @return a RoleResult object, including a RoleList (for roles
     * successfully retrieved) and a RoleUnresolvedList (for roles not
     * retrieved).
     *
     * @exception IllegalArgumentException  if null role name
     * @exception RelationServiceNotRegisteredException  if the Relation
     * Service is not registered in the MBean Server
     *
     * @see #setRoles
     */
    public RoleResult getRoles(String[] roleNameArray)
  throws IllegalArgumentException,
         RelationServiceNotRegisteredException {

  if (roleNameArray == null) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(), "getRoles");

  // Can throw RelationServiceNotRegisteredException
  RoleResult result = getRolesInt(roleNameArray, false, null);

        RELATION_LOGGER.exiting(RelationSupport.class.getName(), "getRoles");
  return result;
    }

    /**
     * Returns all roles present in the relation.
     *
     * @return a RoleResult object, including a RoleList (for roles
     * successfully retrieved) and a RoleUnresolvedList (for roles not
     * readable).
     *
     * @exception RelationServiceNotRegisteredException  if the Relation
     * Service is not registered in the MBean Server
     */
    public RoleResult getAllRoles()
      throws RelationServiceNotRegisteredException {

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "getAllRoles");

  RoleResult result = null;
  try {
      result = getAllRolesInt(false, null);
  } catch (IllegalArgumentException exc) {
      // OK : Invalid parameters, ignore...
  }

        RELATION_LOGGER.exiting(RelationSupport.class.getName(), "getAllRoles");
  return result;
    }

    /**
     * Returns all roles in the relation without checking read mode.
     *
     * @return a RoleList
     */
    public RoleList retrieveAllRoles() {

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "retrieveAllRoles");

  RoleList result;
  synchronized(myRoleName2ValueMap) {
      result =
    new RoleList(new ArrayList<Role>(myRoleName2ValueMap.values()));
  }

        RELATION_LOGGER.exiting(RelationSupport.class.getName(),
                "retrieveAllRoles");
  return result;
    }

    /**
     * Returns the number of MBeans currently referenced in the given role.
     *
     * @param roleName  name of role
     *
     * @return the number of currently referenced MBeans in that role
     *
     * @exception IllegalArgumentException  if null role name
     * @exception RoleNotFoundException  if there is no role with given name
     */
    public Integer getRoleCardinality(String roleName)
  throws IllegalArgumentException,
         RoleNotFoundException {

  if (roleName == null) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "getRoleCardinality", roleName);

  // Try to retrieve the role
  Role role = null;
  synchronized(myRoleName2ValueMap) {
      // No null Role is allowed, so direct use of get()
      role = (myRoleName2ValueMap.get(roleName));
  }
  if (role == null) {
      int pbType = RoleStatus.NO_ROLE_WITH_NAME;
      // Will throw a RoleNotFoundException
      //
      // Will not throw InvalidRoleValueException, so catch it for the
      // compiler
      try {
    RelationService.throwRoleProblemException(pbType,
                roleName);
      } catch (InvalidRoleValueException exc) {
    // OK : Do not throw InvalidRoleValueException as
    //      a RoleNotFoundException will be thrown.
      }
  }

  ArrayList roleValue = (ArrayList)(role.getRoleValue());

        RELATION_LOGGER.exiting(RelationSupport.class.getName(),
                "getRoleCardinality");
  return new Integer(roleValue.size());
    }

    /**
     * Sets the given role.
     * <P>Will check the role according to its corresponding role definition
     * provided in relation's relation type
     * <P>Will send a notification (RelationNotification with type
     * RELATION_BASIC_UPDATE or RELATION_MBEAN_UPDATE, depending if the
     * relation is a MBean or not).
     *
     * @param role  role to be set (name and new value)
     *
     * @exception IllegalArgumentException  if null role
     * @exception RoleNotFoundException  if there is no role with the supplied
     * role's name or if the role is not writable (no test on the write access
     * mode performed when initializing the role)
     * @exception InvalidRoleValueException  if value provided for
     * role is not valid, i.e.:
     * <P>- the number of referenced MBeans in given value is less than
     * expected minimum degree
     * <P>- the number of referenced MBeans in provided value exceeds expected
     * maximum degree
     * <P>- one referenced MBean in the value is not an Object of the MBean
     * class expected for that role
     * <P>- a MBean provided for that role does not exist
     * @exception RelationServiceNotRegisteredException  if the Relation
     * Service is not registered in the MBean Server
     * @exception RelationTypeNotFoundException  if the relation type has not
     * been declared in the Relation Service
     * @exception RelationNotFoundException  if the relation has not been
     * added in the Relation Service.
     *
     * @see #getRole
     */
    public void setRole(Role role)
  throws IllegalArgumentException,
         RoleNotFoundException,
         RelationTypeNotFoundException,
         InvalidRoleValueException,
         RelationServiceNotRegisteredException,
               RelationNotFoundException {

  if (role == null) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "setRole", role);

  // Will return null :)
  Object result = setRoleInt(role, false, null, false);

        RELATION_LOGGER.exiting(RelationSupport.class.getName(), "setRole");
  return;
    }

    /**
     * Sets the given roles.
     * <P>Will check the role according to its corresponding role definition
     * provided in relation's relation type
     * <P>Will send one notification (RelationNotification with type
     * RELATION_BASIC_UPDATE or RELATION_MBEAN_UPDATE, depending if the
     * relation is a MBean or not) per updated role.
     *
     * @param list  list of roles to be set
     *
     * @return a RoleResult object, including a RoleList (for roles
     * successfully set) and a RoleUnresolvedList (for roles not
     * set).
     *
     * @exception IllegalArgumentException  if null role list
     * @exception RelationServiceNotRegisteredException  if the Relation
     * Service is not registered in the MBean Server
     * @exception RelationTypeNotFoundException  if the relation type has not
     * been declared in the Relation Service.
     * @exception RelationNotFoundException  if the relation MBean has not been
     * added in the Relation Service.
     *
     * @see #getRoles
     */
    public RoleResult setRoles(RoleList list)
  throws IllegalArgumentException,
         RelationServiceNotRegisteredException,
               RelationTypeNotFoundException,
               RelationNotFoundException {

  if (list == null) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "setRoles", list);

  RoleResult result = setRolesInt(list, false, null);

        RELATION_LOGGER.exiting(RelationSupport.class.getName(), "setRoles");
  return result;
    }

    /**
     * Callback used by the Relation Service when a MBean referenced in a role
     * is unregistered.
     * <P>The Relation Service will call this method to let the relation
     * take action to reflect the impact of such unregistration.
     * <P>BEWARE. the user is not expected to call this method.
     * <P>Current implementation is to set the role with its current value
     * (list of ObjectNames of referenced MBeans) without the unregistered
     * one.
     *
     * @param objectName  ObjectName of unregistered MBean
     * @param roleName  name of role where the MBean is referenced
     *
     * @exception IllegalArgumentException  if null parameter
     * @exception RoleNotFoundException  if role does not exist in the
     * relation or is not writable
     * @exception InvalidRoleValueException  if role value does not conform to
     * the associated role info (this will never happen when called from the
     * Relation Service)
     * @exception RelationServiceNotRegisteredException  if the Relation
     * Service is not registered in the MBean Server
     * @exception RelationTypeNotFoundException  if the relation type has not
     * been declared in the Relation Service.
     * @exception RelationNotFoundException  if this method is called for a
     * relation MBean not added in the Relation Service.
     */
    public void handleMBeanUnregistration(ObjectName objectName,
            String roleName)
  throws IllegalArgumentException,
               RoleNotFoundException,
               InvalidRoleValueException,
               RelationServiceNotRegisteredException,
               RelationTypeNotFoundException,
               RelationNotFoundException {

  if (objectName == null || roleName == null) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "handleMBeanUnregistration",
                new Object[]{objectName, roleName});

  // Can throw RoleNotFoundException, InvalidRoleValueException,
  // or RelationTypeNotFoundException
  handleMBeanUnregistrationInt(objectName,
             roleName,
             false,
             null);

        RELATION_LOGGER.exiting(RelationSupport.class.getName(),
                "handleMBeanUnregistration");
  return;
    }

    /**
     * Retrieves MBeans referenced in the various roles of the relation.
     *
     * @return a HashMap mapping:
     * <P> ObjectName -> ArrayList of String (role names)
     */
    public Map<ObjectName,List<String>> getReferencedMBeans() {

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "getReferencedMBeans");

  Map<ObjectName,List<String>> refMBeanMap =
      new HashMap<ObjectName,List<String>>();

  synchronized(myRoleName2ValueMap) {

      for (Role currRole : myRoleName2ValueMap.values()) {

    String currRoleName = currRole.getRoleName();
    // Retrieves ObjectNames of MBeans referenced in current role
    List<ObjectName> currRefMBeanList = currRole.getRoleValue();

    for (ObjectName currRoleObjName : currRefMBeanList) {

        // Sees if current MBean has been already referenced in
        // roles already seen
        List<String> mbeanRoleNameList =
      refMBeanMap.get(currRoleObjName);

        boolean newRefFlg = false;
        if (mbeanRoleNameList == null) {
      newRefFlg = true;
      mbeanRoleNameList = new ArrayList<String>();
        }
        mbeanRoleNameList.add(currRoleName);
        if (newRefFlg) {
      refMBeanMap.put(currRoleObjName, mbeanRoleNameList);
        }
    }
      }
  }

        RELATION_LOGGER.exiting(RelationSupport.class.getName(),
                "getReferencedMBeans");
  return refMBeanMap;
    }

    /**
     * Returns name of associated relation type.
     */
    public String getRelationTypeName() {
  return myRelTypeName;
    }

    /**
     * Returns ObjectName of the Relation Service handling the relation.
     *
     * @return the ObjectName of the Relation Service.
     */
    public ObjectName getRelationServiceName() {
  return myRelServiceName;
    }

    /**
     * Returns relation identifier (used to uniquely identify the relation
     * inside the Relation Service).
     *
     * @return the relation id.
     */
    public String getRelationId() {
  return myRelId;
    }

    //
    // MBeanRegistration interface
    //

    // Pre-registration: retrieves the MBean Server (useful to access to the
    // Relation Service)
    // This is the way to retrieve the MBean Server when the relation object is
    // a MBean created by the user outside of the Relation Service.
    //
    // No exception thrown.
    public ObjectName preRegister(MBeanServer server,
          ObjectName name)
  throws Exception {

  myRelServiceMBeanServer = server;
  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;
    }

    //
    // Others
    //

    /**
     * Returns an internal flag specifying if the object is still handled by
     * the Relation Service.
     */
    public Boolean isInRelationService() {
  Boolean result = null;
  synchronized(myInRelServFlg) {
      result = Boolean.valueOf(myInRelServFlg.booleanValue());
  }
  return result;
    }

    public void setRelationServiceManagementFlag(Boolean flag)
  throws IllegalArgumentException {

  if (flag == null) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }
  synchronized(myInRelServFlg) {
      myInRelServFlg = Boolean.valueOf(flag.booleanValue());
  }
  return;
    }

    //
    // Misc
    //

    // Gets the role with given name
    // Checks if the role exists and is readable according to the relation
    // type.
    //
    // This method is called in getRole() above.
    // It is also called in the Relation Service getRole() method.
    // It is also called in getRolesInt() below (used for getRoles() above
    // and for Relation Service getRoles() method).
    //
    // Depending on parameters reflecting its use (either in the scope of
    // getting a single role or of getting several roles), will return:
    // - in case of success:
    //   - for single role retrieval, the ArrayList of ObjectNames being the
    //     role value
    //   - for multi-role retrieval, the Role object itself
    // - in case of failure (except critical exceptions):
    //   - for single role retrieval, if role does not exist or is not
    //     readable, an RoleNotFoundException exception is raised
    //   - for multi-role retrieval, a RoleUnresolved object
    //
    // -param roleName  name of role to be retrieved
    // -param relationServCallFlg  true if call from the Relation Service; this
    //  will happen if the current RelationSupport object has been created by
    //  the Relation Service (via createRelation()) method, so direct access is
    //  possible.
    // -param relationServ  reference to Relation Service object, if object
    //  created by Relation Service.
    // -param multiRoleFlg  true if getting the role in the scope of a
    //  multiple retrieval.
    //
    // -return:
    //  - for single role retrieval (multiRoleFlg false):
    //    - ArrayList of ObjectName objects, value of role with given name, if
    //      the role can be retrieved
    //    - raise a RoleNotFoundException exception else
    //  - for multi-role retrieval (multiRoleFlg true):
    //    - the Role object for given role name if role can be retrieved
    //    - a RoleUnresolved object with problem.
    //
    // -exception IllegalArgumentException  if null parameter
    // -exception RoleNotFoundException  if multiRoleFlg is false and:
    //  - there is no role with given name
    //  or
    //  - the role is not readable.
    // -exception RelationServiceNotRegisteredException  if the Relation
    //  Service is not registered in the MBean Server
    Object getRoleInt(String roleName,
          boolean relationServCallFlg,
          RelationService relationServ,
          boolean multiRoleFlg)
  throws IllegalArgumentException,
         RoleNotFoundException,
         RelationServiceNotRegisteredException {

  if (roleName == null ||
      (relationServCallFlg && relationServ == null)) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "getRoleInt", roleName);

  int pbType = 0;

  Role role = null;
  synchronized(myRoleName2ValueMap) {
      // No null Role is allowed, so direct use of get()
      role = (myRoleName2ValueMap.get(roleName));
  }

  if (role == null) {
    pbType = RoleStatus.NO_ROLE_WITH_NAME;

  } else {
      // Checks if the role is readable
      Integer status = null;

      if (relationServCallFlg) {

    // Call from the Relation Service, so direct access to it,
    // avoiding MBean Server
    // Shall not throw a RelationTypeNotFoundException
    try {
        status = relationServ.checkRoleReading(roleName,
               myRelTypeName);
    } catch (RelationTypeNotFoundException exc) {
        throw new RuntimeException(exc.getMessage());
    }

      } else {

    // Call from getRole() method above
    // So we have a MBean. We must access the Relation Service
    // via the MBean Server.
    Object[] params = new Object[2];
    params[0] = roleName;
    params[1] = myRelTypeName;
    String[] signature = new String[2];
    signature[0] = "java.lang.String";
    signature[1] = "java.lang.String";
    // Can throw InstanceNotFoundException if the Relation
    // Service is not registered (to be catched in any case and
    // transformed into RelationServiceNotRegisteredException).
    //
    // Shall not throw a MBeanException, or a ReflectionException
    // or an InstanceNotFoundException
    try {
        status = (Integer)
      (myRelServiceMBeanServer.invoke(myRelServiceName,
              "checkRoleReading",
              params,
              signature));
    } catch (MBeanException exc1) {
        throw new RuntimeException("incorrect relation type");
    } catch (ReflectionException exc2) {
        throw new RuntimeException(exc2.getMessage());
    } catch (InstanceNotFoundException exc3) {
        throw new RelationServiceNotRegisteredException(
                  exc3.getMessage());
    }
      }

      pbType = status.intValue();
  }

  Object result = null;

  if (pbType == 0) {
      // Role can be retrieved

      if (!(multiRoleFlg)) {
    // Single role retrieved: returns its value
    // Note: no need to test if role value (list) not null before
    //       cloning, null value not allowed, empty list if
    //       nothing.
    result = (ArrayList)
        (((ArrayList)(role.getRoleValue())).clone());

      } else {
    // Role retrieved during multi-role retrieval: returns the
    // role
    result = (Role)(role.clone());
      }

  } else {
      // Role not retrieved

      if (!(multiRoleFlg)) {
    // Problem when retrieving a simple role: either role not
    // found or not readable, so raises a RoleNotFoundException.
    try {
        RelationService.throwRoleProblemException(pbType,
                    roleName);
        // To keep compiler happy :)
        return null;
    } catch (InvalidRoleValueException exc) {
        throw new RuntimeException(exc.getMessage());
    }

      } else {
    // Problem when retrieving a role in a multi-role retrieval:
    // returns a RoleUnresolved object
    result = new RoleUnresolved(roleName, null, pbType);
      }
  }

        RELATION_LOGGER.exiting(RelationSupport.class.getName(), "getRoleInt");
  return result;
    }

    // Gets the given roles
    // For each role, verifies if the role exists and is readable according to
    // the relation type.
    //
    // This method is called in getRoles() above and in Relation Service
    // getRoles() method.
    //
    // -param roleNameArray  array of names of roles to be retrieved
    // -param relationServCallFlg  true if call from the Relation Service; this
    //  will happen if the current RelationSupport object has been created by
    //  the Relation Service (via createRelation()) method, so direct access is
    //  possible.
    // -param relationServ  reference to Relation Service object, if object
    //  created by Relation Service.
    //
    // -return a RoleResult object
    //
    // -exception IllegalArgumentException  if null parameter
    // -exception RelationServiceNotRegisteredException  if the Relation
    //  Service is not registered in the MBean Server
    RoleResult getRolesInt(String[] roleNameArray,
         boolean relationServCallFlg,
         RelationService relationServ)
  throws IllegalArgumentException,
         RelationServiceNotRegisteredException {

  if (roleNameArray == null ||
      (relationServCallFlg && relationServ == null)) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "getRolesInt");

  RoleList roleList = new RoleList();
  RoleUnresolvedList roleUnresList = new RoleUnresolvedList();

  for (int i = 0; i < roleNameArray.length; i++) {
      String currRoleName = roleNameArray[i];

      Object currResult = null;

      // Can throw RelationServiceNotRegisteredException
      //
      // RoleNotFoundException: not possible but catch it for compiler :)
      try {
    currResult = getRoleInt(currRoleName,
          relationServCallFlg,
          relationServ,
          true);

      } catch (RoleNotFoundException exc) {
    return null; // :)
      }

      if (currResult instanceof Role) {
    // Can throw IllegalArgumentException if role is null
    // (normally should not happen :(
    try {
        roleList.add((Role)currResult);
    } catch (IllegalArgumentException exc) {
        throw new RuntimeException(exc.getMessage());
    }

      } else if (currResult instanceof RoleUnresolved) {
    // Can throw IllegalArgumentException if role is null
    // (normally should not happen :(
    try {
        roleUnresList.add((RoleUnresolved)currResult);
    } catch (IllegalArgumentException exc) {
        throw new RuntimeException(exc.getMessage());
    }
      }
  }

  RoleResult result = new RoleResult(roleList, roleUnresList);
        RELATION_LOGGER.exiting(RelationSupport.class.getName(),
                "getRolesInt");
  return result;
    }

    // Returns all roles present in the relation
    //
    // -return a RoleResult object, including a RoleList (for roles
    //  successfully retrieved) and a RoleUnresolvedList (for roles not
    //  readable).
    //
    // -exception IllegalArgumentException if null parameter
    // -exception RelationServiceNotRegisteredException  if the Relation
    //  Service is not registered in the MBean Server
    //
    RoleResult getAllRolesInt(boolean relationServCallFlg,
            RelationService relationServ)
  throws IllegalArgumentException,
         RelationServiceNotRegisteredException {

  if (relationServCallFlg && relationServ == null) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "getAllRolesInt");

  List<String> roleNameList;
  synchronized(myRoleName2ValueMap) {
      roleNameList =
    new ArrayList<String>(myRoleName2ValueMap.keySet());
  }
  String[] roleNames = new String[roleNameList.size()];
  roleNameList.toArray(roleNames);

  RoleResult result = getRolesInt(roleNames,
          relationServCallFlg,
          relationServ);

        RELATION_LOGGER.exiting(RelationSupport.class.getName(),
                "getAllRolesInt");
  return result;
    }

    // Sets the role with given value
    //
    // This method is called in setRole() above.
    // It is also called by the Relation Service setRole() method.
    // It is also called in setRolesInt() method below (used in setRoles()
    // above and in RelationService setRoles() method).
    //
    // Will check the role according to its corresponding role definition
    // provided in relation's relation type
    // Will send a notification (RelationNotification with type
    // RELATION_BASIC_UPDATE or RELATION_MBEAN_UPDATE, depending if the
    // relation is a MBean or not) if not initialization of role.
    //
    // -param aRole  role to be set (name and new value)
    // -param relationServCallFlg  true if call from the Relation Service; this
    //  will happen if the current RelationSupport object has been created by
    //  the Relation Service (via createRelation()) method, so direct access is
    //  possible.
    // -param relationServ  reference to Relation Service object, if internal
    //  relation
    // -param multiRoleFlg  true if getting the role in the scope of a
    //  multiple retrieval.
    //
    // -return (except other "critical" exceptions):
    //  - for single role retrieval (multiRoleFlg false):
    //    - null if the role has been set
    //    - raise an InvalidRoleValueException
    // else
    //  - for multi-role retrieval (multiRoleFlg true):
    //    - the Role object for given role name if role has been set
    //    - a RoleUnresolved object with problem else.
    //
    // -exception IllegalArgumentException if null parameter
    // -exception RoleNotFoundException  if multiRoleFlg is false and:
    //  - internal relation and the role does not exist
    //  or
    //  - existing role (i.e. not initializing it) and the role is not
    //    writable.
    // -exception InvalidRoleValueException  ifmultiRoleFlg is false and
    //  value provided for:
    //   - the number of referenced MBeans in given value is less than
    //     expected minimum degree
    //   or
    //   - the number of referenced MBeans in provided value exceeds expected
    //     maximum degree
    //   or
    //   - one referenced MBean in the value is not an Object of the MBean
    //     class expected for that role
    //   or
    //   - a MBean provided for that role does not exist
    // -exception RelationServiceNotRegisteredException  if the Relation
    //  Service is not registered in the MBean Server
    // -exception RelationTypeNotFoundException  if relation type unknown
    // -exception RelationNotFoundException  if a relation MBean has not been
    //  added in the Relation Service
    Object setRoleInt(Role aRole,
          boolean relationServCallFlg,
          RelationService relationServ,
          boolean multiRoleFlg)
  throws IllegalArgumentException,
         RoleNotFoundException,
         InvalidRoleValueException,
         RelationServiceNotRegisteredException,
         RelationTypeNotFoundException,
               RelationNotFoundException {

  if (aRole == null ||
      (relationServCallFlg && relationServ == null)) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "setRoleInt", new Object[] {aRole, relationServCallFlg,
                relationServ, multiRoleFlg});

  String roleName = aRole.getRoleName();
  int pbType = 0;

  // Checks if role exists in the relation
  // No error if the role does not exist in the relation, to be able to
  // handle initialization of role when creating the relation
  // (roles provided in the RoleList parameter are directly set but
  // roles automatically initialized are set using setRole())
  Role role = null;
  synchronized(myRoleName2ValueMap) {
      role = (myRoleName2ValueMap.get(roleName));
  }

  List<ObjectName> oldRoleValue;
  Boolean initFlg = null;

  if (role == null) {
      initFlg = true;
      oldRoleValue = new ArrayList<ObjectName>();

  } else {
      initFlg = false;
      oldRoleValue = role.getRoleValue();
  }

  // Checks if the role can be set: is writable (except if
  // initialization) and correct value
  try {
      Integer status = null;

      if (relationServCallFlg) {

    // Call from the Relation Service, so direct access to it,
    // avoiding MBean Server
    //
    // Shall not raise a RelationTypeNotFoundException
    status = relationServ.checkRoleWriting(aRole,
                 myRelTypeName,
                 initFlg);

      } else {

    // Call from setRole() method above
    // So we have a MBean. We must access the Relation Service
    // via the MBean Server.
    Object[] params = new Object[3];
    params[0] = aRole;
    params[1] = myRelTypeName;
    params[2] = initFlg;
    String[] signature = new String[3];
    signature[0] = "javax.management.relation.Role";
    signature[1] = "java.lang.String";
    signature[2] = "java.lang.Boolean";
    // Can throw InstanceNotFoundException if the Relation Service
    // is not registered (to be transformed into
    // RelationServiceNotRegisteredException in any case).
    //
    // Can throw a MBeanException wrapping a
    // RelationTypeNotFoundException:
    // throw wrapped exception.
    //
    // Shall not throw a ReflectionException
    status = (Integer)
        (myRelServiceMBeanServer.invoke(myRelServiceName,
                "checkRoleWriting",
                params,
                signature));
      }

      pbType = status.intValue();

  } catch (MBeanException exc2) {

      // Retrieves underlying exception
      Exception wrappedExc = exc2.getTargetException();
      if (wrappedExc instanceof RelationTypeNotFoundException) {
    throw ((RelationTypeNotFoundException)wrappedExc);

      } else {
    throw new RuntimeException(wrappedExc.getMessage());
      }

  } catch (ReflectionException exc3) {
      throw new RuntimeException(exc3.getMessage());

  } catch (RelationTypeNotFoundException exc4) {
      throw new RuntimeException(exc4.getMessage());

  } catch (InstanceNotFoundException exc5) {
      throw new RelationServiceNotRegisteredException(exc5.getMessage());
  }

  Object result = null;

  if (pbType == 0) {
      // Role can be set
      if (!(initFlg.booleanValue())) {

    // Not initializing the role
    // If role being initialized:
    // - do not send an update notification
    // - do not try to update internal map of Relation Service
    //   listing referenced MBeans, as role is initialized to an
    //   empty list

    // Sends a notification (RelationNotification)
    // Can throw a RelationNotFoundException
    sendRoleUpdateNotification(aRole,
             oldRoleValue,
             relationServCallFlg,
             relationServ);

    // Updates the role map of the Relation Service
    // Can throw RelationNotFoundException
    updateRelationServiceMap(aRole,
           oldRoleValue,
           relationServCallFlg,
           relationServ);

      }

      // Sets the role
      synchronized(myRoleName2ValueMap) {
    myRoleName2ValueMap.put(roleName,
          (Role)(aRole.clone()));
      }

      // Single role set: returns null: nothing to set in result

      if (multiRoleFlg) {
    // Multi-roles retrieval: returns the role
    result = aRole;
      }

  } else {

      // Role not set

      if (!(multiRoleFlg)) {
    // Problem when setting a simple role: either role not
    // found, not writable, or incorrect value:
    // raises appropriate exception, RoleNotFoundException or
    // InvalidRoleValueException
    RelationService.throwRoleProblemException(pbType,
                roleName);
    // To keep compiler happy :)
    return null;

      } else {
    // Problem when retrieving a role in a multi-role retrieval:
    // returns a RoleUnresolved object
    result = new RoleUnresolved(roleName,
              aRole.getRoleValue(),
              pbType);
      }
  }

        RELATION_LOGGER.exiting(RelationSupport.class.getName(), "setRoleInt");
  return result;
    }

    // Requires the Relation Service to send a notification
    // RelationNotification, with type being either:
    // - RelationNotification.RELATION_BASIC_UPDATE if the updated relation is
    //   a relation internal to the Relation Service
    // - RelationNotification.RELATION_MBEAN_UPDATE if the updated relation is
    //   a relation MBean.
    //
    // -param newRole  new role
    // -param oldRoleValue  old role value (ArrayList of ObjectNames)
    // -param relationServCallFlg  true if call from the Relation Service; this
    //  will happen if the current RelationSupport object has been created by
    //  the Relation Service (via createRelation()) method, so direct access is
    //  possible.
    // -param relationServ  reference to Relation Service object, if object
    //  created by Relation Service.
    //
    // -exception IllegalArgumentException  if null parameter provided
    // -exception RelationServiceNotRegisteredException  if the Relation
    //  Service is not registered in the MBean Server
    // -exception RelationNotFoundException if:
    //  - relation MBean
    //  and
    //  - it has not been added into the Relation Service
    private void sendRoleUpdateNotification(Role newRole,
              List<ObjectName> oldRoleValue,
              boolean relationServCallFlg,
              RelationService relationServ)
  throws IllegalArgumentException,
         RelationServiceNotRegisteredException,
         RelationNotFoundException {

  if (newRole == null ||
      oldRoleValue == null ||
      (relationServCallFlg && relationServ == null)) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "sendRoleUpdateNotification", new Object[] {newRole,
                oldRoleValue, relationServCallFlg, relationServ});

  if (relationServCallFlg) {
      // Direct call to the Relation Service
      // Shall not throw a RelationNotFoundException for an internal
      // relation
      try {
    relationServ.sendRoleUpdateNotification(myRelId,
                  newRole,
                  oldRoleValue);
      } catch (RelationNotFoundException exc) {
    throw new RuntimeException(exc.getMessage());
      }

  } else {

      Object[] params = new Object[3];
      params[0] = myRelId;
      params[1] = newRole;
      params[2] = ((ArrayList)oldRoleValue);
      String[] signature = new String[3];
      signature[0] = "java.lang.String";
      signature[1] = "javax.management.relation.Role";
      signature[2] = "java.util.List";

      // Can throw InstanceNotFoundException if the Relation Service
      // is not registered (to be transformed).
      //
      // Can throw a MBeanException wrapping a
      // RelationNotFoundException (to be raised in any case): wrapped
      // exception to be thrown
      //
      // Shall not throw a ReflectionException
      try {
    myRelServiceMBeanServer.invoke(myRelServiceName,
                 "sendRoleUpdateNotification",
                 params,
                 signature);
      } catch (ReflectionException exc1) {
    throw new RuntimeException(exc1.getMessage());
      } catch (InstanceNotFoundException exc2) {
    throw new RelationServiceNotRegisteredException(
                  exc2.getMessage());
      } catch (MBeanException exc3) {
    Exception wrappedExc = exc3.getTargetException();
    if (wrappedExc instanceof RelationNotFoundException) {
        throw ((RelationNotFoundException)wrappedExc);
    } else {
        throw new RuntimeException(wrappedExc.getMessage());
    }
      }
  }

        RELATION_LOGGER.exiting(RelationSupport.class.getName(),
                "sendRoleUpdateNotification");
  return;
    }

    // Requires the Relation Service to update its internal map handling
    // MBeans referenced in relations.
    // The Relation Service will also update its recording as a listener to
    // be informed about unregistration of new referenced MBeans, and no longer
    // informed of MBeans no longer referenced.
    //
    // -param newRole  new role
    // -param oldRoleValue  old role value (ArrayList of ObjectNames)
    // -param relationServCallFlg  true if call from the Relation Service; this
    //  will happen if the current RelationSupport object has been created by
    //  the Relation Service (via createRelation()) method, so direct access is
    //  possible.
    // -param relationServ  reference to Relation Service object, if object
    //  created by Relation Service.
    //
    // -exception IllegalArgumentException  if null parameter
    // -exception RelationServiceNotRegisteredException  if the Relation
    //  Service is not registered in the MBean Server
    // -exception RelationNotFoundException if:
    //  - relation MBean
    //  and
    //  - the relation is not added in the Relation Service
    private void updateRelationServiceMap(Role newRole,
            List<ObjectName> oldRoleValue,
            boolean relationServCallFlg,
            RelationService relationServ)
  throws IllegalArgumentException,
         RelationServiceNotRegisteredException,
         RelationNotFoundException {

  if (newRole == null ||
      oldRoleValue == null ||
      (relationServCallFlg && relationServ == null)) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "updateRelationServiceMap", new Object[] {newRole,
                oldRoleValue, relationServCallFlg, relationServ});

  if (relationServCallFlg) {
      // Direct call to the Relation Service
      // Shall not throw a RelationNotFoundException
      try {
    relationServ.updateRoleMap(myRelId,
           newRole,
           oldRoleValue);
      } catch (RelationNotFoundException exc) {
    throw new RuntimeException(exc.getMessage());
      }

  } else {
      Object[] params = new Object[3];
      params[0] = myRelId;
      params[1] = newRole;
      params[2] = oldRoleValue;
      String[] signature = new String[3];
      signature[0] = "java.lang.String";
      signature[1] = "javax.management.relation.Role";
      signature[2] = "java.util.List";
      // Can throw InstanceNotFoundException if the Relation Service
      // is not registered (to be transformed).
      // Can throw a MBeanException wrapping a RelationNotFoundException:
      // wrapped exception to be thrown
      //
      // Shall not throw a ReflectionException
      try {
    myRelServiceMBeanServer.invoke(myRelServiceName,
                 "updateRoleMap",
                 params,
                 signature);
      } catch (ReflectionException exc1) {
    throw new RuntimeException(exc1.getMessage());
      } catch (InstanceNotFoundException exc2) {
    throw new
         RelationServiceNotRegisteredException(exc2.getMessage());
      } catch (MBeanException exc3) {
    Exception wrappedExc = exc3.getTargetException();
    if (wrappedExc instanceof RelationNotFoundException) {
        throw ((RelationNotFoundException)wrappedExc);
    } else {
        throw new RuntimeException(wrappedExc.getMessage());
    }
      }
  }

        RELATION_LOGGER.exiting(RelationSupport.class.getName(),
                "updateRelationServiceMap");
  return;
    }

    // Sets the given roles
    // For each role:
    // - will check the role according to its corresponding role definition
    //   provided in relation's relation type
    // - will send a notification (RelationNotification with type
    //   RELATION_BASIC_UPDATE or RELATION_MBEAN_UPDATE, depending if the
    //   relation is a MBean or not) for each updated role.
    //
    // This method is called in setRoles() above and in Relation Service
    // setRoles() method.
    //
    // -param list  list of roles to be set
    // -param relationServCallFlg  true if call from the Relation Service; this
    //  will happen if the current RelationSupport object has been created by
    //  the Relation Service (via createRelation()) method, so direct access is
    //  possible.
    // -param relationServ  reference to Relation Service object, if object
    //  created by Relation Service.
    //
    // -return a RoleResult object
    //
    // -exception IllegalArgumentException  if null parameter
    // -exception RelationServiceNotRegisteredException  if the Relation
    //  Service is not registered in the MBean Server
    // -exception RelationTypeNotFoundException if:
    //  - relation MBean
    //  and
    //  - unknown relation type
    // -exception RelationNotFoundException if:
    //  - relation MBean
    // and
    // - not added in the RS
    RoleResult setRolesInt(RoleList list,
         boolean relationServCallFlg,
         RelationService relationServ)
  throws IllegalArgumentException,
         RelationServiceNotRegisteredException,
         RelationTypeNotFoundException,
               RelationNotFoundException {

  if (list == null ||
      (relationServCallFlg && relationServ == null)) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "setRolesInt",
                new Object[] {list, relationServCallFlg, relationServ});

  RoleList roleList = new RoleList();
  RoleUnresolvedList roleUnresList = new RoleUnresolvedList();

  for (Iterator roleIter = list.iterator();
       roleIter.hasNext();) {

      Role currRole = (Role)(roleIter.next());

      Object currResult = null;
      // Can throw:
      // RelationServiceNotRegisteredException,
      // RelationTypeNotFoundException
      //
      // Will not throw, due to parameters, RoleNotFoundException or
      // InvalidRoleValueException, but catch them to keep compiler
      // happy
      try {
    currResult = setRoleInt(currRole,
          relationServCallFlg,
          relationServ,
          true);
      } catch (RoleNotFoundException exc1) {
    // OK : Do not throw a RoleNotFoundException.
      } catch (InvalidRoleValueException exc2) {
    // OK : Do not throw an InvalidRoleValueException.
      }

      if (currResult instanceof Role) {
    // Can throw IllegalArgumentException if role is null
    // (normally should not happen :(
    try {
        roleList.add((Role)currResult);
    } catch (IllegalArgumentException exc) {
        throw new RuntimeException(exc.getMessage());
    }

      } else if (currResult instanceof RoleUnresolved) {
    // Can throw IllegalArgumentException if role is null
    // (normally should not happen :(
    try {
        roleUnresList.add((RoleUnresolved)currResult);
    } catch (IllegalArgumentException exc) {
        throw new RuntimeException(exc.getMessage());
    }
      }
  }

  RoleResult result = new RoleResult(roleList, roleUnresList);

        RELATION_LOGGER.exiting(RelationSupport.class.getName(), "setRolesInt");
  return result;
    }

    // Initializes all members
    //
    // -param relationId  relation identifier, to identify the relation in the
    // Relation Service.
    // Expected to be unique in the given Relation Service.
    // -param relationServiceName  ObjectName of the Relation Service where
    // the relation will be registered.
    // It is required as this is the Relation Service that is aware of the
    // definition of the relation type of given relation, so that will be able
    // to check update operations (set). Direct access via the Relation
    // Service (RelationService.setRole()) do not need this information but
    // as any user relation is a MBean, setRole() is part of its management
    // interface and can be called directly on the user relation MBean. So the
    // user relation MBean must be aware of the Relation Service where it will
    // be added.
    // -param relationTypeName  Name of relation type.
    // Expected to have been created in given Relation Service.
    // -param list  list of roles (Role objects) to initialized the
    // relation. Can be null.
    // Expected to conform to relation info in associated relation type.
    //
    // -exception InvalidRoleValueException  if the same name is used for two
    //  roles.
    // -exception IllegalArgumentException  if a required value (Relation
    //  Service Object Name, etc.) is not provided as parameter.
    private void initMembers(String relationId,
           ObjectName relationServiceName,
           MBeanServer relationServiceMBeanServer,
           String relationTypeName,
           RoleList list)
  throws InvalidRoleValueException,
               IllegalArgumentException {

  if (relationId == null ||
      relationServiceName == null ||
      relationTypeName == null) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "initMembers", new Object[] {relationId, relationServiceName,
                relationServiceMBeanServer, relationTypeName, list});

  myRelId = relationId;
  myRelServiceName = relationServiceName;
  myRelServiceMBeanServer = relationServiceMBeanServer;
  myRelTypeName = relationTypeName;
  // Can throw InvalidRoleValueException
  initRoleMap(list);
  myInRelServFlg = Boolean.FALSE;

        RELATION_LOGGER.exiting(RelationSupport.class.getName(), "initMembers");
  return;
    }

    // Initialize the internal role map from given RoleList parameter
    //
    // -param list  role list. Can be null.
    //  As it is a RoleList object, it cannot include null (rejected).
    //
    // -exception InvalidRoleValueException  if the same role name is used for
    //  several roles.
    //
    private void initRoleMap(RoleList list)
  throws InvalidRoleValueException {

  if (list == null) {
      return;
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "initRoleMap", list);

  synchronized(myRoleName2ValueMap) {

      for (Iterator roleIter = list.iterator();
     roleIter.hasNext();) {

    // No need to check if role is null, it is not allowed to store
    // a null role in a RoleList :)
    Role currRole = (Role)(roleIter.next());
    String currRoleName = currRole.getRoleName();

    if (myRoleName2ValueMap.containsKey(currRoleName)) {
        // Role already provided in current list
        StringBuilder excMsgStrB = new StringBuilder("Role name ");
        excMsgStrB.append(currRoleName);
        excMsgStrB.append(" used for two roles.");
        throw new InvalidRoleValueException(excMsgStrB.toString());
    }

    myRoleName2ValueMap.put(currRoleName,
          (Role)(currRole.clone()));
      }
  }

        RELATION_LOGGER.exiting(RelationSupport.class.getName(), "initRoleMap");
  return;
    }

    // Callback used by the Relation Service when a MBean referenced in a role
    // is unregistered.
    // The Relation Service will call this method to let the relation
    // take action to reflect the impact of such unregistration.
    // Current implementation is to set the role with its current value
    // (list of ObjectNames of referenced MBeans) without the unregistered
    // one.
    //
    // -param objectName  ObjectName of unregistered MBean
    // -param roleName  name of role where the MBean is referenced
    // -param relationServCallFlg  true if call from the Relation Service; this
    //  will happen if the current RelationSupport object has been created by
    //  the Relation Service (via createRelation()) method, so direct access is
    //  possible.
    // -param relationServ  reference to Relation Service object, if internal
    //  relation
    //
    // -exception IllegalArgumentException if null parameter
    // -exception RoleNotFoundException  if:
    //  - the role does not exist
    //  or
    //  - role not writable.
    // -exception InvalidRoleValueException  if value provided for:
    //   - the number of referenced MBeans in given value is less than
    //     expected minimum degree
    //   or
    //   - the number of referenced MBeans in provided value exceeds expected
    //     maximum degree
    //   or
    //   - one referenced MBean in the value is not an Object of the MBean
    //     class expected for that role
    //   or
    //   - a MBean provided for that role does not exist
    // -exception RelationServiceNotRegisteredException  if the Relation
    //  Service is not registered in the MBean Server
    // -exception RelationTypeNotFoundException if unknown relation type
    // -exception RelationNotFoundException if current relation has not been
    //  added in the RS
    void handleMBeanUnregistrationInt(ObjectName objectName,
              String roleName,
              boolean relationServCallFlg,
              RelationService relationServ)
  throws IllegalArgumentException,
               RoleNotFoundException,
               InvalidRoleValueException,
         RelationServiceNotRegisteredException,
         RelationTypeNotFoundException,
               RelationNotFoundException {

  if (objectName == null ||
      roleName == null ||
      (relationServCallFlg && relationServ == null)) {
      String excMsg = "Invalid parameter.";
      throw new IllegalArgumentException(excMsg);
  }

        RELATION_LOGGER.entering(RelationSupport.class.getName(),
                "handleMBeanUnregistrationInt", new Object[] {objectName,
                roleName, relationServCallFlg, relationServ});

  // Retrieves current role value
  Role role = null;
  synchronized(myRoleName2ValueMap) {
      role = (myRoleName2ValueMap.get(roleName));
  }

  if (role == null) {
      StringBuilder excMsgStrB = new StringBuilder();
      String excMsg = "No role with name ";
      excMsgStrB.append(excMsg);
      excMsgStrB.append(roleName);
      throw new RoleNotFoundException(excMsgStrB.toString());
  }
  List<ObjectName> currRoleValue = role.getRoleValue();

  // Note: no need to test if list not null before cloning, null value
  //       not allowed for role value.
  List<ObjectName> newRoleValue = new ArrayList<ObjectName>(currRoleValue);
  newRoleValue.remove(objectName);
  Role newRole = new Role(roleName, newRoleValue);

  // Can throw InvalidRoleValueException,
  // RelationTypeNotFoundException
  // (RoleNotFoundException already detected)
  Object result =
      setRoleInt(newRole, relationServCallFlg, relationServ, false);

        RELATION_LOGGER.exiting(RelationSupport.class.getName(),
                "handleMBeanUnregistrationInt");
  return;
    }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.