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