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