KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > fractal > gui > model > BasicComponent


1 /***
2  * FractalGUI: a graphical tool to edit Fractal component configurations.
3  * Copyright (C) 2003 France Telecom R&D
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Contact: fractal@objectweb.org
20  *
21  * Authors: Eric Bruneton, Patrice Fauvel
22  */

23
24 package org.objectweb.fractal.gui.model;
25
26 import java.util.ArrayList JavaDoc;
27 import java.util.Collections JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.Map JavaDoc;
31
32 // TODO notifier aussi tous les slave components
33

34 /**
35  * Basic implementation of the {@link Component} interface.
36  */

37
38 public class BasicComponent extends AbstractComponent {
39
40   /**
41    * The configuration to which this component belongs.
42    */

43
44   private BasicConfiguration owner;
45
46   /**
47    * Status of this component.
48    */

49
50   private long status;
51
52   /**
53    * Name of this component.
54    */

55
56   private String JavaDoc name;
57
58   /**
59    * Name of the type of this component.
60    */

61
62   private String JavaDoc type;
63
64   /**
65    * Name of the class that implements this component.
66    */

67
68   private String JavaDoc implementation;
69
70   /**
71    * The external client interfaces of this component. This list is a list of
72    * {@link Interface} objects.
73    */

74
75   private List JavaDoc clientInterfaces;
76
77   /**
78    * The external server interfaces of this component. This list is a list of
79    * {@link Interface} objects.
80    */

81
82   private List JavaDoc serverInterfaces;
83
84   /**
85    * Name of the attribute controller interface of this component.
86    */

87
88   private String JavaDoc attributeController;
89
90   /**
91    * Values of the attributes of this component.
92    */

93
94   private Map JavaDoc attributes;
95
96   /**
97    * Template controller descriptor of this component.
98    */

99
100   private String JavaDoc tmplDesc;
101
102   /**
103    * Component controller descriptor of this component.
104    */

105
106   private String JavaDoc compDesc;
107
108   /**
109    * List of the slave components of this master component. This list is a list
110    * of {@link Component} objects. It is empty if this component is not a master
111    * component.
112    */

113
114   private List JavaDoc slaveComponents;
115
116   /**
117    * List of the sub components of this component. This list is a list of {@link
118    * Component} objects. It is empty if this component is not a composite
119    * component.
120    */

121
122   private List JavaDoc subComponents;
123
124   /**
125    * If addXXXInterface and removeXXXInterface methods must notify the listeners
126    * or not. See {@link #setBinding setBinding}.
127    */

128
129   private static boolean notificationEnabled;
130
131   /**
132    * Constructs a new component.
133    *
134    * @param owner the configuration to which the component will belong.
135    */

136
137   BasicComponent (final BasicConfiguration owner) {
138     this.owner = owner;
139     status = NAME_MISSING | /*TYPE_MISSING |*/ IMPLEMENTATION_MISSING;
140     name = "";
141     type = "";
142     implementation = "";
143     clientInterfaces = new ArrayList JavaDoc();
144     serverInterfaces = new ArrayList JavaDoc();
145     attributeController = "";
146     attributes = new HashMap JavaDoc();
147     tmplDesc = "";
148     compDesc = "";
149     slaveComponents = new ArrayList JavaDoc();
150     subComponents = new ArrayList JavaDoc();
151     notificationEnabled = true;
152   }
153
154   /**
155    * Returns the configuration to which this component belongs.
156    *
157    * @return the configuration to which this component belongs.
158    */

159
160   public BasicConfiguration getOwner () {
161     return owner;
162   }
163
164   public Configuration getConfiguration () {
165     return owner;
166   }
167
168   public long getStatus () {
169     return status;
170   }
171
172   public void setStatus (final long status) {
173     this.status = status;
174   }
175
176   // -------------------------------------------------------------------------
177
// Name, Type, Implementation
178
// -------------------------------------------------------------------------
179

180   public String JavaDoc getName () {
181     return name;
182   }
183
184   public void setName (final String JavaDoc name) {
185     if (name == null) {
186       throw new IllegalArgumentException JavaDoc();
187     }
188     String JavaDoc oldName = this.name;
189     if (!name.equals(oldName)) {
190       List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
191       for (int i = 0; i < vetoableListeners.size(); ++i) {
192         VetoableConfigurationListener l =
193           (VetoableConfigurationListener)vetoableListeners.get(i);
194         l.canChangeName(this);
195       }
196       this.name = name;
197       List JavaDoc listeners = getOwner().getListeners();
198       for (int i = 0; i < listeners.size(); ++i) {
199         ConfigurationListener l = (ConfigurationListener)listeners.get(i);
200         l.nameChanged(this, oldName);
201       }
202     }
203   }
204
205   public String JavaDoc getType () {
206     return type;
207   }
208
209   public void setType (final String JavaDoc type) {
210     if (type == null) {
211       throw new IllegalArgumentException JavaDoc();
212     }
213     String JavaDoc oldType = this.type;
214     if (!type.equals(oldType)) {
215       List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
216       for (int i = 0; i < vetoableListeners.size(); ++i) {
217         VetoableConfigurationListener l =
218           (VetoableConfigurationListener)vetoableListeners.get(i);
219         l.canChangeType(this);
220       }
221       this.type = type;
222       List JavaDoc listeners = getOwner().getListeners();
223       for (int i = 0; i < listeners.size(); ++i) {
224         ConfigurationListener l = (ConfigurationListener)listeners.get(i);
225         l.typeChanged(this, oldType);
226       }
227     }
228   }
229
230   public String JavaDoc getImplementation () {
231     return implementation;
232   }
233
234   public void setImplementation (final String JavaDoc implementation) {
235     if (implementation == null) {
236       throw new IllegalArgumentException JavaDoc();
237     }
238     String JavaDoc oldImplementation = this.implementation;
239     if (!implementation.equals(oldImplementation)) {
240       List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
241       for (int i = 0; i < vetoableListeners.size(); ++i) {
242         VetoableConfigurationListener l =
243           (VetoableConfigurationListener)vetoableListeners.get(i);
244         l.canChangeImplementation(this);
245       }
246       this.implementation = implementation;
247       List JavaDoc listeners = getOwner().getListeners();
248       for (int i = 0; i < listeners.size(); ++i) {
249         ConfigurationListener l = (ConfigurationListener)listeners.get(i);
250         l.implementationChanged(this, oldImplementation);
251       }
252     }
253   }
254
255   // -------------------------------------------------------------------------
256
// Client and Server interfaces
257
// -------------------------------------------------------------------------
258

259   public List JavaDoc getClientInterfaces () {
260     return Collections.unmodifiableList(clientInterfaces);
261   }
262
263   public Interface getClientInterface (final String JavaDoc name) {
264     if (name == null) {
265       throw new IllegalArgumentException JavaDoc();
266     }
267     for (int i = 0; i < clientInterfaces.size(); ++i) {
268       Interface itf = (Interface)clientInterfaces.get(i);
269       if (itf.getName().equals(name)) {
270         return itf;
271       }
272     }
273     return null;
274   }
275
276   public void addClientInterface (final ClientInterface itf) {
277     if (itf == null) {
278       throw new IllegalArgumentException JavaDoc();
279     }
280     if (itf.getOwner() != this || itf.isInternal()) {
281       throw new RuntimeException JavaDoc("Internal error");
282     }
283     if (!clientInterfaces.contains(itf)) {
284       List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
285       for (int i = 0; i < vetoableListeners.size(); ++i) {
286         VetoableConfigurationListener l =
287           (VetoableConfigurationListener)vetoableListeners.get(i);
288         l.canAddClientInterface(this, itf);
289       }
290       int index = clientInterfaces.size();
291       // add itf
292
clientInterfaces.add(itf);
293       // restore link in master collection interface, if any
294
if (itf.getMasterCollectionInterface() != null) {
295         BasicInterface bitf =
296           (BasicInterface)itf.getMasterCollectionInterface();
297         bitf.addSlaveCollectionInterface(itf);
298       }
299       // restore bindings, if any
300
restoreBinding(itf, true);
301       // notify listeners
302
if (notificationEnabled) {
303         List JavaDoc listeners = getOwner().getListeners();
304         for (int i = 0; i < listeners.size(); ++i) {
305           ConfigurationListener l = (ConfigurationListener)listeners.get(i);
306           l.clientInterfaceAdded(this, itf, index);
307         }
308       }
309     }
310   }
311
312   public void removeClientInterface (final ClientInterface itf) {
313     if (itf == null) {
314       throw new IllegalArgumentException JavaDoc();
315     }
316     if (itf.getOwner() != this || itf.isInternal()) {
317       throw new RuntimeException JavaDoc("Internal error");
318     }
319     if (clientInterfaces.contains(itf)) {
320       List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
321       for (int i = 0; i < vetoableListeners.size(); ++i) {
322         VetoableConfigurationListener l =
323           (VetoableConfigurationListener)vetoableListeners.get(i);
324         l.canRemoveClientInterface(this, itf);
325       }
326       if (itf.getSlaveCollectionInterfaces().size() > 0) {
327         throw new IllegalOperationException(
328           "Cannot remove this root collection interface. " +
329           "You must first remove all the interfaces of the collection");
330       }
331       // remove itf
332
int index = clientInterfaces.indexOf(itf);
333       clientInterfaces.remove(itf);
334       // remove link in master collection interface, if any
335
if (itf.getMasterCollectionInterface() != null) {
336         BasicInterface bitf =
337           (BasicInterface)itf.getMasterCollectionInterface();
338         bitf.removeSlaveCollectionInterface(itf);
339       }
340       // remove bindings, if any
341
removeBinding(itf, true);
342       // notify listeners
343
if (notificationEnabled) {
344         List JavaDoc listeners = getOwner().getListeners();
345         for (int i = 0; i < listeners.size(); ++i) {
346           ConfigurationListener l = (ConfigurationListener)listeners.get(i);
347           l.clientInterfaceRemoved(this, itf, index);
348         }
349       }
350     }
351   }
352
353   public List JavaDoc getServerInterfaces () {
354    return Collections.unmodifiableList(serverInterfaces);
355   }
356
357   public Interface getServerInterface (final String JavaDoc name) {
358     if (name == null) {
359       throw new IllegalArgumentException JavaDoc();
360     }
361     for (int i = 0; i < serverInterfaces.size(); ++i) {
362       Interface itf = (Interface)serverInterfaces.get(i);
363       if (itf.getName().equals(name)) {
364         return itf;
365       }
366     }
367     return null;
368   }
369
370   public void addServerInterface (final ServerInterface itf) {
371     if (itf == null) {
372       throw new IllegalArgumentException JavaDoc();
373     }
374     if (itf.getOwner() != this || itf.isInternal()) {
375       throw new RuntimeException JavaDoc("Internal error");
376     }
377     if (!serverInterfaces.contains(itf)) {
378       List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
379       for (int i = 0; i < vetoableListeners.size(); ++i) {
380         VetoableConfigurationListener l =
381           (VetoableConfigurationListener)vetoableListeners.get(i);
382         l.canAddServerInterface(this, itf);
383       }
384       int index = serverInterfaces.size();
385       // add itf
386
serverInterfaces.add(itf);
387       // restore link in master collection interface, if any
388
if (itf.getMasterCollectionInterface() != null) {
389         BasicInterface bitf =
390           (BasicInterface)itf.getMasterCollectionInterface();
391         bitf.addSlaveCollectionInterface(itf);
392       }
393       // restore bindings, if any
394
restoreBinding(itf, true);
395       // notify listeners
396
if (notificationEnabled) {
397         List JavaDoc listeners = getOwner().getListeners();
398         for (int i = 0; i < listeners.size(); ++i) {
399           ConfigurationListener l = (ConfigurationListener)listeners.get(i);
400           l.serverInterfaceAdded(this, itf, index);
401         }
402       }
403     }
404   }
405
406   public void removeServerInterface (final ServerInterface itf) {
407     if (itf == null) {
408       throw new IllegalArgumentException JavaDoc();
409     }
410     if (itf.getOwner() != this || itf.isInternal()) {
411       throw new RuntimeException JavaDoc("Internal error");
412     }
413     if (serverInterfaces.contains(itf)) {
414       List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
415       for (int i = 0; i < vetoableListeners.size(); ++i) {
416         VetoableConfigurationListener l =
417           (VetoableConfigurationListener)vetoableListeners.get(i);
418         l.canRemoveServerInterface(this, itf);
419       }
420       if (itf.getSlaveCollectionInterfaces().size() > 0) {
421         throw new IllegalOperationException(
422           "Cannot remove this root collection interface. " +
423           "You must first remove all the interfaces of the collection");
424       }
425       // remove itf
426
int index = serverInterfaces.indexOf(itf);
427       serverInterfaces.remove(itf);
428       // remove link in master collection interface, if any
429
if (itf.getMasterCollectionInterface() != null) {
430         BasicInterface bitf =
431           (BasicInterface)itf.getMasterCollectionInterface();
432         bitf.removeSlaveCollectionInterface(itf);
433       }
434       // remove bindings, if any
435
removeBinding(itf, true);
436       // notify listeners
437
if (notificationEnabled) {
438         List JavaDoc listeners = getOwner().getListeners();
439         for (int i = 0; i < listeners.size(); ++i) {
440           ConfigurationListener l = (ConfigurationListener)listeners.get(i);
441           l.serverInterfaceRemoved(this, itf, index);
442         }
443       }
444     }
445   }
446
447   // -------------------------------------------------------------------------
448
// Bindings
449
// -------------------------------------------------------------------------
450

451   public void bind (ClientInterface citf, final String JavaDoc suffix, final ServerInterface sitf) {
452     if (citf == null || sitf == null) {
453       throw new IllegalArgumentException JavaDoc();
454     }
455     if (citf.getBinding() != null) {
456       throw new IllegalOperationException("Interface already bound");
457     }
458     List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
459     for (int i = 0; i < vetoableListeners.size(); ++i) {
460       VetoableConfigurationListener l =
461         (VetoableConfigurationListener)vetoableListeners.get(i);
462       l.canBindInterface(citf);
463     }
464     // TODO check citf belongs to this
465
checkBinding(citf, sitf);
466
467     // if citf is a master collection itf, create a new client interface
468
if (citf.isCollection() && citf.getMasterCollectionInterface() == null) {
469       if (citf.isInternal()) {
470         ServerInterface s = (ServerInterface)citf.getComplementaryInterface();
471         s = new BasicServerInterface(s, suffix);
472         serverInterfaces.add(s);
473         citf = (ClientInterface)s.getComplementaryInterface();
474       } else {
475         citf = new BasicClientInterface(citf, suffix);
476         clientInterfaces.add(citf);
477       }
478     }
479
480     Binding b = new BasicBinding(citf, sitf);
481     setBinding(citf, b);
482     addBinding(sitf, b);
483     // notify listeners
484
List JavaDoc listeners = getOwner().getListeners();
485     for (int i = 0; i < listeners.size(); ++i) {
486       ConfigurationListener l = (ConfigurationListener)listeners.get(i);
487       l.interfaceBound(citf, sitf);
488     }
489   }
490
491   public void rebind (final ClientInterface citf, final ServerInterface sitf) {
492     if (citf == null || sitf == null) {
493       throw new IllegalArgumentException JavaDoc();
494     }
495     if (citf.getBinding() == null) {
496       throw new IllegalOperationException("Interface not bound");
497     }
498     List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
499     for (int i = 0; i < vetoableListeners.size(); ++i) {
500       VetoableConfigurationListener l =
501         (VetoableConfigurationListener)vetoableListeners.get(i);
502       l.canRebindInterface(citf);
503     }
504     // TODO check citf belongs to this
505
checkBinding(citf, sitf);
506
507     Binding b = citf.getBinding();
508     ServerInterface oldSitf = b.getServerInterface();
509     removeBinding(oldSitf, b);
510     b = new BasicBinding(citf, sitf);
511     setBinding(citf, b);
512     addBinding(sitf, b);
513     // notify listeners
514
List JavaDoc listeners = getOwner().getListeners();
515     for (int i = 0; i < listeners.size(); ++i) {
516       ConfigurationListener l = (ConfigurationListener)listeners.get(i);
517       l.interfaceRebound(citf, oldSitf);
518     }
519   }
520
521   public void unbind (final ClientInterface citf) {
522     if (citf == null) {
523       throw new IllegalArgumentException JavaDoc();
524     }
525     if (citf.getBinding() == null) {
526       throw new IllegalOperationException("Interface not bound");
527     }
528     List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
529     for (int i = 0; i < vetoableListeners.size(); ++i) {
530       VetoableConfigurationListener l =
531         (VetoableConfigurationListener)vetoableListeners.get(i);
532       l.canUnbindInterface(citf);
533     }
534     // TODO check citf belongs to this
535

536     // if citf is a slave collection interface, delete it
537
if (citf.isCollection()) {
538       if (citf.isInternal()) {
539         removeServerInterface((ServerInterface)citf.getComplementaryInterface());
540       } else {
541         removeClientInterface(citf);
542       }
543       return;
544     }
545
546     Binding b = citf.getBinding();
547     ServerInterface sitf = b.getServerInterface();
548     setBinding(citf, null);
549     removeBinding(sitf, b);
550     // notify listeners
551
List JavaDoc listeners = getOwner().getListeners();
552     for (int i = 0; i < listeners.size(); ++i) {
553       ConfigurationListener l = (ConfigurationListener)listeners.get(i);
554       l.interfaceUnbound(citf, sitf);
555     }
556   }
557
558   /**
559    * Checks that the given binding verifies the structural constraints for
560    * bindings. There are several cases, for normal, import and export bindings.
561    *
562    * @param citf a client interface.
563    * @param sitf a server interface.
564    */

565
566   private void checkBinding (
567     final ClientInterface citf,
568     final ServerInterface sitf)
569   {
570     List JavaDoc cparents = new ArrayList JavaDoc();
571     Component c = citf.getOwner();
572     cparents.add(c.getParent());
573     List JavaDoc slaves = c.getSlaveComponents();
574     for (int i = 0; i < slaves.size(); ++i) {
575       cparents.add(((Component)slaves.get(i)).getParent());
576     }
577     if (citf.isInternal()) {
578       if (sitf.isInternal()) {
579         if (sitf.getOwner() != citf.getOwner()) {
580           throw new IllegalOperationException(
581             "Cannot bind internal interfaces of two distinct components");
582         }
583       } else if (sitf.getOwner().getParent() != citf.getOwner()) {
584         throw new IllegalOperationException(
585           "An internal interface must be bound to a direct sub component " +
586           "or to another internal interface of the same component");
587       }
588     } else if (sitf.isInternal()) {
589       if (!cparents.contains(sitf.getOwner())) {
590         throw new IllegalOperationException(
591           "Cannot bind a component to the internal interface of another " +
592           "component, unless it is its parent component");
593       }
594     } else if (!cparents.contains(sitf.getOwner().getParent())) {
595       throw new IllegalOperationException(
596         "Cannot bind two components that do not belong to the same component");
597     }
598   }
599
600   // -------------------------------------------------------------------------
601
// Attributes
602
// -------------------------------------------------------------------------
603

604   public String JavaDoc getAttributeController () {
605     return attributeController;
606   }
607
608   public void setAttributeController (final String JavaDoc attributeController) {
609     if (attributeController == null) {
610       throw new IllegalArgumentException JavaDoc();
611     }
612     String JavaDoc oldAttributeController = this.attributeController;
613     if (!attributeController.equals(oldAttributeController)) {
614       List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
615       for (int i = 0; i < vetoableListeners.size(); ++i) {
616         VetoableConfigurationListener l =
617           (VetoableConfigurationListener)vetoableListeners.get(i);
618         l.canChangeAttributeController(this);
619       }
620       this.attributeController = attributeController;
621       List JavaDoc listeners = getOwner().getListeners();
622       for (int i = 0; i < listeners.size(); ++i) {
623         ConfigurationListener l = (ConfigurationListener)listeners.get(i);
624         l.attributeControllerChanged(this, oldAttributeController);
625       }
626     }
627   }
628
629   public List JavaDoc getAttributeNames () {
630     return Collections.unmodifiableList(new ArrayList JavaDoc(attributes.keySet()));
631   }
632
633   public String JavaDoc getAttribute (final String JavaDoc attributeName) {
634     if (attributeName == null) {
635       throw new IllegalArgumentException JavaDoc();
636     }
637     return (String JavaDoc)attributes.get(attributeName);
638   }
639
640   public void setAttribute (
641     final String JavaDoc attributeName,
642     final String JavaDoc attributeValue)
643   {
644     if (attributeName == null) {
645       throw new IllegalArgumentException JavaDoc();
646     }
647     String JavaDoc oldValue = (String JavaDoc)attributes.get(attributeName);
648     if (oldValue == null && attributeValue == null) {
649       return;
650     }
651     if ((oldValue == null && attributeValue != null) ||
652         (oldValue != null && attributeValue == null) ||
653         !oldValue.equals(attributeValue))
654     {
655       List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
656       for (int i = 0; i < vetoableListeners.size(); ++i) {
657         VetoableConfigurationListener l =
658           (VetoableConfigurationListener)vetoableListeners.get(i);
659         l.canChangeAttribute(this, attributeName);
660       }
661       if (attributeValue == null) {
662         attributes.remove(attributeName);
663       } else {
664         attributes.put(attributeName, attributeValue);
665       }
666       List JavaDoc listeners = getOwner().getListeners();
667       for (int i = 0; i < listeners.size(); ++i) {
668         ConfigurationListener l = (ConfigurationListener)listeners.get(i);
669         l.attributeChanged(this, attributeName, oldValue);
670       }
671     }
672   }
673
674   // -------------------------------------------------------------------------
675
// Controller descriptors
676
// -------------------------------------------------------------------------
677

678   public String JavaDoc getTemplateControllerDescriptor () {
679     return tmplDesc;
680   }
681
682   public void setTemplateControllerDescriptor (final String JavaDoc desc) {
683     if (desc == null) {
684       throw new IllegalArgumentException JavaDoc();
685     }
686     String JavaDoc oldDesc = this.tmplDesc;
687     if (!desc.equals(oldDesc)) {
688       List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
689       for (int i = 0; i < vetoableListeners.size(); ++i) {
690         VetoableConfigurationListener l =
691           (VetoableConfigurationListener)vetoableListeners.get(i);
692         l.canChangeTemplateControllerDescriptor(this);
693       }
694       this.tmplDesc = desc;
695       List JavaDoc listeners = getOwner().getListeners();
696       for (int i = 0; i < listeners.size(); ++i) {
697         ConfigurationListener l = (ConfigurationListener)listeners.get(i);
698         l.templateControllerDescriptorChanged(this, oldDesc);
699       }
700     }
701   }
702
703   public String JavaDoc getComponentControllerDescriptor () {
704     return compDesc;
705   }
706
707   public void setComponentControllerDescriptor (final String JavaDoc desc) {
708     if (desc == null) {
709       throw new IllegalArgumentException JavaDoc();
710     }
711     String JavaDoc oldDesc = this.compDesc;
712     if (!desc.equals(oldDesc)) {
713       List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
714       for (int i = 0; i < vetoableListeners.size(); ++i) {
715         VetoableConfigurationListener l =
716           (VetoableConfigurationListener)vetoableListeners.get(i);
717         l.canChangeComponentControllerDescriptor(this);
718       }
719       this.compDesc = desc;
720       List JavaDoc listeners = getOwner().getListeners();
721       for (int i = 0; i < listeners.size(); ++i) {
722         ConfigurationListener l = (ConfigurationListener)listeners.get(i);
723         l.componentControllerDescriptorChanged(this, oldDesc);
724       }
725     }
726   }
727
728   // -------------------------------------------------------------------------
729
// Sharing
730
// -------------------------------------------------------------------------
731

732   public boolean isShared () {
733     return slaveComponents.size() > 0;
734   }
735
736   public Component getMasterComponent () {
737     return null;
738   }
739
740   public List JavaDoc getSlaveComponents () {
741     return Collections.unmodifiableList(slaveComponents);
742   }
743
744   /**
745    * Adds the given component to the list of slave components of this component.
746    *
747    * @param slaveComponent a new slave component of this component.
748    */

749
750   void addSlaveComponent (final Component slaveComponent) {
751     if (!slaveComponents.contains(slaveComponent)) {
752       slaveComponents.add(slaveComponent);
753     }
754   }
755
756   /**
757    * Removes the given component from the list of slave components of this
758    * component.
759    *
760    * @param slaveComponent a slave component of this component.
761    */

762
763   void removeSlaveComponent (final Component slaveComponent) {
764     slaveComponents.remove(slaveComponent);
765   }
766
767   // -------------------------------------------------------------------------
768
// Composite specific informations
769
// -------------------------------------------------------------------------
770

771   public boolean isComposite () {
772     return subComponents.size() > 0;
773   }
774
775   public List JavaDoc getSubComponents () {
776     return Collections.unmodifiableList(subComponents);
777   }
778
779   public Component getSubComponent (final String JavaDoc name) {
780     if (name == null) {
781       throw new IllegalArgumentException JavaDoc();
782     }
783     for (int i = 0; i < subComponents.size(); ++i) {
784       Component c = (Component)subComponents.get(i);
785       if (c.getName().equals(name)) {
786         return c;
787       }
788     }
789     return null;
790   }
791
792   public void addSubComponent (final Component child) {
793     if (!subComponents.contains(child)) {
794       implementation = "";
795       int index = subComponents.size();
796
797       if (child.getMasterComponent() != null) {
798         if (child.getMasterComponent() == this ||
799             child.getMasterComponent().contains(this))
800         {
801           throw new IllegalOperationException(
802             "Cannot add shared a component inside its master component");
803         }
804       }
805
806       List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
807       for (int i = 0; i < vetoableListeners.size(); ++i) {
808         VetoableConfigurationListener l =
809           (VetoableConfigurationListener)vetoableListeners.get(i);
810         l.canAddSubComponent(this, child);
811       }
812
813       // add sub component
814
subComponents.add(child);
815       ((AbstractComponent)child).setParent(this);
816       // restore bindings, if any
817
List JavaDoc itfs = child.getClientInterfaces();
818       for (int i = 0; i < itfs.size(); ++i) {
819         restoreBinding((ClientInterface)itfs.get(i), false);
820       }
821       itfs = child.getServerInterfaces();
822       for (int i = 0; i < itfs.size(); ++i) {
823         restoreBinding((ServerInterface)itfs.get(i), false);
824       }
825       // restores references from external master components to
826
// slave components inside child
827
List JavaDoc slaves = new ArrayList JavaDoc();
828       getSlavesOfExternalComponents(child, child, slaves);
829       for (int i = 0; i < slaves.size(); ++i) {
830         Component slave = (Component)slaves.get(i);
831         ((BasicComponent)slave.getMasterComponent()).addSlaveComponent(slave);
832       }
833       // notify listeners
834