KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > management > relation > RelationService


1 /*
2  * @(#)RelationService.java 1.42 04/04/13
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.management.relation;
9
10 import javax.management.Attribute JavaDoc;
11 import javax.management.AttributeNotFoundException JavaDoc;
12 import javax.management.NotificationListener JavaDoc;
13 import javax.management.ObjectName JavaDoc;
14 import javax.management.NotCompliantMBeanException JavaDoc;
15 import javax.management.Notification JavaDoc;
16 import javax.management.NotificationBroadcasterSupport JavaDoc;
17 import javax.management.MBeanRegistration JavaDoc;
18 import javax.management.MBeanServer JavaDoc;
19 import javax.management.ListenerNotFoundException JavaDoc;
20 import javax.management.InstanceNotFoundException JavaDoc;
21 import javax.management.InvalidAttributeValueException JavaDoc;
22 import javax.management.MBeanException JavaDoc;
23 import javax.management.ReflectionException JavaDoc;
24 import javax.management.MBeanServerNotification JavaDoc;
25 import javax.management.MBeanNotificationInfo JavaDoc;
26 import javax.management.MalformedObjectNameException JavaDoc;
27
28 import com.sun.jmx.defaults.ServiceName;
29
30 import com.sun.jmx.trace.Trace;
31
32 import java.util.ArrayList JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.Iterator JavaDoc;
35 import java.util.Set JavaDoc;
36 import java.util.List JavaDoc;
37 import java.util.Map JavaDoc;
38 import java.util.Date JavaDoc;
39
40 /**
41  * The Relation Service is in charge of creating and deleting relation types
42  * and relations, of handling the consistency and of providing query
43  * mechanisms.
44  * <P>It implements the NotificationBroadcaster by extending
45  * NotificationBroadcasterSupport to send notifications when a relation is
46  * removed from it.
47  * <P>It implements the NotificationListener interface to be able to receive
48  * notifications concerning unregistration of MBeans referenced in relation
49  * roles and of relation MBeans.
50  * <P>It implements the MBeanRegistration interface to be able to retrieve
51  * its ObjectName and MBean Server.
52  *
53  * @since 1.5
54  */

55 public class RelationService extends NotificationBroadcasterSupport JavaDoc
56     implements RelationServiceMBean JavaDoc, MBeanRegistration JavaDoc, NotificationListener JavaDoc {
57
58     //
59
// Private members
60
//
61

62     // Map associating:
63
// <relation id> -> <RelationSupport object/ObjectName>
64
// depending if the relation has been created using createRelation()
65
// method (so internally handled) or is an MBean added as a relation by the
66
// user
67
private HashMap JavaDoc myRelId2ObjMap = new HashMap JavaDoc();
68
69     // Map associating:
70
// <relation id> -> <relation type name>
71
private HashMap JavaDoc myRelId2RelTypeMap = new HashMap JavaDoc();
72
73     // Map associating:
74
// <relation MBean Object Name> -> <relation id>
75
private HashMap JavaDoc myRelMBeanObjName2RelIdMap = new HashMap JavaDoc();
76
77     // Map associating:
78
// <relation type name> -> <RelationType object>
79
private HashMap JavaDoc myRelType2ObjMap = new HashMap JavaDoc();
80
81     // Map associating:
82
// <relation type name> -> ArrayList of <relation id>
83
// to list all the relations of a given type
84
private HashMap JavaDoc myRelType2RelIdsMap = new HashMap JavaDoc();
85
86     // Map associating:
87
// <ObjectName> -> HashMap
88
// the value HashMap mapping:
89
// <relation id> -> ArrayList of <role name>
90
// to track where a given MBean is referenced.
91
private HashMap JavaDoc myRefedMBeanObjName2RelIdsMap = new HashMap JavaDoc();
92
93     // Flag to indicate if, when a notification is received for the
94
// unregistration of an MBean referenced in a relation, if an immediate
95
// "purge" of the relations (look for the relations no
96
// longer valid) has to be performed , or if that will be performed only
97
// when the purgeRelations method will be explicitly called.
98
// true is immediate purge.
99
private boolean myPurgeFlg = true;
100
101     // Internal counter to provide sequence numbers for notifications sent by:
102
// - the Relation Service
103
// - a relation handled by the Relation Service
104
private Long JavaDoc myNtfSeqNbrCounter = new Long JavaDoc(0);
105
106     // ObjectName used to register the Relation Service in the MBean Server
107
private ObjectName JavaDoc myObjName = null;
108
109     // MBean Server where the Relation Service is registered
110
private MBeanServer JavaDoc myMBeanServer = null;
111
112     // Filter registered in the MBean Server with the Relation Service to be
113
// informed of referenced MBean unregistrations
114
private MBeanServerNotificationFilter JavaDoc myUnregNtfFilter = null;
115
116     // List of unregistration notifications received (storage used if purge
117
// of relations when unregistering a referenced MBean is not immediate but
118
// on user request)
119
private ArrayList JavaDoc myUnregNtfList = new ArrayList JavaDoc();
120
121     //
122
// Constructor
123
//
124

125     /**
126      * Constructor.
127      *
128      * @param theImmediatePurgeFlg flag to indicate when a notification is
129      * received for the unregistration of an MBean referenced in a relation, if
130      * an immediate "purge" of the relations (look for the relations no
131      * longer valid) has to be performed , or if that will be performed only
132      * when the purgeRelations method will be explicitly called.
133      * <P>true is immediate purge.
134      */

135     public RelationService(boolean theImmediatePurgeFlg) {
136
137     if (isTraceOn())
138         trace("Constructor: entering", null);
139
140     setPurgeFlag(theImmediatePurgeFlg);
141
142     if (isTraceOn())
143         trace("Constructor: exiting", null);
144     return;
145     }
146
147     /**
148      * Checks if the Relation Service is active.
149      * Current condition is that the Relation Service must be registered in the
150      * MBean Server
151      *
152      * @exception RelationServiceNotRegisteredException if it is not
153      * registered
154      */

155     public void isActive()
156     throws RelationServiceNotRegisteredException JavaDoc {
157     if (myMBeanServer == null) {
158         // MBean Server not set by preRegister(): relation service not
159
// registered
160
// Revisit [cebro] Localize message
161
String JavaDoc excMsg =
162         "Relation Service not registered in the MBean Server.";
163         throw new RelationServiceNotRegisteredException JavaDoc(excMsg);
164     }
165     return;
166     }
167
168     //
169
// MBeanRegistration interface
170
//
171

172     // Pre-registration: retrieves its ObjectName and MBean Server
173
//
174
// No exception thrown.
175
public ObjectName JavaDoc preRegister(MBeanServer JavaDoc server,
176                   ObjectName JavaDoc name)
177     throws Exception JavaDoc {
178
179     myMBeanServer = server;
180     myObjName = name;
181     return name;
182     }
183
184     // Post-registration: does nothing
185
public void postRegister(Boolean JavaDoc registrationDone) {
186     return;
187     }
188
189     // Pre-unregistration: does nothing
190
public void preDeregister()
191     throws Exception JavaDoc {
192     return;
193     }
194
195     // Post-unregistration: does nothing
196
public void postDeregister() {
197     return;
198     }
199
200     //
201
// Accessors
202
//
203

204     /**
205      * Returns the flag to indicate if when a notification is received for the
206      * unregistration of an MBean referenced in a relation, if an immediate
207      * "purge" of the relations (look for the relations no longer valid)
208      * has to be performed , or if that will be performed only when the
209      * purgeRelations method will be explicitly called.
210      * <P>true is immediate purge.
211      *
212      * @return true if purges are automatic.
213      *
214      * @see #setPurgeFlag
215      */

216     public boolean getPurgeFlag() {
217     return myPurgeFlg;
218     }
219
220     /**
221      * Sets the flag to indicate if when a notification is received for the
222      * unregistration of an MBean referenced in a relation, if an immediate
223      * "purge" of the relations (look for the relations no longer valid)
224      * has to be performed , or if that will be performed only when the
225      * purgeRelations method will be explicitly called.
226      * <P>true is immediate purge.
227      *
228      * @param thePurgeFlg flag
229      *
230      * @see #getPurgeFlag
231      */

232     public void setPurgeFlag(boolean thePurgeFlg) {
233
234     myPurgeFlg = thePurgeFlg;
235     return;
236     }
237
238     // Returns internal counter to be used for Sequence Numbers of
239
// notifications to be raised by:
240
// - a relation handled by this Relation Service (when updated)
241
// - the Relation Service
242
private Long JavaDoc getNotificationSequenceNumber() {
243     Long JavaDoc result = null;
244     synchronized(myNtfSeqNbrCounter) {
245         result = new Long JavaDoc(myNtfSeqNbrCounter.longValue() + 1);
246         myNtfSeqNbrCounter = new Long JavaDoc(result.longValue());
247     }
248     return result;
249     }
250
251     //
252
// Relation type handling
253
//
254

255     /**
256      * Creates a relation type (a RelationTypeSupport object) with given
257      * role infos (provided by the RoleInfo objects), and adds it in the
258      * Relation Service.
259      *
260      * @param theRelTypeName name of the relation type
261      * @param theRoleInfoArray array of role infos
262      *
263      * @exception IllegalArgumentException if null parameter
264      * @exception InvalidRelationTypeException If:
265      * <P>- there is already a relation type with that name
266      * <P>- the same name has been used for two different role infos
267      * <P>- no role info provided
268      * <P>- one null role info provided
269      */

270     public void createRelationType(String JavaDoc theRelTypeName,
271                    RoleInfo JavaDoc[] theRoleInfoArray)
272     throws IllegalArgumentException JavaDoc,
273            InvalidRelationTypeException JavaDoc {
274
275     if (theRelTypeName == null || theRoleInfoArray == null) {
276         // Revisit [cebro] Localize message
277
String JavaDoc excMsg = "Invalid parameter.";
278         throw new IllegalArgumentException JavaDoc(excMsg);
279     }
280
281     if (isTraceOn())
282         trace("createRelationType: entering", theRelTypeName);
283
284     // Can throw an InvalidRelationTypeException
285
RelationType JavaDoc relType =
286         new RelationTypeSupport JavaDoc(theRelTypeName, theRoleInfoArray);
287
288     addRelationTypeInt(relType);
289
290     if (isTraceOn())
291         trace("createRelationType: exiting", null);
292     return;
293     }
294
295     /**
296      * Adds given object as a relation type. The object is expected to
297      * implement the RelationType interface.
298      *
299      * @param theRelTypeObj relation type object (implementing the
300      * RelationType interface)
301      *
302      * @exception IllegalArgumentException if null parameter
303      * @exception InvalidRelationTypeException if:
304      * <P>- the same name has been used for two different roles
305      * <P>- no role info provided
306      * <P>- one null role info provided
307      * <P>- there is already a relation type with that name
308      */

309     public void addRelationType(RelationType JavaDoc theRelTypeObj)
310     throws IllegalArgumentException JavaDoc,
311            InvalidRelationTypeException JavaDoc {
312
313     if (theRelTypeObj == null) {
314         // Revisit [cebro] Localize message
315
String JavaDoc excMsg = "Invalid parameter.";
316         throw new IllegalArgumentException JavaDoc(excMsg);
317     }
318
319     if (isTraceOn())
320         trace("addRelationType: entering", null);
321
322     // Checks the role infos
323
List JavaDoc roleInfoList = theRelTypeObj.getRoleInfos();
324     if (roleInfoList == null) {
325         // Revisit [cebro] Localize message
326
String JavaDoc excMsg = "No role info provided.";
327         throw new InvalidRelationTypeException JavaDoc(excMsg);
328     }
329
330     RoleInfo JavaDoc[] roleInfoArray = new RoleInfo JavaDoc[roleInfoList.size()];
331     int i = 0;
332     for (Iterator JavaDoc roleInfoIter = roleInfoList.iterator();
333          roleInfoIter.hasNext();) {
334         RoleInfo JavaDoc currRoleInfo = (RoleInfo JavaDoc)(roleInfoIter.next());
335         roleInfoArray[i] = currRoleInfo;
336         i++;
337     }
338     // Can throw InvalidRelationTypeException
339
RelationTypeSupport.checkRoleInfos(roleInfoArray);
340
341     addRelationTypeInt(theRelTypeObj);
342
343     if (isTraceOn())
344         trace("addRelationType: exiting", null);
345     return;
346      }
347
348     /**
349      * Retrieves names of all known relation types.
350      *
351      * @return ArrayList of relation type names (Strings)
352      */

353     public List JavaDoc getAllRelationTypeNames() {
354     ArrayList JavaDoc result = null;
355     synchronized(myRelType2ObjMap) {
356         result = new ArrayList JavaDoc(myRelType2ObjMap.keySet());
357     }
358     return result;
359     }
360
361     /**
362      * Retrieves list of role infos (RoleInfo objects) of a given relation
363      * type.
364      *
365      * @param theRelTypeName name of relation type
366      *
367      * @return ArrayList of RoleInfo.
368      *
369      * @exception IllegalArgumentException if null parameter
370      * @exception RelationTypeNotFoundException if there is no relation type
371      * with that name.
372      */

373     public List JavaDoc getRoleInfos(String JavaDoc theRelTypeName)
374     throws IllegalArgumentException JavaDoc,
375            RelationTypeNotFoundException JavaDoc {
376
377     if (theRelTypeName == null) {
378         // Revisit [cebro[ Localize message
379
String JavaDoc excMsg = "Invalid parameter.";
380         throw new IllegalArgumentException JavaDoc(excMsg);
381     }
382
383     if (isTraceOn())
384         trace("getRoleInfos: entering", theRelTypeName);
385
386     // Can throw a RelationTypeNotFoundException
387
RelationType JavaDoc relType = getRelationType(theRelTypeName);
388
389     if (isTraceOn())
390         trace("getRoleInfos: exiting", null);
391     return relType.getRoleInfos();
392     }
393
394     /**
395      * Retrieves role info for given role name of a given relation type.
396      *
397      * @param theRelTypeName name of relation type
398      * @param theRoleInfoName name of role
399      *
400      * @return RoleInfo object.
401      *
402      * @exception IllegalArgumentException if null parameter
403      * @exception RelationTypeNotFoundException if the relation type is not
404      * known in the Relation Service
405      * @exception RoleInfoNotFoundException if the role is not part of the
406      * relation type.
407      */

408     public RoleInfo JavaDoc getRoleInfo(String JavaDoc theRelTypeName,
409                 String JavaDoc theRoleInfoName)
410     throws IllegalArgumentException JavaDoc,
411            RelationTypeNotFoundException JavaDoc,
412                RoleInfoNotFoundException JavaDoc {
413
414     if (theRelTypeName == null || theRoleInfoName == null) {
415         // Revisit [cebro[ Localize message
416
String JavaDoc excMsg = "Invalid parameter.";
417         throw new IllegalArgumentException JavaDoc(excMsg);
418     }
419
420     if (isTraceOn()) {
421         String JavaDoc str = "theRelTypeName " + theRelTypeName
422                     + ", theRoleInfoName " + theRoleInfoName;
423         trace("getRoleInfo: entering", str);
424     }
425
426     // Can throw a RelationTypeNotFoundException
427
RelationType JavaDoc relType = getRelationType(theRelTypeName);
428
429     // Can throw a RoleInfoNotFoundException
430
RoleInfo JavaDoc roleInfo = relType.getRoleInfo(theRoleInfoName);
431
432     if (isTraceOn())
433         trace("getRoleInfo: exiting", null);
434     return roleInfo;
435     }
436
437     /**
438      * Removes given relation type from Relation Service.
439      * <P>The relation objects of that type will be removed from the
440      * Relation Service.
441      *
442      * @param theRelTypeName name of the relation type to be removed
443      *
444      * @exception RelationServiceNotRegisteredException if the Relation
445      * Service is not registered in the MBean Server
446      * @exception IllegalArgumentException if null parameter
447      * @exception RelationTypeNotFoundException If there is no relation type
448      * with that name
449      */

450     public void removeRelationType(String JavaDoc theRelTypeName)
451     throws RelationServiceNotRegisteredException JavaDoc,
452            IllegalArgumentException JavaDoc,
453            RelationTypeNotFoundException JavaDoc {
454
455     // Can throw RelationServiceNotRegisteredException
456
isActive();
457
458     if (theRelTypeName == null) {
459         // Revisit [cebro[ Localize message
460
String JavaDoc excMsg = "Invalid parameter.";
461         throw new IllegalArgumentException JavaDoc(excMsg);
462     }
463
464     if (isTraceOn())
465         trace("removeRelationType: entering", theRelTypeName);
466
467     // Checks if the relation type to be removed exists
468
// Can throw a RelationTypeNotFoundException
469
RelationType JavaDoc relType = getRelationType(theRelTypeName);
470
471     // Retrieves the relation ids for relations of that type
472
ArrayList JavaDoc relIdList = null;
473     synchronized(myRelType2RelIdsMap) {
474         // Note: take a copy of the list as it is a part of a map that
475
// will be updated by removeRelation() below.
476
ArrayList JavaDoc relIdList1 = (ArrayList JavaDoc)
477         (myRelType2RelIdsMap.get(theRelTypeName));
478         if (relIdList1 != null) {
479         relIdList = (ArrayList JavaDoc)(relIdList1.clone());
480         }
481     }
482
483     // Removes the relation type from all maps
484
synchronized(myRelType2ObjMap) {
485         myRelType2ObjMap.remove(theRelTypeName);
486     }
487     synchronized(myRelType2RelIdsMap) {
488         myRelType2RelIdsMap.remove(theRelTypeName);
489     }
490
491     // Removes all relations of that type
492
if (relIdList != null) {
493         for (Iterator JavaDoc relIdIter = relIdList.iterator();
494          relIdIter.hasNext();) {
495         String JavaDoc currRelId = (String JavaDoc)(relIdIter.next());
496         // Note: will remove it from myRelId2RelTypeMap :)
497
//
498
// Can throw RelationServiceNotRegisteredException (detected
499
// above)
500
// Shall not throw a RelationNotFoundException
501
try {
502             removeRelation(currRelId);
503         } catch (RelationNotFoundException JavaDoc exc1) {
504             throw new RuntimeException JavaDoc(exc1.getMessage());
505         }
506         }
507     }
508
509     if (isTraceOn())
510         trace("removeRelationType: exiting", null);
511     return;
512     }
513
514     //
515
// Relation handling
516
//
517

518     /**
519      * Creates a simple relation (represented by a RelationSupport object) of
520      * given relation type, and adds it in the Relation Service.
521      * <P>Roles are initialized according to the role list provided in
522      * parameter. The ones not initialized in this way are set to an empty
523      * ArrayList of ObjectNames.
524      * <P>A RelationNotification, with type RELATION_BASIC_CREATION, is sent.
525      *
526      * @param theRelId relation identifier, to identify uniquely the relation
527      * inside the Relation Service
528      * @param theRelTypeName name of the relation type (has to be created
529      * in the Relation Service)
530      * @param theRoleList role list to initialize roles of the relation (can
531      * be null).
532      *
533      * @exception RelationServiceNotRegisteredException if the Relation
534      * Service is not registered in the MBean Server
535      * @exception IllegalArgumentException if null parameter, except the role
536      * list which can be null if no role initialization
537      * @exception RoleNotFoundException if a value is provided for a role
538      * that does not exist in the relation type
539      * @exception InvalidRelationIdException if relation id already used
540      * @exception RelationTypeNotFoundException if relation type not known in
541      * Relation Service
542      * @exception InvalidRoleValueException if:
543      * <P>- the same role name is used for two different roles
544      * <P>- the number of referenced MBeans in given value is less than
545      * expected minimum degree
546      * <P>- the number of referenced MBeans in provided value exceeds expected
547      * maximum degree
548      * <P>- one referenced MBean in the value is not an Object of the MBean
549      * class expected for that role
550      * <P>- an MBean provided for that role does not exist
551      */

552     public void createRelation(String JavaDoc theRelId,
553                    String JavaDoc theRelTypeName,
554                    RoleList JavaDoc theRoleList)
555     throws RelationServiceNotRegisteredException JavaDoc,
556            IllegalArgumentException JavaDoc,
557                RoleNotFoundException JavaDoc,
558                InvalidRelationIdException JavaDoc,
559                RelationTypeNotFoundException JavaDoc,
560                InvalidRoleValueException JavaDoc {
561
562     // Can throw RelationServiceNotRegisteredException
563
isActive();
564
565     if (theRelId == null ||
566         theRelTypeName == null) {
567         // Revisit [cebro[ Localize message
568
String JavaDoc excMsg = "Invalid parameter.";
569         throw new IllegalArgumentException JavaDoc(excMsg);
570     }
571
572     if (isTraceOn()) {
573         StringBuffer JavaDoc strB =
574         new StringBuffer JavaDoc("theRelId " + theRelId
575                  + ", theRelTypeName " + theRelTypeName);
576         if (theRoleList != null) {
577         strB.append(", theRoleList " + theRoleList.toString());
578         }
579         trace("createRelation: entering", strB.toString());
580     }
581
582     // Creates RelationSupport object
583
// Can throw InvalidRoleValueException
584
RelationSupport JavaDoc relObj = new RelationSupport JavaDoc(theRelId,
585                            myObjName,
586                            theRelTypeName,
587                            theRoleList);
588
589     // Adds relation object as a relation into the Relation Service
590
// Can throw RoleNotFoundException, InvalidRelationId,
591
// RelationTypeNotFoundException, InvalidRoleValueException
592
//
593
// Cannot throw MBeanException
594
addRelationInt(true,
595                relObj,
596                null,
597                theRelId,
598                theRelTypeName,
599                theRoleList);
600
601     if (isTraceOn())
602         trace("createRelation: exiting", null);
603     return;
604     }
605
606     /**
607      * Adds an MBean created by the user (and registered by him in the MBean
608      * Server) as a relation in the Relation Service.
609      * <P>To be added as a relation, the MBean must conform to the
610      * following:
611      * <P>- implement the Relation interface
612      * <P>- have for RelationService ObjectName the ObjectName of current
613      * Relation Service
614      * <P>- have a relation id unique and unused in current Relation Service
615      * <P>- have for relation type a relation type created in the Relation
616      * Service
617      * <P>- have roles conforming to the role info provided in the relation
618      * type.
619      *
620      * @param theRelObjectName ObjectName of the relation MBean to be added.
621      *
622      * @exception IllegalArgumentException if null parameter
623      * @exception RelationServiceNotRegisteredException if the Relation
624      * Service is not registered in the MBean Server
625      * @exception NoSuchMethodException If the MBean does not implement the
626      * Relation interface
627      * @exception InvalidRelationIdException if:
628      * <P>- no relation identifier in MBean
629      * <P>- the relation identifier is already used in the Relation Service
630      * @exception InstanceNotFoundException if the MBean for given ObjectName
631      * has not been registered
632      * @exception InvalidRelationServiceException if:
633      * <P>- no Relation Service name in MBean
634      * <P>- the Relation Service name in the MBean is not the one of the
635      * current Relation Service
636      * @exception RelationTypeNotFoundException if:
637      * <P>- no relation type name in MBean
638      * <P>- the relation type name in MBean does not correspond to a relation
639      * type created in the Relation Service
640      * @exception InvalidRoleValueException if:
641      * <P>- the number of referenced MBeans in a role is less than
642      * expected minimum degree
643      * <P>- the number of referenced MBeans in a role exceeds expected
644      * maximum degree
645      * <P>- one referenced MBean in the value is not an Object of the MBean
646      * class expected for that role
647      * <P>- an MBean provided for a role does not exist
648      * @exception RoleNotFoundException if a value is provided for a role
649      * that does not exist in the relation type
650      */

651     public void addRelation(ObjectName JavaDoc theRelObjectName)
652     throws IllegalArgumentException JavaDoc,
653            RelationServiceNotRegisteredException JavaDoc,
654            NoSuchMethodException JavaDoc,
655            InvalidRelationIdException JavaDoc,
656            InstanceNotFoundException JavaDoc,
657            InvalidRelationServiceException JavaDoc,
658                RelationTypeNotFoundException JavaDoc,
659                RoleNotFoundException JavaDoc,
660            InvalidRoleValueException JavaDoc {
661
662     if (theRelObjectName == null) {
663         // Revisit [cebro[ Localize message
664
String JavaDoc excMsg = "Invalid parameter.";
665         throw new IllegalArgumentException JavaDoc(excMsg);
666     }
667
668     if (isTraceOn())
669         trace("addRelation: entering", theRelObjectName.toString());
670
671     // Can throw RelationServiceNotRegisteredException
672
isActive();
673
674     // Checks that the relation MBean implements the Relation interface.
675
// It will also check that the provided ObjectName corresponds to a
676
// registered MBean (else will throw an InstanceNotFoundException)
677
if ((!(myMBeanServer.isInstanceOf(theRelObjectName, "javax.management.relation.Relation")))) {
678         // Revisit [cebro] Localize message
679
String JavaDoc excMsg = "This MBean does not implement the Relation interface.";
680         throw new NoSuchMethodException JavaDoc(excMsg);
681     }
682     // Checks there is a relation id in the relation MBean (its uniqueness
683
// is checked in addRelationInt())
684
// Can throw InstanceNotFoundException (but detected above)
685
// No MBeanException as no exception raised by this method, and no
686
// ReflectionException
687
String JavaDoc relId = null;
688     try {
689         relId = (String JavaDoc)(myMBeanServer.getAttribute(theRelObjectName,
690                                                         "RelationId"));
691
692     } catch (MBeanException JavaDoc exc1) {
693         throw new RuntimeException JavaDoc(
694                      (exc1.getTargetException()).getMessage());
695     } catch (ReflectionException JavaDoc exc2) {
696         throw new RuntimeException JavaDoc(exc2.getMessage());
697     } catch (AttributeNotFoundException JavaDoc exc3) {
698         throw new RuntimeException JavaDoc(exc3.getMessage());
699     }
700
701     if (relId == null) {
702         // Revisit [cebro] Localize message
703
String JavaDoc excMsg = "This MBean does not provide a relation id.";
704         throw new InvalidRelationIdException JavaDoc(excMsg);
705     }
706     // Checks that the Relation Service where the relation MBean is
707
// expected to be added is the current one
708
// Can throw InstanceNotFoundException (but detected above)
709
// No MBeanException as no exception raised by this method, no
710
// ReflectionException
711
ObjectName JavaDoc relServObjName = null;
712     try {
713         relServObjName = (ObjectName JavaDoc)
714         (myMBeanServer.getAttribute(theRelObjectName,
715                                             "RelationServiceName"));
716
717     } catch (MBeanException JavaDoc exc1) {
718         throw new RuntimeException JavaDoc(
719                      (exc1.getTargetException()).getMessage());
720     } catch (ReflectionException JavaDoc exc2) {
721         throw new RuntimeException JavaDoc(exc2.getMessage());
722     } catch (AttributeNotFoundException JavaDoc exc3) {
723         throw new RuntimeException JavaDoc(exc3.getMessage());
724     }
725
726     boolean badRelServFlg = false;
727     if (relServObjName == null) {
728         badRelServFlg = true;
729
730     } else if (!(relServObjName.equals(myObjName))) {
731         badRelServFlg = true;
732     }
733     if (badRelServFlg) {
734         // Revisit [cebro] Localize message
735
String JavaDoc excMsg = "The Relation Service referenced in the MBean is not the current one.";
736         throw new InvalidRelationServiceException JavaDoc(excMsg);
737     }
738     // Checks that a relation type has been specified for the relation
739
// Can throw InstanceNotFoundException (but detected above)
740
// No MBeanException as no exception raised by this method, no
741
// ReflectionException
742
String JavaDoc relTypeName = null;
743     try {
744         relTypeName = (String JavaDoc)(myMBeanServer.getAttribute(theRelObjectName,
745                                                               "RelationTypeName"));
746
747     } catch (MBeanException JavaDoc exc1) {
748         throw new RuntimeException JavaDoc(
749                      (exc1.getTargetException()).getMessage());
750     }catch (ReflectionException JavaDoc exc2) {
751         throw new RuntimeException JavaDoc(exc2.getMessage());
752     } catch (AttributeNotFoundException JavaDoc exc3) {
753         throw new RuntimeException JavaDoc(exc3.getMessage());
754     }
755     if (relTypeName == null) {
756         // Revisit [cebro] Localize message
757
String JavaDoc excMsg = "No relation type provided.";
758         throw new RelationTypeNotFoundException JavaDoc(excMsg);
759     }
760     // Retrieves all roles without considering read mode
761
// Can throw InstanceNotFoundException (but detected above)
762
// No MBeanException as no exception raised by this method, no
763
// ReflectionException
764
RoleList JavaDoc roleList = null;
765     try {
766         roleList = (RoleList JavaDoc)(myMBeanServer.invoke(theRelObjectName,
767                                "retrieveAllRoles",
768                                null,
769                                null));
770     } catch (MBeanException JavaDoc exc1) {
771         throw new RuntimeException JavaDoc(
772                      (exc1.getTargetException()).getMessage());
773     } catch (ReflectionException JavaDoc exc2) {
774         throw new RuntimeException JavaDoc(exc2.getMessage());
775     }
776
777     // Can throw RoleNotFoundException, InvalidRelationIdException,
778
// RelationTypeNotFoundException, InvalidRoleValueException
779
addRelationInt(false,
780                null,
781                theRelObjectName,
782                relId,
783                relTypeName,
784                roleList);
785     // Adds relation MBean ObjectName in map
786
synchronized(myRelMBeanObjName2RelIdMap) {
787         myRelMBeanObjName2RelIdMap.put(theRelObjectName, relId);
788     }
789
790     // Updates flag to specify that the relation is managed by the Relation
791
// Service
792
// This flag and setter are inherited from RelationSupport and not parts
793
// of the Relation interface, so may be not supported.
794
try {
795         myMBeanServer.setAttribute(theRelObjectName,
796                                        new Attribute JavaDoc(
797                                          "RelationServiceManagementFlag",
798                                          new Boolean JavaDoc(true)));
799     } catch (Exception JavaDoc exc) {
800         // OK : The flag is not supported.
801
}
802
803     // Updates listener information to received notification for
804
// unregistration of this MBean
805
ArrayList JavaDoc newRefList = new ArrayList JavaDoc();
806     newRefList.add(theRelObjectName);
807     updateUnregistrationListener(newRefList, null);
808
809     if (isTraceOn())
810         trace("addRelation: exiting", null);
811     return;
812     }
813
814     /**
815      * If the relation is represented by an MBean (created by the user and
816      * added as a relation in the Relation Service), returns the ObjectName of
817      * the MBean.
818      *
819      * @param theRelId relation id identifying the relation
820      *
821      * @return ObjectName of the corresponding relation MBean, or null if
822      * the relation is not an MBean.
823      *
824      * @exception IllegalArgumentException if null parameter
825      * @exception RelationNotFoundException there is no relation associated
826      * to that id
827      */

828     public ObjectName JavaDoc isRelationMBean(String JavaDoc theRelId)
829     throws IllegalArgumentException JavaDoc,
830            RelationNotFoundException JavaDoc{
831
832     if (theRelId == null) {
833         // Revisit [cebro[ Localize message
834
String JavaDoc excMsg = "Invalid parameter.";
835         throw new IllegalArgumentException JavaDoc(excMsg);
836     }
837
838     if (isTraceOn())
839         trace("isRelationMBean", theRelId);
840
841     // Can throw RelationNotFoundException
842
Object JavaDoc result = getRelation(theRelId);
843     if (result instanceof ObjectName JavaDoc) {
844         return ((ObjectName JavaDoc)result);
845     } else {
846         return null;
847     }
848     }
849
850     /**
851      * Returns the relation id associated to the given ObjectName if the
852      * MBean has been added as a relation in the Relation Service.
853      *
854      * @param theObjName ObjectName of supposed relation
855      *
856      * @return relation id (String) or null (if the ObjectName is not a
857      * relation handled by the Relation Service)
858      *
859      * @exception IllegalArgumentException if null parameter
860      */

861     public String JavaDoc isRelation(ObjectName JavaDoc theObjName)
862     throws IllegalArgumentException JavaDoc {
863
864     if (theObjName == null) {
865         // Revisit [cebro[ Localize message
866
String JavaDoc excMsg = "Invalid parameter.";
867         throw new IllegalArgumentException JavaDoc(excMsg);
868     }
869
870     if (isTraceOn())
871         trace("isRelation", theObjName.toString());
872
873     String JavaDoc result = null;
874     synchronized(myRelMBeanObjName2RelIdMap) {
875         String JavaDoc relId = (String JavaDoc)
876                 (myRelMBeanObjName2RelIdMap.get(theObjName));
877         if (relId != null) {
878         result = relId;
879         }
880     }
881     return result;
882     }
883
884     /**
885      * Checks if there is a relation identified in Relation Service with given
886      * relation id.
887      *
888      * @param theRelId relation id identifying the relation
889      *
890      * @return boolean: true if there is a relation, false else
891      *
892      * @exception IllegalArgumentException if null parameter
893      */

894     public Boolean JavaDoc hasRelation(String JavaDoc theRelId)
895     throws IllegalArgumentException JavaDoc {
896
897     if (theRelId == null) {
898         // Revisit [cebro[ Localize message
899
String JavaDoc excMsg = "Invalid parameter.";
900         throw new IllegalArgumentException JavaDoc(excMsg);
901     }
902
903     if (isTraceOn())
904         trace("hasRelation", theRelId);
905
906     try {
907         // Can throw RelationNotFoundException
908
Object JavaDoc result = getRelation(theRelId);
909         return new Boolean JavaDoc(true);
910     } catch (RelationNotFoundException JavaDoc exc) {
911         return new Boolean JavaDoc(false);
912     }
913     }
914
915     /**
916      * Returns all the relation ids for all the relations handled by the
917      * Relation Service.
918      *
919      * @return ArrayList of String
920      */

921     public List JavaDoc getAllRelationIds() {
922     ArrayList JavaDoc result = null;
923     synchronized(myRelId2ObjMap) {
924         result = new ArrayList JavaDoc(myRelId2ObjMap.keySet());
925     }
926     return result;
927     }
928
929     /**
930      * Checks if given Role can be read in a relation of the given type.
931      *
932      * @param theRoleName name of role to be checked
933      * @param theRelTypeName name of the relation type
934      *
935      * @return an Integer wrapping an integer corresponding to possible
936      * problems represented as constants in RoleUnresolved:
937      * <P>- 0 if role can be read
938      * <P>- integer corresponding to RoleStatus.NO_ROLE_WITH_NAME
939      * <P>- integer corresponding to RoleStatus.ROLE_NOT_READABLE
940      *
941      * @exception IllegalArgumentException if null parameter
942      * @exception RelationTypeNotFoundException if the relation type is not
943      * known in the Relation Service
944      */

945     public Integer JavaDoc checkRoleReading(String JavaDoc theRoleName,
946                     String JavaDoc theRelTypeName)
947     throws IllegalArgumentException JavaDoc,
948                RelationTypeNotFoundException JavaDoc {
949
950     if (theRoleName == null || theRelTypeName == null) {
951         // Revisit [cebro] Localize message
952
String JavaDoc excMsg = "Invalid parameter.";
953         throw new IllegalArgumentException JavaDoc(excMsg);
954     }
955
956     if (isTraceOn()) {
957         String JavaDoc str = "theRoleName " + theRoleName
958                     + ", theRelTypeName " + theRelTypeName;
959         trace("checkRoleReading: entering", str);
960     }
961
962     Integer JavaDoc result = null;
963
964     // Can throw a RelationTypeNotFoundException
965
RelationType JavaDoc relType = getRelationType(theRelTypeName);
966
967     try {
968         // Can throw a RoleInfoNotFoundException to be transformed into
969
// returned value RoleStatus.NO_ROLE_WITH_NAME
970
RoleInfo JavaDoc roleInfo = relType.getRoleInfo(theRoleName);
971
972         result = checkRoleInt(1,
973                    theRoleName,
974                    null,
975                    roleInfo,
976                    false);
977
978     } catch (RoleInfoNotFoundException JavaDoc exc) {
979         result = new Integer JavaDoc(RoleStatus.NO_ROLE_WITH_NAME);
980     }
981
982     if (isTraceOn())
983         trace("checkRoleReading: exiting", null);
984     return result;
985     }
986
987     /**
988      * Checks if given Role can be set in a relation of given type.
989      *
990      * @param theRole role to be checked
991      * @param theRelTypeName name of relation type
992      * @param theInitFlg flag to specify that the checking is done for the
993      * initialization of a role, write access shall not be verified.
994      *
995      * @return an Integer wrapping an integer corresponding to possible
996      * problems represented as constants in RoleUnresolved:
997      * <P>- 0 if role can be set
998      * <P>- integer corresponding to RoleStatus.NO_ROLE_WITH_NAME
999      * <P>- integer for RoleStatus.ROLE_NOT_WRITABLE
1000     * <P>- integer for RoleStatus.LESS_THAN_MIN_ROLE_DEGREE
1001     * <P>- integer for RoleStatus.MORE_THAN_MAX_ROLE_DEGREE
1002     * <P>- integer for RoleStatus.REF_MBEAN_OF_INCORRECT_CLASS
1003     * <P>- integer for RoleStatus.REF_MBEAN_NOT_REGISTERED
1004     *
1005     * @exception IllegalArgumentException if null parameter
1006     * @exception RelationTypeNotFoundException if unknown relation type
1007     */

1008    public Integer JavaDoc checkRoleWriting(Role JavaDoc theRole,
1009                    String JavaDoc theRelTypeName,
1010                    Boolean JavaDoc theInitFlg)
1011    throws IllegalArgumentException JavaDoc,
1012           RelationTypeNotFoundException JavaDoc {
1013
1014    if (theRole == null ||
1015        theRelTypeName == null ||
1016        theInitFlg == null) {
1017        // Revisit [cebro] Localize message
1018
String JavaDoc excMsg = "Invalid parameter.";
1019        throw new IllegalArgumentException JavaDoc(excMsg);
1020    }
1021
1022    if (isTraceOn()) {
1023        String JavaDoc str = new String JavaDoc("theRole " + theRole.toString()
1024                    + ", theRelTypeName " + theRelTypeName
1025                    + ", theInitFlg " + theInitFlg);
1026        trace("checkRoleWriting: entering", str);
1027    }
1028
1029    // Can throw a RelationTypeNotFoundException
1030
RelationType JavaDoc relType = getRelationType(theRelTypeName);
1031
1032    String JavaDoc roleName = theRole.getRoleName();
1033    ArrayList JavaDoc roleValue = (ArrayList JavaDoc)(theRole.getRoleValue());
1034    boolean writeChkFlg = true;
1035    if (theInitFlg.booleanValue()) {
1036        writeChkFlg = false;
1037    }
1038
1039    RoleInfo JavaDoc roleInfo = null;
1040    try {
1041        roleInfo = relType.getRoleInfo(roleName);
1042    } catch (RoleInfoNotFoundException JavaDoc exc) {
1043        if (isTraceOn())
1044        trace("checkRoleWriting: exiting", null);
1045        return new Integer JavaDoc(RoleStatus.NO_ROLE_WITH_NAME);
1046    }
1047
1048    Integer JavaDoc result = checkRoleInt(2,
1049                      roleName,
1050                      roleValue,
1051                      roleInfo,
1052                      writeChkFlg);
1053
1054    if (isTraceOn())
1055        trace("checkRoleWriting: exiting", null);
1056    return result;
1057    }
1058
1059    /**
1060     * Sends a notification (RelationNotification) for a relation creation.
1061     * The notification type is:
1062     * <P>- RelationNotification.RELATION_BASIC_CREATION if the relation is an
1063     * object internal to the Relation Service
1064     * <P>- RelationNotification.RELATION_MBEAN_CREATION if the relation is a
1065     * MBean added as a relation.
1066     * <P>The source object is the Relation Service itself.
1067     * <P>It is called in Relation Service createRelation() and
1068     * addRelation() methods.
1069     *
1070     * @param theRelId relation identifier of the updated relation
1071     *
1072     * @exception IllegalArgumentException if null parameter
1073     * @exception RelationNotFoundException if there is no relation for given
1074     * relation id
1075     */

1076    public void sendRelationCreationNotification(String JavaDoc theRelId)
1077    throws IllegalArgumentException JavaDoc,
1078           RelationNotFoundException JavaDoc {
1079
1080    if (theRelId == null) {
1081        // Revisit [cebro[ Localize message
1082
String JavaDoc excMsg = "Invalid parameter.";
1083        throw new IllegalArgumentException JavaDoc(excMsg);
1084    }
1085
1086    if (isTraceOn())
1087        trace("sendRelationCreationNotification: entering", theRelId);
1088
1089    // Message
1090
// Revisit [cebro] Localize message
1091
StringBuffer JavaDoc ntfMsg = new StringBuffer JavaDoc("Creation of relation ");
1092    ntfMsg.append(theRelId);
1093
1094    // Can throw RelationNotFoundException
1095
sendNotificationInt(1,
1096                ntfMsg.toString(),
1097                theRelId,
1098                null,
1099                null,
1100                null,
1101                null);
1102
1103    if (isTraceOn())
1104        trace("sendRelationCreationNotification: exiting", null);
1105    return;
1106    }
1107
1108    /**
1109     * Sends a notification (RelationNotification) for a role update in the
1110     * given relation. The notification type is:
1111     * <P>- RelationNotification.RELATION_BASIC_UPDATE if the relation is an
1112     * object internal to the Relation Service
1113     * <P>- RelationNotification.RELATION_MBEAN_UPDATE if the relation is a
1114     * MBean added as a relation.
1115     * <P>The source object is the Relation Service itself.
1116     * <P>It is called in relation MBean setRole() (for given role) and
1117     * setRoles() (for each role) methods (implementation provided in
1118     * RelationSupport class).
1119     * <P>It is also called in Relation Service setRole() (for given role) and
1120     * setRoles() (for each role) methods.
1121     *
1122     * @param theRelId relation identifier of the updated relation
1123     * @param theNewRole new role (name and new value)
1124     * @param theOldRoleValue old role value (List of ObjectName objects)
1125     *
1126     * @exception IllegalArgumentException if null parameter
1127     * @exception RelationNotFoundException if there is no relation for given
1128     * relation id
1129     */

1130    public void sendRoleUpdateNotification(String JavaDoc theRelId,
1131                       Role JavaDoc theNewRole,
1132                       List JavaDoc theOldRoleValue)
1133    throws IllegalArgumentException JavaDoc,
1134           RelationNotFoundException JavaDoc {
1135
1136    if (theRelId == null ||
1137        theNewRole == null ||
1138        theOldRoleValue == null) {
1139        // Revisit [cebro] Localize message
1140
String JavaDoc excMsg = "Invalid parameter.";
1141        throw new IllegalArgumentException JavaDoc(excMsg);
1142    }
1143
1144    if (!(theOldRoleValue instanceof ArrayList JavaDoc))
1145        theOldRoleValue = new ArrayList JavaDoc(theOldRoleValue);
1146
1147    if (isTraceOn()) {
1148        String JavaDoc str = new String JavaDoc("theRelId " + theRelId
1149                    + ", theNewRole " + theNewRole.toString()
1150                    + ", theOldRoleValue "
1151                    + theOldRoleValue.toString());
1152        trace("sendRoleUpdateNotification: entering", str);
1153    }
1154
1155    String JavaDoc roleName = theNewRole.getRoleName();
1156    ArrayList JavaDoc newRoleVal = (ArrayList JavaDoc)(theNewRole.getRoleValue());
1157
1158    // Message
1159
String JavaDoc newRoleValString = Role.roleValueToString(newRoleVal);
1160    String JavaDoc oldRoleValString = Role.roleValueToString(theOldRoleValue);
1161    // Revisit [cebro] Localize message
1162
StringBuffer JavaDoc ntfMsg = new StringBuffer JavaDoc("Value of role ");
1163    ntfMsg.append(roleName);
1164    ntfMsg.append(" has changed\nOld value:\n");
1165    ntfMsg.append(oldRoleValString);
1166    ntfMsg.append("\nNew value:\n");
1167    ntfMsg.append(newRoleValString);
1168
1169    // Can throw a RelationNotFoundException
1170
sendNotificationInt(2,
1171                ntfMsg.toString(),
1172                theRelId,
1173                null,
1174                roleName,
1175                newRoleVal,
1176                theOldRoleValue);
1177
1178    if (isTraceOn())
1179        trace("sendRoleUpdateNotification: exiting", null);
1180    return;
1181    }
1182
1183    /**
1184     * Sends a notification (RelationNotification) for a relation removal.
1185     * The notification type is:
1186     * <P>- RelationNotification.RELATION_BASIC_REMOVAL if the relation is an
1187     * object internal to the Relation Service
1188     * <P>- RelationNotification.RELATION_MBEAN_REMOVAL if the relation is a
1189     * MBean added as a relation.
1190     * <P>The source object is the Relation Service itself.
1191     * <P>It is called in Relation Service removeRelation() method.
1192     *
1193     * @param theRelId relation identifier of the updated relation
1194     * @param theUnregMBeanList List of ObjectNames of MBeans expected
1195     * to be unregistered due to relation removal (can be null)
1196     *
1197     * @exception IllegalArgumentException if null parameter
1198     * @exception RelationNotFoundException if there is no relation for given
1199     * relation id
1200     */

1201    public void sendRelationRemovalNotification(String JavaDoc theRelId,
1202                        List JavaDoc theUnregMBeanList)
1203    throws IllegalArgumentException JavaDoc,
1204           RelationNotFoundException JavaDoc {
1205
1206    if (theRelId == null) {
1207        String JavaDoc excMsg = "Invalid parameter";
1208        throw new IllegalArgumentException JavaDoc(excMsg);
1209    }
1210
1211    if (isTraceOn()) {
1212        StringBuffer JavaDoc strB = new StringBuffer JavaDoc("theRelId " + theRelId);
1213        if (theUnregMBeanList != null) {
1214        strB.append(", theUnregMBeanList "
1215                + theUnregMBeanList.toString());
1216        }
1217        trace("sendRelationRemovalNotification: entering",
1218          strB.toString());
1219    }
1220
1221    // Message
1222
// Revisit [cebro] Include string for ObjectNames to be unregistered?
1223
StringBuffer JavaDoc ntfMsg = new StringBuffer JavaDoc("Removal of relation ");
1224    ntfMsg.append(theRelId);
1225
1226    // Can throw RelationNotFoundException
1227
sendNotificationInt(3,
1228                ntfMsg.toString(),
1229                theRelId,
1230                theUnregMBeanList,
1231                null,
1232                null,
1233                null);
1234
1235    if (isTraceOn())
1236        trace("sendRelationRemovalNotification: exiting", null);
1237    return;
1238    }
1239
1240    /**
1241     * Handles update of the Relation Service role map for the update of given
1242     * role in given relation.
1243     * <P>It is called in relation MBean setRole() (for given role) and
1244     * setRoles() (for each role) methods (implementation provided in
1245     * RelationSupport class).
1246     * <P>It is also called in Relation Service setRole() (for given role) and
1247     * setRoles() (for each role) methods.
1248     * <P>To allow the Relation Service to maintain the consistency (in case
1249     * of MBean unregistration) and to be able to perform queries, this method
1250     * must be called when a role is updated.
1251     *
1252     * @param theRelId relation identifier of the updated relation
1253     * @param theNewRole new role (name and new value)
1254     * @param theOldRoleValue old role value (List of ObjectName objects)
1255     *
1256     * @exception IllegalArgumentException if null parameter
1257     * @exception RelationServiceNotRegisteredException if the Relation
1258     * Service is not registered in the MBean Server
1259     * @exception RelationNotFoundException if no relation for given id.
1260     */

1261    public void updateRoleMap(String JavaDoc theRelId,
1262                  Role JavaDoc theNewRole,
1263                  List JavaDoc theOldRoleValue)
1264    throws IllegalArgumentException JavaDoc,
1265           RelationServiceNotRegisteredException JavaDoc,
1266               RelationNotFoundException JavaDoc {
1267
1268    if (theRelId == null ||
1269        theNewRole == null ||
1270        theOldRoleValue == null) {
1271        String JavaDoc excMsg = "Invalid parameter.";
1272        throw new IllegalArgumentException JavaDoc(excMsg);
1273    }
1274
1275    if (isTraceOn()) {
1276        String JavaDoc str = new String JavaDoc("theRelId " + theRelId
1277                    + ", theNewRole " + theNewRole.toString()
1278                    + ", theOldRoleValue "
1279                    + theOldRoleValue.toString());
1280        trace("updateRoleMap: entering", str);
1281    }
1282
1283    // Can throw RelationServiceNotRegisteredException
1284
isActive();
1285
1286    // Verifies the relation has been added in the Relation Service
1287
// Can throw a RelationNotFoundException
1288
Object JavaDoc result = getRelation(theRelId);
1289
1290    String JavaDoc roleName = theNewRole.getRoleName();
1291    ArrayList JavaDoc newRoleValue = (ArrayList JavaDoc)(theNewRole.getRoleValue());
1292    // Note: no need to test if theOldRoleValue not null before cloning,
1293
// tested above.
1294
ArrayList JavaDoc oldRoleValue = new ArrayList JavaDoc(theOldRoleValue);
1295
1296    // List of ObjectNames of new referenced MBeans
1297
ArrayList JavaDoc newRefList = new ArrayList JavaDoc();
1298
1299    for (Iterator JavaDoc newRoleIter = newRoleValue.iterator();
1300         newRoleIter.hasNext();) {
1301        ObjectName JavaDoc currObjName = (ObjectName JavaDoc)(newRoleIter.next());
1302
1303        // Checks if this ObjectName was already present in old value
1304
// Note: use copy (oldRoleValue) instead of original
1305
// theOldRoleValue to speed up, as oldRoleValue is decreased
1306
// by removing unchanged references :)
1307
int currObjNamePos = oldRoleValue.indexOf(currObjName);
1308
1309        if (currObjNamePos == -1) {
1310        // New reference to an ObjectName
1311

1312        // Stores this reference into map
1313
// Returns true if new reference, false if MBean already
1314
// referenced
1315
boolean isNewFlg = addNewMBeanReference(currObjName,
1316                            theRelId,
1317                            roleName);
1318
1319        if (isNewFlg) {
1320            // Adds it into list of new reference
1321
newRefList.add(currObjName);
1322        }
1323
1324        } else {
1325        // MBean was already referenced in old value
1326

1327        // Removes it from old value (local list) to ignore it when
1328
// looking for remove MBean references
1329
oldRoleValue.remove(currObjNamePos);
1330        }
1331    }
1332
1333    // List of ObjectNames of MBeans no longer referenced
1334
ArrayList JavaDoc obsRefList = new ArrayList JavaDoc();
1335
1336    // Each ObjectName remaining in oldRoleValue is an ObjectName no longer
1337
// referenced in new value
1338
for (Iterator JavaDoc oldRoleIter = oldRoleValue.iterator();
1339         oldRoleIter.hasNext();) {
1340
1341        ObjectName JavaDoc currObjName = (ObjectName JavaDoc)(oldRoleIter.next());
1342        // Removes MBean reference from map
1343
// Returns true if the MBean is no longer referenced in any
1344
// relation
1345
boolean noLongerRefFlg = removeMBeanReference(currObjName,
1346                              theRelId,
1347                              roleName,
1348                              false);
1349
1350        if (noLongerRefFlg) {
1351        // Adds it into list of references to be removed
1352
obsRefList.add(currObjName);
1353        }
1354    }
1355
1356    // To avoid having one listener per ObjectName of referenced MBean,
1357
// and to increase performances, there is only one listener recording
1358
// all ObjectNames of interest
1359
updateUnregistrationListener(newRefList, obsRefList);
1360
1361    if (isTraceOn())
1362        trace("updateRoleMap: exiting", null);
1363    return;
1364    }
1365
1366    /**
1367     * Removes given relation from the Relation Service.
1368     * <P>A RelationNotification notification is sent, its type being:
1369     * <P>- RelationNotification.RELATION_BASIC_REMOVAL if the relation was
1370     * only internal to the Relation Service
1371     * <P>- RelationNotification.RELATION_MBEAN_REMOVAL if the relation is
1372     * registered as an MBean.
1373     * <P>For MBeans referenced in such relation, nothing will be done,
1374     *
1375     * @param theRelId relation id of the relation to be removed
1376     *
1377     * @exception RelationServiceNotRegisteredException if the Relation
1378     * Service is not registered in the MBean Server
1379     * @exception IllegalArgumentException if null parameter
1380     * @exception RelationNotFoundException if no relation corresponding to
1381     * given relation id
1382     */

1383    public void removeRelation(String JavaDoc theRelId)
1384    throws RelationServiceNotRegisteredException JavaDoc,
1385           IllegalArgumentException JavaDoc,
1386           RelationNotFoundException JavaDoc {
1387
1388    // Can throw RelationServiceNotRegisteredException
1389
isActive();
1390
1391    if (theRelId == null) {
1392        // Revisit [cebro[ Localize message
1393
String JavaDoc excMsg = "Invalid parameter.";
1394        throw new IllegalArgumentException JavaDoc(excMsg);
1395    }
1396
1397    if (isTraceOn())
1398        trace("removeRelation: entering", theRelId);
1399
1400    // Checks there is a relation with this id
1401
// Can throw RelationNotFoundException
1402
Object JavaDoc result = getRelation(theRelId);
1403
1404    // Removes it from listener filter
1405
if (result instanceof ObjectName JavaDoc) {
1406        ArrayList JavaDoc obsRefList = new ArrayList JavaDoc();
1407        obsRefList.add((ObjectName JavaDoc)result);
1408        // Can throw a RelationServiceNotRegisteredException
1409
updateUnregistrationListener(null, obsRefList);
1410    }
1411
1412    // Sends a notification
1413
// Note: has to be done FIRST as needs the relation to be still in the
1414
// Relation Service
1415
// No RelationNotFoundException as checked above
1416

1417    // Revisit [cebro] Handle CIM "Delete" and "IfDeleted" qualifiers:
1418
// deleting the relation can mean to delete referenced MBeans. In
1419
// that case, MBeans to be unregistered are put in a list sent along
1420
// with the notification below
1421

1422    // Can throw a RelationNotFoundException (but detected above)
1423
sendRelationRemovalNotification(theRelId, null);
1424
1425    // Removes the relation from various internal maps
1426

1427    // - MBean reference map
1428
// Retrieves the MBeans referenced in this relation
1429
// Note: here we cannot use removeMBeanReference() because it would
1430
// require to know the MBeans referenced in the relation. For
1431
// that it would be necessary to call 'getReferencedMBeans()'
1432
// on the relation itself. Ok if it is an internal one, but if
1433
// it is an MBean, it is possible it is already unregistered, so
1434
// not available through the MBean Server.
1435
ArrayList JavaDoc refMBeanList = new ArrayList JavaDoc();
1436    // List of MBeans no longer referenced in any relation, to be
1437
// removed fom the map
1438
ArrayList JavaDoc nonRefObjNameList = new ArrayList JavaDoc();
1439
1440    synchronized(myRefedMBeanObjName2RelIdsMap) {
1441
1442        for (Iterator JavaDoc refMBeanIter =
1443             (myRefedMBeanObjName2RelIdsMap.keySet()).iterator();
1444         refMBeanIter.hasNext();) {
1445
1446        ObjectName JavaDoc currRefObjName = (ObjectName JavaDoc)(refMBeanIter.next());
1447        // Retrieves relations where the MBean is referenced
1448
HashMap JavaDoc relIdMap = (HashMap JavaDoc)
1449            (myRefedMBeanObjName2RelIdsMap.get(currRefObjName));
1450
1451        if (relIdMap.containsKey(theRelId)) {
1452            relIdMap.remove(theRelId);
1453            refMBeanList.add(currRefObjName);
1454        }
1455
1456        if (relIdMap.isEmpty()) {
1457            // MBean no longer referenced
1458
// Note: do not remove it here because pointed by the
1459
// iterator!
1460
nonRefObjNameList.add(currRefObjName);
1461        }
1462        }
1463
1464        // Cleans MBean reference map by removing MBeans no longer
1465
// referenced
1466
for (Iterator JavaDoc nonRefObjNameIter = nonRefObjNameList.iterator();
1467         nonRefObjNameIter.hasNext();) {
1468        ObjectName JavaDoc currRefObjName = (ObjectName JavaDoc)
1469            (nonRefObjNameIter.next());
1470        myRefedMBeanObjName2RelIdsMap.remove(currRefObjName);
1471        }
1472    }
1473
1474    // - Relation id to object map
1475
synchronized(myRelId2ObjMap) {
1476        myRelId2ObjMap.remove(theRelId);
1477    }
1478
1479    if (result instanceof ObjectName JavaDoc) {
1480        // - ObjectName to relation id map
1481
synchronized(myRelMBeanObjName2RelIdMap) {
1482        myRelMBeanObjName2RelIdMap.remove((ObjectName JavaDoc)result);
1483        }
1484    }
1485
1486    // Relation id to relation type name map
1487
// First retrieves the relation type name
1488
String JavaDoc relTypeName = null;
1489    synchronized(myRelId2RelTypeMap) {
1490        relTypeName = (String JavaDoc)(myRelId2RelTypeMap.get(theRelId));
1491        myRelId2RelTypeMap.remove(theRelId);
1492    }
1493    // - Relation type name to relation id map
1494
synchronized(myRelType2RelIdsMap) {
1495        ArrayList JavaDoc relIdList =
1496        (ArrayList JavaDoc)(myRelType2RelIdsMap.get(relTypeName));
1497        if (relIdList != null) {
1498        // Can be null if called from removeRelationType()
1499
relIdList.remove(theRelId);
1500        if (relIdList.isEmpty()) {
1501            // No other relation of that type
1502
myRelType2RelIdsMap.remove(relTypeName);
1503        }
1504        }
1505    }
1506
1507    if (isTraceOn())
1508        trace("removeRelation: exiting", null);
1509    return;
1510    }
1511
1512    /**
1513     * Purges the relations.
1514     *
1515     * <P>Depending on the purgeFlag value, this method is either called
1516     * automatically when a notification is received for the unregistration of
1517     * an MBean referenced in a relation (if the flag is set to true), or not
1518     * (if the flag is set to false).
1519     * <P>In that case it is up to the user to call it to maintain the
1520     * consistency of the relations. To be kept in mind that if an MBean is
1521     * unregistered and the purge not done immediately, if the ObjectName is
1522     * reused and assigned to another MBean referenced in a relation, calling
1523     * manually this purgeRelations() method will cause trouble, as will
1524     * consider the ObjectName as corresponding to the unregistered MBean, not
1525     * seeing the new one.
1526     *
1527     * <P>The behavior depends on the cardinality of the role where the
1528     * unregistered MBean is referenced:
1529     * <P>- if removing one MBean reference in the role makes its number of
1530     * references less than the minimum degree, the relation has to be removed.
1531     * <P>- if the remaining number of references after removing the MBean
1532     * reference is still in the cardinality range, keep the relation and
1533     * update it calling its handleMBeanUnregistration() callback.
1534     *
1535     * @exception RelationServiceNotRegisteredException if the Relation
1536     * Service is not registered in the MBean Server.
1537     */

1538    public void purgeRelations()
1539    throws RelationServiceNotRegisteredException JavaDoc {
1540
1541    if (isTraceOn())
1542        trace("purgeRelations: entering", null);
1543
1544    // Can throw RelationServiceNotRegisteredException
1545
isActive();
1546
1547    // Revisit [cebro] Handle the CIM "Delete" and "IfDeleted" qualifier:
1548
// if the unregistered MBean has the "IfDeleted" qualifier,
1549
// possible that the relation itself or other referenced MBeans
1550
// have to be removed (then a notification would have to be sent
1551
// to inform that they should be unregistered.
1552

1553
1554    // Clones the list of notifications to be able to still receive new
1555
// notifications while proceeding those ones
1556
ArrayList JavaDoc localUnregNtfList = null;
1557    synchronized(myUnregNtfList) {
1558        localUnregNtfList = (ArrayList JavaDoc)(myUnregNtfList.clone());
1559        // Resets list
1560
myUnregNtfList = new ArrayList JavaDoc();
1561    }
1562
1563
1564    // Updates the listener filter to avoid receiving notifications for
1565
// those MBeans again
1566
// Makes also a local "myRefedMBeanObjName2RelIdsMap" map, mapping
1567
// ObjectName -> relId -> roles, to remove the MBean from the global
1568
// map
1569
// List of references to be removed from the listener filter
1570
ArrayList JavaDoc obsRefList = new ArrayList JavaDoc();
1571    // Map including ObjectNames for unregistered MBeans, with
1572
// referencing relation ids and roles
1573
HashMap JavaDoc localMBean2RelIdMap = new HashMap JavaDoc();
1574
1575    synchronized(myRefedMBeanObjName2RelIdsMap) {
1576        for (Iterator JavaDoc unregNtfIter = localUnregNtfList.iterator();
1577         unregNtfIter.hasNext();) {
1578
1579        MBeanServerNotification JavaDoc currNtf =
1580            (MBeanServerNotification JavaDoc)(unregNtfIter.next());
1581
1582        ObjectName JavaDoc unregMBeanName = currNtf.getMBeanName();
1583
1584        // Adds the unregsitered MBean in the list of references to
1585
// remove from the listener filter
1586
obsRefList.add(unregMBeanName);
1587
1588        // Retrieves the associated map of relation ids and roles
1589
HashMap JavaDoc relIdMap = (HashMap JavaDoc)
1590            (myRefedMBeanObjName2RelIdsMap.get(unregMBeanName));
1591        localMBean2RelIdMap.put(unregMBeanName, relIdMap);
1592
1593        myRefedMBeanObjName2RelIdsMap.remove(unregMBeanName);
1594        }
1595    }
1596
1597    // Updates the listener
1598
// Can throw RelationServiceNotRegisteredException
1599
updateUnregistrationListener(null, obsRefList);
1600
1601    for (Iterator JavaDoc unregNtfIter = localUnregNtfList.iterator();
1602         unregNtfIter.hasNext();) {
1603
1604        MBeanServerNotification JavaDoc currNtf =
1605        (MBeanServerNotification JavaDoc)(unregNtfIter.next());
1606
1607        ObjectName JavaDoc unregMBeanName = currNtf.getMBeanName();
1608
1609        // Retrieves the relations where the MBean is referenced
1610
HashMap JavaDoc localRelIdMap = (HashMap JavaDoc)
1611            (localMBean2RelIdMap.get(unregMBeanName));
1612
1613        // List of relation ids where the unregistered MBean is
1614
// referenced
1615
Set JavaDoc localRelIdSet = localRelIdMap.keySet();
1616        for (Iterator JavaDoc relIdIter = localRelIdSet.iterator();
1617         relIdIter.hasNext();) {
1618
1619        String JavaDoc currRelId = (String JavaDoc)(relIdIter.next());
1620
1621        // List of roles of the relation where the MBean is
1622
// referenced
1623
ArrayList JavaDoc localRoleNameList = (ArrayList JavaDoc)
1624            (localRelIdMap.get(currRelId));
1625
1626        // Checks if the relation has to be removed or not,
1627
// regarding expected minimum role cardinality and current
1628
// number of references after removal of the current one
1629
// If the relation is kept, calls
1630
// handleMBeanUnregistration() callback of the relation to
1631
// update it
1632
//
1633
// Can throw RelationServiceNotRegisteredException
1634
//
1635
// Shall not throw RelationNotFoundException,
1636
// RoleNotFoundException, MBeanException
1637
try {
1638            handleReferenceUnregistration(currRelId,
1639                          unregMBeanName,
1640                          localRoleNameList);
1641        } catch (RelationNotFoundException JavaDoc exc1) {
1642            throw new RuntimeException JavaDoc(exc1.getMessage());
1643        } catch (RoleNotFoundException JavaDoc exc2) {
1644            throw new RuntimeException JavaDoc(exc2.getMessage());
1645        }
1646        }
1647    }
1648
1649    if (isTraceOn())
1650        trace("purgeRelations: exiting", null);
1651    return;
1652    }
1653
1654    /**
1655     * Retrieves the relations where a given MBean is referenced.
1656     * <P>This corresponds to the CIM "References" and "ReferenceNames"
1657     * operations.
1658     *
1659     * @param theMBeanName ObjectName of MBean
1660     * @param theRelTypeName can be null; if specified, only the relations
1661     * of that type will be considered in the search. Else all relation types
1662     * are considered.
1663     * @param theRoleName can be null; if specified, only the relations
1664     * where the MBean is referenced in that role will be returned. Else all
1665     * roles are considered.
1666     *
1667     * @return an HashMap, where the keys are the relation ids of the relations
1668     * where the MBean is referenced, and the value is, for each key,
1669     * an ArrayList of role names (as an MBean can be referenced in several
1670     * roles in the same relation).
1671     *
1672     * @exception IllegalArgumentException if null parameter
1673     */

1674    public Map JavaDoc findReferencingRelations(ObjectName JavaDoc theMBeanName,
1675                    String JavaDoc theRelTypeName,
1676                    String JavaDoc theRoleName)
1677    throws IllegalArgumentException JavaDoc {
1678
1679    if (theMBeanName == null) {
1680        // Revisit [cebro] Localize message
1681
String JavaDoc excMsg = "Invalid parameter.";
1682        throw new IllegalArgumentException JavaDoc(excMsg);
1683    }
1684
1685    if (isTraceOn()) {
1686        String JavaDoc str = new String JavaDoc("theMBeanName " + theMBeanName.toString()
1687                    + ", theRelTypeName " + theRelTypeName
1688                    + ", theRoleName " + theRoleName);
1689        trace("findReferencingRelations: entering", str);
1690    }
1691
1692    HashMap JavaDoc result = new HashMap JavaDoc();
1693
1694    synchronized(myRefedMBeanObjName2RelIdsMap) {
1695
1696        // Retrieves the relations referencing the MBean
1697
HashMap JavaDoc relId2RoleNamesMap =
1698        (HashMap JavaDoc)(myRefedMBeanObjName2RelIdsMap.get(theMBeanName));
1699
1700        if (relId2RoleNamesMap != null) {
1701
1702        // Relation Ids where the MBean is referenced
1703
Set JavaDoc allRelIdSet = relId2RoleNamesMap.keySet();
1704
1705        // List of relation ids of interest regarding the selected
1706
// relation type
1707
ArrayList JavaDoc relIdList = null;
1708        if (theRelTypeName == null) {
1709            // Considers all relations
1710
relIdList = new ArrayList JavaDoc(allRelIdSet);
1711
1712        } else {
1713
1714            relIdList = new ArrayList JavaDoc();
1715
1716            // Considers only the relation ids for relations of given
1717
// type
1718
for (Iterator JavaDoc relIdIter = allRelIdSet.iterator();
1719             relIdIter.hasNext();) {
1720            String JavaDoc currRelId = (String JavaDoc)(relIdIter.next());
1721
1722            // Retrieves its relation type
1723
String JavaDoc currRelTypeName = null;
1724            synchronized(myRelId2RelTypeMap) {
1725                currRelTypeName = (String JavaDoc)
1726                (myRelId2RelTypeMap.get(currRelId));
1727            }
1728
1729            if (currRelTypeName.equals(theRelTypeName)) {
1730
1731                relIdList.add(currRelId);
1732
1733            }
1734            }
1735        }
1736
1737        // Now looks at the roles where the MBean is expected to be
1738
// referenced
1739

1740        for (Iterator JavaDoc relIdIter = relIdList.iterator();
1741             relIdIter.hasNext();) {
1742
1743            String JavaDoc currRelId = (String JavaDoc)(relIdIter.next());
1744            // Retrieves list of role names where the MBean is
1745
// referenced
1746
ArrayList JavaDoc currRoleNameList =
1747            (ArrayList JavaDoc)(relId2RoleNamesMap.get(currRelId));
1748
1749            if (theRoleName == null) {
1750            // All roles to be considered
1751
// Note: no need to test if list not null before
1752
// cloning, MUST be not null else bug :(
1753
result.put(currRelId,
1754                   (ArrayList JavaDoc)(currRoleNameList.clone()));
1755
1756            } else if (currRoleNameList.contains(theRoleName)) {
1757            // Filters only the relations where the MBean is
1758
// referenced in // given role
1759
ArrayList JavaDoc dummyList = new ArrayList JavaDoc();
1760            dummyList.add(theRoleName);
1761            result.put(currRelId, dummyList);
1762            }
1763        }
1764        }
1765    }
1766
1767    if (isTraceOn())
1768        trace("findReferencingRelations: exiting", null);
1769    return result;
1770    }
1771
1772    /**
1773     * Retrieves the MBeans associated to given one in a relation.
1774     * <P>This corresponds to CIM Associators and AssociatorNames operations.
1775     *
1776     * @param theMBeanName ObjectName of MBean
1777     * @param theRelTypeName can be null; if specified, only the relations
1778     * of that type will be considered in the search. Else all
1779     * relation types are considered.
1780     * @param theRoleName can be null; if specified, only the relations
1781     * where the MBean is referenced in that role will be considered. Else all
1782     * roles are considered.
1783     *
1784     * @return an HashMap, where the keys are the ObjectNames of the MBeans
1785     * associated to given MBean, and the value is, for each key, an ArrayList
1786     * of the relation ids of the relations where the key MBean is
1787     * associated to given one (as they can be associated in several different
1788     * relations).
1789     *
1790     * @exception IllegalArgumentException if null parameter
1791     */

1792    public Map JavaDoc findAssociatedMBeans(ObjectName JavaDoc theMBeanName,
1793                    String JavaDoc theRelTypeName,
1794                    String JavaDoc theRoleName)
1795    throws IllegalArgumentException JavaDoc {
1796
1797    if (theMBeanName == null) {
1798        // Revisit [cebro[ Localize message
1799
String JavaDoc excMsg = "Invalid parameter.";
1800        throw new IllegalArgumentException JavaDoc(excMsg);
1801    }
1802
1803    if (isTraceOn()) {
1804        String JavaDoc str = new String JavaDoc("theMBeanName " + theMBeanName.toString()
1805                    + ", theRelTypeName " + theRelTypeName
1806                    + ", theRoleName " + theRoleName);
1807        trace("findAssociatedMBeans: entering", str);
1808    }
1809
1810    // Retrieves the map <relation id> -> <role names> for those
1811
// criterias
1812
HashMap JavaDoc relId2RoleNamesMap = (HashMap JavaDoc)
1813        (findReferencingRelations(theMBeanName,
1814                      theRelTypeName,
1815                      theRoleName));
1816
1817    HashMap JavaDoc result = new HashMap JavaDoc();
1818
1819    for (Iterator JavaDoc relIdIter = (relId2RoleNamesMap.keySet()).iterator();
1820         relIdIter.hasNext();) {
1821
1822        String JavaDoc currRelId = (String JavaDoc)(relIdIter.next());
1823
1824        // Retrieves ObjectNames of MBeans referenced in this relation
1825
//
1826
// Shall not throw a RelationNotFoundException if incorrect status
1827
// of maps :(
1828
HashMap JavaDoc objName2RoleNamesMap = null;
1829        try {
1830        objName2RoleNamesMap =
1831            (HashMap JavaDoc)(getReferencedMBeans(currRelId));
1832        } catch (RelationNotFoundException JavaDoc exc) {
1833        throw new RuntimeException JavaDoc(exc.getMessage());
1834        }
1835
1836        // For each MBean associated to given one in a relation, adds the
1837
// association <ObjectName> -> <relation id> into result map
1838
for (Iterator JavaDoc objNameIter =
1839             (objName2RoleNamesMap.keySet()).iterator();
1840         objNameIter.hasNext();) {
1841        
1842        ObjectName JavaDoc currObjName = (ObjectName JavaDoc)(objNameIter.next());
1843
1844        if (!(currObjName.equals(theMBeanName))) {
1845
1846            // Sees if this MBean is already associated to the given
1847
// one in another relation
1848
ArrayList JavaDoc currRelIdList =
1849            (ArrayList JavaDoc)(result.get(currObjName));
1850            if (currRelIdList == null) {
1851
1852            currRelIdList = new ArrayList JavaDoc();
1853            currRelIdList.add(currRelId);
1854            result.put(currObjName, currRelIdList);
1855
1856            } else {
1857            currRelIdList.add(currRelId);
1858            }
1859        }
1860        }
1861    }
1862
1863    if (isTraceOn())
1864        trace("findReferencingRelations: exiting", null);
1865    return result;
1866    }
1867
1868    /**
1869     * Returns the relation ids for relations of the given type.
1870     *
1871     * @param theRelTypeName relation type name
1872     *
1873     * @return an ArrayList of relation ids.
1874     *
1875     * @exception IllegalArgumentException if null parameter
1876     * @exception RelationTypeNotFoundException if there is no relation type
1877     * with that name.
1878     */

1879    public List JavaDoc findRelationsOfType(String JavaDoc theRelTypeName)
1880    throws IllegalArgumentException JavaDoc,
1881               RelationTypeNotFoundException JavaDoc {
1882
1883    if (theRelTypeName == null) {
1884        // Revisit [cebro] Localize message
1885
String JavaDoc excMsg = "Invalid parameter.";
1886        throw new IllegalArgumentException JavaDoc(excMsg);
1887    }
1888
1889    if (isTraceOn())
1890        trace("findRelationsOfType: entering", theRelTypeName);
1891
1892    // Can throw RelationTypeNotFoundException
1893
RelationType JavaDoc relType = getRelationType(theRelTypeName);
1894
1895    ArrayList JavaDoc result = new ArrayList JavaDoc();
1896    synchronized(myRelType2RelIdsMap) {
1897        ArrayList JavaDoc result1 = (ArrayList JavaDoc)
1898        (myRelType2RelIdsMap.get(theRelTypeName));
1899        if (result1 != null) {
1900        result = (ArrayList JavaDoc)(result1.clone());
1901        }
1902    }
1903
1904    if (isTraceOn())
1905        trace("findRelationsOfType: exiting", null);
1906    return result;
1907    }
1908
1909    /**
1910     * Retrieves role value for given role name in given relation.
1911     *
1912     * @param theRelId relation id
1913     * @param theRoleName name of role
1914     *
1915     * @return the ArrayList of ObjectName objects being the role value
1916     *
1917     * @exception RelationServiceNotRegisteredException if the Relation
1918     * Service is not registered
1919     * @exception IllegalArgumentException if null parameter
1920     * @exception RelationNotFoundException if no relation with given id
1921     * @exception RoleNotFoundException if:
1922     * <P>- there is no role with given name
1923     * <P>or
1924     * <P>- the role is not readable.
1925     *
1926     * @see #setRole
1927     */

1928    public List JavaDoc getRole(String JavaDoc theRelId,
1929            String JavaDoc theRoleName)
1930    throws RelationServiceNotRegisteredException JavaDoc,
1931           IllegalArgumentException JavaDoc,
1932               RelationNotFoundException JavaDoc,
1933               RoleNotFoundException JavaDoc {
1934
1935    if (theRelId == null || theRoleName == null) {
1936        // Revisit [cebro[ Localize message
1937
String JavaDoc excMsg = "Invalid parameter.";
1938        throw new IllegalArgumentException JavaDoc(excMsg);
1939    }
1940
1941    if (isTraceOn()) {
1942        String JavaDoc str = "theRelId " + theRelId
1943                    + ", theRoleName " + theRoleName;
1944        trace("getRole: entering", str);
1945    }
1946
1947    // Can throw RelationServiceNotRegisteredException
1948
isActive();
1949
1950    // Can throw a RelationNotFoundException
1951
Object JavaDoc relObj = getRelation(theRelId);
1952
1953    ArrayList JavaDoc result = null;
1954
1955    if (relObj instanceof RelationSupport JavaDoc) {
1956        // Internal relation
1957
// Can throw RoleNotFoundException
1958
result = (ArrayList JavaDoc)
1959        (((RelationSupport JavaDoc)relObj).getRoleInt(theRoleName,
1960                           true,
1961                           this,
1962                           false));
1963
1964    } else {
1965        // Relation MBean
1966
Object JavaDoc[] params = new Object JavaDoc[1];
1967        params[0] = theRoleName;
1968        String JavaDoc[] signature = new String JavaDoc[1];
1969        signature[0] = "java.lang.String";
1970        // Can throw MBeanException wrapping a RoleNotFoundException:
1971
// throw wrapped exception
1972
//
1973
// Shall not throw InstanceNotFoundException or ReflectionException
1974
try {
1975        List JavaDoc invokeResult = (List JavaDoc)
1976            (myMBeanServer.invoke(((ObjectName JavaDoc)relObj),
1977                      "getRole",
1978                      params,
1979                      signature));
1980        if (invokeResult == null || invokeResult instanceof ArrayList JavaDoc)
1981            result = (ArrayList JavaDoc) invokeResult;
1982        else
1983            result = new ArrayList JavaDoc(result);
1984        } catch (InstanceNotFoundException JavaDoc exc1) {
1985        throw new RuntimeException JavaDoc(exc1.getMessage());
1986        } catch (ReflectionException JavaDoc exc2) {
1987        throw new RuntimeException JavaDoc(exc2.getMessage());
1988        } catch (MBeanException JavaDoc exc3) {
1989        Exception JavaDoc wrappedExc = exc3.getTargetException();
1990        if (wrappedExc instanceof RoleNotFoundException JavaDoc) {
1991            throw ((RoleNotFoundException JavaDoc)wrappedExc);
1992        } else {
1993            throw new RuntimeException JavaDoc(wrappedExc.getMessage());
1994        }
1995        }
1996    }
1997
1998    if (isTraceOn())
1999        trace("getRole: exiting", null);
2000    return result;
2001    }
2002
2003    /**
2004     * Retrieves values of roles with given names in given relation.
2005     *
2006     * @param theRelId relation id
2007     * @param theRoleNameArray array of names of roles to be retrieved
2008     *
2009     * @return a RoleResult object, including a RoleList (for roles
2010     * successfully retrieved) and a RoleUnresolvedList (for roles not
2011     * retrieved).
2012     *
2013     * @exception RelationServiceNotRegisteredException if the Relation
2014     * Service is not registered in the MBean Server
2015     * @exception IllegalArgumentException if null parameter
2016     * @exception RelationNotFoundException if no relation with given id
2017     *
2018     * @see #setRoles
2019     */

2020    public RoleResult JavaDoc getRoles(String JavaDoc theRelId,
2021                   String JavaDoc[] theRoleNameArray)
2022    throws RelationServiceNotRegisteredException JavaDoc,
2023           IllegalArgumentException JavaDoc,
2024           RelationNotFoundException JavaDoc {
2025
2026    if (theRelId == null || theRoleNameArray == null) {
2027        // Revisit [cebro[ Localize message
2028
String JavaDoc excMsg = "Invalid parameter.";
2029        throw new IllegalArgumentException JavaDoc(excMsg);
2030    }
2031
2032    if (isTraceOn())
2033        trace("getRoles: entering", theRelId);
2034
2035    // Can throw RelationServiceNotRegisteredException
2036
isActive();
2037
2038    // Can throw a RelationNotFoundException
2039
Object JavaDoc relObj = getRelation(theRelId);
2040
2041    RoleResult JavaDoc result = null;
2042
2043    if (relObj instanceof RelationSupport JavaDoc) {
2044        // Internal relation
2045
result = ((RelationSupport JavaDoc)relObj).getRolesInt(theRoleNameArray,
2046                            true,
2047                            this);
2048    } else {
2049        // Relation MBean
2050
Object JavaDoc[] params = new Object JavaDoc[1];
2051        params[0] = theRoleNameArray;
2052        String JavaDoc[] signature = new String JavaDoc[1];
2053        try {
2054        signature[0] = (theRoleNameArray.getClass()).getName();
2055        } catch (Exception JavaDoc exc) {
2056        // OK : This is an array of java.lang.String
2057
// so this should never happen...
2058
}
2059        // Shall not throw InstanceNotFoundException, ReflectionException
2060
// or MBeanException
2061
try {
2062        result = (RoleResult JavaDoc)
2063            (myMBeanServer.invoke(((ObjectName JavaDoc)relObj),
2064                      "getRoles",
2065                      params,
2066                      signature));
2067        } catch (InstanceNotFoundException JavaDoc exc1) {
2068        throw new RuntimeException JavaDoc(exc1.getMessage());
2069        } catch (ReflectionException JavaDoc exc2) {
2070        throw new RuntimeException JavaDoc(exc2.getMessage());
2071        } catch (MBeanException JavaDoc exc3) {
2072        throw new
2073            RuntimeException JavaDoc((exc3.getTargetException()).getMessage());
2074        }
2075    }
2076
2077    if (isTraceOn())
2078        trace("getRoles: exiting", null);
2079    return result;
2080    }
2081
2082    /**
2083     * Returns all roles present in the relation.
2084     *
2085     * @param theRelId relation id
2086     *
2087     * @return a RoleResult object, including a RoleList (for roles
2088     * successfully retrieved) and a RoleUnresolvedList (for roles not
2089     * readable).
2090     *
2091     * @exception IllegalArgumentException if null parameter
2092     * @exception RelationNotFoundException if no relation for given id
2093     * @exception RelationServiceNotRegisteredException if the Relation
2094     * Service is not registered in the MBean Server
2095     */

2096    public RoleResult JavaDoc getAllRoles(String JavaDoc theRelId)
2097        throws IllegalArgumentException JavaDoc,
2098           RelationNotFoundException JavaDoc,
2099               RelationServiceNotRegisteredException JavaDoc {
2100
2101    if (theRelId == null) {
2102        // Revisit [cebro[ Localize message
2103
String JavaDoc excMsg = "Invalid parameter.";
2104        throw new IllegalArgumentException JavaDoc(excMsg);
2105    }
2106
2107    if (isTraceOn())
2108        trace("getAllRoles: entering", theRelId);
2109
2110    // Can throw a RelationNotFoundException
2111
Object JavaDoc relObj = getRelation(theRelId);
2112
2113    RoleResult JavaDoc result = null;
2114
2115    if (relObj instanceof RelationSupport JavaDoc) {
2116        // Internal relation
2117
result = ((RelationSupport JavaDoc)relObj).getAllRolesInt(true, this);
2118
2119    } else {
2120        // Relation MBean
2121
// Shall not throw any Exception
2122
try {
2123        result = (RoleResult JavaDoc)
2124            (myMBeanServer.getAttribute(((ObjectName JavaDoc)relObj),
2125                                                "AllRoles"));
2126        } catch (Exception JavaDoc exc) {
2127        throw new RuntimeException JavaDoc(exc.getMessage());
2128        }
2129    }
2130
2131    if (isTraceOn())
2132        trace("getAllRoles: exiting", null);
2133    return result;
2134    }
2135
2136    /**
2137     * Retrieves the number of MBeans currently referenced in the given role.
2138     *
2139     * @param theRelId relation id
2140     * @param theRoleName name of role
2141     *
2142     * @return the number of currently referenced MBeans in that role
2143     *
2144     * @exception IllegalArgumentException if null parameter
2145     * @exception RelationNotFoundException if no relation with given id
2146     * @exception RoleNotFoundException if there is no role with given name
2147     */

2148    public Integer JavaDoc getRoleCardinality(String JavaDoc theRelId,
2149                      String JavaDoc theRoleName)
2150    throws IllegalArgumentException JavaDoc,
2151               RelationNotFoundException JavaDoc,
2152               RoleNotFoundException JavaDoc {
2153
2154    if (theRelId == null || theRoleName == null) {
2155        // Revisit [cebro[ Localize message
2156
String JavaDoc excMsg = "Invalid parameter.";
2157        throw new IllegalArgumentException JavaDoc(excMsg);
2158    }
2159
2160    if (isTraceOn()) {
2161        String JavaDoc str = "theRelId " + theRelId
2162                    + ", theRoleName " + theRoleName;
2163        trace("getRoleCardinality: entering", str);
2164    }
2165
2166    // Can throw a RelationNotFoundException
2167
Object JavaDoc relObj = getRelation(theRelId);
2168
2169    Integer JavaDoc result = null;
2170
2171    if (relObj instanceof RelationSupport JavaDoc) {
2172        // Internal relation
2173
// Can throw RoleNotFoundException
2174
result = (Integer JavaDoc)
2175        (((RelationSupport JavaDoc)relObj).getRoleCardinality(theRoleName));
2176
2177    } else {
2178        // Relation MBean
2179
Object JavaDoc[] params = new Object JavaDoc[1];
2180        params[0] = theRoleName;
2181        String JavaDoc[] signature = new String JavaDoc[1];
2182        signature[0] = "java.lang.String";
2183        // Can throw MBeanException wrapping RoleNotFoundException:
2184
// throw wrapped exception
2185
//
2186
// Shall not throw InstanceNotFoundException or ReflectionException
2187
try {
2188        result = (Integer JavaDoc)
2189            (myMBeanServer.invoke(((ObjectName JavaDoc)relObj),
2190                      "getRoleCardinality",
2191                      params,
2192                      signature));
2193        } catch (InstanceNotFoundException JavaDoc exc1) {
2194        throw new RuntimeException JavaDoc(exc1.getMessage());
2195        } catch (ReflectionException JavaDoc exc2) {
2196        throw new RuntimeException JavaDoc(exc2.getMessage());
2197        } catch (MBeanException JavaDoc exc3) {
2198        Exception JavaDoc wrappedExc = exc3.getTargetException();
2199        if (wrappedExc instanceof RoleNotFoundException JavaDoc) {
2200            throw ((RoleNotFoundException JavaDoc)wrappedExc);
2201        } else {
2202            throw new RuntimeException JavaDoc(wrappedExc.getMessage());
2203        }
2204        }
2205    }
2206
2207    if (isTraceOn())
2208        trace("getRoleCardinality: exiting", null);
2209    return result;
2210    }
2211
2212    /**
2213     * Sets the given role in given relation.
2214     * <P>Will check the role according to its corresponding role definition
2215     * provided in relation's relation type
2216     * <P>The Relation Service will keep track of the change to keep the
2217     * consistency of relations by handling referenced MBean unregistrations.
2218     *
2219     * @param theRelId relation id
2220     * @param theRole role to be set (name and new value)
2221     *
2222     * @exception RelationServiceNotRegisteredException if the Relation
2223     * Service is not registered in the MBean Server
2224     * @exception IllegalArgumentException if null parameter
2225     * @exception RelationNotFoundException if no relation with given id
2226     * @exception RoleNotFoundException if the role does not exist or is not
2227     * writable
2228     * @exception InvalidRoleValueException if value provided for role is not
2229     * valid:
2230     * <P>- the number of referenced MBeans in given value is less than
2231     * expected minimum degree
2232     * <P>or
2233     * <P>- the number of referenced MBeans in provided value exceeds expected
2234     * maximum degree
2235     * <P>or
2236     * <P>- one referenced MBean in the value is not an Object of the MBean
2237     * class expected for that role
2238     * <P>or
2239     * <P>- an MBean provided for that role does not exist
2240     *
2241     * @see #getRole
2242     */

2243    public void setRole(String JavaDoc theRelId,
2244            Role JavaDoc theRole)
2245    throws RelationServiceNotRegisteredException JavaDoc,
2246           IllegalArgumentException JavaDoc,
2247           RelationNotFoundException JavaDoc,
2248           RoleNotFoundException JavaDoc,
2249           InvalidRoleValueException JavaDoc {
2250
2251    if (theRelId == null || theRole == null) {
2252        // Revisit [cebro[ Localize message
2253
String JavaDoc excMsg = "Invalid parameter.";
2254        throw new IllegalArgumentException JavaDoc(excMsg);
2255    }
2256
2257    if (isTraceOn()) {
2258        String JavaDoc str = new String JavaDoc("theRelId " + theRelId
2259                    + ", theRole " + theRole.toString());
2260        trace("setRole: entering", str);
2261    }
2262
2263    // Can throw RelationServiceNotRegisteredException
2264
isActive();
2265
2266    // Can throw a RelationNotFoundException
2267
Object JavaDoc relObj = getRelation(theRelId);
2268
2269    if (relObj instanceof RelationSupport JavaDoc) {
2270        // Internal relation
2271
// Can throw RoleNotFoundException,
2272
// InvalidRoleValueException and
2273
// RelationServiceNotRegisteredException
2274
//
2275
// Shall not throw RelationTypeNotFoundException
2276
// (as relation exists in the RS, its relation type is known)
2277
try {
2278        ((RelationSupport JavaDoc)relObj).setRoleInt(theRole,
2279                          true,
2280                          this,
2281                          false);
2282
2283        } catch (RelationTypeNotFoundException JavaDoc exc) {
2284        throw new RuntimeException JavaDoc(exc.getMessage());
2285        }
2286
2287    } else {
2288        // Relation MBean
2289
Object JavaDoc[] params = new Object JavaDoc[1];
2290        params[0] = theRole;
2291        String JavaDoc[] signature = new String JavaDoc[1];
2292        signature[0] = "javax.management.relation.Role";
2293        // Can throw MBeanException wrapping RoleNotFoundException,
2294
// InvalidRoleValueException
2295
//
2296
// Shall not MBeanException wrapping an MBeanException wrapping
2297
// RelationTypeNotFoundException, or ReflectionException, or
2298
// InstanceNotFoundException
2299
try {
2300        myMBeanServer.setAttribute(((ObjectName JavaDoc)relObj),
2301                                           new Attribute JavaDoc("Role", theRole));
2302
2303        } catch (InstanceNotFoundException JavaDoc exc1) {
2304        throw new RuntimeException JavaDoc(exc1.getMessage());
2305        } catch (ReflectionException JavaDoc exc3) {
2306        throw new RuntimeException JavaDoc(exc3.getMessage());
2307        } catch (MBeanException JavaDoc exc2) {
2308        Exception JavaDoc wrappedExc = exc2.getTargetException();
2309        if (wrappedExc instanceof RoleNotFoundException JavaDoc) {
2310            throw ((RoleNotFoundException JavaDoc)wrappedExc);
2311        } else if (wrappedExc instanceof InvalidRoleValueException JavaDoc) {
2312            throw ((InvalidRoleValueException JavaDoc)wrappedExc);
2313        } else {
2314            throw new RuntimeException JavaDoc(wrappedExc.getMessage());
2315
2316        }
2317        } catch (AttributeNotFoundException JavaDoc exc4) {
2318              throw new RuntimeException JavaDoc(exc4.getMessage());
2319            } catch (InvalidAttributeValueException JavaDoc exc5) {
2320              throw new RuntimeException JavaDoc(exc5.getMessage());
2321            }
2322    }
2323
2324    if (isTraceOn())
2325        trace("setRole: exiting", null);
2326    return;
2327    }
2328
2329    /**
2330     * Sets the given roles in given relation.
2331     * <P>Will check the role according to its corresponding role definition
2332     * provided in relation's relation type
2333     * <P>The Relation Service keeps track of the changes to keep the
2334     * consistency of relations by handling referenced MBean unregistrations.
2335     *
2336     * @param theRelId relation id
2337     * @param theRoleList list of roles to be set
2338     *
2339     * @return a RoleResult object, including a RoleList (for roles
2340     * successfully set) and a RoleUnresolvedList (for roles not
2341     * set).
2342     *
2343     * @exception RelationServiceNotRegisteredException if the Relation
2344     * Service is not registered in the MBean Server
2345     * @exception IllegalArgumentException if null parameter
2346     * @exception RelationNotFoundException if no relation with given id
2347     *
2348     * @see #getRoles
2349     */

2350    public RoleResult JavaDoc setRoles(String JavaDoc theRelId,
2351                   RoleList JavaDoc theRoleList)
2352    throws RelationServiceNotRegisteredException JavaDoc,
2353           IllegalArgumentException JavaDoc,
2354               RelationNotFoundException JavaDoc {
2355
2356    if (theRelId == null || theRoleList == null) {
2357        // Revisit [cebro[ Localize message
2358
String JavaDoc excMsg = "Invalid parameter.";
2359        throw new IllegalArgumentException JavaDoc(excMsg);
2360    }
2361
2362    if (isTraceOn()) {
2363        String JavaDoc str = new String JavaDoc("theRelId " + theRelId
2364                    + ", theRoleList "
2365                    + theRoleList.toString());
2366        trace("setRoles: entering", str);
2367    }
2368
2369    // Can throw RelationServiceNotRegisteredException
2370
isActive();
2371
2372    // Can throw a RelationNotFoundException
2373
Object JavaDoc relObj = getRelation(theRelId);
2374
2375    RoleResult JavaDoc result = null;
2376
2377    if (relObj instanceof RelationSupport JavaDoc) {
2378        // Internal relation
2379
// Can throw RelationServiceNotRegisteredException
2380
//
2381
// Shall not throw RelationTypeNotFoundException (as relation is
2382
// known, its relation type exists)
2383
try {
2384        result = ((RelationSupport JavaDoc)relObj).setRolesInt(theRoleList,
2385                                true,
2386                                this);
2387        } catch (RelationTypeNotFoundException JavaDoc exc) {
2388        throw new RuntimeException JavaDoc(exc.getMessage());
2389        }
2390
2391    } else {
2392        // Relation MBean
2393
Object JavaDoc[] params = new Object JavaDoc[1];
2394        params[0] = theRoleList;
2395        String JavaDoc[] signature = new String JavaDoc[1];
2396        signature[0] = "javax.management.relation.RoleList";
2397        // Shall not throw InstanceNotFoundException or an MBeanException
2398
// or ReflectionException
2399
try {
2400        result = (RoleResult JavaDoc)
2401            (myMBeanServer.invoke(((ObjectName JavaDoc)relObj),
2402                      "setRoles",
2403                      params,
2404                      signature));
2405        } catch (InstanceNotFoundException JavaDoc exc1) {
2406        throw new RuntimeException JavaDoc(exc1.getMessage());
2407        } catch (ReflectionException JavaDoc exc3) {
2408        throw new RuntimeException JavaDoc(exc3.getMessage());
2409        } catch (MBeanException JavaDoc exc2) {
2410        throw new
2411            RuntimeException JavaDoc((exc2.getTargetException()).getMessage());
2412        }
2413    }
2414
2415    if (isTraceOn())
2416        trace("setRoles: exiting", null);
2417    return result;
2418    }
2419
2420    /**
2421     * Retrieves MBeans referenced in the various roles of the relation.
2422     *
2423     * @param theRelId relation id
2424     *
2425     * @return a HashMap mapping:
2426     * <P> ObjectName -> ArrayList of String (role
2427     * names)
2428     *
2429     * @exception IllegalArgumentException if null parameter
2430     * @exception RelationNotFoundException if no relation for given
2431     * relation id
2432     */

2433    public Map JavaDoc getReferencedMBeans(String JavaDoc theRelId)
2434    throws IllegalArgumentException JavaDoc,
2435           RelationNotFoundException JavaDoc {
2436
2437    if (theRelId == null) {
2438        // Revisit [cebro[ Localize message
2439
String JavaDoc excMsg = "Invalid parameter.";
2440        throw new IllegalArgumentException JavaDoc(excMsg);
2441    }
2442
2443    if (isTraceOn())
2444        trace("getReferencedMBeans: entering", theRelId);
2445
2446    // Can throw a RelationNotFoundException
2447
Object JavaDoc relObj = getRelation(theRelId);
2448
2449    HashMap JavaDoc result = null;
2450
2451    if (relObj instanceof RelationSupport JavaDoc) {
2452        // Internal relation
2453
result = (HashMap JavaDoc)(((RelationSupport JavaDoc)relObj).getReferencedMBeans());
2454
2455    } else {
2456        // Relation MBean
2457
// No Exception
2458
try {
2459        result = (HashMap JavaDoc)
2460            (myMBeanServer.getAttribute(((ObjectName JavaDoc)relObj),
2461                                                "ReferencedMBeans"));
2462        } catch (Exception JavaDoc exc) {
2463        throw new RuntimeException JavaDoc(exc.getMessage());
2464        }
2465    }
2466
2467    if (isTraceOn())
2468        trace("getReferencedMBeans: exiting", null);
2469    return result;
2470    }
2471
2472    /**
2473     * Returns name of associated relation type for given relation.
2474     *
2475     * @param theRelId relation id
2476     *
2477     * @return the name of the associated relation type.
2478     *
2479     * @exception IllegalArgumentException if null parameter
2480     * @exception RelationNotFoundException if no relation for given
2481     * relation id
2482     */

2483    public String JavaDoc getRelationTypeName(String JavaDoc theRelId)
2484    throws IllegalArgumentException JavaDoc,
2485           RelationNotFoundException JavaDoc {
2486
2487    if (theRelId == null) {
2488        // Revisit [cebro[ Localize message
2489
String JavaDoc excMsg = "Invalid parameter.";
2490        throw new IllegalArgumentException JavaDoc(excMsg);
2491    }
2492
2493    if (isTraceOn())
2494        trace("getRelationTypeName: entering", theRelId);
2495
2496    // Can throw a RelationNotFoundException
2497
Object JavaDoc relObj = getRelation(theRelId);
2498
2499    String JavaDoc result = null;
2500
2501    if (relObj instanceof RelationSupport JavaDoc) {
2502        // Internal relation
2503
result = ((RelationSupport JavaDoc)relObj).getRelationTypeName();
2504
2505    } else {
2506        // Relation MBean
2507
// No Exception
2508
try {
2509        result = (String JavaDoc)
2510            (myMBeanServer.getAttribute(((ObjectName JavaDoc)relObj),
2511                                                "RelationTypeName"));
2512        } catch (Exception JavaDoc exc) {
2513        throw new RuntimeException JavaDoc(exc.getMessage());
2514        }
2515    }
2516
2517    if (isTraceOn())
2518        trace("getRelationTypeName: exiting", null);
2519    return result;
2520    }
2521
2522    //
2523
// NotificationListener Interface
2524
//
2525

2526    /**
2527     * Invoked when a JMX notification occurs.
2528     * Currently handles notifications for unregistration of MBeans, either
2529     * referenced in a relation role or being a relation itself.
2530     *
2531     * @param theNtf The notification.
2532     * @param theHandback An opaque object which helps the listener to
2533     * associate information regarding the MBean emitter (can be null).
2534     */

2535    public void handleNotification(Notification JavaDoc theNtf,
2536                   Object JavaDoc theHandback) {
2537
2538    if (theNtf == null) {
2539        // Revisit [cebro[ Localize message
2540
String JavaDoc excMsg = "Invalid parameter.";
2541        throw new IllegalArgumentException JavaDoc(excMsg);
2542    }
2543
2544    if (isTraceOn())
2545        trace("handleNotification: entering", theNtf.toString());
2546
2547    if (theNtf instanceof MBeanServerNotification JavaDoc) {
2548
2549        String JavaDoc ntfType = theNtf.getType();
2550
2551        if (ntfType.equals(
2552               MBeanServerNotification.UNREGISTRATION_NOTIFICATION )) {
2553        ObjectName JavaDoc mbeanName =
2554            ((MBeanServerNotification JavaDoc)theNtf).getMBeanName();
2555
2556        // Note: use a flag to block access to
2557
// myRefedMBeanObjName2RelIdsMap only for a quick access
2558
boolean isRefedMBeanFlg = false;
2559        synchronized(myRefedMBeanObjName2RelIdsMap) {
2560
2561            if (myRefedMBeanObjName2RelIdsMap.containsKey(mbeanName)) {
2562            // Unregistration of a referenced MBean
2563
synchronized(myUnregNtfList) {
2564                myUnregNtfList.add(theNtf);
2565            }
2566            isRefedMBeanFlg = true;
2567            }
2568            if (isRefedMBeanFlg && myPurgeFlg) {
2569            // Immediate purge
2570
// Can throw RelationServiceNotRegisteredException
2571
// but assume that will be fine :)
2572
try {
2573                purgeRelations();
2574            } catch (Exception JavaDoc exc) {
2575                throw new RuntimeException JavaDoc(exc.getMessage());
2576            }
2577            }
2578        }
2579
2580        // Note: do both tests as a relation can be an MBean and be
2581
// itself referenced in another relation :)
2582
String JavaDoc relId = null;
2583        synchronized(myRelMBeanObjName2RelIdMap){
2584            relId = (String JavaDoc)
2585            (myRelMBeanObjName2RelIdMap.get(mbeanName));
2586        }
2587        if (relId != null) {
2588            // Unregistration of a relation MBean
2589
// Can throw RelationTypeNotFoundException,
2590
// RelationServiceNotRegisteredException
2591
//
2592
// Shall not throw RelationTypeNotFoundException or
2593
// InstanceNotFoundException
2594
try {
2595            removeRelation(relId);
2596            } catch (Exception JavaDoc exc) {
2597            throw new RuntimeException JavaDoc(exc.getMessage());
2598            }
2599        }
2600        }
2601    }
2602
2603    if (isTraceOn())
2604        trace("handleNotification: exiting", null);
2605    return;
2606    }
2607
2608    //
2609
// NotificationBroadcaster interface
2610
//
2611

2612    /**
2613     * Returns a NotificationInfo object containing the name of the Java class
2614     * of the notification and the notification types sent.
2615     */

2616    public MBeanNotificationInfo JavaDoc[] getNotificationInfo() {
2617
2618    if (isTraceOn())
2619        trace("getNotificationInfo: entering", null);
2620
2621    MBeanNotificationInfo JavaDoc[] ntfInfoArray =
2622        new MBeanNotificationInfo JavaDoc[1];
2623
2624    String JavaDoc ntfClass = "javax.management.relation.RelationNotification";
2625
2626    String JavaDoc[] ntfTypes = new String JavaDoc[] {
2627        RelationNotification.RELATION_BASIC_CREATION,
2628        RelationNotification.RELATION_MBEAN_CREATION,
2629        RelationNotification.RELATION_BASIC_UPDATE,
2630        RelationNotification.RELATION_MBEAN_UPDATE,
2631        RelationNotification.RELATION_BASIC_REMOVAL,
2632        RelationNotification.RELATION_MBEAN_REMOVAL,
2633    };
2634
2635    String JavaDoc ntfDesc = "Sent when a relation is created, updated or deleted.";
2636
2637    MBeanNotificationInfo JavaDoc ntfInfo =
2638        new MBeanNotificationInfo JavaDoc(ntfTypes, ntfClass, ntfDesc);
2639
2640    if (isTraceOn())
2641        trace("getNotificationInfo: exiting", null);
2642    return new MBeanNotificationInfo JavaDoc[] {ntfInfo};
2643    }
2644
2645    //
2646
// Misc
2647
//
2648

2649    // Adds given object as a relation type.
2650
//
2651
// -param theRelTypeObj relation type object
2652
//
2653
// -exception IllegalArgumentException if null parameter
2654
// -exception InvalidRelationTypeException if there is already a relation
2655
// type with that name
2656
private void addRelationTypeInt(RelationType JavaDoc theRelTypeObj)
2657    throws IllegalArgumentException JavaDoc,
2658           InvalidRelationTypeException JavaDoc {
2659
2660    if (theRelTypeObj == null) {
2661        // Revisit [cebro] Localize message
2662
String JavaDoc excMsg = "Invalid parameter.";
2663        throw new IllegalArgumentException JavaDoc(excMsg);
2664    }
2665
2666    if (isDebugOn())
2667        debug("addRelationTypeInt: entering", null);
2668
2669    String JavaDoc relTypeName = theRelTypeObj.getRelationTypeName();
2670
2671    // Checks that there is not already a relation type with that name
2672
// existing in the Relation Service
2673
try {
2674        // Can throw a RelationTypeNotFoundException (in fact should ;)
2675
RelationType JavaDoc relType = getRelationType(relTypeName);
2676
2677        if (relType != null) {
2678        // Revisit [cebro] Localize message
2679
String JavaDoc excMsg = "There is already a relation type in the Relation Service with name ";
2680        StringBuffer JavaDoc excMsgStrB = new StringBuffer JavaDoc(excMsg);
2681        excMsgStrB.append(relTypeName);
2682        throw new InvalidRelationTypeException JavaDoc(excMsgStrB.toString());
2683        }
2684
2685    } catch (RelationTypeNotFoundException JavaDoc exc) {
2686        // OK : The RelationType could not be found.
2687
}
2688
2689    // Adds the relation type
2690
synchronized(myRelType2ObjMap) {
2691        myRelType2ObjMap.put(relTypeName, theRelTypeObj);
2692    }
2693
2694    if (theRelTypeObj instanceof RelationTypeSupport JavaDoc) {
2695        ((RelationTypeSupport JavaDoc)theRelTypeObj).setRelationServiceFlag(true);
2696    }
2697
2698    if (isDebugOn())
2699        debug("addRelationTypeInt: exiting", null);
2700    return;
2701     }
2702
2703    // Retrieves relation type with given name
2704
//
2705
// -param theRelTypeName expected name of a relation type created in the
2706
// Relation Service
2707
//
2708
// -return RelationType object corresponding to given name
2709
//
2710
// -exception IllegalArgumentException if null parameter
2711
// -exception RelationTypeNotFoundException if no relation type for that
2712
// name created in Relation Service
2713
//
2714
RelationType JavaDoc getRelationType(String JavaDoc theRelTypeName)
2715    throws IllegalArgumentException JavaDoc,
2716           RelationTypeNotFoundException JavaDoc {
2717
2718    if (theRelTypeName == null) {
2719        // Revisit [cebro[ Localize message
2720
String JavaDoc excMsg = "Invalid parameter.";
2721        throw new IllegalArgumentException JavaDoc(excMsg);
2722    }
2723
2724    if (isDebugOn())
2725        debug("getRelationType: entering", theRelTypeName);
2726
2727    // No null relation type accepted, so can use get()
2728
RelationType JavaDoc relType = null;
2729    synchronized(myRelType2ObjMap) {
2730        relType = (RelationType JavaDoc)(myRelType2ObjMap.get(theRelTypeName));
2731    }
2732
2733    if (relType == null) {
2734        // Revisit [cebro] Localize message
2735
String JavaDoc excMsg = "No relation type created in the Relation Service with the name ";
2736        StringBuffer JavaDoc excMsgStrB = new StringBuffer JavaDoc(excMsg);
2737        excMsgStrB.append(theRelTypeName);
2738        throw new RelationTypeNotFoundException JavaDoc(excMsgStrB.toString());
2739    }
2740
2741    if (isDebugOn())
2742        debug("getRelationType: exiting", null);
2743    return relType;
2744    }
2745
2746    // Retrieves relation corresponding to given relation id.
2747
// Returns either:
2748
// - a RelationSupport object if the relation is internal
2749
// or
2750
// - the ObjectName of the corresponding MBean
2751
//
2752
// -param theRelId expected relation id
2753
//
2754
// -return RelationSupport object or ObjectName of relation with given id
2755
//
2756
// -exception IllegalArgumentException if null parameter
2757
// -exception RelationNotFoundException if no relation for that
2758
// relation id created in Relation Service
2759
//
2760
Object JavaDoc getRelation(String JavaDoc theRelId)
2761    throws IllegalArgumentException JavaDoc,
2762           RelationNotFoundException JavaDoc {
2763
2764    if (theRelId == null) {
2765        // Revisit [cebro] Localize message
2766
String JavaDoc excMsg = "Invalid parameter.";
2767        throw new IllegalArgumentException JavaDoc(excMsg);
2768    }
2769
2770    if (isDebugOn())
2771        debug("getRelation: entering", theRelId);
2772
2773    // No null relation accepted, so can use get()
2774
Object JavaDoc rel = null;
2775    synchronized(myRelId2ObjMap) {
2776        rel = myRelId2ObjMap.get(theRelId);
2777    }
2778
2779    if (rel == null) {
2780        StringBuffer JavaDoc excMsgStrB = new StringBuffer JavaDoc();
2781        // Revisit [cebro] Localize message
2782
String JavaDoc excMsg = "No relation associated to relation id ";
2783        excMsgStrB.append(excMsg);
2784        excMsgStrB.append(theRelId);
2785        throw new RelationNotFoundException JavaDoc(excMsgStrB.toString());
2786    }
2787
2788    if (isDebugOn())
2789        debug("getRelation: exiting", null);
2790    return rel;
2791    }
2792
2793    // Adds a new MBean reference (reference to an ObjectName) in the
2794
// referenced MBean map (myRefedMBeanObjName2RelIdsMap).
2795
//
2796
// -param theObjName ObjectName of new referenced MBean
2797
// -param theRelId relation id of the relation where the MBean is
2798
// referenced
2799
// -param theRoleName name of the role where the MBean is referenced
2800
//
2801
// -return boolean:
2802
// - true if the MBean was not referenced before, so really a new
2803
// reference
2804
// - false else
2805
//
2806
// -exception IllegalArgumentException if null parameter
2807
private boolean addNewMBeanReference(ObjectName JavaDoc theObjName,
2808                     String JavaDoc theRelId,
2809                     String JavaDoc theRoleName)
2810    throws IllegalArgumentException JavaDoc {
2811
2812    if (theObjName == null ||
2813        theRelId == null ||
2814        theRoleName == null) {
2815        // Revisit [cebro] Localize message
2816
String JavaDoc excMsg = "Invalid parameter.";
2817        throw new IllegalArgumentException JavaDoc(excMsg);
2818    }
2819
2820    if (isDebugOn()) {
2821        String JavaDoc str = new String JavaDoc("theObjName " + theObjName.toString()
2822                    + ", theRelId " + theRelId
2823                    + ", theRoleName " + theRoleName);
2824        debug("addNewMBeanReference: entering", str);
2825    }
2826
2827    boolean isNewFlg = false;
2828
2829    synchronized(myRefedMBeanObjName2RelIdsMap) {
2830
2831        // Checks if the MBean was already referenced
2832
// No null value allowed, use get() directly
2833
HashMap JavaDoc mbeanRefMap = (HashMap JavaDoc)
2834        (myRefedMBeanObjName2RelIdsMap.get(theObjName));
2835
2836        if (mbeanRefMap == null) {
2837        // MBean not referenced in any relation yet
2838

2839        isNewFlg = true;
2840
2841        // List of roles where the MBean is referenced in given
2842
// relation
2843
ArrayList JavaDoc roleNames = new ArrayList JavaDoc();
2844        roleNames.add(theRoleName);
2845
2846        // Map of relations where the MBean is referenced
2847
mbeanRefMap = new HashMap JavaDoc();
2848        mbeanRefMap.put(theRelId, roleNames);
2849
2850        myRefedMBeanObjName2RelIdsMap.put(theObjName, mbeanRefMap);
2851
2852        } else {
2853        // MBean already referenced in at least another relation
2854
// Checks if already referenced in another role in current
2855
// relation
2856
ArrayList JavaDoc roleNames = (ArrayList JavaDoc)(mbeanRefMap.get(theRelId));
2857
2858        if (roleNames == null) {
2859            // MBean not referenced in current relation
2860

2861            // List of roles where the MBean is referenced in given
2862
// relation
2863
roleNames = new ArrayList JavaDoc();
2864            roleNames.add(theRoleName);
2865
2866            // Adds new reference done in current relation
2867
mbeanRefMap.put(theRelId, roleNames);
2868
2869        } else {
2870            // MBean already referenced in current relation in another
2871
// role
2872
// Adds new reference done
2873
roleNames.add(theRoleName);
2874        }
2875        }
2876    }
2877
2878    if (isDebugOn())
2879        debug("addNewMBeanReference: exiting", null);
2880    return isNewFlg;
2881    }
2882
2883    // Removes an obsolete MBean reference (reference to an ObjectName) in
2884
// the referenced MBean map (myRefedMBeanObjName2RelIdsMap).
2885
//
2886
// -param theObjName ObjectName of MBean no longer referenced
2887
// -param theRelId relation id of the relation where the MBean was
2888
// referenced
2889
// -param theRoleName name of the role where the MBean was referenced
2890
// -param theAllRolesFlg flag, if true removes reference to MBean for all
2891
// roles in the relation, not only for the one above
2892
//
2893
// -return boolean:
2894
// - true if the MBean is no longer reference in any relation
2895
// - false else
2896
//
2897
// -exception IllegalArgumentException if null parameter
2898
private boolean removeMBeanReference(ObjectName JavaDoc theObjName,
2899                     String JavaDoc theRelId,
2900                     String JavaDoc theRoleName,
2901                     boolean theAllRolesFlg)
2902    throws IllegalArgumentException JavaDoc {
2903
2904    if (theObjName == null ||
2905        theRelId == null ||
2906        theRoleName == null) {
2907        // Revisit [cebro] Localize message
2908
String JavaDoc excMsg = "Invalid parameter.";
2909        throw new IllegalArgumentException JavaDoc(excMsg);
2910    }
2911
2912    if (isDebugOn()) {
2913        String JavaDoc str = new String JavaDoc("theObjName " + theObjName.toString()
2914                    + ", theRelId " + theRelId
2915                    + ", theRoleName " + theRoleName
2916                    + ", theAllRolesFlg " + theAllRolesFlg);
2917        debug("removeMBeanReference: entering", str);
2918    }
2919
2920    boolean noLongerRefFlg = false;
2921
2922    synchronized(myRefedMBeanObjName2RelIdsMap) {
2923
2924        // Retrieves the set of relations (designed via their relation ids)
2925
// where the MBean is referenced
2926
// Note that it is possible that the MBean has already been removed
2927
// from the internal map: this is the case when the MBean is
2928
// unregistered, the role is updated, then we arrive here.
2929
HashMap JavaDoc mbeanRefMap = (HashMap JavaDoc)
2930        (myRefedMBeanObjName2RelIdsMap.get(theObjName));
2931
2932        if (mbeanRefMap == null) {
2933        // The MBean is no longer referenced
2934
if (isDebugOn())
2935            debug("removeMBeanReference: exiting", null);
2936        return true;
2937        }
2938
2939        ArrayList JavaDoc roleNames = new ArrayList JavaDoc();
2940        if (!theAllRolesFlg) {
2941        // Now retrieves the roles of current relation where the MBean
2942
// was referenced
2943
roleNames = (ArrayList JavaDoc)(mbeanRefMap.get(theRelId));
2944
2945        // Removes obsolete reference to role
2946
int obsRefIdx = roleNames.indexOf(theRoleName);
2947        if (obsRefIdx != -1) {
2948            roleNames.remove(obsRefIdx);
2949        }
2950        }
2951
2952        // Checks if there is still at least one role in current relation
2953
// where the MBean is referenced
2954
if (roleNames.isEmpty() || theAllRolesFlg) {
2955        // MBean no longer referenced in current relation: removes
2956
// entry
2957
mbeanRefMap.remove(theRelId);
2958        }
2959
2960        // Checks if the MBean is still referenced in at least on relation
2961
if (mbeanRefMap.isEmpty()) {
2962        // MBean no longer referenced in any relation: removes entry
2963
myRefedMBeanObjName2RelIdsMap.remove(theObjName);
2964        noLongerRefFlg = true;
2965        }
2966    }
2967
2968    if (isDebugOn())
2969        debug("removeMBeanReference: exiting", null);
2970    return noLongerRefFlg;
2971    }
2972
2973    // Updates the listener registered to the MBean Server to be informed of
2974
// referenced MBean unregistrations
2975
//
2976
// -param theNewRefList ArrayList of ObjectNames for new references done
2977
// to MBeans (can be null)
2978
// -param theObsRefList ArrayList of ObjectNames for obsolete references
2979
// to MBeans (can be null)
2980
//
2981
// -exception RelationServiceNotRegisteredException if the Relation
2982
// Service is not registered in the MBean Server.
2983
private void updateUnregistrationListener(List JavaDoc theNewRefList,
2984                          List JavaDoc theObsRefList)
2985    throws RelationServiceNotRegisteredException JavaDoc {
2986
2987    if (theNewRefList != null && theObsRefList != null) {
2988        if (theNewRefList.isEmpty() && theObsRefList.isEmpty()) {
2989        // Nothing to do :)
2990
return;
2991        }
2992    }
2993
2994    if (isDebugOn()) {
2995        StringBuffer JavaDoc strB = new StringBuffer JavaDoc();
2996        if (theNewRefList != null) {
2997        strB.append("theNewRefList " + theNewRefList.toString());
2998        }
2999        if (theObsRefList != null) {
3000        strB.append(", theObsRefList" + theObsRefList.toString());
3001        }
3002        debug("updateUnregistrationListener: entering", strB.toString());
3003    }
3004
3005    // Can throw RelationServiceNotRegisteredException
3006
isActive();
3007
3008    if (theNewRefList != null || theObsRefList != null) {
3009
3010        boolean newListenerFlg = false;
3011        if (myUnregNtfFilter == null) {
3012        // Initialise it to be able to synchronise it :)
3013
myUnregNtfFilter = new MBeanServerNotificationFilter JavaDoc();
3014        newListenerFlg = true;
3015        }
3016
3017        synchronized(myUnregNtfFilter) {
3018
3019        // Enables ObjectNames in theNewRefList
3020
if (theNewRefList != null) {
3021            for (Iterator JavaDoc newRefIter = theNewRefList.iterator();
3022             newRefIter.hasNext();) {
3023
3024            ObjectName JavaDoc newObjName = (ObjectName JavaDoc)
3025                (newRefIter.next());
3026            myUnregNtfFilter.enableObjectName(newObjName);
3027            }
3028        }
3029
3030        if (theObsRefList != null) {
3031            // Disables ObjectNames in theObsRefList
3032
for (Iterator JavaDoc obsRefIter = theObsRefList.iterator();
3033             obsRefIter.hasNext();) {
3034
3035            ObjectName JavaDoc obsObjName = (ObjectName JavaDoc)
3036                (obsRefIter.next());
3037            myUnregNtfFilter.disableObjectName(obsObjName);
3038            }
3039        }
3040
3041        // Creates ObjectName of the MBeanServerDelegate handling the
3042
// notifications
3043
ObjectName JavaDoc mbeanServerDelegateName = null;
3044        try {
3045            mbeanServerDelegateName =
3046            new ObjectName JavaDoc(ServiceName.DELEGATE);
3047        } catch (MalformedObjectNameException JavaDoc exc) {
3048            // OK : Should never happen...
3049
}
3050
3051// Under test
3052
if (newListenerFlg) {
3053            try {
3054            myMBeanServer.addNotificationListener(
3055                               mbeanServerDelegateName,
3056                               this,
3057                               myUnregNtfFilter,
3058                               null);
3059            } catch (InstanceNotFoundException JavaDoc exc) {
3060            throw new
3061               RelationServiceNotRegisteredException JavaDoc(exc.getMessage());
3062            }
3063        }
3064// End test
3065

3066
3067// if (!newListenerFlg) {
3068
// The Relation Service was already registered as a
3069
// listener:
3070
// removes it
3071
// Shall not throw InstanceNotFoundException (as the
3072
// MBean Server Delegate is expected to exist) or
3073
// ListenerNotFoundException (as it has been checked above
3074
// that the Relation Service is registered)
3075
// try {
3076
// myMBeanServer.removeNotificationListener(
3077
// mbeanServerDelegateName,
3078
// this);
3079
// } catch (InstanceNotFoundException exc1) {
3080
// throw new RuntimeException(exc1.getMessage());
3081
// } catch (ListenerNotFoundException exc2) {
3082
// throw new
3083
// RelationServiceNotRegisteredException(exc2.getMessage());
3084
// }
3085
// }
3086

3087        // Adds Relation Service with current filter
3088
// Can throw InstanceNotFoundException if the Relation
3089
// Service is not registered, to be transformed into
3090
// RelationServiceNotRegisteredException
3091
//
3092
// Assume that there will not be any InstanceNotFoundException
3093
// for the MBean Server Delegate :)
3094
// try {
3095
// myMBeanServer.addNotificationListener(
3096
// mbeanServerDelegateName,
3097
// this,
3098
// myUnregNtfFilter,
3099
// null);
3100
// } catch (InstanceNotFoundException exc) {
3101
// throw new
3102
// RelationServiceNotRegisteredException(exc.getMessage());
3103
// }
3104
}
3105    }
3106
3107    if (isDebugOn())
3108        debug("updateUnregistrationListener: exiting", null);
3109    return;
3110    }
3111
3112    // Adds a relation (being either a RelationSupport object or an MBean
3113
// referenced using its ObjectName) in the Relation Service.
3114
// Will send a notification RelationNotification with type:
3115
// - RelationNotification.RELATION_BASIC_CREATION for internal relation
3116
// creation
3117
// - RelationNotification.RELATION_MBEAN_CREATION for an MBean being added
3118
// as a relation.
3119
//
3120
// -param theRelBaseFlg flag true if the relation is a RelationSupport
3121
// object, false if it is an MBean
3122
// -param theRelObj RelationSupport object (if relation is internal)
3123
// -param theRelObjName ObjectName of the MBean to be added as a relation
3124
// (only for the relation MBean)
3125
// -param theRelId relation identifier, to uniquely identify the relation
3126
// inside the Relation Service
3127
// -param theRelTypeName name of the relation type (has to be created
3128
// in the Relation Service)
3129
// -param theRoleList role list to initialize roles of the relation
3130
// (can be null)
3131
//
3132
// -exception IllegalArgumentException if null paramater
3133
// -exception RelationServiceNotRegisteredException if the Relation
3134
// Service is not registered in the MBean Server
3135
// -exception RoleNotFoundException if a value is provided for a role
3136
// that does not exist in the relation type
3137
// -exception InvalidRelationIdException if relation id already used
3138
// -exception RelationTypeNotFoundException if relation type not known in
3139
// Relation Service
3140
// -exception InvalidRoleValueException if:
3141
// - the same role name is used for two different roles
3142
// - the number of referenced MBeans in given value is less than
3143
// expected minimum degree
3144
// - the number of referenced MBeans in provided value exceeds expected
3145
// maximum degree
3146
// - one referenced MBean in the value is not an Object of the MBean
3147
// class expected for that role
3148
// - an MBean provided for that role does not exist
3149
private void addRelationInt(boolean theRelBaseFlg,
3150                RelationSupport JavaDoc theRelObj,
3151                ObjectName JavaDoc theRelObjName,
3152                String JavaDoc theRelId,
3153                String JavaDoc theRelTypeName,
3154                RoleList JavaDoc theRoleList)
3155    throws IllegalArgumentException JavaDoc,
3156           RelationServiceNotRegisteredException JavaDoc,
3157               RoleNotFoundException JavaDoc,
3158               InvalidRelationIdException JavaDoc,
3159               RelationTypeNotFoundException JavaDoc,
3160               InvalidRoleValueException JavaDoc {
3161
3162    if (theRelId == null ||
3163        theRelTypeName == null ||
3164        (theRelBaseFlg &&
3165         (theRelObj == null ||
3166          theRelObjName != null)) ||
3167        (!theRelBaseFlg &&
3168         (theRelObjName == null ||
3169          theRelObj != null))) {
3170        // Revisit [cebro[ Localize message
3171
String JavaDoc excMsg = "Invalid parameter.";
3172        throw new IllegalArgumentException JavaDoc(excMsg);
3173    }
3174
3175    if (isDebugOn()) {
3176        StringBuffer JavaDoc strB = new StringBuffer JavaDoc("theRelBaseFlg "
3177                         + theRelBaseFlg
3178                         + ", theRelId " + theRelId
3179                         + ", theRelTypeName "
3180                         + theRelTypeName);
3181        if (theRelObjName != null) {
3182        strB.append(", theRelObjName " + theRelObjName.toString());
3183        }
3184        if (theRoleList != null) {
3185        strB.append(", theRoleList " + theRoleList.toString());
3186        }
3187        debug("addRelationInt: entering", strB.toString());
3188    }
3189
3190    // Can throw RelationServiceNotRegisteredException
3191
isActive();
3192
3193    // Checks if there is already a relation with given id
3194
try {
3195        // Can throw a RelationNotFoundException (in fact should :)
3196
Object JavaDoc rel = getRelation(theRelId);
3197
3198        if (rel != null) {
3199        // There is already a relation with that id
3200
// Revisit [cebro] Localize message
3201
String JavaDoc excMsg = "There is already a relation with id ";
3202        StringBuffer JavaDoc excMsgStrB = new StringBuffer JavaDoc(excMsg);
3203        excMsgStrB.append(theRelId);
3204        throw new InvalidRelationIdException JavaDoc(excMsgStrB.toString());
3205        }
3206    } catch (RelationNotFoundException JavaDoc exc) {
3207        // OK : The Relation could not be found.
3208
}
3209
3210    // Retrieves the relation type
3211
// Can throw RelationTypeNotFoundException
3212
RelationType JavaDoc relType = getRelationType(theRelTypeName);
3213
3214    // Checks that each provided role conforms to its role info provided in
3215
// the relation type
3216
// First retrieves a local list of the role infos of the relation type
3217
// to see which roles have not been initialized
3218
// Note: no need to test if list not null before cloning, not allowed
3219
// to have an empty relation type.
3220
ArrayList JavaDoc roleInfoList = (ArrayList JavaDoc)
3221        (((ArrayList JavaDoc)(relType.getRoleInfos())).clone());
3222
3223    if (theRoleList != null) {
3224
3225        for (Iterator JavaDoc roleIter = theRoleList.iterator();
3226         roleIter.hasNext();) {
3227
3228        Role JavaDoc currRole = (Role JavaDoc)(roleIter.next());
3229        String JavaDoc currRoleName = currRole.getRoleName();
3230        ArrayList JavaDoc currRoleValue = (ArrayList JavaDoc)
3231            (currRole.getRoleValue());
3232        // Retrieves corresponding role info
3233
// Can throw a RoleInfoNotFoundException to be converted into a
3234
// RoleNotFoundException
3235
RoleInfo JavaDoc roleInfo = null;
3236        try {
3237            roleInfo = relType.getRoleInfo(currRoleName);
3238        } catch (RoleInfoNotFoundException JavaDoc exc) {
3239            throw new RoleNotFoundException JavaDoc(exc.getMessage());
3240        }
3241
3242        // Checks that role conforms to role info,
3243
Integer JavaDoc status = checkRoleInt(2,
3244                          currRoleName,
3245                          currRoleValue,
3246                          roleInfo,
3247                          false);
3248        int pbType = status.intValue();
3249        if (pbType != 0) {
3250            // A problem has occured: throws appropriate exception
3251
// here InvalidRoleValueException
3252
throwRoleProblemException(pbType, currRoleName);
3253        }
3254
3255        // Removes role info for that list from list of role infos for
3256
// roles to be defaulted
3257
int roleInfoIdx = roleInfoList.indexOf(roleInfo);
3258        // Note: no need to check if != -1, MUST be there :)
3259
roleInfoList.remove(roleInfoIdx);
3260        }
3261    }
3262
3263    // Initializes roles not initialized by theRoleList
3264
// Can throw InvalidRoleValueException
3265
initialiseMissingRoles(theRelBaseFlg,
3266                   theRelObj,
3267                   theRelObjName,
3268                   theRelId,
3269                   theRelTypeName,
3270                   roleInfoList);
3271
3272    // Creation of relation successfull!!!!
3273

3274    // Updates internal maps
3275
// Relation id to object map
3276
synchronized(myRelId2ObjMap) {
3277        if (theRelBaseFlg) {
3278        // Note: do not clone relation object, created by us :)
3279
myRelId2ObjMap.put(theRelId, theRelObj);
3280        } else {
3281        myRelId2ObjMap.put(theRelId, theRelObjName);
3282        }
3283    }
3284
3285    // Relation id to relation type name map
3286
synchronized(myRelId2RelTypeMap) {
3287        myRelId2RelTypeMap.put(theRelId,
3288                   theRelTypeName);
3289    }
3290
3291    // Relation type to relation id map
3292
synchronized(myRelType2RelIdsMap) {
3293        ArrayList JavaDoc relIdList = (ArrayList JavaDoc)
3294        (myRelType2RelIdsMap.get(theRelTypeName));
3295        boolean firstRelFlg = false;
3296        if (relIdList == null) {
3297        firstRelFlg = true;
3298        relIdList = new ArrayList JavaDoc();
3299        }
3300        relIdList.add(theRelId);
3301        if (firstRelFlg) {
3302        myRelType2RelIdsMap.put(theRelTypeName, relIdList);
3303        }
3304    }
3305
3306    // Referenced MBean to relation id map
3307
// Only role list parameter used, as default initialization of roles
3308
// done automatically in initialiseMissingRoles() sets each
3309
// uninitialized role to an empty value.
3310
for (Iterator JavaDoc roleIter = theRoleList.iterator();
3311         roleIter.hasNext();) {
3312        Role JavaDoc currRole = (Role JavaDoc)(roleIter.next());
3313        // Creates a dummy empty ArrayList of ObjectNames to be the old
3314
// role value :)
3315
ArrayList JavaDoc dummyList = new ArrayList JavaDoc();
3316        // Will not throw a RelationNotFoundException (as the RelId2Obj map
3317
// has been updated above) so catch it :)
3318
try {
3319        updateRoleMap(theRelId, currRole, dummyList);
3320
3321        } catch (RelationNotFoundException JavaDoc exc) {
3322        // OK : The Relation could not be found.
3323
}
3324    }
3325
3326    // Sends a notification for relation creation
3327
// Will not throw RelationNotFoundException so catch it :)
3328
try {
3329        sendRelationCreationNotification(theRelId);
3330
3331    } catch (RelationNotFoundException JavaDoc exc) {
3332        // OK : The Relation could not be found.
3333
}
3334
3335    if (isDebugOn())
3336        debug("addRelationInt: exiting", null);
3337    return;
3338    }
3339
3340    // Checks that given role conforms to given role info.
3341
//
3342
// -param theChkType type of check:
3343
// - 1: read, just check read access
3344
// - 2: write, check value and write access if theWriteChkFlg
3345
// -param theRoleName role name
3346
// -param theRoleValue role value
3347
// -param theRoleInfo corresponding role info
3348
// -param theWriteChkFlg boolean to specify a current write access and
3349
// to check it
3350
//
3351
// -return Integer with value:
3352
// - 0: ok
3353
// - RoleStatus.NO_ROLE_WITH_NAME
3354
// - RoleStatus.ROLE_NOT_READABLE
3355
// - RoleStatus.ROLE_NOT_WRITABLE
3356
// - RoleStatus.LESS_THAN_MIN_ROLE_DEGREE
3357
// - RoleStatus.MORE_THAN_MAX_ROLE_DEGREE
3358
// - RoleStatus.REF_MBEAN_OF_INCORRECT_CLASS
3359
// - RoleStatus.REF_MBEAN_NOT_REGISTERED
3360
//
3361
// -exception IllegalArgumentException if null parameter
3362
private Integer JavaDoc checkRoleInt(int theChkType,
3363                 String JavaDoc theRoleName,
3364                 List JavaDoc theRoleValue,
3365                 RoleInfo JavaDoc theRoleInfo,
3366                 boolean theWriteChkFlg)
3367    throws IllegalArgumentException JavaDoc {
3368
3369    if (theRoleName == null ||
3370        theRoleInfo == null ||
3371        (theChkType == 2 && theRoleValue == null)) {
3372        // Revisit [cebro] Localize message
3373
String JavaDoc excMsg = "Invalid parameter.";
3374        throw new IllegalArgumentException JavaDoc(excMsg);
3375    }
3376
3377    if (isDebugOn()) {
3378        StringBuffer JavaDoc strB = new StringBuffer JavaDoc("theChkType "
3379                         + theChkType
3380                         + ", theRoleName "
3381                         + theRoleName
3382                         + ", theRoleInfo "
3383                         + theRoleInfo.toString()
3384                         + ", theWriteChkFlg "
3385                         + theWriteChkFlg);
3386        if (theRoleValue != null) {
3387        strB.append(", theRoleValue " + theRoleValue.toString());
3388        }
3389        debug("checkRoleInt: entering", strB.toString());
3390    }
3391
3392    // Compares names
3393
String JavaDoc expName = theRoleInfo.getName();
3394    if (!(theRoleName.equals(expName))) {
3395        if (isDebugOn())
3396        debug("checkRoleInt: exiting", null);
3397        return new Integer JavaDoc(RoleStatus.NO_ROLE_WITH_NAME);
3398    }
3399
3400    // Checks read access if required
3401
if (theChkType == 1) {
3402        boolean isReadable = theRoleInfo.isReadable();
3403        if (!isReadable) {
3404        if (isDebugOn())
3405            debug("checkRoleInt: exiting", null);
3406        return new Integer JavaDoc(RoleStatus.ROLE_NOT_READABLE);
3407        } else {
3408        // End of check :)
3409
if (isDebugOn())
3410            debug("checkRoleInt: exiting", null);
3411        return new Integer JavaDoc(0);
3412        }
3413    }
3414
3415    // Checks write access if required
3416
if (theWriteChkFlg) {
3417        boolean isWritable = theRoleInfo.isWritable();
3418        if (!isWritable) {
3419        if (isDebugOn())
3420            debug("checkRoleInt: exiting", null);
3421        return new Integer JavaDoc(RoleStatus.ROLE_NOT_WRITABLE);
3422        }
3423    }
3424
3425    int refNbr = theRoleValue.size();
3426
3427    // Checks minimum cardinality
3428
boolean chkMinFlg = theRoleInfo.checkMinDegree(refNbr);
3429    if (!chkMinFlg) {
3430        if (isDebugOn())
3431        debug("checkRoleInt: exiting", null);
3432        return new Integer JavaDoc(RoleStatus.LESS_THAN_MIN_ROLE_DEGREE);
3433    }
3434
3435    // Checks maximum cardinality
3436
boolean chkMaxFlg = theRoleInfo.checkMaxDegree(refNbr);
3437    if (!chkMaxFlg) {
3438        if (isDebugOn())
3439        debug("checkRoleInt: exiting", null);
3440        return new Integer JavaDoc(RoleStatus.MORE_THAN_MAX_ROLE_DEGREE);
3441    }
3442    
3443    // Verifies that each referenced MBean is registered in the MBean
3444
// Server and that it is an instance of the class specified in the
3445
// role info, or of a subclass of it
3446
// Note that here again this is under the assumption that
3447
// referenced MBeans, relation MBeans and the Relation Service are
3448
// registered in the same MBean Server.
3449
String JavaDoc expClassName = theRoleInfo.getRefMBeanClassName();
3450
3451    for (Iterator JavaDoc refMBeanIter = theRoleValue.iterator();
3452         refMBeanIter.hasNext();) {
3453        ObjectName JavaDoc currObjName = (ObjectName JavaDoc)(refMBeanIter.next());
3454
3455        // Checks it is registered
3456
if (currObjName == null) {
3457        if (isDebugOn())
3458            debug("checkRoleInt: exiting", null);
3459        return new Integer JavaDoc(RoleStatus.REF_MBEAN_NOT_REGISTERED);
3460        }
3461
3462        // Checks if it is of the correct class
3463
// Can throw an InstanceNotFoundException, if MBean not registered
3464
try {
3465        boolean classSts = myMBeanServer.isInstanceOf(currObjName,
3466                                  expClassName);
3467        if (!classSts) {
3468            if (isDebugOn())
3469            debug("checkRoleInt: exiting", null);
3470            return new Integer JavaDoc(RoleStatus.REF_MBEAN_OF_INCORRECT_CLASS);
3471        }
3472
3473        } catch (InstanceNotFoundException JavaDoc exc) {
3474        if (isDebugOn())
3475            debug("checkRoleInt: exiting", null);
3476        return new Integer JavaDoc(RoleStatus.REF_MBEAN_NOT_REGISTERED);
3477        }
3478    }
3479
3480    if (isDebugOn())
3481        debug("checkRoleInt: exiting", null);
3482    return new Integer JavaDoc(0);
3483    }
3484    
3485
3486    // Initialises roles associated to given role infos to default value (empty
3487
// ArrayList of ObjectNames) in given relation.
3488
// It will succeed for every role except if the role info has a minimum
3489
// cardinality greater than 0. In that case, an InvalidRoleValueException
3490
// will be raised.
3491
//
3492
// -param theRelBaseFlg flag true if the relation is a RelationSupport
3493
// object, false if it is an MBean
3494
// -param theRelObj RelationSupport object (if relation is internal)
3495
// -param theRelObjName ObjectName of the MBean to be added as a relation
3496
// (only for the relation MBean)
3497
// -param theRelId relation id
3498
// -param theRelTypeName name of the relation type (has to be created
3499
// in the Relation Service)
3500
// -param theRoleInfoList list of role infos for roles to be defaulted
3501
//
3502
// -exception IllegalArgumentException if null paramater
3503
// -exception RelationServiceNotRegisteredException if the Relation
3504
// Service is not registered in the MBean Server
3505
// -exception InvalidRoleValueException if role must have a non-empty
3506
// value
3507

3508    // Revisit [cebro] Handle CIM qualifiers as REQUIRED to detect roles which
3509
// should have been initialized by the user
3510
private void initialiseMissingRoles(boolean theRelBaseFlg,
3511                    RelationSupport JavaDoc theRelObj,
3512                    ObjectName JavaDoc theRelObjName,
3513                    String JavaDoc theRelId,
3514                    String JavaDoc theRelTypeName,
3515                    List JavaDoc theRoleInfoList)
3516    throws IllegalArgumentException JavaDoc,
3517           RelationServiceNotRegisteredException JavaDoc,
3518           InvalidRoleValueException JavaDoc {
3519
3520    if ((theRelBaseFlg &&
3521         (theRelObj == null ||
3522          theRelObjName != null)) ||
3523        (!theRelBaseFlg &&
3524         (theRelObjName == null ||
3525          theRelObj != null)) ||
3526        theRelId == null ||
3527        theRelTypeName == null ||
3528        theRoleInfoList == null) {
3529        // Revisit [cebro[ Localize message
3530
String JavaDoc excMsg = "Invalid parameter.";
3531        throw new IllegalArgumentException JavaDoc(excMsg);
3532    }
3533
3534    if (isDebugOn()) {
3535        StringBuffer JavaDoc strB =
3536        new StringBuffer JavaDoc("theRelBaseFlg " + theRelBaseFlg
3537                 + ", theRelId " + theRelId
3538                 + ", theRelTypeName " + theRelTypeName
3539                 + ", theRoleInfoList " + theRoleInfoList);
3540        if (theRelObjName != null) {
3541        strB.append(theRelObjName.toString());
3542        }
3543        debug("initialiseMissingRoles: entering", strB.toString());
3544    }
3545
3546    // Can throw RelationServiceNotRegisteredException
3547
isActive();
3548
3549    // For each role info (corresponding to a role not initialized by the
3550
// role list provided by the user), try to set in the relation a role
3551
// with an empty list of ObjectNames.
3552
// A check is performed to verify that the role can be set to an
3553
// empty value, according to its minimum cardinality
3554
for (Iterator JavaDoc roleInfoIter = theRoleInfoList.iterator();
3555         roleInfoIter.hasNext();) {
3556
3557        RoleInfo JavaDoc currRoleInfo = (RoleInfo JavaDoc)(roleInfoIter.next());
3558        String JavaDoc roleName = currRoleInfo.getName();
3559
3560        // Creates an empty value
3561
ArrayList JavaDoc emptyValue = new ArrayList JavaDoc();
3562        // Creates a role
3563
Role JavaDoc role = new Role JavaDoc(roleName, emptyValue);
3564
3565        if (theRelBaseFlg) {
3566
3567        // Internal relation
3568
// Can throw InvalidRoleValueException
3569
//
3570
// Will not throw RoleNotFoundException (role to be
3571
// initialized), or RelationNotFoundException, or
3572
// RelationTypeNotFoundException
3573
try {
3574            theRelObj.setRoleInt(role, true, this, false);
3575
3576        } catch (RoleNotFoundException JavaDoc exc1) {
3577            throw new RuntimeException JavaDoc(exc1.getMessage());
3578        } catch (RelationNotFoundException JavaDoc exc2) {
3579            throw new RuntimeException JavaDoc(exc2.getMessage());
3580        } catch (RelationTypeNotFoundException JavaDoc exc3) {
3581            throw new RuntimeException JavaDoc(exc3.getMessage());
3582        }
3583
3584        } else {
3585
3586        // Relation is an MBean
3587
// Use standard setRole()
3588
Object JavaDoc[] params = new Object JavaDoc[1];
3589        params[0] = role;
3590        String JavaDoc[] signature = new String JavaDoc[1];
3591        signature[0] = "javax.management.relation.Role";
3592        // Can throw MBeanException wrapping
3593
// InvalidRoleValueException. Returns the target exception to
3594
// be homogeneous.
3595
//
3596
// Will not throw MBeanException (wrapping
3597
// RoleNotFoundException or MBeanException) or
3598
// InstanceNotFoundException, or ReflectionException
3599
//
3600
// Again here the assumption is that the Relation Service and
3601
// the relation MBeans are registered in the same MBean Server.
3602
try {
3603            myMBeanServer.setAttribute(theRelObjName,
3604                                               new Attribute JavaDoc("Role", role));
3605
3606        } catch (InstanceNotFoundException JavaDoc exc1) {
3607            throw new RuntimeException JavaDoc(exc1.getMessage());
3608        } catch (ReflectionException JavaDoc exc3) {
3609            throw new RuntimeException JavaDoc(exc3.getMessage());
3610        } catch (MBeanException JavaDoc exc2) {
3611            Exception JavaDoc wrappedExc = exc2.getTargetException();
3612            if (wrappedExc instanceof InvalidRoleValueException JavaDoc) {
3613            throw ((InvalidRoleValueException JavaDoc)wrappedExc);
3614            } else {
3615            throw new RuntimeException JavaDoc(wrappedExc.getMessage());
3616            }
3617        } catch (AttributeNotFoundException JavaDoc exc4) {
3618                  throw new RuntimeException JavaDoc(exc4.getMessage());
3619                } catch (InvalidAttributeValueException JavaDoc exc5) {
3620                  throw new RuntimeException JavaDoc(exc5.getMessage());
3621                }
3622        }
3623    }
3624
3625    if (isDebugOn())
3626        debug("initializeMissingRoles: exiting", null);
3627    return;
3628    }
3629
3630    // Throws an exception corresponding to a given problem type
3631
//
3632
// -param thePbType possible problem, defined in RoleUnresolved
3633
// -param theRoleName role name
3634
//
3635
// -exception IllegalArgumentException if null parameter
3636
// -exception RoleNotFoundException for problems:
3637
// - NO_ROLE_WITH_NAME
3638
// - ROLE_NOT_READABLE
3639
// - ROLE_NOT_WRITABLE
3640
// -exception InvalidRoleValueException for problems:
3641
// - LESS_THAN_MIN_ROLE_DEGREE
3642
// - MORE_THAN_MAX_ROLE_DEGREE
3643
// - REF_MBEAN_OF_INCORRECT_CLASS
3644
// - REF_MBEAN_NOT_REGISTERED
3645
static void throwRoleProblemException(int thePbType,
3646                      String JavaDoc theRoleName)
3647    throws IllegalArgumentException JavaDoc,
3648           RoleNotFoundException JavaDoc,
3649           InvalidRoleValueException JavaDoc {
3650
3651    if (theRoleName == null) {
3652        // Revisit [cebro] Localize message
3653
String JavaDoc excMsg = "Invalid parameter.";
3654        throw new IllegalArgumentException JavaDoc(excMsg);
3655    }
3656
3657    // Exception type: 1 = RoleNotFoundException
3658
// 2 = InvalidRoleValueException
3659
int excType = 0;
3660
3661    String JavaDoc excMsgPart = null;
3662
3663    // Revisit [cebro] Localize messages
3664
switch (thePbType) {
3665    case RoleStatus.NO_ROLE_WITH_NAME:
3666        excMsgPart = " does not exist in relation.";
3667        excType = 1;
3668        break;
3669    case RoleStatus.ROLE_NOT_READABLE:
3670        excMsgPart = " is not readable.";
3671        excType = 1;
3672        break;
3673    case RoleStatus.ROLE_NOT_WRITABLE:
3674        excMsgPart = " is not writable.";
3675        excType = 1;
3676        break;
3677    case RoleStatus.LESS_THAN_MIN_ROLE_DEGREE:
3678        excMsgPart = " has a number of MBean references less than the expected minimum degree.";
3679        excType = 2;
3680        break;
3681    case RoleStatus.MORE_THAN_MAX_ROLE_DEGREE:
3682        excMsgPart = " has a number of MBean references greater than the expected maximum degree.";
3683        excType = 2;
3684        break;
3685    case RoleStatus.REF_MBEAN_OF_INCORRECT_CLASS:
3686        excMsgPart = " has an MBean reference to an MBean not of the expected class of references for that role.";
3687        excType = 2;
3688        break;
3689    case RoleStatus.REF_MBEAN_NOT_REGISTERED:
3690        excMsgPart = " has a reference to null or to an MBean not registered.";
3691        excType = 2;
3692        break;
3693    }
3694    // No default as we must have been in one of those cases
3695

3696    StringBuffer JavaDoc excMsgStrB = new StringBuffer JavaDoc(theRoleName);
3697    excMsgStrB.append(excMsgPart);
3698    String JavaDoc excMsg = excMsgStrB.toString();
3699    if (excType == 1) {
3700        throw new RoleNotFoundException JavaDoc(excMsg);
3701
3702    } else if (excType == 2) {
3703        throw new InvalidRoleValueException JavaDoc(excMsg);
3704    }
3705    }
3706
3707    // Sends a notification of given type, with given parameters
3708
//
3709
// -param theIntNtfType integer to represent notification type:
3710
// - 1 : create
3711
// - 2 : update
3712
// - 3 : delete
3713
// -param theMsg human-readable message
3714
// -param theRelId relation id of the created/updated/deleted relation
3715
// -param theUnregMBeanList list of ObjectNames of referenced MBeans
3716
// expected to be unregistered due to relation removal (only for removal,
3717
// due to CIM qualifiers, can be null)
3718
// -param theRoleName role name
3719
// -param theRoleNewValue role new value (ArrayList of ObjectNames)
3720
// -param theOldRoleValue old role value (ArrayList of ObjectNames)
3721
//
3722
// -exception IllegalArgument if null parameter
3723
// -exception RelationNotFoundException if no relation for given id
3724
private void sendNotificationInt(int theIntNtfType,
3725                     String JavaDoc theMsg,
3726                     String JavaDoc theRelId,
3727                     List JavaDoc theUnregMBeanList,
3728                     String JavaDoc theRoleName,
3729                     List JavaDoc theRoleNewValue,
3730                     List JavaDoc theOldRoleValue)
3731    throws IllegalArgumentException JavaDoc,
3732           RelationNotFoundException JavaDoc {
3733
3734    if (theMsg == null ||
3735        theRelId == null ||
3736        (theIntNtfType != 3 && theUnregMBeanList != null) ||
3737        (theIntNtfType == 2 &&
3738         (theRoleName == null ||
3739          theRoleNewValue == null ||
3740          theOldRoleValue == null))) {
3741        // Revisit [cebro] Localize message
3742
String JavaDoc excMsg = "Invalid parameter.";
3743        throw new IllegalArgumentException JavaDoc(excMsg);
3744    }
3745
3746    if (isDebugOn()) {
3747        StringBuffer JavaDoc strB =
3748        new StringBuffer JavaDoc("theIntNtfType " + theIntNtfType
3749                 + ", theMsg " + theMsg
3750                 + ", theRelId " + theRelId);
3751        if (theUnregMBeanList != null) {
3752        strB.append(", theUnregMBeanList " +
3753                theUnregMBeanList.toString());
3754        }
3755        if (theRoleName != null) {
3756        strB.append(", theRoleName " + theRoleName);
3757        }
3758        if (theRoleNewValue != null) {
3759        strB.append(", theRoleNewValue " + theRoleNewValue.toString());
3760        }
3761        if (theOldRoleValue != null) {
3762        strB.append(", theOldRoleValue " + theOldRoleValue.toString());
3763        }
3764        debug("sendNotificationInt: entering", strB.toString());
3765    }
3766
3767    // Relation type name
3768
// Note: do not use getRelationTypeName() as if it is a relation MBean
3769
// it is already unregistered.
3770
String JavaDoc relTypeName = null;
3771    synchronized(myRelId2RelTypeMap) {
3772        relTypeName = (String JavaDoc)(myRelId2RelTypeMap.get(theRelId));
3773    }
3774
3775    // ObjectName (for a relation MBean)
3776
// Can also throw a RelationNotFoundException, but detected above
3777
ObjectName JavaDoc relObjName = isRelationMBean(theRelId);
3778
3779    String JavaDoc ntfType = null;
3780    if (relObjName != null) {
3781        switch (theIntNtfType) {
3782        case 1:
3783        ntfType = RelationNotification.RELATION_MBEAN_CREATION;
3784        break;
3785        case 2:
3786        ntfType = RelationNotification.RELATION_MBEAN_UPDATE;
3787        break;
3788        case 3:
3789        ntfType = RelationNotification.RELATION_MBEAN_REMOVAL;
3790        break;
3791        }
3792    } else {
3793        switch (theIntNtfType) {
3794        case 1:
3795        ntfType = RelationNotification.RELATION_BASIC_CREATION;
3796        break;
3797        case 2:
3798        ntfType = RelationNotification.RELATION_BASIC_UPDATE;
3799        break;
3800        case 3:
3801        ntfType = RelationNotification.RELATION_BASIC_REMOVAL;
3802        break;
3803        }
3804    }
3805
3806    // Sequence number
3807
Long JavaDoc seqNbr = getNotificationSequenceNumber();
3808
3809    // Timestamp
3810
Date JavaDoc currDate = new Date JavaDoc();
3811    long timeStamp = currDate.getTime();
3812
3813    RelationNotification JavaDoc ntf = null;
3814
3815    if (ntfType.equals(RelationNotification.RELATION_BASIC_CREATION) ||
3816        ntfType.equals(RelationNotification.RELATION_MBEAN_CREATION) ||
3817        ntfType.equals(RelationNotification.RELATION_BASIC_REMOVAL) ||
3818        ntfType.equals(RelationNotification.RELATION_MBEAN_REMOVAL))
3819
3820        // Creation or removal
3821
ntf = new RelationNotification JavaDoc(ntfType,
3822                       this,
3823                       seqNbr.longValue(),
3824                       timeStamp,
3825                       theMsg,
3826                       theRelId,
3827                       relTypeName,
3828                       relObjName,
3829                       theUnregMBeanList);
3830
3831    else if (ntfType.equals(RelationNotification.RELATION_BASIC_UPDATE)
3832         ||
3833         ntfType.equals(RelationNotification.RELATION_MBEAN_UPDATE))
3834        {
3835        // Update
3836
ntf = new RelationNotification JavaDoc(ntfType,
3837                           this,
3838                           seqNbr.longValue(),
3839                           timeStamp,
3840                           theMsg,
3841                           theRelId,
3842                           relTypeName,
3843                           relObjName,
3844                           theRoleName,
3845                           theRoleNewValue,
3846                           theOldRoleValue);
3847        }
3848
3849    sendNotification(ntf);
3850
3851    if (isDebugOn())
3852        debug("sendNotificationInt: exiting", null);
3853    return;
3854    }
3855
3856    // Checks, for the unregistration of an MBean referenced in the roles given
3857
// in parameter, if the relation has to be removed or not, regarding
3858
// expected minimum role cardinality and current number of
3859
// references in each role after removal of the current one.
3860
// If the relation is kept, calls handleMBeanUnregistration() callback of
3861
// the relation to update it.
3862
//
3863
// -param theRelId relation id
3864
// -param theObjName ObjectName of the unregistered MBean
3865
// -param theRoleNameList list of names of roles where the unregistered
3866
// MBean is referenced.
3867
//
3868
// -exception IllegalArgumentException if null parameter
3869
// -exception RelationServiceNotRegisteredException if the Relation
3870
// Service is not registered in the MBean Server
3871
// -exception RelationNotFoundException if unknown relation id
3872
// -exception RoleNotFoundException if one role given as parameter does
3873
// not exist in the relation
3874
private void handleReferenceUnregistration(String JavaDoc theRelId,
3875                           ObjectName JavaDoc theObjName,
3876                           List JavaDoc theRoleNameList)
3877    throws IllegalArgumentException JavaDoc,
3878           RelationServiceNotRegisteredException JavaDoc,
3879               RelationNotFoundException JavaDoc,
3880           RoleNotFoundException JavaDoc {
3881
3882    if (theRelId == null ||
3883        theRoleNameList == null ||
3884        theObjName == null) {
3885        // Revisit [cebro[ Localize message
3886
String JavaDoc excMsg = "Invalid parameter.";
3887        throw new IllegalArgumentException JavaDoc(excMsg);
3888    }
3889
3890    if (isDebugOn()) {
3891        String JavaDoc str =
3892        new String JavaDoc("theRelId " + theRelId
3893               + ", theRoleNameList " + theRoleNameList.toString()
3894               + "theObjName " + theObjName.toString());
3895        debug("handleReferenceUnregistration: entering", str);
3896    }
3897
3898    // Can throw RelationServiceNotRegisteredException
3899
isActive();
3900
3901    // Retrieves the relation type name of the relation
3902
// Can throw RelationNotFoundException
3903
String JavaDoc currRelTypeName = getRelationTypeName(theRelId);
3904
3905    // Retrieves the relation
3906
// Can throw RelationNotFoundException, but already detected above
3907
Object JavaDoc relObj = getRelation(theRelId);
3908
3909    // Flag to specify if the relation has to be deleted
3910
boolean deleteRelFlg = false;
3911
3912    for (Iterator JavaDoc roleNameIter = theRoleNameList.iterator();
3913         roleNameIter.hasNext();) {
3914
3915        if (deleteRelFlg) {
3916        break;
3917        }
3918
3919        String JavaDoc currRoleName = (String JavaDoc)(roleNameIter.next());
3920        // Retrieves number of MBeans currently referenced in role
3921
// BEWARE! Do not use getRole() as role may be not readable
3922
//
3923
// Can throw RelationNotFoundException (but already checked),
3924
// RoleNotFoundException
3925
int currRoleRefNbr =
3926        (getRoleCardinality(theRelId, currRoleName)).intValue();
3927
3928        // Retrieves new number of element in role
3929
int currRoleNewRefNbr = currRoleRefNbr - 1;
3930
3931        // Retrieves role info for that role
3932
//
3933
// Shall not throw RelationTypeNotFoundException or
3934
// RoleInfoNotFoundException
3935
RoleInfo JavaDoc currRoleInfo = null;
3936        try {
3937        currRoleInfo = getRoleInfo(currRelTypeName,
3938                       currRoleName);
3939        } catch (RelationTypeNotFoundException JavaDoc exc1) {
3940        throw new RuntimeException JavaDoc(exc1.getMessage());
3941        } catch (RoleInfoNotFoundException JavaDoc exc2) {
3942        throw new RuntimeException JavaDoc(exc2.getMessage());
3943        }
3944
3945        // Checks with expected minimum number of elements
3946
boolean chkMinFlg = currRoleInfo.checkMinDegree(currRoleNewRefNbr);
3947
3948        if (!chkMinFlg) {
3949        // The relation has to be deleted
3950
deleteRelFlg = true;
3951        }
3952    }
3953
3954    if (deleteRelFlg) {
3955        // Removes the relation
3956
removeRelation(theRelId);
3957
3958    } else {
3959
3960        // Updates each role in the relation using
3961
// handleMBeanUnregistration() callback
3962
//
3963
// BEWARE: this theRoleNameList list MUST BE A COPY of a role name
3964
// list for a referenced MBean in a relation, NOT a
3965
// reference to an original one part of the
3966
// myRefedMBeanObjName2RelIdsMap!!!! Because each role
3967
// which name is in that list will be updated (potentially
3968
// using setRole(). So the Relation Service will update the
3969
// myRefedMBeanObjName2RelIdsMap to refelect the new role
3970
// value!
3971
for (Iterator JavaDoc roleNameIter = theRoleNameList.iterator();
3972         roleNameIter.hasNext();) {
3973
3974        String JavaDoc currRoleName = (String JavaDoc)(roleNameIter.next());
3975
3976        if (relObj instanceof RelationSupport JavaDoc) {
3977            // Internal relation
3978
// Can throw RoleNotFoundException (but already checked)
3979
//
3980
// Shall not throw
3981
// RelationTypeNotFoundException,
3982
// InvalidRoleValueException (value was correct, removing
3983
// one reference shall not invalidate it, else detected
3984
// above)
3985
try {
3986            ((RelationSupport JavaDoc)relObj).handleMBeanUnregistrationInt(
3987                          theObjName,
3988                          currRoleName,
3989                          true,
3990                          this);
3991            } catch (RelationTypeNotFoundException JavaDoc exc3) {
3992            throw new RuntimeException JavaDoc(exc3.getMessage());
3993            } catch (InvalidRoleValueException JavaDoc exc4) {
3994            throw new RuntimeException JavaDoc(exc4.getMessage());
3995            }
3996
3997        } else {
3998            // Relation MBean
3999
Object JavaDoc[] params = new Object JavaDoc[2];
4000            params[0] = theObjName;
4001            params[1] = currRoleName;
4002            String JavaDoc[] signature = new String JavaDoc[2];
4003            signature[0] = "javax.management.ObjectName";
4004            signature[1] = "java.lang.String";
4005            // Shall not throw InstanceNotFoundException, or
4006
// MBeanException (wrapping RoleNotFoundException or
4007
// MBeanException or InvalidRoleValueException) or
4008
// ReflectionException
4009
try {
4010            myMBeanServer.invoke(((ObjectName JavaDoc)relObj),
4011                         "handleMBeanUnregistration",
4012                         params,
4013                         signature);
4014            } catch (InstanceNotFoundException JavaDoc exc1) {
4015            throw new RuntimeException JavaDoc(exc1.getMessage());
4016            } catch (ReflectionException JavaDoc exc3) {
4017            throw new RuntimeException JavaDoc(exc3.getMessage());
4018            } catch (MBeanException JavaDoc exc2) {
4019            Exception JavaDoc wrappedExc = exc2.getTargetException();
4020            throw new RuntimeException JavaDoc(wrappedExc.getMessage());
4021            }
4022
4023        }
4024        }
4025    }
4026
4027    if (isDebugOn())
4028        debug("handleReferenceUnregistration: exiting", null);
4029    return;
4030    }
4031
4032    // stuff for Tracing
4033

4034    private static String JavaDoc localClassName = "RelationService";
4035
4036    // trace level
4037
private boolean isTraceOn() {
4038        return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_RELATION);
4039    }
4040
4041// private void trace(String className, String methodName, String info) {
4042
// Trace.send(Trace.LEVEL_TRACE, Trace.INFO_RELATION, className, methodName, info);
4043
// }
4044

4045    private void trace(String JavaDoc methodName, String JavaDoc info) {
4046        Trace.send(Trace.LEVEL_TRACE, Trace.INFO_RELATION, localClassName, methodName, info);
4047    Trace.send(Trace.LEVEL_TRACE, Trace.INFO_RELATION, "", "", "\n");
4048    }
4049
4050// private void trace(String className, String methodName, Exception e) {
4051
// Trace.send(Trace.LEVEL_TRACE, Trace.INFO_RELATION, className, methodName, e);
4052
// }
4053

4054// private void trace(String methodName, Exception e) {
4055
// Trace.send(Trace.LEVEL_TRACE, Trace.INFO_RELATION, localClassName, methodName, e);
4056
// }
4057

4058    // debug level
4059
private boolean isDebugOn() {
4060        return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_RELATION);
4061    }
4062
4063// private void debug(String className, String methodName, String info) {
4064
// Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_RELATION, className, methodName, info);
4065
// }
4066

4067    private void debug(String JavaDoc methodName, String JavaDoc info) {
4068        Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_RELATION, localClassName, methodName, info);
4069    Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_RELATION, "", "", "\n");
4070    }
4071
4072// private void debug(String className, String methodName, Exception e) {
4073
// Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_RELATION, className, methodName, e);
4074
// }
4075

4076// private void debug(String methodName, Exception e) {
4077
// Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_RELATION, localClassName, methodName, e);
4078
// }
4079
}
4080
Popular Tags