();
// Flag to indicate if the object has been added in the Relation Service
private final AtomicBoolean myInRelServFlg = new AtomicBoolean();
//
// Constructors
//
/**
* Creates a {@code RelationSupport} object.
* 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.
*
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:
*
- any of the required parameters is {@code null}.
*
- the same name is used for two roles.
*
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.
*
Expected to be unique in the given Relation Service.
* @param relationServiceName ObjectName of the Relation Service where
* the relation will be registered.
*
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.
*
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}.
*
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.
*
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.
*
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.
*
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.
*
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:
*
- any of the required parameters is {@code null}.
*
- the same name is used for two roles.
*
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.
*
Expected to be unique in the given Relation Service.
* @param relationServiceName ObjectName of the Relation Service where
* the relation will be registered.
*
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.
*
Expected to be the MBean Server where the Relation Service is or will
* be registered.
* @param relationTypeName Name of relation type.
*
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}.
*
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.
*
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:
*
- there is no role with given name
*
- the role is not readable.
* @exception RelationServiceNotRegisteredException if the Relation
* Service is not registered in the MBean Server
*
* @see #setRole
*/
public List 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 result = cast(
getRoleInt(roleName, false, null, false));
RELATION_LOGGER.exiting(RelationSupport.class.getName(), "getRole");
return result;
}
/**
* Retrieves values of roles with given names.
* 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(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;
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.
}
}
List roleValue = role.getRoleValue();
RELATION_LOGGER.exiting(RelationSupport.class.getName(),
"getRoleCardinality");
return roleValue.size();
}
/**
* Sets the given 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).
*
* @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.:
*
- the number of referenced MBeans in given value is less than
* expected minimum degree
*
- the number of referenced MBeans in provided value exceeds expected
* maximum degree
*
- one referenced MBean in the value is not an Object of the MBean
* class expected for that role
*
- 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.
*
Will check the role according to its corresponding role definition
* provided in relation's relation type
*
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.
*
The Relation Service will call this method to let the relation
* take action to reflect the impact of such unregistration.
*
BEWARE. the user is not expected to call this method.
*
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:
*
ObjectName -> ArrayList of String (role names)
*/
public Map> getReferencedMBeans() {
RELATION_LOGGER.entering(RelationSupport.class.getName(),
"getReferencedMBeans");
Map> refMBeanMap =
new HashMap>();
synchronized(myRoleName2ValueMap) {
for (Role currRole : myRoleName2ValueMap.values()) {
String currRoleName = currRole.getRoleName();
// Retrieves ObjectNames of MBeans referenced in current role
List currRefMBeanList = currRole.getRoleValue();
for (ObjectName currRoleObjName : currRefMBeanList) {
// Sees if current MBean has been already referenced in
// roles already seen
List mbeanRoleNameList =
refMBeanMap.get(currRoleObjName);
boolean newRefFlg = false;
if (mbeanRoleNameList == null) {
newRefFlg = true;
mbeanRoleNameList = new ArrayList();
}
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() {
return myInRelServFlg.get();
}
public void setRelationServiceManagementFlag(Boolean flag)
throws IllegalArgumentException {
if (flag == null) {
String excMsg = "Invalid parameter.";
throw new IllegalArgumentException(excMsg);
}
myInRelServFlg.set(flag);
}
//
// 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;
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;
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;
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 = new ArrayList(role.getRoleValue());
} 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;
// 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 roleNameList;
synchronized(myRoleName2ValueMap) {
roleNameList =
new ArrayList(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;
synchronized(myRoleName2ValueMap) {
role = (myRoleName2ValueMap.get(roleName));
}
List oldRoleValue;
Boolean initFlg;
if (role == null) {
initFlg = true;
oldRoleValue = new ArrayList();
} else {
initFlg = false;
oldRoleValue = role.getRoleValue();
}
// Checks if the role can be set: is writable (except if
// initialization) and correct value
try {
Integer status;
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 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] = 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 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 (Role currRole : list.asList()) {
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);
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 (Role currRole : list.asList()) {
// No need to check if role is null, it is not allowed to store
// a null role in a RoleList :)
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;
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 currRoleValue = role.getRoleValue();
// Note: no need to test if list not null before cloning, null value
// not allowed for role value.
List newRoleValue = new ArrayList(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;
}
}