0001: /**
0002: * The XMOJO Project 5
0003: * Copyright © 2003 XMOJO.org. All rights reserved.
0004:
0005: * NO WARRANTY
0006:
0007: * BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
0008: * THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
0009: * OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
0010: * PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
0011: * OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
0012: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
0013: * TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE
0014: * LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
0015: * REPAIR OR CORRECTION.
0016:
0017: * IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
0018: * ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
0019: * THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
0020: * GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
0021: * USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF
0022: * DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
0023: * PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE),
0024: * EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
0025: * SUCH DAMAGES.
0026: **/package javax.management.relation;
0027:
0028: import javax.management.*;
0029:
0030: import java.util.*;
0031:
0032: /**
0033: * The Relation Service is in charge of creating and deleting relation types
0034: * and relations, of handling the consistency and of providing query mechanisms.
0035: * <P>
0036: * It implements the NotificationBroadcaster by extending
0037: * NotificationBroadcasterSupport to send notifications when a relation
0038: * is removed from it.
0039: * <P>
0040: * It implements the NotificationListener interface to be able to receive
0041: * notifications concerning unregistration of MBeans referenced in relation
0042: * roles and of relation MBeans. It implements the MBeanRegistration interface
0043: * to be able to retrieve its ObjectName and MBean Server.
0044: */
0045: public class RelationService extends NotificationBroadcasterSupport
0046: implements RelationServiceMBean, MBeanRegistration,
0047: NotificationListener {
0048: /** **/
0049: private HashMap relationsTable = new HashMap();
0050:
0051: /** **/
0052: private HashMap relationTypesTable = new HashMap();
0053:
0054: /** **/
0055: private HashMap relationObjNamesTable = new HashMap();
0056:
0057: /** **/
0058: private HashMap relationTypeObjTable = new HashMap();
0059:
0060: /** **/
0061: private HashMap relTypeToIDTable = new HashMap();
0062:
0063: private String ERR_VALUE = new String();
0064:
0065: private HashMap refMBeansTable = new HashMap();
0066:
0067: private boolean purgeFlag = true;
0068:
0069: private long notifNo = 0;
0070:
0071: private ObjectName relObjectName = null;
0072:
0073: private ObjectName objectName = null;
0074:
0075: private MBeanServer mbeanServer = null;
0076:
0077: private MBeanServerNotificationFilter notifFilter = null;
0078:
0079: private ArrayList notifList = new ArrayList();
0080:
0081: /**
0082: * Constructor initiates relation service
0083: * @param theImmediatePurgeFlg - flag to indicate when a notification is
0084: * received for the unregistration of a MBean referenced in
0085: * a relation, if an immediate "purge" of the relations (look
0086: * for the relations no longer valid) has to be performed ,
0087: * or if that will be performed only when the purgeRelations
0088: * method will be explicitly called. true is immediate purge.
0089: */
0090: public RelationService(boolean theImmediatePurgeFlg) {
0091: this .purgeFlag = theImmediatePurgeFlg;
0092: try {
0093: objectName = new ObjectName("Services:type=RelationService");
0094: } catch (Exception e) {
0095: }
0096: }
0097:
0098: /**
0099: * Description copied from interface: MBeanRegistration
0100: * <P>
0101: * Allows the MBean to perform any operations needed after having been
0102: * de-registered in the MBean mbeanServer.
0103: * <P>
0104: * Specified by:
0105: * postDeregister in interface MBeanRegistration
0106: */
0107: public void postDeregister() {
0108: //This is only for satisfying MBeanRegistration Interface.
0109: }
0110:
0111: /**
0112: * Description copied from interface: MBeanRegistration
0113: * <P>Allows the MBean to perform any operations needed after having been
0114: * registered in the MBean server or after the registration has failed.
0115: * <P>
0116: * Specified by:
0117: * postRegister in interface MBeanRegistration
0118: * Tags copied from interface: MBeanRegistration
0119: *
0120: * @param registrationDone - Indicates whether or not the MBean has been
0121: * successfully registered in the MBean mbeanServer. The
0122: * value false means that the registration phase has failed.
0123: */
0124: public void postRegister(java.lang.Boolean registrationDone) {
0125: // after registration with the MBean Server , register the
0126: // RelationService for MBeanServer Notifications.To register for
0127: // MBeanServer notifications, register with the Standard
0128: // MBeanServerDelegate ObjectName.
0129: try {
0130: if (registrationDone.booleanValue()) {
0131: //This filter will be created with all the ObjectNames selected by default.
0132: mbeanServer.addNotificationListener(new ObjectName(
0133: "JMImplementation:type=MBeanServerDelegate"),
0134: this , new MBeanServerNotificationFilter(),
0135: (new Integer(2)));
0136: }
0137: } catch (Exception e) {
0138: System.out
0139: .println("Exception occured while adding the RelationService as a Notification"
0140: + "Listener to the MBean Server for MBeanServerNotifications!!!!!!!");
0141: }
0142: }
0143:
0144: /**
0145: * Description copied from interface: MBeanRegistration
0146: * <P>Allows the MBean to perform any operations it needs before being
0147: * de-registered by the MBean mbeanServer.
0148: * <P>
0149: * Specified by:
0150: * preDeregister in interface MBeanRegistration
0151: * Tags copied from interface: MBeanRegistration
0152: *
0153: * @exception java.langException - This exception should be caught by the
0154: * MBean server and re-thrown as an MBeanRegistrationException.
0155: */
0156: public void preDeregister() throws Exception {
0157: //This method is only to satisfy MBeanRegistration Interface ...Maybe used later
0158: }
0159:
0160: /**
0161: * Description copied from interface: MBeanRegistration
0162: * <P>
0163: * Allows the MBean to perform any operations it needs before being
0164: * registered in the MBean mbeanServer. If the name of the MBean is not
0165: * specified, the MBean can provide a name for its registration.
0166: * <P>If any exception is raised, the MBean will not be registered in the
0167: * MBean mbeanServer.
0168: * <P>
0169: * Specified by:
0170: * preRegister in interface MBeanRegistration
0171: * Tags copied from interface: MBeanRegistration
0172: *
0173: * @param server - The MBean server in which the MBean will be registered.
0174: *
0175: * @param name - The object name of the MBean.
0176: *
0177: * @return The name of the MBean registered.
0178: *
0179: * @exception java.lang.Exception - This exception should be caught by the
0180: * MBean server and re-thrown as an MBeanRegistrationException.
0181: */
0182: public ObjectName preRegister(MBeanServer server, ObjectName name)
0183: throws java.lang.Exception {
0184: //store the reference of the MBeanServer and the ObjectName of this RelationService.
0185: this .mbeanServer = server;
0186: this .objectName = name;
0187:
0188: return name;
0189: }
0190:
0191: /**
0192: * Adds a MBean created by the user (and registered by him in the
0193: * MBean Server) as a relation in the Relation Service.
0194: * <P>To be added as a relation, the MBean must conform to the following:
0195: * <P>- implement the Relation interface
0196: * <P>- have for RelationService ObjectName the ObjectName of current Relation Service
0197: * <P>- have a relation id unique and unused in current Relation Service
0198: * <P>- have for relation type a relation type created in the Relation Service
0199: * <P>- have roles conforming to the role info provided in the relation type.
0200: *
0201: * @param theRelObjectName - ObjectName of the relation MBean to be added.
0202: *
0203: * @throws java.lang.IllegalArgumentException - if null parameter
0204: *
0205: * @throws RelationServiceNotRegisteredException - if the Relation Service
0206: * is not registered in the MBean Server
0207: *
0208: * @throws java.lang.NoSuchMethodException - If the MBean does not
0209: * implement the Relation interface
0210: *
0211: * @throws InvalidRelationIdException - if:
0212: * <P> - no relation identifier in MBean
0213: * <P> - the relation identifier is already used in the Relation Service
0214: *
0215: * @throws InstanceNotFoundException - if the MBean for given ObjectName
0216: * has not been registered
0217: *
0218: * @throws InvalidRelationServiceException - if:
0219: * <P> - no Relation Service name in MBean
0220: * <P> - the Relation Service name in the MBean is not the one
0221: * of the current Relation Service
0222: *
0223: * @throws RelationTypeNotFoundException - if:
0224: * <P> - no relation type name in MBean
0225: * <P> - the relation type name in MBean does not correspond to
0226: * a relation type created in the Relation Service
0227: *
0228: * @throws InvalidRoleValueException - if:
0229: * <P> - the number of referenced MBeans in a role is less than
0230: * expected minimum degree
0231: * <P> - the number of referenced MBeans in a role exceeds
0232: * expected maximum degree
0233: * <P> - one referenced MBean in the value is not an Object of
0234: * the MBean class expected for that role
0235: * <P> - a MBean provided for a role does not exist
0236: *
0237: * @throws RoleNotFoundException - if a value is provided for a role that
0238: * does not exist in the relation type
0239: */
0240: public void addRelation(ObjectName theRelObjectName)
0241: throws IllegalArgumentException,
0242: RelationServiceNotRegisteredException,
0243: NoSuchMethodException, InvalidRelationIdException,
0244: InstanceNotFoundException, InvalidRelationServiceException,
0245: RelationTypeNotFoundException, RoleNotFoundException,
0246: InvalidRoleValueException {
0247: if (theRelObjectName == null)
0248: throw new IllegalArgumentException(
0249: RelationErrs.ERR_ILLEGAL_ARG);
0250:
0251: if (!(mbeanServer.isRegistered(this .objectName)))
0252: throw new RelationServiceNotRegisteredException(
0253: RelationErrs.ERR_REL_SERV_NOT_FOUND);
0254:
0255: if (!(mbeanServer.isRegistered(theRelObjectName))) {
0256: throw new InstanceNotFoundException();
0257: }
0258:
0259: //check if the given ObjectName is actually an instanceOf Relation.
0260: boolean isRelation = mbeanServer.isInstanceOf(theRelObjectName,
0261: "javax.management.relation.Relation");
0262:
0263: if (!isRelation)
0264: throw new NoSuchMethodException();
0265:
0266: Object[] params = new Object[0];
0267: String[] signature = new String[0];
0268: String relId = null;
0269:
0270: try {
0271: relId = (String) (mbeanServer.invoke(theRelObjectName,
0272: "getRelationId", params, signature));
0273: } catch (MBeanException me) {
0274: throw new RuntimeException((me.getTargetException())
0275: .getMessage());
0276: } catch (ReflectionException re) {
0277: throw new RuntimeException(re.getMessage());
0278: }
0279:
0280: if (relId == null) {
0281: throw new InvalidRelationIdException("Null Value");
0282: }
0283:
0284: //Now check if there is already exisitng RelationId.
0285: if (this .isRelationIdAlreadyExists(relId)) {
0286: throw new InvalidRelationIdException(
0287: RelationErrs.ERR_RELATIONID_ALREADY_EXISTS);
0288: }
0289:
0290: ObjectName relServObjName = null;
0291:
0292: try {
0293: relServObjName = (ObjectName) (mbeanServer.invoke(
0294: theRelObjectName, "getRelationServiceName", params,
0295: signature));
0296: } catch (MBeanException me) {
0297: throw new RuntimeException((me.getTargetException())
0298: .getMessage());
0299: } catch (ReflectionException re) {
0300: throw new RuntimeException(re.getMessage());
0301: }
0302:
0303: boolean badRelServFlg = false;
0304: if (relServObjName == null) {
0305: badRelServFlg = true;
0306: } else if (!(relServObjName.equals(objectName))) {
0307: badRelServFlg = true;
0308: }
0309:
0310: if (badRelServFlg) {
0311: throw new InvalidRelationServiceException();
0312: }
0313:
0314: String relTypeName = null;
0315: try {
0316: relTypeName = (String) (mbeanServer.invoke(
0317: theRelObjectName, "getRelationTypeName", params,
0318: signature));
0319: } catch (MBeanException me) {
0320: throw new RuntimeException((me.getTargetException())
0321: .getMessage());
0322: } catch (ReflectionException re) {
0323: throw new RuntimeException(re.getMessage());
0324: }
0325:
0326: if (relTypeName == null) {
0327: throw new RelationTypeNotFoundException(
0328: "RelationType is null");
0329: }
0330:
0331: RoleList roleList = null;
0332:
0333: try {
0334: roleList = (RoleList) (mbeanServer.invoke(theRelObjectName,
0335: "retrieveAllRoles", params, signature));
0336: } catch (MBeanException me) {
0337: throw new RuntimeException((me.getTargetException())
0338: .getMessage());
0339: } catch (ReflectionException re) {
0340: throw new RuntimeException(re.getMessage());
0341: }
0342:
0343: validateAndAddRelation(false, null, theRelObjectName, relId,
0344: relTypeName, roleList);
0345:
0346: relationObjNamesTable.put(theRelObjectName, relId);
0347:
0348: try {
0349: Object[] params1 = new Object[1];
0350: params1[0] = new Boolean(true);
0351: String[] sig1 = new String[1];
0352: sig1[0] = "java.lang.Boolean";
0353: mbeanServer.invoke(theRelObjectName,
0354: "setRelationServiceManagementFlag", params1, sig1);
0355: } catch (Exception exc) {
0356: }
0357:
0358: //TODO
0359: ArrayList newRefList = new ArrayList();
0360: newRefList.add(theRelObjectName);
0361: updateUnregistrationListener(newRefList, null);
0362: }
0363:
0364: /**
0365: * Adds given object as a relation type. The object is expected to
0366: * implement the RelationType interface.
0367: *
0368: * @param theRelTypeObj - relation type object (implementing the
0369: * RelationType interface)
0370: *
0371: * @exception java.lang.IllegalArgumentException - if null parameter
0372: *
0373: * @exception InvalidRelationTypeException - if there is already a
0374: * relation type with that name.
0375: */
0376: public void addRelationType(RelationType theRelTypeObj)
0377: throws IllegalArgumentException,
0378: InvalidRelationTypeException {
0379: if (theRelTypeObj == null) {
0380: throw new IllegalArgumentException(
0381: RelationErrs.ERR_ILLEGAL_ARG);
0382: }
0383:
0384: List roleInfoList = theRelTypeObj.getRoleInfos();
0385:
0386: if (roleInfoList == null) {
0387: throw new InvalidRelationTypeException("Null Value");
0388: }
0389:
0390: RoleInfo[] roleInfoArray = new RoleInfo[roleInfoList.size()];
0391: int i = 0;
0392:
0393: Iterator iter = roleInfoList.iterator();
0394: while (iter.hasNext()) {
0395: RoleInfo roleInfo = (RoleInfo) (iter.next());
0396: roleInfoArray[i] = roleInfo;
0397: i++;
0398: }
0399:
0400: checkRoleInfoConsistency(roleInfoArray);
0401: validateAndAddRelationType(theRelTypeObj);
0402: }
0403:
0404: /**
0405: * Checks if given Role can be read in a relation of the given type.
0406: *
0407: * @param theRoleName - name of role to be checked
0408: *
0409: * @param theRelTypeName - name of the relation type
0410: *
0411: * @return an Integer wrapping an integer corresponding to possible
0412: * problems represented as constants in RoleUnresolved:
0413: * <P> - 0 if role can be read
0414: * <P> - integer corresponding to RoleStatus.NO_ROLE_WITH_NAME
0415: * <P> - integer corresponding to RoleStatus.ROLE_NOT_READABLE
0416: *
0417: * @exception IllegalArgument - if null parameter
0418: *
0419: * @exception RelationTypeNotFoundException - if the relation type is
0420: * not known in the Relation Service
0421: */
0422: public Integer checkRoleReading(String theRoleName,
0423: String theRelTypeName) throws IllegalArgumentException,
0424: RelationTypeNotFoundException {
0425: if (theRoleName == null || theRelTypeName == null) {
0426: throw new IllegalArgumentException(
0427: RelationErrs.ERR_ILLEGAL_ARG);
0428: }
0429:
0430: Integer toRet = null;
0431: RelationType relType = getRelationType(theRelTypeName);
0432:
0433: try {
0434: RoleInfo roleInfo = relType.getRoleInfo(theRoleName);
0435:
0436: toRet = getRoleStatusInteger(theRoleName, null, roleInfo,
0437: false, 1);
0438:
0439: } catch (RoleInfoNotFoundException e) {
0440: toRet = new Integer(RoleStatus.NO_ROLE_WITH_NAME);
0441: }
0442:
0443: return toRet;
0444: }
0445:
0446: /**
0447: * Checks if given Role can be set in a relation of given type.
0448: *
0449: * @param theRole - role to be checked
0450: *
0451: * @param theRelTypeName - name of relation type
0452: *
0453: * @param theInitFlg - flag to specify that the checking is done for the
0454: * initialisation of a role, write access shall not be verified.
0455: *
0456: * @return an Integer wrapping an integer corresponding to possible
0457: * problems represented as constants in RoleUnresolved:
0458: * - 0 if role can be set
0459: * - integer corresponding to RoleStatus.NO_ROLE_WITH_NAME
0460: * - integer for RoleStatus.ROLE_NOT_WRITABLE
0461: * - integer for RoleStatus.LESS_THAN_MIN_ROLE_DEGREE
0462: * - integer for RoleStatus.MORE_THAN_MAX_ROLE_DEGREE
0463: * - integer for RoleStatus.REF_MBEAN_OF_INCORRECT_CLASS
0464: * - integer for RoleStatus.REF_MBEAN_NOT_REGISTERED
0465: *
0466: * @exception java.lang.IllegalArgumentException - if null parameter
0467: *
0468: * @exception RelationTypeNotFoundException - if unknown relation type
0469: */
0470: public Integer checkRoleWriting(Role theRole,
0471: String theRelTypeName, Boolean theInitFlg)
0472: throws IllegalArgumentException,
0473: RelationTypeNotFoundException {
0474: if (theRole == null || theRelTypeName == null
0475: || theInitFlg == null) {
0476: throw new IllegalArgumentException(
0477: RelationErrs.ERR_ILLEGAL_ARG);
0478: }
0479:
0480: RelationType relType = getRelationType(theRelTypeName);
0481:
0482: String roleName = theRole.getRoleName();
0483: ArrayList roleValue = (ArrayList) (theRole.getRoleValue());
0484: boolean writeFlag = true;
0485:
0486: if (theInitFlg.booleanValue()) {
0487: writeFlag = false;
0488: }
0489:
0490: RoleInfo roleInfo = null;
0491:
0492: try {
0493: roleInfo = relType.getRoleInfo(roleName);
0494: } catch (RoleInfoNotFoundException exc) {
0495: return new Integer(RoleStatus.NO_ROLE_WITH_NAME);
0496: }
0497:
0498: Integer toRet = getRoleStatusInteger(roleName, roleValue,
0499: roleInfo, writeFlag, 2);
0500:
0501: return toRet;
0502: }
0503:
0504: /**
0505: * Creates a simple relation (represented by a RelationSupport object) of
0506: * given relation type, and adds it in the Relation Service.
0507: * <P>Roles are initialized according to the role list provided in
0508: * parameter. The ones not initialised using that mean are set to an
0509: * empty ArrayList of ObjectNames.
0510: * <P>A RelationNotification, with type RELATION_BASIC_CREATION, is sent.
0511: *
0512: * @param theRelId - relation identifier, to uniquely identify the
0513: * relation inside the Relation Service
0514: *
0515: * @param theRelTypeName - name of the relation type (has to be created
0516: * in the Relation Service)
0517: *
0518: * @param theRoleList - role list to initialise roles of the relation
0519: * (can be null).
0520: *
0521: * @exception RelationServiceNotRegisteredException - if the Relation
0522: * Service is not registered in the MBean Server
0523: *
0524: * @exception java.lang.IllegalArgumentException - if null paramater
0525: *
0526: * @exception RoleNotFoundException - if a value is provided for a role
0527: * that does not exist in the relation type
0528: *
0529: * @exception InvalidRelationIdException - if relation id already used
0530: *
0531: * @exception RelationTypeNotFoundException - if relation type not known
0532: * in Relation Service
0533: *
0534: * @exception InvalidRoleValueException - if:
0535: * - the same role name is used for two different roles
0536: * - the number of referenced MBeans in given value is less than
0537: * expected minimum degree
0538: * - the number of referenced MBeans in provided value exceeds
0539: * expected maximum degree
0540: * - one referenced MBean in the value is not an Object of the
0541: * MBean class expected for that role
0542: * - a MBean provided for that role does not exist
0543: */
0544: public void createRelation(String theRelId, String theRelTypeName,
0545: RoleList theRoleList)
0546: throws RelationServiceNotRegisteredException,
0547: IllegalArgumentException, RoleNotFoundException,
0548: InvalidRelationIdException, RelationTypeNotFoundException,
0549: InvalidRoleValueException {
0550: isActive();
0551:
0552: if (theRelId == null || theRelTypeName == null) {
0553: throw new IllegalArgumentException(
0554: RelationErrs.ERR_ILLEGAL_ARG);
0555: }
0556:
0557: RelationSupport relSupObj = new RelationSupport(theRelId,
0558: objectName, theRelTypeName, theRoleList);
0559: validateAndAddRelation(true, relSupObj, null, theRelId,
0560: theRelTypeName, theRoleList);
0561: }
0562:
0563: /**
0564: * Creates a relation type (RelationTypeSupport object) with given role infos
0565: * (provided by the RoleInfo objects), and adds it in the Relation Service.
0566: *
0567: * @param theRelTypeName - name of the relation type
0568: *
0569: * @param theRoleInfoArray - array of role infos
0570: *
0571: * @exception java.lang.IllegalArgumentException - if null parameter
0572: *
0573: * @exception InvalidRelationTypeException - If:
0574: * - there is already a relation type with that name
0575: * - the same name has been used for two different role infos
0576: * - no role info provided
0577: * - one null role info provided
0578: */
0579: public void createRelationType(String theRelTypeName,
0580: RoleInfo[] theRoleInfoArray)
0581: throws IllegalArgumentException,
0582: InvalidRelationTypeException {
0583: if (theRelTypeName == null || theRoleInfoArray == null)
0584: throw new IllegalArgumentException(
0585: "Cannot create a RelationType for null values");
0586:
0587: RelationType relType = new RelationTypeSupport(theRelTypeName,
0588: theRoleInfoArray);
0589:
0590: validateAndAddRelationType(relType);
0591: }
0592:
0593: /**
0594: * Retrieves the MBeans associated to given one in a relation.
0595: * <P>This corresponds to CIM Associators and AssociatorNames operations.
0596: *
0597: * @param theMBeanName - ObjectName of MBean
0598: *
0599: * @param theRelTypeName - can be null; if specified, only the relations of
0600: * that type will be considered in the search. Else all
0601: * relation types are considered.
0602: *
0603: * @param theRoleName - can be null; if specified, only the relations where
0604: * the MBean is referenced in that role will be considered.
0605: * Else all roles are considered.
0606: *
0607: * @return an HashMap, where the keys are the ObjectNames of the MBeans
0608: * associated to given MBean, and the value is, for each key,
0609: * an ArrayList of the relation ids of the relations where
0610: * the key MBean is associated to given one (as they can be
0611: * associated in several different relations).
0612: *
0613: * @exception java.lang.IllegalArgumentException - if null parameter
0614: */
0615: public Map findAssociatedMBeans(ObjectName theMBeanName,
0616: String theRelTypeName, String theRoleName)
0617: throws IllegalArgumentException {
0618: if (theMBeanName == null) {
0619: throw new IllegalArgumentException(
0620: RelationErrs.ERR_ILLEGAL_ARG);
0621: }
0622:
0623: //1.Find the relations referred by this Relation Type.
0624: //2.Find the referred MBeans in that Relation.
0625: //3.Form a HashMap without duplicating the values.
0626:
0627: HashMap referredRelations = (HashMap) (findReferencingRelations(
0628: theMBeanName, theRelTypeName, theRoleName));
0629:
0630: //The result will be populated in this HashMap
0631: HashMap toRet = new HashMap();
0632:
0633: Iterator iter = referredRelations.keySet().iterator();
0634: HashMap referredMBeans = null;
0635: while (iter.hasNext()) {
0636: String relId = (String) (iter.next());
0637: try {
0638: referredMBeans = (HashMap) (getReferencedMBeans(relId));
0639: } catch (Exception e) {
0640: throw new RuntimeException(e.getMessage());
0641: }
0642:
0643: Iterator iter1 = referredMBeans.keySet().iterator();
0644: while (iter1.hasNext()) {
0645: ObjectName mbeanName = (ObjectName) (iter1.next());
0646: if (!mbeanName.equals(theMBeanName)) {
0647: ArrayList relIdList = (ArrayList) (toRet
0648: .get(mbeanName));
0649: if (relIdList == null) {
0650: relIdList = new ArrayList();
0651: relIdList.add(relId);
0652: toRet.put(mbeanName, relIdList);
0653: } else {
0654: relIdList.add(relId);
0655: }
0656:
0657: }
0658: }
0659: }
0660:
0661: return toRet;
0662: }
0663:
0664: /**
0665: * Retrieves the relations where a given MBean is referenced.
0666: * <P>This corresponds to the CIM "References" and "ReferenceNames" operations.
0667: *
0668: * @param theMBeanName - ObjectName of MBean
0669: *
0670: * @param theRelTypeName - can be null; if specified, only the relations of
0671: * that type will be considered in the search. Else all
0672: * relation types are considered.
0673: *
0674: * @param theRoleName - can be null; if specified, only the relations where
0675: * the MBean is referenced in that role will be returned.
0676: * Else all roles are considered.
0677: *
0678: * @return an HashMap, where the keys are the relation ids of the relations
0679: * where the MBean is referenced, and the value is, for each
0680: * key, an ArrayList of role names (as a MBean can be
0681: * referenced in several roles in the same relation).
0682: *
0683: * @exception java.lang.IllegalArgumentException - if null parameter
0684: */
0685: public Map findReferencingRelations(ObjectName theMBeanName,
0686: String theRelTypeName, String theRoleName)
0687: throws IllegalArgumentException {
0688: if (theMBeanName == null)
0689: throw new IllegalArgumentException(
0690: "Cannot find Referencing relations for a Null Object");
0691:
0692: HashMap toRet = new HashMap();
0693:
0694: Iterator e = relationsTable.keySet().iterator();
0695: String relId = null;
0696: String relTypeName = null;
0697:
0698: try {
0699: while (e.hasNext()) {
0700: //This array List will be the Object for every key in the HashMap.
0701: ArrayList toPut = new ArrayList();
0702:
0703: relId = (String) (e.next());
0704: Object relObject = relationsTable.get(relId);
0705:
0706: if (!(theRelTypeName == null)) {
0707: if (relObject instanceof RelationSupport) {
0708: relTypeName = ((RelationSupport) (relObject))
0709: .getRelationTypeName();
0710: } else {
0711: relTypeName = (String) (mbeanServer.invoke(
0712: (ObjectName) (relObject),
0713: "getRelationTypeName", null, null));
0714: }
0715: if (!(relTypeName.equals(theRelTypeName)))
0716: continue;
0717: }
0718:
0719: RoleList roleList = null;
0720: if (relObject instanceof RelationSupport) {
0721: roleList = ((RelationSupport) (relObject))
0722: .retrieveAllRoles();
0723: } else {
0724: roleList = (RoleList) (mbeanServer.invoke(
0725: (ObjectName) relObject, "retrieveAllRoles",
0726: null, null));
0727: }
0728: List roleValueList = null;
0729: for (int i = 0; i < roleList.size(); i++) {
0730: Role role = (Role) (roleList.get(i));
0731: if (theRoleName != null) {
0732: if (role.getRoleName().equals(theRoleName)) {
0733: roleValueList = this
0734: .getRoleValueFromRoleList(roleList,
0735: role.getRoleName());
0736: for (int j = 0; j < roleValueList.size(); j++) {
0737: if (((ObjectName) (roleValueList.get(j)))
0738: .toString()
0739: .equals(theMBeanName.toString()))
0740: toPut.add(role.getRoleName());
0741: }
0742: }
0743: continue;
0744: }
0745:
0746: roleValueList = this .getRoleValueFromRoleList(
0747: roleList, role.getRoleName());
0748: for (int j = 0; j < roleValueList.size(); j++) {
0749: if (((ObjectName) (roleValueList.get(j)))
0750: .toString().equals(
0751: theMBeanName.toString())) {
0752: toPut.add(role.getRoleName());
0753: }
0754: }
0755: }
0756:
0757: if (!(toPut == null || toPut.size() <= 0))
0758: toRet.put(relId, toPut);
0759: }//End while loop.
0760: } catch (Exception eee) {
0761: }
0762:
0763: return toRet;
0764: }
0765:
0766: /**
0767: * Returns the relation ids for relations of the given type.
0768: *
0769: * @param theRelTypeName - relation type name
0770: *
0771: * @return an ArrayList of relation ids.
0772: *
0773: * @exception java.lang.IllegalArgumentException - if null parameter
0774: *
0775: * @exception RelationTypeNotFoundException - if there is no relation
0776: * type with that name.
0777: */
0778: public List findRelationsOfType(String theRelTypeName)
0779: throws IllegalArgumentException, RelationTypeNotFoundException
0780: {
0781: if (theRelTypeName == null)
0782: {
0783: throw new IllegalArgumentException(RelationErrs.ERR_ILLEGAL_ARG);
0784: }
0785:
0786: RelationType relType = getRelationType(theRelTypeName);
0787:
0788: ArrayList toRet = new ArrayList();
0789: //get the relationIds of those relations that are of the given relation type.
0790: //add it to the ArrayList and return it.
0791: Object relObject = null;
0792: String relTypeName = null;
0793: String relId = null;
0794:
0795: Iterator enum = relationsTable.keySet().iterator();
0796: while(enum.hasNext())
0797: {
0798: relId = (String)(enum.next());
0799: relObject = relationsTable.get(relId);
0800: if(relObject instanceof RelationSupport)
0801: {
0802: relTypeName = ((RelationSupport)(relObject)).getRelationTypeName();
0803: }
0804: else
0805: {
0806: try
0807: {
0808: if(mbeanServer.isRegistered((ObjectName)relObject))
0809: {
0810: relTypeName = (String)(mbeanServer.invoke((ObjectName)relObject,"getRelationTypeName",null,null));
0811: }
0812: }
0813: catch(Exception e)
0814: {
0815: //e.printStackTrace();
0816: }
0817: }
0818:
0819: if(relTypeName != null && relTypeName.equals(theRelTypeName))
0820: {
0821: toRet.add(relId);
0822: }
0823: }
0824:
0825: //Before returning , check if there was any relation of that name
0826: return toRet;
0827: }
0828:
0829: /**
0830: * Returns all the relation ids for all the relations handled by the
0831: * Relation Service
0832: *
0833: * @return ArrayList of String
0834: */
0835: public List getAllRelationIds() {
0836: return new ArrayList(relationsTable.keySet());
0837: }
0838:
0839: /**
0840: * Retrieves names of all known relation types
0841: *
0842: * @return ArrayList of relation type names (Strings)
0843: */
0844: public List getAllRelationTypeNames() {
0845: return new ArrayList(relationTypeObjTable.keySet());
0846: }
0847:
0848: /**
0849: * Returns all roles present in the relation
0850: *
0851: * @param theRelId - relation id
0852: *
0853: * @return a RoleResult object, including a RoleList (for roles
0854: * succcessfully retrieved) and a RoleUnresolvedList (for
0855: * roles not readable).
0856: *
0857: * @exception java.lang.IllegalArgumentException - if null parameter
0858: *
0859: * @exception RelationNotFoundException - if no relation for given id
0860: *
0861: * @exception RelationServiceNotRegisteredException - if the Relation
0862: * Service is not registered in the MBean Server
0863: */
0864: public RoleResult getAllRoles(String theRelId)
0865: throws IllegalArgumentException, RelationNotFoundException,
0866: RelationServiceNotRegisteredException {
0867: if (theRelId == null) {
0868: throw new IllegalArgumentException(
0869: RelationErrs.ERR_ILLEGAL_ARG);
0870: }
0871:
0872: Object relObj = getRelation(theRelId);
0873:
0874: RoleResult result = null;
0875:
0876: if (relObj instanceof RelationSupport) {
0877: result = ((RelationSupport) relObj).getAllRolesFriend(this );
0878: } else {
0879: Object[] params = new Object[0];
0880: String[] signature = new String[0];
0881:
0882: try {
0883: result = (RoleResult) (mbeanServer.invoke(
0884: ((ObjectName) relObj), "getAllRoles", params,
0885: signature));
0886: } catch (Exception exc) {
0887: throw new RuntimeException(exc.getMessage());
0888: }
0889: }
0890:
0891: return result;
0892: }
0893:
0894: /**
0895: * Returns the flag to indicate if when a notification is received for the
0896: * unregistration of a MBean referenced in a relation, if an immediate
0897: * "purge" of the relations (look for the relations no longer valid) has
0898: * to be performed , or if that will be performed only when the
0899: * purgeRelations method will be explicitly called. true is immediate purge.
0900: *
0901: * @return boolean indicating the purgeFlag. true - means immediate Purge.
0902: */
0903: public boolean getPurgeFlag() {
0904: return this .purgeFlag;
0905: }//End getPurgeFlag().
0906:
0907: /**
0908: * Retrieves MBeans referenced in the various roles of the relation.
0909: *
0910: * @param theRelId - relation id
0911: *
0912: * @return a HashMap mapping:
0913: * ObjectName -> ArrayList of String (role names)
0914: *
0915: * @exception java.lang.IllegalArgumentException - if null parameter
0916: *
0917: * @exception RelationNotFoundException - if no relation for given relation id
0918: */
0919: public Map getReferencedMBeans(String theRelId)
0920: throws IllegalArgumentException, RelationNotFoundException {
0921: if (theRelId == null) {
0922: throw new IllegalArgumentException(
0923: RelationErrs.ERR_ILLEGAL_ARG);
0924: }
0925:
0926: Object relObj = getRelation(theRelId);
0927: HashMap toRet = null;
0928:
0929: if (relObj instanceof RelationSupport) {
0930: toRet = (HashMap) (((RelationSupport) relObj)
0931: .getReferencedMBeans());
0932: } else {
0933: try {
0934: toRet = (HashMap) (mbeanServer.invoke(
0935: ((ObjectName) relObj), "getReferencedMBeans",
0936: new Object[0], new String[0]));
0937: } catch (Exception e) {
0938: throw new RuntimeException(e.getMessage());
0939: }
0940: }
0941:
0942: return toRet;
0943: }
0944:
0945: /**
0946: * Returns name of associated relation type for given relation.
0947: *
0948: * @param theRelId - relation id
0949: *
0950: * @return The name of associated relation type for given relation
0951: *
0952: * @exception java.lang.IllegalArgumentException - if null parameter
0953: *
0954: * @exception RelationNotFoundException - if no relation for given relation id
0955: */
0956: public String getRelationTypeName(String theRelId)
0957: throws IllegalArgumentException, RelationNotFoundException {
0958: if (theRelId == null) {
0959: throw new IllegalArgumentException(
0960: RelationErrs.ERR_ILLEGAL_ARG);
0961: }
0962:
0963: Object relObj = getRelation(theRelId);
0964:
0965: String toRet = null;
0966:
0967: if (relObj instanceof RelationSupport) {
0968: toRet = ((RelationSupport) relObj).getRelationTypeName();
0969: } else {
0970: try {
0971: toRet = (String) (mbeanServer.invoke(
0972: ((ObjectName) relObj), "getRelationTypeName",
0973: new Object[0], new String[0]));
0974: } catch (Exception e) {
0975: throw new RuntimeException(e.getMessage());
0976: }
0977: }
0978:
0979: return toRet;
0980: }
0981:
0982: /**
0983: * Retrieves role value for given role name in given relation.
0984: *
0985: * @param theRelId - relation id
0986: *
0987: * @param theRoleName - name of role the ArrayList of ObjectName objects
0988: * being the role value
0989: *
0990: * @exception RelationServiceNotRegisteredException - if the Relation
0991: * Service is not registered
0992: *
0993: * @exception java.lang.IllegalArgumentException - if null parameter
0994: *
0995: * @exception RelationNotFoundException - if no relation with given id
0996: *
0997: * @exception RoleNotFoundException - if:
0998: * - there is no role with given name
0999: * or
1000: * - the role is not readable.
1001: */
1002: public List getRole(String theRelId, String theRoleName)
1003: throws RelationServiceNotRegisteredException,
1004: IllegalArgumentException, RelationNotFoundException,
1005: RoleNotFoundException {
1006: if (theRelId == null || theRoleName == null) {
1007: throw new IllegalArgumentException(
1008: RelationErrs.ERR_ILLEGAL_ARG);
1009: }
1010:
1011: isActive();
1012: Object relObj = getRelation(theRelId);
1013:
1014: ArrayList toRet = null;
1015:
1016: if (relObj instanceof RelationSupport) {
1017: toRet = (ArrayList) (((RelationSupport) relObj)
1018: .getRoleFriend(theRoleName, false, this ));
1019: } else {
1020: Object[] params = new Object[] { theRoleName };
1021: String[] sig = new String[] { "java.lang.String" };
1022:
1023: try {
1024: toRet = (ArrayList) (mbeanServer.invoke(
1025: ((ObjectName) relObj), "getRole", params, sig));
1026: } catch (MBeanException me) {
1027: if (me.getTargetException() instanceof RoleNotFoundException) {
1028: throw ((RoleNotFoundException) (me
1029: .getTargetException()));
1030: } else {
1031: throw new RuntimeException(me.getMessage());
1032: }
1033: } catch (Exception e) {
1034: throw new RuntimeException(e.getMessage());
1035: }
1036: }
1037:
1038: return toRet;
1039: }
1040:
1041: /**
1042: * Retrieves the number of MBeans currently referenced in the given role
1043: *
1044: * @param theRelId - relation id
1045: *
1046: * @param theRoleName - name of role
1047: *
1048: * @return the number of currently referenced MBeans in that role
1049: *
1050: * @exception java.lang.IllegalArgumentException - if null parameter
1051: *
1052: * @exception RelationNotFoundException - if no relation with given id
1053: *
1054: * @exception RoleNotFoundException - if there is no role with given name
1055: */
1056: public Integer getRoleCardinality(String theRelId,
1057: String theRoleName) throws IllegalArgumentException,
1058: RelationNotFoundException, RoleNotFoundException {
1059: if (theRelId == null || theRoleName == null) {
1060: throw new IllegalArgumentException(
1061: RelationErrs.ERR_ILLEGAL_ARG);
1062: }
1063:
1064: Object relObj = getRelation(theRelId);
1065:
1066: Integer toRet = null;
1067:
1068: if (relObj instanceof RelationSupport) {
1069: toRet = (Integer) (((RelationSupport) relObj)
1070: .getRoleCardinality(theRoleName));
1071: } else {
1072: Object[] params = new Object[] { theRoleName };
1073: String[] sig = new String[] { "java.lang.String" };
1074:
1075: try {
1076: toRet = (Integer) (mbeanServer.invoke(
1077: ((ObjectName) relObj), "getRoleCardinality",
1078: params, sig));
1079: } catch (MBeanException me) {
1080: if (me.getTargetException() instanceof RoleNotFoundException) {
1081: throw ((RoleNotFoundException) (me
1082: .getTargetException()));
1083: } else {
1084: throw new RuntimeException(me.getMessage());
1085: }
1086: } catch (Exception e) {
1087: throw new RuntimeException(e.getMessage());
1088: }
1089: }
1090:
1091: return toRet;
1092: }
1093:
1094: /**
1095: * Retrieves role info for given role of a given relation type
1096: *
1097: * @param theRelTypeName - name of relation type
1098: *
1099: * @param theRoleInfoName - name of role
1100: *
1101: * @return RoleInfo object.
1102: *
1103: * @exception java.lang.IllegalArgumentException - if null parameter
1104: *
1105: * @exception RelationTypeNotFoundException - if the relation type is not
1106: * known in the Relation Service
1107: *
1108: * @exception RoleInfoNotFoundException - if the role is not part of
1109: * the relation type.
1110: */
1111: public RoleInfo getRoleInfo(String theRelTypeName,
1112: String theRoleInfoName) throws IllegalArgumentException,
1113: RelationTypeNotFoundException, RoleInfoNotFoundException {
1114: if (theRelTypeName == null || theRoleInfoName == null) {
1115: throw new IllegalArgumentException(
1116: RelationErrs.ERR_ILLEGAL_ARG);
1117: }
1118:
1119: RelationType relType = getRelationType(theRelTypeName);
1120: RoleInfo roleInfo = relType.getRoleInfo(theRoleInfoName);
1121:
1122: return roleInfo;
1123: }
1124:
1125: /**
1126: * Retrieves list of role infos (RoleInfo objects) of a given relation type
1127: *
1128: * @param theRelTypeName - name of relation type
1129: *
1130: * @return ArrayList of RoleInfo.
1131: *
1132: * @exception java.lang.IllegalArgumentException - if null parameter
1133: *
1134: * @exception RelationTypeNotFoundException - if there is no relation
1135: * type with that name.
1136: */
1137: public List getRoleInfos(String theRelTypeName)
1138: throws IllegalArgumentException,
1139: RelationTypeNotFoundException {
1140: if (theRelTypeName == null) {
1141: throw new IllegalArgumentException(
1142: RelationErrs.ERR_ILLEGAL_ARG);
1143: }
1144:
1145: RelationType relType = getRelationType(theRelTypeName);
1146:
1147: return relType.getRoleInfos();
1148: }
1149:
1150: /**
1151: * Retrieves values of roles with given names in given relation.
1152: *
1153: * @param theRelId - relation id
1154: *
1155: * @param theRoleNameArray - array of names of roles to be retrieved
1156: *
1157: * @return a RoleResult object, including a RoleList (for roles
1158: * succcessfully retrieved) and a RoleUnresolvedList (for
1159: * roles not retrieved).
1160: *
1161: * @exception RelationServiceNotRegisteredException - if the Relation
1162: * Service is not registered in the MBean Server
1163: *
1164: * @exception java.lang.IllegalArgumentException - if null parameter
1165: *
1166: * @exception RelationNotFoundException - if no relation with given id
1167: */
1168: public RoleResult getRoles(String theRelId,
1169: String[] theRoleNameArray)
1170: throws RelationServiceNotRegisteredException,
1171: IllegalArgumentException, RelationNotFoundException {
1172: if (theRelId == null || theRoleNameArray == null) {
1173: throw new IllegalArgumentException(
1174: RelationErrs.ERR_ILLEGAL_ARG);
1175: }
1176:
1177: isActive();
1178: Object relObj = getRelation(theRelId);
1179:
1180: RoleResult toRet = null;
1181:
1182: if (relObj instanceof RelationSupport) {
1183: toRet = ((RelationSupport) relObj).getRolesFriend(
1184: theRoleNameArray, this );
1185: } else {
1186: try {
1187: Object[] params = new Object[] { theRoleNameArray };
1188: String[] sig = new String[] { theRoleNameArray
1189: .getClass().getName() };
1190:
1191: toRet = (RoleResult) (mbeanServer.invoke(
1192: ((ObjectName) relObj), "getRoles", params, sig));
1193: } catch (MBeanException me) {
1194: throw new RuntimeException((me.getTargetException())
1195: .getMessage());
1196: } catch (Exception e) {
1197: throw new RuntimeException(e.getMessage());
1198: }
1199: }
1200:
1201: return toRet;
1202: }
1203:
1204: /**
1205: * Checks if there is a relation identified in Relation Service with
1206: * given relation id.
1207: *
1208: * @param theRelId - relation id identifying the relation
1209: *
1210: * @return boolean: true if there is a relation, false else
1211: *
1212: * @exception java.lang.IllegalArgumentException - if null parameter
1213: */
1214: public Boolean hasRelation(String theRelId)
1215: throws IllegalArgumentException {
1216: if (theRelId == null) {
1217: throw new IllegalArgumentException(
1218: RelationErrs.ERR_ILLEGAL_ARG);
1219: }
1220:
1221: try {
1222: Object result = getRelation(theRelId);
1223: return new Boolean(true);
1224: } catch (RelationNotFoundException exc) {
1225: return new Boolean(false);
1226: }
1227: }
1228:
1229: /**
1230: * Checks if the Relation Service is active. Current condition is that
1231: * the Relation Service must be registered in the MBean Server
1232: **
1233: * @exception RelationServiceNotRegisteredException - if it is not registered
1234: */
1235: public void isActive() throws RelationServiceNotRegisteredException {
1236: if (mbeanServer == null) {
1237: throw new RelationServiceNotRegisteredException(
1238: "Relation Service not registered in the MBean mbeanServer.");
1239: }
1240: }
1241:
1242: /**
1243: * Returns the relation id associated to the given ObjectName if the MBean
1244: * has been added as a relation in the Relation Service.
1245: *
1246: * @param theObjName - ObjectName of supposed relation
1247: *
1248: * @return relation id (String) or null (if the ObjectName is not a
1249: * relation handled by the Relation Service)
1250: *
1251: * @exception java.lang.IllegalArgumentException - if null parameter
1252: */
1253: public String isRelation(ObjectName theObjName)
1254: throws IllegalArgumentException {
1255: if (theObjName == null) {
1256: throw new IllegalArgumentException(
1257: RelationErrs.ERR_ILLEGAL_ARG);
1258: }
1259:
1260: String relId = null;
1261: relId = (String) (relationObjNamesTable.get(theObjName));
1262:
1263: return relId;
1264: }
1265:
1266: /**
1267: * If the relation is represented by a MBean (created by the user and added
1268: * as a relation in the Relation Service), returns the ObjectName of the MBean.
1269: *
1270: * @param theRelId - relation id identifying the relation
1271: *
1272: * @return ObjectName of the corresponding relation MBean, or null if
1273: * the relation is not a MBean.
1274: *
1275: * @exception java.lang.IllegalArgumentException - if null parameter
1276: *
1277: * @exception RelationNotFoundException - there is no relation associated to that id
1278: */
1279: public ObjectName isRelationMBean(String theRelId)
1280: throws IllegalArgumentException, RelationNotFoundException {
1281: if (theRelId == null) {
1282: throw new IllegalArgumentException(
1283: RelationErrs.ERR_ILLEGAL_ARG);
1284: }
1285:
1286: Object relObj = getRelation(theRelId);
1287:
1288: if (relObj instanceof ObjectName) {
1289: return ((ObjectName) relObj);
1290: } else {
1291: return null;
1292: }
1293: }
1294:
1295: /**
1296: * Purges the relations.
1297: * <P>Depending on the purgeFlag value, this method is either called
1298: * automatically when a notification is received for the unregistration of
1299: * a MBean referenced in a relation (if the flag is set to true), or not
1300: * (if the flag is set to false).
1301: *
1302: * <P>In that case it is up to the user to call it to maintain the
1303: * consistency of the relations. To be kept in mind that if a MBean is
1304: * unregistered and the purge not done immediately, if the ObjectName is
1305: * reused and assigned to another MBean referenced in a relation, calling
1306: * manually this purgeRelations() method will cause trouble, as will
1307: * consider the ObjectName as corresponding to the unregistered MBean,
1308: * not seeing the new one.
1309: *
1310: * <P>The behavior depends on the cardinality of the role where the
1311: * unregistered MBean is referenced:
1312: * <P> - if removing one MBean reference in the role makes its number
1313: * of references less than the minimum degree, the relation
1314: * has to be removed.
1315: * <P> - if the remaining number of references after removing the
1316: * MBean reference is still in the cardinality range, keep the
1317: * relation and update it calling its
1318: * handleMBeanUnregistration() callback.
1319: *
1320: * @exception RelationServiceNotRegisteredException - if the Relation
1321: * Service is not registered in the MBean mbeanServer.
1322: */
1323: public void purgeRelations()
1324: throws RelationServiceNotRegisteredException {
1325: isActive();
1326:
1327: ArrayList localUnregNtfList = null;
1328:
1329: synchronized (notifList) {
1330: localUnregNtfList = (ArrayList) (notifList.clone());
1331: notifList = new ArrayList();
1332: }
1333:
1334: HashMap localMBean2RelIdMap = new HashMap();
1335: ArrayList obsRefList = new ArrayList();
1336:
1337: synchronized (refMBeansTable) {
1338: for (Iterator unregNtfIter = localUnregNtfList.iterator(); unregNtfIter
1339: .hasNext();) {
1340: MBeanServerNotification currNtf = (MBeanServerNotification) (unregNtfIter
1341: .next());
1342:
1343: ObjectName unregMBeanName = currNtf.getMBeanName();
1344:
1345: obsRefList.add(unregMBeanName);
1346:
1347: HashMap relIdMap = (HashMap) (refMBeansTable
1348: .get(unregMBeanName));
1349: localMBean2RelIdMap.put(unregMBeanName, relIdMap);
1350:
1351: refMBeansTable.remove(unregMBeanName);
1352: }
1353: }
1354:
1355: updateUnregistrationListener(null, obsRefList);
1356:
1357: for (Iterator unregNtfIter = localUnregNtfList.iterator(); unregNtfIter
1358: .hasNext();) {
1359: MBeanServerNotification currNtf = (MBeanServerNotification) (unregNtfIter
1360: .next());
1361:
1362: ObjectName unregMBeanName = currNtf.getMBeanName();
1363: HashMap localRelIdMap = (HashMap) (localMBean2RelIdMap
1364: .get(unregMBeanName));
1365:
1366: if (localRelIdMap != null) {
1367: Set localRelIdSet = localRelIdMap.keySet();
1368:
1369: for (Iterator relIdIter = localRelIdSet.iterator(); relIdIter
1370: .hasNext();) {
1371: String currRelId = (String) (relIdIter.next());
1372:
1373: ArrayList localRoleNameList = (ArrayList) (localRelIdMap
1374: .get(currRelId));
1375:
1376: try {
1377: handleReferenceUnregistration(currRelId,
1378: unregMBeanName, localRoleNameList);
1379: } catch (RelationNotFoundException e) {
1380: throw new RuntimeException(e.getMessage());
1381: } catch (RoleNotFoundException re) {
1382: throw new RuntimeException(re.getMessage());
1383: }
1384: }
1385: }
1386: }
1387:
1388: return;
1389: }
1390:
1391: /**
1392: * Removes given relation from the Relation Service.
1393: * <P>A RelationNotification notification is sent, its type being:
1394: * <P> - RelationNotification.RELATION_BASIC_REMOVAL if the relation
1395: * was only internal to the Relation Service
1396: * <P> - RelationNotification.RELATION_MBEAN_REMOVAL if the relation
1397: * is registered as a MBean. For MBeans referenced in such
1398: * relation, nothing will be done,
1399: *
1400: * @param theRelId - relation id of the relation to be removed
1401: *
1402: * @exception RelationServiceNotRegisteredException - if the Relation
1403: * Service is not registered in the MBean Server
1404: *
1405: * @exception java.lang.IllegalArgumentException - if null parameter
1406: *
1407: * @exception RelationNotFoundException - if no relation corresponding
1408: * to given relation id
1409: */
1410: public void removeRelation(String theRelId)
1411: throws RelationServiceNotRegisteredException,
1412: IllegalArgumentException, RelationNotFoundException {
1413: isActive();
1414:
1415: if (theRelId == null) {
1416: throw new IllegalArgumentException(
1417: RelationErrs.ERR_ILLEGAL_ARG);
1418: }
1419:
1420: Object relObj = getRelation(theRelId);
1421:
1422: // Removes it from listener filter
1423: if (relObj instanceof ObjectName) {
1424: ArrayList obsRefList = new ArrayList();
1425: obsRefList.add((ObjectName) relObj);
1426: // Can throw a RelationServiceNotRegisteredException
1427: updateUnregistrationListener(null, obsRefList);
1428: }
1429:
1430: sendRelationRemovalNotification(theRelId, null);
1431:
1432: //Let us clean everything here.
1433: //1. ReferredMBeans Table
1434: Iterator iter = refMBeansTable.keySet().iterator();
1435: ArrayList nonreferredObjs = new ArrayList();
1436:
1437: while (iter.hasNext()) {
1438: ObjectName refName = (ObjectName) (iter.next());
1439: //get the relatiosn where the MBean is used.
1440: HashMap map = (HashMap) (refMBeansTable.get(refName));
1441: if (map.containsKey(theRelId)) {
1442: map.remove(theRelId);
1443: }
1444: if (map.isEmpty()) {
1445: //This means that the MBean is no longer referred.
1446: //Add it temporarily to a list
1447: nonreferredObjs.add(refName);
1448: }
1449:
1450: }
1451:
1452: Iterator iter1 = nonreferredObjs.iterator();
1453: while (iter1.hasNext()) {
1454: ObjectName mbeanToRemove = (ObjectName) (iter1.next());
1455: refMBeansTable.remove(mbeanToRemove);
1456: }
1457:
1458: relationsTable.remove(theRelId);
1459:
1460: if (relObj instanceof ObjectName) {
1461: relationObjNamesTable.remove((ObjectName) relObj);
1462: }
1463:
1464: String relTypeName = null;
1465:
1466: relTypeName = (String) (relationTypesTable.get(theRelId));
1467: relationTypesTable.remove(theRelId);
1468: // - Relation type name to relation id map
1469: synchronized (relTypeToIDTable) {
1470: ArrayList relIdList = (ArrayList) (relTypeToIDTable
1471: .get(relTypeName));
1472: if (relIdList != null) {
1473: // Can be null if called from removeRelationType()
1474: relIdList.remove(theRelId);
1475: if (relIdList.isEmpty()) {
1476: // No other relation of that type
1477: relTypeToIDTable.remove(relTypeName);
1478: }
1479: }
1480: }
1481: }
1482:
1483: /**
1484: * Removes given relation type from Relation Service.
1485: * <P>
1486: * The relation objects of that type will be removed from the Relation Service.
1487: *
1488: * @param theRelTypeName - name of the relation type to be removed
1489: *
1490: * @exception RelationServiceNotRegisteredException - if the Relation
1491: * Service is not registered in the MBean Server
1492: *
1493: * @exception java.lang.IllegalArgumentException - if null parameter
1494: *
1495: * @exception RelationTypeNotFoundException - If there is no relation
1496: * type with that name
1497: */
1498: public void removeRelationType(String theRelTypeName)
1499: throws RelationServiceNotRegisteredException,
1500: IllegalArgumentException, RelationTypeNotFoundException {
1501: isActive();
1502:
1503: if (theRelTypeName == null) {
1504: throw new IllegalArgumentException(
1505: RelationErrs.ERR_ILLEGAL_ARG);
1506: }
1507:
1508: RelationType relType = getRelationType(theRelTypeName);
1509:
1510: ArrayList relIdList = null;
1511:
1512: synchronized (relTypeToIDTable) {
1513: // Note: take a copy of the list as it is a part of a map that
1514: // will be updated by removeRelation() below.
1515: ArrayList relIdList1 = (ArrayList) (relTypeToIDTable
1516: .get(theRelTypeName));
1517: if (relIdList1 != null) {
1518: relIdList = (ArrayList) (relIdList1.clone());
1519: }
1520: }
1521:
1522: // Removes the relation type from all maps
1523: synchronized (relationTypeObjTable) {
1524: relationTypeObjTable.remove(theRelTypeName);
1525: }
1526:
1527: synchronized (relTypeToIDTable) {
1528: relTypeToIDTable.remove(theRelTypeName);
1529: }
1530:
1531: // Removes all relations of that type
1532: if (relIdList != null) {
1533: for (Iterator relIdIter = relIdList.iterator(); relIdIter
1534: .hasNext();) {
1535: String currRelId = (String) (relIdIter.next());
1536: // Note: will remove it from relationTypesTable :)
1537: //
1538: // Can throw RelationServiceNotRegisteredException (detected
1539: // above)
1540: // Shall not throw a RelationNotFoundException
1541: try {
1542: removeRelation(currRelId);
1543: } catch (RelationNotFoundException exc1) {
1544: throw new RuntimeException(exc1.getMessage());
1545: }
1546: }
1547: }
1548: }
1549:
1550: /**
1551: * Sends a notification (RelationNotification) for a relation creation.
1552: * The notification type is:
1553: * <P> - RelationNotification.RELATION_BASIC_CREATION if the relation is
1554: * an object internal to the Relation Service
1555: * <P> - RelationNotification.RELATION_MBEAN_CREATION if the relation is a MBean added
1556: * as a relation. The source object is the Relation Service itself.
1557: * It is called in Relation Service createRelation() and
1558: * addRelation() methods.
1559: *
1560: * @param theRelId - relation identifier of the updated relation
1561: *
1562: * @exception java.lang.IllegalArgumentException - if null parameter
1563: *
1564: * @exception RelationNotFoundException - if there is no relation
1565: * for given relation id
1566: */
1567: public void sendRelationCreationNotification(String theRelId)
1568: throws IllegalArgumentException, RelationNotFoundException {
1569: if (theRelId == null) {
1570: throw new IllegalArgumentException(
1571: RelationErrs.ERR_ILLEGAL_ARG);
1572: }
1573:
1574: String relTypeName = (String) (relationTypesTable.get(theRelId));
1575: ObjectName relObjName = isRelationMBean(theRelId);
1576: String type = null;
1577:
1578: if (relObjName != null) {
1579: type = RelationNotification.RELATION_MBEAN_CREATION;
1580: } else {
1581: type = RelationNotification.RELATION_BASIC_CREATION;
1582: }
1583: RelationNotification notif = new RelationNotification(type,
1584: this , notifNo++, new Date().getTime(),
1585: "creating Relation" + theRelId, theRelId, relTypeName,
1586: relObjName, null);
1587:
1588: sendNotification(notif);
1589: }
1590:
1591: /**
1592: * Sends a notification (RelationNotification) for a relation removal.
1593: * The notification type is:
1594: * <P> - RelationNotification.RELATION_BASIC_REMOVAL if the relation is an
1595: * object internal to the Relation Service
1596: * <P> - RelationNotification.RELATION_MBEAN_REMOVAL if the relation is a
1597: * MBean added as a relation. The source object is the Relation
1598: * Service itself. It is called in Relation Service removeRelation() method.
1599: *
1600: * @param theRelId - relation identifier of the updated relation
1601: *
1602: * @param theUnregMBeanList - ArrayList of ObjectNames of MBeans expected
1603: * to be unregistered due to relation removal (can be null)
1604: *
1605: * @exception java.lang.IllegalArgumentException - if null parameter
1606: *
1607: * @exception RelationNotFoundException - if there is no relation
1608: * for given relation id
1609: */
1610: public void sendRelationRemovalNotification(String theRelId,
1611: List theUnregMBeanList) throws IllegalArgumentException,
1612: RelationNotFoundException {
1613: if (theRelId == null) {
1614: throw new IllegalArgumentException(
1615: RelationErrs.ERR_ILLEGAL_ARG);
1616: }
1617:
1618: String relTypeName = (String) (relationTypesTable.get(theRelId));
1619: ObjectName relObjName = isRelationMBean(theRelId);
1620: String type = null;
1621:
1622: if (relObjName != null) {
1623: type = RelationNotification.RELATION_MBEAN_REMOVAL;
1624: } else {
1625: type = RelationNotification.RELATION_BASIC_REMOVAL;
1626: }
1627:
1628: RelationNotification notif = new RelationNotification(type,
1629: this , notifNo++, new Date().getTime(),
1630: "Removing Relation" + theRelId, theRelId, relTypeName,
1631: relObjName, theUnregMBeanList);
1632:
1633: sendNotification(notif);
1634: }
1635:
1636: /**
1637: * Sends a notification (RelationNotification) for a role update in the
1638: * given relation. The notification type is:
1639: * <P> - RelationNotification.RELATION_BASIC_UPDATE if the relation is an
1640: * object internal to the Relation Service
1641: * <P> - RelationNotification.RELATION_MBEAN_UPDATE if the relation is a
1642: * MBean added as a relation.
1643: * The source object is the Relation Service itself.
1644: * It is called in relation MBean setRole() (for given role) and
1645: * setRoles() (for each role) methods (implementation provided in
1646: * RelationSupport class). It is also called in Relation Service
1647: * setRole() (for given role) and setRoles() (for each role) methods.
1648: *
1649: * @param theRelId - relation identifier of the updated relation
1650: *
1651: * @param theNewRole - new role (name and new value)
1652: *
1653: * @param theOldRoleValue - old role value (ArrayList of ObjectName objects)
1654: *
1655: * @exception java.lang.IllegalArgumentException - if null parameter
1656: *
1657: * @exception RelationNotFoundException - if there is no relation
1658: * for given relation id
1659: */
1660: public void sendRoleUpdateNotification(String theRelId,
1661: Role theNewRole, List theOldRoleValue)
1662: throws IllegalArgumentException, RelationNotFoundException {
1663: if (theRelId == null || theNewRole == null
1664: || theOldRoleValue == null) {
1665: throw new IllegalArgumentException(
1666: RelationErrs.ERR_ILLEGAL_ARG);
1667: }
1668:
1669: String roleName = theNewRole.getRoleName();
1670: ArrayList newRoleVal = (ArrayList) (theNewRole.getRoleValue());
1671:
1672: String relTypeName = (String) (relationTypesTable.get(theRelId));
1673: ObjectName relObjName = isRelationMBean(theRelId);
1674: String type = null;
1675: if (relObjName != null) {
1676: type = RelationNotification.RELATION_MBEAN_UPDATE;
1677: } else {
1678: type = RelationNotification.RELATION_BASIC_UPDATE;
1679: }
1680: RelationNotification notif = new RelationNotification(type,
1681: this , notifNo++, new Date().getTime(),
1682: "Updation of a role" + roleName, theRelId, relTypeName,
1683: relObjName, roleName, newRoleVal, theOldRoleValue);
1684:
1685: sendNotification(notif);
1686: }
1687:
1688: /**
1689: * Sets the flag to indicate if when a notification is received for the
1690: * unregistration of a MBean referenced in a relation, if an immediate
1691: * "purge" of the relations (look for the relations no longer valid) has
1692: * to be performed , or if that will be performed only when the
1693: * purgeRelations method will be explicitly called. true is immediate purge.
1694: *
1695: * @param thePurgeFlg - flag
1696: */
1697: public void setPurgeFlag(boolean thePurgeFlg) {
1698: this .purgeFlag = thePurgeFlg;
1699: }// End setPurgeFlag().
1700:
1701: /**
1702: * Sets the given role in given relation.
1703: * <P>Will check the role according to its corresponding role definition
1704: * provided in relation's relation type.
1705: * <P>The Relation Service will keep track of the change to keep the
1706: * consistency of relations by handling referenced MBean unregistrations.
1707: *
1708: * @param theRelId - relation id
1709: *
1710: * @param theRole - role to be set (name and new value)
1711: *
1712: * @exception RelationServiceNotRegisteredException - if the Relation
1713: * Service is not registered in the MBean Server.
1714: *
1715: * @exception java.lang.IllegalArgumentException - if null parameter
1716: *
1717: * @exception RelationNotFoundException - if no relation with given id
1718: *
1719: * @exception RoleNotFoundException - if:
1720: * - internal relation
1721: * and
1722: * - the role does not exist or is not writable
1723: *
1724: * @exception InvalidRoleValueException - if internal relation and value
1725: * provided for role is not valid:
1726: * - the number of referenced MBeans in given value is less
1727: * than expected minimum degree
1728: * or
1729: * - the number of referenced MBeans in provided value exceeds
1730: * expected maximum degree
1731: * or
1732: * - one referenced MBean in the value is not an Object of the
1733: * MBean class expected for that role
1734: * or
1735: * - a MBean provided for that role does not exist
1736: *
1737: * @exception RelationTypeNotFoundException - if unknown relation type
1738: */
1739: public void setRole(String theRelId, Role theRole)
1740: throws RelationServiceNotRegisteredException,
1741: IllegalArgumentException, RelationNotFoundException,
1742: RoleNotFoundException, InvalidRoleValueException {
1743: if (theRelId == null || theRole == null) {
1744: throw new IllegalArgumentException(
1745: RelationErrs.ERR_ILLEGAL_ARG);
1746: }
1747:
1748: isActive();
1749: Object relObj = getRelation(theRelId);
1750:
1751: if (relObj instanceof RelationSupport) {
1752: try {
1753: ((RelationSupport) relObj).setRoleFriend(theRole,
1754: false, this );
1755: } catch (RelationTypeNotFoundException exc) {
1756: throw new RuntimeException(exc.getMessage());
1757: }
1758: } else {
1759: Object[] params = new Object[] { theRole };
1760: String[] sig = new String[] { "javax.management.relation.Role" };
1761:
1762: try {
1763: mbeanServer.invoke(((ObjectName) relObj), "setRole",
1764: params, sig);
1765: } catch (MBeanException me) {
1766: if (me.getTargetException() instanceof RoleNotFoundException) {
1767: throw (RoleNotFoundException) (me
1768: .getTargetException());
1769: } else if (me.getTargetException() instanceof InvalidRoleValueException) {
1770: throw (InvalidRoleValueException) (me
1771: .getTargetException());
1772: } else {
1773: throw new RuntimeException(me.getMessage());
1774: }
1775: } catch (Exception e) {
1776: throw new RuntimeException(e.getMessage());
1777: }
1778: }
1779: }
1780:
1781: /**
1782: * Sets the given roles in given relation.
1783: * <P>Will check the role according to its corresponding role definition
1784: * provided in relation's relation type.
1785: * <P>The Relation Service keeps track of the changes to keep the
1786: * consistency of relations by handling referenced MBean unregistrations.
1787: *
1788: * @param theRelId - relation id
1789: *
1790: * @param theRoleList - list of roles to be set
1791: *
1792: * @return a RoleResult object, including a RoleList (for roles
1793: * succcessfully set) and a RoleUnresolvedList (for roles not set).
1794: *
1795: * @exception RelationServiceNotRegisteredException - if the Relation
1796: * Service is not registered in the MBean Server
1797: *
1798: * @exception java.lang.IllegalArgumentException - if null parameter
1799: *
1800: * @exception RelationNotFoundException - if no relation with given id
1801: */
1802: public RoleResult setRoles(String theRelId, RoleList theRoleList)
1803: throws RelationServiceNotRegisteredException,
1804: IllegalArgumentException, RelationNotFoundException {
1805: if (theRelId == null || theRoleList == null) {
1806: throw new IllegalArgumentException(
1807: RelationErrs.ERR_ILLEGAL_ARG);
1808: }
1809:
1810: isActive();
1811: Object relObj = getRelation(theRelId);
1812:
1813: RoleResult result = null;
1814:
1815: if (relObj instanceof RelationSupport) {
1816: try {
1817: result = ((RelationSupport) relObj).setRolesFriend(
1818: theRoleList, true, this );
1819: } catch (RelationTypeNotFoundException e) {
1820: throw new RuntimeException(e.getMessage());
1821: }
1822:
1823: } else {
1824: Object[] params = new Object[] { theRoleList };
1825: String[] sig = new String[] { "javax.management.relation.RoleList" };
1826:
1827: try {
1828: result = (RoleResult) (mbeanServer.invoke(
1829: ((ObjectName) relObj), "setRoles", params, sig));
1830: } catch (MBeanException me) {
1831: throw new RuntimeException(me.getTargetException()
1832: .getMessage());
1833: } catch (Exception e) {
1834: throw new RuntimeException(e.getMessage());
1835: }
1836: }
1837:
1838: return result;
1839: }
1840:
1841: /**
1842: * Handles update of the Relation Service role map for the update of given
1843: * role in given relation. It is called in relation MBean setRole() (for
1844: * given role) and setRoles() (for each role) methods (implementation
1845: * provided in RelationSupport class).
1846: * <P>It is also called in Relation Service setRole() (for given role) and
1847: * setRoles() (for each role) methods.
1848: * <P>To allow the Relation Service to maintain the consistency (in case of
1849: * MBean unregistration) and to be able to perform queries, this method
1850: * must be called when a role is updated.
1851: *
1852: * @param theRelId - relation identifier of the updated relation
1853: *
1854: * @param theNewRole - new role (name and new value)
1855: *
1856: * @param theOldRoleValue - old role value (ArrayList of ObjectName objects)
1857: *
1858: * @exception java.lang.IllegalArgumentException - if null parameter
1859: *
1860: * @exception RelationServiceNotRegisteredException - if the Relation
1861: * Service is not registered in the MBean Server
1862: *
1863: * @exception RelationNotFoundException - if no relation for given id.
1864: */
1865: public void updateRoleMap(String theRelId, Role theNewRole,
1866: List theOldRoleValue) throws IllegalArgumentException,
1867: RelationServiceNotRegisteredException,
1868: RelationNotFoundException {
1869: if (theRelId == null || theNewRole == null
1870: || theOldRoleValue == null) {
1871: throw new IllegalArgumentException(
1872: RelationErrs.ERR_ILLEGAL_ARG);
1873: }
1874:
1875: // Can throw RelationServiceNotRegisteredException
1876: isActive();
1877:
1878: // Verifies the relation has been added in the Relation Service
1879: // Can throw a RelationNotFoundException
1880: Object result = getRelation(theRelId);
1881:
1882: String roleName = theNewRole.getRoleName();
1883: ArrayList newRoleValue = (ArrayList) (theNewRole.getRoleValue());
1884: // Note: no need to test if theOldRoleValue not null before cloning,
1885: // tested above.
1886: ArrayList oldRoleValue = (ArrayList) (((ArrayList) theOldRoleValue)
1887: .clone());
1888:
1889: // List of ObjectNames of new referenced MBeans
1890: ArrayList newRefList = new ArrayList();
1891:
1892: for (Iterator newRoleIter = newRoleValue.iterator(); newRoleIter
1893: .hasNext();) {
1894: ObjectName currObjName = (ObjectName) (newRoleIter.next());
1895:
1896: // Checks if this ObjectName was already present in old value
1897: // Note: use copy (oldRoleValue) instead of original
1898: // theOldRoleValue to speed up, as oldRoleValue is decreased
1899: // by removing unchanged references :)
1900: int currObjNamePos = oldRoleValue.indexOf(currObjName);
1901:
1902: if (currObjNamePos == -1) {
1903: // New reference to an ObjectName
1904:
1905: // Stores this reference into map
1906: // Returns true if new reference, false if MBean already
1907: // referenced
1908: boolean isNewFlg = addNewMBeanReference(currObjName,
1909: theRelId, roleName);
1910:
1911: if (isNewFlg) {
1912: // Adds it into list of new reference
1913: newRefList.add(currObjName);
1914: }
1915: } else {
1916: // MBean was already referenced in old value
1917:
1918: // Removes it from old value (local list) to ignore it when
1919: // looking for remove MBean references
1920: oldRoleValue.remove(currObjNamePos);
1921: }
1922: }
1923:
1924: // List of ObjectNames of MBeans no longer referenced
1925: ArrayList obsRefList = new ArrayList();
1926:
1927: // Each ObjectName remaining in oldRoleValue is an ObjectName no longer
1928: // referenced in new value
1929: for (Iterator oldRoleIter = oldRoleValue.iterator(); oldRoleIter
1930: .hasNext();) {
1931: ObjectName currObjName = (ObjectName) (oldRoleIter.next());
1932: // Removes MBean reference from map
1933: // Returns true if the MBean is no longer referenced in any
1934: // relation
1935: boolean noLongerRefFlg = removeMBeanReference(currObjName,
1936: theRelId, roleName, false);
1937:
1938: if (noLongerRefFlg) {
1939: // Adds it into list of references to be removed
1940: obsRefList.add(currObjName);
1941: }
1942: }
1943:
1944: // To avoid having one listener per ObjectName of referenced MBean,
1945: // and to increase performances, there is only one listener recording
1946: // all ObjectNames of interest
1947: updateUnregistrationListener(newRefList, obsRefList);
1948: }
1949:
1950: /**
1951: * Method inherited from the NotificationListener Interface
1952: */
1953: public void handleNotification(Notification theNtf,
1954: Object theHandback) {
1955: if (theNtf == null) {
1956: throw new IllegalArgumentException(
1957: RelationErrs.ERR_ILLEGAL_ARG);
1958: }
1959:
1960: if (theNtf instanceof MBeanServerNotification) {
1961: String ntfType = theNtf.getType();
1962:
1963: if (ntfType
1964: .equals(MBeanServerNotification.UNREGISTRATION_NOTIFICATION)) {
1965: ObjectName mbeanName = ((MBeanServerNotification) theNtf)
1966: .getMBeanName();
1967:
1968: if (refMBeansTable.containsKey(mbeanName)) {
1969: //This list will be used when purge flag is false and sooner or later, the user calls purge relations.
1970: //check and add into the NotificationList
1971: boolean isPresent = false;
1972: for (int i = 0; i < notifList.size(); i++) {
1973: if (mbeanName
1974: .equals(((MBeanServerNotification) (notifList
1975: .get(i))).getMBeanName())) {
1976: isPresent = true;
1977: break;
1978: }
1979: }
1980: if (!isPresent)
1981: notifList.add(theNtf);
1982: }
1983: if (purgeFlag) {
1984: try {
1985: purgeRelations();
1986: } catch (Exception e) {
1987: throw new RuntimeException(e.getMessage());
1988: }
1989:
1990: String relId = (String) (relationObjNamesTable
1991: .get(mbeanName));
1992:
1993: if (relId != null) {
1994: try {
1995: removeRelation(relId);
1996: } catch (Exception e) {
1997: throw new RuntimeException(e.getMessage());
1998: }
1999: }
2000: }
2001: }
2002: }
2003: }
2004:
2005: /**
2006: * Returns a NotificationInfo object containing the name of the Java class
2007: * of the notification and the notification types sent.
2008: */
2009: public MBeanNotificationInfo[] getNotificationInfo() {
2010: MBeanNotificationInfo[] notifInfo = new MBeanNotificationInfo[1];
2011:
2012: String[] notifTypes = new String[] {
2013: RelationNotification.RELATION_BASIC_CREATION,
2014: RelationNotification.RELATION_MBEAN_CREATION,
2015: RelationNotification.RELATION_BASIC_UPDATE,
2016: RelationNotification.RELATION_MBEAN_UPDATE,
2017: RelationNotification.RELATION_BASIC_REMOVAL,
2018: RelationNotification.RELATION_MBEAN_REMOVAL };
2019: ;
2020:
2021: notifInfo[0] = new MBeanNotificationInfo(notifTypes,
2022: "Relation Notification",
2023: "Relation Notifications sent during creation/deletion or updation");
2024:
2025: return notifInfo;
2026: }
2027:
2028: ////////////////////////////////////////////////////////////////////////////////
2029: /**
2030: *
2031: */
2032: private void validateAndAddRelationType(RelationType theRelTypeObj)
2033: throws IllegalArgumentException,
2034: InvalidRelationTypeException {
2035: if (theRelTypeObj == null) {
2036: throw new IllegalArgumentException(
2037: RelationErrs.ERR_ILLEGAL_ARG);
2038: }
2039:
2040: String relTypeName = theRelTypeObj.getRelationTypeName();
2041: try {
2042:
2043: RelationType relType = getRelationType(relTypeName);
2044: if (relType != null) {
2045: throw new InvalidRelationTypeException(
2046: "RelationType already exists");
2047: }
2048: } catch (RelationTypeNotFoundException exc) {
2049: }
2050: relationTypeObjTable
2051: .put(new String(relTypeName), theRelTypeObj);
2052: }
2053:
2054: /**
2055: *
2056: */
2057: RelationType getRelationType(String theRelTypeName)
2058: throws IllegalArgumentException,
2059: RelationTypeNotFoundException {
2060: if (theRelTypeName == null) {
2061: throw new IllegalArgumentException(
2062: RelationErrs.ERR_ILLEGAL_ARG);
2063: }
2064:
2065: RelationType relType = null;
2066: relType = (RelationType) (relationTypeObjTable
2067: .get(theRelTypeName));
2068:
2069: if (relType == null) {
2070: throw new RelationTypeNotFoundException("No such relation "
2071: + theRelTypeName);
2072: }
2073:
2074: return relType;
2075: }
2076:
2077: /**
2078: *
2079: */
2080: Object getRelation(String theRelId)
2081: throws IllegalArgumentException, RelationNotFoundException {
2082: if (theRelId == null) {
2083: throw new IllegalArgumentException(
2084: RelationErrs.ERR_ILLEGAL_ARG);
2085: }
2086:
2087: Object rel = null;
2088: rel = relationsTable.get(theRelId);
2089:
2090: if (rel == null) {
2091: throw new RelationNotFoundException("No such Relation"
2092: + theRelId);
2093: }
2094:
2095: return rel;
2096: }
2097:
2098: /**
2099: *
2100: */
2101: private boolean addNewMBeanReference(ObjectName theObjName,
2102: String theRelId, String theRoleName)
2103: throws IllegalArgumentException {
2104: if (theObjName == null || theRelId == null
2105: || theRoleName == null) {
2106: throw new IllegalArgumentException(
2107: RelationErrs.ERR_ILLEGAL_ARG);
2108: }
2109:
2110: boolean isNewFlg = false;
2111:
2112: synchronized (refMBeansTable) {
2113: HashMap mbeanRefMap = (HashMap) (refMBeansTable
2114: .get(theObjName));
2115:
2116: if (mbeanRefMap == null) {
2117: isNewFlg = true;
2118:
2119: ArrayList roleNames = new ArrayList();
2120: roleNames.add(theRoleName);
2121:
2122: mbeanRefMap = new HashMap();
2123: mbeanRefMap.put(new String(theRelId), roleNames);
2124:
2125: refMBeansTable.put(theObjName, mbeanRefMap);
2126: } else {
2127: ArrayList roleNames = (ArrayList) (mbeanRefMap
2128: .get(theRelId));
2129:
2130: if (roleNames == null) {
2131: roleNames = new ArrayList();
2132: roleNames.add(theRoleName);
2133:
2134: mbeanRefMap.put(new String(theRelId), roleNames);
2135: } else {
2136: roleNames.add(theRoleName);
2137: }
2138: }
2139: }
2140:
2141: return isNewFlg;
2142: }
2143:
2144: private boolean removeMBeanReference(ObjectName theObjName,
2145: String theRelId, String theRoleName, boolean theAllRolesFlg)
2146: throws IllegalArgumentException {
2147: if (theObjName == null || theRelId == null
2148: || theRoleName == null) {
2149: throw new IllegalArgumentException(
2150: RelationErrs.ERR_ILLEGAL_ARG);
2151: }
2152:
2153: boolean noLongerRefFlg = false;
2154:
2155: synchronized (refMBeansTable) {
2156: HashMap mbeanRefMap = (HashMap) (refMBeansTable
2157: .get(theObjName));
2158:
2159: if (mbeanRefMap == null) {
2160: return true;
2161: }
2162:
2163: ArrayList roleNames = new ArrayList();
2164: if (!theAllRolesFlg) {
2165: roleNames = (ArrayList) (mbeanRefMap.get(theRelId));
2166:
2167: int obsRefIdx = roleNames.indexOf(theRoleName);
2168: if (obsRefIdx != -1) {
2169: roleNames.remove(obsRefIdx);
2170: }
2171: }
2172:
2173: if (roleNames.isEmpty() || theAllRolesFlg) {
2174: mbeanRefMap.remove(theRelId);
2175: }
2176:
2177: if (mbeanRefMap.isEmpty()) {
2178: refMBeansTable.remove(theObjName);
2179: noLongerRefFlg = true;
2180: }
2181: }
2182:
2183: return noLongerRefFlg;
2184: }
2185:
2186: private void updateUnregistrationListener(List theNewRefList,
2187: List theObsRefList)
2188: throws RelationServiceNotRegisteredException {
2189: if (theNewRefList != null && theObsRefList != null) {
2190: if (theNewRefList.isEmpty() && theObsRefList.isEmpty()) {
2191: return;
2192: }
2193: }
2194:
2195: isActive();
2196:
2197: if (theNewRefList != null || theObsRefList != null) {
2198: boolean newListenerFlg = false;
2199:
2200: if (notifFilter == null) {
2201: notifFilter = new MBeanServerNotificationFilter();
2202: newListenerFlg = true;
2203: }
2204:
2205: synchronized (notifFilter) {
2206: if (theNewRefList != null) {
2207: for (Iterator newRefIter = theNewRefList.iterator(); newRefIter
2208: .hasNext();) {
2209: ObjectName newObjName = (ObjectName) (newRefIter
2210: .next());
2211: notifFilter.enableObjectName(newObjName);
2212: }
2213: }
2214:
2215: if (theObsRefList != null) {
2216: for (Iterator obsRefIter = theObsRefList.iterator(); obsRefIter
2217: .hasNext();) {
2218: ObjectName obsObjName = (ObjectName) (obsRefIter
2219: .next());
2220: notifFilter.disableObjectName(obsObjName);
2221: }
2222: }
2223:
2224: if (newListenerFlg) {
2225: try {
2226: mbeanServer
2227: .addNotificationListener(
2228: new ObjectName(
2229: "JMImplementation:type=MBeanServerDelegate"),
2230: this , notifFilter, null);
2231: } catch (InstanceNotFoundException exc) {
2232: throw new RelationServiceNotRegisteredException(
2233: exc.getMessage());
2234: } catch (MalformedObjectNameException ee) {
2235: }
2236: }
2237: }
2238: }
2239: }
2240:
2241: private void validateAndAddRelation(boolean theRelBaseFlg,
2242: RelationSupport theRelObj, ObjectName theRelObjName,
2243: String theRelId, String theRelTypeName, RoleList theRoleList)
2244: throws IllegalArgumentException,
2245: RelationServiceNotRegisteredException,
2246: RoleNotFoundException, InvalidRelationIdException,
2247: RelationTypeNotFoundException, InvalidRoleValueException {
2248: if (theRelId == null
2249: || theRelTypeName == null
2250: || (theRelBaseFlg && (theRelObj == null || theRelObjName != null))
2251: || (!theRelBaseFlg && (theRelObjName == null || theRelObj != null))) {
2252: throw new IllegalArgumentException(
2253: RelationErrs.ERR_ILLEGAL_ARG);
2254: }
2255:
2256: isActive();
2257:
2258: try {
2259: Object rel = getRelation(theRelId);
2260:
2261: if (rel != null) {
2262: throw new InvalidRelationIdException("Relation exists ");
2263: }
2264: } catch (RelationNotFoundException exc) {
2265: }
2266:
2267: RelationType relType = getRelationType(theRelTypeName);
2268:
2269: ArrayList roleInfoList = (ArrayList) (((ArrayList) (relType
2270: .getRoleInfos())).clone());
2271:
2272: if (theRoleList == null) {
2273: throw new InvalidRoleValueException();
2274: }
2275:
2276: if (theRoleList != null) {
2277: for (Iterator roleIter = theRoleList.iterator(); roleIter
2278: .hasNext();) {
2279: Role currRole = (Role) (roleIter.next());
2280: String currRoleName = currRole.getRoleName();
2281: ArrayList currRoleValue = (ArrayList) (currRole
2282: .getRoleValue());
2283: RoleInfo roleInfo = null;
2284: try {
2285: roleInfo = relType.getRoleInfo(currRoleName);
2286: } catch (RoleInfoNotFoundException exc) {
2287: throw new RoleNotFoundException(exc.getMessage());
2288: }
2289:
2290: int problem = getRoleStatusInteger(currRoleName,
2291: currRoleValue, roleInfo, false, 2).intValue();
2292:
2293: if (problem != 0) {
2294: if (problem == RoleStatus.NO_ROLE_WITH_NAME
2295: || problem == RoleStatus.ROLE_NOT_READABLE
2296: || problem == RoleStatus.ROLE_NOT_WRITABLE)
2297: throw new RoleNotFoundException();
2298: else
2299: throw new InvalidRoleValueException();
2300: }
2301:
2302: int roleInfoIdx = roleInfoList.indexOf(roleInfo);
2303:
2304: roleInfoList.remove(roleInfoIdx);
2305: }
2306: }
2307:
2308: initialiseMissingRoles(theRelBaseFlg, theRelObj, theRelObjName,
2309: theRelId, theRelTypeName, roleInfoList);
2310:
2311: synchronized (relationsTable) {
2312: if (theRelBaseFlg) {
2313: relationsTable.put(new String(theRelId), theRelObj);
2314: } else {
2315: relationsTable.put(new String(theRelId), theRelObjName);
2316: }
2317: }
2318:
2319: synchronized (relationTypesTable) {
2320: relationTypesTable.put(new String(theRelId), new String(
2321: theRelTypeName));
2322: }
2323:
2324: synchronized (relTypeToIDTable) {
2325: ArrayList relIdList = (ArrayList) (relTypeToIDTable
2326: .get(theRelTypeName));
2327: boolean firstRelFlg = false;
2328: if (relIdList == null) {
2329: firstRelFlg = true;
2330: relIdList = new ArrayList();
2331: }
2332: relIdList.add(theRelId);
2333: if (firstRelFlg) {
2334: relTypeToIDTable.put(new String(theRelTypeName),
2335: relIdList);
2336: }
2337: }
2338:
2339: for (Iterator roleIter = theRoleList.iterator(); roleIter
2340: .hasNext();) {
2341: Role currRole = (Role) (roleIter.next());
2342: ArrayList dummyList = new ArrayList();
2343:
2344: try {
2345: updateRoleMap(theRelId, currRole, dummyList);
2346: } catch (RelationNotFoundException exc) {
2347: }
2348: }
2349:
2350: try {
2351: sendRelationCreationNotification(theRelId);
2352: } catch (RelationNotFoundException exc) {
2353: }
2354: }
2355:
2356: /**
2357: * This method checks the Role for conformance to the RoleInfo.
2358: */
2359: private Integer getRoleStatusInteger(String theRoleName,
2360: List theRoleValue, RoleInfo theRoleInfo, boolean writeFlg,
2361: int type) throws IllegalArgumentException {
2362: if (theRoleName == null || theRoleInfo == null) {
2363: throw new IllegalArgumentException(
2364: RelationErrs.ERR_ILLEGAL_ARG);
2365: }
2366:
2367: String roleInfoName = theRoleInfo.getName();
2368:
2369: if (!(theRoleName.equals(roleInfoName))) {
2370: return new Integer(RoleStatus.NO_ROLE_WITH_NAME);
2371: }
2372:
2373: if (type == 1) {
2374: if (!theRoleInfo.isReadable()) {
2375: return new Integer(RoleStatus.ROLE_NOT_READABLE);
2376: } else {
2377: return new Integer(0);
2378: }
2379: }
2380:
2381: if (writeFlg) {
2382: if (!theRoleInfo.isWritable()) {
2383: return new Integer(RoleStatus.ROLE_NOT_WRITABLE);
2384: }
2385: }
2386:
2387: int roleValueLength = theRoleValue.size();
2388:
2389: if (!theRoleInfo.checkMinDegree(roleValueLength)) {
2390: return new Integer(RoleStatus.LESS_THAN_MIN_ROLE_DEGREE);
2391: }
2392:
2393: if (!theRoleInfo.checkMaxDegree(roleValueLength)) {
2394: return new Integer(RoleStatus.MORE_THAN_MAX_ROLE_DEGREE);
2395: }
2396:
2397: String className = theRoleInfo.getRefMBeanClassName();
2398:
2399: for (Iterator iter = theRoleValue.iterator(); iter.hasNext();) {
2400: ObjectName objName = (ObjectName) (iter.next());
2401:
2402: if (objName == null) {
2403: return new Integer(RoleStatus.REF_MBEAN_NOT_REGISTERED);
2404: }
2405:
2406: if (!mbeanServer.isRegistered(objName)) {
2407: return new Integer(RoleStatus.REF_MBEAN_NOT_REGISTERED);
2408: }
2409:
2410: try {
2411: if (!mbeanServer.isInstanceOf(objName, className)) {
2412: return new Integer(
2413: RoleStatus.REF_MBEAN_OF_INCORRECT_CLASS);
2414: }
2415: } catch (InstanceNotFoundException exc) {
2416: return null;
2417: }
2418: }
2419:
2420: return new Integer(0);
2421: }
2422:
2423: private void initialiseMissingRoles(boolean theRelBaseFlg,
2424: RelationSupport theRelObj, ObjectName theRelObjName,
2425: String theRelId, String theRelTypeName, List theRoleInfoList)
2426: throws IllegalArgumentException,
2427: RelationServiceNotRegisteredException,
2428: InvalidRoleValueException {
2429: if ((theRelBaseFlg && (theRelObj == null || theRelObjName != null))
2430: || (!theRelBaseFlg && (theRelObjName == null || theRelObj != null))
2431: || theRelId == null
2432: || theRelTypeName == null
2433: || theRoleInfoList == null) {
2434: throw new IllegalArgumentException(
2435: RelationErrs.ERR_ILLEGAL_ARG);
2436: }
2437:
2438: isActive();
2439:
2440: for (Iterator roleInfoIter = theRoleInfoList.iterator(); roleInfoIter
2441: .hasNext();) {
2442:
2443: RoleInfo currRoleInfo = (RoleInfo) (roleInfoIter.next());
2444: String roleName = currRoleInfo.getName();
2445:
2446: ArrayList emptyValue = new ArrayList();
2447:
2448: Role role = new Role(roleName, emptyValue);
2449:
2450: if (theRelBaseFlg) {
2451: try {
2452: theRelObj.setRoleFriend(role, true, this );
2453:
2454: } catch (RoleNotFoundException e) {
2455: throw new RuntimeException(e.getMessage());
2456: } catch (RelationNotFoundException re) {
2457: throw new RuntimeException(re.getMessage());
2458: } catch (RelationTypeNotFoundException ex) {
2459: throw new RuntimeException(ex.getMessage());
2460: }
2461:
2462: } else {
2463:
2464: Object[] params = new Object[1];
2465: params[0] = role;
2466: String[] signature = new String[1];
2467: signature[0] = "javax.management.relation.Role";
2468:
2469: try {
2470: mbeanServer.invoke(theRelObjName, "setRole",
2471: params, signature);
2472:
2473: } catch (InstanceNotFoundException exc1) {
2474: throw new RuntimeException(exc1.getMessage());
2475: } catch (ReflectionException exc3) {
2476: throw new RuntimeException(exc3.getMessage());
2477: } catch (MBeanException exc2) {
2478: Exception wrappedExc = exc2.getTargetException();
2479: if (wrappedExc instanceof InvalidRoleValueException) {
2480: throw ((InvalidRoleValueException) wrappedExc);
2481: } else {
2482: throw new RuntimeException(wrappedExc
2483: .getMessage());
2484: }
2485: }
2486: }
2487: }
2488: }
2489:
2490: private void handleReferenceUnregistration(String theRelId,
2491: ObjectName theObjName, List theRoleNameList)
2492: throws IllegalArgumentException,
2493: RelationServiceNotRegisteredException,
2494: RelationNotFoundException, RoleNotFoundException {
2495:
2496: if (theRelId == null || theRoleNameList == null
2497: || theObjName == null) {
2498: throw new IllegalArgumentException(
2499: RelationErrs.ERR_ILLEGAL_ARG);
2500: }
2501:
2502: isActive();
2503:
2504: String currRelTypeName = getRelationTypeName(theRelId);
2505:
2506: Object relObj = getRelation(theRelId);
2507:
2508: boolean deleteRelFlg = false;
2509:
2510: for (Iterator roleNameIter = theRoleNameList.iterator(); roleNameIter
2511: .hasNext();) {
2512:
2513: if (deleteRelFlg) {
2514: break;
2515: }
2516:
2517: String currRoleName = (String) (roleNameIter.next());
2518: int currRoleRefNbr = (getRoleCardinality(theRelId,
2519: currRoleName)).intValue();
2520:
2521: int currRoleNewRefNbr = currRoleRefNbr - 1;
2522:
2523: RoleInfo currRoleInfo = null;
2524: try {
2525: currRoleInfo = getRoleInfo(currRelTypeName,
2526: currRoleName);
2527: } catch (RelationTypeNotFoundException ree) {
2528: throw new RuntimeException(ree.getMessage());
2529: } catch (RoleInfoNotFoundException re) {
2530: throw new RuntimeException(re.getMessage());
2531: }
2532:
2533: boolean chkMinFlg = currRoleInfo
2534: .checkMinDegree(currRoleNewRefNbr);
2535:
2536: if (!chkMinFlg) {
2537: deleteRelFlg = true;
2538: }
2539: }
2540:
2541: if (deleteRelFlg) {
2542: removeRelation(theRelId);
2543: } else {
2544:
2545: for (Iterator roleNameIter = theRoleNameList.iterator(); roleNameIter
2546: .hasNext();) {
2547:
2548: String currRoleName = (String) (roleNameIter.next());
2549:
2550: if (relObj instanceof RelationSupport) {
2551: try {
2552: ((RelationSupport) relObj)
2553: .handleMBeanUnregistrationFriend(
2554: theObjName, currRoleName, this );
2555: } catch (RelationTypeNotFoundException exc3) {
2556: throw new RuntimeException(exc3.getMessage());
2557: } catch (InvalidRoleValueException exc4) {
2558: throw new RuntimeException(exc4.getMessage());
2559: }
2560:
2561: } else {
2562: // Relation MBean
2563: Object[] params = new Object[2];
2564: params[0] = theObjName;
2565: params[1] = currRoleName;
2566: String[] signature = new String[2];
2567: signature[0] = "javax.management.ObjectName";
2568: signature[1] = "java.lang.String";
2569: try {
2570: mbeanServer.invoke(((ObjectName) relObj),
2571: "handleMBeanUnregistration", params,
2572: signature);
2573: } catch (InstanceNotFoundException exc1) {
2574: throw new RuntimeException(exc1.getMessage());
2575: } catch (ReflectionException exc3) {
2576: throw new RuntimeException(exc3.getMessage());
2577: } catch (MBeanException exc2) {
2578: Exception wrappedExc = exc2
2579: .getTargetException();
2580: throw new RuntimeException(wrappedExc
2581: .getMessage());
2582: }
2583: }
2584: }
2585: }
2586:
2587: return;
2588: }
2589:
2590: private void checkRoleInfoConsistency(RoleInfo[] theRoleInfoArray)
2591: throws InvalidRelationTypeException {
2592: if (!(theRoleInfoArray.length > 0))
2593: throw new InvalidRelationTypeException(
2594: "No elements in the RoleInfo");
2595:
2596: if (!(this .validateRoleInfoArray(theRoleInfoArray)))
2597: throw new InvalidRelationTypeException("ERR_VALUE");
2598: }
2599:
2600: private boolean validateRoleInfoArray(RoleInfo[] info) {
2601:
2602: if (info == null) {
2603: ERR_VALUE = "Cannot create RelationType for null RoleInfo";
2604: return false;
2605: }
2606: Hashtable temp = new Hashtable();
2607: for (int i = 0; i < info.length; i++) {
2608: if (info[i] == null) {
2609: ERR_VALUE = "Cannot create RelationType for null RoleInfo at"
2610: + i + " st Index";
2611: return false;
2612: } else {
2613: if (!(temp.containsKey(((RoleInfo) info[i]).getName()))) {
2614: temp.put(((RoleInfo) info[i]).getName(),
2615: new Object());
2616: } else {
2617: ERR_VALUE = "Cannot create RelationType duplicate RoleInfos";
2618: return false;
2619: }
2620: }
2621: }
2622: return true;
2623: }
2624:
2625: private boolean isRelationIdAlreadyExists(String relId) {
2626: Iterator e = relationsTable.keySet().iterator();
2627: boolean isPresent = false;
2628: while (e.hasNext()) {
2629: if (relId.equals((String) (e.next()))) {
2630: isPresent = true;
2631: break;
2632: }
2633: }
2634: return isPresent;
2635: }
2636:
2637: private List getRoleValueFromRoleList(RoleList roleList,
2638: String roleName) {
2639:
2640: for (int i = 0; i < roleList.size(); i++) {
2641: Role temp = (Role) (roleList.get(i));
2642: if (temp.getRoleName().equals(roleName)) {
2643: return temp.getRoleValue();
2644: }
2645: }
2646: return null;
2647: }
2648: }
|