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
List JavaDoc listeners = getOwner().getListeners();
835       for (int i = 0; i < listeners.size(); ++i) {
836         ConfigurationListener l = (ConfigurationListener)listeners.get(i);
837         l.subComponentAdded(this, child, index);
838       }
839     }
840   }
841
842   public void removeSubComponent (final Component child) {
843     if (subComponents.contains(child)) {
844       int index = subComponents.indexOf(child);
845
846       if (child.containsMasterOfExternalComponent(child)) {
847         throw new IllegalOperationException(
848           "Cannot remove a component that contains or is the master " +
849           "component of an external shared component");
850       }
851
852       List JavaDoc vetoableListeners = getOwner().getVetoableListeners();
853       for (int i = 0; i < vetoableListeners.size(); ++i) {
854         VetoableConfigurationListener l =
855           (VetoableConfigurationListener)vetoableListeners.get(i);
856         l.canRemoveSubComponent(this, child);
857       }
858
859       // remove sub component
860
subComponents.remove(child);
861       ((AbstractComponent)child).setParent(null);
862       // remove bindings, if any
863
List JavaDoc itfs = child.getClientInterfaces();
864       for (int i = 0; i < itfs.size(); ++i) {
865         removeBinding((ClientInterface)itfs.get(i), false);
866       }
867       itfs = child.getServerInterfaces();
868       for (int i = 0; i < itfs.size(); ++i) {
869         removeBinding((ServerInterface)itfs.get(i), false);
870       }
871       // removes references from external master components to
872
// slave components inside child
873
List JavaDoc slaves = new ArrayList JavaDoc();
874       getSlavesOfExternalComponents(child, child, slaves);
875       for (int i = 0; i < slaves.size(); ++i) {
876         Component slave = (Component)slaves.get(i);
877         ((BasicComponent)slave.getMasterComponent()).removeSlaveComponent(slave);
878       }
879       // notify listeners
880
List JavaDoc listeners = getOwner().getListeners();
881       for (int i = 0; i < listeners.size(); ++i) {
882         ConfigurationListener l = (ConfigurationListener)listeners.get(i);
883         l.subComponentRemoved(this, child, index);
884       }
885     }
886   }
887
888   /**
889    * Returns the sub components of the given root component that are slaves of
890    * external components. 'External' meaning components that are not sub
891    * components of the given root component.
892    *
893    * @param c a direct or indirect sub component of the root component.
894    * @param root a root component.
895    * @param slaves the list to which the sub components found must be added.
896    */

897
898   private static void getSlavesOfExternalComponents (
899     final Component c,
900     final Component root,
901     final List JavaDoc slaves)
902   {
903     Component master = c.getMasterComponent();
904     if (master != null && !root.contains(master)) {
905       slaves.add(c);
906     }
907     List JavaDoc subComponents = c.getSubComponents();
908     for (int i = 0; i < subComponents.size(); ++i) {
909       Component subComponent = (Component)subComponents.get(i);
910       getSlavesOfExternalComponents(subComponent, root, slaves);
911     }
912   }
913
914   // -------------------------------------------------------------------------
915
// Other methods
916
// -------------------------------------------------------------------------
917

918   /**
919    * Restores the binding associated to the given client interface. If the
920    * binding associated to the given interface is not <tt>null</tt>, this method
921    * restores the redundant reference from the server interface to the binding
922    * object, by calling the {@link #addBinding(ServerInterface,Binding)
923    * addBinding} method. If <tt>internal</tt> is <tt>true</tt>, the bindings
924    * <i>to</i> the complementary interface of the given interface are also
925    * restored: for each binding that refer to this complementary interface, the
926    * redundant reference from the client interface to the binding is restored by
927    * calling the {@link #setBinding setBinding} method.
928    *
929    * @param itf an external client interface.
930    * @param internal <tt>true</tt> if the bindings <i>to</i> the given interface
931    * must be restored also, of <tt>false</tt> if only the binding
932    * <i>from</i> the interface must be restored.
933    */

934
935   private void restoreBinding (
936     final ClientInterface itf,
937     final boolean internal)
938   {
939     Binding b = itf.getBinding();
940     if (b != null) {
941       addBinding(b.getServerInterface(), b);
942     }
943     if (internal && itf.getOwner().isComposite()) {
944       List JavaDoc bs = ((ServerInterface)itf.getComplementaryInterface()).getBindings();
945       for (int i = 0; i < bs.size(); ++i) {
946         b = (Binding)bs.get(i);
947         setBinding(b.getClientInterface(), b);
948       }
949     }
950   }
951
952   /**
953    * Removes the binding associated to the given client interface. This method
954    * only removes the redundant reference from the server interface to the
955    * binding object (if it is not <tt>null</tt>). If <tt>internal</tt> is
956    * <tt>true</tt>, the bindings <i>to</i> the complementary interface of the
957    * given interface are also removed: for each binding that refer to this
958    * complementary interface, the redundant reference from the client interface
959    * to the binding is removed by calling the {@link #setBinding setBinding}
960    * method.
961    *
962    * @param itf an external client interface.
963    * @param internal <tt>true</tt> if the bindings <i>to</i> the given interface
964    * must be removed also, of <tt>false</tt> if only the binding
965    * <i>from</i> the interface must be removed.
966    */

967
968   private void removeBinding (
969     final ClientInterface itf,
970     final boolean internal)
971   {
972     Binding b = itf.getBinding();
973     if (b != null) {
974       removeBinding(b.getServerInterface(), b);
975     }
976     if (internal && itf.getOwner().isComposite()) {
977       List JavaDoc bs = ((ServerInterface)itf.getComplementaryInterface()).getBindings();
978       for (int i = 0; i < bs.size(); ++i) {
979         b = (Binding)bs.get(i);
980         setBinding(b.getClientInterface(), null);
981       }
982     }
983   }
984
985   /**
986    * Restores the binding associated the given server interface. For each
987    * binding that refer to the given interface, this method restores the
988    * redundant reference from the client interface to the binding object, by
989    * calling the {@link #setBinding setBinding} method. If <tt>internal</tt> is
990    * <tt>true</tt>, the binding <i>from</i> the complementary interface of the
991    * given interface is also restored: the redundant reference from the server
992    * interface to the binding is restored by calling the {@link #addBinding
993    * addBinding} method.
994    *
995    * @param itf an external server interface.
996    * @param internal <tt>true</tt> if the binding <i>from</i> the given
997    * interface must be restored also, of <tt>false</tt> if only the
998    * bindings <i>to</i> the interface must be restored.
999    */

1000
1001  private void restoreBinding (
1002    final ServerInterface itf,
1003    final boolean internal)
1004  {
1005    List JavaDoc bs = itf.getBindings();
1006    for (int i = 0; i < bs.size(); ++i) {
1007      Binding b = (Binding)bs.get(i);
1008      setBinding(b.getClientInterface(), b);
1009    }
1010    if (internal && itf.getOwner().isComposite()) {
1011      Binding b = ((ClientInterface)itf.getComplementaryInterface()).getBinding();
1012      if (b != null) {
1013        addBinding(b.getServerInterface(), b);
1014      }
1015    }
1016  }
1017
1018  /**
1019   * Removes the binding associated the given server interface. For each
1020   * binding that refer to the given interface, this method removes the
1021   * redundant reference from the client interface to the binding object, by
1022   * calling the {@link #setBinding setBinding} method. If <tt>internal</tt> is
1023   * <tt>true</tt>, the binding <i>from</i> the complementary interface of the
1024   * given interface is also removed: the redundant reference from the server
1025   * interface to the binding is removed by calling the {@link #removeBinding
1026   * removeBinding} method.
1027   *
1028   * @param itf an external server interface.
1029   * @param internal <tt>true</tt> if the binding <i>from</i> the given
1030   * interface must be removed also, of <tt>false</tt> if only the
1031   * bindings <i>to</i> the interface must be removed.
1032   */

1033
1034  private void removeBinding (
1035    final ServerInterface itf,
1036    final boolean internal)
1037  {
1038    List JavaDoc bs = itf.getBindings();
1039    for (int i = 0; i < bs.size(); ++i) {
1040      Binding b = (Binding)bs.get(i);
1041      setBinding(b.getClientInterface(), null);
1042    }
1043    if (internal && itf.getOwner().isComposite()) {
1044      Binding b = ((ClientInterface)itf.getComplementaryInterface()).getBinding();
1045      if (b != null) {
1046        removeBinding(b.getServerInterface(), b);
1047      }
1048    }
1049  }
1050
1051  /**
1052   * Sets the binding associated to the given client interface. If the given
1053   * interface is a slave collection interface, then the interface is added to
1054   * (or, if the given binding is <tt>null</tt>, removed from) its owner
1055   * component, by calling the addXXXInterface (or removeXXXInterface) method,
1056   * <i>with notifications disabled</i>, so that only the main operation is
1057   * notified, even if this operation internally triggers other operations (when
1058   * an external collection interface is unbound on a composite component, for
1059   * example, this interface and its complementary interface are removed, which
1060   * requires to unbind the interfaces that where bound to this complementary
1061   * interface, if any, which can again remove an external collection interface
1062   * of a composite component, which requires to unbind that where bound to this
1063   * complementary interface, and so on).
1064   *
1065   * @param i a client interface.
1066   * @param b the binding associated to this client interface. May be
1067   * <tt>null</tt>.
1068   */

1069
1070  private void setBinding (ClientInterface i, final Binding b) {
1071    if (i instanceof SharedClientInterface) {
1072      i = (ClientInterface)((SharedClientInterface)i).masterInterface;
1073    }
1074    ((BasicClientInterface)i).setBinding(b);
1075    if (i.isCollection()) {
1076      notificationEnabled = false;
1077      try {
1078        Component c = i.getOwner();
1079        if (b == null) {
1080          if (i.isInternal()) {
1081            c.removeServerInterface((ServerInterface)i.getComplementaryInterface());
1082          } else {
1083            c.removeClientInterface(i);
1084          }
1085        } else {
1086          if (i.isInternal()) {
1087            c.addServerInterface((ServerInterface)i.getComplementaryInterface());
1088          } else {
1089            c.addClientInterface(i);
1090          }
1091        }
1092      } finally {
1093        notificationEnabled = true;
1094      }
1095    }
1096  }
1097
1098  /**
1099   * Adds the given binding to the list of bindings that refer to the given
1100   * interface.
1101   *
1102   * @param i a server interface.
1103   * @param b a binding that refer to this interface.
1104   */

1105
1106  private void addBinding (final ServerInterface i, final Binding b) {
1107    if (i instanceof BasicServerInterface) {
1108      ((BasicServerInterface)i).addBinding(b);
1109    } else {
1110      ((SharedServerInterface)i).addBinding(b);
1111    }
1112  }
1113
1114  /**
1115   * Removes the given binding from the list of bindings that refer to the given
1116   * interface.
1117   *
1118   * @param i a server interface.
1119   * @param b a binding that refer to this interface.
1120   */

1121
1122  private void removeBinding (final ServerInterface i, final Binding b) {
1123    if (i instanceof BasicServerInterface) {
1124      ((BasicServerInterface)i).removeBinding(b);
1125    } else {
1126      ((SharedServerInterface)i).removeBinding(b);
1127    }
1128  }
1129}
1130
Popular Tags