KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > xml > XmlConfiguration


1 // ========================================================================
2
// $Id: XmlConfiguration.java,v 1.28 2005/08/13 08:12:14 gregwilkins Exp $
3
// Copyright 1999-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.xml;
17
18 import java.io.IOException JavaDoc;
19 import java.io.InputStream JavaDoc;
20 import java.io.StringReader JavaDoc;
21 import java.lang.reflect.Array JavaDoc;
22 import java.lang.reflect.Constructor JavaDoc;
23 import java.lang.reflect.Field JavaDoc;
24 import java.lang.reflect.InvocationTargetException JavaDoc;
25 import java.lang.reflect.Method JavaDoc;
26 import java.lang.reflect.Modifier JavaDoc;
27 import java.net.InetAddress JavaDoc;
28 import java.net.MalformedURLException JavaDoc;
29 import java.net.URL JavaDoc;
30 import java.net.UnknownHostException JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.Map JavaDoc;
33
34 import org.apache.commons.logging.Log;
35 import org.mortbay.log.LogFactory;
36 import org.mortbay.util.InetAddrPort;
37 import org.mortbay.util.Loader;
38 import org.mortbay.util.LogSupport;
39 import org.mortbay.util.Resource;
40 import org.mortbay.util.TypeUtil;
41 import org.xml.sax.InputSource JavaDoc;
42 import org.xml.sax.SAXException JavaDoc;
43
44 /* ------------------------------------------------------------ */
45 /**
46  * Configure Objects from XML. This class reads an XML file conforming to the configure.dtd DTD and
47  * uses it to configure and object by calling set, put or other methods on the object.
48  *
49  * @version $Id: XmlConfiguration.java,v 1.28 2005/08/13 08:12:14 gregwilkins Exp $
50  * @author Greg Wilkins (gregw)
51  */

52 public class XmlConfiguration
53 {
54     private static Log log = LogFactory.getLog(XmlConfiguration.class);
55
56     private static Class JavaDoc[] __primitives = { Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE,
57             Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE};
58
59     private static Class JavaDoc[] __primitiveHolders = { Boolean JavaDoc.class, Character JavaDoc.class, Byte JavaDoc.class,
60             Short JavaDoc.class, Integer JavaDoc.class, Long JavaDoc.class, Float JavaDoc.class, Double JavaDoc.class, Void JavaDoc.class};
61
62     /* ------------------------------------------------------------ */
63     private static XmlParser __parser;
64     private XmlParser.Node _config;
65     private Map JavaDoc _idMap = new HashMap JavaDoc();
66
67     /* ------------------------------------------------------------ */
68     private synchronized static void initParser() throws IOException JavaDoc
69     {
70         if (__parser != null) return;
71
72         __parser = new XmlParser();
73         URL JavaDoc config13URL = XmlConfiguration.class.getClassLoader().getResource(
74                 "org/mortbay/xml/configure_1_3.dtd");
75         __parser.redirectEntity("configure.dtd", config13URL);
76         __parser.redirectEntity("configure_1_3.dtd", config13URL);
77         __parser.redirectEntity("http://jetty.mortbay.org/configure_1_3.dtd", config13URL);
78         __parser.redirectEntity("http://jetty.mortbay.org/configure.dtd", config13URL);
79         __parser.redirectEntity("-//Mort Bay Consulting//DTD Configure 1.3//EN", config13URL);
80         __parser.redirectEntity("-//Mort Bay Consulting//DTD Configure//EN", config13URL);
81
82         URL JavaDoc config12URL = XmlConfiguration.class.getClassLoader().getResource(
83                 "org/mortbay/xml/configure_1_2.dtd");
84         __parser.redirectEntity("configure_1_2.dtd", config12URL);
85         __parser.redirectEntity("http://jetty.mortbay.org/configure_1_2.dtd", config12URL);
86         __parser.redirectEntity("-//Mort Bay Consulting//DTD Configure 1.2//EN", config12URL);
87
88         URL JavaDoc config11URL = XmlConfiguration.class.getClassLoader().getResource(
89                 "org/mortbay/xml/configure_1_1.dtd");
90         __parser.redirectEntity("configure_1_1.dtd", config11URL);
91         __parser.redirectEntity("http://jetty.mortbay.org/configure_1_1.dtd", config11URL);
92         __parser.redirectEntity("-//Mort Bay Consulting//DTD Configure 1.1//EN", config11URL);
93
94         URL JavaDoc config10URL = XmlConfiguration.class.getClassLoader().getResource(
95                 "org/mortbay/xml/configure_1_0.dtd");
96         __parser.redirectEntity("configure_1_0.dtd", config10URL);
97         __parser.redirectEntity("http://jetty.mortbay.org/configure_1_0.dtd", config10URL);
98         __parser.redirectEntity("-//Mort Bay Consulting//DTD Configure 1.0//EN", config10URL);
99     }
100
101     /* ------------------------------------------------------------ */
102     /**
103      * Constructor. Reads the XML configuration file.
104      *
105      * @param configuration
106      */

107     public XmlConfiguration(URL JavaDoc configuration) throws SAXException JavaDoc, IOException JavaDoc
108     {
109         initParser();
110         synchronized (__parser)
111         {
112             _config = __parser.parse(configuration.toString());
113         }
114     }
115
116     /* ------------------------------------------------------------ */
117     /**
118      * Constructor.
119      *
120      * @param configuration String of XML configuration commands excluding the normal XML preamble.
121      * The String should start with a " <Configure ...." element.
122      * @exception SAXException
123      * @exception IOException
124      */

125     public XmlConfiguration(String JavaDoc configuration) throws SAXException JavaDoc, IOException JavaDoc
126     {
127         initParser();
128         configuration = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<!DOCTYPE Configure PUBLIC \"-//Mort Bay Consulting//DTD Configure 1.2//EN\" \"http://jetty.mortbay.org/configure_1_2.dtd\">"
129                 + configuration;
130         InputSource JavaDoc source = new InputSource JavaDoc(new StringReader JavaDoc(configuration));
131         synchronized (__parser)
132         {
133             _config = __parser.parse(source);
134         }
135     }
136
137     /* ------------------------------------------------------------ */
138     /**
139      * Constructor.
140      *
141      * @param configuration An input stream containing a complete e.g. configuration file
142      * @exception SAXException
143      * @exception IOException
144      */

145     public XmlConfiguration(InputStream JavaDoc configuration) throws SAXException JavaDoc, IOException JavaDoc
146     {
147         initParser();
148         InputSource JavaDoc source = new InputSource JavaDoc(configuration);
149         synchronized (__parser)
150         {
151             _config = __parser.parse(source);
152         }
153     }
154
155     /* ------------------------------------------------------------ */
156     /**
157      * Configure an object. If the object is of the approprate class, the XML configuration script
158      * is applied to the object.
159      *
160      * @param obj The object to be configured.
161      * @exception ClassNotFoundException
162      * @exception NoSuchMethodException
163      * @exception InvocationTargetException
164      * @throws IllegalAccessException
165      * @throws InstantiationException
166      */

167     public void configure(Object JavaDoc obj) throws ClassNotFoundException JavaDoc, NoSuchMethodException JavaDoc,
168             InvocationTargetException JavaDoc, InstantiationException JavaDoc, IllegalAccessException JavaDoc
169     {
170         //Check the class of the object
171
Class JavaDoc oClass = nodeClass(_config);
172         if (oClass != null)
173         {
174             if (obj != null && !oClass.isInstance(obj))
175                     throw new IllegalArgumentException JavaDoc("Object is not of type " + oClass);
176             if (obj == null) obj = oClass.newInstance();
177         }
178         configure(obj, _config, 0);
179     }
180
181     /* ------------------------------------------------------------ */
182     /**
183      * Create a new object and configure it. A new object is created and configured.
184      *
185      * @return The newly created configured object.
186      * @exception ClassNotFoundException
187      * @exception NoSuchMethodException
188      * @exception InvocationTargetException
189      * @exception InstantiationException
190      * @exception IllegalAccessException
191      */

192     public Object JavaDoc newInstance() throws ClassNotFoundException JavaDoc, NoSuchMethodException JavaDoc,
193             InvocationTargetException JavaDoc, InstantiationException JavaDoc, IllegalAccessException JavaDoc
194     {
195         Class JavaDoc oClass = nodeClass(_config);
196         Object JavaDoc obj = null;
197         if (oClass != null) obj = oClass.newInstance();
198         configure(obj, _config, 0);
199         return obj;
200     }
201
202     /* ------------------------------------------------------------ */
203     private Class JavaDoc nodeClass(XmlParser.Node node) throws ClassNotFoundException JavaDoc
204     {
205         String JavaDoc className = node.getAttribute("class");
206         if (className == null) return null;
207
208         return Loader.loadClass(XmlConfiguration.class, className);
209     }
210
211     /* ------------------------------------------------------------ */
212     /*
213      * Recursive configuration step. This method applies the remaining Set, Put and Call elements to
214      * the current object. @param obj @param cfg @param i @exception ClassNotFoundException
215      * @exception NoSuchMethodException @exception InvocationTargetException
216      */

217     private void configure(Object JavaDoc obj, XmlParser.Node cfg, int i) throws ClassNotFoundException JavaDoc,
218             NoSuchMethodException JavaDoc, InvocationTargetException JavaDoc, IllegalAccessException JavaDoc
219     {
220         XmlParser.Node node = null;
221         try
222         {
223             for (; i < cfg.size(); i++)
224             {
225                 Object JavaDoc o = cfg.get(i);
226                 if (o instanceof String JavaDoc) continue;
227                 node = (XmlParser.Node) o;
228
229                 String JavaDoc tag = node.getTag();
230                 if ("Set".equals(tag))
231                     set(obj, node);
232                 else if ("Put".equals(tag))
233                     put(obj, node);
234                 else if ("Call".equals(tag))
235                     call(obj, node);
236                 else if ("Get".equals(tag))
237                     get(obj, node);
238                 else if ("New".equals(tag))
239                     newObj(obj, node);
240                 else if ("Ref".equals(tag))
241                     refObj(obj, node);
242                 else
243                     throw new IllegalStateException JavaDoc("Unknown tag: " + tag);
244             }
245         }
246         catch(InvocationTargetException JavaDoc e)
247         {
248             log.warn("Exception at "+node.toString(),e.getTargetException());
249             throw e;
250         }
251         catch (Error JavaDoc e)
252         {
253             log.debug(node);
254             throw e;
255         }
256         catch (Exception JavaDoc e)
257         {
258             log.debug(node);
259             if (e instanceof NoSuchMethodException JavaDoc) throw (NoSuchMethodException JavaDoc) e;
260             if (e instanceof InvocationTargetException JavaDoc) throw (InvocationTargetException JavaDoc) e;
261             if (e instanceof IllegalAccessException JavaDoc) throw (IllegalAccessException JavaDoc) e;
262             if (e instanceof RuntimeException JavaDoc) throw (RuntimeException JavaDoc) e;
263         }
264     }
265
266     /* ------------------------------------------------------------ */
267     /*
268      * Call a set method. This method makes a best effort to find a matching set method. The type of
269      * the value is used to find a suitable set method by 1. Trying for a trivial type match. 2.
270      * Looking for a native type match. 3. Trying all correctly named methods for an auto
271      * conversion. 4. Attempting to construct a suitable value from original value. @param obj
272      * @param node
273      */

274     private void set(Object JavaDoc obj, XmlParser.Node node) throws ClassNotFoundException JavaDoc,
275             NoSuchMethodException JavaDoc, InvocationTargetException JavaDoc, IllegalAccessException JavaDoc
276     {
277         String JavaDoc attr = node.getAttribute("name");
278         String JavaDoc name = "set" + attr.substring(0, 1).toUpperCase() + attr.substring(1);
279         Object JavaDoc value = value(obj, node);
280         Object JavaDoc[] arg = { value};
281
282         Class JavaDoc oClass = nodeClass(node);
283         if (oClass != null)
284             obj = null;
285         else
286             oClass = obj.getClass();
287
288         Class JavaDoc[] vClass = { Object JavaDoc.class};
289         if (value != null) vClass[0] = value.getClass();
290
291         if (log.isDebugEnabled())
292                 log.debug(obj + "." + name + "(" + vClass[0] + " " + value + ")");
293
294         // Try for trivial match
295
try
296         {
297             Method JavaDoc set = oClass.getMethod(name, vClass);
298             set.invoke(obj, arg);
299             return;
300         }
301         catch (IllegalArgumentException JavaDoc e)
302         {
303             LogSupport.ignore(log, e);
304         }
305         catch (IllegalAccessException JavaDoc e)
306         {
307             LogSupport.ignore(log, e);
308         }
309         catch (NoSuchMethodException JavaDoc e)
310         {
311             LogSupport.ignore(log, e);
312         }
313
314         // Try for native match
315
try
316         {
317             Field JavaDoc type = vClass[0].getField("TYPE");
318             vClass[0] = (Class JavaDoc) type.get(null);
319             Method JavaDoc set = oClass.getMethod(name, vClass);
320             set.invoke(obj, arg);
321             return;
322         }
323         catch (NoSuchFieldException JavaDoc e)
324         {
325             LogSupport.ignore(log, e);
326         }
327         catch (IllegalArgumentException JavaDoc e)
328         {
329             LogSupport.ignore(log, e);
330         }
331         catch (IllegalAccessException JavaDoc e)
332         {
333             LogSupport.ignore(log, e);
334         }
335         catch (NoSuchMethodException JavaDoc e)
336         {
337             LogSupport.ignore(log, e);
338         }
339
340         // Try a field
341
try
342         {
343             Field JavaDoc field = oClass.getField(attr);
344             if (Modifier.isPublic(field.getModifiers()))
345             {
346                 field.set(obj, value);
347                 return;
348             }
349         }
350         catch (NoSuchFieldException JavaDoc e)
351         {
352             LogSupport.ignore(log, e);
353         }
354
355         // Search for a match by trying all the set methods
356
Method JavaDoc[] sets = oClass.getMethods();
357         Method JavaDoc set = null;
358         for (int s = 0; sets != null && s < sets.length; s++)
359         {
360             if (name.equals(sets[s].getName()) && sets[s].getParameterTypes().length == 1)
361             {
362                 // lets try it
363
try
364                 {
365                     set = sets[s];
366                     sets[s].invoke(obj, arg);
367                     return;
368                 }
369                 catch (IllegalArgumentException JavaDoc e)
370                 {
371                     LogSupport.ignore(log, e);
372                 }
373                 catch (IllegalAccessException JavaDoc e)
374                 {
375                     LogSupport.ignore(log, e);
376                 }
377             }
378         }
379
380         // Try converting the arg to the last set found.
381
if (set != null)
382         {
383             try
384             {
385                 Class JavaDoc sClass = set.getParameterTypes()[0];
386                 if (sClass.isPrimitive())
387                 {
388                     for (int t = 0; t < __primitives.length; t++)
389                     {
390                         if (sClass.equals(__primitives[t]))
391                         {
392                             sClass = __primitiveHolders[t];
393                             break;
394                         }
395                     }
396                 }
397                 Constructor JavaDoc cons = sClass.getConstructor(vClass);
398                 arg[0] = cons.newInstance(arg);
399                 set.invoke(obj, arg);
400                 return;
401             }
402             catch (NoSuchMethodException JavaDoc e)
403             {
404                 LogSupport.ignore(log, e);
405             }
406             catch (IllegalAccessException JavaDoc e)
407             {
408                 LogSupport.ignore(log, e);
409             }
410             catch (InstantiationException JavaDoc e)
411             {
412                 LogSupport.ignore(log, e);
413             }
414         }
415
416         // No Joy
417
throw new NoSuchMethodException JavaDoc(oClass + "." + name + "(" + vClass[0] + ")");
418     }
419
420     /* ------------------------------------------------------------ */
421     /*
422      * Call a put method.
423      *
424      * @param obj @param node
425      */

426     private void put(Object JavaDoc obj, XmlParser.Node node) throws NoSuchMethodException JavaDoc,
427             ClassNotFoundException JavaDoc, InvocationTargetException JavaDoc, IllegalAccessException JavaDoc
428     {
429         if (!(obj instanceof Map JavaDoc))
430                 throw new IllegalArgumentException JavaDoc("Object for put is not a Map: " + obj);
431         Map JavaDoc map = (Map JavaDoc) obj;
432
433         String JavaDoc name = node.getAttribute("name");
434         Object JavaDoc value = value(obj, node);
435         map.put(name, value);
436         if (log.isDebugEnabled()) log.debug(obj + ".put(" + name + "+" + value + ")");
437     }
438
439     /* ------------------------------------------------------------ */
440     /*
441      * Call a get method. Any object returned from the call is passed to the configure method to
442      * consume the remaining elements. @param obj @param node @return @exception
443      * NoSuchMethodException @exception ClassNotFoundException @exception InvocationTargetException
444      */

445     private Object JavaDoc get(Object JavaDoc obj, XmlParser.Node node) throws NoSuchMethodException JavaDoc,
446             ClassNotFoundException JavaDoc, InvocationTargetException JavaDoc, IllegalAccessException JavaDoc
447     {
448         Class JavaDoc oClass = nodeClass(node);
449         if (oClass != null)
450             obj = null;
451         else
452             oClass = obj.getClass();
453
454         String JavaDoc name = node.getAttribute("name");
455         String JavaDoc id = node.getAttribute("id");
456         if (log.isDebugEnabled()) log.debug("get " + name);
457
458         try
459         {
460             // try calling a getXxx method.
461
Method JavaDoc method = oClass.getMethod("get" + name.substring(0, 1).toUpperCase()
462                     + name.substring(1), (java.lang.Class JavaDoc[]) null);
463             obj = method.invoke(obj, (java.lang.Object JavaDoc[]) null);
464             configure(obj, node, 0);
465         }
466         catch (NoSuchMethodException JavaDoc nsme)
467         {
468             try
469             {
470                 Field JavaDoc field = oClass.getField(name);
471                 obj = field.get(obj);
472                 configure(obj, node, 0);
473             }
474             catch (NoSuchFieldException JavaDoc nsfe)
475             {
476                 throw nsme;
477             }
478         }
479         if (id != null) _idMap.put(id, obj);
480         return obj;
481     }
482
483     /* ------------------------------------------------------------ */
484     /*
485      * Call a method. A method is selected by trying all methods with matching names and number of
486      * arguments. Any object returned from the call is passed to the configure method to consume the
487      * remaining elements. Note that if this is a static call we consider only methods declared
488      * directly in the given class. i.e. we ignore any static methods in superclasses. @param obj
489      * @param node @return @exception NoSuchMethodException @exception ClassNotFoundException
490      * @exception InvocationTargetException
491      */

492     private Object JavaDoc call(Object JavaDoc obj, XmlParser.Node node) throws NoSuchMethodException JavaDoc,
493             ClassNotFoundException JavaDoc, InvocationTargetException JavaDoc, IllegalAccessException JavaDoc
494     {
495         String JavaDoc id = node.getAttribute("id");
496         Class JavaDoc oClass = nodeClass(node);
497         if (oClass != null)
498             obj = null;
499         else if (obj != null) oClass = obj.getClass();
500         if (oClass == null) throw new IllegalArgumentException JavaDoc(node.toString());
501
502         int size = 0;
503         int argi = node.size();
504         for (int i = 0; i < node.size(); i++)
505         {
506             Object JavaDoc o = node.get(i);
507             if (o instanceof String JavaDoc) continue;
508             if (!((XmlParser.Node) o).getTag().equals("Arg"))
509             {
510                 argi = i;
511                 break;
512             }
513             size++;
514         }
515
516         Object JavaDoc[] arg = new Object JavaDoc[size];
517         for (int i = 0, j = 0; j < size; i++)
518         {
519             Object JavaDoc o = node.get(i);
520             if (o instanceof String JavaDoc) continue;
521             arg[j++] = value(obj, (XmlParser.Node) o);
522         }
523
524         String JavaDoc method = node.getAttribute("name");
525         if (log.isDebugEnabled()) log.debug("call " + method);
526
527         // Lets just try all methods for now
528
Method JavaDoc[] methods = oClass.getMethods();
529         for (int c = 0; methods != null && c < methods.length; c++)
530         {
531             if (!methods[c].getName().equals(method)) continue;
532             if (methods[c].getParameterTypes().length != size) continue;
533             if (Modifier.isStatic(methods[c].getModifiers()) != (obj == null)) continue;
534             if ((obj == null) && methods[c].getDeclaringClass() != oClass) continue;
535
536             Object JavaDoc n = null;
537             boolean called = false;
538             try
539             {
540                 n = methods[c].invoke(obj, arg);
541                 called = true;
542             }
543             catch (IllegalAccessException JavaDoc e)
544             {
545                 LogSupport.ignore(log, e);
546             }
547             catch (IllegalArgumentException JavaDoc e)
548             {
549                 LogSupport.ignore(log, e);
550             }
551             if (called)
552             {
553                 if (id != null) _idMap.put(id, n);
554                 configure(n, node, argi);
555                 return n;
556             }
557         }
558
559         throw new IllegalStateException JavaDoc("No Method: " + node + " on " + oClass);
560     }
561
562     /* ------------------------------------------------------------ */
563     /*
564      * Create a new value object.
565      *
566      * @param obj @param node @return @exception NoSuchMethodException @exception
567      * ClassNotFoundException @exception InvocationTargetException
568      */

569     private Object JavaDoc newObj(Object JavaDoc obj, XmlParser.Node node) throws NoSuchMethodException JavaDoc,
570             ClassNotFoundException JavaDoc, InvocationTargetException JavaDoc, IllegalAccessException JavaDoc
571     {
572         Class JavaDoc oClass = nodeClass(node);
573         String JavaDoc id = node.getAttribute("id");
574         int size = 0;
575         int argi = node.size();
576         for (int i = 0; i < node.size(); i++)
577         {
578             Object JavaDoc o = node.get(i);
579             if (o instanceof String JavaDoc) continue;
580             if (!((XmlParser.Node) o).getTag().equals("Arg"))
581             {
582                 argi = i;
583                 break;
584             }
585             size++;
586         }
587
588         Object JavaDoc[] arg = new Object JavaDoc[size];
589         for (int i = 0, j = 0; j < size; i++)
590         {
591             Object JavaDoc o = node.get(i);
592             if (o instanceof String JavaDoc) continue;
593             arg[j++] = value(obj, (XmlParser.Node) o);
594         }
595
596         if (log.isDebugEnabled()) log.debug("new " + oClass);
597
598         // Lets just try all constructors for now
599
Constructor JavaDoc[] constructors = oClass.getConstructors();
600         for (int c = 0; constructors != null && c < constructors.length; c++)
601         {
602             if (constructors[c].getParameterTypes().length != size) continue;
603
604             Object JavaDoc n = null;
605             boolean called = false;
606             try
607             {
608                 n = constructors[c].newInstance(arg);
609                 called = true;
610             }
611             catch (IllegalAccessException JavaDoc e)
612             {
613                 LogSupport.ignore(log, e);
614             }
615             catch (InstantiationException JavaDoc e)
616             {
617                 LogSupport.ignore(log, e);
618             }
619             catch (IllegalArgumentException JavaDoc e)
620             {
621                 LogSupport.ignore(log, e);
622             }
623             if (called)
624             {
625                 if (id != null) _idMap.put(id, n);
626                 configure(n, node, argi);
627                 return n;
628             }
629         }
630
631         throw new IllegalStateException JavaDoc("No Constructor: " + node + " on " + obj);
632     }
633
634     /* ------------------------------------------------------------ */
635     /*
636      * Reference an id value object.
637      *
638      * @param obj @param node @return @exception NoSuchMethodException @exception
639      * ClassNotFoundException @exception InvocationTargetException
640      */

641     private Object JavaDoc refObj(Object JavaDoc obj, XmlParser.Node node) throws NoSuchMethodException JavaDoc,
642             ClassNotFoundException JavaDoc, InvocationTargetException JavaDoc, IllegalAccessException JavaDoc
643     {
644         String JavaDoc id = node.getAttribute("id");
645         obj = _idMap.get(id);
646         if (obj == null) throw new IllegalStateException JavaDoc("No object for id=" + id);
647         configure(obj, node, 0);
648         return obj;
649     }
650
651     /* ------------------------------------------------------------ */
652     /*
653      * Create a new array object.
654      *
655      * @param obj @param node @return @exception NoSuchMethodException @exception
656      * ClassNotFoundException @exception InvocationTargetException
657      */

658     private Object JavaDoc newArray(Object JavaDoc obj, XmlParser.Node node) throws NoSuchMethodException JavaDoc,
659             ClassNotFoundException JavaDoc, InvocationTargetException JavaDoc, IllegalAccessException JavaDoc
660     {
661         // Get the type
662
Class JavaDoc aClass = java.lang.Object JavaDoc.class;
663         String JavaDoc type = node.getAttribute("type");
664         String JavaDoc id = node.getAttribute("id");
665         if (type != null)
666         {
667             aClass = TypeUtil.fromName(type);
668             if (aClass == null)
669             {
670                 if ("String".equals(type))
671                     aClass = java.lang.String JavaDoc.class;
672                 else if ("URL".equals(type))
673                     aClass = java.net.URL JavaDoc.class;
674                 else if ("InetAddress".equals(type))
675                     aClass = java.net.InetAddress JavaDoc.class;
676                 else if ("InetAddrPort".equals(type))
677                     aClass = org.mortbay.util.InetAddrPort.class;
678                 else
679                     aClass = Loader.loadClass(XmlConfiguration.class, type);
680             }
681         }
682
683         Object JavaDoc array = Array.newInstance(aClass, node.size());
684         if (id != null) _idMap.put(id, obj);
685
686         for (int i = 0; i < node.size(); i++)
687         {
688             Object JavaDoc o = node.get(i);
689             if (o instanceof String JavaDoc) continue;
690             XmlParser.Node item = (XmlParser.Node) o;
691             if (!item.getTag().equals("Item")) throw new IllegalStateException JavaDoc("Not an Item");
692             id = item.getAttribute("id");
693             Object JavaDoc v = value(obj, item);
694             if (v != null) Array.set(array, i, v);
695             if (id != null) _idMap.put(id, v);
696         }
697
698         return array;
699     }
700
701     /* ------------------------------------------------------------ */
702     /*
703      * Get the value of an element. If no value type is specified, then white space is trimmed out
704      * of the value. If it contains multiple value elements they are added as strings before being
705      * converted to any specified type. @param node
706      */

707     private Object JavaDoc value(Object JavaDoc obj, XmlParser.Node node) throws NoSuchMethodException JavaDoc,
708             ClassNotFoundException JavaDoc, InvocationTargetException JavaDoc, IllegalAccessException JavaDoc
709     {
710         Object JavaDoc value = null;
711
712         // Get the type
713
String JavaDoc type = node.getAttribute("type");
714
715         // Try a ref lookup
716
String JavaDoc ref = node.getAttribute("ref");
717         if (ref != null)
718         {
719             value = _idMap.get(ref);
720         }
721         else
722         {
723             // handle trivial case
724
if (node.size() == 0)
725             {
726                 if ("String".equals(type)) return "";
727                 return null;
728             }
729
730             // Trim values
731
int first = 0;
732             int last = node.size() - 1;
733
734             // Handle default trim type
735
if (type == null || !"String".equals(type))
736             {
737                 // Skip leading white
738
Object JavaDoc item = null;
739                 while (first <= last)
740                 {
741                     item = node.get(first);
742                     if (!(item instanceof String JavaDoc)) break;
743                     item = ((String JavaDoc) item).trim();
744                     if (((String JavaDoc) item).length() > 0) break;
745                     first++;
746                 }
747
748                 // Skip trailing white
749
while (first < last)
750                 {
751                     item = node.get(last);
752                     if (!(item instanceof String JavaDoc)) break;
753                     item = ((String JavaDoc) item).trim();
754                     if (((String JavaDoc) item).length() > 0) break;
755                     last--;
756                 }
757
758                 // All white, so return null
759
if (first > last) return null;
760             }
761
762             if (first == last)
763                 // Single Item value
764
value = itemValue(obj, node.get(first));
765             else
766             {
767                 // Get the multiple items as a single string
768
StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
769                 synchronized (buf)
770                 {
771                     for (int i = first; i <= last; i++)
772                     {
773                         Object JavaDoc item = node.get(i);
774                         buf.append(itemValue(obj, item));
775                     }
776                     value = buf.toString();
777                 }
778             }
779         }
780
781         // Untyped or unknown
782
if (value == null)
783         {
784             if ("String".equals(type)) return "";
785             return null;
786         }
787
788         // Try to type the object
789
if (type == null)
790         {
791             if (value != null && value instanceof String JavaDoc) return ((String JavaDoc) value).trim();
792             return value;
793         }
794
795         if ("String".equals(type) || "java.lang.String".equals(type)) return value.toString();
796
797         Class JavaDoc pClass = TypeUtil.fromName(type);
798         if (pClass != null) return TypeUtil.valueOf(pClass, value.toString());
799
800         if ("URL".equals(type) || "java.net.URL".equals(type))
801         {
802             if (value instanceof URL JavaDoc) return value;
803             try
804             {
805                 return new URL JavaDoc(value.toString());
806             }
807             catch (MalformedURLException JavaDoc e)
808             {
809                 throw new InvocationTargetException JavaDoc(e);
810             }
811         }
812
813         if ("InetAddress".equals(type) || "java.net.InetAddress".equals(type))
814         {
815             if (value instanceof InetAddress JavaDoc) return value;
816             try
817             {
818                 return InetAddress.getByName(value.toString());
819             }
820             catch (UnknownHostException JavaDoc e)
821             {
822                 throw new InvocationTargetException JavaDoc(e);
823             }
824         }
825
826         if ("InetAddrPort".equals(type) || "org.mortbay.util.InetAddrPort".equals(type))
827         {
828             if (value instanceof InetAddrPort) return value;
829             try
830             {
831                 return new InetAddrPort(value.toString());
832             }
833             catch (UnknownHostException JavaDoc e)
834             {
835                 throw new InvocationTargetException JavaDoc(e);
836             }
837         }
838
839         throw new IllegalStateException JavaDoc("Unknown type " + type);
840     }
841
842     /* ------------------------------------------------------------ */
843     /*
844      * Get the value of a single element. @param obj @param item @return @exception
845      * ClassNotFoundException
846      */

847     private Object JavaDoc itemValue(Object JavaDoc obj, Object JavaDoc item) throws NoSuchMethodException JavaDoc,
848             ClassNotFoundException JavaDoc, InvocationTargetException JavaDoc, IllegalAccessException JavaDoc
849     {
850         // String value
851
if (item instanceof String JavaDoc) return item;
852
853         XmlParser.Node node = (XmlParser.Node) item;
854         String JavaDoc tag = node.getTag();
855         if ("Call".equals(tag)) return call(obj, node);
856         if ("Get".equals(tag)) return get(obj, node);
857         if ("New".equals(tag)) return newObj(obj, node);
858         if ("Ref".equals(tag)) return refObj(obj, node);
859         if ("Array".equals(tag)) return newArray(obj, node);
860
861         if ("SystemProperty".equals(tag))
862         {
863             String JavaDoc name = node.getAttribute("name");
864             String JavaDoc defaultValue = node.getAttribute("default");
865             return System.getProperty(name, defaultValue);
866         }
867
868         log.warn("Unknown value tag: " + node, new Throwable JavaDoc());
869         return null;
870     }
871
872     /* ------------------------------------------------------------ */
873     /* ------------------------------------------------------------ */
874     /* ------------------------------------------------------------ */
875     public static void main(String JavaDoc[] arg)
876     {
877         try
878         {
879             for (int i = 0; i < arg.length; i++)
880                 new XmlConfiguration(Resource.newResource(arg[i]).getURL()).newInstance();
881         }
882         catch (Exception JavaDoc e)
883         {
884             log.warn(LogSupport.EXCEPTION, e);
885         }
886     }
887 }
888
889
Popular Tags