KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > fractal > julia > factory > BasicTemplateMixin


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.factory;
25
26 import org.objectweb.fractal.api.Component;
27 import org.objectweb.fractal.api.Fractal;
28 import org.objectweb.fractal.api.Interface;
29 import org.objectweb.fractal.api.NoSuchInterfaceException;
30 import org.objectweb.fractal.api.Type;
31 import org.objectweb.fractal.api.control.BindingController;
32 import org.objectweb.fractal.api.control.ContentController;
33 import org.objectweb.fractal.api.control.IllegalBindingException;
34 import org.objectweb.fractal.api.control.IllegalContentException;
35 import org.objectweb.fractal.api.control.IllegalLifeCycleException;
36 import org.objectweb.fractal.api.factory.GenericFactory;
37 import org.objectweb.fractal.api.factory.InstantiationException;
38 import org.objectweb.fractal.api.type.ComponentType;
39 import org.objectweb.fractal.api.type.InterfaceType;
40
41 import org.objectweb.fractal.julia.Controller;
42 import org.objectweb.fractal.julia.InitializationContext;
43 import org.objectweb.fractal.julia.control.content.Util;
44 import org.objectweb.fractal.julia.type.BasicComponentType;
45
46 import java.util.ArrayList JavaDoc;
47 import java.util.HashMap JavaDoc;
48 import java.util.List JavaDoc;
49 import java.util.Map JavaDoc;
50
51 /**
52  * Provides a basic implementation of the {@link Template} interface.
53  * <br>
54  * <br>
55  * <b>Requirements</b> (here "sub template" means "any direct or indirect sub
56  * template")
57  * <ul>
58  * <li>the type of this template component must be an instance of {@link
59  * ComponentType}.</li>
60  * <li>all the sub templates of this template component must provide the {@link
61  * Template} interface (and the {@link Component} interface).</li>
62  * <li>if this template component, or one of its sub templates, has a {@link
63  * ContentController} interface, then the components instantiated by this
64  * template component must also have the {@link ContentController} interface.
65  * Likewise for the {@link BindingController} interface.</li>
66  * <li>For each binding between template components, the server interface must
67  * implement the {@link Interface} interface. Moreover, the owner of this
68  * interface must be a (sub) template of this template component.</li>
69  * </ul>
70  */

71
72 public abstract class BasicTemplateMixin implements Controller, Template {
73
74   // -------------------------------------------------------------------------
75
// Private constructor
76
// -------------------------------------------------------------------------
77

78   private BasicTemplateMixin () {
79   }
80
81   // -------------------------------------------------------------------------
82
// Fields and methods added and overriden by the mixin class
83
// -------------------------------------------------------------------------
84

85   /**
86    * The functional type of the components instantiated by this template.
87    */

88
89   public Type fcInstanceType;
90
91   /**
92    * The controller and content descriptors of the components instantiated by
93    * this template.
94    */

95
96   public Object JavaDoc[] fcContent;
97
98   /**
99    * Initializes the fields of this mixin and then calls the overriden method.
100    *
101    * @param ic information about the component to which this controller object
102    * belongs.
103    * @throws InstantiationException if the initialization fails.
104    */

105
106   public void initFcController (final InitializationContext ic)
107     throws InstantiationException JavaDoc
108   {
109     // initializes the fcContent field
110
fcContent = (Object JavaDoc[])ic.content;
111
112     // initializes the fcInstanceType field
113
// this type is computed from the type of this component by removing the
114
// factory interface type, and all the control interface types
115
ComponentType tmplType = (ComponentType)ic.type;
116     InterfaceType[] itfTypes = tmplType.getFcInterfaceTypes();
117     List JavaDoc itfList = new ArrayList JavaDoc();
118     for (int j = 0; j < itfTypes.length; ++j) {
119       String JavaDoc n = itfTypes[j].getFcItfName();
120       if (!n.equals("factory")) {
121         if (n.equals("attribute-controller")) {
122           itfList.add(itfTypes[j]);
123         } else if (!(n.equals("component") || n.endsWith("-controller"))) {
124           itfList.add(itfTypes[j]);
125         }
126       }
127     }
128     itfTypes = new InterfaceType[itfList.size()];
129     itfTypes = (InterfaceType[])itfList.toArray(itfTypes);
130     fcInstanceType = new BasicComponentType(itfTypes);
131
132     // calls the overriden method
133
_super_initFcController(ic);
134   }
135
136   public Type getFcInstanceType () {
137     return fcInstanceType;
138   }
139
140   public Object JavaDoc getFcControllerDesc () {
141     return fcContent[0];
142   }
143
144   public Object JavaDoc getFcContentDesc () {
145     return fcContent[1];
146   }
147
148   public Component newFcInstance () throws InstantiationException JavaDoc {
149     // finds all the direct and indirect sub templates of this template
150
// finds all the direct and indirect sub components of this component
151
Component thisComponent;
152     try {
153       thisComponent = (Component)_this_weaveableC.getFcInterface("component");
154     } catch (NoSuchInterfaceException e) {
155       throw new ChainedInstantiationException(
156         e,
157         _this_weaveableC,
158         "The template component must provide the Component interface");
159     }
160     List JavaDoc allSubTemplates = Util.getAllSubComponents(thisComponent);
161
162     // instantiates all the templates
163
Map JavaDoc instances = new HashMap JavaDoc();
164     for (int i = 0; i < allSubTemplates.size(); ++i) {
165       Component tmpl = (Component)allSubTemplates.get(i);
166       Template t;
167       try {
168         t = (Template)tmpl.getFcInterface("factory");
169       } catch (Exception JavaDoc e) {
170         try {
171           t = (Template)tmpl.getFcInterface("/template");
172         } catch (NoSuchInterfaceException f) {
173           throw new ChainedInstantiationException(
174             f,
175             _this_weaveableC,
176             "All the (sub) templates must provide the Template interface");
177         }
178       }
179       Component instance = t.newFcControllerInstance();
180       instances.put(tmpl, instance);
181     }
182
183     // adds the instances into each other
184
for (int i = 0; i < allSubTemplates.size(); ++i) {
185       Component tmpl = (Component)allSubTemplates.get(i);
186       Component instance = (Component)instances.get(tmpl);
187
188       ContentController tmplCC, instanceCC;
189       try {
190         tmplCC = (ContentController)tmpl.getFcInterface("content-controller");
191       } catch (NoSuchInterfaceException e) {
192         continue;
193       }
194       try {
195         instanceCC =
196           (ContentController)instance.getFcInterface("content-controller");
197       } catch (NoSuchInterfaceException e) {
198         throw new ChainedInstantiationException(
199           e,
200           tmpl,
201           "A component instantiated from a template with a ContentController " +
202           "interface must provide the ContentController interface");
203       }
204       Component[] subTemplates = tmplCC.getFcSubComponents();
205       Component[] subInstances = instanceCC.getFcSubComponents();
206       for (int j = 0; j < subTemplates.length; ++j) {
207         Component subInstance = (Component)instances.get(subTemplates[j]);
208         boolean add = true;
209         for (int k = 0; k < subInstances.length; ++k) {
210           if (subInstances[k].equals(subInstance)) {
211             // if sunInstance is already a sub component of instance,
212
// do not add it again (this can happen with singleton templates)
213
add = false;
214           }
215         }
216         if (add) {
217           try {
218             instanceCC.addFcSubComponent(subInstance);
219           } catch (IllegalContentException e) {
220             throw new ChainedInstantiationException(
221               e,
222               tmpl,
223               "Cannot set the component hierarchy from the template hierarchy");
224           } catch (IllegalLifeCycleException e) {
225             throw new ChainedInstantiationException(
226               e,
227               tmpl,
228               "Cannot set the component hierarchy from the template hierarchy");
229           }
230         }
231       }
232     }
233
234     // binds the instances to each other, as the templates are bound
235
for (int i = 0; i < allSubTemplates.size(); ++i) {
236       Component tmpl = (Component)allSubTemplates.get(i);
237       Component instance = (Component)instances.get(tmpl);
238
239       BindingController tmplBC, instanceBC;
240       try {
241         tmplBC = (BindingController)tmpl.getFcInterface("binding-controller");
242       } catch (NoSuchInterfaceException e) {
243         continue;
244       }
245       try {
246         instanceBC =
247           (BindingController)instance.getFcInterface("binding-controller");
248       } catch (NoSuchInterfaceException e) {
249         throw new ChainedInstantiationException(
250           e,
251           tmpl,
252           "A component instantiated from a template with a BindingController " +
253           "interface must provide the BindingController interface");
254       }
255       String JavaDoc[] itfNames = tmplBC.listFc();
256       for (int j = 0; j < itfNames.length; ++j) {
257         String JavaDoc itfName = itfNames[j];
258         Interface serverItf;
259         try {
260           serverItf = (Interface)tmplBC.lookupFc(itfName);
261         } catch (ClassCastException JavaDoc e) {
262           throw new ChainedInstantiationException(
263             e,
264             tmpl,
265             "The server interface of each binding between templates " +
266             "must implement the Interface interface");
267         } catch (NoSuchInterfaceException e) {
268           throw new ChainedInstantiationException(
269             e,
270             tmpl,
271             "The '" + itfName +
272             "' interface returned by the listFc method does not exist");
273         }
274         if (serverItf == null) {
275           continue;
276         }
277
278         Component serverTmpl = serverItf.getFcItfOwner();
279         Component serverInstance = (Component)instances.get(serverTmpl);
280         if (serverInstance == null) {
281           // 'tmpl' bound to a component that does not belong to the root
282
// instantiated template: do not create this binding for 'instance'
283
continue;
284         }
285
286         Object JavaDoc itfValue;
287         try {
288           if (serverItf.isFcInternalItf()) {
289             ContentController cc = (ContentController)serverInstance.
290               getFcInterface("content-controller");
291             itfValue = cc.getFcInternalInterface(serverItf.getFcItfName());
292           } else {
293             itfValue = serverInstance.getFcInterface(serverItf.getFcItfName());
294           }
295         } catch (NoSuchInterfaceException e) {
296           throw new ChainedInstantiationException(
297             e,
298             serverTmpl,
299             "The server interface '" + serverItf.getFcItfName() +
300             "'is missing in the component instantiated from the template");
301         }
302
303         try {
304           if (instanceBC.lookupFc(itfName).equals(itfValue)) {
305             // if the binding already exists, do not create again
306
// (this can happen with singleton templates)
307
continue;
308           }
309         } catch (Exception JavaDoc e) {
310         }
311
312         try {
313           instanceBC.bindFc(itfName, itfValue);
314         } catch (NoSuchInterfaceException e) {
315           throw new ChainedInstantiationException(
316             e,
317             tmpl,
318             "Cannot set the component bindings from the template bindings");
319         } catch (IllegalBindingException e) {
320           throw new ChainedInstantiationException(
321             e,
322             tmpl,
323             "Cannot set the component bindings from the template bindings");
324         } catch (IllegalLifeCycleException e) {
325           throw new ChainedInstantiationException(
326             e,
327             tmpl,
328             "Cannot set the component bindings from the template bindings");
329         }
330       }
331     }
332
333     return (Component)instances.get(allSubTemplates.get(0));
334   }
335
336   public Component newFcControllerInstance () throws InstantiationException JavaDoc {
337     if (fcContent[1] instanceof Component) {
338       return (Component)fcContent[1];
339     }
340     GenericFactory factory;
341     try {
342       factory = (GenericFactory)Fractal.getBootstrapComponent().
343         getFcInterface("generic-factory");
344     } catch (InstantiationException JavaDoc e) {
345       throw new ChainedInstantiationException(
346         e,
347         _this_weaveableC,
348         "Cannot find the GenericFactory interface of the bootstrap " +
349         "component, which is needed to instantiate the template");
350     } catch (NoSuchInterfaceException e) {
351       throw new ChainedInstantiationException(
352         e,
353         _this_weaveableC,
354         "Cannot find the GenericFactory interface of the bootstrap " +
355         "component, which is needed to instantiate the template");
356     }
357     return factory.newFcInstance(fcInstanceType, fcContent[0], fcContent[1]);
358   }
359
360   // -------------------------------------------------------------------------
361
// Fields and methods required by the mixin class in the base class
362
// -------------------------------------------------------------------------
363

364   /**
365    * The <tt>weaveableC</tt> field required by this mixin. This field is
366    * supposed to reference the {@link Component} interface of the component to
367    * which this controller object belongs.
368    */

369
370   public Component _this_weaveableC;
371
372   /**
373    * The {@link Controller#initFcController initFcController} method overriden
374    * by this mixin.
375    *
376    * @param ic information about the component to which this controller object
377    * belongs.
378    * @throws InstantiationException if the initialization fails.
379    */

380
381   public abstract void _super_initFcController (InitializationContext ic)
382     throws InstantiationException JavaDoc;
383 }
384
Popular Tags