1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.eclipse.jetty.xml;
15
16 import java.io.IOException;
17 import java.io.InputStream;
18 import java.io.StringReader;
19 import java.lang.reflect.Array;
20 import java.lang.reflect.Constructor;
21 import java.lang.reflect.Field;
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24 import java.lang.reflect.Modifier;
25 import java.net.InetAddress;
26 import java.net.MalformedURLException;
27 import java.net.URL;
28 import java.net.UnknownHostException;
29 import java.security.AccessController;
30 import java.security.PrivilegedAction;
31 import java.util.ArrayList;
32 import java.util.Collection;
33 import java.util.Enumeration;
34 import java.util.HashMap;
35 import java.util.HashSet;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Properties;
39 import java.util.Queue;
40 import java.util.Set;
41 import java.util.concurrent.atomic.AtomicReference;
42
43 import org.eclipse.jetty.util.ArrayQueue;
44 import org.eclipse.jetty.util.LazyList;
45 import org.eclipse.jetty.util.Loader;
46 import org.eclipse.jetty.util.TypeUtil;
47 import org.eclipse.jetty.util.component.LifeCycle;
48 import org.eclipse.jetty.util.log.Log;
49 import org.eclipse.jetty.util.log.Logger;
50 import org.eclipse.jetty.util.resource.Resource;
51 import org.eclipse.jetty.xml.XmlParser.Node;
52 import org.xml.sax.InputSource;
53 import org.xml.sax.SAXException;
54
55
56
57
58
59
60
61
62
63
64
65 public class XmlConfiguration
66 {
67 private static final Logger LOG = Log.getLogger(XmlConfiguration.class);
68
69 private static final Class<?>[] __primitives =
70 { Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE };
71
72 private static final Class<?>[] __primitiveHolders =
73 { Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class };
74
75 private static final Class<?>[] __supportedCollections =
76 { ArrayList.class,ArrayQueue.class,HashSet.class,Queue.class,List.class,Set.class,Collection.class,};
77
78 private static final Iterable<?> __factoryLoader;
79
80 private static final XmlParser __parser = initParser();
81
82 static
83 {
84 Iterable<?> loader=null;
85 try
86 {
87
88
89 Class<?> slc = ClassLoader.getSystemClassLoader().loadClass("java.util.ServiceLoader");
90 Method load = slc.getMethod("load",Class.class);
91 loader=(Iterable<?>)load.invoke(null,ConfigurationProcessorFactory.class);
92 }
93 catch(Exception e)
94 {
95 LOG.ignore(e);
96 }
97 finally
98 {
99 __factoryLoader=loader;
100 }
101 }
102
103
104 private URL _url;
105 private String _dtd;
106 private ConfigurationProcessor _processor;
107 private final Map<String, Object> _idMap = new HashMap<String, Object>();
108 private final Map<String, String> _propertyMap = new HashMap<String, String>();
109
110
111 private synchronized static XmlParser initParser()
112 {
113 XmlParser parser = new XmlParser();
114 try
115 {
116 URL config60 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_6_0.dtd",true);
117 URL config76 = Loader.getResource(XmlConfiguration.class,"org/eclipse/jetty/xml/configure_7_6.dtd",true);
118 parser.redirectEntity("configure.dtd",config76);
119 parser.redirectEntity("configure_1_0.dtd",config60);
120 parser.redirectEntity("configure_1_1.dtd",config60);
121 parser.redirectEntity("configure_1_2.dtd",config60);
122 parser.redirectEntity("configure_1_3.dtd",config60);
123 parser.redirectEntity("configure_6_0.dtd",config60);
124 parser.redirectEntity("configure_7_6.dtd",config76);
125
126 parser.redirectEntity("http://jetty.mortbay.org/configure.dtd",config76);
127 parser.redirectEntity("http://jetty.eclipse.org/configure.dtd",config76);
128 parser.redirectEntity("http://www.eclipse.org/jetty/configure.dtd",config76);
129
130 parser.redirectEntity("-//Mort Bay Consulting//DTD Configure//EN",config76);
131 parser.redirectEntity("-//Jetty//Configure//EN",config76);
132 }
133 catch (ClassNotFoundException e)
134 {
135 LOG.warn(e.toString());
136 LOG.debug(e);
137 }
138 return parser;
139 }
140
141
142
143
144
145
146
147
148
149 public XmlConfiguration(URL configuration) throws SAXException, IOException
150 {
151 synchronized (__parser)
152 {
153 _url=configuration;
154 setConfig(__parser.parse(configuration.toString()));
155 _dtd=__parser.getDTD();
156 }
157 }
158
159
160
161
162
163
164
165
166
167
168 public XmlConfiguration(String configuration) throws SAXException, IOException
169 {
170 configuration = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<!DOCTYPE Configure PUBLIC \"-//Mort Bay Consulting//DTD Configure 1.2//EN\" \"http://jetty.eclipse.org/configure_1_2.dtd\">"
171 + configuration;
172 InputSource source = new InputSource(new StringReader(configuration));
173 synchronized (__parser)
174 {
175 setConfig( __parser.parse(source));
176 _dtd=__parser.getDTD();
177 }
178 }
179
180
181
182
183
184
185
186
187
188 public XmlConfiguration(InputStream configuration) throws SAXException, IOException
189 {
190 InputSource source = new InputSource(configuration);
191 synchronized (__parser)
192 {
193 setConfig(__parser.parse(source));
194 _dtd=__parser.getDTD();
195 }
196 }
197
198
199 private void setConfig(XmlParser.Node config)
200 {
201 if ("Configure".equals(config.getTag()))
202 {
203 _processor=new JettyXmlConfiguration();
204 }
205 else if (__factoryLoader!=null)
206 {
207 for ( Object factory : __factoryLoader)
208 {
209
210 Method gcp;
211 try
212 {
213 gcp = factory.getClass().getMethod("getConfigurationProcessor",String.class,String.class);
214 _processor = (ConfigurationProcessor) gcp.invoke(factory,_dtd,config.getTag());
215 }
216 catch (Exception e)
217 {
218 LOG.warn(e);
219 }
220 if (_processor!=null)
221 break;
222 }
223
224 if (_processor==null)
225 throw new IllegalStateException("Unknown configuration type: "+config.getTag()+" in "+this);
226 }
227 else
228 {
229 throw new IllegalArgumentException("Unknown XML tag:"+config.getTag());
230 }
231 _processor.init(_url,config,_idMap, _propertyMap);
232 }
233
234
235
236 public Map<String, Object> getIdMap()
237 {
238 return _idMap;
239 }
240
241
242
243
244
245
246 @Deprecated
247 public void setIdMap(Map<String, Object> map)
248 {
249 _idMap.clear();
250 _idMap.putAll(map);
251 }
252
253
254
255
256
257
258 @Deprecated
259 public void setProperties(Map<String, String> map)
260 {
261 _propertyMap.clear();
262 _propertyMap.putAll(map);
263 }
264
265
266 public Map<String, String> getProperties()
267 {
268 return _propertyMap;
269 }
270
271
272
273
274
275
276
277
278
279
280 public Object configure(Object obj) throws Exception
281 {
282 return _processor.configure(obj);
283 }
284
285
286
287
288
289
290
291
292
293
294
295 public Object configure() throws Exception
296 {
297 return _processor.configure();
298 }
299
300
301
302
303 private static class JettyXmlConfiguration implements ConfigurationProcessor
304 {
305 XmlParser.Node _config;
306 Map<String, Object> _idMap;
307 Map<String, String> _propertyMap;
308
309 public void init(URL url, XmlParser.Node config, Map<String, Object> idMap, Map<String, String> properties)
310 {
311 _config=config;
312 _idMap=idMap;
313 _propertyMap=properties;
314 }
315
316
317 public Object configure(Object obj) throws Exception
318 {
319
320 Class<?> oClass = nodeClass(_config);
321 if (oClass != null && !oClass.isInstance(obj))
322 {
323 String loaders = (oClass.getClassLoader()==obj.getClass().getClassLoader())?"":"Object Class and type Class are from different loaders.";
324 throw new IllegalArgumentException("Object of class '"+obj.getClass().getCanonicalName()+"' is not of type '" + oClass.getCanonicalName()+"'. "+loaders);
325 }
326 configure(obj,_config,0);
327 return obj;
328 }
329
330
331 public Object configure() throws Exception
332 {
333 Class<?> oClass = nodeClass(_config);
334
335 String id = _config.getAttribute("id");
336 Object obj = id == null?null:_idMap.get(id);
337
338 if (obj == null && oClass != null)
339 obj = oClass.newInstance();
340
341 if (oClass != null && !oClass.isInstance(obj))
342 throw new ClassCastException(oClass.toString());
343
344 configure(obj,_config,0);
345 return obj;
346 }
347
348
349 private static Class<?> nodeClass(XmlParser.Node node) throws ClassNotFoundException
350 {
351 String className = node.getAttribute("class");
352 if (className == null)
353 return null;
354
355 return Loader.loadClass(XmlConfiguration.class,className,true);
356 }
357
358
359
360
361
362
363
364
365
366
367
368 public void configure(Object obj, XmlParser.Node cfg, int i) throws Exception
369 {
370 String id = cfg.getAttribute("id");
371 if (id != null)
372 _idMap.put(id,obj);
373
374 for (; i < cfg.size(); i++)
375 {
376 Object o = cfg.get(i);
377 if (o instanceof String)
378 continue;
379 XmlParser.Node node = (XmlParser.Node)o;
380
381 try
382 {
383 String tag = node.getTag();
384 if ("Set".equals(tag))
385 set(obj,node);
386 else if ("Put".equals(tag))
387 put(obj,node);
388 else if ("Call".equals(tag))
389 call(obj,node);
390 else if ("Get".equals(tag))
391 get(obj,node);
392 else if ("New".equals(tag))
393 newObj(obj,node);
394 else if ("Array".equals(tag))
395 newArray(obj,node);
396 else if ("Ref".equals(tag))
397 refObj(obj,node);
398 else if ("Property".equals(tag))
399 propertyObj(node);
400 else
401 throw new IllegalStateException("Unknown tag: " + tag);
402 }
403 catch (Exception e)
404 {
405 LOG.warn("Config error at " + node,e.toString());
406 throw e;
407 }
408 }
409 }
410
411
412
413
414
415
416
417
418
419 private void set(Object obj, XmlParser.Node node) throws Exception
420 {
421 String attr = node.getAttribute("name");
422 String name = "set" + attr.substring(0,1).toUpperCase() + attr.substring(1);
423 Object value = value(obj,node);
424 Object[] arg =
425 { value };
426
427 Class<?> oClass = nodeClass(node);
428 if (oClass != null)
429 obj = null;
430 else
431 oClass = obj.getClass();
432
433 Class<?>[] vClass =
434 { Object.class };
435 if (value != null)
436 vClass[0] = value.getClass();
437
438 if (LOG.isDebugEnabled())
439 LOG.debug("XML " + (obj != null?obj.toString():oClass.getName()) + "." + name + "(" + value + ")");
440
441
442 try
443 {
444 Method set = oClass.getMethod(name,vClass);
445 set.invoke(obj,arg);
446 return;
447 }
448 catch (IllegalArgumentException e)
449 {
450 LOG.ignore(e);
451 }
452 catch (IllegalAccessException e)
453 {
454 LOG.ignore(e);
455 }
456 catch (NoSuchMethodException e)
457 {
458 LOG.ignore(e);
459 }
460
461
462 try
463 {
464 Field type = vClass[0].getField("TYPE");
465 vClass[0] = (Class<?>)type.get(null);
466 Method set = oClass.getMethod(name,vClass);
467 set.invoke(obj,arg);
468 return;
469 }
470 catch (NoSuchFieldException e)
471 {
472 LOG.ignore(e);
473 }
474 catch (IllegalArgumentException e)
475 {
476 LOG.ignore(e);
477 }
478 catch (IllegalAccessException e)
479 {
480 LOG.ignore(e);
481 }
482 catch (NoSuchMethodException e)
483 {
484 LOG.ignore(e);
485 }
486
487
488 try
489 {
490 Field field = oClass.getField(attr);
491 if (Modifier.isPublic(field.getModifiers()))
492 {
493 field.set(obj,value);
494 return;
495 }
496 }
497 catch (NoSuchFieldException e)
498 {
499 LOG.ignore(e);
500 }
501
502
503 Method[] sets = oClass.getMethods();
504 Method set = null;
505 for (int s = 0; sets != null && s < sets.length; s++)
506 {
507 Class<?>[] paramTypes = sets[s].getParameterTypes();
508 if (name.equals(sets[s].getName()) && paramTypes.length == 1)
509 {
510
511
512 try
513 {
514 set = sets[s];
515 sets[s].invoke(obj,arg);
516 return;
517 }
518 catch (IllegalArgumentException e)
519 {
520 LOG.ignore(e);
521 }
522 catch (IllegalAccessException e)
523 {
524 LOG.ignore(e);
525 }
526
527 try
528 {
529 for (Class<?> c : __supportedCollections)
530 if (paramTypes[0].isAssignableFrom(c))
531 {
532 sets[s].invoke(obj,convertArrayToCollection(value,c));
533 return;
534 }
535 }
536 catch (IllegalAccessException e)
537 {
538 LOG.ignore(e);
539 }
540 }
541 }
542
543
544 if (set != null)
545 {
546 try
547 {
548 Class<?> sClass = set.getParameterTypes()[0];
549 if (sClass.isPrimitive())
550 {
551 for (int t = 0; t < __primitives.length; t++)
552 {
553 if (sClass.equals(__primitives[t]))
554 {
555 sClass = __primitiveHolders[t];
556 break;
557 }
558 }
559 }
560 Constructor<?> cons = sClass.getConstructor(vClass);
561 arg[0] = cons.newInstance(arg);
562 set.invoke(obj,arg);
563 return;
564 }
565 catch (NoSuchMethodException e)
566 {
567 LOG.ignore(e);
568 }
569 catch (IllegalAccessException e)
570 {
571 LOG.ignore(e);
572 }
573 catch (InstantiationException e)
574 {
575 LOG.ignore(e);
576 }
577 }
578
579
580 throw new NoSuchMethodException(oClass + "." + name + "(" + vClass[0] + ")");
581 }
582
583
584
585
586
587
588 private static Collection<?> convertArrayToCollection(Object array, Class<?> collectionType)
589 {
590 Collection<?> collection = null;
591 if (array.getClass().isArray())
592 {
593 if (collectionType.isAssignableFrom(ArrayList.class))
594 collection = convertArrayToArrayList(array);
595 else if (collectionType.isAssignableFrom(HashSet.class))
596 collection = new HashSet<Object>(convertArrayToArrayList(array));
597 else if (collectionType.isAssignableFrom(ArrayQueue.class))
598 {
599 ArrayQueue<Object> q= new ArrayQueue<Object>();
600 q.addAll(convertArrayToArrayList(array));
601 collection=q;
602 }
603 }
604 if (collection==null)
605 throw new IllegalArgumentException("Can't convert \"" + array.getClass() + "\" to " + collectionType);
606 return collection;
607 }
608
609
610 private static ArrayList<Object> convertArrayToArrayList(Object array)
611 {
612 int length = Array.getLength(array);
613 ArrayList<Object> list = new ArrayList<Object>(length);
614 for (int i = 0; i < length; i++)
615 list.add(Array.get(array,i));
616 return list;
617 }
618
619
620
621
622
623
624
625 private void put(Object obj, XmlParser.Node node) throws Exception
626 {
627 if (!(obj instanceof Map))
628 throw new IllegalArgumentException("Object for put is not a Map: " + obj);
629 @SuppressWarnings("unchecked")
630 Map<Object, Object> map = (Map<Object, Object>)obj;
631
632 String name = node.getAttribute("name");
633 Object value = value(obj,node);
634 map.put(name,value);
635 if (LOG.isDebugEnabled())
636 LOG.debug("XML " + obj + ".put(" + name + "," + value + ")");
637 }
638
639
640
641
642
643
644
645 private Object get(Object obj, XmlParser.Node node) throws Exception
646 {
647 Class<?> oClass = nodeClass(node);
648 if (oClass != null)
649 obj = null;
650 else
651 oClass = obj.getClass();
652
653 String name = node.getAttribute("name");
654 String id = node.getAttribute("id");
655 if (LOG.isDebugEnabled())
656 LOG.debug("XML get " + name);
657
658 try
659 {
660
661 Method method = oClass.getMethod("get" + name.substring(0,1).toUpperCase() + name.substring(1),(java.lang.Class[])null);
662 obj = method.invoke(obj,(java.lang.Object[])null);
663 configure(obj,node,0);
664 }
665 catch (NoSuchMethodException nsme)
666 {
667 try
668 {
669 Field field = oClass.getField(name);
670 obj = field.get(obj);
671 configure(obj,node,0);
672 }
673 catch (NoSuchFieldException nsfe)
674 {
675 throw nsme;
676 }
677 }
678 if (id != null)
679 _idMap.put(id,obj);
680 return obj;
681 }
682
683
684
685
686
687
688
689
690
691 private Object call(Object obj, XmlParser.Node node) throws Exception
692 {
693 String id = node.getAttribute("id");
694 Class<?> oClass = nodeClass(node);
695 if (oClass != null)
696 obj = null;
697 else if (obj != null)
698 oClass = obj.getClass();
699 if (oClass == null)
700 throw new IllegalArgumentException(node.toString());
701
702 int size = 0;
703 int argi = node.size();
704 for (int i = 0; i < node.size(); i++)
705 {
706 Object o = node.get(i);
707 if (o instanceof String)
708 continue;
709 if (!((XmlParser.Node)o).getTag().equals("Arg"))
710 {
711 argi = i;
712 break;
713 }
714 size++;
715 }
716
717 Object[] arg = new Object[size];
718 for (int i = 0, j = 0; j < size; i++)
719 {
720 Object o = node.get(i);
721 if (o instanceof String)
722 continue;
723 arg[j++] = value(obj,(XmlParser.Node)o);
724 }
725
726 String method = node.getAttribute("name");
727 if (LOG.isDebugEnabled())
728 LOG.debug("XML call " + method);
729
730 try
731 {
732 Object n= TypeUtil.call(oClass,method,obj,arg);
733 if (id != null)
734 _idMap.put(id,n);
735 configure(n,node,argi);
736 return n;
737 }
738 catch (NoSuchMethodException e)
739 {
740 IllegalStateException ise = new IllegalStateException("No Method: " + node + " on " + oClass);
741 ise.initCause(e);
742 throw ise;
743 }
744
745 }
746
747
748
749
750
751
752
753 private Object newObj(Object obj, XmlParser.Node node) throws Exception
754 {
755 Class<?> oClass = nodeClass(node);
756 String id = node.getAttribute("id");
757 int size = 0;
758 int argi = node.size();
759 for (int i = 0; i < node.size(); i++)
760 {
761 Object o = node.get(i);
762 if (o instanceof String)
763 continue;
764 if (!((XmlParser.Node)o).getTag().equals("Arg"))
765 {
766 argi = i;
767 break;
768 }
769 size++;
770 }
771
772 Object[] arg = new Object[size];
773 for (int i = 0, j = 0; j < size; i++)
774 {
775 Object o = node.get(i);
776 if (o instanceof String)
777 continue;
778 arg[j++] = value(obj,(XmlParser.Node)o);
779 }
780
781 if (LOG.isDebugEnabled())
782 LOG.debug("XML new " + oClass);
783
784
785 Constructor<?>[] constructors = oClass.getConstructors();
786 for (int c = 0; constructors != null && c < constructors.length; c++)
787 {
788 if (constructors[c].getParameterTypes().length != size)
789 continue;
790
791 Object n = null;
792 boolean called = false;
793 try
794 {
795 n = constructors[c].newInstance(arg);
796 called = true;
797 }
798 catch (IllegalAccessException e)
799 {
800 LOG.ignore(e);
801 }
802 catch (InstantiationException e)
803 {
804 LOG.ignore(e);
805 }
806 catch (IllegalArgumentException e)
807 {
808 LOG.ignore(e);
809 }
810 if (called)
811 {
812 if (id != null)
813 _idMap.put(id,n);
814 configure(n,node,argi);
815 return n;
816 }
817 }
818
819 throw new IllegalStateException("No Constructor: " + node + " on " + obj);
820 }
821
822
823
824
825
826
827
828 private Object refObj(Object obj, XmlParser.Node node) throws Exception
829 {
830 String id = node.getAttribute("id");
831 obj = _idMap.get(id);
832 if (obj == null)
833 throw new IllegalStateException("No object for id=" + id);
834 configure(obj,node,0);
835 return obj;
836 }
837
838
839
840
841
842 private Object newArray(Object obj, XmlParser.Node node) throws Exception
843 {
844
845
846 Class<?> aClass = java.lang.Object.class;
847 String type = node.getAttribute("type");
848 final String id = node.getAttribute("id");
849 if (type != null)
850 {
851 aClass = TypeUtil.fromName(type);
852 if (aClass == null)
853 {
854 if ("String".equals(type))
855 aClass = java.lang.String.class;
856 else if ("URL".equals(type))
857 aClass = java.net.URL.class;
858 else if ("InetAddress".equals(type))
859 aClass = java.net.InetAddress.class;
860 else
861 aClass = Loader.loadClass(XmlConfiguration.class,type,true);
862 }
863 }
864
865 Object al = null;
866
867 for (Object nodeObject : node)
868 {
869 XmlParser.Node item = (Node)nodeObject;
870 String nid = item.getAttribute("id");
871 Object v = value(obj,item);
872 al = LazyList.add(al,(v == null && aClass.isPrimitive())?0:v);
873 if (nid != null)
874 _idMap.put(nid,v);
875 }
876
877 Object array = LazyList.toArray(al,aClass);
878 if (id != null)
879 _idMap.put(id,array);
880 return array;
881 }
882
883
884
885
886
887 private Object newMap(Object obj, XmlParser.Node node) throws Exception
888 {
889 String id = node.getAttribute("id");
890
891 Map<Object, Object> map = new HashMap<Object, Object>();
892 if (id != null)
893 _idMap.put(id,map);
894
895 for (Object o : node)
896 {
897 if (o instanceof String)
898 continue;
899 XmlParser.Node entry = (XmlParser.Node)o;
900 if (!entry.getTag().equals("Entry"))
901 throw new IllegalStateException("Not an Entry");
902
903 XmlParser.Node key = null;
904 XmlParser.Node value = null;
905
906 for (Object object : entry)
907 {
908 if (object instanceof String)
909 continue;
910 XmlParser.Node item = (XmlParser.Node)object;
911 if (!item.getTag().equals("Item"))
912 throw new IllegalStateException("Not an Item");
913 if (key == null)
914 key = item;
915 else
916 value = item;
917 }
918
919 if (key == null || value == null)
920 throw new IllegalStateException("Missing Item in Entry");
921 String kid = key.getAttribute("id");
922 String vid = value.getAttribute("id");
923
924 Object k = value(obj,key);
925 Object v = value(obj,value);
926 map.put(k,v);
927
928 if (kid != null)
929 _idMap.put(kid,k);
930 if (vid != null)
931 _idMap.put(vid,v);
932 }
933
934 return map;
935 }
936
937
938
939
940
941
942
943
944
945 private Object propertyObj(XmlParser.Node node) throws Exception
946 {
947 String id = node.getAttribute("id");
948 String name = node.getAttribute("name");
949 String defaultValue = node.getAttribute("default");
950 Object prop;
951 if (_propertyMap != null && _propertyMap.containsKey(name))
952 prop = _propertyMap.get(name);
953 else
954 prop = defaultValue;
955 if (id != null)
956 _idMap.put(id,prop);
957 if (prop != null)
958 configure(prop,node,0);
959 return prop;
960 }
961
962
963
964
965
966
967
968 private Object value(Object obj, XmlParser.Node node) throws Exception
969 {
970 Object value;
971
972
973 String type = node.getAttribute("type");
974
975
976 String ref = node.getAttribute("ref");
977 if (ref != null)
978 {
979 value = _idMap.get(ref);
980 }
981 else
982 {
983
984 if (node.size() == 0)
985 {
986 if ("String".equals(type))
987 return "";
988 return null;
989 }
990
991
992 int first = 0;
993 int last = node.size() - 1;
994
995
996 if (type == null || !"String".equals(type))
997 {
998
999 Object item;
1000 while (first <= last)
1001 {
1002 item = node.get(first);
1003 if (!(item instanceof String))
1004 break;
1005 item = ((String)item).trim();
1006 if (((String)item).length() > 0)
1007 break;
1008 first++;
1009 }
1010
1011
1012 while (first < last)
1013 {
1014 item = node.get(last);
1015 if (!(item instanceof String))
1016 break;
1017 item = ((String)item).trim();
1018 if (((String)item).length() > 0)
1019 break;
1020 last--;
1021 }
1022
1023
1024 if (first > last)
1025 return null;
1026 }
1027
1028 if (first == last)
1029
1030 value = itemValue(obj,node.get(first));
1031 else
1032 {
1033
1034 StringBuilder buf = new StringBuilder();
1035 for (int i = first; i <= last; i++)
1036 {
1037 Object item = node.get(i);
1038 buf.append(itemValue(obj,item));
1039 }
1040 value = buf.toString();
1041 }
1042 }
1043
1044
1045 if (value == null)
1046 {
1047 if ("String".equals(type))
1048 return "";
1049 return null;
1050 }
1051
1052
1053 if (type == null)
1054 {
1055 if (value instanceof String)
1056 return ((String)value).trim();
1057 return value;
1058 }
1059
1060 if (isTypeMatchingClass(type,String.class))
1061 return value.toString();
1062
1063 Class<?> pClass = TypeUtil.fromName(type);
1064 if (pClass != null)
1065 return TypeUtil.valueOf(pClass,value.toString());
1066
1067 if (isTypeMatchingClass(type,URL.class))
1068 {
1069 if (value instanceof URL)
1070 return value;
1071 try
1072 {
1073 return new URL(value.toString());
1074 }
1075 catch (MalformedURLException e)
1076 {
1077 throw new InvocationTargetException(e);
1078 }
1079 }
1080
1081 if (isTypeMatchingClass(type,InetAddress.class))
1082 {
1083 if (value instanceof InetAddress)
1084 return value;
1085 try
1086 {
1087 return InetAddress.getByName(value.toString());
1088 }
1089 catch (UnknownHostException e)
1090 {
1091 throw new InvocationTargetException(e);
1092 }
1093 }
1094
1095 for (Class<?> collectionClass : __supportedCollections)
1096 {
1097 if (isTypeMatchingClass(type,collectionClass))
1098 return convertArrayToCollection(value,collectionClass);
1099 }
1100
1101 throw new IllegalStateException("Unknown type " + type);
1102 }
1103
1104
1105 private static boolean isTypeMatchingClass(String type, Class<?> classToMatch)
1106 {
1107 return classToMatch.getSimpleName().equalsIgnoreCase(type) || classToMatch.getName().equals(type);
1108 }
1109
1110
1111
1112
1113
1114 private Object itemValue(Object obj, Object item) throws Exception
1115 {
1116
1117 if (item instanceof String)
1118 return item;
1119
1120 XmlParser.Node node = (XmlParser.Node)item;
1121 String tag = node.getTag();
1122 if ("Call".equals(tag))
1123 return call(obj,node);
1124 if ("Get".equals(tag))
1125 return get(obj,node);
1126 if ("New".equals(tag))
1127 return newObj(obj,node);
1128 if ("Ref".equals(tag))
1129 return refObj(obj,node);
1130 if ("Array".equals(tag))
1131 return newArray(obj,node);
1132 if ("Map".equals(tag))
1133 return newMap(obj,node);
1134 if ("Property".equals(tag))
1135 return propertyObj(node);
1136
1137 if ("SystemProperty".equals(tag))
1138 {
1139 String name = node.getAttribute("name");
1140 String defaultValue = node.getAttribute("default");
1141 return System.getProperty(name,defaultValue);
1142 }
1143
1144 if ("Env".equals(tag))
1145 {
1146 String name = node.getAttribute("name");
1147 String defaultValue = node.getAttribute("default");
1148 String value=System.getenv(name);
1149 return value==null?defaultValue:value;
1150 }
1151
1152 LOG.warn("Unknown value tag: " + node,new Throwable());
1153 return null;
1154 }
1155 }
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178 public static void main(final String[] args) throws Exception
1179 {
1180
1181 final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
1182
1183 AccessController.doPrivileged(new PrivilegedAction<Object>()
1184 {
1185 public Object run()
1186 {
1187 try
1188 {
1189
1190 Properties properties = null;
1191
1192
1193 try
1194 {
1195 Class<?> config = XmlConfiguration.class.getClassLoader().loadClass("org.eclipse.jetty.start.Config");
1196 properties = (Properties)config.getMethod("getProperties").invoke(null);
1197 LOG.debug("org.eclipse.jetty.start.Config properties = {}",properties);
1198 }
1199 catch (NoClassDefFoundError e)
1200 {
1201 LOG.ignore(e);
1202 }
1203 catch (ClassNotFoundException e)
1204 {
1205 LOG.ignore(e);
1206 }
1207 catch (Exception e)
1208 {
1209 LOG.warn(e);
1210 }
1211
1212
1213 if (properties == null)
1214 {
1215 properties = new Properties();
1216
1217 Enumeration<?> ensysprop = System.getProperties().propertyNames();
1218 while (ensysprop.hasMoreElements())
1219 {
1220 String name = (String)ensysprop.nextElement();
1221 properties.put(name,System.getProperty(name));
1222 }
1223 }
1224
1225
1226 XmlConfiguration last = null;
1227 Object[] obj = new Object[args.length];
1228 for (int i = 0; i < args.length; i++)
1229 {
1230 if (args[i].toLowerCase().endsWith(".properties"))
1231 {
1232 properties.load(Resource.newResource(args[i]).getInputStream());
1233 }
1234 else
1235 {
1236 XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(args[i]).getURL());
1237 if (last != null)
1238 configuration.getIdMap().putAll(last.getIdMap());
1239 if (properties.size() > 0)
1240 {
1241 Map<String, String> props = new HashMap<String, String>();
1242 for (Object key : properties.keySet())
1243 {
1244 props.put(key.toString(),String.valueOf(properties.get(key)));
1245 }
1246 configuration.getProperties().putAll(props);
1247 }
1248 obj[i] = configuration.configure();
1249 last = configuration;
1250 }
1251 }
1252
1253
1254 for (int i = 0; i < args.length; i++)
1255 {
1256 if (obj[i] instanceof LifeCycle)
1257 {
1258 LifeCycle lc = (LifeCycle)obj[i];
1259 if (!lc.isRunning())
1260 lc.start();
1261 }
1262 }
1263 }
1264 catch (Exception e)
1265 {
1266 LOG.debug(Log.EXCEPTION,e);
1267 exception.set(e);
1268 }
1269 return null;
1270 }
1271 });
1272
1273 Throwable th = exception.get();
1274 if (th != null)
1275 {
1276 if (th instanceof RuntimeException)
1277 throw (RuntimeException)th;
1278 else if (th instanceof Exception)
1279 throw (Exception)th;
1280 else if (th instanceof Error)
1281 throw (Error)th;
1282 throw new Error(th);
1283 }
1284 }
1285 }