KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > servicemix > components > xslt > XalanExtension


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.servicemix.components.xslt;
18
19 import org.apache.commons.lang.math.NumberUtils;
20 import org.apache.servicemix.components.util.ComponentSupport;
21 import org.apache.servicemix.components.util.CopyTransformer;
22 import org.apache.servicemix.components.util.MarshalerSupport;
23 import org.apache.xalan.extensions.XSLProcessorContext;
24 import org.apache.xalan.lib.ExsltDynamic;
25 import org.apache.xalan.templates.ElemTemplateElement;
26 import org.apache.xalan.transformer.TransformerImpl;
27 import org.apache.xml.utils.DOMBuilder;
28 import org.apache.xml.utils.PrefixResolver;
29 import org.apache.xpath.objects.XObject;
30 import org.w3c.dom.Document JavaDoc;
31 import org.w3c.dom.Element JavaDoc;
32 import org.xml.sax.SAXNotSupportedException JavaDoc;
33
34 import javax.jbi.messaging.Fault;
35 import javax.jbi.messaging.InOnly;
36 import javax.jbi.messaging.InOut;
37 import javax.jbi.messaging.MessageExchange;
38 import javax.jbi.messaging.MessagingException;
39 import javax.jbi.messaging.NormalizedMessage;
40 import javax.xml.namespace.QName JavaDoc;
41 import javax.xml.parsers.ParserConfigurationException JavaDoc;
42 import javax.xml.transform.TransformerException JavaDoc;
43 import javax.xml.transform.dom.DOMSource JavaDoc;
44
45 /**
46  * An extension to allow <a HREF="http://xml.apache.org/xalan/">Xalan</a> to perform XPath based routing using
47  * ServiceMix.
48  *
49  * @version $Revision: 426415 $
50  */

51 public class XalanExtension extends MarshalerSupport {
52
53     // Extension elements
54
//-------------------------------------------------------------------------
55

56
57     /**
58      * Forwards the inbound message to the destination copying the content and properties
59      */

60     public void forward(XSLProcessorContext context, Element element) throws MessagingException {
61         ComponentSupport component = getComponent(context, element);
62         if (component == null) {
63             throw new MessagingException("Could not find a component on which to perform the service invocation!");
64         }
65
66         TransformerImpl transformer = context.getTransformer();
67         PrefixResolver namespaceContext = transformer.getXPathContext().getNamespaceContext();
68
69         QName JavaDoc service = getQNameAttribute(namespaceContext, element, "service");
70         QName JavaDoc interfaceName = getQNameAttribute(namespaceContext, element, "interface");
71         QName JavaDoc operation = getQNameAttribute(namespaceContext, element, "operation");
72
73         MessageExchange exchange = getExchange(context, element);
74         NormalizedMessage in = getInMessage(context, element);
75
76         // TODO we should allow nested setOutProperty tags
77

78         component.invoke(exchange, in, service, interfaceName, operation);
79     }
80
81     /**
82      * Invokes the service with the XML content included in the XML element
83      */

84     public void invoke(XSLProcessorContext context, ElemTemplateElement element) throws MessagingException, ParserConfigurationException JavaDoc, TransformerException JavaDoc {
85         ComponentSupport component = getComponent(context, element);
86         if (component == null) {
87             throw new MessagingException("Could not find a component on which to perform the service invocation!");
88         }
89
90         TransformerImpl transformer = context.getTransformer();
91         PrefixResolver namespaceContext = transformer.getXPathContext().getNamespaceContext();
92
93         QName JavaDoc service = getQNameAttribute(namespaceContext, element, "service");
94         QName JavaDoc interfaceName = getQNameAttribute(namespaceContext, element, "interface");
95         QName JavaDoc operation = getQNameAttribute(namespaceContext, element, "operation");
96
97         InOnly outExchange = component.createInOnlyExchange(service, interfaceName, operation);
98         NormalizedMessage out = outExchange.createMessage();
99         outExchange.setInMessage(out);
100
101         transformer.setParameter("out", out);
102
103         // lets copy the content into the body
104
Document JavaDoc document = getTransformer().createDocument();
105         DOMBuilder builder = new DOMBuilder(document);
106         transformer.executeChildTemplates(element, context.getContextNode(), context.getMode(), builder);
107         
108         out.setContent(new DOMSource JavaDoc(document));
109
110         // now lets perform the invocation
111
component.send(outExchange);
112     }
113
114     /**
115      * Calls the service with the XML content included in the XML element and outputs the XML content
116      */

117     public void call(XSLProcessorContext context, ElemTemplateElement element) throws MessagingException, ParserConfigurationException JavaDoc, TransformerException JavaDoc {
118         ComponentSupport component = getComponent(context, element);
119         if (component == null) {
120             throw new MessagingException("Could not find a component on which to perform the service invocation!");
121         }
122
123         TransformerImpl transformer = context.getTransformer();
124         PrefixResolver namespaceContext = transformer.getXPathContext().getNamespaceContext();
125
126         QName JavaDoc service = getQNameAttribute(namespaceContext, element, "service");
127         QName JavaDoc interfaceName = getQNameAttribute(namespaceContext, element, "interface");
128         QName JavaDoc operation = getQNameAttribute(namespaceContext, element, "operation");
129
130         InOut outExchange = component.createInOutExchange(service, interfaceName, operation);
131         NormalizedMessage out = outExchange.createMessage();
132         outExchange.setInMessage(out);
133
134
135         // lets copy the content into the body
136
Document JavaDoc document = getTransformer().createDocument();
137         DOMBuilder builder = new DOMBuilder(document);
138         transformer.executeChildTemplates(element, context.getContextNode(), context.getMode(), builder);
139
140         out.setContent(new DOMSource JavaDoc(document));
141
142         // now lets perform the invocation
143
if (component.getDeliveryChannel().sendSync(outExchange)) {
144             NormalizedMessage result = outExchange.getOutMessage();
145             String JavaDoc outVarName = getAttribute(element, "outVar", "out");
146             transformer.setParameter(outVarName, result);
147         }
148         else {
149             Exception JavaDoc error = outExchange.getError();
150             if (error != null) {
151                 transformer.setParameter("error", error);
152             }
153             Fault fault = outExchange.getFault();
154             if (fault != null) {
155                 transformer.setParameter("fault", fault);
156             }
157         }
158
159     }
160
161     /**
162      * Copies the properties from the input to the output message
163      */

164     public void copyProperties(XSLProcessorContext context, Element element) throws MessagingException {
165         NormalizedMessage in = getInMessage(context, element);
166         NormalizedMessage out = getOutMessage(context, element);
167         CopyTransformer.copyProperties(in, out);
168     }
169
170     /**
171      * Sets a named property on the output message
172      */

173     public void setOutProperty(XSLProcessorContext context, ElemTemplateElement element) throws MessagingException, SAXNotSupportedException JavaDoc {
174         NormalizedMessage out = getOutMessage(context, element);
175         String JavaDoc name = element.getAttribute("name");
176         if (name == null) {
177             throw new IllegalArgumentException JavaDoc("Must specify a 'name' attribute to set a property on the output message");
178         }
179         String JavaDoc xpath = element.getAttribute("select");
180         if (xpath == null) {
181             throw new IllegalArgumentException JavaDoc("Must specify a 'select' attribute to set a property on the output message");
182         }
183         XObject answer = ExsltDynamic.evaluate(context.getTransformer().getXPathContext().getExpressionContext(), xpath);
184         Object JavaDoc value;
185         try {
186             if (answer.getType() == XObject.CLASS_NUMBER) {
187                 value = NumberUtils.createNumber(answer.str());
188             } else if (answer.getType() == XObject.CLASS_BOOLEAN) {
189                 value = new Boolean JavaDoc(answer.bool());
190             } else {
191                 // XObject guarantees we are never null.
192
value = answer.str();
193             }
194         } catch (TransformerException JavaDoc e) {
195             value = answer.str();
196         } catch (NumberFormatException JavaDoc e) {
197             value = answer.str();
198         }
199         out.setProperty(name, value);
200     }
201
202     // Extension XPath functions
203
//-------------------------------------------------------------------------
204

205     // Implementation methods
206
//-------------------------------------------------------------------------
207
protected ComponentSupport getComponent(XSLProcessorContext context, Element element) {
208         return (ComponentSupport) getParameter(context, "component");
209     }
210
211     protected MessageExchange getExchange(XSLProcessorContext context, Element element) {
212         return (MessageExchange) getParameter(context, "exchange");
213     }
214
215     protected NormalizedMessage getInMessage(XSLProcessorContext context, Element element) {
216         return (NormalizedMessage) getParameter(context, "in");
217     }
218
219     protected NormalizedMessage getOutMessage(XSLProcessorContext context, Element element) {
220         return (NormalizedMessage) getParameter(context, "out");
221     }
222
223     protected Object JavaDoc getParameter(XSLProcessorContext context, String JavaDoc name) {
224         return context.getTransformer().getParameter(name);
225     }
226
227     protected QName JavaDoc getQNameAttribute(PrefixResolver namespaceContext, Element element, String JavaDoc name) {
228         String JavaDoc qualifiedName = element.getAttribute(name);
229         if (qualifiedName != null) {
230             int index = qualifiedName.indexOf(':');
231             if (index >= 0) {
232                 String JavaDoc prefix = qualifiedName.substring(0, index);
233                 String JavaDoc localName = qualifiedName.substring(index + 1);
234                 String JavaDoc uri = namespaceContext.getNamespaceForPrefix(prefix);
235                 return new QName JavaDoc(uri, localName, prefix);
236             }
237             else {
238                 String JavaDoc uri = namespaceContext.getNamespaceForPrefix("");
239                 if (uri != null) {
240                     return new QName JavaDoc(uri, qualifiedName);
241                 }
242                 return new QName JavaDoc(qualifiedName);
243             }
244         }
245         return null;
246     }
247
248     protected String JavaDoc getAttribute(Element element, String JavaDoc attribute, String JavaDoc defaultValue) {
249         String JavaDoc answer = element.getAttribute(attribute);
250         if (answer == null || answer.length() == 0) {
251             answer = defaultValue;
252         }
253         return answer;
254     }
255 }
256
Popular Tags