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