KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > core > ACConfiguration


1 /*
2   Copyright (C) 2001-2003 Renaud Pawlak <renaud@aopsys.com>
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12   GNU Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public
15   License along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17   USA */

18
19 package org.objectweb.jac.core;
20
21
22 import java.io.Serializable JavaDoc;
23 import java.lang.reflect.Array JavaDoc;
24 import java.net.URL JavaDoc;
25 import org.apache.log4j.Logger;
26 import org.objectweb.jac.aspects.gui.Length;
27 import org.objectweb.jac.core.rtti.*;
28 import org.objectweb.jac.util.Classes;
29 import org.objectweb.jac.util.Strings;
30
31 /**
32  * This class defines aspect component configurations so that the
33  * programmer or the system administrator will be able to configure
34  * the available aspects for a given application.
35  *
36  * <p>The default available aspects in the system are the ones that
37  * are declared to the AC manager in the <code>jac.prop</code> (see
38  * the <code>org.objectweb.jac.acs</code> property).
39  *
40  * @see ApplicationRepository
41  * @see Application
42  * @see Parser
43  * @see ACManager
44  */

45
46 public class ACConfiguration implements Serializable JavaDoc {
47     static Logger logger = Logger.getLogger("jac");
48     static Logger loggerAspects = Logger.getLogger("aspects");
49     static Logger loggerConf = Logger.getLogger("aspects.config");
50     static Logger loggerPerf = Logger.getLogger("perf");
51
52     /** The application this configuration belongs to. */
53     protected Application application;
54     /** The name of the configured AC. */
55     protected String JavaDoc name;
56     /** The aspect component that corresponds to this configuration
57         once instantiated (null before). This is a local aspect
58         component. */

59     transient AspectComponent instance = null;
60    
61     /** The configuration file's URL. */
62     protected URL JavaDoc filePath;
63
64     String JavaDoc acPath = null;
65
66     /**
67      * Sets the URL of the configuration file that defines the
68      * configuration operations.
69      *
70      * @param filePath a valid file path
71      * @see #getURL() */

72
73     public void setURL(URL JavaDoc filePath) {
74         this.filePath = filePath;
75     }
76
77     /**
78      * The getter of the configuration file's URL.
79      *
80      * @return the URL
81      * @see #setURL(URL) */

82
83     public URL JavaDoc getURL() {
84         return filePath;
85     }
86
87     /**
88      * This flag tells if the aspect that is configured by the current
89      * configuration will be woven on demand (by the administrator or
90      * by a configuration program) or if the aspect will be
91      * automatically woven and restored by the system.
92      *
93      * <p>For instance, a persistence aspect should always have this
94      * configuration flag to false whilst a debugging aspect should
95      * most of the time be woven on demand (when debugging is
96      * needed). */

97
98     protected boolean weaveOnDemand = true;
99    
100     /**
101      * Gets the <code>weaveOnDemand</code> flag value.
102      * @return the flag value */

103
104     public boolean getWeaveOnDemand() {
105         return weaveOnDemand;
106     }
107    
108     /**
109      * Sets the <code>weaveOnDemand</code> flag value.
110      * @param b the new flag value */

111
112     public void setWeaveOnDemand(boolean b) {
113         weaveOnDemand = b;
114     }
115
116     /**
117      * Creates a new aspect component configuration.
118      *
119      * @param application the application this configuration belongs to
120      * @param name the name of the AC as defined in the declared ACs of
121      * the AC manager, or the of the aspect component's class
122      * @param filePath the path of the configuration file; it can be
123      * absolute but, if relative, it is automatically concatened to the
124      * application's path
125      * @param weaveNow a true value means that the aspect that
126      * configured by this configuration will be automatically woven at
127      * the application's start, a false value means that the user will
128      * have to weave it with a program (or with the administration
129      * GUI); default is true */

130
131     public ACConfiguration(Application application, String JavaDoc name,
132                            String JavaDoc filePath, boolean weaveNow) {
133         this.name = name;
134         this.application = application;
135         this.weaveOnDemand = ! weaveNow;
136         if (filePath!=null) {
137             try {
138                 if (filePath.startsWith("file:")) {
139                     filePath = filePath.substring(5);
140                 }
141                 this.filePath = new URL JavaDoc("file:"+filePath);
142             } catch (Exception JavaDoc e) {
143                 e.printStackTrace();
144             }
145         }
146
147         // If name is not the name of a registered AC,
148
// It must be the class name of the AC
149
ACManager acm = ACManager.getACM();
150         if (!acm.isACDeclared(name)) {
151             acm.declareAC(name,name);
152         }
153     }
154
155     /**
156      * Gets the name of the configured AC as defined in the declared
157      * ACs of the AC manager.
158      *
159      * @return the AC name
160      * @see #setName(String)
161      * @see ACManager */

162
163     public String JavaDoc getName() {
164         return name;
165     }
166
167     /**
168      * The aspect name setter. Must be declared in the
169      * <code>jac.prop</code>.
170      *
171      * @param name the aspect name
172      * @see ACManager */

173
174     public void setName(String JavaDoc name) {
175         this.name = name;
176     }
177    
178     /**
179      * Gets the aspect component instance that corresponds to this
180      * configuration.
181      *
182      * @return the AC instance */

183
184     public AspectComponent getInstance() {
185         return instance;
186     }
187
188     /**
189      * Gets the owning application.
190      *
191      * @return the application that owns this configuration */

192
193     public Application getApplication() {
194         return application;
195     }
196
197     /**
198      * Return the class item for the configured aspect component.
199      *
200      * @return the AC type */

201
202     public ClassItem getAspectClass() {
203         String JavaDoc acPath = ((ACManager)ACManager.get()).getACPathFromName(name);
204         return ClassRepository.get().getClass(acPath);
205     }
206
207     /**
208      * Instantiates a new aspect component.
209      *
210      * @return the new aspect component, null if something went wrong
211      */

212
213     protected AspectComponent instantiate() {
214         loggerAspects.debug("instantiating "+name);
215         ACManager acm = (ACManager)ACManager.get();
216         // String oldAC = Collaboration.get().getCurAC();
217
// Collaboration.get().setCurAC(
218
// getApplication().getName() + "." + name );
219
try {
220             instance = (AspectComponent) acm.getObject(
221                 application.getName()+"."+name);
222             if (instance == null) {
223                 if (acPath == null)
224                     acPath = acm.getACPathFromName(name);
225                 loggerAspects.debug(name + " : " + acPath);
226                 if( acPath == null ) return null;
227                 Class JavaDoc cl = Class.forName( acPath );
228                 loggerAspects.debug("instantiating "+cl);
229                 instance = (AspectComponent) cl.newInstance();
230                 instance.setApplication(getApplication().getName());
231             }
232             return instance;
233         } catch(Exception JavaDoc e) {
234             e.printStackTrace();
235             return null;
236         } finally {
237             // Collaboration.get().setCurAC(oldAC);
238
}
239     }
240
241     /**
242      * Configures the aspect component.
243      *
244      * <p>This method takes the aspect component instance that corresponds
245      * to this configuration, parse the configuration file, and calls
246      * all the configuration operations that are defined in this file.
247      *
248      * @see Parser
249      * @see #getInstance() */

250
251
252     protected void configure() {
253         logger.info("--- configuring "+name+" aspect ---");
254         long start = System.currentTimeMillis();
255         String JavaDoc[] defaults = instance.getDefaultConfigs();
256         for (int i=0; i<defaults.length; i++) {
257             instance.configure(name,defaults[i]);
258         }
259         instance.configure(name,filePath.getFile());
260         instance.whenConfigured();
261         loggerPerf.info("aspect "+name+" configured in "+
262                         (System.currentTimeMillis()-start)+"ms");
263     }
264
265     public static Object JavaDoc convertArray(Object JavaDoc[] array, Class JavaDoc componentType, Imports imports)
266         throws Exception JavaDoc
267     {
268         Object JavaDoc result = Array.newInstance(componentType, array.length);
269         for (int i=0; i<array.length; i++) {
270             Array.set(result,i,convertValue(array[i],componentType,imports));
271         }
272         return result;
273     }
274
275     public static Object JavaDoc convertValue(Object JavaDoc object, Class JavaDoc type)
276         throws Exception JavaDoc
277     {
278         return convertValue(object,type,null);
279     }
280
281     public static Object JavaDoc convertValue(Object JavaDoc object, Class JavaDoc type, Imports imports)
282         throws Exception JavaDoc
283     {
284         Object JavaDoc result = object;
285         if (object != null && object.getClass() != type) {
286             try {
287                 if (type.isArray()) {
288                     result = convertArray((Object JavaDoc[])object,type.getComponentType(),imports);
289                 } else if (type==double.class || type==Double JavaDoc.class) {
290                     result = new Double JavaDoc((String JavaDoc)object);
291                 } else if (type==int.class || type==Integer JavaDoc.class) {
292                     result = new Integer JavaDoc((String JavaDoc)object);
293                 } else if (type==long.class || type==Long JavaDoc.class) {
294                     result = new Long JavaDoc((String JavaDoc)object);
295                 } else if (type==float.class || type==Float JavaDoc.class) {
296                     result = new Float JavaDoc((String JavaDoc)object);
297                 } else if (type==boolean.class || type==Boolean JavaDoc.class) {
298                     result = Boolean.valueOf((String JavaDoc)object);
299                 } else if (type==short.class || type==Short JavaDoc.class) {
300                     result = new Short JavaDoc((String JavaDoc)object);
301                 } else if (type==Class JavaDoc.class) {
302                     result = Class.forName((String JavaDoc)object);
303                 } else if (type==ClassItem.class) {
304                     result = getClass((String JavaDoc)object,imports);
305                 } else if (type==VirtualClassItem.class) {
306                     result = ClassRepository.get().getVirtualClassStrict((String JavaDoc)object);
307                 } else if (AbstractMethodItem.class.isAssignableFrom(type)) {
308                     String JavaDoc str = (String JavaDoc)object;
309                     int index = str.indexOf("(");
310                     try {
311                         ClassItem classItem;
312                         if (index==-1) {
313                             classItem = getClass(str,imports);
314                             result = classItem.getConstructor("");
315                         } else {
316                             classItem = getClass(
317                                 str.substring(0,index),imports);
318
319                             // resolve parameter types
320
String JavaDoc[] paramTypes =
321                                 Strings.split(str.substring(index+1,str.length()-1), ",");
322                             resolveTypes(paramTypes,imports);
323                             String JavaDoc fullName = str.substring(0,index+1)+Strings.join(paramTypes,",")+")";
324                             result = classItem.getConstructor(fullName.substring(index));
325                         }
326                     } catch (NoSuchClassException e) {
327                         if (index!=-1) {
328                             // resolve parameter types
329
String JavaDoc[] paramTypes =
330                                 Strings.split(str.substring(index+1,str.length()-1), ",");
331                             resolveTypes(paramTypes,imports);
332                             str = str.substring(0,index+1)+Strings.join(paramTypes,",")+")";
333                             index = str.lastIndexOf(".",index);
334                         } else {
335                             index = str.lastIndexOf(".");
336                         }
337                         if (index!=-1) {
338                             try {
339                                 ClassItem classItem = getClass(
340                                     str.substring(0,index),imports);
341                                 result = classItem.getAbstractMethod(
342                                     str.substring(index+1));
343                             } catch (NoSuchClassException e2) {
344                                 throw new Exception JavaDoc("Failed to convert "+str+
345                                                     " into a "+type.getName());
346                             }
347                         } else {
348                             throw new Exception JavaDoc("Failed to convert "+str+
349                                                 " into a "+type.getName());
350                         }
351                     }
352                 } else if (FieldItem.class.isAssignableFrom(type)) {
353                     String JavaDoc str = (String JavaDoc)object;
354                     loggerConf.debug("Trying to convert "+str+" into a FieldItem");
355                     int index = str.length();
356                     result = null;
357                     while (index!=-1 && result==null) {
358                         index = str.lastIndexOf(".",index-1);
359                         if (index!=-1) {
360                             try {
361                                 loggerConf.debug(
362                                     " Trying class="+str.substring(0,index)+
363                                     " and field="+str.substring(index+1));
364                                 ClassItem classItem = getClass(
365                                     str.substring(0,index),imports);
366                                 result = classItem.getField(str.substring(index+1));
367                                 loggerConf.debug(" -> "+result);
368                             } catch (NoSuchClassException e) {
369                                 loggerConf.info(
370                                     " Failed conversion of "+object+
371                                     " to FieldItem with class="+str.substring(0,index)+
372                                     " and field="+str.substring(index+1));
373                             }
374                         }
375                     }
376                     if (index==-1 || result==null) {
377                         throw new Exception JavaDoc("Failed to convert "+str+
378                                             " into a "+type.getName());
379                     }
380                 } else if (MemberItem.class.isAssignableFrom(type)) {
381                     String JavaDoc str = (String JavaDoc)object;
382                     int index = -1;
383                     int paren = str.indexOf("(");
384                     if (paren==-1)
385                         index = str.length();
386                     else
387                         index = paren;
388
389                     result = null;
390                     while (index!=-1 && result==null) {
391                         index = str.lastIndexOf(".",index-1);
392                         if (index!=-1) {
393                             try {
394                                 ClassItem classItem = getClass(
395                                     str.substring(0,index),imports);
396                                 result = classItem.getMember(str.substring(index+1));
397                             } catch (NoSuchClassException e) {
398                             }
399                         }
400                     }
401
402                     if (index==-1 || result==null) {
403                         throw new Exception JavaDoc("Failed to convert "+str+
404                                             " into a "+type.getName());
405                     }
406                 } else if (type == Length.class) {
407                     return new Length((String JavaDoc)object);
408                 } else {
409                     throw new Exception JavaDoc("Don't know how to convert "+object+" into a "+type);
410                 }
411             } catch (Exception JavaDoc e) {
412                 loggerConf.info("Failed to convert "+object+" into "+type.getName(),e);
413                 throw new Exception JavaDoc(
414                     "Failed to convert "+object+" into "+type.getName()+" : "+e);
415             }
416         }
417         loggerConf.debug("Converted "+object+" into "+type+": "+result);
418         return result;
419     }
420
421     protected static void resolveTypes(String JavaDoc[] types, Imports imports) {
422         for (int i=0; i<types.length; i++) {
423             String JavaDoc type = types[i];
424             boolean isArray = false;
425             if (type.endsWith("[]")) {
426                 type = type.substring(0,type.length()-2);
427             }
428             try {
429                 if (isArray)
430                     types[i] =
431                         imports.getClass(
432                             types[i].substring(0,types[i].length()-2)).getName()+"[]";
433                 else
434                     types[i] = imports.getClass(types[i]).getName();
435             } catch (NoSuchClassException nse) {
436                 if (!Classes.isPrimitiveType(type))
437                     throw nse;
438             }
439         }
440     }
441
442     protected static ClassItem getClass(String JavaDoc name, Imports imports) {
443         if (imports!=null) {
444             try {
445                 return imports.getClass(name);
446             } catch (NoSuchClassException e) {
447                 return ClassRepository.get().getClass(name);
448             }
449         } else {
450             return ClassRepository.get().getClass(name);
451         }
452     }
453
454     /**
455      * Instantiates, configures, and weaves the aspect component that
456      * corresponds to this configuration.
457      *
458      * @see #instantiate()
459      * @see #configure()
460      */

461     public void weave() {
462         //acs.put( acName, ac );
463
instantiate();
464         if (instance == null) {
465             logger.error("could not instantiate aspect "+name);
466             return;
467         }
468         try {
469             instance.beforeConfiguration();
470             configure();
471         } catch (Exception JavaDoc e) {
472             e.printStackTrace();
473             return;
474         }
475         loggerAspects.debug(
476             "registering " + instance +
477             " on application " + getApplication() );
478         // This line is useful for composite aspects
479
instance.doRegister();
480         ACManager.get().register( getApplication().getName() +
481                                   "." + name, instance );
482     }
483
484     /**
485      * Unweaves the aspect component that corresponds to this
486      * configuration.
487      */

488     public void unweave() {
489         // This line is useful for composite aspects
490
instance.doUnregister();
491         ((ACManager)ACManager.get()).unregister( application.getName() + "." + name );
492         instance = null;
493     }
494
495     /**
496      * Returns a string representation of this configuration.
497      * @return a string
498      */

499     public String JavaDoc toString() {
500         return "AC " + name + " configuration";
501     }
502
503 }
504
Popular Tags