KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jfun > yan > xml > NutsProcessor


1 package jfun.yan.xml;
2
3 import java.beans.IntrospectionException JavaDoc;
4 import java.beans.PropertyEditor JavaDoc;
5 import java.beans.PropertyEditorManager JavaDoc;
6 import java.io.File JavaDoc;
7 import java.io.IOException JavaDoc;
8 import java.io.InputStream JavaDoc;
9 import java.net.URL JavaDoc;
10 import java.util.ArrayList JavaDoc;
11 import java.util.Arrays JavaDoc;
12 import java.util.Comparator JavaDoc;
13 import java.util.HashMap JavaDoc;
14 import java.util.Hashtable JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Map JavaDoc;
18 import java.util.Set JavaDoc;
19
20
21
22 import jfun.util.Misc;
23 import jfun.util.dict.Dict;
24 import jfun.util.dict.DictFactory;
25 import jfun.yan.Component;
26 import jfun.yan.Components;
27 import jfun.yan.Container;
28 import jfun.yan.Creator;
29 import jfun.yan.ParameterBinder;
30 import jfun.yan.PropertyBinder;
31 import jfun.yan.Registrar;
32 import jfun.yan.containers.ManualContainer;
33 import jfun.yan.factory.Factory;
34 import jfun.yan.lifecycle.DefaultLifecycleManager;
35 import jfun.yan.util.deserializer.Deserializer;
36 import jfun.yan.util.resource.ClassLoader2ResourceLoader;
37 import jfun.yan.util.resource.ResourceLoader;
38 import jfun.yan.xml.nut.Nut;
39 import jfun.yan.xml.nut.NutDescriptor;
40 import jfun.yan.xml.nut.NutIntrospector;
41
42
43 import org.xml.sax.InputSource JavaDoc;
44
45
46 /**
47  * The main class that parses an xml config file and populates
48  * container and lifecycle manager with the information stored
49  * in the config file.
50  * <p>
51  * @author Ben Yu
52  *
53  */

54 public class NutsProcessor implements java.io.Serializable JavaDoc{
55   private Map JavaDoc getDeserializers(){
56     final Map JavaDoc deserializers = NutsUtils.getDeserializers();
57     deserializers.put(File JavaDoc.class, new Deserializer(){
58       public Object JavaDoc deserialize(String JavaDoc str) throws Exception JavaDoc {
59         return NutsUtils.toFile(getBaseDir(), str);
60       }
61     });
62     deserializers.put(Class JavaDoc.class, new Deserializer(){
63       public Object JavaDoc deserialize(String JavaDoc str) throws Exception JavaDoc {
64         return MyUtil.getClass(getClassLoader(), str);
65       }
66     });
67     deserializers.put(URL JavaDoc.class, new Deserializer(){
68       public Object JavaDoc deserialize(String JavaDoc str) throws Exception JavaDoc {
69         return NutsUtils.toUrl(getBaseDir(), str);
70       }
71     });
72     deserializers.put(SingletonMode.class, new SingletonModeEditor());
73     return deserializers;
74   }
75   private final DefaultLifecycleManager manager;
76   private final Container yan;
77   private final ClassLoader JavaDoc cloader;
78   private final ResourceLoader rloader;
79   private final File JavaDoc basedir;
80   private final Map JavaDoc deserializers = getDeserializers();
81   private final Map JavaDoc services = new Hashtable JavaDoc();
82   private final Map JavaDoc external_nuts = new Hashtable JavaDoc();
83   private final Map JavaDoc eager_instantiations = new Hashtable JavaDoc();
84   private final Map JavaDoc variables = new Hashtable JavaDoc();
85   private ParameterBinder param_wiring = null;
86   private PropertyBinder prop_wiring = null;
87   private SingletonMode singleton_mode = Modes.simple_singleton;
88   private static final NutIntrospector introspector = new NutIntrospector();
89   private static final class CustomWiringModes implements AutoWiringMap{
90     private final Map JavaDoc prop_wiring_modes = new Hashtable JavaDoc();
91     private final Map JavaDoc param_wiring_modes = new Hashtable JavaDoc();
92     void addWiringMode(String JavaDoc name, ParameterBinder pmode){
93       param_wiring_modes.put(canonicalize(name),
94           pmode);
95     }
96     void addWiringMode(String JavaDoc name, PropertyBinder pmode){
97       prop_wiring_modes.put(canonicalize(name), pmode);
98     }
99     private static String JavaDoc canonicalize(String JavaDoc name){
100       return NutsUtils.canonicalizeAttributeName(name);
101     }
102     public ParameterBinder getParameterWiringMode(String JavaDoc mode_name) {
103       return (ParameterBinder)param_wiring_modes.get(canonicalize(mode_name));
104     }
105     public PropertyBinder getPropertyWiringMode(String JavaDoc mode_name) {
106       return (PropertyBinder)prop_wiring_modes.get(canonicalize(mode_name));
107     }
108   }
109   private final CustomWiringModes custom_wiring_modes = new CustomWiringModes();
110   private Interpreter createInterpreter(){
111     return new Interpreter(this, getInitialFrame(), this.getInitialCompileContext());
112   }
113   private Dict bindVariables(Dict ctxt){
114     synchronized(variables){
115       final Object JavaDoc[] keys = variables.keySet().toArray();
116       final Object JavaDoc[] vals = new Object JavaDoc[keys.length];
117       for(int i=0; i<keys.length; i++){
118         vals[i] = variables.get(keys[i]);
119       }
120       return ctxt.puts(keys, vals);
121       //.put(Constants.THIS_CONTAINER, Components.thisContainer());
122
}
123   }
124   private Dict getInitialFrame(){
125     return bindVariables(DictFactory.safeInstance().put(Constants.NULL, null));
126   }
127   private Dict getInitialCompileContext(){
128     return bindVariables(DictFactory.instance()
129       .put(Constants.NULL, MyUtil.value(null, new Location("SYSTEM", 0, 0)))
130     );
131   }
132   private String JavaDoc[] processModule(Module module){
133     module.register(toRegistry(yan));
134     registerDynamics(this.yan);
135     return (String JavaDoc[])module.getDependencies().clone();
136   }
137   /**
138    * Create a NutsProcessor object.
139    * <p>
140    * The ClassLoader object that loads this class
141    * is used to load the nut classes and the component classes.
142    * </p>
143    */

144   public NutsProcessor(){
145     this(NutsProcessor.class.getClassLoader());
146   }
147   /**
148    * Create an NutsProcessor object.
149    * @param classloader the ClassLoader object to load component classes and resources.
150    */

151   public NutsProcessor(ClassLoader JavaDoc classloader){
152     this(classloader, new ClassLoader2ResourceLoader(classloader));
153   }
154   /**
155    * Create an NutsProcessor object.
156    * @param classloader the ClassLoader object to load component classes.
157    * @param rloader the ResourceLoader object to load resources.
158    */

159   public NutsProcessor(ClassLoader JavaDoc classloader, ResourceLoader rloader){
160     this(classloader, rloader, new ManualContainer());
161   }
162   /**
163    * Create an NutsProcessor object.
164    * @param cloader the ClassLoader object to load component classes and resources.
165    * @param yan the container that registers the components.
166    * @param manager the life cycle manager.
167    * @param basedir the base directory against which relative paths
168    * found in the config file can be resolved.
169    */

170   public NutsProcessor(ClassLoader JavaDoc cloader, Container yan,
171       DefaultLifecycleManager manager,
172       File JavaDoc basedir) {
173     this(cloader, new ClassLoader2ResourceLoader(cloader), yan, manager, basedir);
174   }
175   /**
176    * Create an NutsProcessor object.
177    * @param cloader the ClassLoader object to load component classes.
178    * @param rloader the ResourceLoader object to load resources.
179    * @param yan the container that registers the components.
180    * @param manager the life cycle manager.
181    * @param basedir the base directory against which relative paths
182    * found in the config file can be resolved.
183    */

184   public NutsProcessor(ClassLoader JavaDoc cloader, ResourceLoader rloader,
185       Container yan,
186       DefaultLifecycleManager manager,
187       File JavaDoc basedir) {
188     this.basedir = basedir;
189     this.cloader = cloader;
190     this.rloader = rloader;
191     this.manager = manager;
192     this.yan = yan;
193     this.variables.put(Constants.THIS_CONTAINER, Components.thisContainer());
194     this.variables.put(Constants.RESOURCE_LOADER, rloader);
195   }
196   /**
197    * Create an NutsProcessor object.
198    * @param cloader the ClassLoader to load the component classes and resources.
199    * @param yan the container that registeres the components.
200    */

201   public NutsProcessor(ClassLoader JavaDoc cloader, Container yan){
202     this(cloader, new ClassLoader2ResourceLoader(cloader), yan);
203   }
204   /**
205    * Create an NutsProcessor object.
206    * @param cloader the ClassLoader to load the component classes.
207    * @param rloader the ResourceLoader to load resources.
208    * @param yan the container that registeres the components.
209    */

210   public NutsProcessor(ClassLoader JavaDoc cloader, ResourceLoader rloader,
211       Container yan){
212     this(cloader, rloader, yan,
213         new DefaultLifecycleManager(), new File JavaDoc(".").getAbsoluteFile());
214   }
215   /**
216    * Convert a string literal to an object of a certain type.
217    * A PropertyEditor is searched if the deserialization of the target type
218    * is not supported by the framework by default.
219    * @param type the target type.
220    * @param v the string literal.
221    * @return the object of the target type.
222    * @throws Throwable when any error happens.
223    */

224   public Object JavaDoc deserialize(Class JavaDoc type, String JavaDoc v)
225   throws Throwable JavaDoc{
226     final Deserializer des = (Deserializer)deserializers.get(type);
227     if(des != null) return des.deserialize(v);
228     else{
229       final PropertyEditor JavaDoc editor = PropertyEditorManager.findEditor(type);
230       if(editor==null){
231         throw new IllegalArgumentException JavaDoc("cannot convert to "+
232           Misc.getTypeName(type));
233       }
234       else{
235         editor.setAsText(v);
236         return editor.getValue();
237       }
238     }
239   }
240   /**
241    * To determine if string literal can be converted to the target type.
242    * PropertyEditor is also searched if the type is not by default
243    * deserializable by the framework
244    * @param type the target type.
245    * @return true if convertible.
246    */

247   public boolean isDeserializable(Class JavaDoc type){
248     return type.isAssignableFrom(String JavaDoc.class)
249       || deserializers.get(type)!=null
250       || PropertyEditorManager.findEditor(type)!=null;
251   }
252   private synchronized String JavaDoc[] process(Object JavaDoc id, final InputSource JavaDoc in)
253   throws IOException JavaDoc{
254     return processModule(createInterpreter()
255         .interpret(id, in));
256   }
257   /**
258    * Process a resource from the component class loader as an xml configuration.
259    * @param resourcename the resource name.
260    * @return an array of dependency names that the module requires
261    * to be present in the container in order for the module to
262    * wire up properly.
263    * An empty array is returned if there's no dependency required.
264    * @throws IOException when resource reading fails.
265    */

266   public synchronized String JavaDoc[] processResource(final String JavaDoc resourcename)
267   throws IOException JavaDoc{
268     return processModule(createInterpreter()
269         .interpretResource(resourcename));
270   }
271   /**
272    * Process a config file.
273    * @param filename the configuration file name.
274    * @return an array of dependency names that the module requires
275    * to be present in the container in order for the module to
276    * wire up properly.
277    * An empty array is returned if there's no dependency required.
278    * @throws IOException if file reading fails.
279    */

280   public synchronized String JavaDoc[] processFile(String JavaDoc filename)
281   throws IOException JavaDoc{
282     return processFile(new File JavaDoc(filename));
283     //processModule(createInterpreter().interpretFile(filename));
284
}
285   /**
286    * Process a config file.
287    * @param file the configuration file.
288    * @return an array of dependency names that the module requires
289    * to be present in the container in order for the module to
290    * wire up properly.
291    * An empty array is returned if there's no dependency required. An empty array is returned if there's no dependency required.
292    * @throws IOException if file reading fails.
293    */

294   public synchronized String JavaDoc[] processFile(File JavaDoc file)
295   throws IOException JavaDoc{
296     return processModule(createInterpreter()
297         .interpretFile(file));
298   }
299   /**
300    * Process bytes read from an InputStream.
301    * @param id the module id.
302    * @param in the InputStream object.
303    * @return an array of dependency names that the module requires
304    * to be present in the container in order for the module to
305    * wire up properly.
306    * An empty array is returned if there's no dependency required.
307    * @throws IOException any io error.
308    */

309   public synchronized String JavaDoc[] process(Object JavaDoc id, InputStream JavaDoc in)
310   throws IOException JavaDoc{
311     return processModule(createInterpreter().interpret(id, in));
312   }
313   /**
314    * Pre-initialize eagerly instantiated components.
315    * @param container the container to resolve dependency for these components.
316    * @param store the Map object to collect the instantiated results.
317    * The map key is {@link UID}, which is a combination of the module id and the component id.
318    * @return reference to the Map object.
319    */

320   public Map JavaDoc preInstantiate(Container container, Map JavaDoc store){
321     final UID[] keys = getOrderedUIDs();
322     for(int i=0; i<keys.length; i++){
323       final UID key = keys[i];
324       final Creator c = (Creator)eager_instantiations.get(key);
325       store.put(key, container.instantiateComponent(key, c));
326     }
327     return store;
328   }
329   /**
330    * Pre-initialize eagerly instantiated components.
331    * @param container the container to resolve dependency for these components.
332    * @return the Map object to collect the instantiated results.
333    * The map key is {@link UID}, which is a combination of the module id and the component id.
334    */

335   public Map JavaDoc preInstantiate(Container container){
336     return preInstantiate(container, new HashMap JavaDoc());
337   }
338   /**
339    * Pre-initialize eagerly instantiated components.
340    * @param store the Map object to collect the instantiated results.
341    * The map key is {@link UID}, which is a combination of the module id and the component id.
342    * @return reference to the Map object.
343    */

344   public Map JavaDoc preInstantiate(Map JavaDoc store){
345     return preInstantiate(yan, store);
346   }
347   /**
348    * Pre-initialize eagerly instantiated components.
349    * @return the Map object to collect the instantiated results.
350    * The map key is {@link UID}, which is a combination of the module id and the component id.
351    */

352   public Map JavaDoc preInstantiate(){
353     return preInstantiate(yan);
354   }
355   /**
356    * To get the lifecycle manager used by this processor.
357    */

358   public DefaultLifecycleManager getLifecycleManager() {
359     return manager;
360   }
361   /**
362    * To get the container used by this processor.
363    */

364   public Container getContainer() {
365     return yan;
366   }
367   /**
368    * To get the base directory used by the processor.
369    */

370   public File JavaDoc getBaseDir() {
371     return basedir;
372   }
373
374   /**
375    * To get the ClassLoader used to load component classes.
376    */

377   public ClassLoader JavaDoc getClassLoader() {
378     return cloader;
379   }
380   /**
381    * To get the ResourceLoader used to load resources.
382    */

383   public ResourceLoader getResourceLoader(){
384     return rloader;
385   }
386   /**
387    * Register a property autowiring mode. Any existent mode or predefined mode
388    * with the same name will be overriden.
389    * @param mode_name the mode name.
390    * @param mode the PropertyBinder object encapsulating the autowiring logic.
391    */

392   public void registerAutoWiring(String JavaDoc mode_name, PropertyBinder mode){
393     custom_wiring_modes.addWiringMode(mode_name, mode);
394   }
395   /**
396    * Register a parameter autowiring mode. Any existent mode or predefined mode
397    * with the same name will be overriden.
398    * @param mode_name the mode name.
399    * @param mode the ParameterBinder object encapsulating the autowiring logic.
400    */

401   public void registerAutoWiring(String JavaDoc mode_name, ParameterBinder mode){
402     custom_wiring_modes.addWiringMode(mode_name, mode);
403   }
404   /**
405    * To register a Deserializer.
406    * @param type the type that uses the Deserializer to convert
407    * literal string to objects of this type.
408    * @param deserializer the Deserializer object.
409    * @param overriding whether override the existent Deserializer if any.
410    * @param mandatory true if this registration has to go through.
411    * @exception IllegalArgumentException if the registration is mandatory but not overriding
412    * and an Deserializer object is already registered for the target type.
413    */

414   public void registerDeserializer(Class JavaDoc type, Deserializer deserializer,
415       boolean overriding, boolean mandatory)
416   throws IllegalArgumentException JavaDoc{
417     if(!overriding){
418       if(deserializers.containsKey(type)){
419         if(mandatory){
420           throw new IllegalArgumentException JavaDoc("Deserializer for "
421               + type + " already exists");
422         }
423         else return;
424       }
425     }
426     deserializers.put(type, deserializer);
427   }
428   /**
429    * To find the service object registered using
430    * {@link #registerService(Object, Object)}.
431    * @param key the key to the service object.
432    * @return the service object.
433    * null is returned if no object is registered under this key.
434    */

435   public Object JavaDoc findService(Object JavaDoc key){
436     return services.get(key);
437   }
438   /**
439    * To register a service object that can be read by customized Nuts classes
440    * through the call of {@link NutEnvironment#findService(Object)}.
441    * <p>
442    * register and unregister are thread safe.
443    * </p>
444    * @param key the service key.
445    * @param service the service object.
446    */

447   public void registerService(Object JavaDoc key, Object JavaDoc service){
448     services.put(key, service);
449   }
450   /**
451    * To unregister a service object. No-op if the key is not found.
452    * @param key the key of the service object.
453    */

454   public void unregisterService(Object JavaDoc key){
455     services.remove(key);
456   }
457   /**
458    * Get the set of the keys of the service objects.
459    */

460   public Set JavaDoc getServiceKeys(){
461     return services.keySet();
462   }
463   
464   /**
465    * Add an external nut descriptor for the processor to use.
466    * @param key the key of the nut.
467    * @param desc the descriptor.
468    */

469   public void registerNut(String JavaDoc key, NutDescriptor desc){
470     external_nuts.put(key, desc);
471   }
472   /**
473    * Get a NutDescriptor registered by putNut().
474    * @param key the key of the NutDescriptor.
475    * @return the NutDescriptor object.
476    * Null is returned if the key is not found.
477    */

478   public NutDescriptor findNut(String JavaDoc key){
479     return (NutDescriptor)external_nuts.get(key);
480   }
481   /**
482    * Unregister a NutDescriptor.
483    * @param key the key of the NutDescriptor.
484    */

485   public void removeNut(String JavaDoc key){
486     external_nuts.remove(key);
487   }
488   /**
489    * Register a variable that can be referenced in the xml file
490    * using "$varname" syntax.
491    * @param key the variable name.
492    * @param val the variable value.
493    */

494   public void registerVariable(String JavaDoc key, Object JavaDoc val){
495     variables.put(key, val);
496   }
497   /**
498    * To get a variable value.
499    * @param key the variable name.
500    * @return the variable value. Or null if not found.
501    */

502   public Object JavaDoc getVariable(String JavaDoc key){
503     return variables.get(key);
504   }
505   /**
506    * Checks whether a variable name exists.
507    * @param key the variable name.
508    */

509   public boolean hasVariable(String JavaDoc key){
510     return variables.containsKey(key);
511   }
512   /**
513    * To remove a registration of a variable.
514    * @param key the variable name.
515    */

516   public void removeVariable(String JavaDoc key){
517     variables.remove(key);
518   }
519   /**
520    * Get the set of keys of Nut descriptors.
521    */

522   public Set JavaDoc getNutKeys(){
523     return external_nuts.keySet();
524   }
525   /**
526    * Get the default parameter auto wiring mode.
527    */

528   public synchronized ParameterBinder getParameterWiring() {
529     return param_wiring;
530   }
531   /**
532    * Set the default parameter auto-wiring mode.
533    * @param param_wiring the wiring mode. Null if auto-wiring is disabled.
534    */

535   public synchronized void setParameterWiring(ParameterBinder param_wiring) {
536     this.param_wiring = param_wiring;
537   }
538   /**
539    * Get the default property auto-wiring mode.
540    */

541   public synchronized PropertyBinder getPropertyWiring() {
542     return prop_wiring;
543   }
544   /**
545    * Set the default property auto-wiring mode.
546    * @param prop_wiring the wiring mode.
547    * Null if auto-wiring is disabled.
548    */

549   public synchronized void setPropertyWiring(PropertyBinder prop_wiring) {
550     this.prop_wiring = prop_wiring;
551   }
552   /**
553    * Get the default singleton mode.
554    */

555   public synchronized SingletonMode getSingletonMode() {
556     return singleton_mode;
557   }
558   /**
559    * Set the default singleton mode.
560    * @param singleton_mode the singleton mode.
561    * Null if prototype is used.
562    */

563   public synchronized void setSingletonMode(SingletonMode singleton_mode) {
564     this.singleton_mode = singleton_mode;
565   }
566   
567   /**
568    * Create an NutsProcessor object that's gonna be used to
569    * load meta configuration of Nut classes.
570    * <p>
571    * The default singleton mode is "off" and the default parameter auto-wiring
572    * mode is "bytype".
573    * </p>
574    * <p>
575    * All the service objects and externally registered nuts descriptors
576    * will be copied to this new NutsProcessor object.
577    * </p>
578    * <p>
579    * It is fine to create an NutsProcessor object by calling
580    * the constructor directly.
581    * Any NutsProcessor object can be used to interpret meta configuration.
582    * </p>
583    * <p>
584    * This method just makes it more convenient
585    * to set the default settings and copy the existing service objects
586    * and externally registered nut descriptors.
587    * </p>
588    * @param loader The class loader to load classes.
589    * @param rloader the ResourceLoader to load resources.
590    * @return the new NutsProcessor object.
591    */

592   public synchronized NutsProcessor createMetaProcessor(ClassLoader JavaDoc loader,
593       ResourceLoader rloader){
594     final NutsProcessor aux = new NutsProcessor(loader, rloader, new ManualContainer(),
595         manager, basedir);
596     aux.setSingletonMode(null);
597     aux.setParameterWiring(Modes.params_bytype);
598     aux.services.putAll(services);
599     aux.external_nuts.putAll(external_nuts);
600     return aux;
601   }
602   /**
603    * Create an NutsProcessor object that's gonna be used to
604    * load meta configuration of Nut classes.
605    * <p>
606    * The default singleton mode is "off" and the default parameter auto-wiring
607    * mode is "bytype".
608    * </p>
609    * <p>
610    * All the service objects and externally registered nuts descriptors
611    * will be copied to this new NutsProcessor object.
612    * </p>
613    * <p>
614    * It is fine to create an NutsProcessor object by calling
615    * the constructor directly.
616    * Any NutsProcessor object can be used to interpret meta configuration.
617    * </p>
618    * <p>
619    * This method just makes it more convenient
620    * to set the default settings and copy the existing service objects
621    * and externally registered nut descriptors.
622    * </p>
623    * @param loader The class loader to load classes and resources.
624    * @return the new NutsProcessor object.
625    */

626   public NutsProcessor createMetaProcessor(ClassLoader JavaDoc loader){
627     return createMetaProcessor(loader, new ClassLoader2ResourceLoader(loader));
628   }
629   /**
630    * Create an NutsProcessor object that's gonna be used to
631    * load meta configuration of Nut classes.
632    * <p>
633    * The component classloader is used to load classes.
634    * </p>
635    * <p>
636    * The default singleton mode is "off" and the default parameter auto-wiring
637    * mode is "bytype".
638    * </p>
639    * <p>
640    * All the service objects and externally registered nuts descriptors
641    * will be copied to this new NutsProcessor object.
642    * </p>
643    * <p>
644    * It is fine to create an NutsProcessor object by calling
645    * the constructor directly.
646    * Any NutsProcessor object can be used to interpret meta configuration.
647    * </p>
648    * <p>
649    * This method just makes it more convenient
650    * to set the default settings and copy the existing service objects
651    * and externally registered nut descriptors.
652    * </p>
653    * @return the new NutsProcessor object.
654    */

655   public NutsProcessor createMetaInterpreter(){
656     return createMetaProcessor(cloader, rloader);
657   }
658   /**
659    * Load descriptors of the nut classes registered in a Container.
660    * @param nuts the container containing nut components.
661    */

662   public synchronized void loadNutsFromContainer(Container nuts){
663     final HashMap JavaDoc descs = new HashMap JavaDoc();
664     populateNuts(nuts, descs);
665     addNuts(nuts, descs);
666   }
667   private static void populateNuts(Container nuts, Map JavaDoc descs){
668     final Set JavaDoc nutkeys = nuts.keys();
669     for(Iterator JavaDoc it=nutkeys.iterator(); it.hasNext();){
670       final Object JavaDoc key = it.next();
671       if(!(key instanceof String JavaDoc)){
672         //non-configured component, skip.
673
continue;
674       }
675       final Component c = nuts.getComponent(key);
676       final Class JavaDoc type = c.getType();
677       if(type==null){
678         throw new IllegalArgumentException JavaDoc("unknown type for nut component "+key
679             + ", consider using 'type' attribute to explicitly specify the type for it");
680       }
681       if(!Nut.class.isAssignableFrom(type)){
682         //not nut class, helper type.
683
continue;
684         /*
685         if(type.isAssignableFrom(Nut.class)){
686           throw new IllegalArgumentException("nut component "+key
687               + " is of type " + Misc.getTypeName(type)
688               + ", not a subtype of Nut.\nconsider using 'type' attribute to explicitly specify the type.");
689         }
690         else{
691           throw new IllegalArgumentException("nut component "+key
692               + " is of type "+Misc.getTypeName(type)
693               +", not a subtype of Nut.");
694         }*/

695       }
696       try{
697         final NutDescriptor desc = introspector.getNutDescriptor(type);
698         descs.put(key, desc);
699       }
700       catch(IntrospectionException JavaDoc e){
701         throw new IllegalArgumentException JavaDoc("failed to introspect type "+Misc.getTypeName(type));
702       }
703       //nuts.registerComponent(key, c.factory());
704
}
705   }
706   private synchronized void addNuts(Container nuts, Map JavaDoc descs){
707     for(Iterator JavaDoc it=descs.keySet().iterator();it.hasNext();){
708       final Object JavaDoc key = it.next();
709       final NutDescriptor desc = (NutDescriptor)descs.get(key);
710       final Factory factory = nuts.getFactory(key);
711       desc.setFactory(factory);
712       registerNut(key.toString(), desc);
713     }
714   }
715   private void prewireNuts(Object JavaDoc id, ClassLoader JavaDoc loader, ResourceLoader rloader, InputSource JavaDoc in)
716   throws IOException JavaDoc{
717     final NutsProcessor aux = createMetaProcessor(loader, rloader);
718     final Container nuts = aux.getContainer();
719     aux.process(id, in);
720     loadNutsFromContainer(nuts);
721   }
722   /**
723    * Load a configuration file that wires Nut classes.
724    * The Nut descriptors and their ids loaded from this file will be used
725    * during interpretation of regular configuration files for components.
726    * <p>
727    * By default, singleton mode in a nuts meta file is disabled.
728    * </p>
729    * @param loader the class loader to load classes during interpretation.
730    * @param rloader the
731    * @param filename the config file containing the nuts class wiring.
732    * @throws IOException when file reading fails.
733    */

734   public void loadNutsMetaFile(ClassLoader JavaDoc loader, ResourceLoader rloader,
735       String JavaDoc filename)
736   throws IOException JavaDoc{
737     final File JavaDoc file = Misc.getAbsolutePath(basedir, new File JavaDoc(filename));
738     prewireNuts(file, loader, rloader, new InputSource JavaDoc(filename));
739   }
740   /**
741    * Load configuration information from an InputStream and wires Nut classes.
742    * The Nut descriptors and their ids loaded from this InputStream will be used
743    * during interpretation of regular configuration files for components.
744    * <p>
745    * By default, singleton mode is disabled.
746    * </p>
747    * @param loader the class loader to load classes during interpretation.
748    * @param rloader the ResourceLoader to load resources during interpretation.
749    * @param in the stream containing meta configuration information.
750    * @throws IOException when file reading fails.
751    */

752   public void loadNutsMetaData(Object JavaDoc id, ClassLoader JavaDoc loader,
753       ResourceLoader rloader, InputStream JavaDoc in)
754   throws IOException JavaDoc{
755     prewireNuts(id, loader, rloader, new InputSource JavaDoc(in));
756   }
757   
758   
759   /**
760    * Load a configuration file that wires Nut classes.
761    * The Nut descriptors and their ids loaded from this file will be used
762    * during interpretation of regular configuration files for components.
763    * <p>
764    * By default, singleton mode in a nuts meta file is disabled.
765    * </p>
766    * <p>
767    * The component classloader is used to load these nuts classes.
768    * </p>
769    * @param filename the config file containing the nuts class wiring.
770    * @throws IOException when file reading fails.
771    */

772   public void loadNutsMetaFile(String JavaDoc filename)
773   throws IOException JavaDoc{
774     loadNutsMetaFile(filename);
775   }
776   /**
777    * Load configuration information from an InputStream and wires Nut classes.
778    * The Nut descriptors and their ids loaded from this InputStream will be used
779    * during interpretation of regular configuration files for components.
780    * <p>
781    * By default, singleton mode is disabled.
782    * </p>
783    * <p>
784    * The component classloader is used to load these nuts classes.
785    * </p>
786    * @param in the stream containing meta configuration information.
787    * @throws IOException when file reading fails.
788    */

789   public void loadNutsMetaData(Object JavaDoc id, InputStream JavaDoc in)
790   throws IOException JavaDoc{
791     loadNutsMetaData(id, cloader, rloader, in);
792   }
793   /**
794    * Load configuration information from a resource loaded
795    * by the component class loader.
796    * Nuts classes are wired using this configuration information.
797    * <p>
798    * The Nut descriptors and their ids loaded from this InputStream will be used
799    * during interpretation of regular configuration files for components.
800    * </p>
801    * <p>
802    * By default, singleton mode is disabled.
803    * </p>
804    * <p>
805    * The component classloader is used to load these nuts classes.
806    * </p>
807    * @param resourcename the name of the resource containing meta configuration
808    * information.
809    * @throws IOException when file reading fails.
810    */

811   public void loadNutsMetaResource(String JavaDoc resourcename)
812   throws IOException JavaDoc{
813     final URL JavaDoc url = rloader.getResource(resourcename);
814     final InputStream JavaDoc in = MyUtil.readResource(this.rloader, resourcename);
815     try{
816       loadNutsMetaData(url, this.cloader, rloader, in);
817     }
818     finally{
819       in.close();
820     }
821   }
822   private static Registry toRegistry(final Registrar reg){
823     return new Registry(){
824       public void put(String JavaDoc key, Object JavaDoc v, Location loc){
825         reg.registerComponent(key, NutsUtils.asComponent(v));
826       }
827       public String JavaDoc toString(){
828         return reg.toString();
829       }
830     };
831   }
832   private final List JavaDoc modules_involved = new ArrayList JavaDoc();
833   void registerModuleImport(Object JavaDoc module_id){
834     modules_involved.add(module_id);
835   }
836   void registerEagerInstantiation(UID key, Component c){
837     this.eager_instantiations.put(key, c);
838   }
839   Map JavaDoc getExternalNuts(){
840     return external_nuts;
841   }
842   AutoWiringMap getCustomWiringModes(){
843     return custom_wiring_modes;
844   }
845   Map JavaDoc getServices(){
846     return this.services;
847   }
848   private UID[] getOrderedUIDs(){
849     final Set JavaDoc uids = this.eager_instantiations.keySet();
850     final UID[] result = new UID[uids.size()];
851     uids.toArray(result);
852     Arrays.sort(result, getUIDComparator());
853     return result;
854   }
855   private Comparator JavaDoc getUIDComparator(){
856     final HashMap JavaDoc module_sequence = new HashMap JavaDoc();
857     final int sz = modules_involved.size();
858     for(int i=0; i<sz; i++){
859       module_sequence.put(modules_involved.get(i), new Integer JavaDoc(i));
860     }
861     return new Comparator JavaDoc(){
862       public int compare(Object JavaDoc arg0, Object JavaDoc arg1) {
863         final UID id1 = (UID)arg0;
864         final UID id2 = (UID)arg1;
865         final Integer JavaDoc module_seq1 = (Integer JavaDoc)module_sequence.get(id1.getModuleId());
866         final Integer JavaDoc module_seq2 = (Integer JavaDoc)module_sequence.get(id2.getModuleId());
867         int result = module_seq1.intValue() - module_seq2.intValue();
868         if(result==0){
869           result = id1.getDeclarationSequence() - id2.getDeclarationSequence();
870           if(result == 0){
871             result = id1.getEvaluationSequence()-id2.getEvaluationSequence();
872           }
873         }
874         return result;
875       }
876       public String JavaDoc toString(){
877         return "UID comparator";
878       }
879     };
880   }
881   private final NutsRegistrar dynamic_registered = new NutsRegistrar();
882   void register(Object JavaDoc key, Object JavaDoc val, boolean overridable,
883       boolean overriding, Location loc){
884     dynamic_registered.register(key, val, overridable, overriding, loc);
885   }
886   
887   private void registerDynamics(Registrar reg){
888     for(Iterator JavaDoc it=dynamic_registered.keySet().iterator(); it.hasNext();){
889       final Object JavaDoc key = it.next();
890       final NutsRegistrar.Entry entry = dynamic_registered.getEntry(key);
891       if(reg.containsKey(key)){
892         throw new ConfigurationException("component "+key+" already registered.",
893             entry.getLocation());
894       }
895       reg.registerComponent(key, NutsUtils.asComponent(entry.getValue()));
896     }
897   }
898 }
899
Popular Tags