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