1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.xml.filters;
12
13 import org.mule.api.MuleMessage;
14 import org.mule.api.routing.filter.Filter;
15 import org.mule.module.xml.util.XMLUtils;
16
17 import java.io.InputStream;
18 import java.util.Iterator;
19 import java.util.Map;
20
21 import javax.xml.transform.dom.DOMSource;
22
23 import org.apache.commons.jxpath.AbstractFactory;
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.dom4j.Document;
27 import org.jaxen.BaseXPath;
28 import org.jaxen.JaxenException;
29 import org.jaxen.dom.DOMXPath;
30 import org.jaxen.dom4j.Dom4jXPath;
31 import org.jaxen.javabean.JavaBeanXPath;
32
33
34
35
36
37 public class JaxenFilter implements Filter
38 {
39 protected transient Log logger = LogFactory.getLog(getClass());
40
41 private String pattern;
42 private String expectedValue;
43 private Map namespaces = null;
44 private Map contextProperties = null;
45 private AbstractFactory factory;
46
47 public JaxenFilter()
48 {
49 super();
50 }
51
52 public JaxenFilter(String pattern)
53 {
54 this.pattern = pattern;
55 }
56
57 public JaxenFilter(String pattern, String expectedValue)
58 {
59 this.pattern = pattern;
60 this.expectedValue = expectedValue;
61 }
62
63 public boolean accept(MuleMessage obj)
64 {
65 Object payload = obj.getPayload();
66
67 try
68 {
69
70 if (payload instanceof DOMSource)
71 {
72 accept(((DOMSource) payload).getNode());
73 }
74 else if (payload instanceof byte[]
75 || payload instanceof InputStream
76 || payload instanceof String)
77 {
78 try
79 {
80 return accept(obj.getPayload(org.w3c.dom.Document.class));
81 }
82 catch (Exception e)
83 {
84 logger.warn("JaxenPath filter rejected message because it could not convert from "
85 + payload.getClass()
86 + " to Source: "+ e.getMessage(), e);
87 return false;
88 }
89 }
90
91 return accept(payload);
92 }
93 catch (JaxenException e)
94 {
95 logger.warn("JaxenPath filter rejected message because it could not build/evaluate the XPath expression.", e);
96 return false;
97 }
98 }
99
100 private boolean accept(Object obj) throws JaxenException
101 {
102 if (obj == null)
103 {
104 logger.warn("Applying JaxenFilter to null object.");
105 return false;
106 }
107 if (pattern == null)
108 {
109 logger.warn("Expression for JaxenFilter is not set.");
110 return false;
111 }
112 if (expectedValue == null)
113 {
114
115 if (pattern.endsWith("= null") || pattern.endsWith("=null"))
116 {
117 expectedValue = "null";
118 pattern = pattern.substring(0, pattern.lastIndexOf("="));
119 }
120 else
121 {
122 if (logger.isInfoEnabled())
123 {
124 logger.info("Expected value for JaxenFilter is not set, using 'true' by default");
125 }
126 expectedValue = Boolean.TRUE.toString();
127 }
128 }
129
130 Object xpathResult = null;
131 boolean accept = false;
132
133 Document dom4jDoc;
134 try
135 {
136 dom4jDoc = XMLUtils.toDocument(obj);
137 }
138 catch (Exception e)
139 {
140 throw new JaxenException(e);
141 }
142
143
144 if (dom4jDoc != null)
145 {
146 xpathResult = getDom4jXPath().valueOf(dom4jDoc);
147 }
148
149 else if (obj instanceof DOMSource)
150 {
151 xpathResult = getDOMXPath().valueOf(obj);
152 }
153
154 else if (obj instanceof org.w3c.dom.Document)
155 {
156 xpathResult = getDOMXPath().valueOf(obj);
157 }
158
159 else
160 {
161 if (logger.isDebugEnabled())
162 {
163 logger.debug("Passing object of type " + obj.getClass().getName() + " to JaxenContext");
164 }
165 xpathResult = getJavaBeanXPath().valueOf(obj);
166 }
167
168 if (logger.isDebugEnabled())
169 {
170 logger.debug("JaxenFilter Expression result = '" + xpathResult + "' - Expected value = '"
171 + expectedValue + "'");
172 }
173
174 if (xpathResult != null)
175 {
176 accept = xpathResult.toString().equals(expectedValue);
177 }
178 else
179 {
180
181 if (expectedValue.equals("null"))
182 {
183 accept = true;
184 }
185
186 else
187 {
188 logger.warn("JaxenFilter expression evaluates to null: " + pattern);
189 }
190 }
191
192 if (logger.isDebugEnabled())
193 {
194 logger.debug("JaxenFilter accept object : " + accept);
195 }
196
197 return accept;
198 }
199
200 protected DOMXPath getDOMXPath() throws JaxenException
201 {
202 DOMXPath xpath = new DOMXPath(pattern);
203 setupNamespaces(xpath);
204 return xpath;
205 }
206
207 protected Dom4jXPath getDom4jXPath() throws JaxenException
208 {
209 Dom4jXPath xpath = new Dom4jXPath(pattern);
210 setupNamespaces(xpath);
211 return xpath;
212 }
213
214 protected JavaBeanXPath getJavaBeanXPath() throws JaxenException
215 {
216 JavaBeanXPath xpath = new JavaBeanXPath(pattern);
217 setupNamespaces(xpath);
218 return xpath;
219 }
220
221 private void setupNamespaces(BaseXPath xpath) throws JaxenException
222 {
223 if (namespaces != null)
224 {
225 for (Iterator itr = namespaces.entrySet().iterator(); itr.hasNext();)
226 {
227 Map.Entry entry = (Map.Entry) itr.next();
228
229 xpath.addNamespace((String) entry.getKey(), (String) entry.getValue());
230 }
231 }
232 }
233
234
235 public String getPattern()
236 {
237 return pattern;
238 }
239
240
241 public void setPattern(String pattern)
242 {
243 this.pattern = pattern;
244 }
245
246
247 public String getExpectedValue()
248 {
249 return expectedValue;
250 }
251
252
253 public void setExpectedValue(String expectedValue)
254 {
255 this.expectedValue = expectedValue;
256 }
257
258 public Map getNamespaces()
259 {
260 return namespaces;
261 }
262
263 public void setNamespaces(Map namespaces)
264 {
265 this.namespaces = namespaces;
266 }
267
268 public Map getContextProperties()
269 {
270 return contextProperties;
271 }
272
273 public void setContextProperties(Map contextProperties)
274 {
275 this.contextProperties = contextProperties;
276 }
277
278 public AbstractFactory getFactory()
279 {
280 return factory;
281 }
282
283 public void setFactory(AbstractFactory factory)
284 {
285 this.factory = factory;
286 }
287 }