19
19
import java .io .IOException ;
20
20
import java .lang .reflect .Constructor ;
21
21
import java .lang .reflect .InvocationTargetException ;
22
+ import java .util .ArrayList ;
23
+ import java .util .List ;
24
+ import java .util .Map ;
25
+ import java .util .Properties ;
22
26
23
27
import javax .jms .JMSException ;
28
+ import javax .xml .parsers .DocumentBuilder ;
29
+ import javax .xml .parsers .DocumentBuilderFactory ;
30
+ import javax .xml .parsers .ParserConfigurationException ;
24
31
25
32
import org .apache .activemq .command .Message ;
26
33
import org .apache .activemq .util .JMSExceptionSupport ;
@@ -35,15 +42,32 @@ public final class XPathExpression implements BooleanExpression {
35
42
private static final Logger LOG = LoggerFactory .getLogger (XPathExpression .class );
36
43
private static final String EVALUATOR_SYSTEM_PROPERTY = "org.apache.activemq.XPathEvaluatorClassName" ;
37
44
private static final String DEFAULT_EVALUATOR_CLASS_NAME = "org.apache.activemq.filter.XalanXPathEvaluator" ;
45
+ public static final String DOCUMENT_BUILDER_FACTORY_FEATURE = "org.apache.activemq.documentBuilderFactory.feature" ;
38
46
39
47
private static final Constructor EVALUATOR_CONSTRUCTOR ;
48
+ private static DocumentBuilder builder = null ;
40
49
41
50
static {
42
51
String cn = System .getProperty (EVALUATOR_SYSTEM_PROPERTY , DEFAULT_EVALUATOR_CLASS_NAME );
43
52
Constructor m = null ;
44
53
try {
45
54
try {
46
55
m = getXPathEvaluatorConstructor (cn );
56
+ DocumentBuilderFactory builderFactory = DocumentBuilderFactory .newInstance ();
57
+ builderFactory .setNamespaceAware (true );
58
+ builderFactory .setIgnoringElementContentWhitespace (true );
59
+ builderFactory .setIgnoringComments (true );
60
+ try {
61
+ // set some reasonable defaults
62
+ builderFactory .setFeature ("http://xml.org/sax/features/external-general-entities" , false );
63
+ builderFactory .setFeature ("http://xml.org/sax/features/external-parameter-entities" , false );
64
+ builderFactory .setFeature ("http://apache.org/xml/features/disallow-doctype-decl" , true );
65
+ } catch (ParserConfigurationException e ) {
66
+ LOG .warn ("Error setting document builder factory feature" , e );
67
+ }
68
+ // setup the feature from the system property
69
+ setupFeatures (builderFactory );
70
+ builder = builderFactory .newDocumentBuilder ();
47
71
} catch (Throwable e ) {
48
72
LOG .warn ("Invalid " + XPathEvaluator .class .getName () + " implementation: " + cn + ", reason: " + e , e );
49
73
cn = DEFAULT_EVALUATOR_CLASS_NAME ;
@@ -75,12 +99,41 @@ private static Constructor getXPathEvaluatorConstructor(String cn) throws ClassN
75
99
if (!XPathEvaluator .class .isAssignableFrom (c )) {
76
100
throw new ClassCastException ("" + c + " is not an instance of " + XPathEvaluator .class );
77
101
}
78
- return c .getConstructor (new Class [] {String .class });
102
+ return c .getConstructor (new Class [] {String .class , DocumentBuilder .class });
103
+ }
104
+
105
+ protected static void setupFeatures (DocumentBuilderFactory factory ) {
106
+ Properties properties = System .getProperties ();
107
+ List <String > features = new ArrayList <String >();
108
+ for (Map .Entry <Object , Object > prop : properties .entrySet ()) {
109
+ String key = (String ) prop .getKey ();
110
+ if (key .startsWith (DOCUMENT_BUILDER_FACTORY_FEATURE )) {
111
+ String uri = key .split (DOCUMENT_BUILDER_FACTORY_FEATURE + ":" )[1 ];
112
+ Boolean value = Boolean .valueOf ((String )prop .getValue ());
113
+ try {
114
+ factory .setFeature (uri , value );
115
+ features .add ("feature " + uri + " value " + value );
116
+ } catch (ParserConfigurationException e ) {
117
+ LOG .warn ("DocumentBuilderFactory doesn't support the feature {} with value {}, due to {}." , new Object []{uri , value , e });
118
+ }
119
+ }
120
+ }
121
+ if (features .size () > 0 ) {
122
+ StringBuffer featureString = new StringBuffer ();
123
+ // just log the configured feature
124
+ for (String feature : features ) {
125
+ if (featureString .length () != 0 ) {
126
+ featureString .append (", " );
127
+ }
128
+ featureString .append (feature );
129
+ }
130
+ }
131
+
79
132
}
80
133
81
134
private XPathEvaluator createEvaluator (String xpath2 ) {
82
135
try {
83
- return (XPathEvaluator )EVALUATOR_CONSTRUCTOR .newInstance (new Object [] {xpath });
136
+ return (XPathEvaluator )EVALUATOR_CONSTRUCTOR .newInstance (new Object [] {xpath , builder });
84
137
} catch (InvocationTargetException e ) {
85
138
Throwable cause = e .getCause ();
86
139
if (cause instanceof RuntimeException ) {
0 commit comments