1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.xml.transformer;
12
13 import org.mule.api.MuleContext;
14 import org.mule.api.expression.ExpressionRuntimeException;
15 import org.mule.api.lifecycle.InitialisationException;
16 import org.mule.api.registry.RegistrationException;
17 import org.mule.api.transformer.TransformerException;
18 import org.mule.config.i18n.CoreMessages;
19 import org.mule.module.xml.util.NamespaceManager;
20 import org.mule.transformer.AbstractTransformer;
21 import org.mule.util.StringUtils;
22
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27
28 import org.apache.commons.jxpath.JXPathContext;
29 import org.dom4j.Document;
30 import org.dom4j.DocumentHelper;
31 import org.dom4j.Node;
32 import org.dom4j.XPath;
33
34
35
36
37
38
39
40
41
42 public class JXPathExtractor extends AbstractTransformer
43 {
44 public static final String OUTPUT_TYPE_NODE = "NODE";
45
46 public static final String OUTPUT_TYPE_XML = "XML";
47
48 public static final String OUTPUT_TYPE_VALUE = "VALUE";
49
50 private volatile String expression;
51
52 private volatile String outputType;
53
54 private volatile Map namespaces;
55
56 private volatile boolean singleResult = true;
57
58 private NamespaceManager namespaceManager;
59
60 public void setMuleContext(MuleContext context)
61 {
62 this.muleContext = context;
63 try
64 {
65 namespaceManager = muleContext.getRegistry().lookupObject(NamespaceManager.class);
66 }
67 catch (RegistrationException e)
68 {
69 throw new ExpressionRuntimeException(CoreMessages.failedToLoad("NamespaceManager"), e);
70 }
71 }
72
73
74
75
76
77
78
79
80 @Override
81 public void initialise() throws InitialisationException
82 {
83 super.initialise();
84 if (namespaceManager != null)
85 {
86 if (namespaces == null)
87 {
88 namespaces = new HashMap(namespaceManager.getNamespaces());
89 }
90 else
91 {
92 namespaces.putAll(namespaceManager.getNamespaces());
93 }
94 }
95 }
96
97
98
99
100
101
102 public Object doTransform(Object src, String encoding) throws TransformerException
103 {
104 try
105 {
106 Object result = null;
107 if (src instanceof String)
108 {
109 Document doc = DocumentHelper.parseText((String) src);
110
111 XPath xpath = doc.createXPath(expression);
112 if (namespaces != null)
113 {
114 xpath.setNamespaceURIs(namespaces);
115 }
116
117
118
119
120 if (outputType == null && singleResult)
121 {
122 return xpath.valueOf(doc);
123 }
124
125
126
127 Object obj = xpath.evaluate(doc);
128 if (obj instanceof List)
129 {
130 for (int i = 0; i < ((List) obj).size(); i++)
131 {
132 final Node node = (Node) ((List) obj).get(i);
133 result = add(result, node);
134
135 if (singleResult)
136 {
137 break;
138 }
139 }
140 }
141 else
142 {
143 result = add(result, obj);
144 }
145
146 }
147 else
148 {
149 JXPathContext context = JXPathContext.newContext(src);
150 result = context.getValue(expression);
151 }
152 return result;
153 }
154 catch (Exception e)
155 {
156 throw new TransformerException(this, e);
157 }
158
159 }
160
161 private Object add(Object result, Object value)
162 {
163 Object formattedResult = getResult(value);
164 if (singleResult)
165 {
166 return formattedResult;
167 }
168 else
169 {
170 if (result == null)
171 {
172 result = new ArrayList();
173 }
174
175 ((List) result).add(formattedResult);
176 }
177 return result;
178 }
179
180 private Object getResult(Object value)
181 {
182 Object result = null;
183 if (StringUtils.contains(OUTPUT_TYPE_VALUE, outputType) || outputType == null)
184 {
185 if (value instanceof Node)
186 {
187 result = ((Node) value).getText();
188 }
189 else
190 {
191
192 result = value.toString();
193 }
194 }
195 else if (StringUtils.contains(OUTPUT_TYPE_XML, outputType))
196 {
197 if (value instanceof Node)
198 {
199 result = ((Node) value).asXML();
200 }
201 else
202 {
203 throw new IllegalStateException("XPath expression output must be a Node to output as XML. Expression type was: " + value.getClass());
204 }
205 }
206 else if (StringUtils.contains(OUTPUT_TYPE_NODE, outputType))
207 {
208 result = value;
209 }
210 return result;
211 }
212
213
214
215
216 public String getExpression()
217 {
218 return expression;
219 }
220
221
222
223
224 public void setExpression(String expression)
225 {
226 this.expression = expression;
227 }
228
229
230
231
232
233
234 public boolean isSingleResult()
235 {
236 return singleResult;
237 }
238
239
240
241
242
243
244
245 public void setSingleResult(boolean singleResult)
246 {
247 this.singleResult = singleResult;
248 }
249
250 public String getOutputType()
251 {
252 return outputType;
253 }
254
255 public void setOutputType(String outputEncoding)
256 {
257 this.outputType = outputEncoding;
258 }
259
260 public Map getNamespaces()
261 {
262 return namespaces;
263 }
264
265 public void setNamespaces(Map namespaceURIs)
266 {
267 this.namespaces = namespaceURIs;
268 }
269
270 }