1. /*
  2. * @(#)RelationService.java 1.42 04/04/13
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.management.relation;
  8. import javax.management.Attribute;
  9. import javax.management.AttributeNotFoundException;
  10. import javax.management.NotificationListener;
  11. import javax.management.ObjectName;
  12. import javax.management.NotCompliantMBeanException;
  13. import javax.management.Notification;
  14. import javax.management.NotificationBroadcasterSupport;
  15. import javax.management.MBeanRegistration;
  16. import javax.management.MBeanServer;
  17. import javax.management.ListenerNotFoundException;
  18. import javax.management.InstanceNotFoundException;
  19. import javax.management.InvalidAttributeValueException;
  20. import javax.management.MBeanException;
  21. import javax.management.ReflectionException;
  22. import javax.management.MBeanServerNotification;
  23. import javax.management.MBeanNotificationInfo;
  24. import javax.management.MalformedObjectNameException;
  25. import com.sun.jmx.defaults.ServiceName;
  26. import com.sun.jmx.trace.Trace;
  27. import java.util.ArrayList;
  28. import java.util.HashMap;
  29. import java.util.Iterator;
  30. import java.util.Set;
  31. import java.util.List;
  32. import java.util.Map;
  33. import java.util.Date;
  34. /**
  35. * The Relation Service is in charge of creating and deleting relation types
  36. * and relations, of handling the consistency and of providing query
  37. * mechanisms.
  38. * <P>It implements the NotificationBroadcaster by extending
  39. * NotificationBroadcasterSupport to send notifications when a relation is
  40. * removed from it.
  41. * <P>It implements the NotificationListener interface to be able to receive
  42. * notifications concerning unregistration of MBeans referenced in relation
  43. * roles and of relation MBeans.
  44. * <P>It implements the MBeanRegistration interface to be able to retrieve
  45. * its ObjectName and MBean Server.
  46. *
  47. * @since 1.5
  48. */
  49. public class RelationService extends NotificationBroadcasterSupport
  50. implements RelationServiceMBean, MBeanRegistration, NotificationListener {
  51. //
  52. // Private members
  53. //
  54. // Map associating:
  55. // <relation id> -> <RelationSupport object/ObjectName>
  56. // depending if the relation has been created using createRelation()
  57. // method (so internally handled) or is an MBean added as a relation by the
  58. // user
  59. private HashMap myRelId2ObjMap = new HashMap();
  60. // Map associating:
  61. // <relation id> -> <relation type name>
  62. private HashMap myRelId2RelTypeMap = new HashMap();
  63. // Map associating:
  64. // <relation MBean Object Name> -> <relation id>
  65. private HashMap myRelMBeanObjName2RelIdMap = new HashMap();
  66. // Map associating:
  67. // <relation type name> -> <RelationType object>
  68. private HashMap myRelType2ObjMap = new HashMap();
  69. // Map associating:
  70. // <relation type name> -> ArrayList of <relation id>
  71. // to list all the relations of a given type
  72. private HashMap myRelType2RelIdsMap = new HashMap();
  73. // Map associating:
  74. // <ObjectName> -> HashMap
  75. // the value HashMap mapping:
  76. // <relation id> -> ArrayList of <role name>
  77. // to track where a given MBean is referenced.
  78. private HashMap myRefedMBeanObjName2RelIdsMap = new HashMap();
  79. // Flag to indicate if, when a notification is received for the
  80. // unregistration of an MBean referenced in a relation, if an immediate
  81. // "purge" of the relations (look for the relations no
  82. // longer valid) has to be performed , or if that will be performed only
  83. // when the purgeRelations method will be explicitly called.
  84. // true is immediate purge.
  85. private boolean myPurgeFlg = true;
  86. // Internal counter to provide sequence numbers for notifications sent by:
  87. // - the Relation Service
  88. // - a relation handled by the Relation Service
  89. private Long myNtfSeqNbrCounter = new Long(0);
  90. // ObjectName used to register the Relation Service in the MBean Server
  91. private ObjectName myObjName = null;
  92. // MBean Server where the Relation Service is registered
  93. private MBeanServer myMBeanServer = null;
  94. // Filter registered in the MBean Server with the Relation Service to be
  95. // informed of referenced MBean unregistrations
  96. private MBeanServerNotificationFilter myUnregNtfFilter = null;
  97. // List of unregistration notifications received (storage used if purge
  98. // of relations when unregistering a referenced MBean is not immediate but
  99. // on user request)
  100. private ArrayList myUnregNtfList = new ArrayList();
  101. //
  102. // Constructor
  103. //
  104. /**
  105. * Constructor.
  106. *
  107. * @param theImmediatePurgeFlg flag to indicate when a notification is
  108. * received for the unregistration of an MBean referenced in a relation, if
  109. * an immediate "purge" of the relations (look for the relations no
  110. * longer valid) has to be performed , or if that will be performed only
  111. * when the purgeRelations method will be explicitly called.
  112. * <P>true is immediate purge.
  113. */
  114. public RelationService(boolean theImmediatePurgeFlg) {
  115. if (isTraceOn())
  116. trace("Constructor: entering", null);
  117. setPurgeFlag(theImmediatePurgeFlg);
  118. if (isTraceOn())
  119. trace("Constructor: exiting", null);
  120. return;
  121. }
  122. /**
  123. * Checks if the Relation Service is active.
  124. * Current condition is that the Relation Service must be registered in the
  125. * MBean Server
  126. *
  127. * @exception RelationServiceNotRegisteredException if it is not
  128. * registered
  129. */
  130. public void isActive()
  131. throws RelationServiceNotRegisteredException {
  132. if (myMBeanServer == null) {
  133. // MBean Server not set by preRegister(): relation service not
  134. // registered
  135. // Revisit [cebro] Localize message
  136. String excMsg =
  137. "Relation Service not registered in the MBean Server.";
  138. throw new RelationServiceNotRegisteredException(excMsg);
  139. }
  140. return;
  141. }
  142. //
  143. // MBeanRegistration interface
  144. //
  145. // Pre-registration: retrieves its ObjectName and MBean Server
  146. //
  147. // No exception thrown.
  148. public ObjectName preRegister(MBeanServer server,
  149. ObjectName name)
  150. throws Exception {
  151. myMBeanServer = server;
  152. myObjName = name;
  153. return name;
  154. }
  155. // Post-registration: does nothing
  156. public void postRegister(Boolean registrationDone) {
  157. return;
  158. }
  159. // Pre-unregistration: does nothing
  160. public void preDeregister()
  161. throws Exception {
  162. return;
  163. }
  164. // Post-unregistration: does nothing
  165. public void postDeregister() {
  166. return;
  167. }
  168. //
  169. // Accessors
  170. //
  171. /**
  172. * Returns the flag to indicate if when a notification is received for the
  173. * unregistration of an MBean referenced in a relation, if an immediate
  174. * "purge" of the relations (look for the relations no longer valid)
  175. * has to be performed , or if that will be performed only when the
  176. * purgeRelations method will be explicitly called.
  177. * <P>true is immediate purge.
  178. *
  179. * @return true if purges are automatic.
  180. *
  181. * @see #setPurgeFlag
  182. */
  183. public boolean getPurgeFlag() {
  184. return myPurgeFlg;
  185. }
  186. /**
  187. * Sets the flag to indicate if when a notification is received for the
  188. * unregistration of an MBean referenced in a relation, if an immediate
  189. * "purge" of the relations (look for the relations no longer valid)
  190. * has to be performed , or if that will be performed only when the
  191. * purgeRelations method will be explicitly called.
  192. * <P>true is immediate purge.
  193. *
  194. * @param thePurgeFlg flag
  195. *
  196. * @see #getPurgeFlag
  197. */
  198. public void setPurgeFlag(boolean thePurgeFlg) {
  199. myPurgeFlg = thePurgeFlg;
  200. return;
  201. }
  202. // Returns internal counter to be used for Sequence Numbers of
  203. // notifications to be raised by:
  204. // - a relation handled by this Relation Service (when updated)
  205. // - the Relation Service
  206. private Long getNotificationSequenceNumber() {
  207. Long result = null;
  208. synchronized(myNtfSeqNbrCounter) {
  209. result = new Long(myNtfSeqNbrCounter.longValue() + 1);
  210. myNtfSeqNbrCounter = new Long(result.longValue());
  211. }
  212. return result;
  213. }
  214. //
  215. // Relation type handling
  216. //
  217. /**
  218. * Creates a relation type (a RelationTypeSupport object) with given
  219. * role infos (provided by the RoleInfo objects), and adds it in the
  220. * Relation Service.
  221. *
  222. * @param theRelTypeName name of the relation type
  223. * @param theRoleInfoArray array of role infos
  224. *
  225. * @exception IllegalArgumentException if null parameter
  226. * @exception InvalidRelationTypeException If:
  227. * <P>- there is already a relation type with that name
  228. * <P>- the same name has been used for two different role infos
  229. * <P>- no role info provided
  230. * <P>- one null role info provided
  231. */
  232. public void createRelationType(String theRelTypeName,
  233. RoleInfo[] theRoleInfoArray)
  234. throws IllegalArgumentException,
  235. InvalidRelationTypeException {
  236. if (theRelTypeName == null || theRoleInfoArray == null) {
  237. // Revisit [cebro] Localize message
  238. String excMsg = "Invalid parameter.";
  239. throw new IllegalArgumentException(excMsg);
  240. }
  241. if (isTraceOn())
  242. trace("createRelationType: entering", theRelTypeName);
  243. // Can throw an InvalidRelationTypeException
  244. RelationType relType =
  245. new RelationTypeSupport(theRelTypeName, theRoleInfoArray);
  246. addRelationTypeInt(relType);
  247. if (isTraceOn())
  248. trace("createRelationType: exiting", null);
  249. return;
  250. }
  251. /**
  252. * Adds given object as a relation type. The object is expected to
  253. * implement the RelationType interface.
  254. *
  255. * @param theRelTypeObj relation type object (implementing the
  256. * RelationType interface)
  257. *
  258. * @exception IllegalArgumentException if null parameter
  259. * @exception InvalidRelationTypeException if:
  260. * <P>- the same name has been used for two different roles
  261. * <P>- no role info provided
  262. * <P>- one null role info provided
  263. * <P>- there is already a relation type with that name
  264. */
  265. public void addRelationType(RelationType theRelTypeObj)
  266. throws IllegalArgumentException,
  267. InvalidRelationTypeException {
  268. if (theRelTypeObj == null) {
  269. // Revisit [cebro] Localize message
  270. String excMsg = "Invalid parameter.";
  271. throw new IllegalArgumentException(excMsg);
  272. }
  273. if (isTraceOn())
  274. trace("addRelationType: entering", null);
  275. // Checks the role infos
  276. List roleInfoList = theRelTypeObj.getRoleInfos();
  277. if (roleInfoList == null) {
  278. // Revisit [cebro] Localize message
  279. String excMsg = "No role info provided.";
  280. throw new InvalidRelationTypeException(excMsg);
  281. }
  282. RoleInfo[] roleInfoArray = new RoleInfo[roleInfoList.size()];
  283. int i = 0;
  284. for (Iterator roleInfoIter = roleInfoList.iterator();
  285. roleInfoIter.hasNext();) {
  286. RoleInfo currRoleInfo = (RoleInfo)(roleInfoIter.next());
  287. roleInfoArray[i] = currRoleInfo;
  288. i++;
  289. }
  290. // Can throw InvalidRelationTypeException
  291. RelationTypeSupport.checkRoleInfos(roleInfoArray);
  292. addRelationTypeInt(theRelTypeObj);
  293. if (isTraceOn())
  294. trace("addRelationType: exiting", null);
  295. return;
  296. }
  297. /**
  298. * Retrieves names of all known relation types.
  299. *
  300. * @return ArrayList of relation type names (Strings)
  301. */
  302. public List getAllRelationTypeNames() {
  303. ArrayList result = null;
  304. synchronized(myRelType2ObjMap) {
  305. result = new ArrayList(myRelType2ObjMap.keySet());
  306. }
  307. return result;
  308. }
  309. /**
  310. * Retrieves list of role infos (RoleInfo objects) of a given relation
  311. * type.
  312. *
  313. * @param theRelTypeName name of relation type
  314. *
  315. * @return ArrayList of RoleInfo.
  316. *
  317. * @exception IllegalArgumentException if null parameter
  318. * @exception RelationTypeNotFoundException if there is no relation type
  319. * with that name.
  320. */
  321. public List getRoleInfos(String theRelTypeName)
  322. throws IllegalArgumentException,
  323. RelationTypeNotFoundException {
  324. if (theRelTypeName == null) {
  325. // Revisit [cebro[ Localize message
  326. String excMsg = "Invalid parameter.";
  327. throw new IllegalArgumentException(excMsg);
  328. }
  329. if (isTraceOn())
  330. trace("getRoleInfos: entering", theRelTypeName);
  331. // Can throw a RelationTypeNotFoundException
  332. RelationType relType = getRelationType(theRelTypeName);
  333. if (isTraceOn())
  334. trace("getRoleInfos: exiting", null);
  335. return relType.getRoleInfos();
  336. }
  337. /**
  338. * Retrieves role info for given role name of a given relation type.
  339. *
  340. * @param theRelTypeName name of relation type
  341. * @param theRoleInfoName name of role
  342. *
  343. * @return RoleInfo object.
  344. *
  345. * @exception IllegalArgumentException if null parameter
  346. * @exception RelationTypeNotFoundException if the relation type is not
  347. * known in the Relation Service
  348. * @exception RoleInfoNotFoundException if the role is not part of the
  349. * relation type.
  350. */
  351. public RoleInfo getRoleInfo(String theRelTypeName,
  352. String theRoleInfoName)
  353. throws IllegalArgumentException,
  354. RelationTypeNotFoundException,
  355. RoleInfoNotFoundException {
  356. if (theRelTypeName == null || theRoleInfoName == null) {
  357. // Revisit [cebro[ Localize message
  358. String excMsg = "Invalid parameter.";
  359. throw new IllegalArgumentException(excMsg);
  360. }
  361. if (isTraceOn()) {
  362. String str = "theRelTypeName " + theRelTypeName
  363. + ", theRoleInfoName " + theRoleInfoName;
  364. trace("getRoleInfo: entering", str);
  365. }
  366. // Can throw a RelationTypeNotFoundException
  367. RelationType relType = getRelationType(theRelTypeName);
  368. // Can throw a RoleInfoNotFoundException
  369. RoleInfo roleInfo = relType.getRoleInfo(theRoleInfoName);
  370. if (isTraceOn())
  371. trace("getRoleInfo: exiting", null);
  372. return roleInfo;
  373. }
  374. /**
  375. * Removes given relation type from Relation Service.
  376. * <P>The relation objects of that type will be removed from the
  377. * Relation Service.
  378. *
  379. * @param theRelTypeName name of the relation type to be removed
  380. *
  381. * @exception RelationServiceNotRegisteredException if the Relation
  382. * Service is not registered in the MBean Server
  383. * @exception IllegalArgumentException if null parameter
  384. * @exception RelationTypeNotFoundException If there is no relation type
  385. * with that name
  386. */
  387. public void removeRelationType(String theRelTypeName)
  388. throws RelationServiceNotRegisteredException,
  389. IllegalArgumentException,
  390. RelationTypeNotFoundException {
  391. // Can throw RelationServiceNotRegisteredException
  392. isActive();
  393. if (theRelTypeName == null) {
  394. // Revisit [cebro[ Localize message
  395. String excMsg = "Invalid parameter.";
  396. throw new IllegalArgumentException(excMsg);
  397. }
  398. if (isTraceOn())
  399. trace("removeRelationType: entering", theRelTypeName);
  400. // Checks if the relation type to be removed exists
  401. // Can throw a RelationTypeNotFoundException
  402. RelationType relType = getRelationType(theRelTypeName);
  403. // Retrieves the relation ids for relations of that type
  404. ArrayList relIdList = null;
  405. synchronized(myRelType2RelIdsMap) {
  406. // Note: take a copy of the list as it is a part of a map that
  407. // will be updated by removeRelation() below.
  408. ArrayList relIdList1 = (ArrayList)
  409. (myRelType2RelIdsMap.get(theRelTypeName));
  410. if (relIdList1 != null) {
  411. relIdList = (ArrayList)(relIdList1.clone());
  412. }
  413. }
  414. // Removes the relation type from all maps
  415. synchronized(myRelType2ObjMap) {
  416. myRelType2ObjMap.remove(theRelTypeName);
  417. }
  418. synchronized(myRelType2RelIdsMap) {
  419. myRelType2RelIdsMap.remove(theRelTypeName);
  420. }
  421. // Removes all relations of that type
  422. if (relIdList != null) {
  423. for (Iterator relIdIter = relIdList.iterator();
  424. relIdIter.hasNext();) {
  425. String currRelId = (String)(relIdIter.next());
  426. // Note: will remove it from myRelId2RelTypeMap :)
  427. //
  428. // Can throw RelationServiceNotRegisteredException (detected
  429. // above)
  430. // Shall not throw a RelationNotFoundException
  431. try {
  432. removeRelation(currRelId);
  433. } catch (RelationNotFoundException exc1) {
  434. throw new RuntimeException(exc1.getMessage());
  435. }
  436. }
  437. }
  438. if (isTraceOn())
  439. trace("removeRelationType: exiting", null);
  440. return;
  441. }
  442. //
  443. // Relation handling
  444. //
  445. /**
  446. * Creates a simple relation (represented by a RelationSupport object) of
  447. * given relation type, and adds it in the Relation Service.
  448. * <P>Roles are initialized according to the role list provided in
  449. * parameter. The ones not initialized in this way are set to an empty
  450. * ArrayList of ObjectNames.
  451. * <P>A RelationNotification, with type RELATION_BASIC_CREATION, is sent.
  452. *
  453. * @param theRelId relation identifier, to identify uniquely the relation
  454. * inside the Relation Service
  455. * @param theRelTypeName name of the relation type (has to be created
  456. * in the Relation Service)
  457. * @param theRoleList role list to initialize roles of the relation (can
  458. * be null).
  459. *
  460. * @exception RelationServiceNotRegisteredException if the Relation
  461. * Service is not registered in the MBean Server
  462. * @exception IllegalArgumentException if null parameter, except the role
  463. * list which can be null if no role initialization
  464. * @exception RoleNotFoundException if a value is provided for a role
  465. * that does not exist in the relation type
  466. * @exception InvalidRelationIdException if relation id already used
  467. * @exception RelationTypeNotFoundException if relation type not known in
  468. * Relation Service
  469. * @exception InvalidRoleValueException if:
  470. * <P>- the same role name is used for two different roles
  471. * <P>- the number of referenced MBeans in given value is less than
  472. * expected minimum degree
  473. * <P>- the number of referenced MBeans in provided value exceeds expected
  474. * maximum degree
  475. * <P>- one referenced MBean in the value is not an Object of the MBean
  476. * class expected for that role
  477. * <P>- an MBean provided for that role does not exist
  478. */
  479. public void createRelation(String theRelId,
  480. String theRelTypeName,
  481. RoleList theRoleList)
  482. throws RelationServiceNotRegisteredException,
  483. IllegalArgumentException,
  484. RoleNotFoundException,
  485. InvalidRelationIdException,
  486. RelationTypeNotFoundException,
  487. InvalidRoleValueException {
  488. // Can throw RelationServiceNotRegisteredException
  489. isActive();
  490. if (theRelId == null ||
  491. theRelTypeName == null) {
  492. // Revisit [cebro[ Localize message
  493. String excMsg = "Invalid parameter.";
  494. throw new IllegalArgumentException(excMsg);
  495. }
  496. if (isTraceOn()) {
  497. StringBuffer strB =
  498. new StringBuffer("theRelId " + theRelId
  499. + ", theRelTypeName " + theRelTypeName);
  500. if (theRoleList != null) {
  501. strB.append(", theRoleList " + theRoleList.toString());
  502. }
  503. trace("createRelation: entering", strB.toString());
  504. }
  505. // Creates RelationSupport object
  506. // Can throw InvalidRoleValueException
  507. RelationSupport relObj = new RelationSupport(theRelId,
  508. myObjName,
  509. theRelTypeName,
  510. theRoleList);
  511. // Adds relation object as a relation into the Relation Service
  512. // Can throw RoleNotFoundException, InvalidRelationId,
  513. // RelationTypeNotFoundException, InvalidRoleValueException
  514. //
  515. // Cannot throw MBeanException
  516. addRelationInt(true,
  517. relObj,
  518. null,
  519. theRelId,
  520. theRelTypeName,
  521. theRoleList);
  522. if (isTraceOn())
  523. trace("createRelation: exiting", null);
  524. return;
  525. }
  526. /**
  527. * Adds an MBean created by the user (and registered by him in the MBean
  528. * Server) as a relation in the Relation Service.
  529. * <P>To be added as a relation, the MBean must conform to the
  530. * following:
  531. * <P>- implement the Relation interface
  532. * <P>- have for RelationService ObjectName the ObjectName of current
  533. * Relation Service
  534. * <P>- have a relation id unique and unused in current Relation Service
  535. * <P>- have for relation type a relation type created in the Relation
  536. * Service
  537. * <P>- have roles conforming to the role info provided in the relation
  538. * type.
  539. *
  540. * @param theRelObjectName ObjectName of the relation MBean to be added.
  541. *
  542. * @exception IllegalArgumentException if null parameter
  543. * @exception RelationServiceNotRegisteredException if the Relation
  544. * Service is not registered in the MBean Server
  545. * @exception NoSuchMethodException If the MBean does not implement the
  546. * Relation interface
  547. * @exception InvalidRelationIdException if:
  548. * <P>- no relation identifier in MBean
  549. * <P>- the relation identifier is already used in the Relation Service
  550. * @exception InstanceNotFoundException if the MBean for given ObjectName
  551. * has not been registered
  552. * @exception InvalidRelationServiceException if:
  553. * <P>- no Relation Service name in MBean
  554. * <P>- the Relation Service name in the MBean is not the one of the
  555. * current Relation Service
  556. * @exception RelationTypeNotFoundException if:
  557. * <P>- no relation type name in MBean
  558. * <P>- the relation type name in MBean does not correspond to a relation
  559. * type created in the Relation Service
  560. * @exception InvalidRoleValueException if:
  561. * <P>- the number of referenced MBeans in a role is less than
  562. * expected minimum degree
  563. * <P>- the number of referenced MBeans in a role exceeds expected
  564. * maximum degree
  565. * <P>- one referenced MBean in the value is not an Object of the MBean
  566. * class expected for that role
  567. * <P>- an MBean provided for a role does not exist
  568. * @exception RoleNotFoundException if a value is provided for a role
  569. * that does not exist in the relation type
  570. */
  571. public void addRelation(ObjectName theRelObjectName)
  572. throws IllegalArgumentException,
  573. RelationServiceNotRegisteredException,
  574. NoSuchMethodException,
  575. InvalidRelationIdException,
  576. InstanceNotFoundException,
  577. InvalidRelationServiceException,
  578. RelationTypeNotFoundException,
  579. RoleNotFoundException,
  580. InvalidRoleValueException {
  581. if (theRelObjectName == null) {
  582. // Revisit [cebro[ Localize message
  583. String excMsg = "Invalid parameter.";
  584. throw new IllegalArgumentException(excMsg);
  585. }
  586. if (isTraceOn())
  587. trace("addRelation: entering", theRelObjectName.toString());
  588. // Can throw RelationServiceNotRegisteredException
  589. isActive();
  590. // Checks that the relation MBean implements the Relation interface.
  591. // It will also check that the provided ObjectName corresponds to a
  592. // registered MBean (else will throw an InstanceNotFoundException)
  593. if ((!(myMBeanServer.isInstanceOf(theRelObjectName, "javax.management.relation.Relation")))) {
  594. // Revisit [cebro] Localize message
  595. String excMsg = "This MBean does not implement the Relation interface.";
  596. throw new NoSuchMethodException(excMsg);
  597. }
  598. // Checks there is a relation id in the relation MBean (its uniqueness
  599. // is checked in addRelationInt())
  600. // Can throw InstanceNotFoundException (but detected above)
  601. // No MBeanException as no exception raised by this method, and no
  602. // ReflectionException
  603. String relId = null;
  604. try {
  605. relId = (String)(myMBeanServer.getAttribute(theRelObjectName,
  606. "RelationId"));
  607. } catch (MBeanException exc1) {
  608. throw new RuntimeException(
  609. (exc1.getTargetException()).getMessage());
  610. } catch (ReflectionException exc2) {
  611. throw new RuntimeException(exc2.getMessage());
  612. } catch (AttributeNotFoundException exc3) {
  613. throw new RuntimeException(exc3.getMessage());
  614. }
  615. if (relId == null) {
  616. // Revisit [cebro] Localize message
  617. String excMsg = "This MBean does not provide a relation id.";
  618. throw new InvalidRelationIdException(excMsg);
  619. }
  620. // Checks that the Relation Service where the relation MBean is
  621. // expected to be added is the current one
  622. // Can throw InstanceNotFoundException (but detected above)
  623. // No MBeanException as no exception raised by this method, no
  624. // ReflectionException
  625. ObjectName relServObjName = null;
  626. try {
  627. relServObjName = (ObjectName)
  628. (myMBeanServer.getAttribute(theRelObjectName,
  629. "RelationServiceName"));
  630. } catch (MBeanException exc1) {
  631. throw new RuntimeException(
  632. (exc1.getTargetException()).getMessage());
  633. } catch (ReflectionException exc2) {
  634. throw new RuntimeException(exc2.getMessage());
  635. } catch (AttributeNotFoundException exc3) {
  636. throw new RuntimeException(exc3.getMessage());
  637. }
  638. boolean badRelServFlg = false;
  639. if (relServObjName == null) {
  640. badRelServFlg = true;
  641. } else if (!(relServObjName.equals(myObjName))) {
  642. badRelServFlg = true;
  643. }
  644. if (badRelServFlg) {
  645. // Revisit [cebro] Localize message
  646. String excMsg = "The Relation Service referenced in the MBean is not the current one.";
  647. throw new InvalidRelationServiceException(excMsg);
  648. }
  649. // Checks that a relation type has been specified for the relation
  650. // Can throw InstanceNotFoundException (but detected above)
  651. // No MBeanException as no exception raised by this method, no
  652. // ReflectionException
  653. String relTypeName = null;
  654. try {
  655. relTypeName = (String)(myMBeanServer.getAttribute(theRelObjectName,
  656. "RelationTypeName"));
  657. } catch (MBeanException exc1) {
  658. throw new RuntimeException(
  659. (exc1.getTargetException()).getMessage());
  660. }catch (ReflectionException exc2) {
  661. throw new RuntimeException(exc2.getMessage());
  662. } catch (AttributeNotFoundException exc3) {
  663. throw new RuntimeException(exc3.getMessage());
  664. }
  665. if (relTypeName == null) {
  666. // Revisit [cebro] Localize message
  667. String excMsg = "No relation type provided.";
  668. throw new RelationTypeNotFoundException(excMsg);
  669. }
  670. // Retrieves all roles without considering read mode
  671. // Can throw InstanceNotFoundException (but detected above)
  672. // No MBeanException as no exception raised by this method, no
  673. // ReflectionException
  674. RoleList roleList = null;
  675. try {
  676. roleList = (RoleList)(myMBeanServer.invoke(theRelObjectName,
  677. "retrieveAllRoles",
  678. null,
  679. null));
  680. } catch (MBeanException exc1) {
  681. throw new RuntimeException(
  682. (exc1.getTargetException()).getMessage());
  683. } catch (ReflectionException exc2) {
  684. throw new RuntimeException(exc2.getMessage());
  685. }
  686. // Can throw RoleNotFoundException, InvalidRelationIdException,
  687. // RelationTypeNotFoundException, InvalidRoleValueException
  688. addRelationInt(false,
  689. null,
  690. theRelObjectName,
  691. relId,
  692. relTypeName,
  693. roleList);
  694. // Adds relation MBean ObjectName in map
  695. synchronized(myRelMBeanObjName2RelIdMap) {
  696. myRelMBeanObjName2RelIdMap.put(theRelObjectName, relId);
  697. }
  698. // Updates flag to specify that the relation is managed by the Relation
  699. // Service
  700. // This flag and setter are inherited from RelationSupport and not parts
  701. // of the Relation interface, so may be not supported.
  702. try {
  703. myMBeanServer.setAttribute(theRelObjectName,
  704. new Attribute(
  705. "RelationServiceManagementFlag",
  706. new Boolean(true)));
  707. } catch (Exception exc) {
  708. // OK : The flag is not supported.
  709. }
  710. // Updates listener information to received notification for
  711. // unregistration of this MBean
  712. ArrayList newRefList = new ArrayList();
  713. newRefList.add(theRelObjectName);
  714. updateUnregistrationListener(newRefList, null);
  715. if (isTraceOn())
  716. trace("addRelation: exiting", null);
  717. return;
  718. }
  719. /**
  720. * If the relation is represented by an MBean (created by the user and
  721. * added as a relation in the Relation Service), returns the ObjectName of
  722. * the MBean.
  723. *
  724. * @param theRelId relation id identifying the relation
  725. *
  726. * @return ObjectName of the corresponding relation MBean, or null if
  727. * the relation is not an MBean.
  728. *
  729. * @exception IllegalArgumentException if null parameter
  730. * @exception RelationNotFoundException there is no relation associated
  731. * to that id
  732. */
  733. public ObjectName isRelationMBean(String theRelId)
  734. throws IllegalArgumentException,
  735. RelationNotFoundException{
  736. if (theRelId == null) {
  737. // Revisit [cebro[ Localize message
  738. String excMsg = "Invalid parameter.";
  739. throw new IllegalArgumentException(excMsg);
  740. }
  741. if (isTraceOn())
  742. trace("isRelationMBean", theRelId);
  743. // Can throw RelationNotFoundException
  744. Object result = getRelation(theRelId);
  745. if (result instanceof ObjectName) {
  746. return ((ObjectName)result);
  747. } else {
  748. return null;
  749. }
  750. }
  751. /**
  752. * Returns the relation id associated to the given ObjectName if the
  753. * MBean has been added as a relation in the Relation Service.
  754. *
  755. * @param theObjName ObjectName of supposed relation
  756. *
  757. * @return relation id (String) or null (if the ObjectName is not a
  758. * relation handled by the Relation Service)
  759. *
  760. * @exception IllegalArgumentException if null parameter
  761. */
  762. public String isRelation(ObjectName theObjName)
  763. throws IllegalArgumentException {
  764. if (theObjName == null) {
  765. // Revisit [cebro[ Localize message
  766. String excMsg = "Invalid parameter.";
  767. throw new IllegalArgumentException(excMsg);
  768. }
  769. if (isTraceOn())
  770. trace("isRelation", theObjName.toString());
  771. String result = null;
  772. synchronized(myRelMBeanObjName2RelIdMap) {
  773. String relId = (String)
  774. (myRelMBeanObjName2RelIdMap.get(theObjName));
  775. if (relId != null) {
  776. result = relId;
  777. }
  778. }
  779. return result;
  780. }
  781. /**
  782. * Checks if there is a relation identified in Relation Service with given
  783. * relation id.
  784. *
  785. * @param theRelId relation id identifying the relation
  786. *
  787. * @return boolean: true if there is a relation, false else
  788. *
  789. * @exception IllegalArgumentException if null parameter
  790. */
  791. public Boolean hasRelation(String theRelId)
  792. throws IllegalArgumentException {
  793. if (theRelId == null) {
  794. // Revisit [cebro[ Localize message
  795. String excMsg = "Invalid parameter.";
  796. throw new IllegalArgumentException(excMsg);
  797. }
  798. if (isTraceOn())
  799. trace("hasRelation", theRelId);
  800. try {
  801. // Can throw RelationNotFoundException
  802. Object result = getRelation(theRelId);
  803. return new Boolean(true);
  804. } catch (RelationNotFoundException exc) {
  805. return new Boolean(false);
  806. }
  807. }
  808. /**
  809. * Returns all the relation ids for all the relations handled by the
  810. * Relation Service.
  811. *
  812. * @return ArrayList of String
  813. */
  814. public List getAllRelationIds() {
  815. ArrayList result = null;
  816. synchronized(myRelId2ObjMap) {
  817. result = new ArrayList(myRelId2ObjMap.keySet());
  818. }
  819. return result;
  820. }
  821. /**
  822. * Checks if given Role can be read in a relation of the given type.
  823. *
  824. * @param theRoleName name of role to be checked
  825. * @param theRelTypeName name of the relation type
  826. *
  827. * @return an Integer wrapping an integer corresponding to possible
  828. * problems represented as constants in RoleUnresolved:
  829. * <P>- 0 if role can be read
  830. * <P>- integer corresponding to RoleStatus.NO_ROLE_WITH_NAME
  831. * <P>- integer corresponding to RoleStatus.ROLE_NOT_READABLE
  832. *
  833. * @exception IllegalArgumentException if null parameter
  834. * @exception RelationTypeNotFoundException if the relation type is not
  835. * known in the Relation Service
  836. */
  837. public Integer checkRoleReading(String theRoleName,
  838. String theRelTypeName)
  839. throws IllegalArgumentException,
  840. RelationTypeNotFoundException {
  841. if (theRoleName == null || theRelTypeName == null) {
  842. // Revisit [cebro] Localize message
  843. String excMsg = "Invalid parameter.";
  844. throw new IllegalArgumentException(excMsg);
  845. }
  846. if (isTraceOn()) {
  847. String str = "theRoleName " + theRoleName
  848. + ", theRelTypeName " + theRelTypeName;
  849. trace("checkRoleReading: entering", str);
  850. }
  851. Integer result = null;
  852. // Can throw a RelationTypeNotFoundException
  853. RelationType relType = getRelationType(theRelTypeName);
  854. try {
  855. // Can throw a RoleInfoNotFoundException to be transformed into
  856. // returned value RoleStatus.NO_ROLE_WITH_NAME
  857. RoleInfo roleInfo = relType.getRoleInfo(theRoleName);
  858. result = checkRoleInt(1,
  859. theRoleName,
  860. null,
  861. roleInfo,
  862. false);
  863. } catch (RoleInfoNotFoundException exc) {
  864. result = new Integer(RoleStatus.NO_ROLE_WITH_NAME);
  865. }
  866. if (isTraceOn())
  867. trace("checkRoleReading: exiting", null);
  868. return result;
  869. }
  870. /**
  871. * Checks if given Role can be set in a relation of given type.
  872. *
  873. * @param theRole role to be checked
  874. * @param theRelTypeName name of relation type
  875. * @param theInitFlg flag to specify that the checking is done for the
  876. * initialization of a role, write access shall not be verified.
  877. *
  878. * @return an Integer wrapping an integer corresponding to possible
  879. * problems represented as constants in RoleUnresolved:
  880. * <P>- 0 if role can be set
  881. * <P>- integer corresponding to RoleStatus.NO_ROLE_WITH_NAME
  882. * <P>- integer for RoleStatus.ROLE_NOT_WRITABLE
  883. * <P>- integer for RoleStatus.LESS_THAN_MIN_ROLE_DEGREE
  884. * <P>- integer for RoleStatus.MORE_THAN_MAX_ROLE_DEGREE
  885. * <P>- integer for RoleStatus.REF_MBEAN_OF_INCORRECT_CLASS
  886. * <P>- integer for RoleStatus.REF_MBEAN_NOT_REGISTERED
  887. *
  888. * @exception IllegalArgumentException if null parameter
  889. * @exception RelationTypeNotFoundException if unknown relation type
  890. */
  891. public Integer checkRoleWriting(Role theRole,
  892. String theRelTypeName,
  893. Boolean theInitFlg)
  894. throws IllegalArgumentException,
  895. RelationTypeNotFoundException {
  896. if (theRole == null ||
  897. theRelTypeName == null ||
  898. theInitFlg == null) {
  899. // Revisit [cebro] Localize message
  900. String excMsg = "Invalid parameter.";
  901. throw new IllegalArgumentException(excMsg);
  902. }
  903. if (isTraceOn()) {
  904. String str = new String("theRole " + theRole.toString()
  905. + ", theRelTypeName " + theRelTypeName
  906. + ", theInitFlg " + theInitFlg);
  907. trace("checkRoleWriting: entering", str);
  908. }
  909. // Can throw a RelationTypeNotFoundException
  910. RelationType relType = getRelationType(theRelTypeName);
  911. String roleName = theRole.getRoleName();
  912. ArrayList roleValue = (ArrayList)(theRole.getRoleValue());
  913. boolean writeChkFlg = true;
  914. if (theInitFlg.booleanValue()) {
  915. writeChkFlg = false;
  916. }
  917. RoleInfo roleInfo = null;
  918. try {
  919. roleInfo = relType.getRoleInfo(roleName);
  920. } catch (RoleInfoNotFoundException exc) {
  921. if (isTraceOn())
  922. trace("checkRoleWriting: exiting", null);
  923. return new Integer(RoleStatus.NO_ROLE_WITH_NAME);
  924. }
  925. Integer result = checkRoleInt(2,
  926. roleName,
  927. roleValue,
  928. roleInfo,
  929. writeChkFlg);
  930. if (isTraceOn())
  931. trace("checkRoleWriting: exiting", null);
  932. return result;
  933. }
  934. /**
  935. * Sends a notification (RelationNotification) for a relation creation.
  936. * The notification type is:
  937. * <P>- RelationNotification.RELATION_BASIC_CREATION if the relation is an
  938. * object internal to the Relation Service
  939. * <P>- RelationNotification.RELATION_MBEAN_CREATION if the relation is a
  940. * MBean added as a relation.
  941. * <P>The source object is the Relation Service itself.
  942. * <P>It is called in Relation Service createRelation() and
  943. * addRelation() methods.
  944. *
  945. * @param theRelId relation identifier of the updated relation
  946. *
  947. * @exception IllegalArgumentException if null parameter
  948. * @exception RelationNotFoundException if there is no relation for given
  949. * relation id
  950. */
  951. public void sendRelationCreationNotification(String theRelId)
  952. throws IllegalArgumentException,
  953. RelationNotFoundException {
  954. if (theRelId == null) {
  955. // Revisit [cebro[ Localize message
  956. String excMsg = "Invalid parameter.";
  957. throw new IllegalArgumentException(excMsg);
  958. }
  959. if (isTraceOn())
  960. trace("sendRelationCreationNotification: entering", theRelId);
  961. // Message
  962. // Revisit [cebro] Localize message
  963. StringBuffer ntfMsg = new StringBuffer("Creation of relation ");
  964. ntfMsg.append(theRelId);
  965. // Can throw RelationNotFoundException
  966. sendNotificationInt(1,
  967. ntfMsg.toString(),
  968. theRelId,
  969. null,
  970. null,
  971. null,
  972. null);
  973. if (isTraceOn())
  974. trace("sendRelationCreationNotification: exiting", null);
  975. return;
  976. }
  977. /**
  978. * Sends a notification (RelationNotification) for a role update in the
  979. * given relation. The notification type is:
  980. * <P>- RelationNotification.RELATION_BASIC_UPDATE if the relation is an
  981. * object internal to the Relation Service
  982. * <P>- RelationNotification.RELATION_MBEAN_UPDATE if the relation is a
  983. * MBean added as a relation.
  984. * <P>The source object is the Relation Service itself.
  985. * <P>It is called in relation MBean setRole() (for given role) and
  986. * setRoles() (for each role) methods (implementation provided in
  987. * RelationSupport class).
  988. * <P>It is also called in Relation Service setRole() (for given role) and
  989. * setRoles() (for each role) methods.
  990. *
  991. * @param theRelId relation identifier of the updated relation
  992. * @param theNewRole new role (name and new value)
  993. * @param theOldRoleValue old role value (List of ObjectName objects)
  994. *
  995. * @exception IllegalArgumentException if null parameter
  996. * @exception RelationNotFoundException if there is no relation for given
  997. * relation id
  998. */
  999. public void sendRoleUpdateNotification(String theRelId,
  1000. Role theNewRole,
  1001. List theOldRoleValue)
  1002. throws IllegalArgumentException,
  1003. RelationNotFoundException {
  1004. if (theRelId == null ||
  1005. theNewRole == null ||
  1006. theOldRoleValue == null) {
  1007. // Revisit [cebro] Localize message
  1008. String excMsg = "Invalid parameter.";
  1009. throw new IllegalArgumentException(excMsg);
  1010. }
  1011. if (!(theOldRoleValue instanceof ArrayList))
  1012. theOldRoleValue = new ArrayList(theOldRoleValue);
  1013. if (isTraceOn()) {
  1014. String str = new String("theRelId " + theRelId
  1015. + ", theNewRole " + theNewRole.toString()
  1016. + ", theOldRoleValue "
  1017. + theOldRoleValue.toString());
  1018. trace("sendRoleUpdateNotification: entering", str);
  1019. }
  1020. String roleName = theNewRole.getRoleName();
  1021. ArrayList newRoleVal = (ArrayList)(theNewRole.getRoleValue());
  1022. // Message
  1023. String newRoleValString = Role.roleValueToString(newRoleVal);
  1024. String oldRoleValString = Role.roleValueToString(theOldRoleValue);
  1025. // Revisit [cebro] Localize message
  1026. StringBuffer ntfMsg = new StringBuffer("Value of role ");
  1027. ntfMsg.append(roleName);
  1028. ntfMsg.append(" has changed\nOld value:\n");
  1029. ntfMsg.append(oldRoleValString);
  1030. ntfMsg.append("\nNew value:\n");
  1031. ntfMsg.append(newRoleValString);
  1032. // Can throw a RelationNotFoundException
  1033. sendNotificationInt(2,
  1034. ntfMsg.toString(),
  1035. theRelId,
  1036. null,
  1037. roleName,
  1038. newRoleVal,
  1039. theOldRoleValue);
  1040. if (isTraceOn())
  1041. trace("sendRoleUpdateNotification: exiting", null);
  1042. return;
  1043. }
  1044. /**
  1045. * Sends a notification (RelationNotification) for a relation removal.
  1046. * The notification type is:
  1047. * <P>- RelationNotification.RELATION_BASIC_REMOVAL if the relation is an
  1048. * object internal to the Relation Service
  1049. * <P>- RelationNotification.RELATION_MBEAN_REMOVAL if the relation is a
  1050. * MBean added as a relation.
  1051. * <P>The source object is the Relation Service itself.
  1052. * <P>It is called in Relation Service removeRelation() method.
  1053. *
  1054. * @param theRelId relation identifier of the updated relation
  1055. * @param theUnregMBeanList List of ObjectNames of MBeans expected
  1056. * to be unregistered due to relation removal (can be null)
  1057. *
  1058. * @exception IllegalArgumentException if null parameter
  1059. * @exception RelationNotFoundException if there is no relation for given
  1060. * relation id
  1061. */
  1062. public void sendRelationRemovalNotification(String theRelId,
  1063. List theUnregMBeanList)
  1064. throws IllegalArgumentException,
  1065. RelationNotFoundException {
  1066. if (theRelId == null) {
  1067. String excMsg = "Invalid parameter";
  1068. throw new IllegalArgumentException(excMsg);
  1069. }
  1070. if (isTraceOn()) {
  1071. StringBuffer strB = new StringBuffer("theRelId " + theRelId);
  1072. if (theUnregMBeanList != null) {
  1073. strB.append(", theUnregMBeanList "
  1074. + theUnregMBeanList.toString());
  1075. }
  1076. trace("sendRelationRemovalNotification: entering",
  1077. strB.toString());
  1078. }
  1079. // Message
  1080. // Revisit [cebro] Include string for ObjectNames to be unregistered?
  1081. StringBuffer ntfMsg = new StringBuffer("Removal of relation ");
  1082. ntfMsg.append(theRelId);
  1083. // Can throw RelationNotFoundException
  1084. sendNotificationInt(3,
  1085. ntfMsg.toString(),
  1086. theRelId,
  1087. theUnregMBeanList,
  1088. null,
  1089. null,
  1090. null);
  1091. if (isTraceOn())
  1092. trace("sendRelationRemovalNotification: exiting", null);
  1093. return;
  1094. }
  1095. /**
  1096. * Handles update of the Relation Service role map for the update of given
  1097. * role in given relation.
  1098. * <P>It is called in relation MBean setRole() (for given role) and
  1099. * setRoles() (for each role) methods (implementation provided in
  1100. * RelationSupport class).
  1101. * <P>It is also called in Relation Service setRole() (for given role) and
  1102. * setRoles() (for each role) methods.
  1103. * <P>To allow the Relation Service to maintain the consistency (in case
  1104. * of MBean unregistration) and to be able to perform queries, this method
  1105. * must be called when a role is updated.
  1106. *
  1107. * @param theRelId relation identifier of the updated relation
  1108. * @param theNewRole new role (name and new value)
  1109. * @param theOldRoleValue old role value (List of ObjectName objects)
  1110. *
  1111. * @exception IllegalArgumentException if null parameter
  1112. * @exception RelationServiceNotRegisteredException if the Relation
  1113. * Service is not registered in the MBean Server
  1114. * @exception RelationNotFoundException if no relation for given id.
  1115. */
  1116. public void updateRoleMap(String theRelId,
  1117. Role theNewRole,
  1118. List theOldRoleValue)
  1119. throws IllegalArgumentException,
  1120. RelationServiceNotRegisteredException,
  1121. RelationNotFoundException {
  1122. if (theRelId == null ||
  1123. theNewRole == null ||
  1124. theOldRoleValue == null) {
  1125. String excMsg = "Invalid parameter.";
  1126. throw new IllegalArgumentException(excMsg);
  1127. }
  1128. if (isTraceOn()) {
  1129. String str = new String("theRelId " + theRelId
  1130. + ", theNewRole " + theNewRole.toString()
  1131. + ", theOldRoleValue "
  1132. + theOldRoleValue.toString());
  1133. trace("updateRoleMap: entering", str);
  1134. }
  1135. // Can throw RelationServiceNotRegisteredException
  1136. isActive();
  1137. // Verifies the relation has been added in the Relation Service
  1138. // Can throw a RelationNotFoundException
  1139. Object result = getRelation(theRelId);
  1140. String roleName = theNewRole.getRoleName();
  1141. ArrayList newRoleValue = (ArrayList)(theNewRole.getRoleValue());
  1142. // Note: no need to test if theOldRoleValue not null before cloning,
  1143. // tested above.
  1144. ArrayList oldRoleValue = new ArrayList(theOldRoleValue);
  1145. // List of ObjectNames of new referenced MBeans
  1146. ArrayList newRefList = new ArrayList();
  1147. for (Iterator newRoleIter = newRoleValue.iterator();
  1148. newRoleIter.hasNext();) {
  1149. ObjectName currObjName = (ObjectName)(newRoleIter.next());
  1150. // Checks if this ObjectName was already present in old value
  1151. // Note: use copy (oldRoleValue) instead of original
  1152. // theOldRoleValue to speed up, as oldRoleValue is decreased
  1153. // by removing unchanged references :)
  1154. int currObjNamePos = oldRoleValue.indexOf(currObjName);
  1155. if (currObjNamePos == -1) {
  1156. // New reference to an ObjectName
  1157. // Stores this reference into map
  1158. // Returns true if new reference, false if MBean already
  1159. // referenced
  1160. boolean isNewFlg = addNewMBeanReference(currObjName,
  1161. theRelId,
  1162. roleName);
  1163. if (isNewFlg) {
  1164. // Adds it into list of new reference
  1165. newRefList.add(currObjName);
  1166. }
  1167. } else {
  1168. // MBean was already referenced in old value
  1169. // Removes it from old value (local list) to ignore it when
  1170. // looking for remove MBean references
  1171. oldRoleValue.remove(currObjNamePos);
  1172. }
  1173. }
  1174. // List of ObjectNames of MBeans no longer referenced
  1175. ArrayList obsRefList = new ArrayList();
  1176. // Each ObjectName remaining in oldRoleValue is an ObjectName no longer
  1177. // referenced in new value
  1178. for (Iterator oldRoleIter = oldRoleValue.iterator();
  1179. oldRoleIter.hasNext();) {
  1180. ObjectName currObjName = (ObjectName)(oldRoleIter.next());
  1181. // Removes MBean reference from map
  1182. // Returns true if the MBean is no longer referenced in any
  1183. // relation
  1184. boolean noLongerRefFlg = removeMBeanReference(currObjName,
  1185. theRelId,
  1186. roleName,
  1187. false);
  1188. if (noLongerRefFlg) {
  1189. // Adds it into list of references to be removed
  1190. obsRefList.add(currObjName);
  1191. }
  1192. }
  1193. // To avoid having one listener per ObjectName of referenced MBean,
  1194. // and to increase performances, there is only one listener recording
  1195. // all ObjectNames of interest
  1196. updateUnregistrationListener(newRefList, obsRefList);
  1197. if (isTraceOn())
  1198. trace("updateRoleMap: exiting", null);
  1199. return;
  1200. }
  1201. /**
  1202. * Removes given relation from the Relation Service.
  1203. * <P>A RelationNotification notification is sent, its type being:
  1204. * <P>- RelationNotification.RELATION_BASIC_REMOVAL if the relation was
  1205. * only internal to the Relation Service
  1206. * <P>- RelationNotification.RELATION_MBEAN_REMOVAL if the relation is
  1207. * registered as an MBean.
  1208. * <P>For MBeans referenced in such relation, nothing will be done,
  1209. *
  1210. * @param theRelId relation id of the relation to be removed
  1211. *
  1212. * @exception RelationServiceNotRegisteredException if the Relation
  1213. * Service is not registered in the MBean Server
  1214. * @exception IllegalArgumentException if null parameter
  1215. * @exception RelationNotFoundException if no relation corresponding to
  1216. * given relation id
  1217. */
  1218. public void removeRelation(String theRelId)
  1219. throws RelationServiceNotRegisteredException,
  1220. IllegalArgumentException,
  1221. RelationNotFoundException {
  1222. // Can throw RelationServiceNotRegisteredException
  1223. isActive();
  1224. if (theRelId == null) {
  1225. // Revisit [cebro[ Localize message
  1226. String excMsg = "Invalid parameter.";
  1227. throw new IllegalArgumentException(excMsg);
  1228. }
  1229. if (isTraceOn())
  1230. trace("removeRelation: entering", theRelId);
  1231. // Checks there is a relation with this id
  1232. // Can throw RelationNotFoundException
  1233. Object result = getRelation(theRelId);
  1234. // Removes it from listener filter
  1235. if (result instanceof ObjectName) {
  1236. ArrayList obsRefList = new ArrayList();
  1237. obsRefList.add((ObjectName)result);
  1238. // Can throw a RelationServiceNotRegisteredException
  1239. updateUnregistrationListener(null, obsRefList);
  1240. }
  1241. // Sends a notification
  1242. // Note: has to be done FIRST as needs the relation to be still in the
  1243. // Relation Service
  1244. // No RelationNotFoundException as checked above
  1245. // Revisit [cebro] Handle CIM "Delete" and "IfDeleted" qualifiers:
  1246. // deleting the relation can mean to delete referenced MBeans. In
  1247. // that case, MBeans to be unregistered are put in a list sent along
  1248. // with the notification below
  1249. // Can throw a RelationNotFoundException (but detected above)
  1250. sendRelationRemovalNotification(theRelId, null);
  1251. // Removes the relation from various internal maps
  1252. // - MBean reference map
  1253. // Retrieves the MBeans referenced in this relation
  1254. // Note: here we cannot use removeMBeanReference() because it would
  1255. // require to know the MBeans referenced in the relation. For
  1256. // that it would be necessary to call 'getReferencedMBeans()'
  1257. // on the relation itself. Ok if it is an internal one, but if
  1258. // it is an MBean, it is possible it is already unregistered, so
  1259. // not available through the MBean Server.
  1260. ArrayList refMBeanList = new ArrayList();
  1261. // List of MBeans no longer referenced in any relation, to be
  1262. // removed fom the map
  1263. ArrayList nonRefObjNameList = new ArrayList();
  1264. synchronized(myRefedMBeanObjName2RelIdsMap) {
  1265. for (Iterator refMBeanIter =
  1266. (myRefedMBeanObjName2RelIdsMap.keySet()).iterator();
  1267. refMBeanIter.hasNext();) {
  1268. ObjectName currRefObjName = (ObjectName)(refMBeanIter.next());
  1269. // Retrieves relations where the MBean is referenced
  1270. HashMap relIdMap = (HashMap)
  1271. (myRefedMBeanObjName2RelIdsMap.get(currRefObjName));
  1272. if (relIdMap.containsKey(theRelId)) {
  1273. relIdMap.remove(theRelId);
  1274. refMBeanList.add(currRefObjName);
  1275. }
  1276. if (relIdMap.isEmpty()) {
  1277. // MBean no longer referenced
  1278. // Note: do not remove it here because pointed by the
  1279. // iterator!
  1280. nonRefObjNameList.add(currRefObjName);
  1281. }
  1282. }
  1283. // Cleans MBean reference map by removing MBeans no longer
  1284. // referenced
  1285. for (Iterator nonRefObjNameIter = nonRefObjNameList.iterator();
  1286. nonRefObjNameIter.hasNext();) {
  1287. ObjectName currRefObjName = (ObjectName)
  1288. (nonRefObjNameIter.next());
  1289. myRefedMBeanObjName2RelIdsMap.remove(currRefObjName);
  1290. }
  1291. }
  1292. // - Relation id to object map
  1293. synchronized(myRelId2ObjMap) {
  1294. myRelId2ObjMap.remove(theRelId);
  1295. }
  1296. if (result instanceof ObjectName) {
  1297. // - ObjectName to relation id map
  1298. synchronized(myRelMBeanObjName2RelIdMap) {
  1299. myRelMBeanObjName2RelIdMap.remove((ObjectName)result);
  1300. }
  1301. }
  1302. // Relation id to relation type name map
  1303. // First retrieves the relation type name
  1304. String relTypeName = null;
  1305. synchronized(myRelId2RelTypeMap) {
  1306. relTypeName = (String)(myRelId2RelTypeMap.get(theRelId));
  1307. myRelId2RelTypeMap.remove(theRelId);
  1308. }
  1309. // - Relation type name to relation id map
  1310. synchronized(myRelType2RelIdsMap) {
  1311. ArrayList relIdList =
  1312. (ArrayList)(myRelType2RelIdsMap.get(relTypeName));
  1313. if (relIdList != null) {
  1314. // Can be null if called from removeRelationType()
  1315. relIdList.remove(theRelId);
  1316. if (relIdList.isEmpty()) {
  1317. // No other relation of that type
  1318. myRelType2RelIdsMap.remove(relTypeName);
  1319. }
  1320. }
  1321. }
  1322. if (isTraceOn())
  1323. trace("removeRelation: exiting", null);
  1324. return;
  1325. }
  1326. /**
  1327. * Purges the relations.
  1328. *
  1329. * <P>Depending on the purgeFlag value, this method is either called
  1330. * automatically when a notification is received for the unregistration of
  1331. * an MBean referenced in a relation (if the flag is set to true), or not
  1332. * (if the flag is set to false).
  1333. * <P>In that case it is up to the user to call it to maintain the
  1334. * consistency of the relations. To be kept in mind that if an MBean is
  1335. * unregistered and the purge not done immediately, if the ObjectName is
  1336. * reused and assigned to another MBean referenced in a relation, calling
  1337. * manually this purgeRelations() method will cause trouble, as will
  1338. * consider the ObjectName as corresponding to the unregistered MBean, not
  1339. * seeing the new one.
  1340. *
  1341. * <P>The behavior depends on the cardinality of the role where the
  1342. * unregistered MBean is referenced:
  1343. * <P>- if removing one MBean reference in the role makes its number of
  1344. * references less than the minimum degree, the relation has to be removed.
  1345. * <P>- if the remaining number of references after removing the MBean
  1346. * reference is still in the cardinality range, keep the relation and
  1347. * update it calling its handleMBeanUnregistration() callback.
  1348. *
  1349. * @exception RelationServiceNotRegisteredException if the Relation
  1350. * Service is not registered in the MBean Server.
  1351. */
  1352. public void purgeRelations()
  1353. throws RelationServiceNotRegisteredException {
  1354. if (isTraceOn())
  1355. trace("purgeRelations: entering", null);
  1356. // Can throw RelationServiceNotRegisteredException
  1357. isActive();
  1358. // Revisit [cebro] Handle the CIM "Delete" and "IfDeleted" qualifier:
  1359. // if the unregistered MBean has the "IfDeleted" qualifier,
  1360. // possible that the relation itself or other referenced MBeans
  1361. // have to be removed (then a notification would have to be sent
  1362. // to inform that they should be unregistered.
  1363. // Clones the list of notifications to be able to still receive new
  1364. // notifications while proceeding those ones
  1365. ArrayList localUnregNtfList = null;
  1366. synchronized(myUnregNtfList) {
  1367. localUnregNtfList = (ArrayList)(myUnregNtfList.clone());
  1368. // Resets list
  1369. myUnregNtfList = new ArrayList();
  1370. }
  1371. // Updates the listener filter to avoid receiving notifications for
  1372. // those MBeans again
  1373. // Makes also a local "myRefedMBeanObjName2RelIdsMap" map, mapping
  1374. // ObjectName -> relId -> roles, to remove the MBean from the global
  1375. // map
  1376. // List of references to be removed from the listener filter
  1377. ArrayList obsRefList = new ArrayList();
  1378. // Map including ObjectNames for unregistered MBeans, with
  1379. // referencing relation ids and roles
  1380. HashMap localMBean2RelIdMap = new HashMap();
  1381. synchronized(myRefedMBeanObjName2RelIdsMap) {
  1382. for (Iterator unregNtfIter = localUnregNtfList.iterator();
  1383. unregNtfIter.hasNext();) {
  1384. MBeanServerNotification currNtf =
  1385. (MBeanServerNotification)(unregNtfIter.next());
  1386. ObjectName unregMBeanName = currNtf.getMBeanName();
  1387. // Adds the unregsitered MBean in the list of references to
  1388. // remove from the listener filter
  1389. obsRefList.add(unregMBeanName);
  1390. // Retrieves the associated map of relation ids and roles
  1391. HashMap relIdMap = (HashMap)
  1392. (myRefedMBeanObjName2RelIdsMap.get(unregMBeanName));
  1393. localMBean2RelIdMap.put(unregMBeanName, relIdMap);
  1394. myRefedMBeanObjName2RelIdsMap.remove(unregMBeanName);
  1395. }
  1396. }
  1397. // Updates the listener
  1398. // Can throw RelationServiceNotRegisteredException
  1399. updateUnregistrationListener(null, obsRefList);
  1400. for (Iterator unregNtfIter = localUnregNtfList.iterator();
  1401. unregNtfIter.hasNext();) {
  1402. MBeanServerNotification currNtf =
  1403. (MBeanServerNotification)(unregNtfIter.next());
  1404. ObjectName unregMBeanName = currNtf.getMBeanName();
  1405. // Retrieves the relations where the MBean is referenced
  1406. HashMap localRelIdMap = (HashMap)
  1407. (localMBean2RelIdMap.get(unregMBeanName));
  1408. // List of relation ids where the unregistered MBean is
  1409. // referenced
  1410. Set localRelIdSet = localRelIdMap.keySet();
  1411. for (Iterator relIdIter = localRelIdSet.iterator();
  1412. relIdIter.hasNext();) {
  1413. String currRelId = (String)(relIdIter.next());
  1414. // List of roles of the relation where the MBean is
  1415. // referenced
  1416. ArrayList localRoleNameList = (ArrayList)
  1417. (localRelIdMap.get(currRelId));
  1418. // Checks if the relation has to be removed or not,
  1419. // regarding expected minimum role cardinality and current
  1420. // number of references after removal of the current one
  1421. // If the relation is kept, calls
  1422. // handleMBeanUnregistration() callback of the relation to
  1423. // update it
  1424. //
  1425. // Can throw RelationServiceNotRegisteredException
  1426. //
  1427. // Shall not throw RelationNotFoundException,
  1428. // RoleNotFoundException, MBeanException
  1429. try {
  1430. handleReferenceUnregistration(currRelId,
  1431. unregMBeanName,
  1432. localRoleNameList);
  1433. } catch (RelationNotFoundException exc1) {
  1434. throw new RuntimeException(exc1.getMessage());
  1435. } catch (RoleNotFoundException exc2) {
  1436. throw new RuntimeException(exc2.getMessage());
  1437. }
  1438. }
  1439. }
  1440. if (isTraceOn())
  1441. trace("purgeRelations: exiting", null);
  1442. return;
  1443. }
  1444. /**
  1445. * Retrieves the relations where a given MBean is referenced.
  1446. * <P>This corresponds to the CIM "References" and "ReferenceNames"
  1447. * operations.
  1448. *
  1449. * @param theMBeanName ObjectName of MBean
  1450. * @param theRelTypeName can be null; if specified, only the relations
  1451. * of that type will be considered in the search. Else all relation types
  1452. * are considered.
  1453. * @param theRoleName can be null; if specified, only the relations
  1454. * where the MBean is referenced in that role will be returned. Else all
  1455. * roles are considered.
  1456. *
  1457. * @return an HashMap, where the keys are the relation ids of the relations
  1458. * where the MBean is referenced, and the value is, for each key,
  1459. * an ArrayList of role names (as an MBean can be referenced in several
  1460. * roles in the same relation).
  1461. *
  1462. * @exception IllegalArgumentException if null parameter
  1463. */
  1464. public Map findReferencingRelations(ObjectName theMBeanName,
  1465. String theRelTypeName,
  1466. String theRoleName)
  1467. throws IllegalArgumentException {
  1468. if (theMBeanName == null) {
  1469. // Revisit [cebro] Localize message
  1470. String excMsg = "Invalid parameter.";
  1471. throw new IllegalArgumentException(excMsg);
  1472. }
  1473. if (isTraceOn()) {
  1474. String str = new String("theMBeanName " + theMBeanName.toString()
  1475. + ", theRelTypeName " + theRelTypeName
  1476. + ", theRoleName " + theRoleName);
  1477. trace("findReferencingRelations: entering", str);
  1478. }
  1479. HashMap result = new HashMap();
  1480. synchronized(myRefedMBeanObjName2RelIdsMap) {
  1481. // Retrieves the relations referencing the MBean
  1482. HashMap relId2RoleNamesMap =
  1483. (HashMap)(myRefedMBeanObjName2RelIdsMap.get(theMBeanName));
  1484. if (relId2RoleNamesMap != null) {
  1485. // Relation Ids where the MBean is referenced
  1486. Set allRelIdSet = relId2RoleNamesMap.keySet();
  1487. // List of relation ids of interest regarding the selected
  1488. // relation type
  1489. ArrayList relIdList = null;
  1490. if (theRelTypeName == null) {
  1491. // Considers all relations
  1492. relIdList = new ArrayList(allRelIdSet);
  1493. } else {
  1494. relIdList = new ArrayList();
  1495. // Considers only the relation ids for relations of given
  1496. // type
  1497. for (Iterator relIdIter = allRelIdSet.iterator();
  1498. relIdIter.hasNext();) {
  1499. String currRelId = (String)(relIdIter.next());
  1500. // Retrieves its relation type
  1501. String currRelTypeName = null;
  1502. synchronized(myRelId2RelTypeMap) {
  1503. currRelTypeName = (String)
  1504. (myRelId2RelTypeMap.get(currRelId));
  1505. }
  1506. if (currRelTypeName.equals(theRelTypeName)) {
  1507. relIdList.add(currRelId);
  1508. }
  1509. }
  1510. }
  1511. // Now looks at the roles where the MBean is expected to be
  1512. // referenced
  1513. for (Iterator relIdIter = relIdList.iterator();
  1514. relIdIter.hasNext();) {
  1515. String currRelId = (String)(relIdIter.next());
  1516. // Retrieves list of role names where the MBean is
  1517. // referenced
  1518. ArrayList currRoleNameList =
  1519. (ArrayList)(relId2RoleNamesMap.get(currRelId));
  1520. if (theRoleName == null) {
  1521. // All roles to be considered
  1522. // Note: no need to test if list not null before
  1523. // cloning, MUST be not null else bug :(
  1524. result.put(currRelId,
  1525. (ArrayList)(currRoleNameList.clone()));
  1526. } else if (currRoleNameList.contains(theRoleName)) {
  1527. // Filters only the relations where the MBean is
  1528. // referenced in // given role
  1529. ArrayList dummyList = new ArrayList();
  1530. dummyList.add(theRoleName);
  1531. result.put(currRelId, dummyList);
  1532. }
  1533. }
  1534. }
  1535. }
  1536. if (isTraceOn())
  1537. trace("findReferencingRelations: exiting", null);
  1538. return result;
  1539. }
  1540. /**
  1541. * Retrieves the MBeans associated to given one in a relation.
  1542. * <P>This corresponds to CIM Associators and AssociatorNames operations.
  1543. *
  1544. * @param theMBeanName ObjectName of MBean
  1545. * @param theRelTypeName can be null; if specified, only the relations
  1546. * of that type will be considered in the search. Else all
  1547. * relation types are considered.
  1548. * @param theRoleName can be null; if specified, only the relations
  1549. * where the MBean is referenced in that role will be considered. Else all
  1550. * roles are considered.
  1551. *
  1552. * @return an HashMap, where the keys are the ObjectNames of the MBeans
  1553. * associated to given MBean, and the value is, for each key, an ArrayList
  1554. * of the relation ids of the relations where the key MBean is
  1555. * associated to given one (as they can be associated in several different
  1556. * relations).
  1557. *
  1558. * @exception IllegalArgumentException if null parameter
  1559. */
  1560. public Map findAssociatedMBeans(ObjectName theMBeanName,
  1561. String theRelTypeName,
  1562. String theRoleName)
  1563. throws IllegalArgumentException {
  1564. if (theMBeanName == null) {
  1565. // Revisit [cebro[ Localize message
  1566. String excMsg = "Invalid parameter.";
  1567. throw new IllegalArgumentException(excMsg);
  1568. }
  1569. if (isTraceOn()) {
  1570. String str = new String("theMBeanName " + theMBeanName.toString()
  1571. + ", theRelTypeName " + theRelTypeName
  1572. + ", theRoleName " + theRoleName);
  1573. trace("findAssociatedMBeans: entering", str);
  1574. }
  1575. // Retrieves the map <relation id> -> <role names> for those
  1576. // criterias
  1577. HashMap relId2RoleNamesMap = (HashMap)
  1578. (findReferencingRelations(theMBeanName,
  1579. theRelTypeName,
  1580. theRoleName));
  1581. HashMap result = new HashMap();
  1582. for (Iterator relIdIter = (relId2RoleNamesMap.keySet()).iterator();
  1583. relIdIter.hasNext();) {
  1584. String currRelId = (String)(relIdIter.next());
  1585. // Retrieves ObjectNames of MBeans referenced in this relation
  1586. //
  1587. // Shall not throw a RelationNotFoundException if incorrect status
  1588. // of maps :(
  1589. HashMap objName2RoleNamesMap = null;
  1590. try {
  1591. objName2RoleNamesMap =
  1592. (HashMap)(getReferencedMBeans(currRelId));
  1593. } catch (RelationNotFoundException exc) {
  1594. throw new RuntimeException(exc.getMessage());
  1595. }
  1596. // For each MBean associated to given one in a relation, adds the
  1597. // association <ObjectName> -> <relation id> into result map
  1598. for (Iterator objNameIter =
  1599. (objName2RoleNamesMap.keySet()).iterator();
  1600. objNameIter.hasNext();) {
  1601. ObjectName currObjName = (ObjectName)(objNameIter.next());
  1602. if (!(currObjName.equals(theMBeanName))) {
  1603. // Sees if this MBean is already associated to the given
  1604. // one in another relation
  1605. ArrayList currRelIdList =
  1606. (ArrayList)(result.get(currObjName));
  1607. if (currRelIdList == null) {
  1608. currRelIdList = new ArrayList();
  1609. currRelIdList.add(currRelId);
  1610. result.put(currObjName, currRelIdList);
  1611. } else {
  1612. currRelIdList.add(currRelId);
  1613. }
  1614. }
  1615. }
  1616. }
  1617. if (isTraceOn())
  1618. trace("findReferencingRelations: exiting", null);
  1619. return result;
  1620. }
  1621. /**
  1622. * Returns the relation ids for relations of the given type.
  1623. *
  1624. * @param theRelTypeName relation type name
  1625. *
  1626. * @return an ArrayList of relation ids.
  1627. *
  1628. * @exception IllegalArgumentException if null parameter
  1629. * @exception RelationTypeNotFoundException if there is no relation type
  1630. * with that name.
  1631. */
  1632. public List findRelationsOfType(String theRelTypeName)
  1633. throws IllegalArgumentException,
  1634. RelationTypeNotFoundException {
  1635. if (theRelTypeName == null) {
  1636. // Revisit [cebro] Localize message
  1637. String excMsg = "Invalid parameter.";
  1638. throw new IllegalArgumentException(excMsg);
  1639. }
  1640. if (isTraceOn())
  1641. trace("findRelationsOfType: entering", theRelTypeName);
  1642. // Can throw RelationTypeNotFoundException
  1643. RelationType relType = getRelationType(theRelTypeName);
  1644. ArrayList result = new ArrayList();
  1645. synchronized(myRelType2RelIdsMap) {
  1646. ArrayList result1 = (ArrayList)
  1647. (myRelType2RelIdsMap.get(theRelTypeName));
  1648. if (result1 != null) {
  1649. result = (ArrayList)(result1.clone());
  1650. }
  1651. }
  1652. if (isTraceOn())
  1653. trace("findRelationsOfType: exiting", null);
  1654. return result;
  1655. }
  1656. /**
  1657. * Retrieves role value for given role name in given relation.
  1658. *
  1659. * @param theRelId relation id
  1660. * @param theRoleName name of role
  1661. *
  1662. * @return the ArrayList of ObjectName objects being the role value
  1663. *
  1664. * @exception RelationServiceNotRegisteredException if the Relation
  1665. * Service is not registered
  1666. * @exception IllegalArgumentException if null parameter
  1667. * @exception RelationNotFoundException if no relation with given id
  1668. * @exception RoleNotFoundException if:
  1669. * <P>- there is no role with given name
  1670. * <P>or
  1671. * <P>- the role is not readable.
  1672. *
  1673. * @see #setRole
  1674. */
  1675. public List getRole(String theRelId,
  1676. String theRoleName)
  1677. throws RelationServiceNotRegisteredException,
  1678. IllegalArgumentException,
  1679. RelationNotFoundException,
  1680. RoleNotFoundException {
  1681. if (theRelId == null || theRoleName == null) {
  1682. // Revisit [cebro[ Localize message
  1683. String excMsg = "Invalid parameter.";
  1684. throw new IllegalArgumentException(excMsg);
  1685. }
  1686. if (isTraceOn()) {
  1687. String str = "theRelId " + theRelId
  1688. + ", theRoleName " + theRoleName;
  1689. trace("getRole: entering", str);
  1690. }
  1691. // Can throw RelationServiceNotRegisteredException
  1692. isActive();
  1693. // Can throw a RelationNotFoundException
  1694. Object relObj = getRelation(theRelId);
  1695. ArrayList result = null;
  1696. if (relObj instanceof RelationSupport) {
  1697. // Internal relation
  1698. // Can throw RoleNotFoundException
  1699. result = (ArrayList)
  1700. (((RelationSupport)relObj).getRoleInt(theRoleName,
  1701. true,
  1702. this,
  1703. false));
  1704. } else {
  1705. // Relation MBean
  1706. Object[] params = new Object[1];
  1707. params[0] = theRoleName;
  1708. String[] signature = new String[1];
  1709. signature[0] = "java.lang.String";
  1710. // Can throw MBeanException wrapping a RoleNotFoundException:
  1711. // throw wrapped exception
  1712. //
  1713. // Shall not throw InstanceNotFoundException or ReflectionException
  1714. try {
  1715. List invokeResult = (List)
  1716. (myMBeanServer.invoke(((ObjectName)relObj),
  1717. "getRole",
  1718. params,
  1719. signature));
  1720. if (invokeResult == null || invokeResult instanceof ArrayList)
  1721. result = (ArrayList) invokeResult;
  1722. else
  1723. result = new ArrayList(result);
  1724. } catch (InstanceNotFoundException exc1) {
  1725. throw new RuntimeException(exc1.getMessage());
  1726. } catch (ReflectionException exc2) {
  1727. throw new RuntimeException(exc2.getMessage());
  1728. } catch (MBeanException exc3) {
  1729. Exception wrappedExc = exc3.getTargetException();
  1730. if (wrappedExc instanceof RoleNotFoundException) {
  1731. throw ((RoleNotFoundException)wrappedExc);
  1732. } else {
  1733. throw new RuntimeException(wrappedExc.getMessage());
  1734. }
  1735. }
  1736. }
  1737. if (isTraceOn())
  1738. trace("getRole: exiting", null);
  1739. return result;
  1740. }
  1741. /**
  1742. * Retrieves values of roles with given names in given relation.
  1743. *
  1744. * @param theRelId relation id
  1745. * @param theRoleNameArray array of names of roles to be retrieved
  1746. *
  1747. * @return a RoleResult object, including a RoleList (for roles
  1748. * successfully retrieved) and a RoleUnresolvedList (for roles not
  1749. * retrieved).
  1750. *
  1751. * @exception RelationServiceNotRegisteredException if the Relation
  1752. * Service is not registered in the MBean Server
  1753. * @exception IllegalArgumentException if null parameter
  1754. * @exception RelationNotFoundException if no relation with given id
  1755. *
  1756. * @see #setRoles
  1757. */
  1758. public RoleResult getRoles(String theRelId,
  1759. String[] theRoleNameArray)
  1760. throws RelationServiceNotRegisteredException,
  1761. IllegalArgumentException,
  1762. RelationNotFoundException {
  1763. if (theRelId == null || theRoleNameArray == null) {
  1764. // Revisit [cebro[ Localize message
  1765. String excMsg = "Invalid parameter.";
  1766. throw new IllegalArgumentException(excMsg);
  1767. }
  1768. if (isTraceOn())
  1769. trace("getRoles: entering", theRelId);
  1770. // Can throw RelationServiceNotRegisteredException
  1771. isActive();
  1772. // Can throw a RelationNotFoundException
  1773. Object relObj = getRelation(theRelId);
  1774. RoleResult result = null;
  1775. if (relObj instanceof RelationSupport) {
  1776. // Internal relation
  1777. result = ((RelationSupport)relObj).getRolesInt(theRoleNameArray,
  1778. true,
  1779. this);
  1780. } else {
  1781. // Relation MBean
  1782. Object[] params = new Object[1];
  1783. params[0] = theRoleNameArray;
  1784. String[] signature = new String[1];
  1785. try {
  1786. signature[0] = (theRoleNameArray.getClass()).getName();
  1787. } catch (Exception exc) {
  1788. // OK : This is an array of java.lang.String
  1789. // so this should never happen...
  1790. }
  1791. // Shall not throw InstanceNotFoundException, ReflectionException
  1792. // or MBeanException
  1793. try {
  1794. result = (RoleResult)
  1795. (myMBeanServer.invoke(((ObjectName)relObj),
  1796. "getRoles",
  1797. params,
  1798. signature));
  1799. } catch (InstanceNotFoundException exc1) {
  1800. throw new RuntimeException(exc1.getMessage());
  1801. } catch (ReflectionException exc2) {
  1802. throw new RuntimeException(exc2.getMessage());
  1803. } catch (MBeanException exc3) {
  1804. throw new
  1805. RuntimeException((exc3.getTargetException()).getMessage());
  1806. }
  1807. }
  1808. if (isTraceOn())
  1809. trace("getRoles: exiting", null);
  1810. return result;
  1811. }
  1812. /**
  1813. * Returns all roles present in the relation.
  1814. *
  1815. * @param theRelId relation id
  1816. *
  1817. * @return a RoleResult object, including a RoleList (for roles
  1818. * successfully retrieved) and a RoleUnresolvedList (for roles not
  1819. * readable).
  1820. *
  1821. * @exception IllegalArgumentException if null parameter
  1822. * @exception RelationNotFoundException if no relation for given id
  1823. * @exception RelationServiceNotRegisteredException if the Relation
  1824. * Service is not registered in the MBean Server
  1825. */
  1826. public RoleResult getAllRoles(String theRelId)
  1827. throws IllegalArgumentException,
  1828. RelationNotFoundException,
  1829. RelationServiceNotRegisteredException {
  1830. if (theRelId == null) {
  1831. // Revisit [cebro[ Localize message
  1832. String excMsg = "Invalid parameter.";
  1833. throw new IllegalArgumentException(excMsg);
  1834. }
  1835. if (isTraceOn())
  1836. trace("getAllRoles: entering", theRelId);
  1837. // Can throw a RelationNotFoundException
  1838. Object relObj = getRelation(theRelId);
  1839. RoleResult result = null;
  1840. if (relObj instanceof RelationSupport) {
  1841. // Internal relation
  1842. result = ((RelationSupport)relObj).getAllRolesInt(true, this);
  1843. } else {
  1844. // Relation MBean
  1845. // Shall not throw any Exception
  1846. try {
  1847. result = (RoleResult)
  1848. (myMBeanServer.getAttribute(((ObjectName)relObj),
  1849. "AllRoles"));
  1850. } catch (Exception exc) {
  1851. throw new RuntimeException(exc.getMessage());
  1852. }
  1853. }
  1854. if (isTraceOn())
  1855. trace("getAllRoles: exiting", null);
  1856. return result;
  1857. }
  1858. /**
  1859. * Retrieves the number of MBeans currently referenced in the given role.
  1860. *
  1861. * @param theRelId relation id
  1862. * @param theRoleName name of role
  1863. *
  1864. * @return the number of currently referenced MBeans in that role
  1865. *
  1866. * @exception IllegalArgumentException if null parameter
  1867. * @exception RelationNotFoundException if no relation with given id
  1868. * @exception RoleNotFoundException if there is no role with given name
  1869. */
  1870. public Integer getRoleCardinality(String theRelId,
  1871. String theRoleName)
  1872. throws IllegalArgumentException,
  1873. RelationNotFoundException,
  1874. RoleNotFoundException {
  1875. if (theRelId == null || theRoleName == null) {
  1876. // Revisit [cebro[ Localize message
  1877. String excMsg = "Invalid parameter.";
  1878. throw new IllegalArgumentException(excMsg);
  1879. }
  1880. if (isTraceOn()) {
  1881. String str = "theRelId " + theRelId
  1882. + ", theRoleName " + theRoleName;
  1883. trace("getRoleCardinality: entering", str);
  1884. }
  1885. // Can throw a RelationNotFoundException
  1886. Object relObj = getRelation(theRelId);
  1887. Integer result = null;
  1888. if (relObj instanceof RelationSupport) {
  1889. // Internal relation
  1890. // Can throw RoleNotFoundException
  1891. result = (Integer)
  1892. (((RelationSupport)relObj).getRoleCardinality(theRoleName));
  1893. } else {
  1894. // Relation MBean
  1895. Object[] params = new Object[1];
  1896. params[0] = theRoleName;
  1897. String[] signature = new String[1];
  1898. signature[0] = "java.lang.String";
  1899. // Can throw MBeanException wrapping RoleNotFoundException:
  1900. // throw wrapped exception
  1901. //
  1902. // Shall not throw InstanceNotFoundException or ReflectionException
  1903. try {
  1904. result = (Integer)
  1905. (myMBeanServer.invoke(((ObjectName)relObj),
  1906. "getRoleCardinality",
  1907. params,
  1908. signature));
  1909. } catch (InstanceNotFoundException exc1) {
  1910. throw new RuntimeException(exc1.getMessage());
  1911. } catch (ReflectionException exc2) {
  1912. throw new RuntimeException(exc2.getMessage());
  1913. } catch (MBeanException exc3) {
  1914. Exception wrappedExc = exc3.getTargetException();
  1915. if (wrappedExc instanceof RoleNotFoundException) {
  1916. throw ((RoleNotFoundException)wrappedExc);
  1917. } else {
  1918. throw new RuntimeException(wrappedExc.getMessage());
  1919. }
  1920. }
  1921. }
  1922. if (isTraceOn())
  1923. trace("getRoleCardinality: exiting", null);
  1924. return result;
  1925. }
  1926. /**
  1927. * Sets the given role in given relation.
  1928. * <P>Will check the role according to its corresponding role definition
  1929. * provided in relation's relation type
  1930. * <P>The Relation Service will keep track of the change to keep the
  1931. * consistency of relations by handling referenced MBean unregistrations.
  1932. *
  1933. * @param theRelId relation id
  1934. * @param theRole role to be set (name and new value)
  1935. *
  1936. * @exception RelationServiceNotRegisteredException if the Relation
  1937. * Service is not registered in the MBean Server
  1938. * @exception IllegalArgumentException if null parameter
  1939. * @exception RelationNotFoundException if no relation with given id
  1940. * @exception RoleNotFoundException if the role does not exist or is not
  1941. * writable
  1942. * @exception InvalidRoleValueException if value provided for role is not
  1943. * valid:
  1944. * <P>- the number of referenced MBeans in given value is less than
  1945. * expected minimum degree
  1946. * <P>or
  1947. * <P>- the number of referenced MBeans in provided value exceeds expected
  1948. * maximum degree
  1949. * <P>or
  1950. * <P>- one referenced MBean in the value is not an Object of the MBean
  1951. * class expected for that role
  1952. * <P>or
  1953. * <P>- an MBean provided for that role does not exist
  1954. *
  1955. * @see #getRole
  1956. */
  1957. public void setRole(String theRelId,
  1958. Role theRole)
  1959. throws RelationServiceNotRegisteredException,
  1960. IllegalArgumentException,
  1961. RelationNotFoundException,
  1962. RoleNotFoundException,
  1963. InvalidRoleValueException {
  1964. if (theRelId == null || theRole == null) {
  1965. // Revisit [cebro[ Localize message
  1966. String excMsg = "Invalid parameter.";
  1967. throw new IllegalArgumentException(excMsg);
  1968. }
  1969. if (isTraceOn()) {
  1970. String str = new String("theRelId " + theRelId
  1971. + ", theRole " + theRole.toString());
  1972. trace("setRole: entering", str);
  1973. }
  1974. // Can throw RelationServiceNotRegisteredException
  1975. isActive();
  1976. // Can throw a RelationNotFoundException
  1977. Object relObj = getRelation(theRelId);
  1978. if (relObj instanceof RelationSupport) {
  1979. // Internal relation
  1980. // Can throw RoleNotFoundException,
  1981. // InvalidRoleValueException and
  1982. // RelationServiceNotRegisteredException
  1983. //
  1984. // Shall not throw RelationTypeNotFoundException
  1985. // (as relation exists in the RS, its relation type is known)
  1986. try {
  1987. ((RelationSupport)relObj).setRoleInt(theRole,
  1988. true,
  1989. this,
  1990. false);
  1991. } catch (RelationTypeNotFoundException exc) {
  1992. throw new RuntimeException(exc.getMessage());
  1993. }
  1994. } else {
  1995. // Relation MBean
  1996. Object[] params = new Object[1];
  1997. params[0] = theRole;
  1998. String[] signature = new String[1];
  1999. signature[0] = "javax.management.relation.Role";
  2000. // Can throw MBeanException wrapping RoleNotFoundException,
  2001. // InvalidRoleValueException
  2002. //
  2003. // Shall not MBeanException wrapping an MBeanException wrapping
  2004. // RelationTypeNotFoundException, or ReflectionException, or
  2005. // InstanceNotFoundException
  2006. try {
  2007. myMBeanServer.setAttribute(((ObjectName)relObj),
  2008. new Attribute("Role", theRole));
  2009. } catch (InstanceNotFoundException exc1) {
  2010. throw new RuntimeException(exc1.getMessage());
  2011. } catch (ReflectionException exc3) {
  2012. throw new RuntimeException(exc3.getMessage());
  2013. } catch (MBeanException exc2) {
  2014. Exception wrappedExc = exc2.getTargetException();
  2015. if (wrappedExc instanceof RoleNotFoundException) {
  2016. throw ((RoleNotFoundException)wrappedExc);
  2017. } else if (wrappedExc instanceof InvalidRoleValueException) {
  2018. throw ((InvalidRoleValueException)wrappedExc);
  2019. } else {
  2020. throw new RuntimeException(wrappedExc.getMessage());
  2021. }
  2022. } catch (AttributeNotFoundException exc4) {
  2023. throw new RuntimeException(exc4.getMessage());
  2024. } catch (InvalidAttributeValueException exc5) {
  2025. throw new RuntimeException(exc5.getMessage());
  2026. }
  2027. }
  2028. if (isTraceOn())
  2029. trace("setRole: exiting", null);
  2030. return;
  2031. }
  2032. /**
  2033. * Sets the given roles in given relation.
  2034. * <P>Will check the role according to its corresponding role definition
  2035. * provided in relation's relation type
  2036. * <P>The Relation Service keeps track of the changes to keep the
  2037. * consistency of relations by handling referenced MBean unregistrations.
  2038. *
  2039. * @param theRelId relation id
  2040. * @param theRoleList list of roles to be set
  2041. *
  2042. * @return a RoleResult object, including a RoleList (for roles
  2043. * successfully set) and a RoleUnresolvedList (for roles not
  2044. * set).
  2045. *
  2046. * @exception RelationServiceNotRegisteredException if the Relation
  2047. * Service is not registered in the MBean Server
  2048. * @exception IllegalArgumentException if null parameter
  2049. * @exception RelationNotFoundException if no relation with given id
  2050. *
  2051. * @see #getRoles
  2052. */
  2053. public RoleResult setRoles(String theRelId,
  2054. RoleList theRoleList)
  2055. throws RelationServiceNotRegisteredException,
  2056. IllegalArgumentException,
  2057. RelationNotFoundException {
  2058. if (theRelId == null || theRoleList == null) {
  2059. // Revisit [cebro[ Localize message
  2060. String excMsg = "Invalid parameter.";
  2061. throw new IllegalArgumentException(excMsg);
  2062. }
  2063. if (isTraceOn()) {
  2064. String str = new String("theRelId " + theRelId
  2065. + ", theRoleList "
  2066. + theRoleList.toString());
  2067. trace("setRoles: entering", str);
  2068. }
  2069. // Can throw RelationServiceNotRegisteredException
  2070. isActive();
  2071. // Can throw a RelationNotFoundException
  2072. Object relObj = getRelation(theRelId);
  2073. RoleResult result = null;
  2074. if (relObj instanceof RelationSupport) {
  2075. // Internal relation
  2076. // Can throw RelationServiceNotRegisteredException
  2077. //
  2078. // Shall not throw RelationTypeNotFoundException (as relation is
  2079. // known, its relation type exists)
  2080. try {
  2081. result = ((RelationSupport)relObj).setRolesInt(theRoleList,
  2082. true,
  2083. this);
  2084. } catch (RelationTypeNotFoundException exc) {
  2085. throw new RuntimeException(exc.getMessage());
  2086. }
  2087. } else {
  2088. // Relation MBean
  2089. Object[] params = new Object[1];
  2090. params[0] = theRoleList;
  2091. String[] signature = new String[1];
  2092. signature[0] = "javax.management.relation.RoleList";
  2093. // Shall not throw InstanceNotFoundException or an MBeanException
  2094. // or ReflectionException
  2095. try {
  2096. result = (RoleResult)
  2097. (myMBeanServer.invoke(((ObjectName)relObj),
  2098. "setRoles",
  2099. params,
  2100. signature));
  2101. } catch (InstanceNotFoundException exc1) {
  2102. throw new RuntimeException(exc1.getMessage());
  2103. } catch (ReflectionException exc3) {
  2104. throw new RuntimeException(exc3.getMessage());
  2105. } catch (MBeanException exc2) {
  2106. throw new
  2107. RuntimeException((exc2.getTargetException()).getMessage());
  2108. }
  2109. }
  2110. if (isTraceOn())
  2111. trace("setRoles: exiting", null);
  2112. return result;
  2113. }
  2114. /**
  2115. * Retrieves MBeans referenced in the various roles of the relation.
  2116. *
  2117. * @param theRelId relation id
  2118. *
  2119. * @return a HashMap mapping:
  2120. * <P> ObjectName -> ArrayList of String (role
  2121. * names)
  2122. *
  2123. * @exception IllegalArgumentException if null parameter
  2124. * @exception RelationNotFoundException if no relation for given
  2125. * relation id
  2126. */
  2127. public Map getReferencedMBeans(String theRelId)
  2128. throws IllegalArgumentException,
  2129. RelationNotFoundException {
  2130. if (theRelId == null) {
  2131. // Revisit [cebro[ Localize message
  2132. String excMsg = "Invalid parameter.";
  2133. throw new IllegalArgumentException(excMsg);
  2134. }
  2135. if (isTraceOn())
  2136. trace("getReferencedMBeans: entering", theRelId);
  2137. // Can throw a RelationNotFoundException
  2138. Object relObj = getRelation(theRelId);
  2139. HashMap result = null;
  2140. if (relObj instanceof RelationSupport) {
  2141. // Internal relation
  2142. result = (HashMap)(((RelationSupport)relObj).getReferencedMBeans());
  2143. } else {
  2144. // Relation MBean
  2145. // No Exception
  2146. try {
  2147. result = (HashMap)
  2148. (myMBeanServer.getAttribute(((ObjectName)relObj),
  2149. "ReferencedMBeans"));
  2150. } catch (Exception exc) {
  2151. throw new RuntimeException(exc.getMessage());
  2152. }
  2153. }
  2154. if (isTraceOn())
  2155. trace("getReferencedMBeans: exiting", null);
  2156. return result;
  2157. }
  2158. /**
  2159. * Returns name of associated relation type for given relation.
  2160. *
  2161. * @param theRelId relation id
  2162. *
  2163. * @return the name of the associated relation type.
  2164. *
  2165. * @exception IllegalArgumentException if null parameter
  2166. * @exception RelationNotFoundException if no relation for given
  2167. * relation id
  2168. */
  2169. public String getRelationTypeName(String theRelId)
  2170. throws IllegalArgumentException,
  2171. RelationNotFoundException {
  2172. if (theRelId == null) {
  2173. // Revisit [cebro[ Localize message
  2174. String excMsg = "Invalid parameter.";
  2175. throw new IllegalArgumentException(excMsg);
  2176. }
  2177. if (isTraceOn())
  2178. trace("getRelationTypeName: entering", theRelId);
  2179. // Can throw a RelationNotFoundException
  2180. Object relObj = getRelation(theRelId);
  2181. String result = null;
  2182. if (relObj instanceof RelationSupport) {
  2183. // Internal relation
  2184. result = ((RelationSupport)relObj).getRelationTypeName();
  2185. } else {
  2186. // Relation MBean
  2187. // No Exception
  2188. try {
  2189. result = (String)
  2190. (myMBeanServer.getAttribute(((ObjectName)relObj),
  2191. "RelationTypeName"));
  2192. } catch (Exception exc) {
  2193. throw new RuntimeException(exc.getMessage());
  2194. }
  2195. }
  2196. if (isTraceOn())
  2197. trace("getRelationTypeName: exiting", null);
  2198. return result;
  2199. }
  2200. //
  2201. // NotificationListener Interface
  2202. //
  2203. /**
  2204. * Invoked when a JMX notification occurs.
  2205. * Currently handles notifications for unregistration of MBeans, either
  2206. * referenced in a relation role or being a relation itself.
  2207. *
  2208. * @param theNtf The notification.
  2209. * @param theHandback An opaque object which helps the listener to
  2210. * associate information regarding the MBean emitter (can be null).
  2211. */
  2212. public void handleNotification(Notification theNtf,
  2213. Object theHandback) {
  2214. if (theNtf == null) {
  2215. // Revisit [cebro[ Localize message
  2216. String excMsg = "Invalid parameter.";
  2217. throw new IllegalArgumentException(excMsg);
  2218. }
  2219. if (isTraceOn())
  2220. trace("handleNotification: entering", theNtf.toString());
  2221. if (theNtf instanceof MBeanServerNotification) {
  2222. String ntfType = theNtf.getType();
  2223. if (ntfType.equals(
  2224. MBeanServerNotification.UNREGISTRATION_NOTIFICATION )) {
  2225. ObjectName mbeanName =
  2226. ((MBeanServerNotification)theNtf).getMBeanName();
  2227. // Note: use a flag to block access to
  2228. // myRefedMBeanObjName2RelIdsMap only for a quick access
  2229. boolean isRefedMBeanFlg = false;
  2230. synchronized(myRefedMBeanObjName2RelIdsMap) {
  2231. if (myRefedMBeanObjName2RelIdsMap.containsKey(mbeanName)) {
  2232. // Unregistration of a referenced MBean
  2233. synchronized(myUnregNtfList) {
  2234. myUnregNtfList.add(theNtf);
  2235. }
  2236. isRefedMBeanFlg = true;
  2237. }
  2238. if (isRefedMBeanFlg && myPurgeFlg) {
  2239. // Immediate purge
  2240. // Can throw RelationServiceNotRegisteredException
  2241. // but assume that will be fine :)
  2242. try {
  2243. purgeRelations();
  2244. } catch (Exception exc) {
  2245. throw new RuntimeException(exc.getMessage());
  2246. }
  2247. }
  2248. }
  2249. // Note: do both tests as a relation can be an MBean and be
  2250. // itself referenced in another relation :)
  2251. String relId = null;
  2252. synchronized(myRelMBeanObjName2RelIdMap){
  2253. relId = (String)
  2254. (myRelMBeanObjName2RelIdMap.get(mbeanName));
  2255. }
  2256. if (relId != null) {
  2257. // Unregistration of a relation MBean
  2258. // Can throw RelationTypeNotFoundException,
  2259. // RelationServiceNotRegisteredException
  2260. //
  2261. // Shall not throw RelationTypeNotFoundException or
  2262. // InstanceNotFoundException
  2263. try {
  2264. removeRelation(relId);
  2265. } catch (Exception exc) {
  2266. throw new RuntimeException(exc.getMessage());
  2267. }
  2268. }
  2269. }
  2270. }
  2271. if (isTraceOn())
  2272. trace("handleNotification: exiting", null);
  2273. return;
  2274. }
  2275. //
  2276. // NotificationBroadcaster interface
  2277. //
  2278. /**
  2279. * Returns a NotificationInfo object containing the name of the Java class
  2280. * of the notification and the notification types sent.
  2281. */
  2282. public MBeanNotificationInfo[] getNotificationInfo() {
  2283. if (isTraceOn())
  2284. trace("getNotificationInfo: entering", null);
  2285. MBeanNotificationInfo[] ntfInfoArray =
  2286. new MBeanNotificationInfo[1];
  2287. String ntfClass = "javax.management.relation.RelationNotification";
  2288. String[] ntfTypes = new String[] {
  2289. RelationNotification.RELATION_BASIC_CREATION,
  2290. RelationNotification.RELATION_MBEAN_CREATION,
  2291. RelationNotification.RELATION_BASIC_UPDATE,
  2292. RelationNotification.RELATION_MBEAN_UPDATE,
  2293. RelationNotification.RELATION_BASIC_REMOVAL,
  2294. RelationNotification.RELATION_MBEAN_REMOVAL,
  2295. };
  2296. String ntfDesc = "Sent when a relation is created, updated or deleted.";
  2297. MBeanNotificationInfo ntfInfo =
  2298. new MBeanNotificationInfo(ntfTypes, ntfClass, ntfDesc);
  2299. if (isTraceOn())
  2300. trace("getNotificationInfo: exiting", null);
  2301. return new MBeanNotificationInfo[] {ntfInfo};
  2302. }
  2303. //
  2304. // Misc
  2305. //
  2306. // Adds given object as a relation type.
  2307. //
  2308. // -param theRelTypeObj relation type object
  2309. //
  2310. // -exception IllegalArgumentException if null parameter
  2311. // -exception InvalidRelationTypeException if there is already a relation
  2312. // type with that name
  2313. private void addRelationTypeInt(RelationType theRelTypeObj)
  2314. throws IllegalArgumentException,
  2315. InvalidRelationTypeException {
  2316. if (theRelTypeObj == null) {
  2317. // Revisit [cebro] Localize message
  2318. String excMsg = "Invalid parameter.";
  2319. throw new IllegalArgumentException(excMsg);
  2320. }
  2321. if (isDebugOn())
  2322. debug("addRelationTypeInt: entering", null);
  2323. String relTypeName = theRelTypeObj.getRelationTypeName();
  2324. // Checks that there is not already a relation type with that name
  2325. // existing in the Relation Service
  2326. try {
  2327. // Can throw a RelationTypeNotFoundException (in fact should ;)
  2328. RelationType relType = getRelationType(relTypeName);
  2329. if (relType != null) {
  2330. // Revisit [cebro] Localize message
  2331. String excMsg = "There is already a relation type in the Relation Service with name ";
  2332. StringBuffer excMsgStrB = new StringBuffer(excMsg);
  2333. excMsgStrB.append(relTypeName);
  2334. throw new InvalidRelationTypeException(excMsgStrB.toString());
  2335. }
  2336. } catch (RelationTypeNotFoundException exc) {
  2337. // OK : The RelationType could not be found.
  2338. }
  2339. // Adds the relation type
  2340. synchronized(myRelType2ObjMap) {
  2341. myRelType2ObjMap.put(relTypeName, theRelTypeObj);
  2342. }
  2343. if (theRelTypeObj instanceof RelationTypeSupport) {
  2344. ((RelationTypeSupport)theRelTypeObj).setRelationServiceFlag(true);
  2345. }
  2346. if (isDebugOn())
  2347. debug("addRelationTypeInt: exiting", null);
  2348. return;
  2349. }
  2350. // Retrieves relation type with given name
  2351. //
  2352. // -param theRelTypeName expected name of a relation type created in the
  2353. // Relation Service
  2354. //
  2355. // -return RelationType object corresponding to given name
  2356. //
  2357. // -exception IllegalArgumentException if null parameter
  2358. // -exception RelationTypeNotFoundException if no relation type for that
  2359. // name created in Relation Service
  2360. //
  2361. RelationType getRelationType(String theRelTypeName)
  2362. throws IllegalArgumentException,
  2363. RelationTypeNotFoundException {
  2364. if (theRelTypeName == null) {
  2365. // Revisit [cebro[ Localize message
  2366. String excMsg = "Invalid parameter.";
  2367. throw new IllegalArgumentException(excMsg);
  2368. }
  2369. if (isDebugOn())
  2370. debug("getRelationType: entering", theRelTypeName);
  2371. // No null relation type accepted, so can use get()
  2372. RelationType relType = null;
  2373. synchronized(myRelType2ObjMap) {
  2374. relType = (RelationType)(myRelType2ObjMap.get(theRelTypeName));
  2375. }
  2376. if (relType == null) {
  2377. // Revisit [cebro] Localize message
  2378. String excMsg = "No relation type created in the Relation Service with the name ";
  2379. StringBuffer excMsgStrB = new StringBuffer(excMsg);
  2380. excMsgStrB.append(theRelTypeName);
  2381. throw new RelationTypeNotFoundException(excMsgStrB.toString());
  2382. }
  2383. if (isDebugOn())
  2384. debug("getRelationType: exiting", null);
  2385. return relType;
  2386. }
  2387. // Retrieves relation corresponding to given relation id.
  2388. // Returns either:
  2389. // - a RelationSupport object if the relation is internal
  2390. // or
  2391. // - the ObjectName of the corresponding MBean
  2392. //
  2393. // -param theRelId expected relation id
  2394. //
  2395. // -return RelationSupport object or ObjectName of relation with given id
  2396. //
  2397. // -exception IllegalArgumentException if null parameter
  2398. // -exception RelationNotFoundException if no relation for that
  2399. // relation id created in Relation Service
  2400. //
  2401. Object getRelation(String theRelId)
  2402. throws IllegalArgumentException,
  2403. RelationNotFoundException {
  2404. if (theRelId == null) {
  2405. // Revisit [cebro] Localize message
  2406. String excMsg = "Invalid parameter.";
  2407. throw new IllegalArgumentException(excMsg);
  2408. }
  2409. if (isDebugOn())
  2410. debug("getRelation: entering", theRelId);
  2411. // No null relation accepted, so can use get()
  2412. Object rel = null;
  2413. synchronized(myRelId2ObjMap) {
  2414. rel = myRelId2ObjMap.get(theRelId);
  2415. }
  2416. if (rel == null) {
  2417. StringBuffer excMsgStrB = new StringBuffer();
  2418. // Revisit [cebro] Localize message
  2419. String excMsg = "No relation associated to relation id ";
  2420. excMsgStrB.append(excMsg);
  2421. excMsgStrB.append(theRelId);
  2422. throw new RelationNotFoundException(excMsgStrB.toString());
  2423. }
  2424. if (isDebugOn())
  2425. debug("getRelation: exiting", null);
  2426. return rel;
  2427. }
  2428. // Adds a new MBean reference (reference to an ObjectName) in the
  2429. // referenced MBean map (myRefedMBeanObjName2RelIdsMap).
  2430. //
  2431. // -param theObjName ObjectName of new referenced MBean
  2432. // -param theRelId relation id of the relation where the MBean is
  2433. // referenced
  2434. // -param theRoleName name of the role where the MBean is referenced
  2435. //
  2436. // -return boolean:
  2437. // - true if the MBean was not referenced before, so really a new
  2438. // reference
  2439. // - false else
  2440. //
  2441. // -exception IllegalArgumentException if null parameter
  2442. private boolean addNewMBeanReference(ObjectName theObjName,
  2443. String theRelId,
  2444. String theRoleName)
  2445. throws IllegalArgumentException {
  2446. if (theObjName == null ||
  2447. theRelId == null ||
  2448. theRoleName == null) {
  2449. // Revisit [cebro] Localize message
  2450. String excMsg = "Invalid parameter.";
  2451. throw new IllegalArgumentException(excMsg);
  2452. }
  2453. if (isDebugOn()) {
  2454. String str = new String("theObjName " + theObjName.toString()
  2455. + ", theRelId " + theRelId
  2456. + ", theRoleName " + theRoleName);
  2457. debug("addNewMBeanReference: entering", str);
  2458. }
  2459. boolean isNewFlg = false;
  2460. synchronized(myRefedMBeanObjName2RelIdsMap) {
  2461. // Checks if the MBean was already referenced
  2462. // No null value allowed, use get() directly
  2463. HashMap mbeanRefMap = (HashMap)
  2464. (myRefedMBeanObjName2RelIdsMap.get(theObjName));
  2465. if (mbeanRefMap == null) {
  2466. // MBean not referenced in any relation yet
  2467. isNewFlg = true;
  2468. // List of roles where the MBean is referenced in given
  2469. // relation
  2470. ArrayList roleNames = new ArrayList();
  2471. roleNames.add(theRoleName);
  2472. // Map of relations where the MBean is referenced
  2473. mbeanRefMap = new HashMap();
  2474. mbeanRefMap.put(theRelId, roleNames);
  2475. myRefedMBeanObjName2RelIdsMap.put(theObjName, mbeanRefMap);
  2476. } else {
  2477. // MBean already referenced in at least another relation
  2478. // Checks if already referenced in another role in current
  2479. // relation
  2480. ArrayList roleNames = (ArrayList)(mbeanRefMap.get(theRelId));
  2481. if (roleNames == null) {
  2482. // MBean not referenced in current relation
  2483. // List of roles where the MBean is referenced in given
  2484. // relation
  2485. roleNames = new ArrayList();
  2486. roleNames.add(theRoleName);
  2487. // Adds new reference done in current relation
  2488. mbeanRefMap.put(theRelId, roleNames);
  2489. } else {
  2490. // MBean already referenced in current relation in another
  2491. // role
  2492. // Adds new reference done
  2493. roleNames.add(theRoleName);
  2494. }
  2495. }
  2496. }
  2497. if (isDebugOn())
  2498. debug("addNewMBeanReference: exiting", null);
  2499. return isNewFlg;
  2500. }
  2501. // Removes an obsolete MBean reference (reference to an ObjectName) in
  2502. // the referenced MBean map (myRefedMBeanObjName2RelIdsMap).
  2503. //
  2504. // -param theObjName ObjectName of MBean no longer referenced
  2505. // -param theRelId relation id of the relation where the MBean was
  2506. // referenced
  2507. // -param theRoleName name of the role where the MBean was referenced
  2508. // -param theAllRolesFlg flag, if true removes reference to MBean for all
  2509. // roles in the relation, not only for the one above
  2510. //
  2511. // -return boolean:
  2512. // - true if the MBean is no longer reference in any relation
  2513. // - false else
  2514. //
  2515. // -exception IllegalArgumentException if null parameter
  2516. private boolean removeMBeanReference(ObjectName theObjName,
  2517. String theRelId,
  2518. String theRoleName,
  2519. boolean theAllRolesFlg)
  2520. throws IllegalArgumentException {
  2521. if (theObjName == null ||
  2522. theRelId == null ||
  2523. theRoleName == null) {
  2524. // Revisit [cebro] Localize message
  2525. String excMsg = "Invalid parameter.";
  2526. throw new IllegalArgumentException(excMsg);
  2527. }
  2528. if (isDebugOn()) {
  2529. String str = new String("theObjName " + theObjName.toString()
  2530. + ", theRelId " + theRelId
  2531. + ", theRoleName " + theRoleName
  2532. + ", theAllRolesFlg " + theAllRolesFlg);
  2533. debug("removeMBeanReference: entering", str);
  2534. }
  2535. boolean noLongerRefFlg = false;
  2536. synchronized(myRefedMBeanObjName2RelIdsMap) {
  2537. // Retrieves the set of relations (designed via their relation ids)
  2538. // where the MBean is referenced
  2539. // Note that it is possible that the MBean has already been removed
  2540. // from the internal map: this is the case when the MBean is
  2541. // unregistered, the role is updated, then we arrive here.
  2542. HashMap mbeanRefMap = (HashMap)
  2543. (myRefedMBeanObjName2RelIdsMap.get(theObjName));
  2544. if (mbeanRefMap == null) {
  2545. // The MBean is no longer referenced
  2546. if (isDebugOn())
  2547. debug("removeMBeanReference: exiting", null);
  2548. return true;
  2549. }
  2550. ArrayList roleNames = new ArrayList();
  2551. if (!theAllRolesFlg) {
  2552. // Now retrieves the roles of current relation where the MBean
  2553. // was referenced
  2554. roleNames = (ArrayList)(mbeanRefMap.get(theRelId));
  2555. // Removes obsolete reference to role
  2556. int obsRefIdx = roleNames.indexOf(theRoleName);
  2557. if (obsRefIdx != -1) {
  2558. roleNames.remove(obsRefIdx);
  2559. }
  2560. }
  2561. // Checks if there is still at least one role in current relation
  2562. // where the MBean is referenced
  2563. if (roleNames.isEmpty() || theAllRolesFlg) {
  2564. // MBean no longer referenced in current relation: removes
  2565. // entry
  2566. mbeanRefMap.remove(theRelId);
  2567. }
  2568. // Checks if the MBean is still referenced in at least on relation
  2569. if (mbeanRefMap.isEmpty()) {
  2570. // MBean no longer referenced in any relation: removes entry
  2571. myRefedMBeanObjName2RelIdsMap.remove(theObjName);
  2572. noLongerRefFlg = true;
  2573. }
  2574. }
  2575. if (isDebugOn())
  2576. debug("removeMBeanReference: exiting", null);
  2577. return noLongerRefFlg;
  2578. }
  2579. // Updates the listener registered to the MBean Server to be informed of
  2580. // referenced MBean unregistrations
  2581. //
  2582. // -param theNewRefList ArrayList of ObjectNames for new references done
  2583. // to MBeans (can be null)
  2584. // -param theObsRefList ArrayList of ObjectNames for obsolete references
  2585. // to MBeans (can be null)
  2586. //
  2587. // -exception RelationServiceNotRegisteredException if the Relation
  2588. // Service is not registered in the MBean Server.
  2589. private void updateUnregistrationListener(List theNewRefList,
  2590. List theObsRefList)
  2591. throws RelationServiceNotRegisteredException {
  2592. if (theNewRefList != null && theObsRefList != null) {
  2593. if (theNewRefList.isEmpty() && theObsRefList.isEmpty()) {
  2594. // Nothing to do :)
  2595. return;
  2596. }
  2597. }
  2598. if (isDebugOn()) {
  2599. StringBuffer strB = new StringBuffer();
  2600. if (theNewRefList != null) {
  2601. strB.append("theNewRefList " + theNewRefList.toString());
  2602. }
  2603. if (theObsRefList != null) {
  2604. strB.append(", theObsRefList" + theObsRefList.toString());
  2605. }
  2606. debug("updateUnregistrationListener: entering", strB.toString());
  2607. }
  2608. // Can throw RelationServiceNotRegisteredException
  2609. isActive();
  2610. if (theNewRefList != null || theObsRefList != null) {
  2611. boolean newListenerFlg = false;
  2612. if (myUnregNtfFilter == null) {
  2613. // Initialise it to be able to synchronise it :)
  2614. myUnregNtfFilter = new MBeanServerNotificationFilter();
  2615. newListenerFlg = true;
  2616. }
  2617. synchronized(myUnregNtfFilter) {
  2618. // Enables ObjectNames in theNewRefList
  2619. if (theNewRefList != null) {
  2620. for (Iterator newRefIter = theNewRefList.iterator();
  2621. newRefIter.hasNext();) {
  2622. ObjectName newObjName = (ObjectName)
  2623. (newRefIter.next());
  2624. myUnregNtfFilter.enableObjectName(newObjName);
  2625. }
  2626. }
  2627. if (theObsRefList != null) {
  2628. // Disables ObjectNames in theObsRefList
  2629. for (Iterator obsRefIter = theObsRefList.iterator();
  2630. obsRefIter.hasNext();) {
  2631. ObjectName obsObjName = (ObjectName)
  2632. (obsRefIter.next());
  2633. myUnregNtfFilter.disableObjectName(obsObjName);
  2634. }
  2635. }
  2636. // Creates ObjectName of the MBeanServerDelegate handling the
  2637. // notifications
  2638. ObjectName mbeanServerDelegateName = null;
  2639. try {
  2640. mbeanServerDelegateName =
  2641. new ObjectName(ServiceName.DELEGATE);
  2642. } catch (MalformedObjectNameException exc) {
  2643. // OK : Should never happen...
  2644. }
  2645. // Under test
  2646. if (newListenerFlg) {
  2647. try {
  2648. myMBeanServer.addNotificationListener(
  2649. mbeanServerDelegateName,
  2650. this,
  2651. myUnregNtfFilter,
  2652. null);
  2653. } catch (InstanceNotFoundException exc) {
  2654. throw new
  2655. RelationServiceNotRegisteredException(exc.getMessage());
  2656. }
  2657. }
  2658. // End test
  2659. // if (!newListenerFlg) {
  2660. // The Relation Service was already registered as a
  2661. // listener:
  2662. // removes it
  2663. // Shall not throw InstanceNotFoundException (as the
  2664. // MBean Server Delegate is expected to exist) or
  2665. // ListenerNotFoundException (as it has been checked above
  2666. // that the Relation Service is registered)
  2667. // try {
  2668. // myMBeanServer.removeNotificationListener(
  2669. // mbeanServerDelegateName,
  2670. // this);
  2671. // } catch (InstanceNotFoundException exc1) {
  2672. // throw new RuntimeException(exc1.getMessage());
  2673. // } catch (ListenerNotFoundException exc2) {
  2674. // throw new
  2675. // RelationServiceNotRegisteredException(exc2.getMessage());
  2676. // }
  2677. // }
  2678. // Adds Relation Service with current filter
  2679. // Can throw InstanceNotFoundException if the Relation
  2680. // Service is not registered, to be transformed into
  2681. // RelationServiceNotRegisteredException
  2682. //
  2683. // Assume that there will not be any InstanceNotFoundException
  2684. // for the MBean Server Delegate :)
  2685. // try {
  2686. // myMBeanServer.addNotificationListener(
  2687. // mbeanServerDelegateName,
  2688. // this,
  2689. // myUnregNtfFilter,
  2690. // null);
  2691. // } catch (InstanceNotFoundException exc) {
  2692. // throw new
  2693. // RelationServiceNotRegisteredException(exc.getMessage());
  2694. // }
  2695. }
  2696. }
  2697. if (isDebugOn())
  2698. debug("updateUnregistrationListener: exiting", null);
  2699. return;
  2700. }
  2701. // Adds a relation (being either a RelationSupport object or an MBean
  2702. // referenced using its ObjectName) in the Relation Service.
  2703. // Will send a notification RelationNotification with type:
  2704. // - RelationNotification.RELATION_BASIC_CREATION for internal relation
  2705. // creation
  2706. // - RelationNotification.RELATION_MBEAN_CREATION for an MBean being added
  2707. // as a relation.
  2708. //
  2709. // -param theRelBaseFlg flag true if the relation is a RelationSupport
  2710. // object, false if it is an MBean
  2711. // -param theRelObj RelationSupport object (if relation is internal)
  2712. // -param theRelObjName ObjectName of the MBean to be added as a relation
  2713. // (only for the relation MBean)
  2714. // -param theRelId relation identifier, to uniquely identify the relation
  2715. // inside the Relation Service
  2716. // -param theRelTypeName name of the relation type (has to be created
  2717. // in the Relation Service)
  2718. // -param theRoleList role list to initialize roles of the relation
  2719. // (can be null)
  2720. //
  2721. // -exception IllegalArgumentException if null paramater
  2722. // -exception RelationServiceNotRegisteredException if the Relation
  2723. // Service is not registered in the MBean Server
  2724. // -exception RoleNotFoundException if a value is provided for a role
  2725. // that does not exist in the relation type
  2726. // -exception InvalidRelationIdException if relation id already used
  2727. // -exception RelationTypeNotFoundException if relation type not known in
  2728. // Relation Service
  2729. // -exception InvalidRoleValueException if:
  2730. // - the same role name is used for two different roles
  2731. // - the number of referenced MBeans in given value is less than
  2732. // expected minimum degree
  2733. // - the number of referenced MBeans in provided value exceeds expected
  2734. // maximum degree
  2735. // - one referenced MBean in the value is not an Object of the MBean
  2736. // class expected for that role
  2737. // - an MBean provided for that role does not exist
  2738. private void addRelationInt(boolean theRelBaseFlg,
  2739. RelationSupport theRelObj,
  2740. ObjectName theRelObjName,
  2741. String theRelId,
  2742. String theRelTypeName,
  2743. RoleList theRoleList)
  2744. throws IllegalArgumentException,
  2745. RelationServiceNotRegisteredException,
  2746. RoleNotFoundException,
  2747. InvalidRelationIdException,
  2748. RelationTypeNotFoundException,
  2749. InvalidRoleValueException {
  2750. if (theRelId == null ||
  2751. theRelTypeName == null ||
  2752. (theRelBaseFlg &&
  2753. (theRelObj == null ||
  2754. theRelObjName != null)) ||
  2755. (!theRelBaseFlg &&
  2756. (theRelObjName == null ||
  2757. theRelObj != null))) {
  2758. // Revisit [cebro[ Localize message
  2759. String excMsg = "Invalid parameter.";
  2760. throw new IllegalArgumentException(excMsg);
  2761. }
  2762. if (isDebugOn()) {
  2763. StringBuffer strB = new StringBuffer("theRelBaseFlg "
  2764. + theRelBaseFlg
  2765. + ", theRelId " + theRelId
  2766. + ", theRelTypeName "
  2767. + theRelTypeName);
  2768. if (theRelObjName != null) {
  2769. strB.append(", theRelObjName " + theRelObjName.toString());
  2770. }
  2771. if (theRoleList != null) {
  2772. strB.append(", theRoleList " + theRoleList.toString());
  2773. }
  2774. debug("addRelationInt: entering", strB.toString());
  2775. }
  2776. // Can throw RelationServiceNotRegisteredException
  2777. isActive();
  2778. // Checks if there is already a relation with given id
  2779. try {
  2780. // Can throw a RelationNotFoundException (in fact should :)
  2781. Object rel = getRelation(theRelId);
  2782. if (rel != null) {
  2783. // There is already a relation with that id
  2784. // Revisit [cebro] Localize message
  2785. String excMsg = "There is already a relation with id ";
  2786. StringBuffer excMsgStrB = new StringBuffer(excMsg);
  2787. excMsgStrB.append(theRelId);
  2788. throw new InvalidRelationIdException(excMsgStrB.toString());
  2789. }
  2790. } catch (RelationNotFoundException exc) {
  2791. // OK : The Relation could not be found.
  2792. }
  2793. // Retrieves the relation type
  2794. // Can throw RelationTypeNotFoundException
  2795. RelationType relType = getRelationType(theRelTypeName);
  2796. // Checks that each provided role conforms to its role info provided in
  2797. // the relation type
  2798. // First retrieves a local list of the role infos of the relation type
  2799. // to see which roles have not been initialized
  2800. // Note: no need to test if list not null before cloning, not allowed
  2801. // to have an empty relation type.
  2802. ArrayList roleInfoList = (ArrayList)
  2803. (((ArrayList)(relType.getRoleInfos())).clone());
  2804. if (theRoleList != null) {
  2805. for (Iterator roleIter = theRoleList.iterator();
  2806. roleIter.hasNext();) {
  2807. Role currRole = (Role)(roleIter.next());
  2808. String currRoleName = currRole.getRoleName();
  2809. ArrayList currRoleValue = (ArrayList)
  2810. (currRole.getRoleValue());
  2811. // Retrieves corresponding role info
  2812. // Can throw a RoleInfoNotFoundException to be converted into a
  2813. // RoleNotFoundException
  2814. RoleInfo roleInfo = null;
  2815. try {
  2816. roleInfo = relType.getRoleInfo(currRoleName);
  2817. } catch (RoleInfoNotFoundException exc) {
  2818. throw new RoleNotFoundException(exc.getMessage());
  2819. }
  2820. // Checks that role conforms to role info,
  2821. Integer status = checkRoleInt(2,
  2822. currRoleName,
  2823. currRoleValue,
  2824. roleInfo,
  2825. false);
  2826. int pbType = status.intValue();
  2827. if (pbType != 0) {
  2828. // A problem has occured: throws appropriate exception
  2829. // here InvalidRoleValueException
  2830. throwRoleProblemException(pbType, currRoleName);
  2831. }
  2832. // Removes role info for that list from list of role infos for
  2833. // roles to be defaulted
  2834. int roleInfoIdx = roleInfoList.indexOf(roleInfo);
  2835. // Note: no need to check if != -1, MUST be there :)
  2836. roleInfoList.remove(roleInfoIdx);
  2837. }
  2838. }
  2839. // Initializes roles not initialized by theRoleList
  2840. // Can throw InvalidRoleValueException
  2841. initialiseMissingRoles(theRelBaseFlg,
  2842. theRelObj,
  2843. theRelObjName,
  2844. theRelId,
  2845. theRelTypeName,
  2846. roleInfoList);
  2847. // Creation of relation successfull!!!!
  2848. // Updates internal maps
  2849. // Relation id to object map
  2850. synchronized(myRelId2ObjMap) {
  2851. if (theRelBaseFlg) {
  2852. // Note: do not clone relation object, created by us :)
  2853. myRelId2ObjMap.put(theRelId, theRelObj);
  2854. } else {
  2855. myRelId2ObjMap.put(theRelId, theRelObjName);
  2856. }
  2857. }
  2858. // Relation id to relation type name map
  2859. synchronized(myRelId2RelTypeMap) {
  2860. myRelId2RelTypeMap.put(theRelId,
  2861. theRelTypeName);
  2862. }
  2863. // Relation type to relation id map
  2864. synchronized(myRelType2RelIdsMap) {
  2865. ArrayList relIdList = (ArrayList)
  2866. (myRelType2RelIdsMap.get(theRelTypeName));
  2867. boolean firstRelFlg = false;
  2868. if (relIdList == null) {
  2869. firstRelFlg = true;
  2870. relIdList = new ArrayList();
  2871. }
  2872. relIdList.add(theRelId);
  2873. if (firstRelFlg) {
  2874. myRelType2RelIdsMap.put(theRelTypeName, relIdList);
  2875. }
  2876. }
  2877. // Referenced MBean to relation id map
  2878. // Only role list parameter used, as default initialization of roles
  2879. // done automatically in initialiseMissingRoles() sets each
  2880. // uninitialized role to an empty value.
  2881. for (Iterator roleIter = theRoleList.iterator();
  2882. roleIter.hasNext();) {
  2883. Role currRole = (Role)(roleIter.next());
  2884. // Creates a dummy empty ArrayList of ObjectNames to be the old
  2885. // role value :)
  2886. ArrayList dummyList = new ArrayList();
  2887. // Will not throw a RelationNotFoundException (as the RelId2Obj map
  2888. // has been updated above) so catch it :)
  2889. try {
  2890. updateRoleMap(theRelId, currRole, dummyList);
  2891. } catch (RelationNotFoundException exc) {
  2892. // OK : The Relation could not be found.
  2893. }
  2894. }
  2895. // Sends a notification for relation creation
  2896. // Will not throw RelationNotFoundException so catch it :)
  2897. try {
  2898. sendRelationCreationNotification(theRelId);
  2899. } catch (RelationNotFoundException exc) {
  2900. // OK : The Relation could not be found.
  2901. }
  2902. if (isDebugOn())
  2903. debug("addRelationInt: exiting", null);
  2904. return;
  2905. }
  2906. // Checks that given role conforms to given role info.
  2907. //
  2908. // -param theChkType type of check:
  2909. // - 1: read, just check read access
  2910. // - 2: write, check value and write access if theWriteChkFlg
  2911. // -param theRoleName role name
  2912. // -param theRoleValue role value
  2913. // -param theRoleInfo corresponding role info
  2914. // -param theWriteChkFlg boolean to specify a current write access and
  2915. // to check it
  2916. //
  2917. // -return Integer with value:
  2918. // - 0: ok
  2919. // - RoleStatus.NO_ROLE_WITH_NAME
  2920. // - RoleStatus.ROLE_NOT_READABLE
  2921. // - RoleStatus.ROLE_NOT_WRITABLE
  2922. // - RoleStatus.LESS_THAN_MIN_ROLE_DEGREE
  2923. // - RoleStatus.MORE_THAN_MAX_ROLE_DEGREE
  2924. // - RoleStatus.REF_MBEAN_OF_INCORRECT_CLASS
  2925. // - RoleStatus.REF_MBEAN_NOT_REGISTERED
  2926. //
  2927. // -exception IllegalArgumentException if null parameter
  2928. private Integer checkRoleInt(int theChkType,
  2929. String theRoleName,
  2930. List theRoleValue,
  2931. RoleInfo theRoleInfo,
  2932. boolean theWriteChkFlg)
  2933. throws IllegalArgumentException {
  2934. if (theRoleName == null ||
  2935. theRoleInfo == null ||
  2936. (theChkType == 2 && theRoleValue == null)) {
  2937. // Revisit [cebro] Localize message
  2938. String excMsg = "Invalid parameter.";
  2939. throw new IllegalArgumentException(excMsg);
  2940. }
  2941. if (isDebugOn()) {
  2942. StringBuffer strB = new StringBuffer("theChkType "
  2943. + theChkType
  2944. + ", theRoleName "
  2945. + theRoleName
  2946. + ", theRoleInfo "
  2947. + theRoleInfo.toString()
  2948. + ", theWriteChkFlg "
  2949. + theWriteChkFlg);
  2950. if (theRoleValue != null) {
  2951. strB.append(", theRoleValue " + theRoleValue.toString());
  2952. }
  2953. debug("checkRoleInt: entering", strB.toString());
  2954. }
  2955. // Compares names
  2956. String expName = theRoleInfo.getName();
  2957. if (!(theRoleName.equals(expName))) {
  2958. if (isDebugOn())
  2959. debug("checkRoleInt: exiting", null);
  2960. return new Integer(RoleStatus.NO_ROLE_WITH_NAME);
  2961. }
  2962. // Checks read access if required
  2963. if (theChkType == 1) {
  2964. boolean isReadable = theRoleInfo.isReadable();
  2965. if (!isReadable) {
  2966. if (isDebugOn())
  2967. debug("checkRoleInt: exiting", null);
  2968. return new Integer(RoleStatus.ROLE_NOT_READABLE);
  2969. } else {
  2970. // End of check :)
  2971. if (isDebugOn())
  2972. debug("checkRoleInt: exiting", null);
  2973. return new Integer(0);
  2974. }
  2975. }
  2976. // Checks write access if required
  2977. if (theWriteChkFlg) {
  2978. boolean isWritable = theRoleInfo.isWritable();
  2979. if (!isWritable) {
  2980. if (isDebugOn())
  2981. debug("checkRoleInt: exiting", null);
  2982. return new Integer(RoleStatus.ROLE_NOT_WRITABLE);
  2983. }
  2984. }
  2985. int refNbr = theRoleValue.size();
  2986. // Checks minimum cardinality
  2987. boolean chkMinFlg = theRoleInfo.checkMinDegree(refNbr);
  2988. if (!chkMinFlg) {
  2989. if (isDebugOn())
  2990. debug("checkRoleInt: exiting", null);
  2991. return new Integer(RoleStatus.LESS_THAN_MIN_ROLE_DEGREE);
  2992. }
  2993. // Checks maximum cardinality
  2994. boolean chkMaxFlg = theRoleInfo.checkMaxDegree(refNbr);
  2995. if (!chkMaxFlg) {
  2996. if (isDebugOn())
  2997. debug("checkRoleInt: exiting", null);
  2998. return new Integer(RoleStatus.MORE_THAN_MAX_ROLE_DEGREE);
  2999. }
  3000. // Verifies that each referenced MBean is registered in the MBean
  3001. // Server and that it is an instance of the class specified in the
  3002. // role info, or of a subclass of it
  3003. // Note that here again this is under the assumption that
  3004. // referenced MBeans, relation MBeans and the Relation Service are
  3005. // registered in the same MBean Server.
  3006. String expClassName = theRoleInfo.getRefMBeanClassName();
  3007. for (Iterator refMBeanIter = theRoleValue.iterator();
  3008. refMBeanIter.hasNext();) {
  3009. ObjectName currObjName = (ObjectName)(refMBeanIter.next());
  3010. // Checks it is registered
  3011. if (currObjName == null) {
  3012. if (isDebugOn())
  3013. debug("checkRoleInt: exiting", null);
  3014. return new Integer(RoleStatus.REF_MBEAN_NOT_REGISTERED);
  3015. }
  3016. // Checks if it is of the correct class
  3017. // Can throw an InstanceNotFoundException, if MBean not registered
  3018. try {
  3019. boolean classSts = myMBeanServer.isInstanceOf(currObjName,
  3020. expClassName);
  3021. if (!classSts) {
  3022. if (isDebugOn())
  3023. debug("checkRoleInt: exiting", null);
  3024. return new Integer(RoleStatus.REF_MBEAN_OF_INCORRECT_CLASS);
  3025. }
  3026. } catch (InstanceNotFoundException exc) {
  3027. if (isDebugOn())
  3028. debug("checkRoleInt: exiting", null);
  3029. return new Integer(RoleStatus.REF_MBEAN_NOT_REGISTERED);
  3030. }
  3031. }
  3032. if (isDebugOn())
  3033. debug("checkRoleInt: exiting", null);
  3034. return new Integer(0);
  3035. }
  3036. // Initialises roles associated to given role infos to default value (empty
  3037. // ArrayList of ObjectNames) in given relation.
  3038. // It will succeed for every role except if the role info has a minimum
  3039. // cardinality greater than 0. In that case, an InvalidRoleValueException
  3040. // will be raised.
  3041. //
  3042. // -param theRelBaseFlg flag true if the relation is a RelationSupport
  3043. // object, false if it is an MBean
  3044. // -param theRelObj RelationSupport object (if relation is internal)
  3045. // -param theRelObjName ObjectName of the MBean to be added as a relation
  3046. // (only for the relation MBean)
  3047. // -param theRelId relation id
  3048. // -param theRelTypeName name of the relation type (has to be created
  3049. // in the Relation Service)
  3050. // -param theRoleInfoList list of role infos for roles to be defaulted
  3051. //
  3052. // -exception IllegalArgumentException if null paramater
  3053. // -exception RelationServiceNotRegisteredException if the Relation
  3054. // Service is not registered in the MBean Server
  3055. // -exception InvalidRoleValueException if role must have a non-empty
  3056. // value
  3057. // Revisit [cebro] Handle CIM qualifiers as REQUIRED to detect roles which
  3058. // should have been initialized by the user
  3059. private void initialiseMissingRoles(boolean theRelBaseFlg,
  3060. RelationSupport theRelObj,
  3061. ObjectName theRelObjName,
  3062. String theRelId,
  3063. String theRelTypeName,
  3064. List theRoleInfoList)
  3065. throws IllegalArgumentException,
  3066. RelationServiceNotRegisteredException,
  3067. InvalidRoleValueException {
  3068. if ((theRelBaseFlg &&
  3069. (theRelObj == null ||
  3070. theRelObjName != null)) ||
  3071. (!theRelBaseFlg &&
  3072. (theRelObjName == null ||
  3073. theRelObj != null)) ||
  3074. theRelId == null ||
  3075. theRelTypeName == null ||
  3076. theRoleInfoList == null) {
  3077. // Revisit [cebro[ Localize message
  3078. String excMsg = "Invalid parameter.";
  3079. throw new IllegalArgumentException(excMsg);
  3080. }
  3081. if (isDebugOn()) {
  3082. StringBuffer strB =
  3083. new StringBuffer("theRelBaseFlg " + theRelBaseFlg
  3084. + ", theRelId " + theRelId
  3085. + ", theRelTypeName " + theRelTypeName
  3086. + ", theRoleInfoList " + theRoleInfoList);
  3087. if (theRelObjName != null) {
  3088. strB.append(theRelObjName.toString());
  3089. }
  3090. debug("initialiseMissingRoles: entering", strB.toString());
  3091. }
  3092. // Can throw RelationServiceNotRegisteredException
  3093. isActive();
  3094. // For each role info (corresponding to a role not initialized by the
  3095. // role list provided by the user), try to set in the relation a role
  3096. // with an empty list of ObjectNames.
  3097. // A check is performed to verify that the role can be set to an
  3098. // empty value, according to its minimum cardinality
  3099. for (Iterator roleInfoIter = theRoleInfoList.iterator();
  3100. roleInfoIter.hasNext();) {
  3101. RoleInfo currRoleInfo = (RoleInfo)(roleInfoIter.next());
  3102. String roleName = currRoleInfo.getName();
  3103. // Creates an empty value
  3104. ArrayList emptyValue = new ArrayList();
  3105. // Creates a role
  3106. Role role = new Role(roleName, emptyValue);
  3107. if (theRelBaseFlg) {
  3108. // Internal relation
  3109. // Can throw InvalidRoleValueException
  3110. //
  3111. // Will not throw RoleNotFoundException (role to be
  3112. // initialized), or RelationNotFoundException, or
  3113. // RelationTypeNotFoundException
  3114. try {
  3115. theRelObj.setRoleInt(role, true, this, false);
  3116. } catch (RoleNotFoundException exc1) {
  3117. throw new RuntimeException(exc1.getMessage());
  3118. } catch (RelationNotFoundException exc2) {
  3119. throw new RuntimeException(exc2.getMessage());
  3120. } catch (RelationTypeNotFoundException exc3) {
  3121. throw new RuntimeException(exc3.getMessage());
  3122. }
  3123. } else {
  3124. // Relation is an MBean
  3125. // Use standard setRole()
  3126. Object[] params = new Object[1];
  3127. params[0] = role;
  3128. String[] signature = new String[1];
  3129. signature[0] = "javax.management.relation.Role";
  3130. // Can throw MBeanException wrapping
  3131. // InvalidRoleValueException. Returns the target exception to
  3132. // be homogeneous.
  3133. //
  3134. // Will not throw MBeanException (wrapping
  3135. // RoleNotFoundException or MBeanException) or
  3136. // InstanceNotFoundException, or ReflectionException
  3137. //
  3138. // Again here the assumption is that the Relation Service and
  3139. // the relation MBeans are registered in the same MBean Server.
  3140. try {
  3141. myMBeanServer.setAttribute(theRelObjName,
  3142. new Attribute("Role", role));
  3143. } catch (InstanceNotFoundException exc1) {
  3144. throw new RuntimeException(exc1.getMessage());
  3145. } catch (ReflectionException exc3) {
  3146. throw new RuntimeException(exc3.getMessage());
  3147. } catch (MBeanException exc2) {
  3148. Exception wrappedExc = exc2.getTargetException();
  3149. if (wrappedExc instanceof InvalidRoleValueException) {
  3150. throw ((InvalidRoleValueException)wrappedExc);
  3151. } else {
  3152. throw new RuntimeException(wrappedExc.getMessage());
  3153. }
  3154. } catch (AttributeNotFoundException exc4) {
  3155. throw new RuntimeException(exc4.getMessage());
  3156. } catch (InvalidAttributeValueException exc5) {
  3157. throw new RuntimeException(exc5.getMessage());
  3158. }
  3159. }
  3160. }
  3161. if (isDebugOn())
  3162. debug("initializeMissingRoles: exiting", null);
  3163. return;
  3164. }
  3165. // Throws an exception corresponding to a given problem type
  3166. //
  3167. // -param thePbType possible problem, defined in RoleUnresolved
  3168. // -param theRoleName role name
  3169. //
  3170. // -exception IllegalArgumentException if null parameter
  3171. // -exception RoleNotFoundException for problems:
  3172. // - NO_ROLE_WITH_NAME
  3173. // - ROLE_NOT_READABLE
  3174. // - ROLE_NOT_WRITABLE
  3175. // -exception InvalidRoleValueException for problems:
  3176. // - LESS_THAN_MIN_ROLE_DEGREE
  3177. // - MORE_THAN_MAX_ROLE_DEGREE
  3178. // - REF_MBEAN_OF_INCORRECT_CLASS
  3179. // - REF_MBEAN_NOT_REGISTERED
  3180. static void throwRoleProblemException(int thePbType,
  3181. String theRoleName)
  3182. throws IllegalArgumentException,
  3183. RoleNotFoundException,
  3184. InvalidRoleValueException {
  3185. if (theRoleName == null) {
  3186. // Revisit [cebro] Localize message
  3187. String excMsg = "Invalid parameter.";
  3188. throw new IllegalArgumentException(excMsg);
  3189. }
  3190. // Exception type: 1 = RoleNotFoundException
  3191. // 2 = InvalidRoleValueException
  3192. int excType = 0;
  3193. String excMsgPart = null;
  3194. // Revisit [cebro] Localize messages
  3195. switch (thePbType) {
  3196. case RoleStatus.NO_ROLE_WITH_NAME:
  3197. excMsgPart = " does not exist in relation.";
  3198. excType = 1;
  3199. break;
  3200. case RoleStatus.ROLE_NOT_READABLE:
  3201. excMsgPart = " is not readable.";
  3202. excType = 1;
  3203. break;
  3204. case RoleStatus.ROLE_NOT_WRITABLE:
  3205. excMsgPart = " is not writable.";
  3206. excType = 1;
  3207. break;
  3208. case RoleStatus.LESS_THAN_MIN_ROLE_DEGREE:
  3209. excMsgPart = " has a number of MBean references less than the expected minimum degree.";
  3210. excType = 2;
  3211. break;
  3212. case RoleStatus.MORE_THAN_MAX_ROLE_DEGREE:
  3213. excMsgPart = " has a number of MBean references greater than the expected maximum degree.";
  3214. excType = 2;
  3215. break;
  3216. case RoleStatus.REF_MBEAN_OF_INCORRECT_CLASS:
  3217. excMsgPart = " has an MBean reference to an MBean not of the expected class of references for that role.";
  3218. excType = 2;
  3219. break;
  3220. case RoleStatus.REF_MBEAN_NOT_REGISTERED:
  3221. excMsgPart = " has a reference to null or to an MBean not registered.";
  3222. excType = 2;
  3223. break;
  3224. }
  3225. // No default as we must have been in one of those cases
  3226. StringBuffer excMsgStrB = new StringBuffer(theRoleName);
  3227. excMsgStrB.append(excMsgPart);
  3228. String excMsg = excMsgStrB.toString();
  3229. if (excType == 1) {
  3230. throw new RoleNotFoundException(excMsg);
  3231. } else if (excType == 2) {
  3232. throw new InvalidRoleValueException(excMsg);
  3233. }
  3234. }
  3235. // Sends a notification of given type, with given parameters
  3236. //
  3237. // -param theIntNtfType integer to represent notification type:
  3238. // - 1 : create
  3239. // - 2 : update
  3240. // - 3 : delete
  3241. // -param theMsg human-readable message
  3242. // -param theRelId relation id of the created/updated/deleted relation
  3243. // -param theUnregMBeanList list of ObjectNames of referenced MBeans
  3244. // expected to be unregistered due to relation removal (only for removal,
  3245. // due to CIM qualifiers, can be null)
  3246. // -param theRoleName role name
  3247. // -param theRoleNewValue role new value (ArrayList of ObjectNames)
  3248. // -param theOldRoleValue old role value (ArrayList of ObjectNames)
  3249. //
  3250. // -exception IllegalArgument if null parameter
  3251. // -exception RelationNotFoundException if no relation for given id
  3252. private void sendNotificationInt(int theIntNtfType,
  3253. String theMsg,
  3254. String theRelId,
  3255. List theUnregMBeanList,
  3256. String theRoleName,
  3257. List theRoleNewValue,
  3258. List theOldRoleValue)
  3259. throws IllegalArgumentException,
  3260. RelationNotFoundException {
  3261. if (theMsg == null ||
  3262. theRelId == null ||
  3263. (theIntNtfType != 3 && theUnregMBeanList != null) ||
  3264. (theIntNtfType == 2 &&
  3265. (theRoleName == null ||
  3266. theRoleNewValue == null ||
  3267. theOldRoleValue == null))) {
  3268. // Revisit [cebro] Localize message
  3269. String excMsg = "Invalid parameter.";
  3270. throw new IllegalArgumentException(excMsg);
  3271. }
  3272. if (isDebugOn()) {
  3273. StringBuffer strB =
  3274. new StringBuffer("theIntNtfType " + theIntNtfType
  3275. + ", theMsg " + theMsg
  3276. + ", theRelId " + theRelId);
  3277. if (theUnregMBeanList != null) {
  3278. strB.append(", theUnregMBeanList " +
  3279. theUnregMBeanList.toString());
  3280. }
  3281. if (theRoleName != null) {
  3282. strB.append(", theRoleName " + theRoleName);
  3283. }
  3284. if (theRoleNewValue != null) {
  3285. strB.append(", theRoleNewValue " + theRoleNewValue.toString());
  3286. }
  3287. if (theOldRoleValue != null) {
  3288. strB.append(", theOldRoleValue " + theOldRoleValue.toString());
  3289. }
  3290. debug("sendNotificationInt: entering", strB.toString());
  3291. }
  3292. // Relation type name
  3293. // Note: do not use getRelationTypeName() as if it is a relation MBean
  3294. // it is already unregistered.
  3295. String relTypeName = null;
  3296. synchronized(myRelId2RelTypeMap) {
  3297. relTypeName = (String)(myRelId2RelTypeMap.get(theRelId));
  3298. }
  3299. // ObjectName (for a relation MBean)
  3300. // Can also throw a RelationNotFoundException, but detected above
  3301. ObjectName relObjName = isRelationMBean(theRelId);
  3302. String ntfType = null;
  3303. if (relObjName != null) {
  3304. switch (theIntNtfType) {
  3305. case 1:
  3306. ntfType = RelationNotification.RELATION_MBEAN_CREATION;
  3307. break;
  3308. case 2:
  3309. ntfType = RelationNotification.RELATION_MBEAN_UPDATE;
  3310. break;
  3311. case 3:
  3312. ntfType = RelationNotification.RELATION_MBEAN_REMOVAL;
  3313. break;
  3314. }
  3315. } else {
  3316. switch (theIntNtfType) {
  3317. case 1:
  3318. ntfType = RelationNotification.RELATION_BASIC_CREATION;
  3319. break;
  3320. case 2:
  3321. ntfType = RelationNotification.RELATION_BASIC_UPDATE;
  3322. break;
  3323. case 3:
  3324. ntfType = RelationNotification.RELATION_BASIC_REMOVAL;
  3325. break;
  3326. }
  3327. }
  3328. // Sequence number
  3329. Long seqNbr = getNotificationSequenceNumber();
  3330. // Timestamp
  3331. Date currDate = new Date();
  3332. long timeStamp = currDate.getTime();
  3333. RelationNotification ntf = null;
  3334. if (ntfType.equals(RelationNotification.RELATION_BASIC_CREATION) ||
  3335. ntfType.equals(RelationNotification.RELATION_MBEAN_CREATION) ||
  3336. ntfType.equals(RelationNotification.RELATION_BASIC_REMOVAL) ||
  3337. ntfType.equals(RelationNotification.RELATION_MBEAN_REMOVAL))
  3338. // Creation or removal
  3339. ntf = new RelationNotification(ntfType,
  3340. this,
  3341. seqNbr.longValue(),
  3342. timeStamp,
  3343. theMsg,
  3344. theRelId,
  3345. relTypeName,
  3346. relObjName,
  3347. theUnregMBeanList);
  3348. else if (ntfType.equals(RelationNotification.RELATION_BASIC_UPDATE)
  3349. ||
  3350. ntfType.equals(RelationNotification.RELATION_MBEAN_UPDATE))
  3351. {
  3352. // Update
  3353. ntf = new RelationNotification(ntfType,
  3354. this,
  3355. seqNbr.longValue(),
  3356. timeStamp,
  3357. theMsg,
  3358. theRelId,
  3359. relTypeName,
  3360. relObjName,
  3361. theRoleName,
  3362. theRoleNewValue,
  3363. theOldRoleValue);
  3364. }
  3365. sendNotification(ntf);
  3366. if (isDebugOn())
  3367. debug("sendNotificationInt: exiting", null);
  3368. return;
  3369. }
  3370. // Checks, for the unregistration of an MBean referenced in the roles given
  3371. // in parameter, if the relation has to be removed or not, regarding
  3372. // expected minimum role cardinality and current number of
  3373. // references in each role after removal of the current one.
  3374. // If the relation is kept, calls handleMBeanUnregistration() callback of
  3375. // the relation to update it.
  3376. //
  3377. // -param theRelId relation id
  3378. // -param theObjName ObjectName of the unregistered MBean
  3379. // -param theRoleNameList list of names of roles where the unregistered
  3380. // MBean is referenced.
  3381. //
  3382. // -exception IllegalArgumentException if null parameter
  3383. // -exception RelationServiceNotRegisteredException if the Relation
  3384. // Service is not registered in the MBean Server
  3385. // -exception RelationNotFoundException if unknown relation id
  3386. // -exception RoleNotFoundException if one role given as parameter does
  3387. // not exist in the relation
  3388. private void handleReferenceUnregistration(String theRelId,
  3389. ObjectName theObjName,
  3390. List theRoleNameList)
  3391. throws IllegalArgumentException,
  3392. RelationServiceNotRegisteredException,
  3393. RelationNotFoundException,
  3394. RoleNotFoundException {
  3395. if (theRelId == null ||
  3396. theRoleNameList == null ||
  3397. theObjName == null) {
  3398. // Revisit [cebro[ Localize message
  3399. String excMsg = "Invalid parameter.";
  3400. throw new IllegalArgumentException(excMsg);
  3401. }
  3402. if (isDebugOn()) {
  3403. String str =
  3404. new String("theRelId " + theRelId
  3405. + ", theRoleNameList " + theRoleNameList.toString()
  3406. + "theObjName " + theObjName.toString());
  3407. debug("handleReferenceUnregistration: entering", str);
  3408. }
  3409. // Can throw RelationServiceNotRegisteredException
  3410. isActive();
  3411. // Retrieves the relation type name of the relation
  3412. // Can throw RelationNotFoundException
  3413. String currRelTypeName = getRelationTypeName(theRelId);
  3414. // Retrieves the relation
  3415. // Can throw RelationNotFoundException, but already detected above
  3416. Object relObj = getRelation(theRelId);
  3417. // Flag to specify if the relation has to be deleted
  3418. boolean deleteRelFlg = false;
  3419. for (Iterator roleNameIter = theRoleNameList.iterator();
  3420. roleNameIter.hasNext();) {
  3421. if (deleteRelFlg) {
  3422. break;
  3423. }
  3424. String currRoleName = (String)(roleNameIter.next());
  3425. // Retrieves number of MBeans currently referenced in role
  3426. // BEWARE! Do not use getRole() as role may be not readable
  3427. //
  3428. // Can throw RelationNotFoundException (but already checked),
  3429. // RoleNotFoundException
  3430. int currRoleRefNbr =
  3431. (getRoleCardinality(theRelId, currRoleName)).intValue();
  3432. // Retrieves new number of element in role
  3433. int currRoleNewRefNbr = currRoleRefNbr - 1;
  3434. // Retrieves role info for that role
  3435. //
  3436. // Shall not throw RelationTypeNotFoundException or
  3437. // RoleInfoNotFoundException
  3438. RoleInfo currRoleInfo = null;
  3439. try {
  3440. currRoleInfo = getRoleInfo(currRelTypeName,
  3441. currRoleName);
  3442. } catch (RelationTypeNotFoundException exc1) {
  3443. throw new RuntimeException(exc1.getMessage());
  3444. } catch (RoleInfoNotFoundException exc2) {
  3445. throw new RuntimeException(exc2.getMessage());
  3446. }
  3447. // Checks with expected minimum number of elements
  3448. boolean chkMinFlg = currRoleInfo.checkMinDegree(currRoleNewRefNbr);
  3449. if (!chkMinFlg) {
  3450. // The relation has to be deleted
  3451. deleteRelFlg = true;
  3452. }
  3453. }
  3454. if (deleteRelFlg) {
  3455. // Removes the relation
  3456. removeRelation(theRelId);
  3457. } else {
  3458. // Updates each role in the relation using
  3459. // handleMBeanUnregistration() callback
  3460. //
  3461. // BEWARE: this theRoleNameList list MUST BE A COPY of a role name
  3462. // list for a referenced MBean in a relation, NOT a
  3463. // reference to an original one part of the
  3464. // myRefedMBeanObjName2RelIdsMap!!!! Because each role
  3465. // which name is in that list will be updated (potentially
  3466. // using setRole(). So the Relation Service will update the
  3467. // myRefedMBeanObjName2RelIdsMap to refelect the new role
  3468. // value!
  3469. for (Iterator roleNameIter = theRoleNameList.iterator();
  3470. roleNameIter.hasNext();) {
  3471. String currRoleName = (String)(roleNameIter.next());
  3472. if (relObj instanceof RelationSupport) {
  3473. // Internal relation
  3474. // Can throw RoleNotFoundException (but already checked)
  3475. //
  3476. // Shall not throw
  3477. // RelationTypeNotFoundException,
  3478. // InvalidRoleValueException (value was correct, removing
  3479. // one reference shall not invalidate it, else detected
  3480. // above)
  3481. try {
  3482. ((RelationSupport)relObj).handleMBeanUnregistrationInt(
  3483. theObjName,
  3484. currRoleName,
  3485. true,
  3486. this);
  3487. } catch (RelationTypeNotFoundException exc3) {
  3488. throw new RuntimeException(exc3.getMessage());
  3489. } catch (InvalidRoleValueException exc4) {
  3490. throw new RuntimeException(exc4.getMessage());
  3491. }
  3492. } else {
  3493. // Relation MBean
  3494. Object[] params = new Object[2];
  3495. params[0] = theObjName;
  3496. params[1] = currRoleName;
  3497. String[] signature = new String[2];
  3498. signature[0] = "javax.management.ObjectName";
  3499. signature[1] = "java.lang.String";
  3500. // Shall not throw InstanceNotFoundException, or
  3501. // MBeanException (wrapping RoleNotFoundException or
  3502. // MBeanException or InvalidRoleValueException) or
  3503. // ReflectionException
  3504. try {
  3505. myMBeanServer.invoke(((ObjectName)relObj),
  3506. "handleMBeanUnregistration",
  3507. params,
  3508. signature);
  3509. } catch (InstanceNotFoundException exc1) {
  3510. throw new RuntimeException(exc1.getMessage());
  3511. } catch (ReflectionException exc3) {
  3512. throw new RuntimeException(exc3.getMessage());
  3513. } catch (MBeanException exc2) {
  3514. Exception wrappedExc = exc2.getTargetException();
  3515. throw new RuntimeException(wrappedExc.getMessage());
  3516. }
  3517. }
  3518. }
  3519. }
  3520. if (isDebugOn())
  3521. debug("handleReferenceUnregistration: exiting", null);
  3522. return;
  3523. }
  3524. // stuff for Tracing
  3525. private static String localClassName = "RelationService";
  3526. // trace level
  3527. private boolean isTraceOn() {
  3528. return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_RELATION);
  3529. }
  3530. // private void trace(String className, String methodName, String info) {
  3531. // Trace.send(Trace.LEVEL_TRACE, Trace.INFO_RELATION, className, methodName, info);
  3532. // }
  3533. private void trace(String methodName, String info) {
  3534. Trace.send(Trace.LEVEL_TRACE, Trace.INFO_RELATION, localClassName, methodName, info);
  3535. Trace.send(Trace.LEVEL_TRACE, Trace.INFO_RELATION, "", "", "\n");
  3536. }
  3537. // private void trace(String className, String methodName, Exception e) {
  3538. // Trace.send(Trace.LEVEL_TRACE, Trace.INFO_RELATION, className, methodName, e);
  3539. // }
  3540. // private void trace(String methodName, Exception e) {
  3541. // Trace.send(Trace.LEVEL_TRACE, Trace.INFO_RELATION, localClassName, methodName, e);
  3542. // }
  3543. // debug level
  3544. private boolean isDebugOn() {
  3545. return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_RELATION);
  3546. }
  3547. // private void debug(String className, String methodName, String info) {
  3548. // Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_RELATION, className, methodName, info);
  3549. // }
  3550. private void debug(String methodName, String info) {
  3551. Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_RELATION, localClassName, methodName, info);
  3552. Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_RELATION, "", "", "\n");
  3553. }
  3554. // private void debug(String className, String methodName, Exception e) {
  3555. // Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_RELATION, className, methodName, e);
  3556. // }
  3557. // private void debug(String methodName, Exception e) {
  3558. // Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_RELATION, localClassName, methodName, e);
  3559. // }
  3560. }