1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.settings4j.config;
18
19 import java.beans.PropertyDescriptor;
20 import java.io.IOException;
21 import java.lang.reflect.Constructor;
22 import java.lang.reflect.InvocationTargetException;
23 import java.lang.reflect.Method;
24 import java.net.URL;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29
30 import javax.xml.parsers.DocumentBuilder;
31 import javax.xml.parsers.DocumentBuilderFactory;
32 import javax.xml.parsers.FactoryConfigurationError;
33
34 import org.apache.commons.beanutils.PropertyUtils;
35 import org.apache.commons.lang3.BooleanUtils;
36 import org.apache.commons.lang3.StringUtils;
37 import org.settings4j.Connector;
38 import org.settings4j.ContentResolver;
39 import org.settings4j.Filter;
40 import org.settings4j.ObjectResolver;
41 import org.settings4j.Settings4jInstance;
42 import org.settings4j.Settings4jRepository;
43 import org.settings4j.connector.CachedConnectorWrapper;
44 import org.settings4j.connector.FilteredConnectorWrapper;
45 import org.settings4j.contentresolver.ClasspathContentResolver;
46 import org.settings4j.contentresolver.FilteredContentResolverWrapper;
47 import org.settings4j.objectresolver.AbstractObjectResolver;
48 import org.settings4j.objectresolver.FilteredObjectResolverWrapper;
49 import org.settings4j.settings.DefaultFilter;
50 import org.settings4j.util.ELConnectorWrapper;
51 import org.settings4j.util.ExpressionLanguageUtil;
52 import org.w3c.dom.Document;
53 import org.w3c.dom.Element;
54 import org.w3c.dom.NamedNodeMap;
55 import org.w3c.dom.Node;
56 import org.w3c.dom.NodeList;
57 import org.xml.sax.SAXException;
58
59
60
61
62 public class DOMConfigurator {
63
64
65 private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(DOMConfigurator.class);
66
67 private static final String CONFIGURATION_TAG = "settings4j:configuration";
68
69 private static final String CONNECTOR_TAG = "connector";
70
71 private static final String CONNECTOR_REF_TAG = "connector-ref";
72
73 private static final String OBJECT_RESOLVER_TAG = "objectResolver";
74
75 private static final String OBJECT_RESOLVER_REF_TAG = "objectResolver-ref";
76
77 private static final String CONTENT_RESOLVER_TAG = "contentResolver";
78
79 private static final String CONTENT_RESOLVER_REF_TAG = "contentResolver-ref";
80
81 private static final String MAPPING_TAG = "mapping";
82
83 private static final String FILTER_TAG = "filter";
84
85 private static final String EXCLUDE_TAG = "exclude";
86
87 private static final String INCLUDE_TAG = "include";
88
89 private static final String ENTRY_TAG = "entry";
90
91 private static final String ENTRY_KEY_ATTR = "key";
92
93 private static final String ENTRY_REFKEY_ATTR = "ref-key";
94
95 private static final String PARAM_TAG = "param";
96
97 private static final String NAME_ATTR = "name";
98
99 private static final String CLASS_ATTR = "class";
100
101 private static final String PATTERN_ATTR = "pattern";
102
103 private static final String CACHED_ATTR = "cached";
104
105 private static final String VALUE_ATTR = "value";
106
107 private static final String REF_ATTR = "ref";
108
109 private static final String DOCUMENT_BUILDER_FACTORY_KEY = "javax.xml.parsers.DocumentBuilderFactory";
110
111
112
113 private final Map<String, Connector> connectorBag;
114
115 private final Map<String, ContentResolver> contentResolverBag;
116
117 private final Map<String, ObjectResolver> objectResolverBag;
118
119 private final Settings4jRepository repository;
120
121 private final Map<String, Object> expressionAttributes = new HashMap<String, Object>();
122
123
124
125
126
127 public DOMConfigurator(final Settings4jRepository repository) {
128 super();
129 this.repository = repository;
130 this.connectorBag = new HashMap<String, Connector>();
131 this.contentResolverBag = new HashMap<String, ContentResolver>();
132 this.objectResolverBag = new HashMap<String, ObjectResolver>();
133 }
134
135
136
137
138
139
140
141
142 private void setParameter(final Element elem, final Object bean, final Connector[] connectors) {
143 final String name = elem.getAttribute(NAME_ATTR);
144 final String valueStr = elem.getAttribute(VALUE_ATTR);
145 try {
146 final PropertyDescriptor propertyDescriptor = PropertyUtils.getPropertyDescriptor(bean, name);
147 final Method setter = PropertyUtils.getWriteMethod(propertyDescriptor);
148 Object value;
149 if (connectors != null) {
150 value = subst(valueStr, connectors, setter.getParameterTypes()[0]);
151 } else {
152 value = subst(valueStr, null, setter.getParameterTypes()[0]);
153 }
154 PropertyUtils.setProperty(bean, name, value);
155 } catch (final IllegalAccessException e) {
156 LOG.warn("Cannnot set Property: " + name, e);
157 } catch (final InvocationTargetException e) {
158 LOG.warn("Cannnot set Property: " + name, e);
159 } catch (final NoSuchMethodException e) {
160 LOG.warn("Cannnot set Property: " + name, e);
161 }
162 }
163
164
165
166
167
168
169
170
171 public static void configure(
172 final URL url, final Settings4jRepository repository) throws FactoryConfigurationError {
173 new DOMConfigurator(repository).doConfigure(url);
174 }
175
176
177
178
179 public void doConfigure(final URL url) {
180 final ParseAction action = new ParseAction() {
181
182 public Document parse(final DocumentBuilder parser) throws SAXException, IOException {
183 return parser.parse(url.toString());
184 }
185
186 @Override
187 public String toString() {
188 return "url [" + url.toString() + "]";
189 }
190 };
191 doConfigure(action);
192 }
193
194 private void doConfigure(final ParseAction action) throws FactoryConfigurationError {
195 DocumentBuilderFactory dbf = null;
196 try {
197 LOG.debug("System property is: {}", System.getProperty(DOCUMENT_BUILDER_FACTORY_KEY));
198 dbf = DocumentBuilderFactory.newInstance();
199 LOG.debug("Standard DocumentBuilderFactory search succeded.");
200 LOG.debug("DocumentBuilderFactory is: {}", dbf.getClass().getName());
201 } catch (final FactoryConfigurationError fce) {
202 final Exception e = fce.getException();
203 LOG.debug("Could not instantiate a DocumentBuilderFactory.", e);
204 throw fce;
205 }
206
207 try {
208 dbf.setValidating(true);
209
210 final DocumentBuilder docBuilder = dbf.newDocumentBuilder();
211
212 docBuilder.setErrorHandler(new SAXErrorHandler());
213 docBuilder.setEntityResolver(new Settings4jEntityResolver());
214
215 final Document doc = action.parse(docBuilder);
216 parse(doc.getDocumentElement());
217 } catch (final Exception e) {
218
219 LOG.error("Could not parse " + action.toString() + ".", e);
220 }
221 }
222
223
224
225
226
227
228
229 protected void parse(final Element element) {
230
231 final String rootElementName = element.getTagName();
232
233 if (!rootElementName.equals(CONFIGURATION_TAG)) {
234 LOG.error("DOM element is - not a <{}> element.", CONFIGURATION_TAG);
235 return;
236 }
237
238 final Settings4jInstance root = this.repository.getSettings();
239
240 synchronized (root) {
241 parseChildrenOfSettingsElement(element, root);
242 }
243 }
244
245
246
247
248
249
250
251 protected Filter parseFilter(final Element filterElement) {
252
253 Filter filter;
254
255
256 String className = filterElement.getAttribute(CLASS_ATTR);
257 if (StringUtils.isEmpty(className)) {
258 className = DefaultFilter.class.getName();
259 }
260
261 LOG.debug("Desired Connector class: [{}]", className);
262 try {
263 final Class clazz = loadClass(className);
264 final Constructor constructor = clazz.getConstructor();
265 filter = (Filter) constructor.newInstance();
266 } catch (final Exception oops) {
267 LOG.error("Could not retrieve connector [filter: " + className + "]. Reported error follows.", oops);
268 return null;
269 }
270
271 final NodeList children = filterElement.getChildNodes();
272 final int length = children.getLength();
273
274 for (int loop = 0; loop < length; loop++) {
275 final Node currentNode = children.item(loop);
276
277 if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
278 final Element currentElement = (Element) currentNode;
279 final String tagName = currentElement.getTagName();
280
281 if (tagName.equals(INCLUDE_TAG)) {
282 final Element includeTag = (Element) currentNode;
283 final String patteren = includeTag.getAttribute(PATTERN_ATTR);
284 filter.addInclude(patteren);
285
286 } else if (tagName.equals(EXCLUDE_TAG)) {
287 final Element excludeTag = (Element) currentNode;
288 final String patteren = excludeTag.getAttribute(PATTERN_ATTR);
289 filter.addExclude(patteren);
290 } else {
291 quietParseUnrecognizedElement(filter, currentElement);
292 }
293 }
294 }
295
296 return filter;
297 }
298
299
300
301
302
303
304
305 protected Connector parseConnector(final Element connectorElement) {
306 final String connectorName = connectorElement.getAttribute(NAME_ATTR);
307
308 Connector connector;
309
310 final String className = connectorElement.getAttribute(CLASS_ATTR);
311
312
313 LOG.debug("Desired Connector class: [{}]", className);
314 try {
315 final Class clazz = loadClass(className);
316 final Constructor constructor = clazz.getConstructor();
317 connector = (Connector) constructor.newInstance();
318 } catch (final Exception oops) {
319 LOG.error("Could not retrieve connector [" + connectorName + "]. Reported error follows.", oops);
320 return null;
321 }
322
323 connector.setName(connectorName);
324
325 final Connector[] subConnectors = getConnectors(connectorElement);
326 for (Connector subConnector : subConnectors) {
327 connector.addConnector(subConnector);
328 }
329
330 Filter filter = null;
331
332
333
334 synchronized (connector) {
335
336 final NodeList children = connectorElement.getChildNodes();
337 final int length = children.getLength();
338
339 for (int loop = 0; loop < length; loop++) {
340 final Node currentNode = children.item(loop);
341
342 if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
343 final Element currentElement = (Element) currentNode;
344 final String tagName = currentElement.getTagName();
345
346 if (tagName.equals(CONNECTOR_REF_TAG)) {
347 LOG.debug("{} is only parsed for the RegularExpression Context "
348 + "or init-Method. See org.settings4j.Connector.addConnector(Connector) Javadoc.",
349 CONNECTOR_REF_TAG);
350 } else if (tagName.equals(CONTENT_RESOLVER_REF_TAG)) {
351 final Element contentResolverRef = (Element) currentNode;
352 final ContentResolver contentResolver = findContentResolverByReference(contentResolverRef);
353 connector.setContentResolver(contentResolver);
354
355 } else if (tagName.equals(OBJECT_RESOLVER_REF_TAG)) {
356 final Element objectResolverRef = (Element) currentNode;
357 final ObjectResolver objectResolver = findObjectResolverByReference(objectResolverRef);
358 connector.setObjectResolver(objectResolver);
359
360 } else if (tagName.equals(FILTER_TAG)) {
361 final Element filterElement = (Element) currentNode;
362 filter = parseFilter(filterElement);
363 } else if (tagName.equals(PARAM_TAG)) {
364 setParameter(currentElement, connector, subConnectors);
365 } else {
366 quietParseUnrecognizedElement(connector, currentElement);
367 }
368 }
369 }
370
371 final Boolean cached = (Boolean) subst(connectorElement.getAttribute(CACHED_ATTR), subConnectors,
372 Boolean.class);
373 if (cached != null && cached.booleanValue()) {
374 connector = new CachedConnectorWrapper(connector);
375 }
376
377 if (filter != null) {
378 connector = new FilteredConnectorWrapper(connector, filter);
379 }
380
381
382 connector.init();
383 }
384 return connector;
385 }
386
387
388
389
390
391
392
393 private static void quietParseUnrecognizedElement(final Object instance, final Element element) {
394 String elementName = "UNKNOWN";
395 String instanceClassName = "UNKNOWN";
396
397 try {
398 elementName = element.getNodeName();
399 instanceClassName = instance.getClass().getName();
400 } catch (final Exception e) {
401 LOG.warn("Error in quietParseUnrecognizedElement(): {}", e.getMessage());
402 LOG.debug(e.getMessage(), e);
403 }
404 LOG.warn("Unrecognized Element will be ignored: {} for Instance: {}", elementName, instanceClassName);
405 }
406
407
408
409
410
411
412
413 protected Connector[] getConnectors(final Element connectorsElement) {
414 final List<Connector> connectors = new ArrayList<Connector>();
415
416 final NodeList children = connectorsElement.getChildNodes();
417 final int length = children.getLength();
418
419 for (int loop = 0; loop < length; loop++) {
420 final Node currentNode = children.item(loop);
421
422 if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
423 final Element currentElement = (Element) currentNode;
424 final String tagName = currentElement.getTagName();
425
426 if (tagName.equals(CONNECTOR_REF_TAG)) {
427 final Element connectorRef = (Element) currentNode;
428 final Connector connector = findConnectorByReference(connectorRef);
429 connectors.add(connector);
430 }
431 }
432 }
433
434 return connectors.toArray(new Connector[connectors.size()]);
435 }
436
437
438
439
440
441
442
443
444 protected void parseChildrenOfSettingsElement(final Element settingsElement, final Settings4jInstance settings) {
445
446 Node currentNode = null;
447 Element currentElement = null;
448 String tagName = null;
449
450
451
452 settings.removeAllConnectors();
453
454
455 final NodeList connectorElements = settingsElement.getElementsByTagName(CONNECTOR_TAG);
456 int length = connectorElements.getLength();
457 for (int i = 0; i < length; i++) {
458 currentNode = connectorElements.item(i);
459 currentElement = (Element) currentNode;
460
461 final Connector connector = parseConnector(currentElement);
462 if (connector != null) {
463 this.connectorBag.put(connector.getName(), connector);
464 settings.addConnector(connector);
465 }
466 }
467
468 final List<Connector> list = settings.getConnectors();
469 final Connector[] connectors = list.toArray(new Connector[list.size()]);
470
471 final NodeList children = settingsElement.getChildNodes();
472
473
474 length = children.getLength();
475 for (int i = 0; i < length; i++) {
476 currentNode = children.item(i);
477 if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
478 currentElement = (Element) currentNode;
479 tagName = currentElement.getTagName();
480
481 if (tagName.equals(MAPPING_TAG)) {
482 final Map mapping = parseMapping(currentElement);
483 if (mapping != null) {
484 settings.setMapping(mapping);
485 }
486 } else if (tagName.equals(PARAM_TAG)) {
487 setParameter(currentElement, settings, connectors);
488 } else if (tagName.equals(CONNECTOR_TAG)) {
489 LOG.trace("CONNECTOR_TAG already parsed");
490 } else if (tagName.equals(CONTENT_RESOLVER_TAG)) {
491 LOG.trace("CONTENT_RESOLVER_TAG will be parsed on the maned");
492 } else if (tagName.equals(OBJECT_RESOLVER_TAG)) {
493 LOG.trace("OBJECT_RESOLVER_TAG will be parsed on the maned");
494 } else {
495 quietParseUnrecognizedElement(settings, currentElement);
496 }
497 }
498 }
499 }
500
501
502
503
504
505
506
507
508
509 protected Connector findConnectorByName(final Document doc, final String connectorName) {
510 Connector connector = this.connectorBag.get(connectorName);
511
512 if (connector != null) {
513 return connector;
514 }
515
516 final Element element = getElementByNameAttr(doc, connectorName, "connector");
517
518 if (element == null) {
519 LOG.error("No connector named [{}] could be found.", connectorName);
520 return null;
521 }
522
523 connector = parseConnector(element);
524 this.connectorBag.put(connectorName, connector);
525 return connector;
526 }
527
528
529
530
531
532
533
534 protected Connector findConnectorByReference(final Element connectorRef) {
535 final String connectorName = connectorRef.getAttribute(REF_ATTR);
536 final Document doc = connectorRef.getOwnerDocument();
537 return findConnectorByName(doc, connectorName);
538 }
539
540
541
542
543
544
545
546
547 protected ObjectResolver parseObjectResolver(final Element objectResolverElement) {
548 final String objectResolverName = objectResolverElement.getAttribute(NAME_ATTR);
549
550 ObjectResolver objectResolver;
551
552 final String className = objectResolverElement.getAttribute(CLASS_ATTR);
553
554
555 LOG.debug("Desired ObjectResolver class: [{}]", className);
556 try {
557 final Class clazz = loadClass(className);
558 final Constructor constructor = clazz.getConstructor();
559 objectResolver = (ObjectResolver) constructor.newInstance();
560 } catch (final Exception oops) {
561 LOG.error("Could not retrieve objectResolver [" + objectResolverName + "]. Reported error follows.", oops);
562 return null;
563 } catch (final NoClassDefFoundError e) {
564 LOG.warn("The ObjectResolver '" + objectResolverName
565 + "' cannot be created. There are not all required Libraries inside the Classpath: " + e.getMessage(),
566 e);
567 return null;
568 }
569
570
571 final Connector[] connectors = getConnectors(objectResolverElement);
572
573 Filter filter = null;
574
575
576
577 synchronized (objectResolver) {
578
579 final NodeList children = objectResolverElement.getChildNodes();
580 final int length = children.getLength();
581
582 for (int loop = 0; loop < length; loop++) {
583 final Node currentNode = children.item(loop);
584
585 if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
586 final Element currentElement = (Element) currentNode;
587 final String tagName = currentElement.getTagName();
588
589
590 if (tagName.equals(CONNECTOR_REF_TAG)) {
591 LOG.debug("{} is only parsed for the RegularExpression Context. "
592 + "See org.settings4j.Connector.addConnector(Connector) Javadoc.",
593 CONNECTOR_REF_TAG);
594 } else if (tagName.equals(OBJECT_RESOLVER_REF_TAG)) {
595 final Element objectResolverRef = (Element) currentNode;
596 final ObjectResolver subObjectResolver = findObjectResolverByReference(objectResolverRef);
597 objectResolver.addObjectResolver(subObjectResolver);
598
599 } else if (tagName.equals(PARAM_TAG)) {
600 setParameter(currentElement, objectResolver, connectors);
601 } else if (tagName.equals(FILTER_TAG)) {
602 final Element filterElement = (Element) currentNode;
603 filter = parseFilter(filterElement);
604 } else {
605 quietParseUnrecognizedElement(objectResolver, currentElement);
606 }
607 }
608 }
609
610 String isCachedValue = objectResolverElement.getAttribute(CACHED_ATTR);
611 final Boolean isCached = (Boolean) subst(isCachedValue, null, Boolean.class);
612 if (BooleanUtils.isTrue(isCached)) {
613 if (objectResolver instanceof AbstractObjectResolver) {
614 ((AbstractObjectResolver) objectResolver).setCached(isCached.booleanValue());
615 } else {
616 LOG.warn("Only AbstractObjectResolver can use the attribute cached=\"true\" ");
617
618 }
619 }
620
621 if (filter != null) {
622 objectResolver = new FilteredObjectResolverWrapper(objectResolver, filter);
623 }
624 }
625
626 return objectResolver;
627 }
628
629
630
631
632
633
634
635
636 @SuppressWarnings("unchecked")
637 protected Map parseMapping(final Element mappingElement) {
638 final String mappingName = mappingElement.getAttribute(NAME_ATTR);
639
640 Map<String, String> mapping;
641
642 String className = mappingElement.getAttribute(CLASS_ATTR);
643 if (StringUtils.isEmpty(className)) {
644 className = "java.util.HashMap";
645 }
646
647 LOG.debug("Desired Map class: [{}]", className);
648 try {
649 final Class clazz = loadClass(className);
650 final Constructor constructor = clazz.getConstructor();
651 mapping = (Map<String, String>) constructor.newInstance();
652 } catch (final Exception oops) {
653 LOG.error("Could not retrieve mapping [" + mappingName + "]. Reported error follows.", oops);
654 return null;
655 } catch (final NoClassDefFoundError e) {
656 LOG.warn("The Mapping '" + mappingName
657 + "' cannot be created. There are not all required Libraries inside the Classpath: " + e.getMessage(),
658 e);
659 return null;
660 }
661
662
663
664
665 synchronized (mapping) {
666
667 final NodeList children = mappingElement.getChildNodes();
668 final int length = children.getLength();
669
670 for (int loop = 0; loop < length; loop++) {
671 final Node currentNode = children.item(loop);
672
673 if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
674 final Element currentElement = (Element) currentNode;
675 final String tagName = currentElement.getTagName();
676
677 if (tagName.equals(ENTRY_TAG)) {
678 final String key = currentElement.getAttribute(ENTRY_KEY_ATTR);
679 final String keyRef = currentElement.getAttribute(ENTRY_REFKEY_ATTR);
680 mapping.put(key, keyRef);
681 } else {
682 quietParseUnrecognizedElement(mapping, currentElement);
683 }
684 }
685 }
686 }
687
688 return mapping;
689 }
690
691
692
693
694
695
696
697
698 protected ContentResolver parseContentResolver(final Element contentResolverElement) {
699 final String contentResolverName = contentResolverElement.getAttribute(NAME_ATTR);
700
701 ContentResolver contentResolver;
702
703 final String className = contentResolverElement.getAttribute(CLASS_ATTR);
704
705
706 LOG.debug("Desired ContentResolver class: [{}]", className);
707 try {
708 final Class clazz = loadClass(className);
709 final Constructor constructor = clazz.getConstructor();
710 contentResolver = (ContentResolver) constructor.newInstance();
711 } catch (final Exception e) {
712 LOG.error("Could not retrieve contentResolver [" + contentResolverName + "]. "
713 + "Reported error follows.", e);
714 return null;
715 } catch (final NoClassDefFoundError e) {
716 LOG.warn("The ContentResolver '" + contentResolverName + "' cannot be created. "
717 + "There are not all required Libraries inside the Classpath: " + e.getMessage(), e);
718 return null;
719 }
720
721
722 final Connector[] connectors = getConnectors(contentResolverElement);
723
724 Filter filter = null;
725
726
727
728 synchronized (contentResolver) {
729
730 final NodeList children = contentResolverElement.getChildNodes();
731 final int length = children.getLength();
732
733 for (int loop = 0; loop < length; loop++) {
734 final Node currentNode = children.item(loop);
735
736 if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
737 final Element currentElement = (Element) currentNode;
738 final String tagName = currentElement.getTagName();
739
740 if (tagName.equals(CONNECTOR_REF_TAG)) {
741 LOG.debug("{} is only parsed for the RegularExpression Context. "
742 + "See org.settings4j.Connector.addConnector(Connector) Javadoc.",
743 CONNECTOR_REF_TAG);
744 } else if (tagName.equals(CONTENT_RESOLVER_REF_TAG)) {
745 final Element contentResolverRef = (Element) currentNode;
746 final ContentResolver subContentResolver = findContentResolverByReference(contentResolverRef);
747 contentResolver.addContentResolver(subContentResolver);
748
749 } else if (tagName.equals(PARAM_TAG)) {
750 setParameter(currentElement, contentResolver, connectors);
751 } else if (tagName.equals(FILTER_TAG)) {
752 final Element filterElement = (Element) currentNode;
753 filter = parseFilter(filterElement);
754 } else {
755 quietParseUnrecognizedElement(contentResolver, currentElement);
756 }
757 }
758 }
759
760 if (filter != null) {
761 contentResolver = new FilteredContentResolverWrapper(contentResolver, filter);
762 }
763 }
764
765 return contentResolver;
766 }
767
768
769
770
771
772
773
774
775 protected ContentResolver findContentResolverByName(final Document doc, final String contentResolverName) {
776 ContentResolver contentResolver = this.contentResolverBag.get(contentResolverName);
777
778 if (contentResolver != null) {
779 return contentResolver;
780 }
781
782 final Element element = getElementByNameAttr(doc, contentResolverName, CONTENT_RESOLVER_TAG);
783
784 if (element == null) {
785 LOG.error("No contentResolver named [{}] could be found.", contentResolverName);
786 return null;
787 }
788
789 contentResolver = parseContentResolver(element);
790 this.contentResolverBag.put(contentResolverName, contentResolver);
791 return contentResolver;
792 }
793
794
795
796
797
798
799
800
801
802 protected ObjectResolver findObjectResolverByName(final Document doc, final String objectResolverName) {
803 ObjectResolver objectResolver = this.objectResolverBag.get(objectResolverName);
804
805 if (objectResolver != null) {
806 return objectResolver;
807 }
808
809 final Element element = getElementByNameAttr(doc, objectResolverName, OBJECT_RESOLVER_TAG);
810
811 if (element == null) {
812 LOG.error("No objectResolver named [{}] could be found.", objectResolverName);
813 return null;
814 }
815
816 objectResolver = parseObjectResolver(element);
817 this.objectResolverBag.put(objectResolverName, objectResolver);
818 return objectResolver;
819 }
820
821
822
823
824
825
826
827 protected ObjectResolver findObjectResolverByReference(final Element objectResolverRef) {
828 final String objectResolverName = objectResolverRef.getAttribute(REF_ATTR);
829 final Document doc = objectResolverRef.getOwnerDocument();
830 return findObjectResolverByName(doc, objectResolverName);
831 }
832
833
834
835
836
837
838
839
840 protected ContentResolver findContentResolverByReference(final Element contentResolverRef) {
841 final String contentResolverName = contentResolverRef.getAttribute(REF_ATTR);
842 final Document doc = contentResolverRef.getOwnerDocument();
843 return findContentResolverByName(doc, contentResolverName);
844 }
845
846
847 private static Element getElementByNameAttr(final Document doc, final String nameAttrValue,
848 final String elementTagName) {
849
850
851
852
853 Element element = null;
854 final NodeList list = doc.getElementsByTagName(elementTagName);
855 for (int t = 0; t < list.getLength(); t++) {
856 final Node node = list.item(t);
857 final NamedNodeMap map = node.getAttributes();
858 final Node attrNode = map.getNamedItem("name");
859 if (nameAttrValue.equals(attrNode.getNodeValue())) {
860 element = (Element) node;
861 break;
862 }
863 }
864
865 return element;
866 }
867
868
869
870
871
872 private interface ParseAction {
873 Document parse(final DocumentBuilder parser) throws SAXException, IOException;
874 }
875
876
877
878
879
880
881
882
883 protected String subst(final String value, final Connector[] connectors) {
884 return (String) subst(value, connectors, String.class);
885 }
886
887
888
889
890
891
892
893
894
895 protected Object subst(final String value, final Connector[] connectors, final Class clazz) {
896 if (StringUtils.isEmpty(value)) {
897 return null;
898 }
899
900 if (value.indexOf("${") >= 0) {
901 try {
902 final Map<String, Object> context = new HashMap<String, Object>(this.expressionAttributes);
903 if (connectors != null) {
904
905 context.put("connectors", new ELConnectorWrapper(connectors));
906
907
908
909 final Map<String, ELConnectorWrapper> connectorMap = new HashMap<String, ELConnectorWrapper>();
910 for (Connector connector : connectors) {
911 connectorMap.put(connector.getName(), new ELConnectorWrapper(new Connector[] {connector}));
912 }
913 context.put("connector", connectorMap);
914 }
915 context.put("env", System.getenv());
916 final Object result = ExpressionLanguageUtil.evaluateExpressionLanguage(value, context, clazz);
917 return result;
918 } catch (final Exception e) {
919 LOG.error(e.getMessage(), e);
920 return null;
921 }
922 }
923
924 if (clazz.equals(String.class)) {
925 return value.trim();
926 } else if (clazz.equals(Boolean.class)) {
927 return BooleanUtils.toBooleanObject(value.trim());
928 } else {
929 throw new UnsupportedOperationException("The following Type is not supported now: " + clazz
930 + "; found value: " + value);
931 }
932 }
933
934
935
936
937
938
939
940
941
942
943 public void addExpressionAttribute(final String key, final Object value) {
944 this.expressionAttributes.put(key, value);
945 }
946
947 private static Class loadClass(final String clazz) throws ClassNotFoundException {
948 return ClasspathContentResolver.getClassLoader().loadClass(clazz);
949 }
950 }