KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > config > Config


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.config;
31
32 import com.caucho.el.EL;
33 import com.caucho.el.EnvironmentContext;
34 import com.caucho.relaxng.CompactVerifierFactoryImpl;
35 import com.caucho.relaxng.Schema;
36 import com.caucho.relaxng.Verifier;
37 import com.caucho.relaxng.VerifierFilter;
38 import com.caucho.util.L10N;
39 import com.caucho.util.Log;
40 import com.caucho.util.LruCache;
41 import com.caucho.vfs.MergePath;
42 import com.caucho.vfs.Path;
43 import com.caucho.vfs.ReadStream;
44 import com.caucho.xml.DOMBuilder;
45 import com.caucho.xml.QDocument;
46 import com.caucho.xml.QName;
47 import com.caucho.xml.Xml;
48
49 import org.w3c.dom.Node JavaDoc;
50 import org.xml.sax.InputSource JavaDoc;
51
52 import javax.el.ELContext;
53 import javax.el.ELException;
54 import javax.el.ELResolver;
55 import java.io.IOException JavaDoc;
56 import java.io.InputStream JavaDoc;
57 import java.lang.ref.SoftReference JavaDoc;
58 import java.lang.reflect.Constructor JavaDoc;
59 import java.lang.reflect.Method JavaDoc;
60 import java.lang.reflect.Modifier JavaDoc;
61 import java.util.HashMap JavaDoc;
62 import java.util.Map JavaDoc;
63 import java.util.logging.Logger JavaDoc;
64
65 /**
66  * Facade for Resin's configuration builder.
67  */

68 public class Config {
69   private static final L10N L = new L10N(Config.class);
70   private static final Logger JavaDoc log = Log.open(Config.class);
71
72   private static LruCache<Path,SoftReference JavaDoc<QDocument>> _parseCache =
73     new LruCache<Path,SoftReference JavaDoc<QDocument>>(32);
74
75   // Copied from parent for resin:import, server/13jk
76
private ConfigVariableResolver _varResolver;
77   
78   private HashMap JavaDoc<String JavaDoc,Object JavaDoc> _vars
79     = new HashMap JavaDoc<String JavaDoc,Object JavaDoc>();
80   
81   // the context class loader of the config
82
private ClassLoader JavaDoc _classLoader;
83
84   private ConfigLibrary _configLibrary;
85
86   private boolean _isEL = true;
87   private boolean _allowResinInclude;
88
89   public Config()
90   {
91     this(Thread.currentThread().getContextClassLoader());
92   }
93
94   /**
95    * @param loader the class loader environment to use.
96    */

97   public Config(ClassLoader JavaDoc loader)
98   {
99     _classLoader = loader;
100
101     _configLibrary = ConfigLibrary.getLocal(_classLoader);
102   }
103
104   /**
105    * Set true if resin:include should be allowed.
106    */

107   public void setResinInclude(boolean useResinInclude)
108   {
109     _allowResinInclude = useResinInclude;
110   }
111
112   /**
113    * True if EL expressions are allowed
114    */

115   public boolean isEL()
116   {
117     return _isEL;
118   }
119
120   /**
121    * True if EL expressions are allowed
122    */

123   public void setEL(boolean isEL)
124   {
125     _isEL = isEL;
126   }
127
128   /**
129    * Sets the variable resolver.
130    */

131   public void setConfigVariableResolver(ConfigVariableResolver varResolver)
132   {
133     _varResolver = varResolver;
134   }
135
136   /**
137    * Gets the variable resolver.
138    */

139   public ConfigVariableResolver getConfigVariableResolver()
140   {
141     return _varResolver;
142   }
143
144   /**
145    * Configures a bean with a configuration file.
146    */

147   public Object JavaDoc configure(Object JavaDoc obj, Path path)
148     throws Exception JavaDoc
149   {
150     QDocument doc = parseDocument(path, null);
151
152     return configure(obj, doc.getDocumentElement());
153   }
154
155   /**
156    * Configures a bean with a configuration file.
157    */

158   public Object JavaDoc configure(Object JavaDoc obj, InputStream JavaDoc is)
159     throws Exception JavaDoc
160   {
161     QDocument doc = parseDocument(is, null);
162     
163     return configure(obj, doc.getDocumentElement());
164   }
165
166   /**
167    * Configures a bean with a configuration file and schema.
168    */

169   public Object JavaDoc configure(Object JavaDoc obj, Path path, String JavaDoc schemaLocation)
170     throws Exception JavaDoc
171   {
172     Schema schema = findCompactSchema(schemaLocation);
173
174     QDocument doc = parseDocument(path, schema);
175
176     return configure(obj, doc.getDocumentElement());
177   }
178
179   /**
180    * Configures a bean with a configuration file and schema.
181    */

182   public Object JavaDoc configure(Object JavaDoc obj, Path path, Schema schema)
183     throws Exception JavaDoc
184   {
185     QDocument doc = parseDocument(path, schema);
186
187     return configure(obj, doc.getDocumentElement());
188   }
189
190   /**
191    * Configures a bean with a configuration file.
192    */

193   public Object JavaDoc configure(Object JavaDoc obj,
194               InputStream JavaDoc is,
195               String JavaDoc schemaLocation)
196     throws Exception JavaDoc
197   {
198     Schema schema = findCompactSchema(schemaLocation);
199
200     QDocument doc = parseDocument(is, schema);
201
202     return configure(obj, doc.getDocumentElement());
203   }
204
205   /**
206    * Configures a bean with a configuration file.
207    */

208   public Object JavaDoc configure(Object JavaDoc obj,
209               InputStream JavaDoc is,
210               Schema schema)
211     throws Exception JavaDoc
212   {
213     QDocument doc = parseDocument(is, schema);
214
215     return configure(obj, doc.getDocumentElement());
216   }
217
218   /**
219    * Configures a bean with a DOM.
220    */

221   public Object JavaDoc configure(Object JavaDoc obj, Node JavaDoc topNode)
222     throws Exception JavaDoc
223   {
224     Thread JavaDoc thread = Thread.currentThread();
225     ClassLoader JavaDoc oldLoader = thread.getContextClassLoader();
226
227     try {
228       thread.setContextClassLoader(_classLoader);
229
230       NodeBuilder builder = createBuilder();
231
232       return builder.configure(obj, topNode);
233     } finally {
234       thread.setContextClassLoader(oldLoader);
235     }
236   }
237
238   /**
239    * Configures a bean with a configuration file and schema.
240    */

241   public void configureBean(Object JavaDoc obj,
242                 Path path,
243                 String JavaDoc schemaLocation)
244     throws Exception JavaDoc
245   {
246     Schema schema = findCompactSchema(schemaLocation);
247
248     QDocument doc = parseDocument(path, schema);
249
250     configureBean(obj, doc.getDocumentElement());
251   }
252
253   /**
254    * Configures a bean with a configuration file and schema.
255    */

256   public void configureBean(Object JavaDoc obj, Path path)
257     throws Exception JavaDoc
258   {
259     QDocument doc = parseDocument(path, null);
260
261     configureBean(obj, doc.getDocumentElement());
262   }
263
264   /**
265    * Configures a bean with a DOM. configureBean does not
266    * apply init() or replaceObject().
267    */

268   public void configureBean(Object JavaDoc obj, Node JavaDoc topNode)
269     throws Exception JavaDoc
270   {
271     Thread JavaDoc thread = Thread.currentThread();
272     ClassLoader JavaDoc oldLoader = thread.getContextClassLoader();
273
274     try {
275       thread.setContextClassLoader(_classLoader);
276
277       NodeBuilder builder = createBuilder();
278
279       builder.configureBean(obj, topNode);
280     } finally {
281       thread.setContextClassLoader(oldLoader);
282     }
283   }
284
285   private NodeBuilder createBuilder()
286   {
287     NodeBuilder builder = new NodeBuilder(this);
288
289     for (String JavaDoc var : _vars.keySet())
290       builder.putVar(var, _vars.get(var));
291
292     ConfigLibrary lib = ConfigLibrary.getLocal();
293
294     HashMap JavaDoc<String JavaDoc,Method JavaDoc> methodMap = lib.getMethodMap();
295
296     for (Map.Entry JavaDoc<String JavaDoc,Method JavaDoc> entry : methodMap.entrySet()) {
297       builder.putVar(entry.getKey(), entry.getValue());
298     }
299
300     return builder;
301   }
302
303   /**
304    * Configures a bean with a configuration file and schema.
305    */

306   public void configureBean(Object JavaDoc obj,
307                 Path path,
308                 Schema schema)
309     throws Exception JavaDoc
310   {
311     QDocument doc = parseDocument(path, schema);
312
313     configureBean(obj, doc.getDocumentElement());
314   }
315   
316   /**
317    * Configures the bean from a path
318    */

319   private QDocument parseDocument(Path path, Schema schema)
320     throws LineConfigException, IOException JavaDoc, org.xml.sax.SAXException JavaDoc
321   {
322     // server/2d33
323
SoftReference JavaDoc<QDocument> docRef = null;//_parseCache.get(path);
324
QDocument doc;
325
326     if (docRef != null) {
327       doc = docRef.get();
328
329       if (doc != null && ! doc.isModified())
330     return doc;
331     }
332     
333     ReadStream is = path.openRead();
334
335     try {
336       doc = parseDocument(is, schema);
337
338       // _parseCache.put(path, new SoftReference<QDocument>(doc));
339

340       return doc;
341     } finally {
342       is.close();
343     }
344   }
345   
346   /**
347    * Configures the bean from an input stream.
348    */

349   private QDocument parseDocument(InputStream JavaDoc is, Schema schema)
350     throws LineConfigException,
351        IOException JavaDoc,
352        org.xml.sax.SAXException JavaDoc
353   {
354     QDocument doc = new QDocument();
355     DOMBuilder builder = new DOMBuilder();
356
357     builder.init(doc);
358     String JavaDoc systemId = null;
359     if (is instanceof ReadStream) {
360       systemId = ((ReadStream) is).getPath().getUserPath();
361     }
362
363     doc.setSystemId(systemId);
364     builder.setSystemId(systemId);
365     builder.setSkipWhitespace(true);
366
367     InputSource JavaDoc in = new InputSource JavaDoc();
368     in.setByteStream(is);
369     in.setSystemId(systemId);
370
371     Xml xml = new Xml();
372     xml.setOwner(doc);
373     xml.setResinInclude(_allowResinInclude);
374
375     if (schema != null) {
376       Verifier verifier = schema.newVerifier();
377       VerifierFilter filter = verifier.getVerifierFilter();
378
379       filter.setParent(xml);
380       filter.setContentHandler(builder);
381       filter.setErrorHandler(builder);
382
383       filter.parse(in);
384     }
385     else {
386       xml.setContentHandler(builder);
387       xml.parse(in);
388     }
389
390     return doc;
391   }
392   
393   private Schema findCompactSchema(String JavaDoc location)
394     throws IOException JavaDoc, ConfigException
395   {
396     try {
397       if (location == null)
398     return null;
399       
400       MergePath schemaPath = new MergePath();
401       schemaPath.addClassPath();
402       
403       Path path = schemaPath.lookup(location);
404       if (path.canRead()) {
405     // VerifierFactory factory = VerifierFactory.newInstance("http://caucho.com/ns/compact-relax-ng/1.0");
406

407     CompactVerifierFactoryImpl factory;
408     factory = new CompactVerifierFactoryImpl();
409
410     return factory.compileSchema(path);
411       }
412       else
413     return null;
414     } catch (IOException JavaDoc e) {
415       throw e;
416     } catch (Exception JavaDoc e) {
417       throw new ConfigException(e);
418     }
419   }
420
421   /**
422    * Configures a bean with a configuration map.
423    */

424   public Object JavaDoc configureMap(Object JavaDoc obj, Map JavaDoc<String JavaDoc,Object JavaDoc> map)
425     throws Exception JavaDoc
426   {
427     return new MapBuilder().configure(obj, map);
428   }
429   
430   /**
431    * Returns true if the class can be instantiated.
432    */

433   public static void checkCanInstantiate(Class JavaDoc beanClass)
434     throws ConfigException
435   {
436     if (beanClass == null)
437       throw new ConfigException(L.l("null classes can't be instantiated."));
438     else if (beanClass.isInterface())
439       throw new ConfigException(L.l("`{0}' must be a concrete class. Interfaces cannot be instantiated.", beanClass.getName()));
440     else if (! Modifier.isPublic(beanClass.getModifiers()))
441       throw new ConfigException(L.l("Custom bean class `{0}' is not public. Bean classes must be public, concrete, and have a zero-argument constructor.", beanClass.getName()));
442     else if (Modifier.isAbstract(beanClass.getModifiers()))
443       throw new ConfigException(L.l("Custom bean class `{0}' is abstract. Bean classes must be public, concrete, and have a zero-argument constructor.", beanClass.getName()));
444
445     Constructor JavaDoc []constructors = beanClass.getDeclaredConstructors();
446
447     Constructor JavaDoc constructor = null;
448
449     for (int i = 0; i < constructors.length; i++) {
450       if (constructors[i].getParameterTypes().length == 0) {
451         constructor = constructors[i];
452         break;
453       }
454     }
455
456     if (constructor == null)
457       throw new ConfigException(L.l("Custom bean class `{0}' doesn't have a zero-arg constructor. Bean classes must be have a zero-argument constructor.", beanClass.getName()));
458
459     if (! Modifier.isPublic(constructor.getModifiers())) {
460       throw new ConfigException(L.l("The zero-argument constructor for `{0}' isn't public. Bean classes must have a public zero-argument constructor.", beanClass.getName()));
461     }
462   }
463   
464   /**
465    * Returns true if the class can be instantiated.
466    */

467   public static void validate(Class JavaDoc cl, Class JavaDoc api)
468     throws ConfigException
469   {
470     checkCanInstantiate(cl);
471
472     if (! api.isAssignableFrom(cl)) {
473       throw new ConfigException(L.l("{0} must implement {1}.",
474                     cl.getName(), api.getName()));
475     }
476   }
477
478   /**
479    * Sets an attribute with a value.
480    *
481    * @param obj the bean to be set
482    * @param attr the attribute name
483    * @param value the attribute value
484    */

485   public static void setAttribute(Object JavaDoc obj, String JavaDoc attr, Object JavaDoc value)
486     throws Exception JavaDoc
487   {
488     TypeStrategy strategy = TypeStrategyFactory.getTypeStrategy(obj.getClass());
489
490     QName attrName = new QName(attr);
491     AttributeStrategy attrStrategy = strategy.getAttributeStrategy(attrName);
492     attrStrategy.setAttribute(obj, attrName, value);
493   }
494
495   public static void init(Object JavaDoc bean)
496     throws ConfigException
497   {
498     try {
499       TypeStrategy strategy;
500
501       strategy = TypeStrategyFactory.getTypeStrategy(bean.getClass());
502
503       strategy.init(bean);
504     } catch (RuntimeException JavaDoc e) {
505       throw e;
506     } catch (Exception JavaDoc e) {
507       throw new ConfigException(e);
508     }
509   }
510
511   public static Object JavaDoc replaceObject(Object JavaDoc bean) throws Exception JavaDoc
512   {
513     TypeStrategy strategy = TypeStrategyFactory.getTypeStrategy(bean.getClass());
514
515     return strategy.replaceObject(bean);
516   }
517
518   /**
519    * Returns the variable resolver.
520    */

521   public static ELContext getEnvironment()
522   {
523     NodeBuilder builder = NodeBuilder.getCurrentBuilder();
524
525     if (builder != null) {
526       return builder.getELContext();
527     }
528     else
529       return EL.getEnvironment();
530   }
531
532   /**
533    * Returns the variable resolver.
534    */

535   public static ConfigELContext getELContext()
536   {
537     NodeBuilder builder = NodeBuilder.getCurrentBuilder();
538
539     if (builder != null) {
540       return builder.getELContext();
541     }
542     else
543       return null;
544   }
545
546   /**
547    * Returns the variable resolver.
548    */

549   public static void setELContext(ConfigELContext context)
550   {
551     NodeBuilder builder = NodeBuilder.getCurrentBuilder();
552
553     if (builder != null) {
554       builder.setELContext(context);
555     }
556   }
557
558   /**
559    * Sets an EL configuration variable.
560    */

561   public void setVar(String JavaDoc var, Object JavaDoc value)
562   {
563     setCurrentVar(var, value);
564
565     _vars.put(var, value);
566   }
567
568   /**
569    * Sets an EL configuration variable.
570    */

571   public static void setCurrentVar(String JavaDoc var, Object JavaDoc value)
572   {
573     NodeBuilder builder = NodeBuilder.getCurrentBuilder();
574
575     if (builder != null)
576       builder.putVar(var, value);
577   }
578
579   /**
580    * Sets an EL configuration variable.
581    */

582   public static Object JavaDoc getCurrentVar(String JavaDoc var)
583   {
584     NodeBuilder builder = NodeBuilder.getCurrentBuilder();
585
586     if (builder != null)
587       return builder.getVar(var);
588     else
589       return null;
590   }
591
592   /**
593    * Gets an EL configuration variable.
594    */

595   public static Object JavaDoc getVar(String JavaDoc var) throws ELException
596   {
597     return getEnvironment().getELResolver().getValue(getEnvironment(),
598                              var, null);
599   }
600
601   /**
602    * Evaluates an EL string in the context.
603    */

604   public static String JavaDoc evalString(String JavaDoc str)
605     throws ELException
606   {
607     return AttributeStrategy.evalString(str);
608   }
609
610   /**
611    * Evaluates an EL string in the context.
612    */

613   public static String JavaDoc evalString(String JavaDoc str, HashMap JavaDoc<String JavaDoc,Object JavaDoc> varMap)
614          throws ELException
615   {
616     return EL.evalString(str, getEnvironment(varMap));
617   }
618
619   /**
620    * Evaluates an EL boolean in the context.
621    */

622   public static boolean evalBoolean(String JavaDoc str)
623     throws ELException
624   {
625     return AttributeStrategy.evalBoolean(str);
626   }
627
628   public static ELContext getEnvironment(HashMap JavaDoc<String JavaDoc,Object JavaDoc> varMap)
629   {
630     ELContext context = Config.getEnvironment();
631
632     ELResolver parent = null;
633
634     if (context != null)
635       parent = context.getELResolver();
636
637     if (varMap != null)
638       return new EnvironmentContext(varMap);
639     else
640       return new EnvironmentContext();
641   }
642 }
643
644
Popular Tags