KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > petals > component > common > AbstractComponent


1 package org.objectweb.petals.component.common;
2
3 import java.util.logging.Level JavaDoc;
4 import java.util.logging.Logger JavaDoc;
5
6 import javax.jbi.JBIException;
7 import javax.jbi.component.Component;
8 import javax.jbi.component.ComponentContext;
9 import javax.jbi.component.ComponentLifeCycle;
10 import javax.jbi.component.ServiceUnitManager;
11 import javax.jbi.messaging.DeliveryChannel;
12 import javax.jbi.messaging.Fault;
13 import javax.jbi.messaging.MessageExchange;
14 import javax.jbi.messaging.MessagingException;
15 import javax.jbi.servicedesc.ServiceEndpoint;
16 import javax.management.ObjectName JavaDoc;
17 import javax.xml.transform.Source JavaDoc;
18
19 import org.objectweb.petals.component.common.listener.MessageExchangeListener;
20 import org.objectweb.petals.component.common.listener.MessageExchangeProcessor;
21 import org.objectweb.petals.component.common.listener.ProcessingResult;
22 import org.objectweb.petals.component.common.su.ServiceUnitListener;
23 import org.objectweb.petals.component.common.su.SimpleServiceUnitManager;
24 import org.objectweb.petals.component.common.util.ComponentLogger;
25 import org.objectweb.petals.component.common.util.MessageExchangeWrapper;
26 import org.objectweb.petals.component.common.util.SourceHelper;
27 import org.objectweb.petals.tools.jbicommon.descriptor.Consumes;
28 import org.objectweb.petals.tools.jbicommon.descriptor.Extensions;
29 import org.objectweb.petals.tools.jbicommon.descriptor.Provides;
30 import org.objectweb.petals.tools.jbicommon.util.StringHelper;
31 import org.w3c.dom.Document JavaDoc;
32 import org.w3c.dom.DocumentFragment JavaDoc;
33
34 /**
35  * An abstract class that can be used to easily create a new JBI Component. It
36  * implements Component, ComponentLifeCycle and MessageExchangeProcessor JBI
37  * interfaces.
38  *
39  * @author ofabre
40  *
41  */

42 public abstract class AbstractComponent implements Component,
43     ComponentLifeCycle, MessageExchangeProcessor {
44
45     private static final String JavaDoc MESSAGE_EXCHANGE_SETTING_ERROR = "Error during message exchange setting";
46
47     /**
48      * The component's delivery channel
49      */

50     private DeliveryChannel channel;
51
52     /**
53      * The Component's Context
54      */

55     private ComponentContext context;
56
57     /**
58      * The message exchange listener
59      */

60     private MessageExchangeListener listener;
61
62     /**
63      * The component's logger
64      */

65     private Logger JavaDoc log; // NOPMD by ofabre
66

67     /**
68      * The component's service unit manager
69      */

70     private SimpleServiceUnitManager suManager;
71
72     /**
73      * The ServiceUnit lifecycle listener
74      */

75     private ServiceUnitListener serviceUnitListener;
76
77     public ComponentLifeCycle getLifeCycle() {
78         return this;
79     }
80
81     public Document JavaDoc getServiceDescription(ServiceEndpoint endpoint) {
82         return suManager.getServiceDescription(endpoint);
83     }
84
85     public ServiceUnitManager getServiceUnitManager() {
86         return suManager;
87     }
88
89     public ServiceUnitListener getServiceUnitListener() {
90         return serviceUnitListener;
91     }
92
93     public void setServiceUnitListener(ServiceUnitListener serviceUnitListener) {
94         this.serviceUnitListener = serviceUnitListener;
95     }
96
97     public boolean isExchangeWithConsumerOkay(ServiceEndpoint endpoint,
98         MessageExchange exchange) {
99         return true;
100     }
101
102     public boolean isExchangeWithProviderOkay(ServiceEndpoint endpoint,
103         MessageExchange exchange) {
104         return true;
105     }
106
107     public ServiceEndpoint resolveEndpointReference(DocumentFragment JavaDoc epr) {
108         return null;
109     }
110
111     /**
112      * Returns null by default as this class does not provides JMX extension
113      * MBean
114      *
115      * @see javax.jbi.component.ComponentLifeCycle#getExtensionMBeanName()
116      */

117     public ObjectName JavaDoc getExtensionMBeanName() {
118         return null;
119     }
120
121     public void init(ComponentContext compContext) throws JBIException {
122         this.context = compContext;
123         Logger JavaDoc logger = context.getLogger("", getResourceBundleName());
124         this.log = new ComponentLogger(logger, logger.getName(), logger
125             .getResourceBundleName(), context.getComponentName());
126         channel = context.getDeliveryChannel();
127         suManager = createServiceUnitManager();
128         log.log(Level.INFO, "Component initialized");
129         init();
130     }
131
132     /**
133      * This method is called at the end of the component classical
134      * initialization. It could be overidden to make additional initialization.
135      * When this method is called, the component's delivery channel, context,
136      * logger and service unit manager are available.
137      *
138      */

139     protected void init() {
140
141     }
142
143     /**
144      * Can be overidden to return a custom resource bundle name
145      *
146      * @return the resource bundle name or null if no resource bundle name has
147      * to be used (default value)
148      */

149     protected String JavaDoc getResourceBundleName() {
150         return null;
151     }
152
153     public void shutDown() throws JBIException {
154         log.log(Level.INFO, "shutdown");
155         listener = null; // NOPMD frees the memory while component is
156
// shutdown
157
context = null; // NOPMD idem
158
log = null; // NOPMD idem
159
channel = null; // NOPMD idem
160
suManager = null; // NOPMD idem
161

162     }
163
164     public void start() throws JBIException {
165         log.log(Level.INFO, "start");
166         listener = createMessageExchangeListener(this);
167         listener.listen();
168
169     }
170
171     public void stop() throws JBIException {
172         log.log(Level.INFO, "stop");
173         // FIXME : call terminate or close?
174
this.listener.terminate();
175
176     }
177
178     public ProcessingResult process(final MessageExchangeWrapper exchange)
179         throws JBIException {
180         if (exchange == null) {
181             throw new JBIException("Message exchange to process can't be null");
182         }
183         if (exchange.isActiveStatus()) {
184             if (exchange.isProviderRole()) {
185                 if (exchange.isInOnlyPattern()) {
186                     processInOnly(exchange);
187                 } else if (exchange.isRobustInOnlyPattern()) {
188                     processRobustInOnly(exchange);
189                 } else if (exchange.isInOutPattern()
190                     || exchange.isInOptionalOutPattern()) {
191                     processInOut(exchange);
192                 } else {
193                     MessagingException e = new MessagingException(
194                         "MessageExchangePattern not recognized :"
195                             + exchange.getPattern());
196                     exchange.setError(e);
197                     channel.send(exchange.getMessageExchange());
198                     throw e;
199                 }
200                 channel.send(exchange.getMessageExchange());
201             }
202         } else {
203             log.log(Level.INFO, "No processing on Unactive MEP");
204         }
205         return ProcessingResult.SUCESS;
206     }
207
208     /**
209      * Process "in-only" MessageExchange
210      *
211      * @param exchange
212      * the MessageExchange
213      * @throws PEtALSComponentSDKException
214      * When errors occur during processing
215      */

216     private void processInOnly(final MessageExchangeWrapper exchange)
217         throws PEtALSComponentSDKException {
218         try {
219             Extensions extensions = getExchangeEpJBIExtensions(exchange);
220             onExchange(exchange, extensions);
221         } catch (HandlingException e) {
222             throw new PEtALSComponentSDKException(
223                 "Processing error but InOnly message can not contains Fault.",
224                 e);
225         } finally {
226             try {
227                 if (exchange.isActiveStatus()) {
228                     exchange.setDoneStatus();
229                 }
230             } catch (MessagingException e) {
231                 log.severe(MESSAGE_EXCHANGE_SETTING_ERROR);
232                 throw new PEtALSComponentSDKException(
233                     MESSAGE_EXCHANGE_SETTING_ERROR, e);
234             }
235         }
236     }
237
238     /**
239      * Process "robust-in-only" MessageExchange
240      *
241      * @param exchange
242      * the MessageExchange
243      * @throws PEtALSComponentSDKException
244      * When errors occur during processing
245      *
246      */

247     private void processRobustInOnly(final MessageExchangeWrapper exchange)
248         throws PEtALSComponentSDKException {
249         try {
250             Extensions extensions = getExchangeEpJBIExtensions(exchange);
251             onExchange(exchange, extensions);
252         } catch (HandlingException e) {
253             try {
254                 log.log(Level.SEVERE,
255                     "Error during message exchange processing", e);
256                 exchange.setFault(createFault(e, exchange));
257             } catch (MessagingException e1) {
258                 log.severe(MESSAGE_EXCHANGE_SETTING_ERROR);
259                 throw new PEtALSComponentSDKException(
260                     MESSAGE_EXCHANGE_SETTING_ERROR, e1);
261             }
262         }
263     }
264
265     /**
266      * Process "in-out" MessageExchange
267      *
268      * @param exchange
269      * the MessageExchange
270      * @throws PEtALSComponentSDKException
271      * When errors occur during processing
272      *
273      */

274     private void processInOut(final MessageExchangeWrapper exchange)
275         throws PEtALSComponentSDKException {
276         try {
277             if (!ackFaultReception(exchange)) {
278
279                 Extensions extensions = getExchangeEpJBIExtensions(exchange);
280
281                 boolean outTreated = onExchange(exchange, extensions);
282
283                 if (!outTreated) {
284                     exchange.setDoneStatus();
285                 }
286             }
287         } catch (HandlingException e) {
288             try {
289                 log.log(Level.SEVERE,
290                     "Error during message exchange processing", e);
291                 exchange.setFault(createFault(e, exchange));
292             } catch (MessagingException e1) {
293                 log.severe(MESSAGE_EXCHANGE_SETTING_ERROR);
294                 throw new PEtALSComponentSDKException(
295                     MESSAGE_EXCHANGE_SETTING_ERROR, e1);
296             }
297         } catch (MessagingException e) {
298             log.severe(MESSAGE_EXCHANGE_SETTING_ERROR);
299             throw new PEtALSComponentSDKException(
300                 MESSAGE_EXCHANGE_SETTING_ERROR, e);
301         }
302     }
303
304     private Extensions getExchangeEpJBIExtensions(
305         final MessageExchangeWrapper exchange) {
306         ServiceEndpoint ep = exchange.getEndpoint();
307         Extensions extensions = null;
308         if (ep != null) {
309             Provides provides = suManager.getProvidesFromEndpoint(ep);
310             if (provides != null) {
311                 extensions = provides.getExtensions();
312             }
313         }
314         return extensions;
315     }
316
317     /**
318      * Creates a Fault from an exception
319      *
320      * @param e
321      * The {@link Exception} used to create a new {@link Fault}
322      * @param exchange
323      * The {@link MessageExchange} that allows to create a new
324      * {@link Fault}
325      * @return the created Fault
326      * @throws PEtALSComponentSDKException
327      * if an error occured during Fault creation or filling
328      */

329     private Fault createFault(final JBIException e,
330         final MessageExchangeWrapper exchange)
331         throws PEtALSComponentSDKException {
332         String JavaDoc msg = "";
333         Fault f = null;
334         try {
335             f = exchange.createFault();
336         } catch (MessagingException e1) {
337             msg = "Error during Fault creation";
338             log.severe(msg);
339             throw new PEtALSComponentSDKException(msg, e1);
340         }
341         // String faultString = SourceHelper.createSoapFault(e, null);
342
String JavaDoc faultString = SourceHelper.createSoapFault(e, "0");
343         Source JavaDoc content = SourceHelper.createSource(faultString);
344         try {
345             f.setContent(content);
346         } catch (MessagingException e1) {
347             msg = "Error during Fault content setting";
348             log.severe(msg);
349             throw new PEtALSComponentSDKException(msg, e1);
350         }
351         return f;
352     }
353
354     /**
355      * If the received exchange is a fault response from the consumer,
356      * acknowledge it : status DONE
357      *
358      * @param exchange
359      * The processed {@link MessageExchange}
360      * @return true if the ack. of the Fault is done; false if no fault is
361      * present in the exchange
362      * @throws MessagingException
363      */

364     private boolean ackFaultReception(final MessageExchangeWrapper exchange)
365         throws MessagingException {
366         boolean result = false;
367
368         if (exchange.getFault() != null) {
369             exchange.setDoneStatus();
370             result = true;
371         }
372         return result;
373     }
374
375     /**
376      * Called to process a message exchange. MessageExchange handles all
377      * information of the exchange between provider and consumer (operation,
378      * MessageExchangePattern, payload...). Optionnal extensions can be used to
379      * handle complementary information
380      *
381      * @param exchange
382      * the message exchange to process, wrapped to add some util
383      * methods. Not null
384      * @param extensions
385      * JBI descriptor extensions. The message exchange targets a
386      * specific endpoint, this endpoint has been activated during the
387      * processing of a provides node of a service unit jbi
388      * descriptor. Theses extensions are the extensions of this
389      * provides node. Can be null
390      * @return true if the out response has been set, false otherwise (Useful
391      * for a in-out or in optionnal out mep)
392      *
393      * @see MEPConstants
394      * @throws HandlingException
395      * a Fault will be generated with the exception, the "out"
396      * message will not be treated
397      */

398     protected abstract boolean onExchange(MessageExchangeWrapper exchange,
399         Extensions extensions) throws HandlingException;
400
401     /**
402      * Can be overidden to provide a specific service unit manager
403      *
404      * @return the service unit manager used by this component.
405      */

406     protected SimpleServiceUnitManager createServiceUnitManager() {
407         return new SimpleServiceUnitManager(this, context, log);
408     }
409
410     /**
411      * Creates a new MessageExchangeListener
412      *
413      * @param processor
414      * the messageExchange processor
415      * @return the created {@link MessageExchangeListener}
416      */

417     private MessageExchangeListener createMessageExchangeListener(
418         final MessageExchangeProcessor processor) {
419         return new MessageExchangeListener(channel, processor,
420             MessageExchangeListener.IgnoredStatus.DONE_AND_ERROR_IGNORED, 0,
421             context.getComponentName(), log);
422     }
423
424     /**
425      * Returns the component logger
426      *
427      * @return component logger. Not null.
428      */

429     public Logger JavaDoc getLogger() {
430         return log;
431     }
432
433     /**
434      * Returns the component delivery channel, used to send messages to petals
435      * container
436      *
437      * @return the delivery channel. Not null.
438      */

439     public DeliveryChannel getChannel() {
440         return channel;
441     }
442
443     /**
444      * The component context
445      *
446      * @return the component context. Not null.
447      */

448     public ComponentContext getContext() {
449         return context;
450     }
451
452     /**
453      * Send a message to the endpoint associated to the mapped address. For
454      * exemple, this method can be used by a listener, that listen to messages
455      * from external services (linked to the given address), in order to send
456      * these messages to internal JBI Components.
457      *
458      * @param address
459      * the distant address of the external consumer service. Must be
460      * non null and non empty.
461      * @param exchange
462      * the message exchange to be sent to the internal JBI Component.
463      * Must be non null.
464      * @throws MessagingException
465      * if the address has no endpoint associated to it, or if an
466      * error occurs while sending the message on the container
467      */

468     public void sendMessage(final String JavaDoc address, final MessageExchange exchange)
469         throws MessagingException {
470
471         if (StringHelper.isNullOrEmpty(address)) {
472             throw new MessagingException(
473                 "You must provide a non null and non empty address");
474         }
475         if (exchange == null) {
476             throw new MessagingException(
477                 "You must provide a non null MessageExchange");
478         }
479
480         Consumes consumes = suManager.getConsumesFromAddress(address);
481
482         ServiceEndpoint ep = null;
483         if (consumes.getEndpointName() != null
484             && consumes.getServiceName() != null) {
485             ep = context.getEndpoint(consumes.getServiceName(), consumes
486                 .getEndpointName());
487         }
488
489         exchange.setInterfaceName(consumes.getInterfaceName());
490         exchange.setService(consumes.getServiceName());
491         exchange.setEndpoint(ep);
492
493         try {
494             channel.send(exchange);
495         } catch (JBIException e) {
496             throw new MessagingException(
497                 "Failed to send the mapped message to the delivery channel.");
498         }
499
500     }
501 }
502
Popular Tags