001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.servicemix.components.util;
018:
019: import javax.jbi.component.Component;
020: import javax.jbi.component.ComponentLifeCycle;
021: import javax.jbi.component.ServiceUnitManager;
022: import javax.jbi.messaging.DeliveryChannel;
023: import javax.jbi.messaging.InOnly;
024: import javax.jbi.messaging.InOptionalOut;
025: import javax.jbi.messaging.InOut;
026: import javax.jbi.messaging.MessageExchange;
027: import javax.jbi.messaging.MessageExchangeFactory;
028: import javax.jbi.messaging.MessagingException;
029: import javax.jbi.messaging.NormalizedMessage;
030: import javax.jbi.messaging.RobustInOnly;
031: import javax.jbi.servicedesc.ServiceEndpoint;
032: import javax.xml.namespace.QName;
033:
034: import org.w3c.dom.Document;
035: import org.w3c.dom.DocumentFragment;
036:
037: import org.apache.servicemix.JbiConstants;
038: import org.apache.servicemix.jbi.NoInMessageAvailableException;
039:
040: /**
041: * A useful base class for developers wishing to implement a JBI Component.
042: *
043: * @version $Revision: 564374 $
044: */
045: public abstract class ComponentSupport extends PojoSupport implements
046: Component {
047:
048: private ComponentLifeCycle lifeCycle;
049: private ServiceUnitManager serviceManager;
050: private MessageTransformer messageTransformer = CopyTransformer
051: .getInstance();
052:
053: protected ComponentSupport() {
054: }
055:
056: protected ComponentSupport(QName service, String endpoint) {
057: super (service, endpoint);
058: }
059:
060: /**
061: * @return the lifecycel control implementation
062: */
063: public ComponentLifeCycle getLifeCycle() {
064: synchronized (this ) {
065: if (lifeCycle == null) {
066: lifeCycle = createComponentLifeCycle();
067: }
068: }
069: return lifeCycle;
070: }
071:
072: /**
073: * @return the ServiceUnitManager or null if there isn't one
074: */
075: public ServiceUnitManager getServiceUnitManager() {
076: initializeServiceUnitManager();
077: return serviceManager;
078: }
079:
080: /**
081: * @param fragment
082: * @return the description of the specified reference
083: */
084: public ServiceEndpoint resolveEndpointReference(
085: DocumentFragment fragment) {
086: return null;
087: }
088:
089: /**
090: * Retrieves a DOM representation containing metadata which describes the
091: * service provided by this component, through the given endpoint. The
092: * result can use WSDL 1.1 or WSDL 2.0.
093: *
094: * @param endpoint the service endpoint.
095: * @return the description for the specified service endpoint.
096: */
097:
098: public Document getServiceDescription(ServiceEndpoint endpoint) {
099: return null;
100: }
101:
102: /**
103: * This method is called by JBI to check if this component, in the role of
104: * provider of the service indicated by the given exchange, can actually
105: * perform the operation desired.
106: *
107: * @param endpoint the endpoint to be used by the consumer; must be
108: * non-null.
109: * @param exchange the proposed message exchange to be performed; must be
110: * non-null.
111: * @return <code>true</code> if this provider component can perform the
112: * given exchange with the described consumer.
113: */
114: public boolean isExchangeWithConsumerOkay(ServiceEndpoint endpoint,
115: MessageExchange exchange) {
116: return true;
117: }
118:
119: /**
120: * This method is called by JBI to check if this component, in the role of
121: * consumer of the service indicated by the given exchange, can actually
122: * interact with the provider properly. The provider is described by the
123: * given endpoint and the service description supplied by that endpoint.
124: *
125: * @param endpoint the endpoint to be used by the provider; must be
126: * non-null.
127: * @param exchange the proposed message exchange to be performed; must be
128: * non-null.
129: * @return <code>true</code> if this consumer component can interact with
130: * the described provider to perform the given exchange.
131: */
132: public boolean isExchangeWithProviderOkay(ServiceEndpoint endpoint,
133: MessageExchange exchange) {
134: return true;
135: }
136:
137: // Implementation methods
138: //-------------------------------------------------------------------------
139:
140: protected synchronized void initializeServiceUnitManager() {
141: if (this .serviceManager == null) {
142: this .serviceManager = createServiceUnitManager();
143: }
144: }
145:
146: protected ServiceUnitManager createServiceUnitManager() {
147: return new ServiceUnitManagerSupport();
148: }
149:
150: protected ComponentLifeCycle createComponentLifeCycle() {
151: return this ;
152: }
153:
154: /**
155: * Returns the in message or throws an exception if there is no in message.
156: */
157: protected NormalizedMessage getInMessage(MessageExchange exchange)
158: throws NoInMessageAvailableException {
159: NormalizedMessage message = exchange.getMessage("in");
160: if (message == null) {
161: throw new NoInMessageAvailableException(exchange);
162: }
163: return message;
164: }
165:
166: public MessageTransformer getMessageTransformer() {
167: return messageTransformer;
168: }
169:
170: public void setMessageTransformer(MessageTransformer transformer) {
171: this .messageTransformer = transformer;
172: }
173:
174: /**
175: * Performs an invocation where the service, operation or interface name could be specified
176: *
177: * @param exchange
178: * @param in
179: * @param service
180: * @param interfaceName
181: * @param operation
182: */
183: public void invoke(MessageExchange exchange, NormalizedMessage in,
184: QName service, QName interfaceName, QName operation)
185: throws MessagingException {
186: InOnly outExchange = createInOnlyExchange(service,
187: interfaceName, operation);
188: forwardToExchange(exchange, outExchange, in, operation);
189: }
190:
191: /**
192: * Creates a new InOnly exchange for the given service, interface and/or operation (any of which can be null).
193: */
194: public InOnly createInOnlyExchange(QName service,
195: QName interfaceName, QName operation)
196: throws MessagingException {
197: DeliveryChannel channel = getDeliveryChannel();
198: MessageExchangeFactory factory = null;
199: if (service != null) {
200: factory = channel.createExchangeFactoryForService(service);
201: } else if (interfaceName != null) {
202: factory = channel.createExchangeFactory(interfaceName);
203: } else {
204: factory = getExchangeFactory();
205: }
206: InOnly outExchange = factory.createInOnlyExchange();
207: if (service != null) {
208: outExchange.setService(service);
209: }
210: if (interfaceName != null) {
211: outExchange.setInterfaceName(interfaceName);
212: }
213: if (operation != null) {
214: outExchange.setOperation(operation);
215: }
216: return outExchange;
217: }
218:
219: public InOnly createInOnlyExchange(QName service,
220: QName interfaceName, QName operation,
221: MessageExchange beforeExchange) throws MessagingException {
222: InOnly inOnly = createInOnlyExchange(service, interfaceName,
223: operation);
224: propagateCorrelationId(beforeExchange, inOnly);
225: return inOnly;
226: }
227:
228: /**
229: * Creates a new InOut exchange for the given service, interface and/or operation (any of which can be null).
230: */
231: public InOut createInOutExchange(QName service,
232: QName interfaceName, QName operation)
233: throws MessagingException {
234: DeliveryChannel channel = getDeliveryChannel();
235: MessageExchangeFactory factory = null;
236: if (service != null) {
237: factory = channel.createExchangeFactoryForService(service);
238: } else if (interfaceName != null) {
239: factory = channel.createExchangeFactory(interfaceName);
240: } else {
241: factory = getExchangeFactory();
242: }
243: InOut outExchange = factory.createInOutExchange();
244: if (service != null) {
245: outExchange.setService(service);
246: }
247: if (interfaceName != null) {
248: outExchange.setInterfaceName(interfaceName);
249: }
250: if (operation != null) {
251: outExchange.setOperation(operation);
252: }
253: return outExchange;
254: }
255:
256: public InOut creatInOutExchange(QName service, QName interfaceName,
257: QName operation, MessageExchange srcExchange)
258: throws MessagingException {
259: InOut inOut = createInOutExchange(service, interfaceName,
260: operation);
261: propagateCorrelationId(srcExchange, inOut);
262: return inOut;
263: }
264:
265: /**
266: * Creates an InOnly exchange and propagates the correlation id from the given exchange
267: * to the newly created exchange
268: * @param srcExchange
269: * @return InOnly
270: * @throws MessagingException
271: */
272: public InOnly createInOnlyExchange(MessageExchange srcExchange)
273: throws MessagingException {
274: MessageExchangeFactory factory = getExchangeFactory();
275: InOnly inOnly = factory.createInOnlyExchange();
276:
277: propagateCorrelationId(srcExchange, inOnly);
278:
279: return inOnly;
280: }
281:
282: /**
283: * Creates an InOptionalOut exchange and propagates the correlation id from the given exchange
284: * to the newly created exchange
285: * @param srcExchange
286: * @return InOptionalOut
287: * @throws MessagingException
288: */
289: public InOptionalOut createInOptionalOutExchange(
290: MessageExchange srcExchange) throws MessagingException {
291: MessageExchangeFactory factory = getExchangeFactory();
292: InOptionalOut inOptionalOut = factory
293: .createInOptionalOutExchange();
294:
295: propagateCorrelationId(srcExchange, inOptionalOut);
296:
297: return inOptionalOut;
298: }
299:
300: /**
301: * Creates an InOut exchange and propagates the correlation id from the given exchange
302: * to the newly created exchange
303: * @param srcExchange
304: * @return InOut
305: * @throws MessagingException
306: */
307: public InOut createInOutExchange(MessageExchange srcExchange)
308: throws MessagingException {
309: MessageExchangeFactory factory = getExchangeFactory();
310: InOut inOut = factory.createInOutExchange();
311:
312: propagateCorrelationId(srcExchange, inOut);
313:
314: return inOut;
315: }
316:
317: /**
318: * Creates an RobustInOnly exchange and propagates the correlation id from the given exchange
319: * to the newly created exchange
320: * @param srcExchange
321: * @return RobustInOnly the created exchange
322: * @throws MessagingException
323: */
324: public RobustInOnly createRobustInOnlyExchange(
325: MessageExchange srcExchange) throws MessagingException {
326: MessageExchangeFactory factory = getExchangeFactory();
327: RobustInOnly robustInOnly = factory
328: .createRobustInOnlyExchange();
329:
330: propagateCorrelationId(srcExchange, robustInOnly);
331:
332: return robustInOnly;
333: }
334:
335: /**
336: * Propagates the correlation id from an exchange to a newly created exchange
337: * @param source Exchange which already exists
338: * @param dest Newly created exchange which should get the correlation id
339: */
340: public void propagateCorrelationId(MessageExchange source,
341: MessageExchange dest) {
342: if (source == null || dest == null) {
343: return;
344: }
345: String correlationId = (String) source
346: .getProperty(JbiConstants.CORRELATION_ID);
347: if (correlationId != null) {
348: dest
349: .setProperty(JbiConstants.CORRELATION_ID,
350: correlationId);
351: } else {
352: dest.setProperty(JbiConstants.CORRELATION_ID, source
353: .getExchangeId());
354: }
355: }
356:
357: protected void forwardToExchange(MessageExchange exchange,
358: InOnly outExchange, NormalizedMessage in,
359: QName operationName) throws MessagingException {
360: if (operationName != null) {
361: exchange.setOperation(operationName);
362: }
363: forwardToExchange(exchange, outExchange, in);
364: }
365:
366: protected void forwardToExchange(MessageExchange exchange,
367: InOnly outExchange, NormalizedMessage in)
368: throws MessagingException {
369: NormalizedMessage out = outExchange.createMessage();
370: outExchange.setInMessage(out);
371: getMessageTransformer().transform(exchange, in, out);
372: getDeliveryChannel().send(outExchange);
373: }
374: }
|