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