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