1. /*
  2. * @(#)RelationSupport.java 1.31 04/02/10
  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.ObjectName;
  9. import javax.management.MBeanRegistration;
  10. import javax.management.MBeanServer;
  11. import javax.management.InstanceNotFoundException;
  12. import javax.management.ReflectionException;
  13. import javax.management.MBeanException;
  14. import java.util.HashMap;
  15. import java.util.ArrayList;
  16. import java.util.Iterator;
  17. import java.util.Map;
  18. import java.util.List;
  19. import com.sun.jmx.trace.Trace;
  20. /**
  21. * A RelationSupport object is used internally by the Relation Service to
  22. * represent simple relations (only roles, no properties or methods), with an
  23. * unlimited number of roles, of any relation type. As internal representation,
  24. * it is not exposed to the user.
  25. * <P>RelationSupport class conforms to the design patterns of standard MBean. So
  26. * the user can decide to instantiate a RelationSupport object himself as
  27. * a MBean (as it follows the MBean design patterns), to register it in the
  28. * MBean Server, and then to add it in the Relation Service.
  29. * <P>The user can also, when creating his own MBean relation class, have it
  30. * extending RelationSupport, to retrieve the implementations of required
  31. * interfaces (see below).
  32. * <P>It is also possible to have in a user relation MBean class a member
  33. * being a RelationSupport object, and to implement the required interfaces by
  34. * delegating all to this member.
  35. * <P> RelationSupport implements the Relation interface (to be handled by the
  36. * Relation Service).
  37. * <P>It implements also the MBeanRegistration interface to be able to retrieve
  38. * the MBean Server where it is registered (if registered as a MBean) to access
  39. * to its Relation Service.
  40. *
  41. * @since 1.5
  42. */
  43. public class RelationSupport
  44. implements RelationSupportMBean, MBeanRegistration {
  45. //
  46. // Private members
  47. //
  48. // Relation identifier (expected to be unique in the Relation Service where
  49. // the RelationSupport object will be added)
  50. private String myRelId = null;
  51. // ObjectName of the Relation Service where the relation will be added
  52. // REQUIRED if the RelationSupport is created by the user to be registered as
  53. // a MBean, as it will have to access the Relation Service via the MBean
  54. // Server to perform the check regarding the relation type.
  55. // Is null if current object is directly created by the Relation Service,
  56. // as the object will directly access it.
  57. private ObjectName myRelServiceName = null;
  58. // Reference to the MBean Server where the Relation Service is
  59. // registered
  60. // REQUIRED if the RelationSupport is created by the user to be registered as
  61. // a MBean, as it will have to access the Relation Service via the MBean
  62. // Server to perform the check regarding the relation type.
  63. // If the Relationbase object is created by the Relation Service (use of
  64. // createRelation() method), this is null as not needed, direct access to
  65. // the Relation Service.
  66. // If the Relationbase object is created by the user and registered as a
  67. // MBean, this is set by the preRegister() method below.
  68. private MBeanServer myRelServiceMBeanServer = null;
  69. // Relation type name (must be known in the Relation Service where the
  70. // relation will be added)
  71. private String myRelTypeName = null;
  72. // Role map, mapping <role-name> -> <Role>
  73. // Initialised by role list in the constructor, then updated:
  74. // - if the relation is a MBean, via setRole() and setRoles() methods, or
  75. // via Relation Service setRole() and setRoles() methods
  76. // - if the relation is internal to the Relation Service, via
  77. // setRoleInt() and setRolesInt() methods.
  78. private HashMap myRoleName2ValueMap = new HashMap();
  79. // Flag to indicate if the object has been added in the Relation Service
  80. private Boolean myInRelServFlg = null;
  81. //
  82. // Constructors
  83. //
  84. /**
  85. * Creates object.
  86. * <P>This constructor has to be used when the RelationSupport object will be
  87. * registered as a MBean by the user, or when creating a user relation
  88. * MBean those class extends RelationSupport.
  89. * <P>Nothing is done at the Relation Service level, i.e. the RelationSupport
  90. * object is not added, and no check if the provided values are correct.
  91. * The object is always created, EXCEPT if:
  92. * <P>- one mandatory parameter is not provided
  93. * <P>- the same name is used for two roles.
  94. * <P>To be handled as a relation, the object has then to be added in the
  95. * Relation Service using Relation Service method addRelation().
  96. *
  97. * @param theRelId relation identifier, to identify the relation in the
  98. * Relation Service.
  99. * <P>Expected to be unique in the given Relation Service.
  100. * @param theRelServiceName ObjectName of the Relation Service where
  101. * the relation will be registered.
  102. * <P>It is required as this is the Relation Service that is aware of the
  103. * definition of the relation type of given relation, so that will be able
  104. * to check update operations (set).
  105. * @param theRelTypeName Name of relation type.
  106. * <P>Expected to have been created in given Relation Service.
  107. * @param theRoleList list of roles (Role objects) to initialised the
  108. * relation. Can be null.
  109. * <P>Expected to conform to relation info in associated relation type.
  110. *
  111. * @exception InvalidRoleValueException if the same name is used for two
  112. * roles.
  113. * @exception IllegalArgumentException if a required value (Relation
  114. * Service Object Name, etc.) is not provided as parameter.
  115. */
  116. public RelationSupport(String theRelId,
  117. ObjectName theRelServiceName,
  118. String theRelTypeName,
  119. RoleList theRoleList)
  120. throws InvalidRoleValueException,
  121. IllegalArgumentException {
  122. super();
  123. if (isTraceOn())
  124. trace("Constructor: entering", null);
  125. // Can throw InvalidRoleValueException and IllegalArgumentException
  126. initMembers(theRelId,
  127. theRelServiceName,
  128. null,
  129. theRelTypeName,
  130. theRoleList);
  131. if (isTraceOn())
  132. trace("Constructor: exiting", null);
  133. }
  134. /**
  135. * Creates object.
  136. * <P>This constructor has to be used when the user relation MBean
  137. * implements the interfaces expected to be supported by a relation by
  138. * delegating to a RelationSupport object.
  139. * <P>This object needs to know the Relation Service expected to handle the
  140. * relation. So it has to know the MBean Server where the Relation Service
  141. * is registered.
  142. * <P>According to a limitation, a relation MBean must be registered in the
  143. * same MBean Server as the Relation Service expected to handle it. So the
  144. * user relation MBean has to be created and registered, and then the
  145. * wrapped RelationSupport object can be created with identified MBean
  146. * Server.
  147. * <P>Nothing is done at the Relation Service level, i.e. the RelationSupport
  148. * object is not added, and no check if the provided values are correct.
  149. * The object is always created, EXCEPT if:
  150. * <P>- one required parameter is not provided
  151. * <P>- the same name is used for two roles.
  152. * <P>To be handled as a relation, the object has then to be added in the
  153. * Relation Service using the Relation Service method addRelation().
  154. *
  155. * @param theRelId relation identifier, to identify the relation in the
  156. * Relation Service.
  157. * <P>Expected to be unique in the given Relation Service.
  158. * @param theRelServiceName ObjectName of the Relation Service where
  159. * the relation will be registered.
  160. * <P>It is required as this is the Relation Service that is aware of the
  161. * definition of the relation type of given relation, so that will be able
  162. * to check update operations (set).
  163. * @param theRelServiceMBeanServer MBean Server where the wrapping MBean
  164. * is or will be registered.
  165. * <P>Expected to be the MBean Server where the Relation Service is or will
  166. * be registered.
  167. * @param theRelTypeName Name of relation type.
  168. * <P>Expected to have been created in given Relation Service.
  169. * @param theRoleList list of roles (Role objects) to initialised the
  170. * relation. Can be null.
  171. * <P>Expected to conform to relation info in associated relation type.
  172. *
  173. * @exception InvalidRoleValueException if the same name is used for two
  174. * roles.
  175. * @exception IllegalArgumentException if a required value (Relation
  176. * Service Object Name, etc.) is not provided as parameter.
  177. */
  178. public RelationSupport(String theRelId,
  179. ObjectName theRelServiceName,
  180. MBeanServer theRelServiceMBeanServer,
  181. String theRelTypeName,
  182. RoleList theRoleList)
  183. throws InvalidRoleValueException,
  184. IllegalArgumentException {
  185. super();
  186. if (theRelServiceMBeanServer == null) {
  187. // Revisit [cebro] Localize message
  188. String excMsg = "Invalid parameter.";
  189. throw new IllegalArgumentException(excMsg);
  190. }
  191. if (isTraceOn())
  192. trace("Constructor: entering", null);
  193. // Can throw InvalidRoleValueException and
  194. // IllegalArgumentException
  195. initMembers(theRelId,
  196. theRelServiceName,
  197. theRelServiceMBeanServer,
  198. theRelTypeName,
  199. theRoleList);
  200. if (isTraceOn())
  201. trace("Constructor: exiting", null);
  202. }
  203. //
  204. // Relation Interface
  205. //
  206. /**
  207. * Retrieves role value for given role name.
  208. * <P>Checks if the role exists and is readable according to the relation
  209. * type.
  210. *
  211. * @param theRoleName name of role
  212. *
  213. * @return the ArrayList of ObjectName objects being the role value
  214. *
  215. * @exception IllegalArgumentException if null role name
  216. * @exception RoleNotFoundException if:
  217. * <P>- there is no role with given name
  218. * <P>- the role is not readable.
  219. * @exception RelationServiceNotRegisteredException if the Relation
  220. * Service is not registered in the MBean Server
  221. *
  222. * @see #setRole
  223. */
  224. public List getRole(String theRoleName)
  225. throws IllegalArgumentException,
  226. RoleNotFoundException,
  227. RelationServiceNotRegisteredException {
  228. if (theRoleName == null) {
  229. // Revisit [cebro] Localize message
  230. String excMsg = "Invalid parameter.";
  231. throw new IllegalArgumentException(excMsg);
  232. }
  233. if (isTraceOn())
  234. trace("getRole: entering", theRoleName);
  235. // Can throw RoleNotFoundException and
  236. // RelationServiceNotRegisteredException
  237. ArrayList result = (ArrayList)
  238. (getRoleInt(theRoleName, false, null, false));
  239. if (isTraceOn())
  240. trace("getRole: exiting", null);
  241. return result;
  242. }
  243. /**
  244. * Retrieves values of roles with given names.
  245. * <P>Checks for each role if it exists and is readable according to the
  246. * relation type.
  247. *
  248. * @param theRoleNameArray array of names of roles to be retrieved
  249. *
  250. * @return a RoleResult object, including a RoleList (for roles
  251. * successfully retrieved) and a RoleUnresolvedList (for roles not
  252. * retrieved).
  253. *
  254. * @exception IllegalArgumentException if null role name
  255. * @exception RelationServiceNotRegisteredException if the Relation
  256. * Service is not registered in the MBean Server
  257. *
  258. * @see #setRoles
  259. */
  260. public RoleResult getRoles(String[] theRoleNameArray)
  261. throws IllegalArgumentException,
  262. RelationServiceNotRegisteredException {
  263. if (theRoleNameArray == null) {
  264. // Revisit [cebro] Localize message
  265. String excMsg = "Invalid parameter.";
  266. throw new IllegalArgumentException(excMsg);
  267. }
  268. if (isTraceOn())
  269. trace("getRoles: entering", null);
  270. // Can throw RelationServiceNotRegisteredException
  271. RoleResult result = getRolesInt(theRoleNameArray, false, null);
  272. if (isTraceOn())
  273. trace("getRoles: exiting", null);
  274. return result;
  275. }
  276. /**
  277. * Returns all roles present in the relation.
  278. *
  279. * @return a RoleResult object, including a RoleList (for roles
  280. * successfully retrieved) and a RoleUnresolvedList (for roles not
  281. * readable).
  282. *
  283. * @exception RelationServiceNotRegisteredException if the Relation
  284. * Service is not registered in the MBean Server
  285. */
  286. public RoleResult getAllRoles()
  287. throws RelationServiceNotRegisteredException {
  288. if (isTraceOn())
  289. trace("getAllRoles: entering", null);
  290. RoleResult result = null;
  291. try {
  292. result = getAllRolesInt(false, null);
  293. } catch (IllegalArgumentException exc) {
  294. // OK : Invalid parameters, ignore...
  295. }
  296. if (isTraceOn())
  297. trace("getAllRoles: exiting", null);
  298. return result;
  299. }
  300. /**
  301. * Returns all roles in the relation without checking read mode.
  302. *
  303. * @return a RoleList
  304. */
  305. public RoleList retrieveAllRoles() {
  306. if (isTraceOn())
  307. trace("retrieveAllRoles: entering", null);
  308. RoleList result = null;
  309. synchronized(myRoleName2ValueMap) {
  310. result =
  311. new RoleList(new ArrayList(myRoleName2ValueMap.values()));
  312. }
  313. if (isTraceOn())
  314. trace("retrieveAllRoles: exiting", null);
  315. return result;
  316. }
  317. /**
  318. * Returns the number of MBeans currently referenced in the given role.
  319. *
  320. * @param theRoleName name of role
  321. *
  322. * @return the number of currently referenced MBeans in that role
  323. *
  324. * @exception IllegalArgumentException if null role name
  325. * @exception RoleNotFoundException if there is no role with given name
  326. */
  327. public Integer getRoleCardinality(String theRoleName)
  328. throws IllegalArgumentException,
  329. RoleNotFoundException {
  330. if (theRoleName == null) {
  331. // Revisit [cebro] Localize message
  332. String excMsg = "Invalid parameter.";
  333. throw new IllegalArgumentException(excMsg);
  334. }
  335. if (isTraceOn())
  336. trace("getRoleCardinality: entering", theRoleName);
  337. // Try to retrieve the role
  338. Role role = null;
  339. synchronized(myRoleName2ValueMap) {
  340. // No null Role is allowed, so direct use of get()
  341. role = (Role)(myRoleName2ValueMap.get(theRoleName));
  342. }
  343. if (role == null) {
  344. int pbType = RoleStatus.NO_ROLE_WITH_NAME;
  345. // Will throw a RoleNotFoundException
  346. //
  347. // Will not throw InvalidRoleValueException, so catch it for the
  348. // compiler
  349. try {
  350. RelationService.throwRoleProblemException(pbType,
  351. theRoleName);
  352. } catch (InvalidRoleValueException exc) {
  353. // OK : Do not throw InvalidRoleValueException as
  354. // a RoleNotFoundException will be thrown.
  355. }
  356. }
  357. ArrayList roleValue = (ArrayList)(role.getRoleValue());
  358. if (isTraceOn())
  359. trace("getRoleCardinality: exiting", null);
  360. return new Integer(roleValue.size());
  361. }
  362. /**
  363. * Sets the given role.
  364. * <P>Will check the role according to its corresponding role definition
  365. * provided in relation's relation type
  366. * <P>Will send a notification (RelationNotification with type
  367. * RELATION_BASIC_UPDATE or RELATION_MBEAN_UPDATE, depending if the
  368. * relation is a MBean or not).
  369. *
  370. * @param theRole role to be set (name and new value)
  371. *
  372. * @exception IllegalArgumentException if null role
  373. * @exception RoleNotFoundException if the role is not writable (no
  374. * test on the write access mode performed when initialising the role)
  375. * @exception InvalidRoleValueException if value provided for
  376. * role is not valid, i.e.:
  377. * <P>- the number of referenced MBeans in given value is less than
  378. * expected minimum degree
  379. * <P>- the number of referenced MBeans in provided value exceeds expected
  380. * maximum degree
  381. * <P>- one referenced MBean in the value is not an Object of the MBean
  382. * class expected for that role
  383. * <P>- a MBean provided for that role does not exist
  384. * @exception RelationServiceNotRegisteredException if the Relation
  385. * Service is not registered in the MBean Server
  386. * @exception RelationTypeNotFoundException if the relation type has not
  387. * been declared in the Relation Service
  388. * @exception RelationNotFoundException if the relation has not been
  389. * added in the Relation Service.
  390. *
  391. * @see #getRole
  392. */
  393. public void setRole(Role theRole)
  394. throws IllegalArgumentException,
  395. RoleNotFoundException,
  396. RelationTypeNotFoundException,
  397. InvalidRoleValueException,
  398. RelationServiceNotRegisteredException,
  399. RelationNotFoundException {
  400. if (theRole == null) {
  401. // Revisit [cebro] Localize message
  402. String excMsg = "Invalid parameter.";
  403. throw new IllegalArgumentException(excMsg);
  404. }
  405. if (isTraceOn())
  406. trace("setRole: entering", theRole.toString());
  407. // Will return null :)
  408. Object result = setRoleInt(theRole, false, null, false);
  409. if (isTraceOn())
  410. trace("setRole: exiting", null);
  411. return;
  412. }
  413. /**
  414. * Sets the given roles.
  415. * <P>Will check the role according to its corresponding role definition
  416. * provided in relation's relation type
  417. * <P>Will send one notification (RelationNotification with type
  418. * RELATION_BASIC_UPDATE or RELATION_MBEAN_UPDATE, depending if the
  419. * relation is a MBean or not) per updated role.
  420. *
  421. * @param theRoleList list of roles to be set
  422. *
  423. * @return a RoleResult object, including a RoleList (for roles
  424. * successfully set) and a RoleUnresolvedList (for roles not
  425. * set).
  426. *
  427. * @exception IllegalArgumentException if null role name
  428. * @exception RelationServiceNotRegisteredException if the Relation
  429. * Service is not registered in the MBean Server
  430. * @exception RelationTypeNotFoundException if the relation type has not
  431. * been declared in the Relation Service.
  432. * @exception RelationNotFoundException if the relation MBean has not been
  433. * added in the Relation Service.
  434. *
  435. * @see #getRoles
  436. */
  437. public RoleResult setRoles(RoleList theRoleList)
  438. throws IllegalArgumentException,
  439. RelationServiceNotRegisteredException,
  440. RelationTypeNotFoundException,
  441. RelationNotFoundException {
  442. if (theRoleList == null) {
  443. // Revisit [cebro] Localize message
  444. String excMsg = "Invalid parameter.";
  445. throw new IllegalArgumentException(excMsg);
  446. }
  447. if (isTraceOn())
  448. trace("setRoles: entering", theRoleList.toString());
  449. RoleResult result = setRolesInt(theRoleList, false, null);
  450. if (isTraceOn())
  451. trace("setRoles: exiting", null);
  452. return result;
  453. }
  454. /**
  455. * Callback used by the Relation Service when a MBean referenced in a role
  456. * is unregistered.
  457. * <P>The Relation Service will call this method to let the relation
  458. * take action to reflect the impact of such unregistration.
  459. * <P>BEWARE. the user is not expected to call this method.
  460. * <P>Current implementation is to set the role with its current value
  461. * (list of ObjectNames of referenced MBeans) without the unregistered
  462. * one.
  463. *
  464. * @param theObjName ObjectName of unregistered MBean
  465. * @param theRoleName name of role where the MBean is referenced
  466. *
  467. * @exception IllegalArgumentException if null parameter
  468. * @exception RoleNotFoundException if role does not exist in the
  469. * relation or is not writable
  470. * @exception InvalidRoleValueException if role value does not conform to
  471. * the associated role info (this will never happen when called from the
  472. * Relation Service)
  473. * @exception RelationServiceNotRegisteredException if the Relation
  474. * Service is not registered in the MBean Server
  475. * @exception RelationTypeNotFoundException if the relation type has not
  476. * been declared in the Relation Service.
  477. * @exception RelationNotFoundException if this method is called for a
  478. * relation MBean not added in the Relation Service.
  479. */
  480. public void handleMBeanUnregistration(ObjectName theObjName,
  481. String theRoleName)
  482. throws IllegalArgumentException,
  483. RoleNotFoundException,
  484. InvalidRoleValueException,
  485. RelationServiceNotRegisteredException,
  486. RelationTypeNotFoundException,
  487. RelationNotFoundException {
  488. if (theObjName == null || theRoleName == null) {
  489. // Revisit [cebro] Localize message
  490. String excMsg = "Invalid parameter.";
  491. throw new IllegalArgumentException(excMsg);
  492. }
  493. if (isTraceOn())
  494. trace("handleMBeanUnregistration: entering",
  495. "theObjName " + theObjName + ", theRoleName " + theRoleName);
  496. // Can throw RoleNotFoundException, InvalidRoleValueException,
  497. // or RelationTypeNotFoundException
  498. handleMBeanUnregistrationInt(theObjName,
  499. theRoleName,
  500. false,
  501. null);
  502. if (isTraceOn())
  503. trace("handleMBeanUnregistration: exiting", null);
  504. return;
  505. }
  506. /**
  507. * Retrieves MBeans referenced in the various roles of the relation.
  508. *
  509. * @return a HashMap mapping:
  510. * <P> ObjectName -> ArrayList of String (role names)
  511. */
  512. public Map getReferencedMBeans() {
  513. if (isTraceOn())
  514. trace("getReferencedMBeans: entering", null);
  515. HashMap refMBeanMap = new HashMap();
  516. synchronized(myRoleName2ValueMap) {
  517. for (Iterator roleIter = (myRoleName2ValueMap.values()).iterator();
  518. roleIter.hasNext();) {
  519. Role currRole = (Role)(roleIter.next());
  520. String currRoleName = currRole.getRoleName();
  521. // Retrieves ObjectNames of MBeans referenced in current role
  522. ArrayList currRefMBeanList = (ArrayList)
  523. (currRole.getRoleValue());
  524. for (Iterator mbeanIter = currRefMBeanList.iterator();
  525. mbeanIter.hasNext();) {
  526. ObjectName currRoleObjName =
  527. (ObjectName)(mbeanIter.next());
  528. // Sees if current MBean has been already referenced in
  529. // roles already seen
  530. ArrayList mbeanRoleNameList =
  531. (ArrayList)(refMBeanMap.get(currRoleObjName));
  532. boolean newRefFlg = false;
  533. if (mbeanRoleNameList == null) {
  534. newRefFlg = true;
  535. mbeanRoleNameList = new ArrayList();
  536. }
  537. mbeanRoleNameList.add(currRoleName);
  538. if (newRefFlg) {
  539. refMBeanMap.put(currRoleObjName, mbeanRoleNameList);
  540. }
  541. }
  542. }
  543. }
  544. if (isTraceOn())
  545. trace("getReferencedMBeans: exiting", null);
  546. return refMBeanMap;
  547. }
  548. /**
  549. * Returns name of associated relation type.
  550. */
  551. public String getRelationTypeName() {
  552. return myRelTypeName;
  553. }
  554. /**
  555. * Returns ObjectName of the Relation Service handling the relation.
  556. *
  557. * @return the ObjectName of the Relation Service.
  558. */
  559. public ObjectName getRelationServiceName() {
  560. return myRelServiceName;
  561. }
  562. /**
  563. * Returns relation identifier (used to uniquely identify the relation
  564. * inside the Relation Service).
  565. *
  566. * @return the relation id.
  567. */
  568. public String getRelationId() {
  569. return myRelId;
  570. }
  571. //
  572. // MBeanRegistration interface
  573. //
  574. // Pre-registration: retrieves the MBean Server (useful to access to the
  575. // Relation Service)
  576. // This is the way to retrieve the MBean Server when the relation object is
  577. // a MBean created by the user outside of the Relation Service.
  578. //
  579. // No exception thrown.
  580. public ObjectName preRegister(MBeanServer server,
  581. ObjectName name)
  582. throws Exception {
  583. myRelServiceMBeanServer = server;
  584. return name;
  585. }
  586. // Post-registration: does nothing
  587. public void postRegister(Boolean registrationDone) {
  588. return;
  589. }
  590. // Pre-unregistration: does nothing
  591. public void preDeregister()
  592. throws Exception {
  593. return;
  594. }
  595. // Post-unregistration: does nothing
  596. public void postDeregister() {
  597. return;
  598. }
  599. //
  600. // Others
  601. //
  602. /**
  603. * Returns an internal flag specifying if the object is still handled by
  604. * the Relation Service.
  605. */
  606. public Boolean isInRelationService() {
  607. Boolean result = null;
  608. synchronized(myInRelServFlg) {
  609. result = new Boolean(myInRelServFlg.booleanValue());
  610. }
  611. return result;
  612. }
  613. public void setRelationServiceManagementFlag(Boolean theFlg)
  614. throws IllegalArgumentException {
  615. if (theFlg == null) {
  616. // Revisit [cebro] Localize message
  617. String excMsg = "Invalid parameter.";
  618. throw new IllegalArgumentException(excMsg);
  619. }
  620. synchronized(myInRelServFlg) {
  621. myInRelServFlg = new Boolean(theFlg.booleanValue());
  622. }
  623. return;
  624. }
  625. //
  626. // Misc
  627. //
  628. // Gets the role with given name
  629. // Checks if the role exists and is readable according to the relation
  630. // type.
  631. //
  632. // This method is called in getRole() above.
  633. // It is also called in the Relation Service getRole() method.
  634. // It is also called in getRolesInt() below (used for getRoles() above
  635. // and for Relation Service getRoles() method).
  636. //
  637. // Depending on parameters reflecting its use (either in the scope of
  638. // getting a single role or of getting several roles), will return:
  639. // - in case of success:
  640. // - for single role retrieval, the ArrayList of ObjectNames being the
  641. // role value
  642. // - for multi-role retrieval, the Role object itself
  643. // - in case of failure (except critical exceptions):
  644. // - for single role retrieval, if role does not exist or is not
  645. // readable, an RoleNotFoundException exception is raised
  646. // - for multi-role retrieval, a RoleUnresolved object
  647. //
  648. // -param theRoleName name of role to be retrieved
  649. // -param theRelServCallFlg true if call from the Relation Service; this
  650. // will happen if the current RelationSupport object has been created by
  651. // the Relation Service (via createRelation()) method, so direct access is
  652. // possible.
  653. // -param theRelServ reference to Relation Service object, if object
  654. // created by Relation Service.
  655. // -param theMultiRoleFlg true if getting the role in the scope of a
  656. // multiple retrieval.
  657. //
  658. // -return:
  659. // - for single role retrieval (theMultiRoleFlg false):
  660. // - ArrayList of ObjectName objects, value of role with given name, if
  661. // the role can be retrieved
  662. // - raise a RoleNotFoundException exception else
  663. // - for multi-role retrieval (theMultiRoleFlg true):
  664. // - the Role object for given role name if role can be retrieved
  665. // - a RoleUnresolved object with problem.
  666. //
  667. // -exception IllegalArgumentException if null parameter
  668. // -exception RoleNotFoundException if theMultiRoleFlg is false and:
  669. // - there is no role with given name
  670. // or
  671. // - the role is not readable.
  672. // -exception RelationServiceNotRegisteredException if the Relation
  673. // Service is not registered in the MBean Server
  674. Object getRoleInt(String theRoleName,
  675. boolean theRelServCallFlg,
  676. RelationService theRelServ,
  677. boolean theMultiRoleFlg)
  678. throws IllegalArgumentException,
  679. RoleNotFoundException,
  680. RelationServiceNotRegisteredException {
  681. if (theRoleName == null ||
  682. (theRelServCallFlg && theRelServ == null)) {
  683. // Revisit [cebro] Localize message
  684. String excMsg = "Invalid parameter.";
  685. throw new IllegalArgumentException(excMsg);
  686. }
  687. if (isDebugOn()) {
  688. String str = "theRoleName " + theRoleName;
  689. debug("getRoleInt: entering", str);
  690. }
  691. int pbType = 0;
  692. Role role = null;
  693. synchronized(myRoleName2ValueMap) {
  694. // No null Role is allowed, so direct use of get()
  695. role = (Role)(myRoleName2ValueMap.get(theRoleName));
  696. }
  697. if (role == null) {
  698. pbType = RoleStatus.NO_ROLE_WITH_NAME;
  699. } else {
  700. // Checks if the role is readable
  701. Integer status = null;
  702. if (theRelServCallFlg) {
  703. // Call from the Relation Service, so direct access to it,
  704. // avoiding MBean Server
  705. // Shall not throw a RelationTypeNotFoundException
  706. try {
  707. status = theRelServ.checkRoleReading(theRoleName,
  708. myRelTypeName);
  709. } catch (RelationTypeNotFoundException exc) {
  710. throw new RuntimeException(exc.getMessage());
  711. }
  712. } else {
  713. // Call from getRole() method above
  714. // So we have a MBean. We must access the Relation Service
  715. // via the MBean Server.
  716. Object[] params = new Object[2];
  717. params[0] = theRoleName;
  718. params[1] = myRelTypeName;
  719. String[] signature = new String[2];
  720. signature[0] = "java.lang.String";
  721. signature[1] = "java.lang.String";
  722. // Can throw InstanceNotFoundException if the Relation
  723. // Service is not registered (to be catched in any case and
  724. // transformed into RelationServiceNotRegisteredException).
  725. //
  726. // Shall not throw a MBeanException, or a ReflectionException
  727. // or an InstanceNotFoundException
  728. try {
  729. status = (Integer)
  730. (myRelServiceMBeanServer.invoke(myRelServiceName,
  731. "checkRoleReading",
  732. params,
  733. signature));
  734. } catch (MBeanException exc1) {
  735. throw new RuntimeException("incorrect relation type");
  736. } catch (ReflectionException exc2) {
  737. throw new RuntimeException(exc2.getMessage());
  738. } catch (InstanceNotFoundException exc3) {
  739. throw new RelationServiceNotRegisteredException(
  740. exc3.getMessage());
  741. }
  742. }
  743. pbType = status.intValue();
  744. }
  745. Object result = null;
  746. if (pbType == 0) {
  747. // Role can be retrieved
  748. if (!(theMultiRoleFlg)) {
  749. // Single role retrieved: returns its value
  750. // Note: no need to test if role value (list) not null before
  751. // cloning, null value not allowed, empty list if
  752. // nothing.
  753. result = (ArrayList)
  754. (((ArrayList)(role.getRoleValue())).clone());
  755. } else {
  756. // Role retrieved during multi-role retrieval: returns the
  757. // role
  758. result = (Role)(role.clone());
  759. }
  760. } else {
  761. // Role not retrieved
  762. if (!(theMultiRoleFlg)) {
  763. // Problem when retrieving a simple role: either role not
  764. // found or not readable, so raises a RoleNotFoundException.
  765. try {
  766. RelationService.throwRoleProblemException(pbType,
  767. theRoleName);
  768. // To keep compiler happy :)
  769. return null;
  770. } catch (InvalidRoleValueException exc) {
  771. throw new RuntimeException(exc.getMessage());
  772. }
  773. } else {
  774. // Problem when retrieving a role in a multi-role retrieval:
  775. // returns a RoleUnresolved object
  776. result = new RoleUnresolved(theRoleName, null, pbType);
  777. }
  778. }
  779. if (isDebugOn())
  780. debug("getRoleInt: exiting", null);
  781. return result;
  782. }
  783. // Gets the given roles
  784. // For each role, verifies if the role exists and is readable according to
  785. // the relation type.
  786. //
  787. // This method is called in getRoles() above and in Relation Service
  788. // getRoles() method.
  789. //
  790. // -param theRoleNameArray array of names of roles to be retrieved
  791. // -param theRelServCallFlg true if call from the Relation Service; this
  792. // will happen if the current RelationSupport object has been created by
  793. // the Relation Service (via createRelation()) method, so direct access is
  794. // possible.
  795. // -param theRelServ reference to Relation Service object, if object
  796. // created by Relation Service.
  797. //
  798. // -return a RoleResult object
  799. //
  800. // -exception IllegalArgumentException if null parameter
  801. // -exception RelationServiceNotRegisteredException if the Relation
  802. // Service is not registered in the MBean Server
  803. RoleResult getRolesInt(String[] theRoleNameArray,
  804. boolean theRelServCallFlg,
  805. RelationService theRelServ)
  806. throws IllegalArgumentException,
  807. RelationServiceNotRegisteredException {
  808. if (theRoleNameArray == null ||
  809. (theRelServCallFlg && theRelServ == null)) {
  810. // Revisit [cebro] Localize message
  811. String excMsg = "Invalid parameter.";
  812. throw new IllegalArgumentException(excMsg);
  813. }
  814. if (isDebugOn())
  815. debug("getRolesInt: entering", null);
  816. RoleList roleList = new RoleList();
  817. RoleUnresolvedList roleUnresList = new RoleUnresolvedList();
  818. for (int i = 0; i < theRoleNameArray.length; i++) {
  819. String currRoleName = theRoleNameArray[i];
  820. Object currResult = null;
  821. // Can throw RelationServiceNotRegisteredException
  822. //
  823. // RoleNotFoundException: not possible but catch it for compiler :)
  824. try {
  825. currResult = getRoleInt(currRoleName,
  826. theRelServCallFlg,
  827. theRelServ,
  828. true);
  829. } catch (RoleNotFoundException exc) {
  830. return null; // :)
  831. }
  832. if (currResult instanceof Role) {
  833. // Can throw IllegalArgumentException if role is null
  834. // (normally should not happen :(
  835. try {
  836. roleList.add((Role)currResult);
  837. } catch (IllegalArgumentException exc) {
  838. throw new RuntimeException(exc.getMessage());
  839. }
  840. } else if (currResult instanceof RoleUnresolved) {
  841. // Can throw IllegalArgumentException if role is null
  842. // (normally should not happen :(
  843. try {
  844. roleUnresList.add((RoleUnresolved)currResult);
  845. } catch (IllegalArgumentException exc) {
  846. throw new RuntimeException(exc.getMessage());
  847. }
  848. }
  849. }
  850. RoleResult result = new RoleResult(roleList, roleUnresList);
  851. if (isDebugOn())
  852. debug("getRolesInt: exiting", null);
  853. return result;
  854. }
  855. // Returns all roles present in the relation
  856. //
  857. // -return a RoleResult object, including a RoleList (for roles
  858. // successfully retrieved) and a RoleUnresolvedList (for roles not
  859. // readable).
  860. //
  861. // -exception IllegalArgumentException if null parameter
  862. // -exception RelationServiceNotRegisteredException if the Relation
  863. // Service is not registered in the MBean Server
  864. //
  865. RoleResult getAllRolesInt(boolean theRelServCallFlg,
  866. RelationService theRelServ)
  867. throws IllegalArgumentException,
  868. RelationServiceNotRegisteredException {
  869. if (theRelServCallFlg && theRelServ == null) {
  870. // Revisit [cebro] Localize message
  871. String excMsg = "Invalid parameter.";
  872. throw new IllegalArgumentException(excMsg);
  873. }
  874. if (isDebugOn())
  875. debug("getAllRolesInt: entering", null);
  876. ArrayList roleNameList = null;
  877. synchronized(myRoleName2ValueMap) {
  878. roleNameList =
  879. new ArrayList(myRoleName2ValueMap.keySet());
  880. }
  881. String[] roleNames = new String[roleNameList.size()];
  882. int i = 0;
  883. for (Iterator roleNameIter = roleNameList.iterator();
  884. roleNameIter.hasNext();) {
  885. String currRoleName = (String)(roleNameIter.next());
  886. roleNames[i] = currRoleName;
  887. i++;
  888. }
  889. RoleResult result = getRolesInt(roleNames,
  890. theRelServCallFlg,
  891. theRelServ);
  892. if (isDebugOn())
  893. debug("getAllRolesInt: exiting", null);
  894. return result;
  895. }
  896. // Sets the role with given value
  897. //
  898. // This method is called in setRole() above.
  899. // It is also called by the Relation Service setRole() method.
  900. // It is also called in setRolesInt() method below (used in setRoles()
  901. // above and in RelationService setRoles() method).
  902. //
  903. // Will check the role according to its corresponding role definition
  904. // provided in relation's relation type
  905. // Will send a notification (RelationNotification with type
  906. // RELATION_BASIC_UPDATE or RELATION_MBEAN_UPDATE, depending if the
  907. // relation is a MBean or not) if not initialisation of role.
  908. //
  909. // -param theRole role to be set (name and new value)
  910. // -param theRelServCallFlg true if call from the Relation Service; this
  911. // will happen if the current RelationSupport object has been created by
  912. // the Relation Service (via createRelation()) method, so direct access is
  913. // possible.
  914. // -param theRelServ reference to Relation Service object, if internal
  915. // relation
  916. // -param theMultiRoleFlg true if getting the role in the scope of a
  917. // multiple retrieval.
  918. //
  919. // -return (except other "critical" exceptions):
  920. // - for single role retrieval (theMultiRoleFlg false):
  921. // - null if the role has been set
  922. // - raise an InvalidRoleValueException
  923. // else
  924. // - for multi-role retrieval (theMultiRoleFlg true):
  925. // - the Role object for given role name if role has been set
  926. // - a RoleUnresolved object with problem else.
  927. //
  928. // -exception IllegalArgumentException if null parameter
  929. // -exception RoleNotFoundException if theMultiRoleFlg is false and:
  930. // - internal relation and the role does not exist
  931. // or
  932. // - existing role (i.e. not initialising it) and the role is not
  933. // writable.
  934. // -exception InvalidRoleValueException iftheMultiRoleFlg is false and
  935. // value provided for:
  936. // - the number of referenced MBeans in given value is less than
  937. // expected minimum degree
  938. // or
  939. // - the number of referenced MBeans in provided value exceeds expected
  940. // maximum degree
  941. // or
  942. // - one referenced MBean in the value is not an Object of the MBean
  943. // class expected for that role
  944. // or
  945. // - a MBean provided for that role does not exist
  946. // -exception RelationServiceNotRegisteredException if the Relation
  947. // Service is not registered in the MBean Server
  948. // -exception RelationTypeNotFoundException if relation type unknown
  949. // -exception RelationNotFoundException if a relation MBean has not been
  950. // added in the Relation Service
  951. Object setRoleInt(Role theRole,
  952. boolean theRelServCallFlg,
  953. RelationService theRelServ,
  954. boolean theMultiRoleFlg)
  955. throws IllegalArgumentException,
  956. RoleNotFoundException,
  957. InvalidRoleValueException,
  958. RelationServiceNotRegisteredException,
  959. RelationTypeNotFoundException,
  960. RelationNotFoundException {
  961. if (theRole == null ||
  962. (theRelServCallFlg && theRelServ == null)) {
  963. // Revisit [cebro] Localize message
  964. String excMsg = "Invalid parameter.";
  965. throw new IllegalArgumentException(excMsg);
  966. }
  967. if (isDebugOn()) {
  968. String str =
  969. "theRole " + theRole
  970. + ", theRelServCallFlg " + theRelServCallFlg
  971. + ", theMultiRoleFlg " + theMultiRoleFlg;
  972. debug("setRoleInt: entering" , str);
  973. }
  974. String roleName = theRole.getRoleName();
  975. int pbType = 0;
  976. // Checks if role exists in the relation
  977. // No error if the role does not exist in the relation, to be able to
  978. // handle initialisation of role when creating the relation
  979. // (roles provided in the RoleList parameter are directly set but
  980. // roles automatically initialised are set using setRole())
  981. Role role = null;
  982. synchronized(myRoleName2ValueMap) {
  983. role = (Role)(myRoleName2ValueMap.get(roleName));
  984. }
  985. ArrayList oldRoleValue = null;
  986. Boolean initFlg = null;
  987. if (role == null) {
  988. initFlg = new Boolean(true);
  989. oldRoleValue = new ArrayList();
  990. } else {
  991. initFlg = new Boolean(false);
  992. oldRoleValue = (ArrayList)(role.getRoleValue());
  993. }
  994. // Checks if the role can be set: is writable (except if
  995. // initialisation) and correct value
  996. try {
  997. Integer status = null;
  998. if (theRelServCallFlg) {
  999. // Call from the Relation Service, so direct access to it,
  1000. // avoiding MBean Server
  1001. //
  1002. // Shall not raise a RelationTypeNotFoundException
  1003. status = theRelServ.checkRoleWriting(theRole,
  1004. myRelTypeName,
  1005. initFlg);
  1006. } else {
  1007. // Call from setRole() method above
  1008. // So we have a MBean. We must access the Relation Service
  1009. // via the MBean Server.
  1010. Object[] params = new Object[3];
  1011. params[0] = theRole;
  1012. params[1] = myRelTypeName;
  1013. params[2] = initFlg;
  1014. String[] signature = new String[3];
  1015. signature[0] = "javax.management.relation.Role";
  1016. signature[1] = "java.lang.String";
  1017. signature[2] = "java.lang.Boolean";
  1018. // Can throw InstanceNotFoundException if the Relation Service
  1019. // is not registered (to be transformed into
  1020. // RelationServiceNotRegisteredException in any case).
  1021. //
  1022. // Can throw a MBeanException wrapping a
  1023. // RelationTypeNotFoundException:
  1024. // throw wrapped exception.
  1025. //
  1026. // Shall not throw a ReflectionException
  1027. status = (Integer)
  1028. (myRelServiceMBeanServer.invoke(myRelServiceName,
  1029. "checkRoleWriting",
  1030. params,
  1031. signature));
  1032. }
  1033. pbType = status.intValue();
  1034. } catch (MBeanException exc2) {
  1035. // Retrieves underlying exception
  1036. Exception wrappedExc = exc2.getTargetException();
  1037. if (wrappedExc instanceof RelationTypeNotFoundException) {
  1038. throw ((RelationTypeNotFoundException)wrappedExc);
  1039. } else {
  1040. throw new RuntimeException(wrappedExc.getMessage());
  1041. }
  1042. } catch (ReflectionException exc3) {
  1043. throw new RuntimeException(exc3.getMessage());
  1044. } catch (RelationTypeNotFoundException exc4) {
  1045. throw new RuntimeException(exc4.getMessage());
  1046. } catch (InstanceNotFoundException exc5) {
  1047. throw new RelationServiceNotRegisteredException(exc5.getMessage());
  1048. }
  1049. Object result = null;
  1050. if (pbType == 0) {
  1051. // Role can be set
  1052. if (!(initFlg.booleanValue())) {
  1053. // Not initialising the role
  1054. // If role being initialised:
  1055. // - do not send an update notification
  1056. // - do not try to update internal map of Relation Service
  1057. // listing referenced MBeans, as role is initialised to an
  1058. // empty list
  1059. // Sends a notification (RelationNotification)
  1060. // Can throw a RelationNotFoundException
  1061. sendRoleUpdateNotification(theRole,
  1062. oldRoleValue,
  1063. theRelServCallFlg,
  1064. theRelServ);
  1065. // Updates the role map of the Relation Service
  1066. // Can throw RelationNotFoundException
  1067. updateRelationServiceMap(theRole,
  1068. oldRoleValue,
  1069. theRelServCallFlg,
  1070. theRelServ);
  1071. }
  1072. // Sets the role
  1073. synchronized(myRoleName2ValueMap) {
  1074. myRoleName2ValueMap.put(roleName,
  1075. (Role)(theRole.clone()));
  1076. }
  1077. // Single role set: returns null: nothing to set in result
  1078. if (theMultiRoleFlg) {
  1079. // Multi-roles retrieval: returns the role
  1080. result = theRole;
  1081. }
  1082. } else {
  1083. // Role not set
  1084. if (!(theMultiRoleFlg)) {
  1085. // Problem when setting a simple role: either role not
  1086. // found, not writable, or incorrect value:
  1087. // raises appropriate exception, RoleNotFoundException or
  1088. // InvalidRoleValueException
  1089. RelationService.throwRoleProblemException(pbType,
  1090. roleName);
  1091. // To keep compiler happy :)
  1092. return null;
  1093. } else {
  1094. // Problem when retrieving a role in a multi-role retrieval:
  1095. // returns a RoleUnresolved object
  1096. result = new RoleUnresolved(roleName,
  1097. theRole.getRoleValue(),
  1098. pbType);
  1099. }
  1100. }
  1101. if (isDebugOn())
  1102. debug("setRoleInt: exiting", null);
  1103. return result;
  1104. }
  1105. // Requires the Relation Service to send a notification
  1106. // RelationNotification, with type being either:
  1107. // - RelationNotification.RELATION_BASIC_UPDATE if the updated relation is
  1108. // a relation internal to the Relation Service
  1109. // - RelationNotification.RELATION_MBEAN_UPDATE if the updated relation is
  1110. // a relation MBean.
  1111. //
  1112. // -param theNewRole new role
  1113. // -param theOldRoleValue old role value (ArrayList of ObjectNames)
  1114. // -param theRelServCallFlg true if call from the Relation Service; this
  1115. // will happen if the current RelationSupport object has been created by
  1116. // the Relation Service (via createRelation()) method, so direct access is
  1117. // possible.
  1118. // -param theRelServ reference to Relation Service object, if object
  1119. // created by Relation Service.
  1120. //
  1121. // -exception IllegalArgumentException if null parameter provided
  1122. // -exception RelationServiceNotRegisteredException if the Relation
  1123. // Service is not registered in the MBean Server
  1124. // -exception RelationNotFoundException if:
  1125. // - relation MBean
  1126. // and
  1127. // - it has not been added into the Relation Service
  1128. private void sendRoleUpdateNotification(Role theNewRole,
  1129. List theOldRoleValue,
  1130. boolean theRelServCallFlg,
  1131. RelationService theRelServ)
  1132. throws IllegalArgumentException,
  1133. RelationServiceNotRegisteredException,
  1134. RelationNotFoundException {
  1135. if (theNewRole == null ||
  1136. theOldRoleValue == null ||
  1137. (theRelServCallFlg && theRelServ == null)) {
  1138. // Revisit [cebro] Localize message
  1139. String excMsg = "Invalid parameter.";
  1140. throw new IllegalArgumentException(excMsg);
  1141. }
  1142. if (isDebugOn()) {
  1143. String str =
  1144. "theNewRole " + theNewRole
  1145. + ", theOldRoleValue " + theOldRoleValue
  1146. + ", theRelServCallFlg " + theRelServCallFlg;
  1147. debug("sendRoleUpdateNotification: entering", str);
  1148. }
  1149. if (theRelServCallFlg) {
  1150. // Direct call to the Relation Service
  1151. // Shall not throw a RelationNotFoundException for an internal
  1152. // relation
  1153. try {
  1154. theRelServ.sendRoleUpdateNotification(myRelId,
  1155. theNewRole,
  1156. theOldRoleValue);
  1157. } catch (RelationNotFoundException exc) {
  1158. throw new RuntimeException(exc.getMessage());
  1159. }
  1160. } else {
  1161. Object[] params = new Object[3];
  1162. params[0] = myRelId;
  1163. params[1] = theNewRole;
  1164. params[2] = ((ArrayList)theOldRoleValue);
  1165. String[] signature = new String[3];
  1166. signature[0] = "java.lang.String";
  1167. signature[1] = "javax.management.relation.Role";
  1168. signature[2] = "java.util.List";
  1169. // Can throw InstanceNotFoundException if the Relation Service
  1170. // is not registered (to be transformed).
  1171. //
  1172. // Can throw a MBeanException wrapping a
  1173. // RelationNotFoundException (to be raised in any case): wrapped
  1174. // exception to be thrown
  1175. //
  1176. // Shall not throw a ReflectionException
  1177. try {
  1178. myRelServiceMBeanServer.invoke(myRelServiceName,
  1179. "sendRoleUpdateNotification",
  1180. params,
  1181. signature);
  1182. } catch (ReflectionException exc1) {
  1183. throw new RuntimeException(exc1.getMessage());
  1184. } catch (InstanceNotFoundException exc2) {
  1185. throw new RelationServiceNotRegisteredException(
  1186. exc2.getMessage());
  1187. } catch (MBeanException exc3) {
  1188. Exception wrappedExc = exc3.getTargetException();
  1189. if (wrappedExc instanceof RelationNotFoundException) {
  1190. throw ((RelationNotFoundException)wrappedExc);
  1191. } else {
  1192. throw new RuntimeException(wrappedExc.getMessage());
  1193. }
  1194. }
  1195. }
  1196. if (isDebugOn())
  1197. debug("sendRoleUpdateNotification: exiting", null);
  1198. return;
  1199. }
  1200. // Requires the Relation Service to update its internal map handling
  1201. // MBeans referenced in relations.
  1202. // The Relation Service will also update its recording as a listener to
  1203. // be informed about unregistration of new referenced MBeans, and no longer
  1204. // informed of MBeans no longer referenced.
  1205. //
  1206. // -param theNewRole new role
  1207. // -param theOldRoleValue old role value (ArrayList of ObjectNames)
  1208. // -param theRelServCallFlg true if call from the Relation Service; this
  1209. // will happen if the current RelationSupport object has been created by
  1210. // the Relation Service (via createRelation()) method, so direct access is
  1211. // possible.
  1212. // -param theRelServ reference to Relation Service object, if object
  1213. // created by Relation Service.
  1214. //
  1215. // -exception IllegalArgumentException if null parameter
  1216. // -exception RelationServiceNotRegisteredException if the Relation
  1217. // Service is not registered in the MBean Server
  1218. // -exception RelationNotFoundException if:
  1219. // - relation MBean
  1220. // and
  1221. // - the relation is not added in the Relation Service
  1222. private void updateRelationServiceMap(Role theNewRole,
  1223. List theOldRoleValue,
  1224. boolean theRelServCallFlg,
  1225. RelationService theRelServ)
  1226. throws IllegalArgumentException,
  1227. RelationServiceNotRegisteredException,
  1228. RelationNotFoundException {
  1229. if (theNewRole == null ||
  1230. theOldRoleValue == null ||
  1231. (theRelServCallFlg && theRelServ == null)) {
  1232. // Revisit [cebro] Localize message
  1233. String excMsg = "Invalid parameter.";
  1234. throw new IllegalArgumentException(excMsg);
  1235. }
  1236. if (isDebugOn()) {
  1237. String str =
  1238. "theNewRole " + theNewRole
  1239. + ", theOldRoleValue " + theOldRoleValue
  1240. + ", theRelServCallFlg " + theRelServCallFlg;
  1241. debug("updateRelationServiceMap: entering", str);
  1242. }
  1243. if (theRelServCallFlg) {
  1244. // Direct call to the Relation Service
  1245. // Shall not throw a RelationNotFoundException
  1246. try {
  1247. theRelServ.updateRoleMap(myRelId,
  1248. theNewRole,
  1249. theOldRoleValue);
  1250. } catch (RelationNotFoundException exc) {
  1251. throw new RuntimeException(exc.getMessage());
  1252. }
  1253. } else {
  1254. Object[] params = new Object[3];
  1255. params[0] = myRelId;
  1256. params[1] = theNewRole;
  1257. params[2] = theOldRoleValue;
  1258. String[] signature = new String[3];
  1259. signature[0] = "java.lang.String";
  1260. signature[1] = "javax.management.relation.Role";
  1261. signature[2] = "java.util.List";
  1262. // Can throw InstanceNotFoundException if the Relation Service
  1263. // is not registered (to be transformed).
  1264. // Can throw a MBeanException wrapping a RelationNotFoundException:
  1265. // wrapped exception to be thrown
  1266. //
  1267. // Shall not throw a ReflectionException
  1268. try {
  1269. myRelServiceMBeanServer.invoke(myRelServiceName,
  1270. "updateRoleMap",
  1271. params,
  1272. signature);
  1273. } catch (ReflectionException exc1) {
  1274. throw new RuntimeException(exc1.getMessage());
  1275. } catch (InstanceNotFoundException exc2) {
  1276. throw new
  1277. RelationServiceNotRegisteredException(exc2.getMessage());
  1278. } catch (MBeanException exc3) {
  1279. Exception wrappedExc = exc3.getTargetException();
  1280. if (wrappedExc instanceof RelationNotFoundException) {
  1281. throw ((RelationNotFoundException)wrappedExc);
  1282. } else {
  1283. throw new RuntimeException(wrappedExc.getMessage());
  1284. }
  1285. }
  1286. }
  1287. if (isDebugOn())
  1288. debug("updateRelationServiceMap: exiting", null);
  1289. return;
  1290. }
  1291. // Sets the given roles
  1292. // For each role:
  1293. // - will check the role according to its corresponding role definition
  1294. // provided in relation's relation type
  1295. // - will send a notification (RelationNotification with type
  1296. // RELATION_BASIC_UPDATE or RELATION_MBEAN_UPDATE, depending if the
  1297. // relation is a MBean or not) for each updated role.
  1298. //
  1299. // This method is called in setRoles() above and in Relation Service
  1300. // setRoles() method.
  1301. //
  1302. // -param theRoleList list of roles to be set
  1303. // -param theRelServCallFlg true if call from the Relation Service; this
  1304. // will happen if the current RelationSupport object has been created by
  1305. // the Relation Service (via createRelation()) method, so direct access is
  1306. // possible.
  1307. // -param theRelServ reference to Relation Service object, if object
  1308. // created by Relation Service.
  1309. //
  1310. // -return a RoleResult object
  1311. //
  1312. // -exception IllegalArgumentException if null parameter
  1313. // -exception RelationServiceNotRegisteredException if the Relation
  1314. // Service is not registered in the MBean Server
  1315. // -exception RelationTypeNotFoundException if:
  1316. // - relation MBean
  1317. // and
  1318. // - unknown relation type
  1319. // -exception RelationNotFoundException if:
  1320. // - relation MBean
  1321. // and
  1322. // - not added in the RS
  1323. RoleResult setRolesInt(RoleList theRoleList,
  1324. boolean theRelServCallFlg,
  1325. RelationService theRelServ)
  1326. throws IllegalArgumentException,
  1327. RelationServiceNotRegisteredException,
  1328. RelationTypeNotFoundException,
  1329. RelationNotFoundException {
  1330. if (theRoleList == null ||
  1331. (theRelServCallFlg && theRelServ == null)) {
  1332. // Revisit [cebro] Localize message
  1333. String excMsg = "Invalid parameter.";
  1334. throw new IllegalArgumentException(excMsg);
  1335. }
  1336. if (isDebugOn()) {
  1337. String str =
  1338. "theRoleList " + theRoleList
  1339. + ", theRelServCallFlg " + theRelServCallFlg;
  1340. debug("setRolesInt: entering", str);
  1341. }
  1342. RoleList roleList = new RoleList();
  1343. RoleUnresolvedList roleUnresList = new RoleUnresolvedList();
  1344. for (Iterator roleIter = theRoleList.iterator();
  1345. roleIter.hasNext();) {
  1346. Role currRole = (Role)(roleIter.next());
  1347. Object currResult = null;
  1348. // Can throw:
  1349. // RelationServiceNotRegisteredException,
  1350. // RelationTypeNotFoundException
  1351. //
  1352. // Will not throw, due to parameters, RoleNotFoundException or
  1353. // InvalidRoleValueException, but catch them to keep compiler
  1354. // happy
  1355. try {
  1356. currResult = setRoleInt(currRole,
  1357. theRelServCallFlg,
  1358. theRelServ,
  1359. true);
  1360. } catch (RoleNotFoundException exc1) {
  1361. // OK : Do not throw a RoleNotFoundException.
  1362. } catch (InvalidRoleValueException exc2) {
  1363. // OK : Do not throw an InvalidRoleValueException.
  1364. }
  1365. if (currResult instanceof Role) {
  1366. // Can throw IllegalArgumentException if role is null
  1367. // (normally should not happen :(
  1368. try {
  1369. roleList.add((Role)currResult);
  1370. } catch (IllegalArgumentException exc) {
  1371. throw new RuntimeException(exc.getMessage());
  1372. }
  1373. } else if (currResult instanceof RoleUnresolved) {
  1374. // Can throw IllegalArgumentException if role is null
  1375. // (normally should not happen :(
  1376. try {
  1377. roleUnresList.add((RoleUnresolved)currResult);
  1378. } catch (IllegalArgumentException exc) {
  1379. throw new RuntimeException(exc.getMessage());
  1380. }
  1381. }
  1382. }
  1383. RoleResult result = new RoleResult(roleList, roleUnresList);
  1384. if (isDebugOn())
  1385. debug("setRolesInt: exiting", null);
  1386. return result;
  1387. }
  1388. // Initialises all members
  1389. //
  1390. // -param theRelId relation identifier, to identify the relation in the
  1391. // Relation Service.
  1392. // Expected to be unique in the given Relation Service.
  1393. // -param theRelServiceName ObjectName of the Relation Service where
  1394. // the relation will be registered.
  1395. // It is required as this is the Relation Service that is aware of the
  1396. // definition of the relation type of given relation, so that will be able
  1397. // to check update operations (set). Direct access via the Relation
  1398. // Service (RelationService.setRole()) do not need this information but
  1399. // as any user relation is a MBean, setRole() is part of its management
  1400. // interface and can be called directly on the user relation MBean. So the
  1401. // user relation MBean must be aware of the Relation Service where it will
  1402. // be added.
  1403. // -param theRelTypeName Name of relation type.
  1404. // Expected to have been created in given Relation Service.
  1405. // -param theRoleList list of roles (Role objects) to initialised the
  1406. // relation. Can be null.
  1407. // Expected to conform to relation info in associated relation type.
  1408. //
  1409. // -exception InvalidRoleValueException if the same name is used for two
  1410. // roles.
  1411. // -exception IllegalArgumentException if a required value (Relation
  1412. // Service Object Name, etc.) is not provided as parameter.
  1413. private void initMembers(String theRelId,
  1414. ObjectName theRelServiceName,
  1415. MBeanServer theRelServiceMBeanServer,
  1416. String theRelTypeName,
  1417. RoleList theRoleList)
  1418. throws InvalidRoleValueException,
  1419. IllegalArgumentException {
  1420. if (theRelId == null ||
  1421. theRelServiceName == null ||
  1422. theRelTypeName == null) {
  1423. // Revisit [cebro] Localize message
  1424. String excMsg = "Invalid parameter.";
  1425. throw new IllegalArgumentException(excMsg);
  1426. }
  1427. if (isDebugOn()) {
  1428. StringBuffer strB =
  1429. new StringBuffer("theRelId " + theRelId
  1430. + ", theRelServiceName "
  1431. + theRelServiceName.toString()
  1432. + ", theRelTypeName " + theRelTypeName);
  1433. if (theRoleList != null) {
  1434. strB.append(", theRoleList " + theRoleList.toString());
  1435. }
  1436. debug("initMembers: entering", strB.toString());
  1437. }
  1438. myRelId = theRelId;
  1439. myRelServiceName = theRelServiceName;
  1440. myRelServiceMBeanServer = theRelServiceMBeanServer;
  1441. myRelTypeName = theRelTypeName;
  1442. // Can throw InvalidRoleValueException
  1443. initRoleMap(theRoleList);
  1444. myInRelServFlg = new Boolean(false);
  1445. if (isDebugOn())
  1446. debug("initMembers: exiting", null);
  1447. return;
  1448. }
  1449. // Initialise the internal role map from given RoleList parameter
  1450. //
  1451. // -param theRoleList role list. Can be null.
  1452. // As it is a RoleList object, it cannot include null (rejected).
  1453. //
  1454. // -exception InvalidRoleValueException if the same role name is used for
  1455. // several roles.
  1456. //
  1457. private void initRoleMap(RoleList theRoleList)
  1458. throws InvalidRoleValueException {
  1459. if (theRoleList == null) {
  1460. return;
  1461. }
  1462. if (isDebugOn())
  1463. debug("initRoleMap: entering", theRoleList.toString());
  1464. synchronized(myRoleName2ValueMap) {
  1465. for (Iterator roleIter = theRoleList.iterator();
  1466. roleIter.hasNext();) {
  1467. // No need to check if role is null, it is not allowed to store
  1468. // a null role in a RoleList :)
  1469. Role currRole = (Role)(roleIter.next());
  1470. String currRoleName = currRole.getRoleName();
  1471. if (myRoleName2ValueMap.containsKey(currRoleName)) {
  1472. // Role already provided in current list
  1473. // Revisit [cebro] Localize message
  1474. StringBuffer excMsgStrB = new StringBuffer("Role name ");
  1475. excMsgStrB.append(currRoleName);
  1476. excMsgStrB.append(" used for two roles.");
  1477. throw new InvalidRoleValueException(excMsgStrB.toString());
  1478. }
  1479. myRoleName2ValueMap.put(currRoleName,
  1480. (Role)(currRole.clone()));
  1481. }
  1482. }
  1483. if (isDebugOn())
  1484. debug("initRoleMap: exiting", null);
  1485. return;
  1486. }
  1487. // Callback used by the Relation Service when a MBean referenced in a role
  1488. // is unregistered.
  1489. // The Relation Service will call this method to let the relation
  1490. // take action to reflect the impact of such unregistration.
  1491. // Current implementation is to set the role with its current value
  1492. // (list of ObjectNames of referenced MBeans) without the unregistered
  1493. // one.
  1494. //
  1495. // -param theObjName ObjectName of unregistered MBean
  1496. // -param theRoleName name of role where the MBean is referenced
  1497. // -param theRelServCallFlg true if call from the Relation Service; this
  1498. // will happen if the current RelationSupport object has been created by
  1499. // the Relation Service (via createRelation()) method, so direct access is
  1500. // possible.
  1501. // -param theRelServ reference to Relation Service object, if internal
  1502. // relation
  1503. //
  1504. // -exception IllegalArgumentException if null parameter
  1505. // -exception RoleNotFoundException if:
  1506. // - the role does not exist
  1507. // or
  1508. // - role not writable.
  1509. // -exception InvalidRoleValueException if value provided for:
  1510. // - the number of referenced MBeans in given value is less than
  1511. // expected minimum degree
  1512. // or
  1513. // - the number of referenced MBeans in provided value exceeds expected
  1514. // maximum degree
  1515. // or
  1516. // - one referenced MBean in the value is not an Object of the MBean
  1517. // class expected for that role
  1518. // or
  1519. // - a MBean provided for that role does not exist
  1520. // -exception RelationServiceNotRegisteredException if the Relation
  1521. // Service is not registered in the MBean Server
  1522. // -exception RelationTypeNotFoundException if unknown relation type
  1523. // -exception RelationNotFoundException if current relation has not been
  1524. // added in the RS
  1525. void handleMBeanUnregistrationInt(ObjectName theObjName,
  1526. String theRoleName,
  1527. boolean theRelServCallFlg,
  1528. RelationService theRelServ)
  1529. throws IllegalArgumentException,
  1530. RoleNotFoundException,
  1531. InvalidRoleValueException,
  1532. RelationServiceNotRegisteredException,
  1533. RelationTypeNotFoundException,
  1534. RelationNotFoundException {
  1535. if (theObjName == null ||
  1536. theRoleName == null ||
  1537. (theRelServCallFlg && theRelServ == null)) {
  1538. // Revisit [cebro] Localize message
  1539. String excMsg = "Invalid parameter.";
  1540. throw new IllegalArgumentException(excMsg);
  1541. }
  1542. if (isDebugOn()) {
  1543. String str =
  1544. "theObjName " + theObjName
  1545. + ", theRoleName " + theRoleName
  1546. + ", theRelServCallFlg " + theRelServCallFlg;
  1547. debug("handleMBeanUnregistrationInt: entering", str);
  1548. }
  1549. // Retrieves current role value
  1550. Role role = null;
  1551. synchronized(myRoleName2ValueMap) {
  1552. role = (Role)(myRoleName2ValueMap.get(theRoleName));
  1553. }
  1554. if (role == null) {
  1555. StringBuffer excMsgStrB = new StringBuffer();
  1556. // Revisit [cebro] Localize message
  1557. String excMsg = "No role with name ";
  1558. excMsgStrB.append(excMsg);
  1559. excMsgStrB.append(theRoleName);
  1560. throw new RoleNotFoundException(excMsgStrB.toString());
  1561. }
  1562. ArrayList currRoleValue = (ArrayList)(role.getRoleValue());
  1563. // Note: no need to test if list not null before cloning, null value
  1564. // not allowed for role value.
  1565. ArrayList newRoleValue = (ArrayList)(currRoleValue.clone());
  1566. newRoleValue.remove(theObjName);
  1567. Role newRole = new Role(theRoleName, newRoleValue);
  1568. // Can throw InvalidRoleValueException,
  1569. // RelationTypeNotFoundException
  1570. // (RoleNotFoundException already detected)
  1571. Object result =
  1572. setRoleInt(newRole, theRelServCallFlg, theRelServ, false);
  1573. if (isDebugOn())
  1574. debug("handleMBeanUnregistrationInt: exiting", null);
  1575. return;
  1576. }
  1577. // stuff for Tracing
  1578. private static String localClassName = "RelationSupport";
  1579. // trace level
  1580. private boolean isTraceOn() {
  1581. return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_RELATION);
  1582. }
  1583. // private void trace(String className, String methodName, String info) {
  1584. // Trace.send(Trace.LEVEL_TRACE, Trace.INFO_RELATION, className, methodName, info);
  1585. // }
  1586. private void trace(String methodName, String info) {
  1587. Trace.send(Trace.LEVEL_TRACE, Trace.INFO_RELATION, localClassName, methodName, info);
  1588. Trace.send(Trace.LEVEL_TRACE, Trace.INFO_RELATION, "", "", "\n");
  1589. }
  1590. // private void trace(String className, String methodName, Exception e) {
  1591. // Trace.send(Trace.LEVEL_TRACE, Trace.INFO_RELATION, className, methodName, e);
  1592. // }
  1593. // private void trace(String methodName, Exception e) {
  1594. // Trace.send(Trace.LEVEL_TRACE, Trace.INFO_RELATION, localClassName, methodName, e);
  1595. // }
  1596. // debug level
  1597. private boolean isDebugOn() {
  1598. return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_RELATION);
  1599. }
  1600. // private void debug(String className, String methodName, String info) {
  1601. // Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_RELATION, className, methodName, info);
  1602. // }
  1603. private void debug(String methodName, String info) {
  1604. Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_RELATION, localClassName, methodName, info);
  1605. Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_RELATION, "", "", "\n");
  1606. }
  1607. // private void debug(String className, String methodName, Exception e) {
  1608. // Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_RELATION, className, methodName, e);
  1609. // }
  1610. // private void debug(String methodName, Exception e) {
  1611. // Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_RELATION, localClassName, methodName, e);
  1612. // }
  1613. }