0001: /*
0002: * JBoss, Home of Professional Open Source.
0003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
0004: * as indicated by the @author tags. See the copyright.txt file in the
0005: * distribution for a full listing of individual contributors.
0006: *
0007: * This is free software; you can redistribute it and/or modify it
0008: * under the terms of the GNU Lesser General Public License as
0009: * published by the Free Software Foundation; either version 2.1 of
0010: * the License, or (at your option) any later version.
0011: *
0012: * This software is distributed in the hope that it will be useful,
0013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0015: * Lesser General Public License for more details.
0016: *
0017: * You should have received a copy of the GNU Lesser General Public
0018: * License along with this software; if not, write to the Free
0019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
0021: */
0022: package javax.management.relation;
0023:
0024: import java.util.ArrayList;
0025: import java.util.HashMap;
0026: import java.util.HashSet;
0027: import java.util.Iterator;
0028: import java.util.List;
0029: import java.util.Map;
0030: import java.util.Stack;
0031:
0032: import javax.management.Attribute;
0033: import javax.management.AttributeNotFoundException;
0034: import javax.management.InstanceNotFoundException;
0035: import javax.management.InvalidAttributeValueException;
0036: import javax.management.MBeanException;
0037: import javax.management.MBeanNotificationInfo;
0038: import javax.management.MBeanRegistration;
0039: import javax.management.MBeanServer;
0040: import javax.management.MBeanServerNotification;
0041: import javax.management.Notification;
0042: import javax.management.NotificationBroadcasterSupport;
0043: import javax.management.NotificationListener;
0044: import javax.management.ObjectName;
0045: import javax.management.ReflectionException;
0046:
0047: import org.jboss.logging.Logger;
0048: import org.jboss.mx.server.MBeanServerImpl;
0049:
0050: /**
0051: * Implements the management interface for a relation service.<p>
0052: *
0053: * <p><b>Revisions:</b>
0054: * <p><b>20020311 Adrian Brock:</b>
0055: * <ul>
0056: * <li>Fixed setRole for external MBean and exception handling
0057: * <li>EmptyStack exception in purging
0058: * <li>Unregistered mbeans should only contain relation mbeans
0059: * <li>Unregister notifications not working after change to MBean Filter
0060: * </ul>
0061: * <p><b>20020312 Adrian Brock:</b>
0062: * <ul>
0063: * <li>Fixed wrong exception types thrown and missing exceptions
0064: * <li>Allow null role list in createRelation
0065: * </ul>
0066: *
0067: * @see RelationServiceMBean
0068: *
0069: * @author <a href="mailto:Adrian.Brock@HappeningTimes.com">Adrian Brock</a>.
0070: * @version $Revision: 57200 $
0071: */
0072: public class RelationService extends NotificationBroadcasterSupport
0073: implements RelationServiceMBean, MBeanRegistration,
0074: NotificationListener {
0075: // Constants -----------------------------------------------------
0076:
0077: private static final long serialVersionUID = 5434016005679159613L;
0078:
0079: private static final Logger log = Logger
0080: .getLogger(RelationService.class);
0081:
0082: // Attributes ----------------------------------------------------
0083:
0084: /**
0085: * Relation ids by relation
0086: * Note: A relation is an ObjectName for external relations
0087: * and a RelationSupport object for internal relations
0088: */
0089: private HashMap idsByRelation = new HashMap();
0090:
0091: /**
0092: * The relation service object name
0093: */
0094: private ObjectName relationService;
0095:
0096: /**
0097: * The notification sequence
0098: */
0099: private long notificationSequence = 0;
0100:
0101: /**
0102: * The purge flag
0103: */
0104: private boolean purgeFlag;
0105:
0106: /**
0107: * Relations by relation id
0108: * Note: A relation is an ObjectName for external relations
0109: * and a RelationSupport object for internal relations
0110: */
0111: private HashMap relationsById = new HashMap();
0112:
0113: /**
0114: * The mbean server we are registered with
0115: */
0116: private MBeanServer server;
0117:
0118: /**
0119: * The relation types by name
0120: */
0121: private HashMap typesByName = new HashMap();
0122:
0123: /**
0124: * Relation type names by relation ids
0125: */
0126: private HashMap typeNamesById = new HashMap();
0127:
0128: /**
0129: * A notification listener for unregistration
0130: */
0131: private MBeanServerNotificationFilter filter;
0132:
0133: /**
0134: * A list of MBeans unregistered but not yet removed.
0135: */
0136: private Stack unregistered = new Stack();
0137:
0138: /**
0139: * Relation ids an MBean is part of by MBean object name
0140: * The values side is a HashMap keyed by relation ids
0141: * with values of a HashSet of role names.
0142: */
0143: private HashMap idRolesMapByMBean = new HashMap();
0144:
0145: // The name of the delegate
0146: private ObjectName delegate;
0147:
0148: // Static --------------------------------------------------------
0149:
0150: // Constructors --------------------------------------------------
0151:
0152: /**
0153: * Construct a new relation service
0154: *
0155: * @param purgeFlag whether immediate purges should be performed,
0156: * pass true for immediate, false otherwise
0157: */
0158: public RelationService(boolean purgeFlag) {
0159: setPurgeFlag(purgeFlag);
0160: }
0161:
0162: // RelationServiceMBean implementation ---------------------------
0163:
0164: public synchronized void addRelation(ObjectName relation)
0165: throws IllegalArgumentException, NoSuchMethodException,
0166: RelationServiceNotRegisteredException,
0167: InvalidRelationIdException,
0168: InvalidRelationServiceException,
0169: RelationTypeNotFoundException, InvalidRoleValueException,
0170: RoleNotFoundException, InstanceNotFoundException {
0171: // Check we have a relation
0172: if (relation == null)
0173: throw new IllegalArgumentException("null relation");
0174: isActive();
0175:
0176: // Get the information we need from the relation
0177: ObjectName otherService = null;
0178: String relationId = null;
0179: String relationTypeName = null;
0180: RoleList roleList = null;
0181: try {
0182: server.isInstanceOf(relation, Relation.class.getName());
0183: otherService = (ObjectName) server.getAttribute(relation,
0184: "RelationServiceName");
0185: relationId = (String) server.getAttribute(relation,
0186: "RelationId");
0187: relationTypeName = (String) server.getAttribute(relation,
0188: "RelationTypeName");
0189: roleList = (RoleList) server.invoke(relation,
0190: "retrieveAllRoles", new Object[0], new String[0]);
0191: } catch (InstanceNotFoundException e) {
0192: throw e;
0193: } catch (Exception e) {
0194: throw new NoSuchMethodException(
0195: "Not a relation or not registered");
0196: }
0197: if (relationId == null)
0198: throw new InvalidRelationIdException("Null relation id");
0199:
0200: // Check we are in the correct relation service
0201: if (otherService == null
0202: || otherService.equals(relationService) == false)
0203: throw new InvalidRelationServiceException(otherService
0204: + " != " + relationService);
0205:
0206: // Create a copy of the role list
0207: RoleList copy = new RoleList(roleList);
0208:
0209: // Create any missing roles
0210: createMissingRoles(relationTypeName, copy);
0211:
0212: // Validate the role list
0213: RoleValidator.validateRoles(relationService, server,
0214: relationTypeName, copy, false);
0215:
0216: // Add the relation if it is not already present
0217: validateAndAddRelation(relationId, relation, relationTypeName);
0218:
0219: // Monitor this relation
0220: filter.enableObjectName(relation);
0221: }
0222:
0223: public synchronized void addRelationType(RelationType relationType)
0224: throws IllegalArgumentException,
0225: InvalidRelationTypeException {
0226: if (relationType == null)
0227: throw new IllegalArgumentException("null relation type");
0228: synchronized (typesByName) {
0229: String name = relationType.getRelationTypeName();
0230: if (name == null)
0231: throw new IllegalArgumentException(
0232: "Null relation type name in relation type");
0233: if (typesByName.containsKey(name))
0234: throw new InvalidRelationTypeException(
0235: "duplicate relation id: " + name);
0236: validateRelationType(relationType);
0237: typesByName.put(name, relationType);
0238: }
0239: }
0240:
0241: public Integer checkRoleReading(String roleName,
0242: String relationTypeName) throws IllegalArgumentException,
0243: RelationTypeNotFoundException {
0244: if (roleName == null)
0245: throw new IllegalArgumentException("Null role name");
0246:
0247: // Get the relation type
0248: RelationType relationType = retrieveRelationTypeForName(relationTypeName);
0249:
0250: // Get the role information
0251: RoleInfo roleInfo = null;
0252: try {
0253: roleInfo = relationType.getRoleInfo(roleName);
0254: } catch (RoleInfoNotFoundException e) {
0255: return new Integer(RoleStatus.NO_ROLE_WITH_NAME);
0256: }
0257:
0258: // Is it readable?
0259: if (roleInfo.isReadable() == false)
0260: return new Integer(RoleStatus.ROLE_NOT_READABLE);
0261:
0262: // Yes it is
0263: return new Integer(0);
0264: }
0265:
0266: public Integer checkRoleWriting(Role role, String relationTypeName,
0267: Boolean initFlag) throws IllegalArgumentException,
0268: RelationTypeNotFoundException {
0269: if (role == null)
0270: throw new IllegalArgumentException("Null role name");
0271: if (initFlag == null)
0272: throw new IllegalArgumentException("Null init flag");
0273:
0274: // Get the relation type
0275: RelationType relationType = retrieveRelationTypeForName(relationTypeName);
0276:
0277: // Get the role information
0278: RoleInfo roleInfo = null;
0279: try {
0280: roleInfo = relationType.getRoleInfo(role.getRoleName());
0281: } catch (RoleInfoNotFoundException e) {
0282: return new Integer(RoleStatus.NO_ROLE_WITH_NAME);
0283: }
0284:
0285: // Is it writable?
0286: if (initFlag.booleanValue() == false
0287: && roleInfo.isWritable() == false)
0288: return new Integer(RoleStatus.ROLE_NOT_WRITABLE);
0289:
0290: // Check the cardinality of the role
0291: ArrayList mbeans = (ArrayList) role.getRoleValue();
0292: int beanCount = mbeans.size();
0293: int minimum = roleInfo.getMinDegree();
0294: if (minimum != RoleInfo.ROLE_CARDINALITY_INFINITY
0295: && minimum > beanCount)
0296: return new Integer(RoleStatus.LESS_THAN_MIN_ROLE_DEGREE);
0297: int maximum = roleInfo.getMaxDegree();
0298: if (maximum != RoleInfo.ROLE_CARDINALITY_INFINITY
0299: && maximum < beanCount)
0300: return new Integer(RoleStatus.MORE_THAN_MAX_ROLE_DEGREE);
0301:
0302: // Check the MBeans
0303: String className = roleInfo.getRefMBeanClassName();
0304: Iterator iterator = mbeans.iterator();
0305: while (iterator.hasNext()) {
0306: try {
0307: ObjectName objectName = (ObjectName) iterator.next();
0308: if (server.isInstanceOf(objectName, className) == false)
0309: return new Integer(
0310: RoleStatus.REF_MBEAN_OF_INCORRECT_CLASS);
0311: } catch (Exception e) {
0312: return new Integer(RoleStatus.REF_MBEAN_NOT_REGISTERED);
0313: }
0314: }
0315:
0316: // Yes it is
0317: return new Integer(0);
0318: }
0319:
0320: public synchronized void createRelation(String relationId,
0321: String relationTypeName, RoleList roleList)
0322: throws IllegalArgumentException,
0323: RelationServiceNotRegisteredException,
0324: InvalidRelationIdException, RelationTypeNotFoundException,
0325: InvalidRoleValueException, RoleNotFoundException {
0326: // Take a copy of the role list
0327: RoleList copy = null;
0328: if (roleList != null)
0329: copy = new RoleList(roleList);
0330: else
0331: copy = new RoleList();
0332:
0333: // Create a relation
0334: isActive();
0335: RelationSupport relation = new RelationSupport(relationId,
0336: relationService, server, relationTypeName, copy);
0337:
0338: // Create any missing roles
0339: createMissingRoles(relationTypeName, copy);
0340:
0341: // Validate the role list
0342: RoleValidator.validateRoles(relationService, server,
0343: relationTypeName, copy, false);
0344:
0345: // Add the relation if it is not already present
0346: validateAndAddRelation(relationId, relation, relationTypeName);
0347: }
0348:
0349: public synchronized void createRelationType(
0350: String relationTypeName, RoleInfo[] roleInfos)
0351: throws IllegalArgumentException,
0352: InvalidRelationTypeException {
0353: if (relationTypeName == null)
0354: throw new IllegalArgumentException(
0355: "null relation type name");
0356: synchronized (typesByName) {
0357: if (typesByName.containsKey(relationTypeName))
0358: throw new InvalidRelationTypeException(
0359: "duplicate relation id: " + relationTypeName);
0360: RelationType relationType = new RelationTypeSupport(
0361: relationTypeName, roleInfos);
0362: typesByName.put(relationTypeName, relationType);
0363: }
0364: }
0365:
0366: public Map findAssociatedMBeans(ObjectName mbeanName,
0367: String relationTypeName, String roleName)
0368: throws IllegalArgumentException {
0369: HashMap referencing = (HashMap) findReferencingRelations(
0370: mbeanName, relationTypeName, roleName);
0371: HashMap result = new HashMap();
0372:
0373: // Loop through our relations
0374: Iterator relationIterator = referencing.entrySet().iterator();
0375: while (relationIterator.hasNext()) {
0376: Map.Entry referencingEntry = (Map.Entry) relationIterator
0377: .next();
0378: String relationId = (String) referencingEntry.getKey();
0379:
0380: // Get the all beans in this relation
0381: HashMap referenced = null;
0382: try {
0383: referenced = (HashMap) getReferencedMBeans(relationId);
0384: } catch (RelationNotFoundException e) {
0385: throw new RuntimeException(e.toString());
0386: }
0387:
0388: // Check each bean's roles
0389: Iterator mbeanIterator = referenced.entrySet().iterator();
0390: while (mbeanIterator.hasNext()) {
0391:
0392: Map.Entry referencedEntry = (Map.Entry) mbeanIterator
0393: .next();
0394: ObjectName objectName = (ObjectName) referencedEntry
0395: .getKey();
0396:
0397: // Exclude ourselves from the test
0398: if (objectName.equals(mbeanName) == false) {
0399: // Ok this is one of our associated mbeans
0400: ArrayList resultList = (ArrayList) result
0401: .get(objectName);
0402: if (resultList == null) {
0403: resultList = new ArrayList();
0404: resultList.add(relationId);
0405: result.put(objectName, resultList);
0406: } else if (resultList.contains(relationId) == false)
0407: resultList.add(relationId);
0408: }
0409: }
0410: }
0411: // All done
0412: return result;
0413: }
0414:
0415: public Map findReferencingRelations(ObjectName mbeanName,
0416: String relationTypeName, String roleName)
0417: throws IllegalArgumentException {
0418: if (mbeanName == null)
0419: throw new IllegalArgumentException("null object name");
0420:
0421: HashMap result = new HashMap();
0422:
0423: // Get the relations to roles map for the passed mbean
0424: HashMap idRolesMap = (HashMap) idRolesMapByMBean.get(mbeanName);
0425: if (idRolesMap == null)
0426: return result;
0427: Iterator iterator = idRolesMap.entrySet().iterator();
0428: while (iterator.hasNext()) {
0429: Map.Entry entry = (Map.Entry) iterator.next();
0430: String relationId = (String) entry.getKey();
0431: HashSet roleNames = (HashSet) entry.getValue();
0432:
0433: // See if we have the correct relation type
0434: if (relationTypeName == null
0435: || typeNamesById.get(relationId).equals(
0436: relationTypeName)) {
0437: ArrayList resultRoleNames = new ArrayList();
0438:
0439: // No role specified, add them all
0440: if (roleName == null)
0441: resultRoleNames.addAll(roleNames);
0442: // See if we have this role
0443: else if (roleNames.contains(roleName)
0444: && resultRoleNames.contains(roleName) == false)
0445: resultRoleNames.add(roleName);
0446:
0447: // Did we find anything, use it
0448: if (resultRoleNames.size() > 0)
0449: result.put(relationId, resultRoleNames);
0450: }
0451: }
0452: // All done
0453: return result;
0454: }
0455:
0456: public List findRelationsOfType(String relationTypeName)
0457: throws IllegalArgumentException,
0458: RelationTypeNotFoundException {
0459: if (relationTypeName == null)
0460: throw new IllegalArgumentException(
0461: "null relation type name");
0462: if (typesByName.containsKey(relationTypeName) == false)
0463: throw new RelationTypeNotFoundException(
0464: "relation type name not found");
0465:
0466: // Build the list
0467: ArrayList result = new ArrayList();
0468: Iterator iterator = typeNamesById.entrySet().iterator();
0469: while (iterator.hasNext()) {
0470: Map.Entry entry = (Map.Entry) iterator.next();
0471: String typeName = (String) entry.getValue();
0472: if (typeName.equals(relationTypeName))
0473: result.add(entry.getKey());
0474: }
0475: // All done
0476: return result;
0477: }
0478:
0479: public List getAllRelationIds() {
0480: ArrayList result = new ArrayList(relationsById.size());
0481: synchronized (relationsById) {
0482: Iterator iterator = relationsById.keySet().iterator();
0483: while (iterator.hasNext())
0484: result.add(iterator.next());
0485: }
0486: return result;
0487: }
0488:
0489: public List getAllRelationTypeNames() {
0490: ArrayList result = new ArrayList(typesByName.size());
0491: synchronized (typesByName) {
0492: Iterator iterator = typesByName.keySet().iterator();
0493: while (iterator.hasNext())
0494: result.add(iterator.next());
0495: }
0496: return result;
0497: }
0498:
0499: public RoleResult getAllRoles(String relationId)
0500: throws IllegalArgumentException, RelationNotFoundException,
0501: RelationServiceNotRegisteredException {
0502: isActive();
0503: Object relation = retrieveRelationForId(relationId);
0504:
0505: // Ask the relation for the roles
0506: if (relation instanceof RelationSupport) {
0507: return ((RelationSupport) relation).getAllRoles();
0508: } else {
0509: ObjectName objectName = (ObjectName) relation;
0510: try {
0511: return (RoleResult) server.getAttribute(objectName,
0512: "AllRoles");
0513: } catch (InstanceNotFoundException e) {
0514: throw new RelationNotFoundException(objectName
0515: .toString());
0516: } catch (Exception e) {
0517: throw new RuntimeException(e.toString());
0518: }
0519: }
0520: }
0521:
0522: public boolean getPurgeFlag() {
0523: return purgeFlag;
0524: }
0525:
0526: public Map getReferencedMBeans(String relationId)
0527: throws IllegalArgumentException, RelationNotFoundException {
0528: Object relation = retrieveRelationForId(relationId);
0529:
0530: // Ask the relation for the referenced mbeans
0531: if (relation instanceof RelationSupport) {
0532: return ((RelationSupport) relation).getReferencedMBeans();
0533: } else {
0534: ObjectName objectName = (ObjectName) relation;
0535: try {
0536: return (Map) server.getAttribute(objectName,
0537: "ReferencedMBeans");
0538: } catch (InstanceNotFoundException e) {
0539: throw new RelationNotFoundException(objectName
0540: .toString());
0541: } catch (Exception e) {
0542: throw new RuntimeException(e.toString());
0543: }
0544: }
0545: }
0546:
0547: public String getRelationTypeName(String relationId)
0548: throws IllegalArgumentException, RelationNotFoundException {
0549: return retrieveTypeNameForId(relationId);
0550: }
0551:
0552: public List getRole(String relationId, String roleName)
0553: throws IllegalArgumentException, RelationNotFoundException,
0554: RelationServiceNotRegisteredException,
0555: RoleNotFoundException {
0556: // Get the relation object name
0557: if (roleName == null)
0558: throw new IllegalArgumentException("null role");
0559: isActive();
0560: Object relation = retrieveRelationForId(relationId);
0561:
0562: // Ask the relation for the role value
0563: if (relation instanceof RelationSupport) {
0564: return ((RelationSupport) relation).getRole(roleName);
0565: } else {
0566: ObjectName objectName = (ObjectName) relation;
0567: try {
0568: List result = (List) server.invoke(objectName,
0569: "getRole", new Object[] { roleName },
0570: new String[] { "java.lang.String" });
0571: return result;
0572: } catch (InstanceNotFoundException e) {
0573: throw new RelationNotFoundException(objectName
0574: .toString());
0575: } catch (MBeanException mbe) {
0576: Exception e = mbe.getTargetException();
0577: if (e instanceof RoleNotFoundException)
0578: throw (RoleNotFoundException) e;
0579: else
0580: throw new RuntimeException(e.toString());
0581: } catch (ReflectionException e) {
0582: throw new RuntimeException(e.toString());
0583: }
0584: }
0585: }
0586:
0587: public Integer getRoleCardinality(String relationId, String roleName)
0588: throws IllegalArgumentException, RelationNotFoundException,
0589: RoleNotFoundException {
0590: // Get the relation object name
0591: if (roleName == null)
0592: throw new IllegalArgumentException("null role");
0593: Object relation = retrieveRelationForId(relationId);
0594:
0595: // Ask the relation for the role cardinality
0596: if (relation instanceof RelationSupport) {
0597: return ((RelationSupport) relation)
0598: .getRoleCardinality(roleName);
0599: } else {
0600: ObjectName objectName = (ObjectName) relation;
0601: try {
0602: Integer result = (Integer) server.invoke(objectName,
0603: "getRoleCardinality",
0604: new Object[] { roleName },
0605: new String[] { "java.lang.String" });
0606: return result;
0607: } catch (InstanceNotFoundException e) {
0608: throw new RelationNotFoundException(objectName
0609: .toString());
0610: } catch (MBeanException mbe) {
0611: Exception e = mbe.getTargetException();
0612: if (e instanceof RoleNotFoundException)
0613: throw (RoleNotFoundException) e;
0614: else
0615: throw new RuntimeException(e.toString());
0616: } catch (ReflectionException e) {
0617: throw new RuntimeException(e.toString());
0618: }
0619: }
0620: }
0621:
0622: public RoleInfo getRoleInfo(String relationTypeName,
0623: String roleInfoName) throws IllegalArgumentException,
0624: RelationTypeNotFoundException, RoleInfoNotFoundException {
0625: // Get the relation type
0626: RelationType relationType = retrieveRelationTypeForName(relationTypeName);
0627:
0628: // Return the role information
0629: return relationType.getRoleInfo(roleInfoName);
0630: }
0631:
0632: public List getRoleInfos(String relationTypeName)
0633: throws IllegalArgumentException,
0634: RelationTypeNotFoundException {
0635: // Get the relation type
0636: RelationType relationType = retrieveRelationTypeForName(relationTypeName);
0637:
0638: // Return the role information
0639: return relationType.getRoleInfos();
0640: }
0641:
0642: public RoleResult getRoles(String relationId, String[] roleNames)
0643: throws IllegalArgumentException, RelationNotFoundException,
0644: RelationServiceNotRegisteredException {
0645: // Get the relation object name
0646: if (roleNames == null)
0647: throw new IllegalArgumentException("null role names");
0648: isActive();
0649: Object relation = retrieveRelationForId(relationId);
0650:
0651: // Ask the relation for the role value
0652: if (relation instanceof RelationSupport) {
0653: return ((RelationSupport) relation).getRoles(roleNames);
0654: } else {
0655: ObjectName objectName = (ObjectName) relation;
0656: try {
0657: RoleResult result = (RoleResult) server.invoke(
0658: objectName, "getRoles",
0659: new Object[] { roleNames },
0660: new String[] { new String[0].getClass()
0661: .getName() });
0662: return result;
0663: } catch (InstanceNotFoundException e) {
0664: throw new RelationNotFoundException(objectName
0665: .toString());
0666: } catch (MBeanException e) {
0667: throw new RuntimeException(e.toString());
0668: } catch (ReflectionException e) {
0669: throw new RuntimeException(e.toString());
0670: }
0671: }
0672: }
0673:
0674: public Boolean hasRelation(String relationId)
0675: throws IllegalArgumentException {
0676: if (relationId == null)
0677: throw new IllegalArgumentException("null relation id");
0678: return new Boolean(relationsById.get(relationId) != null);
0679: }
0680:
0681: public void isActive() throws RelationServiceNotRegisteredException {
0682: if (server == null)
0683: throw new RelationServiceNotRegisteredException(
0684: "Not registered");
0685: }
0686:
0687: public String isRelation(ObjectName objectName)
0688: throws IllegalArgumentException {
0689: if (objectName == null)
0690: throw new IllegalArgumentException("null object name");
0691: return (String) idsByRelation.get(objectName);
0692: }
0693:
0694: public ObjectName isRelationMBean(String relationId)
0695: throws IllegalArgumentException, RelationNotFoundException {
0696: if (relationId == null)
0697: throw new IllegalArgumentException("null relation id");
0698: Object result = relationsById.get(relationId);
0699: if (result == null)
0700: throw new RelationNotFoundException(relationId);
0701: if (result instanceof ObjectName)
0702: return (ObjectName) result;
0703: else
0704: return null;
0705: }
0706:
0707: public void purgeRelations()
0708: throws RelationServiceNotRegisteredException {
0709: isActive();
0710: // Keep going until they are all done
0711: while (unregistered.empty() == false) {
0712: // Get the next object
0713: ObjectName mbean = (ObjectName) unregistered.pop();
0714:
0715: // Keep track of the remain relations/roles
0716: HashMap relationRoles = new HashMap();
0717:
0718: // Get the relations for this mbean
0719: HashMap idRolesMap = (HashMap) idRolesMapByMBean.get(mbean);
0720:
0721: // Go through each relation/role
0722: Iterator iterator = idRolesMap.entrySet().iterator();
0723: while (iterator.hasNext()) {
0724: Map.Entry entry = (Map.Entry) iterator.next();
0725: String relationId = (String) entry.getKey();
0726: HashSet roleNames = (HashSet) entry.getValue();
0727: Iterator inner = roleNames.iterator();
0728: while (inner.hasNext()) {
0729: String roleName = (String) inner.next();
0730: relationRoles.put(relationId, roleName);
0731: }
0732: }
0733:
0734: // Tell the relation about the removed role
0735: iterator = relationRoles.entrySet().iterator();
0736: while (iterator.hasNext()) {
0737: Map.Entry entry = (Map.Entry) iterator.next();
0738: String relationId = (String) entry.getKey();
0739: String roleName = (String) entry.getValue();
0740: Object relation = relationsById.get(relationId);
0741: String typeName = (String) typeNamesById
0742: .get(relationId);
0743: RelationType relationType = (RelationType) typesByName
0744: .get(typeName);
0745: if (relation instanceof RelationSupport) {
0746: RelationSupport support = (RelationSupport) relation;
0747: try {
0748: // Check to see if the relation is now invalid
0749: Integer cardinality = support
0750: .getRoleCardinality(roleName);
0751: RoleInfo roleInfo = relationType
0752: .getRoleInfo(roleName);
0753: int minDegree = roleInfo.getMinDegree();
0754:
0755: // It's invalid, remove it
0756: if (cardinality.intValue() == minDegree)
0757: removeRelation(relationId);
0758: else
0759: // It's ok tell the relation about the unregistration
0760: support.handleMBeanUnregistration(mbean,
0761: roleName);
0762: } catch (Exception e) {
0763: log.debug("Error during purge", e);
0764: }
0765: } else {
0766: try {
0767: // Check to see if the relation is now invalid
0768: ObjectName objectName = (ObjectName) relation;
0769: Integer cardinality = (Integer) server.invoke(
0770: objectName, "getRoleCardinality",
0771: new Object[] { roleName },
0772: new String[] { "java.lang.String" });
0773: RoleInfo roleInfo = relationType
0774: .getRoleInfo(roleName);
0775: int minDegree = roleInfo.getMinDegree();
0776:
0777: // It's invalid, remove it
0778: if (cardinality.intValue() == minDegree)
0779: removeRelation(relationId);
0780: else
0781: // It's ok tell the relation about the unregistration
0782: server.invoke(objectName,
0783: "handleMBeanUnregistration",
0784: new Object[] { mbean, roleName },
0785: new String[] { "java.lang.String",
0786: "java.lang.String " });
0787: } catch (MBeanException mbe) {
0788: log.debug("Error during purge", mbe
0789: .getTargetException());
0790: } catch (Exception e) {
0791: log.debug("Error during purge", e);
0792: }
0793: }
0794: }
0795: }
0796: }
0797:
0798: public synchronized void removeRelation(String relationId)
0799: throws IllegalArgumentException, RelationNotFoundException,
0800: RelationServiceNotRegisteredException {
0801: isActive();
0802:
0803: // Get the MBeans that are part of this relation
0804: ArrayList unregMBeans = new ArrayList(getReferencedMBeans(
0805: relationId).keySet());
0806:
0807: // Check to see whether this will remove the MBean
0808: Iterator iterator = unregMBeans.iterator();
0809: while (iterator.hasNext()) {
0810: // Remove the MBeans relation role map
0811: ObjectName mbean = (ObjectName) iterator.next();
0812: HashMap idRolesMap = (HashMap) idRolesMapByMBean.get(mbean);
0813: idRolesMap.remove(relationId);
0814:
0815: // We were the last?
0816: if (idRolesMap.size() == 0)
0817: idRolesMapByMBean.remove(mbean);
0818:
0819: // Is this an MBean a relation?
0820: if (idsByRelation.containsKey(mbean) == false)
0821: iterator.remove();
0822: }
0823:
0824: // Send a notification of the removal
0825: sendRelationRemovalNotification(relationId, unregMBeans);
0826:
0827: // Remove the relation from all the data structures
0828: Object relation = retrieveRelationForId(relationId);
0829: relationsById.remove(relationId);
0830: idsByRelation.remove(relation);
0831: typeNamesById.remove(relationId);
0832:
0833: // Update the relation management flag
0834: if (relation instanceof ObjectName) {
0835: try {
0836: Attribute attribute = new Attribute(
0837: "RelationServiceManagementFlag", new Boolean(
0838: false));
0839: server.setAttribute((ObjectName) relation, attribute);
0840: } catch (Exception doesntImplementRelationSupportMBean) {
0841: }
0842:
0843: // Don't monitor this relation anymore
0844: filter.disableObjectName((ObjectName) relation);
0845: }
0846: }
0847:
0848: public synchronized void removeRelationType(String relationTypeName)
0849: throws IllegalArgumentException,
0850: RelationTypeNotFoundException,
0851: RelationServiceNotRegisteredException {
0852: if (relationTypeName == null)
0853: throw new IllegalArgumentException(
0854: "null relation type name");
0855: isActive();
0856: if (typesByName.containsKey(relationTypeName) == false)
0857: throw new RelationTypeNotFoundException(
0858: "relation type name not found");
0859:
0860: // Remove any relations for this relation type
0861: // FIXME: This is rubbish
0862: ArrayList ids = new ArrayList();
0863: Map.Entry entry;
0864: Iterator iterator = typeNamesById.entrySet().iterator();
0865: while (iterator.hasNext()) {
0866: entry = (Map.Entry) iterator.next();
0867: if (entry.getValue().equals(relationTypeName))
0868: ids.add(entry.getKey());
0869: }
0870: iterator = ids.iterator();
0871: while (iterator.hasNext()) {
0872: try {
0873: removeRelation((String) iterator.next());
0874: } catch (RelationNotFoundException ignored) {
0875: }
0876: }
0877:
0878: // Remove the relation type
0879: typesByName.remove(relationTypeName);
0880: }
0881:
0882: public void sendRelationCreationNotification(String relationId)
0883: throws IllegalArgumentException, RelationNotFoundException {
0884: // Determine the type of relation
0885: String type = null;
0886: String description = null;
0887: if (relationsById.get(relationId) instanceof RelationSupport) {
0888: type = RelationNotification.RELATION_BASIC_CREATION;
0889: description = "Creation of internal relation.";
0890: } else {
0891: type = RelationNotification.RELATION_MBEAN_CREATION;
0892: description = "Creation of external relation.";
0893: }
0894: // Send the notification
0895: sendNotification(type, description, relationId, null, null,
0896: null);
0897: }
0898:
0899: public void sendRelationRemovalNotification(String relationId,
0900: List unregMBeans) throws IllegalArgumentException,
0901: RelationNotFoundException {
0902: // Determine the type of relation
0903: String type = null;
0904: String description = null;
0905: if (relationsById.get(relationId) instanceof RelationSupport) {
0906: type = RelationNotification.RELATION_BASIC_REMOVAL;
0907: description = "Removal of internal relation.";
0908: } else {
0909: type = RelationNotification.RELATION_MBEAN_REMOVAL;
0910: description = "Removal of external relation.";
0911: }
0912: // Send the notification
0913: sendNotification(type, description, relationId, unregMBeans,
0914: null, null);
0915: }
0916:
0917: public void sendRoleUpdateNotification(String relationId,
0918: Role newRole, List oldRoleValue)
0919: throws IllegalArgumentException, RelationNotFoundException {
0920: // Determine the type of relation
0921: String type = null;
0922: String description = null;
0923: if (relationsById.get(relationId) instanceof RelationSupport) {
0924: type = RelationNotification.RELATION_BASIC_UPDATE;
0925: description = "Update of internal relation.";
0926: } else {
0927: type = RelationNotification.RELATION_MBEAN_UPDATE;
0928: description = "Update of external relation.";
0929: }
0930: if (newRole == null)
0931: throw new IllegalArgumentException("null role");
0932:
0933: if (oldRoleValue == null)
0934: throw new IllegalArgumentException("null old role value");
0935:
0936: // Send the notification
0937: sendNotification(type, description, relationId, null, newRole,
0938: oldRoleValue);
0939: }
0940:
0941: public void setPurgeFlag(boolean value) {
0942: purgeFlag = value;
0943: }
0944:
0945: public void setRole(String relationId, Role role)
0946: throws RelationServiceNotRegisteredException,
0947: IllegalArgumentException, RelationNotFoundException,
0948: RoleNotFoundException, InvalidRoleValueException {
0949: // Get the relation object name
0950: if (role == null)
0951: throw new IllegalArgumentException("null role");
0952: isActive();
0953: Object relation = retrieveRelationForId(relationId);
0954:
0955: // Ask the relation to set the role
0956: if (relation instanceof RelationSupport) {
0957: try {
0958: ((RelationSupport) relation).setRole(role);
0959: } catch (RelationTypeNotFoundException e) {
0960: RelationNotFoundException rnfe = new RelationNotFoundException(
0961: e.getMessage());
0962: rnfe.initCause(e);
0963: throw rnfe;
0964: }
0965: } else {
0966: ObjectName objectName = (ObjectName) relation;
0967: try {
0968: server.setAttribute(objectName, new Attribute("Role",
0969: role));
0970: } catch (InstanceNotFoundException e) {
0971: throw new RelationNotFoundException(objectName
0972: .toString());
0973: } catch (MBeanException mbe) {
0974: Exception e = mbe.getTargetException();
0975: if (e instanceof RoleNotFoundException)
0976: throw (RoleNotFoundException) e;
0977: else if (e instanceof InvalidRoleValueException)
0978: throw (InvalidRoleValueException) e;
0979: else
0980: throw new RuntimeException(e.toString());
0981: } catch (AttributeNotFoundException e) {
0982: throw new RuntimeException(e.toString());
0983: } catch (InvalidAttributeValueException e) {
0984: throw new RuntimeException(e.toString());
0985: } catch (ReflectionException e) {
0986: throw new RuntimeException(e.toString());
0987: }
0988: }
0989: }
0990:
0991: public RoleResult setRoles(String relationId, RoleList roles)
0992: throws IllegalArgumentException,
0993: RelationServiceNotRegisteredException,
0994: RelationNotFoundException {
0995: // Get the relation object name
0996: if (roles == null)
0997: throw new IllegalArgumentException("null roles");
0998: isActive();
0999: Object relation = retrieveRelationForId(relationId);
1000:
1001: // Ask the relation to set the roles
1002: if (relation instanceof RelationSupport) {
1003: try {
1004: return ((RelationSupport) relation).setRoles(roles);
1005: }
1006: // Why doesn't it throw this?
1007: catch (RelationTypeNotFoundException e) {
1008: throw new RuntimeException(e.toString());
1009: }
1010: } else {
1011: ObjectName objectName = (ObjectName) relation;
1012: try {
1013: RoleResult result = (RoleResult) server
1014: .invoke(
1015: objectName,
1016: "setRoles",
1017: new Object[] { roles },
1018: new String[] { "javax.management.relation.RoleList" });
1019: return result;
1020: } catch (InstanceNotFoundException e) {
1021: throw new RelationNotFoundException(objectName
1022: .toString());
1023: } catch (MBeanException e) {
1024: throw new RuntimeException(e.getTargetException()
1025: .toString());
1026: } catch (ReflectionException e) {
1027: throw new RuntimeException(e.toString());
1028: }
1029: }
1030: }
1031:
1032: public void updateRoleMap(String relationId, Role newRole,
1033: List oldRoleValue) throws IllegalArgumentException,
1034: RelationServiceNotRegisteredException,
1035: RelationNotFoundException {
1036: if (relationId == null)
1037: throw new IllegalArgumentException("null relation id");
1038: if (newRole == null)
1039: throw new IllegalArgumentException("null role");
1040: if (oldRoleValue == null)
1041: throw new IllegalArgumentException("null old role value");
1042: isActive();
1043:
1044: if (relationsById.containsKey(relationId) == false)
1045: throw new RelationNotFoundException("Invalid relation id: "
1046: + relationId);
1047:
1048: // Get the role name and new Value
1049: String roleName = newRole.getRoleName();
1050: ArrayList newRoleValue = (ArrayList) newRole.getRoleValue();
1051:
1052: // Remove the unused and unchanged object names
1053: Iterator iterator = oldRoleValue.iterator();
1054: while (iterator.hasNext()) {
1055: ObjectName objectName = (ObjectName) iterator.next();
1056: if (newRoleValue.contains(objectName) == false) {
1057: // We have to remove this relation/role
1058: HashMap idRolesMap = (HashMap) idRolesMapByMBean
1059: .get(objectName);
1060: HashSet roleNames = (HashSet) idRolesMap
1061: .get(relationId);
1062: roleNames.remove(roleName);
1063: if (roleNames.size() == 0) {
1064: idRolesMap.remove(relationId);
1065: if (idRolesMap.size() == 0) {
1066: idRolesMapByMBean.remove(objectName);
1067: filter.disableObjectName(objectName);
1068: }
1069: }
1070: }
1071: }
1072:
1073: // Make sure all the roles exist
1074: iterator = newRoleValue.iterator();
1075: while (iterator.hasNext()) {
1076: ObjectName objectName = (ObjectName) iterator.next();
1077: HashMap idRolesMap = (HashMap) idRolesMapByMBean
1078: .get(objectName);
1079: if (idRolesMap == null) {
1080: idRolesMap = new HashMap();
1081: idRolesMapByMBean.put(objectName, idRolesMap);
1082: filter.enableObjectName(objectName);
1083: }
1084: HashSet roleNames = (HashSet) idRolesMap.get(relationId);
1085: if (roleNames == null) {
1086: roleNames = new HashSet();
1087: idRolesMap.put(relationId, roleNames);
1088: }
1089: if (roleNames.contains(roleName) == false)
1090: roleNames.add(roleName);
1091: }
1092: }
1093:
1094: // MBeanRegistration implementation ------------------------------
1095:
1096: public ObjectName preRegister(MBeanServer server,
1097: ObjectName objectName) throws Exception {
1098: // Save some data
1099: this .server = server;
1100: this .relationService = objectName;
1101:
1102: // Install our notification listener we aren't interested in registration
1103: // We aren't monitoring anything at start-up
1104: filter = new MBeanServerNotificationFilter();
1105: filter
1106: .enableType(MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
1107: filter.disableAllObjectNames();
1108: delegate = new ObjectName(MBeanServerImpl.MBEAN_SERVER_DELEGATE);
1109: server.addNotificationListener(delegate, this , filter, null);
1110:
1111: // Ok go ahead and register
1112: return objectName;
1113: }
1114:
1115: public void postRegister(Boolean registered) {
1116: }
1117:
1118: public void preDeregister() throws Exception {
1119: }
1120:
1121: public void postDeregister() {
1122: try {
1123: // Remove the notification listener
1124: server.removeNotificationListener(delegate, this );
1125: } catch (Exception ignored) {
1126: }
1127:
1128: // REVIEW: Should we remove relation types/relations here?
1129:
1130: // We are no longer registered
1131: server = null;
1132: }
1133:
1134: // NotificationListener implementation ----------------------------
1135:
1136: public void handleNotification(Notification notification,
1137: Object handback) {
1138: // Make sure we are not called malicously
1139: if (notification == null
1140: || !(notification instanceof MBeanServerNotification))
1141: return;
1142:
1143: // It still might be malicous
1144: MBeanServerNotification mbsn = (MBeanServerNotification) notification;
1145: if (mbsn.getType().equals(
1146: MBeanServerNotification.UNREGISTRATION_NOTIFICATION) == false)
1147: return;
1148: // Add the object to the list of mbeans to remove
1149: ObjectName objectName = mbsn.getMBeanName();
1150: unregistered.push(objectName);
1151:
1152: try {
1153: // Are we set to automatic purge?
1154: if (purgeFlag == true)
1155: purgeRelations();
1156: } catch (Exception ignored) {
1157: }
1158:
1159: try {
1160: // Is this a relation?
1161: String relationId = (String) idsByRelation.get(objectName);
1162: if (relationId != null)
1163: removeRelation(relationId);
1164: } catch (Exception ignored) {
1165: }
1166: }
1167:
1168: // NotificationBroadcasterSupport overrides -----------------------
1169:
1170: public MBeanNotificationInfo[] getNotificationInfo() {
1171: MBeanNotificationInfo[] result = new MBeanNotificationInfo[1];
1172: String[] types = new String[] {
1173: RelationNotification.RELATION_BASIC_CREATION,
1174: RelationNotification.RELATION_BASIC_REMOVAL,
1175: RelationNotification.RELATION_BASIC_UPDATE,
1176: RelationNotification.RELATION_MBEAN_CREATION,
1177: RelationNotification.RELATION_MBEAN_REMOVAL,
1178: RelationNotification.RELATION_MBEAN_UPDATE };
1179: result[0] = new MBeanNotificationInfo(types,
1180: "javax.management.relation.RelationNotification",
1181: "Notifications sent by the Relation Service MBean");
1182: return result;
1183: }
1184:
1185: // Private --------------------------------------------------------
1186:
1187: /**
1188: * Create missing roles
1189: *
1190: * @param relationTypeName the relation type name
1191: * @param roleList the existing roles
1192: * @exception RelationTypeNotFoundException for a missing relation type
1193: */
1194: private void createMissingRoles(String relationTypeName,
1195: RoleList roleList) throws RelationTypeNotFoundException {
1196: if (relationTypeName == null)
1197: throw new RelationTypeNotFoundException(
1198: "RelationType name null not found");
1199:
1200: // Get the relation type
1201: RelationType relationType = retrieveRelationTypeForName(relationTypeName);
1202:
1203: // Get the Role Information
1204: ArrayList roleInfos = (ArrayList) relationType.getRoleInfos();
1205:
1206: // Add empty roles for missing roles
1207: Iterator iterator = roleInfos.iterator();
1208: while (iterator.hasNext()) {
1209: RoleInfo roleInfo = (RoleInfo) iterator.next();
1210: boolean found = false;
1211: Iterator inner = roleList.iterator();
1212: while (inner.hasNext()) {
1213: Role role = (Role) inner.next();
1214: if (role.getRoleName().equals(roleInfo.getName())) {
1215: found = true;
1216: break;
1217: }
1218: }
1219: if (found == false)
1220: roleList.add(new Role(roleInfo.getName(),
1221: new RoleList()));
1222: }
1223: }
1224:
1225: /**
1226: * Get the relation for a relation id
1227: *
1228: * @param relationId the relation id
1229: * @return the relation's object name or a relation support object
1230: * @exception IllegalArgumentException for a null relation id
1231: * @exception RelationNotFoundException when the relation is not registered
1232: */
1233: private Object retrieveRelationForId(String relationId)
1234: throws IllegalArgumentException, RelationNotFoundException {
1235: if (relationId == null)
1236: throw new IllegalArgumentException("null relation id");
1237: Object result = relationsById.get(relationId);
1238: if (result == null)
1239: throw new RelationNotFoundException(relationId);
1240: return result;
1241: }
1242:
1243: /**
1244: * Get the relation type name for a relation id
1245: *
1246: * @param relationId the relation id
1247: * @return the relation type name
1248: * @exception IllegalArgumentException for a null relation id
1249: * @exception RelationNotFoundException when the relation is not registered
1250: */
1251: private String retrieveTypeNameForId(String relationId)
1252: throws IllegalArgumentException, RelationNotFoundException {
1253: if (relationId == null)
1254: throw new IllegalArgumentException("null relation id");
1255: String result = (String) typeNamesById.get(relationId);
1256: if (result == null)
1257: throw new RelationNotFoundException(relationId);
1258: return result;
1259: }
1260:
1261: /**
1262: * Get the relation type for a relation type name
1263: *
1264: * @param relationTypeName the relation type name
1265: * @return the relation type
1266: * @exception IllegalArgumentException for a null relation type name
1267: * @exception RelationTypeNotFoundException when the relation is not
1268: * registered.
1269: */
1270: private RelationType retrieveRelationTypeForName(
1271: String relationTypeName) throws IllegalArgumentException,
1272: RelationTypeNotFoundException {
1273: if (relationTypeName == null)
1274: throw new IllegalArgumentException(
1275: "Null relation type name");
1276: // Get the relation type
1277: RelationType result = (RelationType) typesByName
1278: .get(relationTypeName);
1279: if (result == null)
1280: throw new RelationTypeNotFoundException(relationTypeName);
1281: return result;
1282: }
1283:
1284: /**
1285: * Send a notification.
1286: *
1287: * @param type the notification type
1288: * @param description the human readable description
1289: * @param relationId the relation id of the relation
1290: * @param unregMBeans the mbeans removed when a relation is removed
1291: * @param newRole the role after an update
1292: * @param oldRoleValue the old role values after an update
1293: * @exception IllegalArgumentException for a null relation id
1294: * @exception RelationNotFoundException for an invalid relation id.
1295: */
1296: private void sendNotification(String type, String description,
1297: String relationId, List unregMBeans, Role newRole,
1298: List oldRoleValue) throws IllegalArgumentException,
1299: RelationNotFoundException {
1300: if (type == null)
1301: throw new IllegalArgumentException("null notification type");
1302:
1303: // Get the relation type name
1304: String typeName = retrieveTypeNameForId(relationId);
1305:
1306: // Get the relation's object name (if it has one)
1307: Object relation = retrieveRelationForId(relationId);
1308: ObjectName relationName = null;
1309: if (relation instanceof ObjectName)
1310: relationName = (ObjectName) relation;
1311:
1312: // Get the next sequence number
1313: long sequence;
1314: synchronized (this ) {
1315: sequence = ++notificationSequence;
1316: }
1317: // Send the notification
1318: // REVIEW: According to the spec, the source should be a RelationService
1319: // that doesn't make any sense, it's not serializable
1320: // I use the object name
1321: if (type.equals(RelationNotification.RELATION_BASIC_UPDATE)
1322: || type
1323: .equals(RelationNotification.RELATION_MBEAN_UPDATE))
1324: sendNotification(new RelationNotification(type,
1325: relationService, sequence, System
1326: .currentTimeMillis(), description,
1327: relationId, typeName, relationName, newRole
1328: .getRoleName(), newRole.getRoleValue(),
1329: oldRoleValue));
1330: else
1331: sendNotification(new RelationNotification(type,
1332: relationService, sequence, System
1333: .currentTimeMillis(), description,
1334: relationId, typeName, relationName, unregMBeans));
1335: }
1336:
1337: /**
1338: * Validate and add the relation.
1339: *
1340: * @param relationId the relation id
1341: * @param relation the relation to add
1342: * @param relationTypeName the relation type name
1343: * @exception InvalidRelationIdException when it is already present
1344: * @exception RelationNotFoundException when an error occurs invoking the
1345: * relation
1346: * @exception IllegalArgumentException when there is an error in the
1347: * parameters
1348: * @exception RelationServiceNotRegisteredException when the relation
1349: * service has not started.
1350: */
1351: private synchronized void validateAndAddRelation(String relationId,
1352: Object relation, String relationTypeName)
1353: throws InvalidRelationIdException {
1354: if (relationsById.containsKey(relationId))
1355: throw new InvalidRelationIdException(relationId);
1356: relationsById.put(relationId, relation);
1357: idsByRelation.put(relation, relationId);
1358: typeNamesById.put(relationId, relationTypeName);
1359:
1360: // Retrieve all the roles
1361: RoleList roles = null;
1362: if (relation instanceof RelationSupport) {
1363: RelationSupport support = (RelationSupport) relation;
1364: roles = support.retrieveAllRoles();
1365: } else {
1366: try {
1367: roles = (RoleList) server.invoke((ObjectName) relation,
1368: "retrieveAllRoles", new Object[0],
1369: new String[0]);
1370: } catch (Exception e) {
1371: throw new RuntimeException(e.toString());
1372: }
1373: }
1374:
1375: // Update the roles
1376: Iterator iterator = roles.iterator();
1377: while (iterator.hasNext()) {
1378: Role role = (Role) iterator.next();
1379: try {
1380: updateRoleMap(relationId, role, role.getRoleValue());
1381: } catch (Exception e) {
1382: throw new RuntimeException(e.toString());
1383: }
1384: }
1385:
1386: // We are now managing this relation
1387: if (relation instanceof RelationSupport) {
1388: RelationSupport support = (RelationSupport) relation;
1389: support.setRelationServiceManagementFlag(new Boolean(true));
1390: } else {
1391: try {
1392: Attribute attribute = new Attribute(
1393: "RelationServiceManagementFlag", new Boolean(
1394: true));
1395: server.setAttribute((ObjectName) relation, attribute);
1396: } catch (Exception doesntImplementRelationSupportMBean) {
1397: }
1398: }
1399:
1400: // Send a notification of the addition
1401: try {
1402: sendRelationCreationNotification(relationId);
1403: } catch (RelationNotFoundException e) {
1404: throw new RuntimeException(e.toString());
1405: }
1406: }
1407:
1408: /**
1409: * Validate a relation type.
1410: *
1411: * @param relationType the relation to validate
1412: * @exception InvalidRelationTypeException when it is not valid
1413: */
1414: private void validateRelationType(RelationType relationType)
1415: throws InvalidRelationTypeException {
1416: // Check the role information
1417: HashSet roleNames = new HashSet();
1418: ArrayList roleInfos = (ArrayList) relationType.getRoleInfos();
1419: if (roleInfos == null)
1420: throw new InvalidRelationTypeException("Null role infos");
1421: if (roleInfos.size() == 0)
1422: throw new InvalidRelationTypeException("No role infos");
1423: synchronized (roleInfos) {
1424: Iterator iterator = roleInfos.iterator();
1425: while (iterator.hasNext()) {
1426: RoleInfo roleInfo = (RoleInfo) iterator.next();
1427: if (roleInfo == null)
1428: throw new InvalidRelationTypeException("Null role");
1429: if (roleNames.contains(roleInfo.getName()))
1430: throw new InvalidRelationTypeException(
1431: "Duplicate role name" + roleInfo.getName());
1432: roleNames.add(roleInfo.getName());
1433: }
1434: }
1435: }
1436: }
|