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