Source Code Cross Referenced for XmlConfiguration.java in  » Sevlet-Container » jetty-modules » org » mortbay » xml » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Sevlet Container » jetty modules » org.mortbay.xml 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // ========================================================================
002:        // Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
003:        // ------------------------------------------------------------------------
004:        // Licensed under the Apache License, Version 2.0 (the "License");
005:        // you may not use this file except in compliance with the License.
006:        // You may obtain a copy of the License at
007:        // http://www.apache.org/licenses/LICENSE-2.0
008:        // Unless required by applicable law or agreed to in writing, software
009:        // distributed under the License is distributed on an "AS IS" BASIS,
010:        // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011:        // See the License for the specific language governing permissions and
012:        // limitations under the License.
013:        // ========================================================================
014:
015:        package org.mortbay.xml;
016:
017:        import java.io.IOException;
018:        import java.io.InputStream;
019:        import java.io.StringReader;
020:        import java.lang.reflect.Constructor;
021:        import java.lang.reflect.Field;
022:        import java.lang.reflect.InvocationTargetException;
023:        import java.lang.reflect.Method;
024:        import java.lang.reflect.Modifier;
025:        import java.net.InetAddress;
026:        import java.net.MalformedURLException;
027:        import java.net.URL;
028:        import java.net.UnknownHostException;
029:        import java.util.HashMap;
030:        import java.util.Iterator;
031:        import java.util.Map;
032:
033:        import org.mortbay.component.LifeCycle;
034:        import org.mortbay.log.Log;
035:        import org.mortbay.resource.Resource;
036:        import org.mortbay.util.LazyList;
037:        import org.mortbay.util.Loader;
038:        import org.mortbay.util.TypeUtil;
039:        import org.xml.sax.InputSource;
040:        import org.xml.sax.SAXException;
041:
042:        /* ------------------------------------------------------------ */
043:        /**
044:         * Configure Objects from XML. This class reads an XML file conforming to the configure.dtd DTD and
045:         * uses it to configure and object by calling set, put or other methods on the object.
046:         *
047:         * @author Greg Wilkins (gregw)
048:         */
049:        public class XmlConfiguration {
050:
051:            private static Class[] __primitives = { Boolean.TYPE,
052:                    Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE,
053:                    Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE };
054:
055:            private static Class[] __primitiveHolders = { Boolean.class,
056:                    Character.class, Byte.class, Short.class, Integer.class,
057:                    Long.class, Float.class, Double.class, Void.class };
058:            private static final Integer ZERO = new Integer(0);
059:
060:            /* ------------------------------------------------------------ */
061:            private static XmlParser __parser;
062:            private XmlParser.Node _config;
063:            private Map _idMap = new HashMap();
064:            private Map _propertyMap = new HashMap();
065:
066:            /* ------------------------------------------------------------ */
067:            private synchronized static void initParser() throws IOException {
068:                if (__parser != null)
069:                    return;
070:
071:                __parser = new XmlParser();
072:                URL configURL = XmlConfiguration.class.getClassLoader()
073:                        .getResource("org/mortbay/xml/configure_6_0.dtd");
074:                __parser.redirectEntity("configure.dtd", configURL);
075:                __parser.redirectEntity("configure_1_3.dtd", configURL);
076:                __parser.redirectEntity(
077:                        "http://jetty.mortbay.org/configure.dtd", configURL);
078:                __parser.redirectEntity(
079:                        "-//Mort Bay Consulting//DTD Configure//EN", configURL);
080:                __parser
081:                        .redirectEntity(
082:                                "http://jetty.mortbay.org/configure_1_3.dtd",
083:                                configURL);
084:                __parser.redirectEntity(
085:                        "-//Mort Bay Consulting//DTD Configure 1.3//EN",
086:                        configURL);
087:                __parser.redirectEntity("configure_1_2.dtd", configURL);
088:                __parser
089:                        .redirectEntity(
090:                                "http://jetty.mortbay.org/configure_1_2.dtd",
091:                                configURL);
092:                __parser.redirectEntity(
093:                        "-//Mort Bay Consulting//DTD Configure 1.2//EN",
094:                        configURL);
095:                __parser.redirectEntity("configure_1_1.dtd", configURL);
096:                __parser
097:                        .redirectEntity(
098:                                "http://jetty.mortbay.org/configure_1_1.dtd",
099:                                configURL);
100:                __parser.redirectEntity(
101:                        "-//Mort Bay Consulting//DTD Configure 1.1//EN",
102:                        configURL);
103:                __parser.redirectEntity("configure_1_0.dtd", configURL);
104:                __parser
105:                        .redirectEntity(
106:                                "http://jetty.mortbay.org/configure_1_0.dtd",
107:                                configURL);
108:                __parser.redirectEntity(
109:                        "-//Mort Bay Consulting//DTD Configure 1.0//EN",
110:                        configURL);
111:            }
112:
113:            /* ------------------------------------------------------------ */
114:            /**
115:             * Constructor. Reads the XML configuration file.
116:             *
117:             * @param configuration
118:             */
119:            public XmlConfiguration(URL configuration) throws SAXException,
120:                    IOException {
121:                initParser();
122:                synchronized (__parser) {
123:                    _config = __parser.parse(configuration.toString());
124:                }
125:            }
126:
127:            /* ------------------------------------------------------------ */
128:            /**
129:             * Constructor.
130:             *
131:             * @param configuration String of XML configuration commands excluding the normal XML preamble.
132:             *            The String should start with a " <Configure ...." element.
133:             * @exception SAXException
134:             * @exception IOException
135:             */
136:            public XmlConfiguration(String configuration) throws SAXException,
137:                    IOException {
138:                initParser();
139:                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\">"
140:                        + configuration;
141:                InputSource source = new InputSource(new StringReader(
142:                        configuration));
143:                synchronized (__parser) {
144:                    _config = __parser.parse(source);
145:                }
146:            }
147:
148:            /* ------------------------------------------------------------ */
149:            /**
150:             * Constructor.
151:             *
152:             * @param configuration An input stream containing a complete e.g. configuration file
153:             * @exception SAXException
154:             * @exception IOException
155:             */
156:            public XmlConfiguration(InputStream configuration)
157:                    throws SAXException, IOException {
158:                initParser();
159:                InputSource source = new InputSource(configuration);
160:                synchronized (__parser) {
161:                    _config = __parser.parse(source);
162:                }
163:            }
164:
165:            /* ------------------------------------------------------------ */
166:            public Map getIdMap() {
167:                return _idMap;
168:            }
169:
170:            /* ------------------------------------------------------------ */
171:            public void setIdMap(Map map) {
172:                _idMap = map;
173:            }
174:
175:            public void setProperties(Map map) {
176:                _propertyMap = map;
177:            }
178:
179:            public Map getProperties() {
180:                return _propertyMap;
181:            }
182:
183:            /* ------------------------------------------------------------ */
184:            /**
185:             * Configure an object. If the object is of the approprate class, the XML configuration script
186:             * is applied to the object.
187:             *
188:             * @param obj The object to be configured.
189:             * @exception Exception
190:             */
191:            public void configure(Object obj) throws Exception {
192:                //Check the class of the object
193:                Class oClass = nodeClass(_config);
194:                if (!oClass.isInstance(obj))
195:                    throw new IllegalArgumentException("Object is not of type "
196:                            + oClass);
197:                configure(obj, _config, 0);
198:            }
199:
200:            /* ------------------------------------------------------------ */
201:            /**
202:             * Configure an object.  If the configuration has an ID, an object is looked up
203:             * by ID and it's type check.  Otherwise a new object is created.
204:             * 
205:             * @return The newly created configured object.
206:             * @exception Exception
207:             */
208:            public Object configure() throws Exception {
209:                Class oClass = nodeClass(_config);
210:
211:                String id = _config.getAttribute("id");
212:                Object obj = id == null ? null : _idMap.get(id);
213:
214:                if (obj == null && oClass != null)
215:                    obj = oClass.newInstance();
216:
217:                if (oClass != null && !oClass.isInstance(obj))
218:                    throw new ClassCastException(oClass.toString());
219:
220:                configure(obj, _config, 0);
221:                return obj;
222:            }
223:
224:            /* ------------------------------------------------------------ */
225:            private Class nodeClass(XmlParser.Node node)
226:                    throws ClassNotFoundException {
227:                String className = node.getAttribute("class");
228:                if (className == null)
229:                    return null;
230:
231:                return Loader
232:                        .loadClass(XmlConfiguration.class, className, true);
233:            }
234:
235:            /* ------------------------------------------------------------ */
236:            /*
237:             * Recursive configuration step. This method applies the remaining Set, Put and Call elements to
238:             * the current object. @param obj @param cfg @param i @exception Exception
239:             */
240:            private void configure(Object obj, XmlParser.Node cfg, int i)
241:                    throws Exception {
242:                String id = cfg.getAttribute("id");
243:                if (id != null)
244:                    _idMap.put(id, obj);
245:
246:                for (; i < cfg.size(); i++) {
247:                    Object o = cfg.get(i);
248:                    if (o instanceof  String)
249:                        continue;
250:                    XmlParser.Node node = (XmlParser.Node) o;
251:
252:                    try {
253:                        String tag = node.getTag();
254:                        if ("Set".equals(tag))
255:                            set(obj, node);
256:                        else if ("Put".equals(tag))
257:                            put(obj, node);
258:                        else if ("Call".equals(tag))
259:                            call(obj, node);
260:                        else if ("Get".equals(tag))
261:                            get(obj, node);
262:                        else if ("New".equals(tag))
263:                            newObj(obj, node);
264:                        else if ("Array".equals(tag))
265:                            newArray(obj, node);
266:                        else if ("Ref".equals(tag))
267:                            refObj(obj, node);
268:                        else
269:                            throw new IllegalStateException("Unknown tag: "
270:                                    + tag);
271:                    } catch (Exception e) {
272:                        Log.warn("Config error at " + node, e.toString());
273:                        throw e;
274:                    }
275:                }
276:            }
277:
278:            /* ------------------------------------------------------------ */
279:            /*
280:             * Call a set method. This method makes a best effort to find a matching set method. The type of
281:             * the value is used to find a suitable set method by 1. Trying for a trivial type match. 2.
282:             * Looking for a native type match. 3. Trying all correctly named methods for an auto
283:             * conversion. 4. Attempting to construct a suitable value from original value. @param obj
284:             * @param node
285:             */
286:            private void set(Object obj, XmlParser.Node node) throws Exception {
287:                String attr = node.getAttribute("name");
288:                String name = "set" + attr.substring(0, 1).toUpperCase()
289:                        + attr.substring(1);
290:                Object value = value(obj, node);
291:                Object[] arg = { value };
292:
293:                Class oClass = nodeClass(node);
294:                if (oClass != null)
295:                    obj = null;
296:                else
297:                    oClass = obj.getClass();
298:
299:                Class[] vClass = { Object.class };
300:                if (value != null)
301:                    vClass[0] = value.getClass();
302:
303:                if (Log.isDebugEnabled())
304:                    Log.debug("XML "
305:                            + (obj != null ? obj.toString() : oClass.getName())
306:                            + "." + name + "(" + value + ")");
307:
308:                // Try for trivial match
309:                try {
310:                    Method set = oClass.getMethod(name, vClass);
311:                    set.invoke(obj, arg);
312:                    return;
313:                } catch (IllegalArgumentException e) {
314:                    Log.ignore(e);
315:                } catch (IllegalAccessException e) {
316:                    Log.ignore(e);
317:                } catch (NoSuchMethodException e) {
318:                    Log.ignore(e);
319:                }
320:
321:                // Try for native match
322:                try {
323:                    Field type = vClass[0].getField("TYPE");
324:                    vClass[0] = (Class) type.get(null);
325:                    Method set = oClass.getMethod(name, vClass);
326:                    set.invoke(obj, arg);
327:                    return;
328:                } catch (NoSuchFieldException e) {
329:                    Log.ignore(e);
330:                } catch (IllegalArgumentException e) {
331:                    Log.ignore(e);
332:                } catch (IllegalAccessException e) {
333:                    Log.ignore(e);
334:                } catch (NoSuchMethodException e) {
335:                    Log.ignore(e);
336:                }
337:
338:                // Try a field
339:                try {
340:                    Field field = oClass.getField(attr);
341:                    if (Modifier.isPublic(field.getModifiers())) {
342:                        field.set(obj, value);
343:                        return;
344:                    }
345:                } catch (NoSuchFieldException e) {
346:                    Log.ignore(e);
347:                }
348:
349:                // Search for a match by trying all the set methods
350:                Method[] sets = oClass.getMethods();
351:                Method set = null;
352:                for (int s = 0; sets != null && s < sets.length; s++) {
353:                    if (name.equals(sets[s].getName())
354:                            && sets[s].getParameterTypes().length == 1) {
355:                        // lets try it
356:                        try {
357:                            set = sets[s];
358:                            sets[s].invoke(obj, arg);
359:                            return;
360:                        } catch (IllegalArgumentException e) {
361:                            Log.ignore(e);
362:                        } catch (IllegalAccessException e) {
363:                            Log.ignore(e);
364:                        }
365:                    }
366:                }
367:
368:                // Try converting the arg to the last set found.
369:                if (set != null) {
370:                    try {
371:                        Class sClass = set.getParameterTypes()[0];
372:                        if (sClass.isPrimitive()) {
373:                            for (int t = 0; t < __primitives.length; t++) {
374:                                if (sClass.equals(__primitives[t])) {
375:                                    sClass = __primitiveHolders[t];
376:                                    break;
377:                                }
378:                            }
379:                        }
380:                        Constructor cons = sClass.getConstructor(vClass);
381:                        arg[0] = cons.newInstance(arg);
382:                        set.invoke(obj, arg);
383:                        return;
384:                    } catch (NoSuchMethodException e) {
385:                        Log.ignore(e);
386:                    } catch (IllegalAccessException e) {
387:                        Log.ignore(e);
388:                    } catch (InstantiationException e) {
389:                        Log.ignore(e);
390:                    }
391:                }
392:
393:                // No Joy
394:                throw new NoSuchMethodException(oClass + "." + name + "("
395:                        + vClass[0] + ")");
396:            }
397:
398:            /* ------------------------------------------------------------ */
399:            /*
400:             * Call a put method.
401:             *
402:             * @param obj @param node
403:             */
404:            private void put(Object obj, XmlParser.Node node) throws Exception {
405:                if (!(obj instanceof  Map))
406:                    throw new IllegalArgumentException(
407:                            "Object for put is not a Map: " + obj);
408:                Map map = (Map) obj;
409:
410:                String name = node.getAttribute("name");
411:                Object value = value(obj, node);
412:                map.put(name, value);
413:                if (Log.isDebugEnabled())
414:                    Log
415:                            .debug("XML " + obj + ".put(" + name + "," + value
416:                                    + ")");
417:            }
418:
419:            /* ------------------------------------------------------------ */
420:            /*
421:             * Call a get method. Any object returned from the call is passed to the configure method to
422:             * consume the remaining elements. @param obj @param node @return @exception Exception
423:             */
424:            private Object get(Object obj, XmlParser.Node node)
425:                    throws Exception {
426:                Class oClass = nodeClass(node);
427:                if (oClass != null)
428:                    obj = null;
429:                else
430:                    oClass = obj.getClass();
431:
432:                String name = node.getAttribute("name");
433:                String id = node.getAttribute("id");
434:                if (Log.isDebugEnabled())
435:                    Log.debug("XML get " + name);
436:
437:                try {
438:                    // try calling a getXxx method.
439:                    Method method = oClass.getMethod("get"
440:                            + name.substring(0, 1).toUpperCase()
441:                            + name.substring(1), (java.lang.Class[]) null);
442:                    obj = method.invoke(obj, (java.lang.Object[]) null);
443:                    configure(obj, node, 0);
444:                } catch (NoSuchMethodException nsme) {
445:                    try {
446:                        Field field = oClass.getField(name);
447:                        obj = field.get(obj);
448:                        configure(obj, node, 0);
449:                    } catch (NoSuchFieldException nsfe) {
450:                        throw nsme;
451:                    }
452:                }
453:                if (id != null)
454:                    _idMap.put(id, obj);
455:                return obj;
456:            }
457:
458:            /* ------------------------------------------------------------ */
459:            /*
460:             * Call a method. A method is selected by trying all methods with matching names and number of
461:             * arguments. Any object returned from the call is passed to the configure method to consume the
462:             * remaining elements. Note that if this is a static call we consider only methods declared
463:             * directly in the given class. i.e. we ignore any static methods in superclasses. @param obj
464:             * @param node @return @exception Exception
465:             */
466:            private Object call(Object obj, XmlParser.Node node)
467:                    throws Exception {
468:                String id = node.getAttribute("id");
469:                Class oClass = nodeClass(node);
470:                if (oClass != null)
471:                    obj = null;
472:                else if (obj != null)
473:                    oClass = obj.getClass();
474:                if (oClass == null)
475:                    throw new IllegalArgumentException(node.toString());
476:
477:                int size = 0;
478:                int argi = node.size();
479:                for (int i = 0; i < node.size(); i++) {
480:                    Object o = node.get(i);
481:                    if (o instanceof  String)
482:                        continue;
483:                    if (!((XmlParser.Node) o).getTag().equals("Arg")) {
484:                        argi = i;
485:                        break;
486:                    }
487:                    size++;
488:                }
489:
490:                Object[] arg = new Object[size];
491:                for (int i = 0, j = 0; j < size; i++) {
492:                    Object o = node.get(i);
493:                    if (o instanceof  String)
494:                        continue;
495:                    arg[j++] = value(obj, (XmlParser.Node) o);
496:                }
497:
498:                String method = node.getAttribute("name");
499:                if (Log.isDebugEnabled())
500:                    Log.debug("XML call " + method);
501:
502:                // Lets just try all methods for now
503:                Method[] methods = oClass.getMethods();
504:                for (int c = 0; methods != null && c < methods.length; c++) {
505:                    if (!methods[c].getName().equals(method))
506:                        continue;
507:                    if (methods[c].getParameterTypes().length != size)
508:                        continue;
509:                    if (Modifier.isStatic(methods[c].getModifiers()) != (obj == null))
510:                        continue;
511:                    if ((obj == null)
512:                            && methods[c].getDeclaringClass() != oClass)
513:                        continue;
514:
515:                    Object n = null;
516:                    boolean called = false;
517:                    try {
518:                        n = methods[c].invoke(obj, arg);
519:                        called = true;
520:                    } catch (IllegalAccessException e) {
521:                        Log.ignore(e);
522:                    } catch (IllegalArgumentException e) {
523:                        Log.ignore(e);
524:                    }
525:                    if (called) {
526:                        if (id != null)
527:                            _idMap.put(id, n);
528:                        configure(n, node, argi);
529:                        return n;
530:                    }
531:                }
532:
533:                throw new IllegalStateException("No Method: " + node + " on "
534:                        + oClass);
535:            }
536:
537:            /* ------------------------------------------------------------ */
538:            /*
539:             * Create a new value object.
540:             *
541:             * @param obj @param node @return @exception Exception
542:             */
543:            private Object newObj(Object obj, XmlParser.Node node)
544:                    throws Exception {
545:                Class oClass = nodeClass(node);
546:                String id = node.getAttribute("id");
547:                int size = 0;
548:                int argi = node.size();
549:                for (int i = 0; i < node.size(); i++) {
550:                    Object o = node.get(i);
551:                    if (o instanceof  String)
552:                        continue;
553:                    if (!((XmlParser.Node) o).getTag().equals("Arg")) {
554:                        argi = i;
555:                        break;
556:                    }
557:                    size++;
558:                }
559:
560:                Object[] arg = new Object[size];
561:                for (int i = 0, j = 0; j < size; i++) {
562:                    Object o = node.get(i);
563:                    if (o instanceof  String)
564:                        continue;
565:                    arg[j++] = value(obj, (XmlParser.Node) o);
566:                }
567:
568:                if (Log.isDebugEnabled())
569:                    Log.debug("XML new " + oClass);
570:
571:                // Lets just try all constructors for now
572:                Constructor[] constructors = oClass.getConstructors();
573:                for (int c = 0; constructors != null && c < constructors.length; c++) {
574:                    if (constructors[c].getParameterTypes().length != size)
575:                        continue;
576:
577:                    Object n = null;
578:                    boolean called = false;
579:                    try {
580:                        n = constructors[c].newInstance(arg);
581:                        called = true;
582:                    } catch (IllegalAccessException e) {
583:                        Log.ignore(e);
584:                    } catch (InstantiationException e) {
585:                        Log.ignore(e);
586:                    } catch (IllegalArgumentException e) {
587:                        Log.ignore(e);
588:                    }
589:                    if (called) {
590:                        if (id != null)
591:                            _idMap.put(id, n);
592:                        configure(n, node, argi);
593:                        return n;
594:                    }
595:                }
596:
597:                throw new IllegalStateException("No Constructor: " + node
598:                        + " on " + obj);
599:            }
600:
601:            /* ------------------------------------------------------------ */
602:            /*
603:             * Reference an id value object.
604:             *
605:             * @param obj @param node @return @exception NoSuchMethodException @exception
606:             * ClassNotFoundException @exception InvocationTargetException
607:             */
608:            private Object refObj(Object obj, XmlParser.Node node)
609:                    throws Exception {
610:                String id = node.getAttribute("id");
611:                obj = _idMap.get(id);
612:                if (obj == null)
613:                    throw new IllegalStateException("No object for id=" + id);
614:                configure(obj, node, 0);
615:                return obj;
616:            }
617:
618:            /* ------------------------------------------------------------ */
619:            /*
620:             * Create a new array object.
621:             *
622:             */
623:            private Object newArray(Object obj, XmlParser.Node node)
624:                    throws Exception {
625:
626:                // Get the type
627:                Class aClass = java.lang.Object.class;
628:                String type = node.getAttribute("type");
629:                final String id = node.getAttribute("id");
630:                if (type != null) {
631:                    aClass = TypeUtil.fromName(type);
632:                    if (aClass == null) {
633:                        if ("String".equals(type))
634:                            aClass = java.lang.String.class;
635:                        else if ("URL".equals(type))
636:                            aClass = java.net.URL.class;
637:                        else if ("InetAddress".equals(type))
638:                            aClass = java.net.InetAddress.class;
639:                        else
640:                            aClass = Loader.loadClass(XmlConfiguration.class,
641:                                    type, true);
642:                    }
643:                }
644:
645:                Object al = null;
646:
647:                Iterator iter = node.iterator("Item");
648:                while (iter.hasNext()) {
649:                    XmlParser.Node item = (XmlParser.Node) iter.next();
650:                    String nid = item.getAttribute("id");
651:                    Object v = value(obj, item);
652:                    al = LazyList.add(al,
653:                            (v == null && aClass.isPrimitive()) ? ZERO : v);
654:                    if (nid != null)
655:                        _idMap.put(nid, v);
656:                }
657:
658:                Object array = LazyList.toArray(al, aClass);
659:                if (id != null)
660:                    _idMap.put(id, array);
661:                return array;
662:            }
663:
664:            /* ------------------------------------------------------------ */
665:            /*
666:             * Create a new map object.
667:             *
668:             */
669:            private Object newMap(Object obj, XmlParser.Node node)
670:                    throws Exception {
671:                String id = node.getAttribute("id");
672:
673:                Map map = new HashMap();
674:                if (id != null)
675:                    _idMap.put(id, map);
676:
677:                for (int i = 0; i < node.size(); i++) {
678:                    Object o = node.get(i);
679:                    if (o instanceof  String)
680:                        continue;
681:                    XmlParser.Node entry = (XmlParser.Node) o;
682:                    if (!entry.getTag().equals("Entry"))
683:                        throw new IllegalStateException("Not an Entry");
684:
685:                    XmlParser.Node key = null;
686:                    XmlParser.Node value = null;
687:
688:                    for (int j = 0; j < entry.size(); j++) {
689:                        o = entry.get(j);
690:                        if (o instanceof  String)
691:                            continue;
692:                        XmlParser.Node item = (XmlParser.Node) o;
693:                        if (!item.getTag().equals("Item"))
694:                            throw new IllegalStateException("Not an Item");
695:                        if (key == null)
696:                            key = item;
697:                        else
698:                            value = item;
699:                    }
700:
701:                    if (key == null || value == null)
702:                        throw new IllegalStateException("Missing Item in Entry");
703:                    String kid = key.getAttribute("id");
704:                    String vid = value.getAttribute("id");
705:
706:                    Object k = value(obj, key);
707:                    Object v = value(obj, value);
708:                    map.put(k, v);
709:
710:                    if (kid != null)
711:                        _idMap.put(kid, k);
712:                    if (vid != null)
713:                        _idMap.put(vid, v);
714:                }
715:
716:                return map;
717:            }
718:
719:            /* ------------------------------------------------------------ */
720:            /*
721:             * Get the value of an element. If no value type is specified, then white space is trimmed out
722:             * of the value. If it contains multiple value elements they are added as strings before being
723:             * converted to any specified type. @param node
724:             */
725:            private Object value(Object obj, XmlParser.Node node)
726:                    throws Exception {
727:                Object value = null;
728:
729:                // Get the type
730:                String type = node.getAttribute("type");
731:
732:                // Try a ref lookup
733:                String ref = node.getAttribute("ref");
734:                if (ref != null) {
735:                    value = _idMap.get(ref);
736:                } else {
737:                    // handle trivial case
738:                    if (node.size() == 0) {
739:                        if ("String".equals(type))
740:                            return "";
741:                        return null;
742:                    }
743:
744:                    // Trim values
745:                    int first = 0;
746:                    int last = node.size() - 1;
747:
748:                    // Handle default trim type
749:                    if (type == null || !"String".equals(type)) {
750:                        // Skip leading white
751:                        Object item = null;
752:                        while (first <= last) {
753:                            item = node.get(first);
754:                            if (!(item instanceof  String))
755:                                break;
756:                            item = ((String) item).trim();
757:                            if (((String) item).length() > 0)
758:                                break;
759:                            first++;
760:                        }
761:
762:                        // Skip trailing white
763:                        while (first < last) {
764:                            item = node.get(last);
765:                            if (!(item instanceof  String))
766:                                break;
767:                            item = ((String) item).trim();
768:                            if (((String) item).length() > 0)
769:                                break;
770:                            last--;
771:                        }
772:
773:                        // All white, so return null
774:                        if (first > last)
775:                            return null;
776:                    }
777:
778:                    if (first == last)
779:                        //  Single Item value
780:                        value = itemValue(obj, node.get(first));
781:                    else {
782:                        // Get the multiple items as a single string
783:                        StringBuffer buf = new StringBuffer();
784:                        synchronized (buf) {
785:                            for (int i = first; i <= last; i++) {
786:                                Object item = node.get(i);
787:                                buf.append(itemValue(obj, item));
788:                            }
789:                            value = buf.toString();
790:                        }
791:                    }
792:                }
793:
794:                // Untyped or unknown
795:                if (value == null) {
796:                    if ("String".equals(type))
797:                        return "";
798:                    return null;
799:                }
800:
801:                // Try to type the object
802:                if (type == null) {
803:                    if (value != null && value instanceof  String)
804:                        return ((String) value).trim();
805:                    return value;
806:                }
807:
808:                if ("String".equals(type) || "java.lang.String".equals(type))
809:                    return value.toString();
810:
811:                Class pClass = TypeUtil.fromName(type);
812:                if (pClass != null)
813:                    return TypeUtil.valueOf(pClass, value.toString());
814:
815:                if ("URL".equals(type) || "java.net.URL".equals(type)) {
816:                    if (value instanceof  URL)
817:                        return value;
818:                    try {
819:                        return new URL(value.toString());
820:                    } catch (MalformedURLException e) {
821:                        throw new InvocationTargetException(e);
822:                    }
823:                }
824:
825:                if ("InetAddress".equals(type)
826:                        || "java.net.InetAddress".equals(type)) {
827:                    if (value instanceof  InetAddress)
828:                        return value;
829:                    try {
830:                        return InetAddress.getByName(value.toString());
831:                    } catch (UnknownHostException e) {
832:                        throw new InvocationTargetException(e);
833:                    }
834:                }
835:
836:                throw new IllegalStateException("Unknown type " + type);
837:            }
838:
839:            /* ------------------------------------------------------------ */
840:            /*
841:             * Get the value of a single element. @param obj @param item @return @exception Exception
842:             */
843:            private Object itemValue(Object obj, Object item) throws Exception {
844:                // String value
845:                if (item instanceof  String)
846:                    return item;
847:
848:                XmlParser.Node node = (XmlParser.Node) item;
849:                String tag = node.getTag();
850:                if ("Call".equals(tag))
851:                    return call(obj, node);
852:                if ("Get".equals(tag))
853:                    return get(obj, node);
854:                if ("New".equals(tag))
855:                    return newObj(obj, node);
856:                if ("Ref".equals(tag))
857:                    return refObj(obj, node);
858:                if ("Array".equals(tag))
859:                    return newArray(obj, node);
860:                if ("Map".equals(tag))
861:                    return newMap(obj, node);
862:
863:                if ("SystemProperty".equals(tag)) {
864:                    String name = node.getAttribute("name");
865:                    String defaultValue = node.getAttribute("default");
866:                    return System.getProperty(name, defaultValue);
867:                }
868:                if ("Property".equals(tag)) {
869:                    String name = node.getAttribute("name");
870:                    Object defval = node.getAttribute("default");
871:                    if (_propertyMap != null && _propertyMap.containsKey(name)) {
872:                        return _propertyMap.get(name);
873:                    } else if (defval != null)
874:                        return defval;
875:                    else
876:                        throw new Exception("Unresolved property name=" + name);
877:                }
878:
879:                Log.warn("Unknown value tag: " + node, new Throwable());
880:                return null;
881:            }
882:
883:            /* ------------------------------------------------------------ */
884:            /* ------------------------------------------------------------ */
885:            /* ------------------------------------------------------------ */
886:            public static void main(String[] args) {
887:                try {
888:                    XmlConfiguration last = null;
889:                    Object[] obj = new Object[args.length];
890:                    for (int i = 0; i < args.length; i++) {
891:                        XmlConfiguration configuration = new XmlConfiguration(
892:                                Resource.newResource(args[i]).getURL());
893:                        if (last != null)
894:                            configuration.getIdMap().putAll(last.getIdMap());
895:                        obj[i] = configuration.configure();
896:                        last = configuration;
897:                    }
898:
899:                    for (int i = 0; i < args.length; i++) {
900:                        if (obj[i] instanceof  LifeCycle) {
901:                            LifeCycle lc = (LifeCycle) obj[i];
902:                            if (!lc.isRunning())
903:                                lc.start();
904:                        }
905:                    }
906:                } catch (Exception e) {
907:                    Log.warn(Log.EXCEPTION, e);
908:                }
909:
910:            }
911:
912:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.