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