KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > servicemix > bpe > external > JbiInvokeAction


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.bpe.external;
18
19 import java.net.URI JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.Map JavaDoc;
23 import java.util.Properties JavaDoc;
24
25 import javax.jbi.messaging.DeliveryChannel;
26 import javax.jbi.messaging.ExchangeStatus;
27 import javax.jbi.messaging.MessageExchange;
28 import javax.jbi.messaging.MessageExchangeFactory;
29 import javax.jbi.messaging.MessagingException;
30 import javax.jbi.messaging.NormalizedMessage;
31 import javax.wsdl.Definition;
32 import javax.wsdl.Fault;
33 import javax.wsdl.Operation;
34 import javax.wsdl.Part;
35 import javax.wsdl.PortType;
36 import javax.xml.namespace.QName JavaDoc;
37 import javax.xml.transform.Source JavaDoc;
38 import javax.xml.transform.dom.DOMSource JavaDoc;
39
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.apache.ode.bpe.action.external.ActionSystemException;
43 import org.apache.ode.bpe.action.external.IExternalAction;
44 import org.apache.ode.bpe.action.external.IURIResolver;
45 import org.apache.ode.bpe.client.IFormattableValue;
46 import org.apache.ode.bpe.interaction.spiimpl.document.DocumentFormattableValue;
47 import org.apache.ode.bpe.scope.service.BPRuntimeException;
48 import org.apache.servicemix.bpe.BPEComponent;
49 import org.apache.servicemix.bpe.BPEEndpoint;
50 import org.apache.servicemix.bpe.BPELifeCycle;
51 import org.apache.servicemix.bpe.BPEServiceUnit;
52 import org.apache.servicemix.jbi.jaxp.BytesSource;
53 import org.apache.servicemix.jbi.jaxp.SourceTransformer;
54 import org.apache.servicemix.jbi.jaxp.StringSource;
55 import org.w3c.dom.Document JavaDoc;
56 import org.w3c.dom.Element JavaDoc;
57
58 public class JbiInvokeAction implements IExternalAction {
59
60     public static final String JavaDoc INTERFACE_NAMESPACE = "interfaceNamespace";
61     public static final String JavaDoc INTERFACE_LOCALNAME = "interfaceLocalName";
62     public static final String JavaDoc OPERATION_NAMESPACE = "operationNamespace";
63     public static final String JavaDoc OPERATION_LOCALNAME = "operationLocalName";
64     public static final String JavaDoc SERVICE_NAMESPACE = "serviceNamespace";
65     public static final String JavaDoc SERVICE_LOCALNAME = "serviceLocalName";
66     public static final String JavaDoc ENDPOINT_NAME = "endpointName";
67     public static final String JavaDoc ACTION = "action";
68     public static final String JavaDoc ENDPOINT = "endpoint";
69     public static final String JavaDoc MEP = "mep";
70     
71     private static Log log = LogFactory.getLog(JbiInvokeAction.class);
72     
73     private Properties JavaDoc properties;
74     private QName JavaDoc interfaceName;
75     private QName JavaDoc serviceName;
76     private String JavaDoc endpointName;
77     private QName JavaDoc operationName;
78     private String JavaDoc inputPartName = BPEComponent.PART_PAYLOAD;
79     private String JavaDoc outputPartName = BPEComponent.PART_PAYLOAD;
80     private URI JavaDoc mep;
81     private SourceTransformer transformer;
82     private Operation wsdlOperation;
83     
84     /**
85      * Generated serial version UID
86      */

87     private static final long serialVersionUID = -8522450752525724302L;
88     
89     public JbiInvokeAction() {
90         transformer = new SourceTransformer();
91     }
92
93     public void init(Properties JavaDoc props) throws BPRuntimeException, ActionSystemException {
94         if (log.isDebugEnabled()) {
95             log.debug("init");
96         }
97         this.properties = props;
98         extractInformations();
99         if (serviceName == null && interfaceName == null) {
100             throw new BPRuntimeException("Interface, Service or Endpoint should be specified", "");
101         }
102         if (log.isDebugEnabled()) {
103             log.debug("properties: " + props);
104         }
105     }
106
107     protected void extractInformations() {
108         String JavaDoc action = properties.getProperty(ACTION);
109         if (action != null) {
110             String JavaDoc[] parts = split(action);
111             interfaceName = new QName JavaDoc(parts[0], parts[1]);
112             operationName = new QName JavaDoc(parts[0], parts[2]);
113         } else {
114             String JavaDoc interfaceNamespace = properties.getProperty(INTERFACE_NAMESPACE);
115             String JavaDoc interfaceLocalName = properties.getProperty(INTERFACE_LOCALNAME);
116             if (interfaceLocalName != null) {
117                 interfaceName = new QName JavaDoc(interfaceNamespace, interfaceLocalName);
118             }
119             String JavaDoc operationNamespace = properties.getProperty(OPERATION_NAMESPACE);
120             String JavaDoc operationLocalName = properties.getProperty(OPERATION_LOCALNAME);
121             if (operationLocalName != null) {
122                 operationName = new QName JavaDoc(operationNamespace, operationLocalName);
123             }
124         }
125         String JavaDoc endpoint = properties.getProperty(ENDPOINT);
126         if (endpoint != null) {
127             String JavaDoc[] parts = split(action);
128             serviceName = new QName JavaDoc(parts[0], parts[1]);
129             endpointName = parts[2];
130         } else {
131             String JavaDoc serviceNamespace = properties.getProperty(SERVICE_NAMESPACE);
132             String JavaDoc serviceLocalName = properties.getProperty(SERVICE_LOCALNAME);
133             if (serviceLocalName != null) {
134                 serviceName = new QName JavaDoc(serviceNamespace, serviceLocalName);
135             }
136             endpointName = properties.getProperty(ENDPOINT_NAME);
137         }
138         String JavaDoc mep = properties.getProperty(MEP);
139         if (mep == null) {
140             BPEEndpoint ep = BPEEndpoint.getCurrent();
141             Definition def = ((BPEServiceUnit) ep.getServiceUnit()).getDefinition();
142             PortType pt = def.getPortType(interfaceName);
143             Operation oper = pt != null ? pt.getOperation(operationName.getLocalPart(), null, null) : null;
144             if (oper != null) {
145                 boolean output = oper.getOutput() != null &&
146                                  oper.getOutput().getMessage() != null &&
147                                  oper.getOutput().getMessage().getParts().size() > 0;
148                 boolean faults = oper.getFaults().size() > 0;
149                 if (output) {
150                     mep = "in-out";
151                 } else if (faults) {
152                     mep = "robust-in-only";
153                 } else {
154                     mep = "in-only";
155                 }
156                 if (oper.getInput() != null && oper.getInput().getMessage() != null) {
157                     Map JavaDoc parts = oper.getInput().getMessage().getParts();
158                     inputPartName = (String JavaDoc) parts.keySet().iterator().next();
159                 }
160                 if (oper.getOutput() != null && oper.getOutput().getMessage() != null) {
161                     Map JavaDoc parts = oper.getOutput().getMessage().getParts();
162                     outputPartName = (String JavaDoc) parts.keySet().iterator().next();
163                 }
164                 wsdlOperation = oper;
165             }
166         }
167         if (mep == null) {
168             mep = "in-out";
169         }
170         this.mep = URI.create("http://www.w3.org/2004/08/wsdl/" + mep);
171     }
172
173     public void execute(HashMap JavaDoc input, HashMap JavaDoc output, IURIResolver resolver)
174             throws BPRuntimeException, ActionSystemException {
175         if (log.isDebugEnabled()) {
176             log.debug("execute");
177         }
178         Object JavaDoc payload = input.get(inputPartName);
179         Source JavaDoc inputSource = getSourceFromPayload(payload);
180         // Create and send exchange
181
try {
182             BPEEndpoint endpoint = BPEEndpoint.getCurrent();
183             BPEComponent component = (BPEComponent) endpoint.getServiceUnit().getComponent();
184             DeliveryChannel channel = ((BPELifeCycle) component.getLifeCycle()).getContext().getDeliveryChannel();
185             MessageExchangeFactory factory = channel.createExchangeFactory();
186             // TODO: need to configure mep
187
MessageExchange me = factory.createExchange(this.mep);
188             me.setInterfaceName(interfaceName);
189             me.setService(serviceName);
190             // TODO: set endpoint
191
me.setOperation(operationName);
192             NormalizedMessage nm = me.createMessage();
193             me.setMessage(nm, "in");
194             nm.setContent(inputSource);
195             boolean res = channel.sendSync(me);
196             if (!res) {
197                 throw new ActionSystemException("Timeout on sending message");
198             }
199             if (me.getStatus() == ExchangeStatus.ACTIVE) {
200                 if (me.getFault() != null) {
201                     Document JavaDoc fault;
202                     try {
203                         fault = transformer.toDOMDocument(me.getFault());
204                         me.setStatus(ExchangeStatus.DONE);
205                     } catch (Exception JavaDoc e) {
206                         me.setError(e);
207                         throw new ActionSystemException(e);
208                     } finally {
209                         channel.send(me);
210                     }
211                     Element JavaDoc e = fault.getDocumentElement();
212                     // Try to determine fault name
213
String JavaDoc faultName = e.getLocalName();
214                     String JavaDoc partName = BPEComponent.PART_PAYLOAD;
215                     QName JavaDoc elemName = new QName JavaDoc(e.getNamespaceURI(), e.getLocalName());
216                     if (wsdlOperation != null) {
217                         for (Iterator JavaDoc itFault = wsdlOperation.getFaults().values().iterator(); itFault.hasNext();) {
218                             Fault f = (Fault) itFault.next();
219                             Part p = (Part) f.getMessage().getParts().values().iterator().next();
220                             if (elemName.equals(p.getTypeName())) {
221                                 faultName = f.getName();
222                                 partName = p.getName();
223                             }
224                         }
225                     }
226                     BPRuntimeException bpre = new BPRuntimeException(faultName, "");
227                     bpre.setNameSpace(e.getNamespaceURI());
228                     /* We must use a type that implements BPE's IFormattableValue interface
229                      * since otherwise the value will get wrapped in a CannedFormattableValue
230                      * which has undesireable side effects.
231                      */

232                     DocumentFormattableValue documentFormattableValue = new DocumentFormattableValue(fault);
233                     bpre.addPartMessage(partName, documentFormattableValue);
234                     throw bpre;
235                 } else {
236                     try {
237                         nm = me.getMessage("out");
238                         if (nm != null) {
239                             /* We must use a type that implements BPE's IFormattableValue interface
240                              * since otherwise the value will get wrapped in a CannedFormattableValue
241                              * which has undesireable side effects.
242                              */

243                             Document JavaDoc out = transformer.toDOMDocument(nm);
244                             DocumentFormattableValue documentFormattableValue = new DocumentFormattableValue(out);
245                             output.put(outputPartName, documentFormattableValue);
246                         }
247                         me.setStatus(ExchangeStatus.DONE);
248                     } catch (Exception JavaDoc e) {
249                         me.setError(e);
250                         throw new ActionSystemException(e);
251                     } finally {
252                         channel.send(me);
253                     }
254                 }
255             } else if (me.getStatus() == ExchangeStatus.ERROR) {
256                 // Extract error
257
Exception JavaDoc error = me.getError();
258                 throw new BPRuntimeException("Unknown", error);
259             }
260         } catch (MessagingException e) {
261             throw new ActionSystemException(e);
262         }
263         if (log.isDebugEnabled()) {
264             log.debug("Request: " + payload);
265             log.debug("Response: " + output.get(outputPartName));
266         }
267     }
268
269     protected Source JavaDoc getSourceFromPayload(Object JavaDoc payload) {
270         Source JavaDoc inputSource;
271         if (payload instanceof IFormattableValue) {
272             IFormattableValue value = (IFormattableValue) payload;
273             if (value.supportsGetValueAs(Document JavaDoc.class)) {
274                 Document JavaDoc doc = (Document JavaDoc) value.getValueAs(Document JavaDoc.class);
275                 inputSource = new DOMSource JavaDoc(doc);
276             } else if (value.supportsGetValueAs(byte[].class)) {
277                 byte[] data = (byte[]) value.getValueAs(byte[].class);
278                 inputSource = new BytesSource(data);
279             } else if (value.supportsGetValueAs(String JavaDoc.class)) {
280                 String JavaDoc data = (String JavaDoc) value.getValueAs(String JavaDoc.class);
281                 inputSource = new StringSource(data);
282             } else {
283                 throw new UnsupportedOperationException JavaDoc("Unable to retrieve value");
284             }
285         } else if (payload instanceof Document JavaDoc) {
286             inputSource = new DOMSource JavaDoc((Document JavaDoc) payload);
287         } else if (payload instanceof byte[]) {
288             inputSource = new BytesSource((byte[]) payload);
289         } else if (payload instanceof String JavaDoc) {
290             inputSource = new StringSource((String JavaDoc) payload);
291         } else {
292             throw new UnsupportedOperationException JavaDoc("Unable to retrieve value");
293         }
294         return inputSource;
295     }
296     
297     public void release() {
298         if (log.isDebugEnabled()) {
299             log.debug("release");
300         }
301     }
302
303     public void process(MessageExchange exchange) throws Exception JavaDoc {
304         // TODO Auto-generated method stub
305

306     }
307
308     public void start() throws Exception JavaDoc {
309         // TODO Auto-generated method stub
310

311     }
312
313     public void stop() throws Exception JavaDoc {
314         // TODO Auto-generated method stub
315

316     }
317
318     protected String JavaDoc[] split(String JavaDoc uri) {
319         char sep;
320         if (uri.indexOf('/') > 0) {
321             sep = '/';
322         } else {
323             sep = ':';
324         }
325         int idx1 = uri.lastIndexOf(sep);
326         int idx2 = uri.lastIndexOf(sep, idx1 - 1);
327         String JavaDoc epName = uri.substring(idx1 + 1);
328         String JavaDoc svcName = uri.substring(idx2 + 1, idx1);
329         String JavaDoc nsUri = uri.substring(0, idx2);
330         return new String JavaDoc[] { nsUri, svcName, epName };
331     }
332 }
333
Popular Tags