KickJava   Java API By Example, From Geeks To Geeks.

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


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  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.config;
30
31 import com.caucho.config.jaxb.JaxbBeanType;
32 import com.caucho.config.types.ClassTypeStrategy;
33 import com.caucho.config.types.InitProgram;
34 import com.caucho.config.types.RawString;
35 import com.caucho.loader.EnvironmentBean;
36 import com.caucho.loader.EnvironmentLocal;
37 import com.caucho.util.L10N;
38 import com.caucho.util.Log;
39 import com.caucho.xml.QName;
40
41 import org.w3c.dom.Node JavaDoc;
42
43 import javax.xml.bind.annotation.XmlRootElement;
44 import java.io.InputStream JavaDoc;
45 import java.net.URL JavaDoc;
46 import java.util.Enumeration JavaDoc;
47 import java.util.HashMap JavaDoc;
48 import java.util.logging.Logger JavaDoc;
49
50 /**
51  * Factory for returning type strategies.
52  */

53 public class TypeStrategyFactory {
54   private static final Logger JavaDoc log = Log.open(TypeStrategyFactory.class);
55   private static L10N L = new L10N(TypeStrategyFactory.class);
56   
57   private static final HashMap JavaDoc<String JavaDoc,TypeStrategy> _primitiveTypes
58     = new HashMap JavaDoc<String JavaDoc,TypeStrategy>();
59   
60   private static final EnvironmentLocal<TypeStrategyFactory> _localFactory
61     = new EnvironmentLocal<TypeStrategyFactory>();
62   
63   private final HashMap JavaDoc<String JavaDoc,TypeStrategy> _typeMap
64     = new HashMap JavaDoc<String JavaDoc,TypeStrategy>();
65
66   private final HashMap JavaDoc<QName,AttributeStrategy> _flowMap
67     = new HashMap JavaDoc<QName,AttributeStrategy>();
68
69   private final HashMap JavaDoc<QName,AttributeStrategy> _envMap
70     = new HashMap JavaDoc<QName,AttributeStrategy>();
71   
72   private TypeStrategyFactory()
73   {
74
75   }
76
77   /**
78    * Returns the appropriate strategy.
79    */

80   public static TypeStrategy getTypeStrategy(Class JavaDoc type)
81           throws Exception JavaDoc
82   {
83     TypeStrategyFactory factory = getFactory(type.getClassLoader());
84
85     return factory.getTypeStrategyImpl(type);
86   }
87   
88   public static AttributeStrategy getFlowAttribute(Class JavaDoc type,
89                                                    QName name) throws Exception JavaDoc
90   {
91     return getFactory(type.getClassLoader()).getFlowAttribute(name);
92   }
93
94   private AttributeStrategy getFlowAttribute(QName name)
95   {
96     return _flowMap.get(name);
97   }
98
99   public static AttributeStrategy getEnvironmentAttribute(Class JavaDoc type,
100                                                           QName name) throws Exception JavaDoc
101   {
102     return getFactory(type.getClassLoader()).getEnvironmentAttribute(name);
103   }
104
105   private AttributeStrategy getEnvironmentAttribute(QName name)
106   {
107     AttributeStrategy strategy = _envMap.get(name);
108
109     if (strategy != null)
110       return strategy;
111
112     if (name.getLocalName() != null && ! name.getLocalName().equals("")) {
113       strategy = _envMap.get(new QName(name.getLocalName(), null));
114       return strategy;
115     }
116     else
117       return null;
118   }
119
120   private static TypeStrategyFactory getFactory(ClassLoader JavaDoc loader)
121           throws Exception JavaDoc
122   {
123     if (loader == null)
124       loader = ClassLoader.getSystemClassLoader();
125
126     TypeStrategyFactory factory = _localFactory.getLevel(loader);
127
128     if (factory == null) {
129       factory = new TypeStrategyFactory();
130       _localFactory.set(factory, loader);
131       factory.init(loader);
132     }
133
134     return factory;
135   }
136
137   /**
138    * Initialize the type strategy factory with files in META-INF/caucho
139    *
140    * @param loader the owning class loader
141    * @throws Exception
142    */

143   private void init(ClassLoader JavaDoc loader)
144           throws Exception JavaDoc
145   {
146     Enumeration JavaDoc<URL JavaDoc> urls = loader.getResources("META-INF/caucho/config-types.xml");
147
148     while (urls.hasMoreElements()) {
149       URL JavaDoc url = urls.nextElement();
150  
151       InputStream JavaDoc is = url.openStream();
152       try {
153         new Config(loader).configure(this, is);
154       } catch (Throwable JavaDoc e) {
155         e.printStackTrace(); // XXX:
156
} finally {
157         is.close();
158       }
159     }
160   }
161
162   /**
163    * Adds a new TypeStrategy
164    */

165   public void addTypeStrategy(TypeStrategyConfig config)
166   {
167     _typeMap.put(config.getName(), config.getType());
168   }
169
170   /**
171    * Adds an new environmnent attribute.
172    */

173   public FlowAttributeConfig createFlowAttribute()
174   {
175     return new FlowAttributeConfig();
176   }
177
178   /**
179    * Adds an new environmnent attribute.
180    */

181   public EnvironmentAttributeConfig createEnvironmentAttribute()
182   {
183     return new EnvironmentAttributeConfig();
184   }
185
186   private TypeStrategy getTypeStrategyImpl(Class JavaDoc type)
187   {
188     TypeStrategy strategy = _typeMap.get(type.getName());
189
190     if (strategy == null) {
191       strategy = _primitiveTypes.get(type.getName());
192
193       if (strategy != null) {
194       }
195       else if (EnvironmentBean.class.isAssignableFrom(type))
196         strategy = new EnvironmentTypeStrategy(type);
197       else if (type.isAnnotationPresent(XmlRootElement.class))
198         strategy = new JaxbBeanType(type);
199       else
200         strategy = new BeanTypeStrategy(type);
201
202       _typeMap.put(type.getName(), strategy);
203     }
204
205     return strategy;
206   }
207
208   // configuration types
209
public static class TypeStrategyConfig {
210     private String JavaDoc _name;
211     private TypeStrategy _type;
212
213     public void setName(Class JavaDoc type)
214     {
215       _name = type.getName();
216     }
217
218     public String JavaDoc getName()
219     {
220       return _name;
221     }
222
223     public void setType(Class JavaDoc type)
224             throws ConfigException, IllegalAccessException JavaDoc, InstantiationException JavaDoc
225     {
226       Config.validate(type, TypeStrategy.class);
227
228       _type = (TypeStrategy) type.newInstance();
229     }
230
231     public TypeStrategy getType()
232     {
233       return _type;
234     }
235   }
236
237   public class EnvironmentAttributeConfig {
238     public void put(QName name, Class JavaDoc type)
239     {
240       TypeStrategy typeStrategy = getTypeStrategyImpl(type);
241
242       _envMap.put(name, new EnvironmentAttributeStrategy(typeStrategy));
243     }
244   }
245
246   public class FlowAttributeConfig {
247     public void put(QName name, Class JavaDoc type)
248     {
249       TypeStrategy typeStrategy = getTypeStrategyImpl(type);
250
251       _flowMap.put(name, new EnvironmentAttributeStrategy(typeStrategy));
252     }
253   }
254    // catalog of primitive types.
255

256   private static class PrimitiveBooleanTypeStrategy extends TypeStrategy {
257     /**
258      * Configures the node as a primitive boolean.
259      *
260      * @param builder the builder context.
261      * @param node the configuration node
262      * @param parent
263      */

264     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
265       throws Exception JavaDoc
266     {
267       String JavaDoc value = builder.configureRawString(node);
268
269       if (value == null || value.equals(""))
270     return Boolean.TRUE; // empty flag tags are true
271
else
272     return builder.evalBoolean(value) ? Boolean.TRUE : Boolean.FALSE;
273     }
274   }
275
276   private static class PrimitiveByteTypeStrategy extends TypeStrategy {
277     /**
278      * Configures the node as a primitive byte
279      *
280      * @param builder the builder context.
281      * @param node the configuration node
282      * @param parent
283      */

284     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
285       throws Exception JavaDoc
286     {
287       String JavaDoc value = builder.configureString(node);
288
289       if (value == null || value.equals(""))
290     return new Byte JavaDoc((byte) 0);
291       else
292     return new Byte JavaDoc(value);
293     }
294   }
295
296   private static class PrimitiveShortTypeStrategy extends TypeStrategy {
297     /**
298      * Configures the node as a primitive short
299      *
300      * @param builder the builder context.
301      * @param node the configuration node
302      * @param parent
303      */

304     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
305       throws Exception JavaDoc
306     {
307       String JavaDoc value = builder.configureString(node);
308
309       if (value == null || value.equals(""))
310     return new Short JavaDoc((short) 0);
311       else
312     return new Short JavaDoc(value);
313     }
314   }
315
316   private static class PrimitiveIntTypeStrategy extends TypeStrategy {
317     /**
318      * Configures the node as a primitive int
319      *
320      * @param builder the builder context.
321      * @param node the configuration node
322      * @param parent
323      */

324     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
325       throws Exception JavaDoc
326     {
327       String JavaDoc value = builder.configureString(node);
328
329       if (value == null || value.equals(""))
330     return new Integer JavaDoc(0);
331       else
332     return new Integer JavaDoc(value);
333     }
334   }
335
336   private static class PrimitiveLongTypeStrategy extends TypeStrategy {
337     /**
338      * Configures the node as a primitive int
339      *
340      * @param builder the builder context.
341      * @param node the configuration node
342      * @param parent
343      */

344     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
345       throws Exception JavaDoc
346     {
347       String JavaDoc value = builder.configureString(node);
348
349       if (value == null || value.equals(""))
350     return new Long JavaDoc(0);
351       else
352     return new Long JavaDoc(value);
353     }
354   }
355
356   private static class PrimitiveFloatTypeStrategy extends TypeStrategy {
357     /**
358      * Configures the node as a primitive float
359      *
360      * @param builder the builder context.
361      * @param node the configuration node
362      * @param parent
363      */

364     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
365       throws Exception JavaDoc
366     {
367       String JavaDoc value = builder.configureString(node);
368
369       if (value == null || value.equals(""))
370     return new Float JavaDoc(0);
371       else
372     return new Float JavaDoc(value);
373     }
374   }
375
376   private static class PrimitiveDoubleTypeStrategy extends TypeStrategy {
377     /**
378      * Configures the node as a primitive double
379      *
380      * @param builder the builder context.
381      * @param node the configuration node
382      * @param parent
383      */

384     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
385       throws Exception JavaDoc
386     {
387       String JavaDoc value = builder.configureString(node);
388
389       if (value == null || value.equals(""))
390     return new Double JavaDoc(0);
391       else
392     return new Double JavaDoc(value);
393     }
394   }
395
396   private static class PrimitiveCharTypeStrategy extends TypeStrategy {
397     /**
398      * Configures the node as a primitive char
399      *
400      * @param builder the builder context.
401      * @param node the configuration node
402      * @param parent
403      */

404     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
405       throws Exception JavaDoc
406     {
407       String JavaDoc value = builder.configureString(node);
408
409       if (value == null || value.length() == 0)
410     return new Character JavaDoc((char) 0);
411       else if (value.length() == 1)
412         return new Character JavaDoc(value.charAt(0));
413       else
414         throw builder.error(L.l("Character must be a single char '{0}'", value),
415                             node);
416     }
417   }
418
419   private static class BooleanTypeStrategy extends TypeStrategy {
420     /**
421      * Configures the node as a boolean object.
422      *
423      * @param builder the builder context.
424      * @param node the configuration node
425      * @param parent
426      */

427     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
428       throws Exception JavaDoc
429     {
430       String JavaDoc value = builder.configureRawString(node);
431
432       if (value == null || value.equals(""))
433     return null;
434       else
435     return builder.evalBoolean(value) ? Boolean.TRUE : Boolean.FALSE;
436     }
437   }
438
439   private static class ByteTypeStrategy extends TypeStrategy {
440     /**
441      * Configures the node as a byte object
442      *
443      * @param builder the builder context.
444      * @param node the configuration node
445      * @param parent
446      */

447     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
448       throws Exception JavaDoc
449     {
450       String JavaDoc value = builder.configureString(node);
451
452       if (value == null || value.equals(""))
453     return null;
454       else
455     return new Byte JavaDoc(value);
456     }
457   }
458
459   private static class ShortTypeStrategy extends TypeStrategy {
460     /**
461      * Configures the node as a short object
462      *
463      * @param builder the builder context.
464      * @param node the configuration node
465      * @param parent
466      */

467     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
468       throws Exception JavaDoc
469     {
470       String JavaDoc value = builder.configureString(node);
471
472       if (value == null || value.equals(""))
473     return null;
474       else
475     return new Short JavaDoc(value);
476     }
477   }
478
479   private static class IntegerTypeStrategy extends TypeStrategy {
480     /**
481      * Configures the node as an integer object
482      *
483      * @param builder the builder context.
484      * @param node the configuration node
485      * @param parent
486      */

487     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
488       throws Exception JavaDoc
489     {
490       String JavaDoc value = builder.configureString(node);
491
492       if (value == null || value.equals(""))
493     return null;
494       else
495     return new Integer JavaDoc(value);
496     }
497   }
498
499   private static class LongTypeStrategy extends TypeStrategy {
500     /**
501      * Configures the node as a long object
502      *
503      * @param builder the builder context.
504      * @param node the configuration node
505      * @param parent
506      */

507     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
508       throws Exception JavaDoc
509     {
510       String JavaDoc value = builder.configureString(node);
511
512       if (value == null || value.equals(""))
513     return null;
514       else
515     return new Long JavaDoc(value);
516     }
517   }
518
519   private static class FloatTypeStrategy extends TypeStrategy {
520     /**
521      * Configures the node as a float object
522      *
523      * @param builder the builder context.
524      * @param node the configuration node
525      * @param parent
526      */

527     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
528       throws Exception JavaDoc
529     {
530       String JavaDoc value = builder.configureString(node);
531
532       if (value == null || value.equals(""))
533     return null;
534       else
535     return new Float JavaDoc(value);
536     }
537   }
538
539   private static class DoubleTypeStrategy extends TypeStrategy {
540     /**
541      * Configures the node as a double object
542      *
543      * @param builder the builder context.
544      * @param node the configuration node
545      * @param parent
546      */

547     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
548       throws Exception JavaDoc
549     {
550       String JavaDoc value = builder.configureString(node);
551
552       if (value == null || value.equals(""))
553     return null;
554       else
555     return new Double JavaDoc(value);
556     }
557   }
558
559   private static class CharacterTypeStrategy extends TypeStrategy {
560     /**
561      * Configures the node as a character object
562      *
563      * @param builder the builder context.
564      * @param node the configuration node
565      * @param parent
566      */

567     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
568       throws Exception JavaDoc
569     {
570       String JavaDoc value = builder.configureString(node);
571
572       if (value == null || value.length() == 0)
573     return null;
574       else if (value.length() == 1)
575         return new Character JavaDoc(value.charAt(0));
576       else
577         throw builder.error(L.l("Character must be a single char '{0}'", value),
578                             node);
579     }
580   }
581
582   private static class StringTypeStrategy extends TypeStrategy {
583     /**
584      * Configures the node as a string object
585      *
586      * @param builder the builder context.
587      * @param node the configuration node
588      * @param parent
589      */

590     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
591       throws Exception JavaDoc
592     {
593       return builder.configureString(node);
594     }
595   }
596
597   private static class RawStringTypeStrategy extends TypeStrategy {
598     /**
599      * Configures the node as a string object
600      *
601      * @param builder the builder context.
602      * @param node the configuration node
603      * @param parent
604      */

605     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
606       throws Exception JavaDoc
607     {
608       return new RawString(builder.configureRawStringNoTrim(node));
609     }
610   }
611
612   private static class NodeTypeStrategy extends TypeStrategy {
613     /**
614      * Configures the node as a node object
615      *
616      * @param builder the builder context.
617      * @param node the configuration node
618      * @param parent
619      */

620     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
621       throws Exception JavaDoc
622     {
623       return node;
624     }
625   }
626
627   private static class ObjectTypeStrategy extends TypeStrategy {
628     /**
629      * Configures the node as an object
630      *
631      * @param builder the builder context.
632      * @param node the configuration node
633      * @param parent
634      */

635     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
636       throws Exception JavaDoc
637     {
638       return builder.configureObject(node, parent);
639     }
640   }
641
642   private static class InitProgramTypeStrategy extends TypeStrategy {
643     /**
644      * Configures the node as an init program object
645      *
646      * @param builder the builder context.
647      * @param node the configuration node
648      * @param parent
649      */

650     public void configureBean(NodeBuilder builder, Object JavaDoc bean, Node JavaDoc node)
651       throws Exception JavaDoc
652     {
653       InitProgram program = (InitProgram) bean;
654
655       program.addBuilderProgram(new NodeBuilderProgram(builder, node));
656     }
657     
658     /**
659      * Configures the node as an init program object
660      *
661      * @param builder the builder context.
662      * @param node the configuration node
663      * @param parent
664      */

665     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
666       throws Exception JavaDoc
667     {
668       return new InitProgram(new NodeBuilderProgram(builder, node));
669     }
670   }
671
672   private static class BuilderProgramTypeStrategy extends TypeStrategy {
673     /**
674      * Configures the node as a child program object
675      *
676      * @param builder the builder context.
677      * @param node the configuration node
678      * @param parent
679      */

680     public Object JavaDoc configure(NodeBuilder builder, Node JavaDoc node, Object JavaDoc parent)
681       throws Exception JavaDoc
682     {
683       return new NodeBuilderChildProgram(builder, node);
684     }
685   }
686
687   static {
688     _primitiveTypes.put("boolean", new PrimitiveBooleanTypeStrategy());
689     _primitiveTypes.put("byte", new PrimitiveByteTypeStrategy());
690     _primitiveTypes.put("short", new PrimitiveShortTypeStrategy());
691     _primitiveTypes.put("int", new PrimitiveIntTypeStrategy());
692     _primitiveTypes.put("long", new PrimitiveLongTypeStrategy());
693     _primitiveTypes.put("float", new PrimitiveFloatTypeStrategy());
694     _primitiveTypes.put("double", new PrimitiveDoubleTypeStrategy());
695     _primitiveTypes.put("char", new PrimitiveCharTypeStrategy());
696
697     _primitiveTypes.put("java.lang.Boolean", new BooleanTypeStrategy());
698     _primitiveTypes.put("java.lang.Byte", new ByteTypeStrategy());
699     _primitiveTypes.put("java.lang.Short", new ShortTypeStrategy());
700     _primitiveTypes.put("java.lang.Integer", new IntegerTypeStrategy());
701     _primitiveTypes.put("java.lang.Long", new LongTypeStrategy());
702     _primitiveTypes.put("java.lang.Float", new FloatTypeStrategy());
703     _primitiveTypes.put("java.lang.Double", new DoubleTypeStrategy());
704     _primitiveTypes.put("java.lang.Character", new CharacterTypeStrategy());
705
706     _primitiveTypes.put("java.lang.Object", new ObjectTypeStrategy());
707     _primitiveTypes.put("java.lang.String", new StringTypeStrategy());
708     _primitiveTypes.put("com.caucho.config.types.RawString",
709                         new RawStringTypeStrategy());
710     _primitiveTypes.put("org.w3c.dom.Node", new NodeTypeStrategy());
711     _primitiveTypes.put("java.lang.Class", new ClassTypeStrategy());
712
713     _primitiveTypes.put("com.caucho.config.types.InitProgram",
714                         new InitProgramTypeStrategy());
715     _primitiveTypes.put("com.caucho.config.BuilderProgram",
716                         new BuilderProgramTypeStrategy());
717   }
718 }
719
Popular Tags