1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.xml.expression;
12
13 import org.apache.commons.jxpath.Container;
14 import org.mule.api.MuleContext;
15 import org.mule.api.MuleMessage;
16 import org.mule.api.context.MuleContextAware;
17 import org.mule.api.expression.ExpressionEvaluator;
18 import org.mule.api.expression.ExpressionRuntimeException;
19 import org.mule.api.registry.RegistrationException;
20 import org.mule.config.i18n.CoreMessages;
21 import org.mule.module.xml.i18n.XmlMessages;
22 import org.mule.module.xml.util.NamespaceManager;
23 import org.mule.module.xml.util.XMLUtils;
24
25 import java.util.Iterator;
26 import java.util.Map;
27
28 import org.apache.commons.jxpath.JXPathContext;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.w3c.dom.Document;
32
33
34
35
36
37
38
39 public class JXPathExpressionEvaluator implements ExpressionEvaluator, MuleContextAware
40 {
41 public static final String NAME = "jxpath";
42
43
44
45 protected transient Log logger = LogFactory.getLog(getClass());
46 protected transient MuleContext muleContext;
47 private NamespaceManager namespaceManager;
48
49 public void setMuleContext(MuleContext context)
50 {
51 muleContext = context;
52 }
53
54 public Object evaluate(String expression, MuleMessage message)
55 {
56 Document document;
57 try
58 {
59 document = XMLUtils.toW3cDocument(message.getPayload());
60 }
61 catch (Exception e)
62 {
63 logger.error(e);
64 return null;
65 }
66
67 JXPathContext context;
68
69 if (document != null)
70 {
71 context = createContextForXml(document);
72 }
73 else
74 {
75 context = createContextForBean(message.getPayload());
76 }
77
78 return getExpressionValue(context, expression);
79 }
80
81 private JXPathContext createContextForXml(final Document document)
82 {
83 Container container = new Container()
84 {
85
86 public Object getValue()
87 {
88 return document;
89 }
90
91 public void setValue(Object value)
92 {
93 throw new UnsupportedOperationException();
94 }
95 };
96
97 return JXPathContext.newContext(container);
98 }
99
100 private JXPathContext createContextForBean(Object payload)
101 {
102 return JXPathContext.newContext(payload);
103 }
104
105 private Object getExpressionValue(JXPathContext context, String expression)
106 {
107 NamespaceManager theNamespaceManager = getNamespaceManager();
108 if (theNamespaceManager != null)
109 {
110 addNamespacesToContext(theNamespaceManager, context);
111 }
112
113 Object result = null;
114
115 try
116 {
117 result = context.getValue(expression);
118 }
119 catch (Exception e)
120 {
121 if (logger.isDebugEnabled())
122 {
123 logger.debug("failed to process JXPath expression: " + expression, e);
124 }
125 }
126
127 return result;
128 }
129
130 protected void addNamespacesToContext(NamespaceManager manager, JXPathContext context)
131 {
132 for (Iterator iterator = manager.getNamespaces().entrySet().iterator(); iterator.hasNext();)
133 {
134 Map.Entry entry = (Map.Entry) iterator.next();
135 try
136 {
137 context.registerNamespace(entry.getKey().toString(), entry.getValue().toString());
138 }
139 catch (Exception e)
140 {
141 throw new ExpressionRuntimeException(XmlMessages.failedToRegisterNamespace(entry.getKey().toString(), entry.getValue().toString()));
142 }
143 }
144 }
145
146
147
148
149 public String getName()
150 {
151 return NAME;
152 }
153
154
155
156
157 public void setName(String name)
158 {
159 throw new UnsupportedOperationException("setName");
160 }
161
162
163
164
165
166 protected synchronized NamespaceManager getNamespaceManager()
167 {
168 if (namespaceManager == null)
169 {
170
171 try
172 {
173
174 if (muleContext != null)
175 {
176 namespaceManager = muleContext.getRegistry().lookupObject(NamespaceManager.class);
177 }
178 }
179 catch (RegistrationException e)
180 {
181 throw new ExpressionRuntimeException(CoreMessages.failedToLoad("NamespaceManager"), e);
182 }
183 }
184 return namespaceManager;
185 }
186 }