KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > fractal > julia > control > binding > OptimizedCompositeBindingMixin


1 /***
2  * Julia: France Telecom's implementation of the Fractal API
3  * Copyright (C) 2001-2002 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: Eric.Bruneton@rd.francetelecom.com
20  *
21  * Author: Eric Bruneton
22  */

23
24 package org.objectweb.fractal.julia.control.binding;
25
26 import org.objectweb.fractal.api.Component;
27 import org.objectweb.fractal.api.Interface;
28 import org.objectweb.fractal.api.NoSuchInterfaceException;
29 import org.objectweb.fractal.api.control.BindingController;
30 import org.objectweb.fractal.api.control.ContentController;
31 import org.objectweb.fractal.api.control.IllegalBindingException;
32 import org.objectweb.fractal.api.control.IllegalLifeCycleException;
33 import org.objectweb.fractal.api.type.InterfaceType;
34
35 import org.objectweb.fractal.julia.ComponentInterface;
36 import org.objectweb.fractal.julia.Interceptor;
37
38 import java.util.HashSet JavaDoc;
39 import java.util.List JavaDoc;
40 import java.util.Set JavaDoc;
41 import java.util.ArrayList JavaDoc;
42
43 /**
44  * Provides optimized {@link ComponentInterface} management to a {@link
45  * BindingController}. This mixin uses shortcut links between component
46  * interfaces where possible, i.e. when some interfaces do not have associated
47  * interceptors.
48  * <br>
49  * <br>
50  * <b>Requirements</b>
51  * <ul>
52  * <li>the component to which this controller object belongs must provide the
53  * {@link Component} and {@link ContentController} interfaces.</li>
54  * <li>TODO.</li>
55  * </ul>
56  */

57
58 public abstract class OptimizedCompositeBindingMixin
59   implements BindingController
60 {
61
62   // -------------------------------------------------------------------------
63
// Private constructor
64
// -------------------------------------------------------------------------
65

66   private OptimizedCompositeBindingMixin () {
67   }
68
69   // -------------------------------------------------------------------------
70
// Fields and methods added and overriden by the mixin class
71
// -------------------------------------------------------------------------
72

73   /**
74    * Sets the shortcuts for the given binding and then calls the overriden
75    * method.
76    *
77    * @param clientItfType the type of the <tt>clientItfName</tt> interface.
78    * @param clientItfName the name of a client interface of the component to
79    * which this interface belongs.
80    * @param serverItf a server interface.
81    * @throws NoSuchInterfaceException if there is no such client interface.
82    * @throws IllegalBindingException if the binding cannot be created.
83    * @throws IllegalLifeCycleException if this component has a {@link
84    * org.objectweb.fractal.api.control.LifeCycleController} interface, but
85    * it is not in an appropriate state to perform this operation.
86    */

87
88   public void bindFc (
89     final InterfaceType clientItfType,
90     final String JavaDoc clientItfName,
91     final Object JavaDoc serverItf)
92     throws
93     NoSuchInterfaceException,
94     IllegalBindingException,
95     IllegalLifeCycleException
96   {
97     _super_bindFc(clientItfType, clientItfName, serverItf);
98     setFcShortcuts(clientItfType, clientItfName, serverItf);
99   }
100
101   /**
102    * Updates the shortcuts for the given binding and then calls the overriden
103    * method.
104    *
105    * @param clientItfType the type of the <tt>clientItfName</tt> interface.
106    * @param clientItfName the name of a client interface of the component to
107    * which this interface belongs.
108    * @throws NoSuchInterfaceException if there is no such client interface.
109    * @throws IllegalBindingException if the binding cannot be removed.
110    * @throws IllegalLifeCycleException if this component has a {@link
111    * org.objectweb.fractal.api.control.LifeCycleController} interface, but
112    * it is not in an appropriate state to perform this operation.
113    */

114
115   public void unbindFc (
116     final InterfaceType clientItfType,
117     final String JavaDoc clientItfName)
118     throws
119     NoSuchInterfaceException,
120     IllegalBindingException,
121     IllegalLifeCycleException
122   {
123     _super_unbindFc(clientItfType, clientItfName);
124     setFcShortcuts(clientItfType, clientItfName, null);
125   }
126
127   // -------------------------------------------------------------------------
128
// Utility methods: algorithm to compute of shortcut links
129
// -------------------------------------------------------------------------
130

131   /**
132    * Creates the given binding and updates the shortcuts links accordingly.
133    *
134    * @param clientItfType the type of the 'clientItfName' interface.
135    * @param clientItfName a client interface name.
136    * @param serverItf the server interface to which the client interface must
137    * be bound, or <tt>null</tt> if it must be unbound.
138    * @throws NoSuchInterfaceException if there is no client interface whose name
139    * is equal to 'clientItfName'.
140    * @throws IllegalBindingException if a problem occurs.
141    */

142
143   public void setFcShortcuts (
144     final InterfaceType clientItfType,
145     final String JavaDoc clientItfName,
146     final Object JavaDoc serverItf)
147     throws
148     NoSuchInterfaceException,
149     IllegalBindingException
150   {
151     Interface clientItf;
152     if (clientItfType.isFcClientItf()) {
153       clientItf =
154         (Interface)_this_weaveableC.getFcInterface(clientItfName);
155     } else {
156       clientItf =
157         (Interface)_this_weaveableCC.getFcInternalInterface(clientItfName);
158     }
159
160     Set JavaDoc visited = new HashSet JavaDoc();
161     List JavaDoc shortcutItfs = new ArrayList JavaDoc();
162     List JavaDoc shortcutImpls = new ArrayList JavaDoc();
163
164     // 'forward' step
165
Object JavaDoc itf = serverItf;
166     while (true) {
167       ComponentInterface citf;
168       if (itf instanceof ComponentInterface) {
169         citf = (ComponentInterface)itf;
170       } else {
171         break;
172       }
173       if (citf.getFcItfImpl() instanceof Interceptor) {
174         break;
175       }
176       try {
177         Component owner = citf.getFcItfOwner();
178         owner.getFcInterface("content-controller");
179         BindingController bc =
180           (BindingController)owner.getFcInterface("binding-controller");
181         itf = bc.lookupFc(citf.getFcItfName());
182       } catch (NoSuchInterfaceException e) {
183         break;
184       }
185     }
186     Object JavaDoc impl;
187     if (itf == null) {
188       impl = null;
189     } else {
190       if (itf instanceof ComponentInterface) {
191         impl = ((ComponentInterface)itf).getFcItfImpl();
192       } else {
193         // cannot create complete shortcut: uses itf as 'impl'
194
impl = itf;
195       }
196     }
197
198     // 'backward' step : creates the shortcuts
199
try {
200       setFcClientShortcuts(clientItf, impl, visited, shortcutItfs, shortcutImpls);
201     } catch (Exception JavaDoc e) {
202       Interface sItf;
203       sItf = serverItf instanceof Interface ? (Interface)serverItf : null;
204       throw new ChainedIllegalBindingException(
205         e,
206         clientItf.getFcItfOwner(),
207         sItf == null ? null : sItf.getFcItfOwner(),
208         clientItf.getFcItfName(),
209         sItf == null ? null : sItf.getFcItfName(),
210         "Cannot create shortcut links");
211     }
212
213     // sets the shortcuts
214
for (int i = 0; i < shortcutItfs.size(); ++i) {
215       Interface shortcutItf = (Interface)shortcutItfs.get(i);
216       Object JavaDoc shortcutImpl = shortcutImpls.get(i);
217       Component c = shortcutItf.getFcItfOwner();
218       ContentController cc;
219       try {
220         cc = (ContentController)c.getFcInterface("content-controller");
221       } catch (NoSuchInterfaceException e) {
222         cc = null;
223       }
224
225       if (cc != null) {
226         ComponentInterface cShortcutItf = (ComponentInterface)shortcutItf;
227         if (cShortcutItf.hasFcInterceptor()) {
228           Object JavaDoc newImpl = cShortcutItf.getFcItfImpl();
229           ((Interceptor)newImpl).setFcItfDelegate(shortcutImpl);
230         } else {
231           cShortcutItf.setFcItfImpl(shortcutImpl);
232         }
233       } else {
234         BindingController bc;
235         try {
236           bc = (BindingController)c.getFcInterface("binding-controller");
237         } catch (NoSuchInterfaceException e) {
238           continue;
239         }
240         try {
241           String JavaDoc itfName = shortcutItf.getFcItfName();
242           Object JavaDoc o = bc.lookupFc(itfName);
243           // following code not needed if refresh done in lookup
244
if (o != null) {
245             bc.unbindFc(itfName);
246             bc.bindFc(itfName, o);
247           }
248         } catch (Exception JavaDoc e) {
249           Interface sItf;
250           sItf = serverItf instanceof Interface ? (Interface)serverItf : null;
251           throw new ChainedIllegalBindingException(
252             e,
253             clientItf.getFcItfOwner(),
254             sItf == null ? null : sItf.getFcItfOwner(),
255             clientItf.getFcItfName(),
256             sItf == null ? null : sItf.getFcItfName(),
257             "Cannot create shortcut links");
258         }
259       }
260     }
261   }
262
263   /**
264    * Finds the shortcut links to be updated by following the bindings backwards
265    * from the given client interface.
266    *
267    * @param clientItf the client interface from which the bindings must be
268    * followed backward.
269    * @param impl the object to be used to update the shortcut links with {@link
270    * ComponentInterface#getFcItfImpl getFcItfImpl}.
271    * @param visited the already visited interfaces.
272    * @param shortcutItfs the interfaces whose shortcut links must be updated.
273    * @param shortcutImpls the values to be used to update the shortcut links.
274    * @throws Exception if a problem occurs.
275    */

276
277   public void setFcClientShortcuts (
278     final Interface clientItf,
279     final Object JavaDoc impl,
280     final Set JavaDoc visited,
281     final List JavaDoc shortcutItfs,
282     final List JavaDoc shortcutImpls) throws Exception JavaDoc
283   {
284     Component clientComp = clientItf.getFcItfOwner();
285     ContentController cc;
286     try {
287       cc = (ContentController)clientComp.getFcInterface("content-controller");
288     } catch (NoSuchInterfaceException e) {
289       cc = null;
290     }
291
292     if (cc != null) {
293       ComponentInterface itf;
294       try {
295         String JavaDoc name = clientItf.getFcItfName();
296         if (clientItf.isFcInternalItf()) {
297           // clientItf is an internal client interface: continue to follow the
298
// bindings backwards from the corresponding external server interface
299
itf = (ComponentInterface)clientComp.getFcInterface(name);
300         } else {
301           // clientItf is an external client interface: continue to follow the
302
// bindings backwards from the corresponding internal server interface
303
itf = (ComponentInterface)cc.getFcInternalInterface(name);
304         }
305       } catch (NoSuchInterfaceException e) {
306         throw new Exception JavaDoc("Cannot create shortcut links");
307       } catch (ClassCastException JavaDoc e) {
308         throw new Exception JavaDoc("Cannot create shortcut links");
309       }
310
311       if (!visited.contains(itf)) {
312         visited.add(itf);
313         shortcutItfs.add(itf);
314         shortcutImpls.add(impl);
315         if (itf.hasFcInterceptor()) {
316           Object JavaDoc newImpl = itf.getFcItfImpl();
317           setFcServerShortcuts(itf, newImpl, visited, shortcutItfs, shortcutImpls);
318         } else {
319           setFcServerShortcuts(itf, impl, visited, shortcutItfs, shortcutImpls);
320         }
321       }
322     } else if (!visited.contains(clientItf)) {
323       visited.add(clientItf);
324       shortcutItfs.add(clientItf);
325       shortcutImpls.add(impl);
326     }
327   }
328
329   /**
330    * Finds the shortcut links to be updated by followng the bindings backwards
331    * from the given server interface.
332    *
333    * @param serverItf the server interface from which the bindings must be
334    * followed backward.
335    * @param impl the object to be used to update the shortcut links with {@link
336    * ComponentInterface#getFcItfImpl getFcItfImpl}.
337    * @param visited the already visited interfaces.
338    * @param shortcutItfs the interfaces whose shortcut links must be updated.
339    * @param shortcutImpls the values to be used to update the shortcut links.
340    * @throws Exception if a problem occurs.
341    */

342
343   public void setFcServerShortcuts (
344     final Interface serverItf,
345     final Object JavaDoc impl,
346     final Set JavaDoc visited,
347     final List JavaDoc shortcutItfs,
348     final List JavaDoc shortcutImpls) throws Exception JavaDoc
349   {
350     Object JavaDoc[] comps = Util.getFcPotentialClientsOf(serverItf).toArray();
351     for (int i = 0; i < comps.length; ++i) {
352       Component comp = (Component)comps[i];
353       List JavaDoc clientItfs = Util.getFcClientItfsBoundTo(comp, serverItf);
354       for (int j = 0; j < clientItfs.size(); ++j) {
355         setFcClientShortcuts(
356           (Interface)clientItfs.get(j),
357           impl,
358           visited,
359           shortcutItfs,
360           shortcutImpls);
361       }
362     }
363   }
364
365   // -------------------------------------------------------------------------
366
// Fields and methods required by the mixin class in the base class
367
// -------------------------------------------------------------------------
368

369   /**
370    * The <tt>weaveableC</tt> field required by this mixin. This field is
371    * supposed to reference the {@link Component} interface of the component to
372    * which this controller object belongs.
373    */

374
375   public Component _this_weaveableC;
376
377   /**
378    * The <tt>weaveableCC</tt> field required by this mixin. This field is
379    * supposed to reference the {@link ContentController} interface of the
380    * component to which this controller object belongs.
381    */

382
383   public ContentController _this_weaveableCC;
384
385   /**
386    * The {@link TypeBindingMixin#bindFc(InterfaceType,String,Object) bindFc}
387    * method overriden by this mixin.
388    *
389    * @param clientItfType the type of the <tt>clientItfName</tt> interface.
390    * @param clientItfName the name of a client interface of the component to
391    * which this interface belongs.
392    * @param serverItf a server interface.
393    * @throws NoSuchInterfaceException if there is no such client interface.
394    * @throws IllegalBindingException if the binding cannot be created.
395    * @throws IllegalLifeCycleException if this component has a {@link
396    * org.objectweb.fractal.api.control.LifeCycleController} interface, but
397    * it is not in an appropriate state to perform this operation.
398    */

399
400   public abstract void _super_bindFc (
401     InterfaceType clientItfType,
402     String JavaDoc clientItfName,
403     Object JavaDoc serverItf)
404     throws
405     NoSuchInterfaceException,
406     IllegalBindingException,
407     IllegalLifeCycleException;
408
409   /**
410    * The {@link TypeBindingMixin#unbindFc(InterfaceType,String) unbindFc}
411    * method overriden by this mixin.
412    *
413    * @param clientItfType the type of the <tt>clientItfName</tt> interface.
414    * @param clientItfName the name of a client interface of the component to
415    * which this interface belongs.
416    * @throws NoSuchInterfaceException if there is no such client interface.
417    * @throws IllegalBindingException if the binding cannot be removed.
418    * @throws IllegalLifeCycleException if this component has a {@link
419    * org.objectweb.fractal.api.control.LifeCycleController} interface, but
420    * it is not in an appropriate state to perform this operation.
421    */

422
423   public abstract void _super_unbindFc (
424     InterfaceType clientItfType,
425     String JavaDoc clientItfName)
426     throws
427     NoSuchInterfaceException,
428     IllegalBindingException,
429     IllegalLifeCycleException;
430 }
431
Popular Tags