KickJava   Java API By Example, From Geeks To Geeks.

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


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.NoSuchInterfaceException;
28 import org.objectweb.fractal.api.Type;
29 import org.objectweb.fractal.api.factory.GenericFactory;
30 import org.objectweb.fractal.api.factory.InstantiationException;
31 import org.objectweb.fractal.api.type.ComponentType;
32 import org.objectweb.fractal.api.type.InterfaceType;
33 import org.objectweb.fractal.api.type.TypeFactory;
34
35 import org.objectweb.fractal.julia.Controller;
36 import org.objectweb.fractal.julia.InitializationContext;
37 import org.objectweb.fractal.julia.loader.Loader;
38 import org.objectweb.fractal.julia.loader.Tree;
39
40 import java.util.HashMap JavaDoc;
41 import java.util.List JavaDoc;
42 import java.util.Map JavaDoc;
43
44 /**
45  * Provides a basic implementation of the {@link GenericFactory} interface.
46  * <br>
47  * <br>
48  * <b>Requirements</b>
49  * <ul>
50  * <li>the types used in the {@link #newFcInstance newFcInstance} method must
51  * be instances of {@link ComponentType}.</li>
52  * <li>the controller descriptors used in the {@link #newFcInstance
53  * newFcInstance} method must be strings referencing "true descriptors", which
54  * are loaded with the {@link #_this_weaveableL} loader. Here "true descriptors"
55  * means controller descriptors as specified in {@link
56  * org.objectweb.fractal.julia.asm.ContextClassGenerator}.</li>
57  * </ul>
58  */

59
60 public class BasicGenericFactoryMixin implements GenericFactory {
61
62   // -------------------------------------------------------------------------
63
// PUBLIC constructor (needed for bootstrap)
64
// -------------------------------------------------------------------------
65

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

73   public Component newFcInstance (
74     final Type type,
75     final Object JavaDoc controllerDesc,
76     final Object JavaDoc contentDesc) throws InstantiationException JavaDoc
77   {
78     Object JavaDoc loader;
79     Object JavaDoc controller;
80     
81     if (controllerDesc instanceof Object JavaDoc[]) {
82       loader = getFcLoader(((Object JavaDoc[])controllerDesc)[0]);
83       controller = ((Object JavaDoc[])controllerDesc)[1];
84     } else {
85       loader = getFcLoader(null);
86       controller = controllerDesc;
87     }
88     
89     // generates the component descriptor
90
Tree typeTree = getFcTypeDescriptor(type);
91     Tree controllerTree = getFcControllerDescriptor(controller);
92     Tree contentTree = getFcContentDescriptor(contentDesc);
93     Tree componentTree = new Tree(new Tree[] {
94       new Tree("org.objectweb.fractal.julia.asm.ContextClassGenerator"),
95       typeTree,
96       controllerTree,
97       contentTree
98     });
99
100     // creates an instance of the corresponding class
101
// (a specific InitializationContext class for components of this kind)
102
Class JavaDoc initializationContextClass;
103     try {
104       initializationContextClass =
105         _this_weaveableL.loadClass(componentTree, loader);
106     } catch (Exception JavaDoc e) {
107       throw new ChainedInstantiationException(
108         e,
109         null,
110         "Cannot load the specific InitializationContext sub class " +
111         "needed to create the component");
112     }
113     InitializationContext initializationContext;
114     try {
115       initializationContext =
116         (InitializationContext)initializationContextClass.newInstance();
117     } catch (Exception JavaDoc e) {
118       throw new ChainedInstantiationException(
119         e,
120         null,
121         "Cannot create the specific InitializationContext object " +
122         "needed to create the component");
123     }
124
125     // initializes the initialization context itself
126
if (!(contentDesc instanceof String JavaDoc)) {
127       initializationContext.content = contentDesc;
128     }
129     initializationContext.hints = _this_weaveableTF;
130     initializationContext.create();
131
132     // initializes all the controller objects of the component
133
List JavaDoc controllers = initializationContext.controllers;
134     for (int i = 0; i < controllers.size(); ++i) {
135       Object JavaDoc o = controllers.get(i);
136       if (o instanceof Controller) {
137         ((Controller)o).initFcController(initializationContext);
138       }
139     }
140
141     // returns the Component interface of the component
142
try {
143       Component c = (Component)initializationContext.getInterface("component");
144       return (Component)c.getFcInterface("component");
145     } catch (NoSuchInterfaceException e) {
146       throw new ChainedInstantiationException(
147         e,
148         null,
149         "The created component does not provide the Component interface");
150     }
151   }
152
153   public Object JavaDoc getFcLoader (final Object JavaDoc loader) {
154     return loader;
155   }
156   
157   /**
158    * Returns a tree representing the given component type. This tree has the
159    * format specified in {@link
160    * org.objectweb.fractal.julia.asm.ContextClassGenerator}
161    *
162    * @param type a component type, must be instance of {@link ComponentType}.
163    * @return a tree representing the given component type.
164    * @throws InstantiationException if the given type is not an instance of
165    * {@link ComponentType}, or if it contains control interface types.
166    */

167
168   public Tree getFcTypeDescriptor (final Type type)
169     throws InstantiationException JavaDoc
170   {
171     // checks the type system
172
ComponentType compType;
173     try {
174       compType = (ComponentType)type;
175     } catch (ClassCastException JavaDoc e) {
176       throw new ChainedInstantiationException(
177         e, null, "The component type must be an instance of ComponentType");
178     }
179
180     // checks the component type
181
InterfaceType[] itfTypes = compType.getFcInterfaceTypes();
182     Tree[] itfTrees = new Tree[itfTypes.length];
183     for (int i = 0; i < itfTypes.length; i++) {
184       InterfaceType itfType = itfTypes[i];
185       String JavaDoc itfName = itfType.getFcItfName();
186       if (!itfName.equals("attribute-controller")) {
187         if (itfName.equals("component") || itfName.endsWith("-controller")) {
188           throw new ChainedInstantiationException(
189             null,
190             null,
191             "The component type must not contain control interface types");
192         }
193       }
194       itfTrees[i] = new Tree(new Tree[] {
195         new Tree(itfName),
196         new Tree(itfType.getFcItfSignature()),
197         new Tree(itfType.isFcClientItf() ? "true" : "false"),
198         new Tree(itfType.isFcOptionalItf() ? "true" : "false"),
199         new Tree(itfType.isFcCollectionItf() ? "true" : "false")
200       });
201     }
202
203     // returns the type descriptor
204
return new Tree(itfTrees);
205   }
206
207   /**
208    * Returns the tree corresponding to the given controller descriptor. This
209    * tree is found by using the {@link #_this_weaveableL} loader. It must have
210    * the format specified in {@link
211    * org.objectweb.fractal.julia.asm.ContextClassGenerator}
212    *
213    * @param controllerDesc a string referencing a true controller descriptor.
214    * @return the tree corresponding to the given controller descriptor.
215    * @throws InstantiationException if the tree cannot be loaded.
216    */

217
218   public Tree getFcControllerDescriptor (final Object JavaDoc controllerDesc)
219     throws InstantiationException JavaDoc
220   {
221     Map JavaDoc definitions = new HashMap JavaDoc();
222     definitions.put("attributeControllerInterface", new Tree("QUOTE"));
223     definitions.put("interfaceName", new Tree("QUOTE"));
224     try {
225       return _this_weaveableL.evalTree(
226         _this_weaveableL.loadTree((String JavaDoc)controllerDesc), definitions);
227     } catch (Exception JavaDoc e) {
228       throw new ChainedInstantiationException(
229         e,
230         null,
231         "Cannot load the '" + controllerDesc + "' controller descriptor");
232     }
233   }
234
235   /**
236    * Returns the tree corresponding to the given content descriptor. This tree
237    * has the format specified in {@link
238    * org.objectweb.fractal.julia.asm.ContextClassGenerator}
239    *
240    * @param contentDesc a content descriptor.
241    * @return the tree corresponding to the given content descriptor.
242    */

243
244   public Tree getFcContentDescriptor (final Object JavaDoc contentDesc) {
245     if (contentDesc instanceof String JavaDoc) {
246       return new Tree((String JavaDoc)contentDesc);
247     } else if (contentDesc != null && !(contentDesc instanceof Object JavaDoc[])) {
248       return new Tree(contentDesc.getClass().getName());
249     } else {
250       return new Tree("EMPTY");
251     }
252   }
253
254   // -------------------------------------------------------------------------
255
// Fields and methods required by the mixin class in the base class
256
// -------------------------------------------------------------------------
257

258   /**
259    * The <tt>weaveableL</tt> field required by this mixin. This field is
260    * supposed to reference the {@link Loader} interface of the component to
261    * which this controller object belongs.
262    */

263
264   public Loader _this_weaveableL;
265
266   /**
267    * The <tt>weaveableTF</tt> field required by this mixin. This field is
268    * supposed to reference the {@link TypeFactory} interface of the component to
269    * which this controller object belongs.
270    */

271
272   public TypeFactory _this_weaveableTF;
273 }
274
Popular Tags