package javax.management.relation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import javax.management.Attribute;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanException;
import javax.management.MBeanNotificationInfo;
import javax.management.MBeanRegistration;
import javax.management.MBeanServer;
import javax.management.MBeanServerNotification;
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import org.jboss.logging.Logger;
import org.jboss.mx.server.MBeanServerImpl;
public class RelationService
extends NotificationBroadcasterSupport
implements RelationServiceMBean, MBeanRegistration, NotificationListener
{
private static final long serialVersionUID = 5434016005679159613L;
private static final Logger log = Logger.getLogger(RelationService.class);
private HashMap idsByRelation = new HashMap();
private ObjectName relationService;
private long notificationSequence = 0;
private boolean purgeFlag;
private HashMap relationsById = new HashMap();
private MBeanServer server;
private HashMap typesByName = new HashMap();
private HashMap typeNamesById = new HashMap();
private MBeanServerNotificationFilter filter;
private Stack unregistered = new Stack();
private HashMap idRolesMapByMBean = new HashMap();
private ObjectName delegate;
public RelationService(boolean purgeFlag)
{
setPurgeFlag(purgeFlag);
}
public synchronized void addRelation(ObjectName relation)
throws IllegalArgumentException, NoSuchMethodException,
RelationServiceNotRegisteredException, InvalidRelationIdException,
InvalidRelationServiceException, RelationTypeNotFoundException,
InvalidRoleValueException, RoleNotFoundException,
InstanceNotFoundException
{
if (relation == null)
throw new IllegalArgumentException("null relation");
isActive();
ObjectName otherService = null;
String relationId = null;
String relationTypeName = null;
RoleList roleList = null;
try
{
server.isInstanceOf(relation, Relation.class.getName());
otherService = (ObjectName) server.getAttribute(relation,
"RelationServiceName");
relationId = (String) server.getAttribute(relation, "RelationId");
relationTypeName = (String) server.getAttribute(relation,
"RelationTypeName");
roleList = (RoleList) server.invoke(relation, "retrieveAllRoles",
new Object[0], new String[0]);
}
catch (InstanceNotFoundException e)
{
throw e;
}
catch (Exception e)
{
throw new NoSuchMethodException("Not a relation or not registered");
}
if (relationId == null)
throw new InvalidRelationIdException("Null relation id");
if (otherService == null || otherService.equals(relationService) == false)
throw new InvalidRelationServiceException(otherService + " != " +
relationService);
RoleList copy = new RoleList(roleList);
createMissingRoles(relationTypeName, copy);
RoleValidator.validateRoles(relationService, server, relationTypeName,
copy, false);
validateAndAddRelation(relationId, relation, relationTypeName);
filter.enableObjectName(relation);
}
public synchronized void addRelationType(RelationType relationType)
throws IllegalArgumentException, InvalidRelationTypeException
{
if (relationType == null)
throw new IllegalArgumentException("null relation type");
synchronized (typesByName)
{
String name = relationType.getRelationTypeName();
if (name == null)
throw new IllegalArgumentException("Null relation type name in relation type");
if (typesByName.containsKey(name))
throw new InvalidRelationTypeException("duplicate relation id: " + name);
validateRelationType(relationType);
typesByName.put(name, relationType);
}
}
public Integer checkRoleReading(String roleName, String relationTypeName)
throws IllegalArgumentException, RelationTypeNotFoundException
{
if (roleName == null)
throw new IllegalArgumentException("Null role name");
RelationType relationType = retrieveRelationTypeForName(relationTypeName);
RoleInfo roleInfo = null;
try
{
roleInfo = relationType.getRoleInfo(roleName);
}
catch (RoleInfoNotFoundException e)
{
return new Integer(RoleStatus.NO_ROLE_WITH_NAME);
}
if (roleInfo.isReadable() == false)
return new Integer(RoleStatus.ROLE_NOT_READABLE);
return new Integer(0);
}
public Integer checkRoleWriting(Role role, String relationTypeName,
Boolean initFlag)
throws IllegalArgumentException, RelationTypeNotFoundException
{
if (role == null)
throw new IllegalArgumentException("Null role name");
if (initFlag == null)
throw new IllegalArgumentException("Null init flag");
RelationType relationType = retrieveRelationTypeForName(relationTypeName);
RoleInfo roleInfo = null;
try
{
roleInfo = relationType.getRoleInfo(role.getRoleName());
}
catch (RoleInfoNotFoundException e)
{
return new Integer(RoleStatus.NO_ROLE_WITH_NAME);
}
if (initFlag.booleanValue() == false && roleInfo.isWritable() == false)
return new Integer(RoleStatus.ROLE_NOT_WRITABLE);
ArrayList mbeans = (ArrayList) role.getRoleValue();
int beanCount = mbeans.size();
int minimum = roleInfo.getMinDegree();
if (minimum != RoleInfo.ROLE_CARDINALITY_INFINITY && minimum > beanCount)
return new Integer(RoleStatus.LESS_THAN_MIN_ROLE_DEGREE);
int maximum = roleInfo.getMaxDegree();
if (maximum != RoleInfo.ROLE_CARDINALITY_INFINITY && maximum < beanCount)
return new Integer(RoleStatus.MORE_THAN_MAX_ROLE_DEGREE);
String className = roleInfo.getRefMBeanClassName();
Iterator iterator = mbeans.iterator();
while (iterator.hasNext())
{
try
{
ObjectName objectName = (ObjectName) iterator.next();
if (server.isInstanceOf(objectName, className) == false)
return new Integer(RoleStatus.REF_MBEAN_OF_INCORRECT_CLASS);
}
catch (Exception e)
{
return new Integer(RoleStatus.REF_MBEAN_NOT_REGISTERED);
}
}
return new Integer(0);
}
public synchronized void createRelation(String relationId,
String relationTypeName, RoleList roleList)
throws IllegalArgumentException,
RelationServiceNotRegisteredException, InvalidRelationIdException,
RelationTypeNotFoundException, InvalidRoleValueException,
RoleNotFoundException
{
RoleList copy = null;
if (roleList != null)
copy = new RoleList(roleList);
else
copy = new RoleList();
isActive();
RelationSupport relation = new RelationSupport(relationId,
relationService,
server,
relationTypeName,
copy);
createMissingRoles(relationTypeName, copy);
RoleValidator.validateRoles(relationService, server, relationTypeName,
copy, false);
validateAndAddRelation(relationId, relation, relationTypeName);
}
public synchronized void createRelationType(String relationTypeName,
RoleInfo[] roleInfos)
throws IllegalArgumentException, InvalidRelationTypeException
{
if (relationTypeName == null)
throw new IllegalArgumentException("null relation type name");
synchronized (typesByName)
{
if (typesByName.containsKey(relationTypeName))
throw new InvalidRelationTypeException("duplicate relation id: "
+ relationTypeName);
RelationType relationType = new RelationTypeSupport(relationTypeName,
roleInfos);
typesByName.put(relationTypeName, relationType);
}
}
public Map findAssociatedMBeans(ObjectName mbeanName,
String relationTypeName, String roleName)
throws IllegalArgumentException
{
HashMap referencing = (HashMap) findReferencingRelations(mbeanName,
relationTypeName,
roleName);
HashMap result = new HashMap();
Iterator relationIterator = referencing.entrySet().iterator();
while (relationIterator.hasNext())
{
Map.Entry referencingEntry = (Map.Entry) relationIterator.next();
String relationId = (String) referencingEntry.getKey();
HashMap referenced = null;
try
{
referenced = (HashMap) getReferencedMBeans(relationId);
}
catch (RelationNotFoundException e)
{
throw new RuntimeException(e.toString());
}
Iterator mbeanIterator = referenced.entrySet().iterator();
while (mbeanIterator.hasNext())
{
Map.Entry referencedEntry = (Map.Entry) mbeanIterator.next();
ObjectName objectName = (ObjectName) referencedEntry.getKey();
if (objectName.equals(mbeanName) == false)
{
ArrayList resultList = (ArrayList) result.get(objectName);
if (resultList == null)
{
resultList = new ArrayList();
resultList.add(relationId);
result.put(objectName, resultList);
}
else if (resultList.contains(relationId) == false)
resultList.add(relationId);
}
}
}
return result;
}
public Map findReferencingRelations(ObjectName mbeanName,
String relationTypeName, String roleName)
throws IllegalArgumentException
{
if (mbeanName == null)
throw new IllegalArgumentException("null object name");
HashMap result = new HashMap();
HashMap idRolesMap = (HashMap) idRolesMapByMBean.get(mbeanName);
if (idRolesMap == null)
return result;
Iterator iterator = idRolesMap.entrySet().iterator();
while (iterator.hasNext())
{
Map.Entry entry = (Map.Entry) iterator.next();
String relationId = (String) entry.getKey();
HashSet roleNames = (HashSet) entry.getValue();
if (relationTypeName == null ||
typeNamesById.get(relationId).equals(relationTypeName))
{
ArrayList resultRoleNames = new ArrayList();
if (roleName == null)
resultRoleNames.addAll(roleNames);
else if (roleNames.contains(roleName) &&
resultRoleNames.contains(roleName) == false)
resultRoleNames.add(roleName);
if (resultRoleNames.size() > 0)
result.put(relationId, resultRoleNames);
}
}
return result;
}
public List findRelationsOfType(String relationTypeName)
throws IllegalArgumentException, RelationTypeNotFoundException
{
if (relationTypeName == null)
throw new IllegalArgumentException("null relation type name");
if (typesByName.containsKey(relationTypeName) == false)
throw new RelationTypeNotFoundException("relation type name not found");
ArrayList result = new ArrayList();
Iterator iterator = typeNamesById.entrySet().iterator();
while (iterator.hasNext())
{
Map.Entry entry = (Map.Entry) iterator.next();
String typeName = (String) entry.getValue();
if (typeName.equals(relationTypeName))
result.add(entry.getKey());
}
return result;
}
public List getAllRelationIds()
{
ArrayList result = new ArrayList(relationsById.size());
synchronized (relationsById)
{
Iterator iterator = relationsById.keySet().iterator();
while (iterator.hasNext())
result.add(iterator.next());
}
return result;
}
public List getAllRelationTypeNames()
{
ArrayList result = new ArrayList(typesByName.size());
synchronized (typesByName)
{
Iterator iterator = typesByName.keySet().iterator();
while (iterator.hasNext())
result.add(iterator.next());
}
return result;
}
public RoleResult getAllRoles(String relationId)
throws IllegalArgumentException, RelationNotFoundException,
RelationServiceNotRegisteredException
{
isActive();
Object relation = retrieveRelationForId(relationId);
if (relation instanceof RelationSupport)
{
return ((RelationSupport) relation).getAllRoles();
}
else
{
ObjectName objectName = (ObjectName) relation;
try
{
return (RoleResult) server.getAttribute(objectName, "AllRoles");
}
catch (InstanceNotFoundException e)
{
throw new RelationNotFoundException(objectName.toString());
}
catch (Exception e)
{
throw new RuntimeException(e.toString());
}
}
}
public boolean getPurgeFlag()
{
return purgeFlag;
}
public Map getReferencedMBeans(String relationId)
throws IllegalArgumentException, RelationNotFoundException
{
Object relation = retrieveRelationForId(relationId);
if (relation instanceof RelationSupport)
{
return ((RelationSupport) relation).getReferencedMBeans();
}
else
{
ObjectName objectName = (ObjectName) relation;
try
{
return (Map) server.getAttribute(objectName, "ReferencedMBeans");
}
catch (InstanceNotFoundException e)
{
throw new RelationNotFoundException(objectName.toString());
}
catch (Exception e)
{
throw new RuntimeException(e.toString());
}
}
}
public String getRelationTypeName(String relationId)
throws IllegalArgumentException, RelationNotFoundException
{
return retrieveTypeNameForId(relationId);
}
public List getRole(String relationId, String roleName)
throws IllegalArgumentException, RelationNotFoundException,
RelationServiceNotRegisteredException, RoleNotFoundException
{
if (roleName == null)
throw new IllegalArgumentException("null role");
isActive();
Object relation = retrieveRelationForId(relationId);
if (relation instanceof RelationSupport)
{
return ((RelationSupport) relation).getRole(roleName);
}
else
{
ObjectName objectName = (ObjectName) relation;
try
{
List result = (List) server.invoke(objectName, "getRole",
new Object[]{roleName},
new String[]{"java.lang.String"});
return result;
}
catch (InstanceNotFoundException e)
{
throw new RelationNotFoundException(objectName.toString());
}
catch (MBeanException mbe)
{
Exception e = mbe.getTargetException();
if (e instanceof RoleNotFoundException)
throw (RoleNotFoundException) e;
else
throw new RuntimeException(e.toString());
}
catch (ReflectionException e)
{
throw new RuntimeException(e.toString());
}
}
}
public Integer getRoleCardinality(String relationId, String roleName)
throws IllegalArgumentException, RelationNotFoundException,
RoleNotFoundException
{
if (roleName == null)
throw new IllegalArgumentException("null role");
Object relation = retrieveRelationForId(relationId);
if (relation instanceof RelationSupport)
{
return ((RelationSupport) relation).getRoleCardinality(roleName);
}
else
{
ObjectName objectName = (ObjectName) relation;
try
{
Integer result = (Integer) server.invoke(
objectName, "getRoleCardinality",
new Object[]{roleName},
new String[]{"java.lang.String"});
return result;
}
catch (InstanceNotFoundException e)
{
throw new RelationNotFoundException(objectName.toString());
}
catch (MBeanException mbe)
{
Exception e = mbe.getTargetException();
if (e instanceof RoleNotFoundException)
throw (RoleNotFoundException) e;
else
throw new RuntimeException(e.toString());
}
catch (ReflectionException e)
{
throw new RuntimeException(e.toString());
}
}
}
public RoleInfo getRoleInfo(String relationTypeName, String roleInfoName)
throws IllegalArgumentException, RelationTypeNotFoundException,
RoleInfoNotFoundException
{
RelationType relationType = retrieveRelationTypeForName(relationTypeName);
return relationType.getRoleInfo(roleInfoName);
}
public List getRoleInfos(String relationTypeName)
throws IllegalArgumentException, RelationTypeNotFoundException
{
RelationType relationType = retrieveRelationTypeForName(relationTypeName);
return relationType.getRoleInfos();
}
public RoleResult getRoles(String relationId, String[] roleNames)
throws IllegalArgumentException, RelationNotFoundException,
RelationServiceNotRegisteredException
{
if (roleNames == null)
throw new IllegalArgumentException("null role names");
isActive();
Object relation = retrieveRelationForId(relationId);
if (relation instanceof RelationSupport)
{
return ((RelationSupport) relation).getRoles(roleNames);
}
else
{
ObjectName objectName = (ObjectName) relation;
try
{
RoleResult result = (RoleResult) server.invoke(objectName, "getRoles",
new Object[]{roleNames},
new String[]{new String[0].getClass().getName()});
return result;
}
catch (InstanceNotFoundException e)
{
throw new RelationNotFoundException(objectName.toString());
}
catch (MBeanException e)
{
throw new RuntimeException(e.toString());
}
catch (ReflectionException e)
{
throw new RuntimeException(e.toString());
}
}
}
public Boolean hasRelation(String relationId)
throws IllegalArgumentException
{
if (relationId == null)
throw new IllegalArgumentException("null relation id");
return new Boolean(relationsById.get(relationId) != null);
}
public void isActive()
throws RelationServiceNotRegisteredException
{
if (server == null)
throw new RelationServiceNotRegisteredException("Not registered");
}
public String isRelation(ObjectName objectName)
throws IllegalArgumentException
{
if (objectName == null)
throw new IllegalArgumentException("null object name");
return (String) idsByRelation.get(objectName);
}
public ObjectName isRelationMBean(String relationId)
throws IllegalArgumentException, RelationNotFoundException
{
if (relationId == null)
throw new IllegalArgumentException("null relation id");
Object result = relationsById.get(relationId);
if (result == null)
throw new RelationNotFoundException(relationId);
if (result instanceof ObjectName)
return (ObjectName) result;
else
return null;
}
public void purgeRelations()
throws RelationServiceNotRegisteredException
{
isActive();
while (unregistered.empty() == false)
{
ObjectName mbean = (ObjectName) unregistered.pop();
HashMap relationRoles = new HashMap();
HashMap idRolesMap = (HashMap) idRolesMapByMBean.get(mbean);
Iterator iterator = idRolesMap.entrySet().iterator();
while (iterator.hasNext())
{
Map.Entry entry = (Map.Entry) iterator.next();
String relationId = (String) entry.getKey();
HashSet roleNames = (HashSet) entry.getValue();
Iterator inner = roleNames.iterator();
while (inner.hasNext())
{
String roleName = (String) inner.next();
relationRoles.put(relationId, roleName);
}
}
iterator = relationRoles.entrySet().iterator();
while (iterator.hasNext())
{
Map.Entry entry = (Map.Entry) iterator.next();
String relationId = (String) entry.getKey();
String roleName = (String) entry.getValue();
Object relation = relationsById.get(relationId);
String typeName = (String) typeNamesById.get(relationId);
RelationType relationType = (RelationType) typesByName.get(typeName);
if (relation instanceof RelationSupport)
{
RelationSupport support = (RelationSupport) relation;
try
{
Integer cardinality = support.getRoleCardinality(roleName);
RoleInfo roleInfo = relationType.getRoleInfo(roleName);
int minDegree = roleInfo.getMinDegree();
if (cardinality.intValue() == minDegree)
removeRelation(relationId);
else
support.handleMBeanUnregistration(mbean, roleName);
}
catch (Exception e)
{
log.debug("Error during purge", e);
}
}
else
{
try
{
ObjectName objectName = (ObjectName) relation;
Integer cardinality = (Integer) server.invoke(
objectName, "getRoleCardinality",
new Object[]{roleName},
new String[]{"java.lang.String"});
RoleInfo roleInfo = relationType.getRoleInfo(roleName);
int minDegree = roleInfo.getMinDegree();
if (cardinality.intValue() == minDegree)
removeRelation(relationId);
else
server.invoke(objectName, "handleMBeanUnregistration",
new Object[]{mbean, roleName},
new String[]{"java.lang.String", "java.lang.String "});
}
catch (MBeanException mbe)
{
log.debug("Error during purge", mbe.getTargetException());
}
catch (Exception e)
{
log.debug("Error during purge", e);
}
}
}
}
}
public synchronized void removeRelation(String relationId)
throws IllegalArgumentException, RelationNotFoundException,
RelationServiceNotRegisteredException
{
isActive();
ArrayList unregMBeans = new ArrayList(
getReferencedMBeans(relationId).keySet());
Iterator iterator = unregMBeans.iterator();
while (iterator.hasNext())
{
ObjectName mbean = (ObjectName) iterator.next();
HashMap idRolesMap = (HashMap) idRolesMapByMBean.get(mbean);
idRolesMap.remove(relationId);
if (idRolesMap.size() == 0)
idRolesMapByMBean.remove(mbean);
if (idsByRelation.containsKey(mbean) == false)
iterator.remove();
}
sendRelationRemovalNotification(relationId, unregMBeans);
Object relation = retrieveRelationForId(relationId);
relationsById.remove(relationId);
idsByRelation.remove(relation);
typeNamesById.remove(relationId);
if (relation instanceof ObjectName)
{
try
{
Attribute attribute = new Attribute("RelationServiceManagementFlag",
new Boolean(false));
server.setAttribute((ObjectName) relation, attribute);
}
catch (Exception doesntImplementRelationSupportMBean)
{
}
filter.disableObjectName((ObjectName) relation);
}
}
public synchronized void removeRelationType(String relationTypeName)
throws IllegalArgumentException, RelationTypeNotFoundException,
RelationServiceNotRegisteredException
{
if (relationTypeName == null)
throw new IllegalArgumentException("null relation type name");
isActive();
if (typesByName.containsKey(relationTypeName) == false)
throw new RelationTypeNotFoundException("relation type name not found");
ArrayList ids = new ArrayList();
Map.Entry entry;
Iterator iterator = typeNamesById.entrySet().iterator();
while (iterator.hasNext())
{
entry = (Map.Entry) iterator.next();
if (entry.getValue().equals(relationTypeName))
ids.add(entry.getKey());
}
iterator = ids.iterator();
while (iterator.hasNext())
{
try
{
removeRelation((String) iterator.next());
}
catch (RelationNotFoundException ignored)
{
}
}
typesByName.remove(relationTypeName);
}
public void sendRelationCreationNotification(String relationId)
throws IllegalArgumentException, RelationNotFoundException
{
String type = null;
String description = null;
if (relationsById.get(relationId) instanceof RelationSupport)
{
type = RelationNotification.RELATION_BASIC_CREATION;
description = "Creation of internal relation.";
}
else
{
type = RelationNotification.RELATION_MBEAN_CREATION;
description = "Creation of external relation.";
}
sendNotification(type, description, relationId, null, null, null);
}
public void sendRelationRemovalNotification(String relationId,
List unregMBeans)
throws IllegalArgumentException, RelationNotFoundException
{
String type = null;
String description = null;
if (relationsById.get(relationId) instanceof RelationSupport)
{
type = RelationNotification.RELATION_BASIC_REMOVAL;
description = "Removal of internal relation.";
}
else
{
type = RelationNotification.RELATION_MBEAN_REMOVAL;
description = "Removal of external relation.";
}
sendNotification(type, description, relationId, unregMBeans, null, null);
}
public void sendRoleUpdateNotification(String relationId,
Role newRole, List oldRoleValue)
throws IllegalArgumentException, RelationNotFoundException
{
String type = null;
String description = null;
if (relationsById.get(relationId) instanceof RelationSupport)
{
type = RelationNotification.RELATION_BASIC_UPDATE;
description = "Update of internal relation.";
}
else
{
type = RelationNotification.RELATION_MBEAN_UPDATE;
description = "Update of external relation.";
}
if (newRole == null)
throw new IllegalArgumentException("null role");
if (oldRoleValue == null)
throw new IllegalArgumentException("null old role value");
sendNotification(type, description, relationId, null, newRole, oldRoleValue);
}
public void setPurgeFlag(boolean value)
{
purgeFlag = value;
}
public void setRole(String relationId, Role role)
throws RelationServiceNotRegisteredException,
IllegalArgumentException,
RelationNotFoundException,
RoleNotFoundException,
InvalidRoleValueException
{
if (role == null)
throw new IllegalArgumentException("null role");
isActive();
Object relation = retrieveRelationForId(relationId);
if (relation instanceof RelationSupport)
{
try
{
((RelationSupport) relation).setRole(role);
}
catch(RelationTypeNotFoundException e)
{
RelationNotFoundException rnfe = new RelationNotFoundException(e.getMessage());
rnfe.initCause(e);
throw rnfe;
}
}
else
{
ObjectName objectName = (ObjectName) relation;
try
{
server.setAttribute(objectName, new Attribute("Role", role));
}
catch (InstanceNotFoundException e)
{
throw new RelationNotFoundException(objectName.toString());
}
catch (MBeanException mbe)
{
Exception e = mbe.getTargetException();
if (e instanceof RoleNotFoundException)
throw (RoleNotFoundException) e;
else if (e instanceof InvalidRoleValueException)
throw (InvalidRoleValueException) e;
else
throw new RuntimeException(e.toString());
}
catch (AttributeNotFoundException e)
{
throw new RuntimeException(e.toString());
}
catch (InvalidAttributeValueException e)
{
throw new RuntimeException(e.toString());
}
catch (ReflectionException e)
{
throw new RuntimeException(e.toString());
}
}
}
public RoleResult setRoles(String relationId, RoleList roles)
throws IllegalArgumentException, RelationServiceNotRegisteredException,
RelationNotFoundException
{
if (roles == null)
throw new IllegalArgumentException("null roles");
isActive();
Object relation = retrieveRelationForId(relationId);
if (relation instanceof RelationSupport)
{
try
{
return ((RelationSupport) relation).setRoles(roles);
}
catch (RelationTypeNotFoundException e)
{
throw new RuntimeException(e.toString());
}
}
else
{
ObjectName objectName = (ObjectName) relation;
try
{
RoleResult result = (RoleResult) server.invoke(objectName, "setRoles",
new Object[]{roles},
new String[]{"javax.management.relation.RoleList"});
return result;
}
catch (InstanceNotFoundException e)
{
throw new RelationNotFoundException(objectName.toString());
}
catch (MBeanException e)
{
throw new RuntimeException(e.getTargetException().toString());
}
catch (ReflectionException e)
{
throw new RuntimeException(e.toString());
}
}
}
public void updateRoleMap(String relationId, Role newRole,
List oldRoleValue)
throws IllegalArgumentException, RelationServiceNotRegisteredException,
RelationNotFoundException
{
if (relationId == null)
throw new IllegalArgumentException("null relation id");
if (newRole == null)
throw new IllegalArgumentException("null role");
if (oldRoleValue == null)
throw new IllegalArgumentException("null old role value");
isActive();
if (relationsById.containsKey(relationId) == false)
throw new RelationNotFoundException("Invalid relation id: " + relationId);
String roleName = newRole.getRoleName();
ArrayList newRoleValue = (ArrayList) newRole.getRoleValue();
Iterator iterator = oldRoleValue.iterator();
while (iterator.hasNext())
{
ObjectName objectName = (ObjectName) iterator.next();
if (newRoleValue.contains(objectName) == false)
{
HashMap idRolesMap = (HashMap) idRolesMapByMBean.get(objectName);
HashSet roleNames = (HashSet) idRolesMap.get(relationId);
roleNames.remove(roleName);
if (roleNames.size() == 0)
{
idRolesMap.remove(relationId);
if (idRolesMap.size() == 0)
{
idRolesMapByMBean.remove(objectName);
filter.disableObjectName(objectName);
}
}
}
}
iterator = newRoleValue.iterator();
while (iterator.hasNext())
{
ObjectName objectName = (ObjectName) iterator.next();
HashMap idRolesMap = (HashMap) idRolesMapByMBean.get(objectName);
if (idRolesMap == null)
{
idRolesMap = new HashMap();
idRolesMapByMBean.put(objectName, idRolesMap);
filter.enableObjectName(objectName);
}
HashSet roleNames = (HashSet) idRolesMap.get(relationId);
if (roleNames == null)
{
roleNames = new HashSet();
idRolesMap.put(relationId, roleNames);
}
if (roleNames.contains(roleName) == false)
roleNames.add(roleName);
}
}
public ObjectName preRegister(MBeanServer server, ObjectName objectName)
throws Exception
{
this.server = server;
this.relationService = objectName;
filter = new MBeanServerNotificationFilter();
filter.enableType(MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
filter.disableAllObjectNames();
delegate = new ObjectName(MBeanServerImpl.MBEAN_SERVER_DELEGATE);
server.addNotificationListener(delegate, this, filter, null);
return objectName;
}
public void postRegister(Boolean registered)
{
}
public void preDeregister()
throws Exception
{
}
public void postDeregister()
{
try
{
server.removeNotificationListener(delegate, this);
}
catch (Exception ignored)
{
}
server = null;
}
public void handleNotification(Notification notification, Object handback)
{
if (notification == null ||
!(notification instanceof MBeanServerNotification))
return;
MBeanServerNotification mbsn = (MBeanServerNotification) notification;
if (mbsn.getType().equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION) == false)
return;
ObjectName objectName = mbsn.getMBeanName();
unregistered.push(objectName);
try
{
if (purgeFlag == true)
purgeRelations();
}
catch (Exception ignored)
{
}
try
{
String relationId = (String) idsByRelation.get(objectName);
if (relationId != null)
removeRelation(relationId);
}
catch (Exception ignored)
{
}
}
public MBeanNotificationInfo[] getNotificationInfo()
{
MBeanNotificationInfo[] result = new MBeanNotificationInfo[1];
String[] types = new String[]
{
RelationNotification.RELATION_BASIC_CREATION,
RelationNotification.RELATION_BASIC_REMOVAL,
RelationNotification.RELATION_BASIC_UPDATE,
RelationNotification.RELATION_MBEAN_CREATION,
RelationNotification.RELATION_MBEAN_REMOVAL,
RelationNotification.RELATION_MBEAN_UPDATE
};
result[0] = new MBeanNotificationInfo(types,
"javax.management.relation.RelationNotification",
"Notifications sent by the Relation Service MBean");
return result;
}
private void createMissingRoles(String relationTypeName, RoleList roleList)
throws RelationTypeNotFoundException
{
if (relationTypeName == null)
throw new RelationTypeNotFoundException("RelationType name null not found");
RelationType relationType = retrieveRelationTypeForName(relationTypeName);
ArrayList roleInfos = (ArrayList) relationType.getRoleInfos();
Iterator iterator = roleInfos.iterator();
while (iterator.hasNext())
{
RoleInfo roleInfo = (RoleInfo) iterator.next();
boolean found = false;
Iterator inner = roleList.iterator();
while (inner.hasNext())
{
Role role = (Role) inner.next();
if (role.getRoleName().equals(roleInfo.getName()))
{
found = true;
break;
}
}
if (found == false)
roleList.add(new Role(roleInfo.getName(), new RoleList()));
}
}
private Object retrieveRelationForId(String relationId)
throws IllegalArgumentException, RelationNotFoundException
{
if (relationId == null)
throw new IllegalArgumentException("null relation id");
Object result = relationsById.get(relationId);
if (result == null)
throw new RelationNotFoundException(relationId);
return result;
}
private String retrieveTypeNameForId(String relationId)
throws IllegalArgumentException, RelationNotFoundException
{
if (relationId == null)
throw new IllegalArgumentException("null relation id");
String result = (String) typeNamesById.get(relationId);
if (result == null)
throw new RelationNotFoundException(relationId);
return result;
}
private RelationType retrieveRelationTypeForName(String relationTypeName)
throws IllegalArgumentException, RelationTypeNotFoundException
{
if (relationTypeName == null)
throw new IllegalArgumentException("Null relation type name");
RelationType result = (RelationType) typesByName.get(relationTypeName);
if (result == null)
throw new RelationTypeNotFoundException(relationTypeName);
return result;
}
private void sendNotification(String type, String description,
String relationId, List unregMBeans,
Role newRole, List oldRoleValue)
throws IllegalArgumentException, RelationNotFoundException
{
if (type == null)
throw new IllegalArgumentException("null notification type");
String typeName = retrieveTypeNameForId(relationId);
Object relation = retrieveRelationForId(relationId);
ObjectName relationName = null;
if (relation instanceof ObjectName)
relationName = (ObjectName) relation;
long sequence;
synchronized (this)
{
sequence = ++notificationSequence;
}
if (type.equals(RelationNotification.RELATION_BASIC_UPDATE) ||
type.equals(RelationNotification.RELATION_MBEAN_UPDATE))
sendNotification(new RelationNotification(type, relationService, sequence,
System.currentTimeMillis(), description, relationId, typeName,
relationName, newRole.getRoleName(), newRole.getRoleValue(),
oldRoleValue));
else
sendNotification(new RelationNotification(type, relationService, sequence,
System.currentTimeMillis(), description, relationId, typeName,
relationName, unregMBeans));
}
private synchronized void validateAndAddRelation(String relationId,
Object relation, String relationTypeName)
throws InvalidRelationIdException
{
if (relationsById.containsKey(relationId))
throw new InvalidRelationIdException(relationId);
relationsById.put(relationId, relation);
idsByRelation.put(relation, relationId);
typeNamesById.put(relationId, relationTypeName);
RoleList roles = null;
if (relation instanceof RelationSupport)
{
RelationSupport support = (RelationSupport) relation;
roles = support.retrieveAllRoles();
}
else
{
try
{
roles = (RoleList) server.invoke((ObjectName) relation,
"retrieveAllRoles", new Object[0], new String[0]);
}
catch (Exception e)
{
throw new RuntimeException(e.toString());
}
}
Iterator iterator = roles.iterator();
while (iterator.hasNext())
{
Role role = (Role) iterator.next();
try
{
updateRoleMap(relationId, role, role.getRoleValue());
}
catch (Exception e)
{
throw new RuntimeException(e.toString());
}
}
if (relation instanceof RelationSupport)
{
RelationSupport support = (RelationSupport) relation;
support.setRelationServiceManagementFlag(new Boolean(true));
}
else
{
try
{
Attribute attribute = new Attribute("RelationServiceManagementFlag",
new Boolean(true));
server.setAttribute((ObjectName) relation, attribute);
}
catch (Exception doesntImplementRelationSupportMBean)
{
}
}
try
{
sendRelationCreationNotification(relationId);
}
catch (RelationNotFoundException e)
{
throw new RuntimeException(e.toString());
}
}
private void validateRelationType(RelationType relationType)
throws InvalidRelationTypeException
{
HashSet roleNames = new HashSet();
ArrayList roleInfos = (ArrayList) relationType.getRoleInfos();
if (roleInfos == null)
throw new InvalidRelationTypeException("Null role infos");
if (roleInfos.size() == 0)
throw new InvalidRelationTypeException("No role infos");
synchronized (roleInfos)
{
Iterator iterator = roleInfos.iterator();
while (iterator.hasNext())
{
RoleInfo roleInfo = (RoleInfo) iterator.next();
if (roleInfo == null)
throw new InvalidRelationTypeException("Null role");
if (roleNames.contains(roleInfo.getName()))
throw new InvalidRelationTypeException(
"Duplicate role name" + roleInfo.getName());
roleNames.add(roleInfo.getName());
}
}
}
}