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.client;
018:
019: import java.util.Iterator;
020: import java.util.Map;
021:
022: import javax.jbi.JBIException;
023: import javax.jbi.component.ComponentContext;
024: import javax.jbi.messaging.DeliveryChannel;
025: import javax.jbi.messaging.Fault;
026: import javax.jbi.messaging.InOnly;
027: import javax.jbi.messaging.InOptionalOut;
028: import javax.jbi.messaging.InOut;
029: import javax.jbi.messaging.MessageExchange;
030: import javax.jbi.messaging.MessageExchangeFactory;
031: import javax.jbi.messaging.MessagingException;
032: import javax.jbi.messaging.NormalizedMessage;
033: import javax.jbi.messaging.RobustInOnly;
034: import javax.jbi.servicedesc.ServiceEndpoint;
035: import javax.xml.namespace.QName;
036:
037: import org.w3c.dom.DocumentFragment;
038:
039: import org.apache.servicemix.components.util.ComponentSupport;
040: import org.apache.servicemix.jbi.FaultException;
041: import org.apache.servicemix.jbi.NoOutMessageAvailableException;
042: import org.apache.servicemix.jbi.container.ActivationSpec;
043: import org.apache.servicemix.jbi.container.JBIContainer;
044: import org.apache.servicemix.jbi.messaging.DefaultMarshaler;
045: import org.apache.servicemix.jbi.messaging.PojoMarshaler;
046: import org.apache.servicemix.jbi.resolver.EndpointFilter;
047: import org.apache.servicemix.jbi.resolver.EndpointResolver;
048: import org.apache.servicemix.jbi.resolver.ExternalInterfaceNameEndpointResolver;
049: import org.apache.servicemix.jbi.resolver.ExternalServiceNameEndpointResolver;
050: import org.apache.servicemix.jbi.resolver.InterfaceNameEndpointResolver;
051: import org.apache.servicemix.jbi.resolver.NullEndpointFilter;
052: import org.apache.servicemix.jbi.resolver.ServiceAndEndpointNameResolver;
053: import org.apache.servicemix.jbi.resolver.ServiceNameEndpointResolver;
054: import org.apache.servicemix.jbi.resolver.URIResolver;
055:
056: /**
057: * The default implementation of the {@link ServiceMixClient} API.
058: *
059: * @version $Revision: 564374 $
060: */
061: public class DefaultServiceMixClient extends ComponentSupport implements
062: ServiceMixClient {
063:
064: private EndpointFilter filter = NullEndpointFilter.getInstance();
065: private PojoMarshaler marshaler = new DefaultMarshaler();
066: private JBIContainer container;
067: private ActivationSpec activationSpec;
068:
069: protected DefaultServiceMixClient() {
070: }
071:
072: /**
073: * Provides the JBI container used for message dispatch.
074: */
075: public DefaultServiceMixClient(JBIContainer container)
076: throws JBIException {
077: this (container, new ActivationSpec());
078: }
079:
080: /**
081: * Provides the JBI container and the activation specification, which can be used to register this
082: * client at a specific endpoint so that default container routing rules can be configured via dependency injection
083: * and the client endpoint metadata can be configured to allow services to talk to this client.
084: */
085: public DefaultServiceMixClient(JBIContainer container,
086: ActivationSpec activationSpec) throws JBIException {
087: this .container = container;
088: this .activationSpec = activationSpec;
089: activationSpec.setComponent(this );
090: container.activateComponent(activationSpec);
091: }
092:
093: public InOnly createInOnlyExchange() throws MessagingException {
094: InOnly exchange = getExchangeFactory().createInOnlyExchange();
095: NormalizedMessage in = exchange.createMessage();
096: exchange.setInMessage(in);
097: return exchange;
098: }
099:
100: public InOnly createInOnlyExchange(EndpointResolver resolver)
101: throws JBIException {
102: InOnly exchange = createInOnlyExchange();
103: configureEndpoint(exchange, resolver);
104: return exchange;
105: }
106:
107: public InOut createInOutExchange() throws MessagingException {
108: InOut exchange = getExchangeFactory().createInOutExchange();
109: NormalizedMessage in = exchange.createMessage();
110: exchange.setInMessage(in);
111: return exchange;
112: }
113:
114: public InOut createInOutExchange(EndpointResolver resolver)
115: throws JBIException {
116: InOut exchange = createInOutExchange();
117: configureEndpoint(exchange, resolver);
118: return exchange;
119: }
120:
121: public InOptionalOut createInOptionalOutExchange()
122: throws MessagingException {
123: InOptionalOut exchange = getExchangeFactory()
124: .createInOptionalOutExchange();
125: NormalizedMessage in = exchange.createMessage();
126: exchange.setInMessage(in);
127: return exchange;
128: }
129:
130: public InOptionalOut createInOptionalOutExchange(
131: EndpointResolver resolver) throws JBIException {
132: InOptionalOut exchange = createInOptionalOutExchange();
133: configureEndpoint(exchange, resolver);
134: return exchange;
135: }
136:
137: public RobustInOnly createRobustInOnlyExchange()
138: throws MessagingException {
139: RobustInOnly exchange = getExchangeFactory()
140: .createRobustInOnlyExchange();
141: NormalizedMessage in = exchange.createMessage();
142: exchange.setInMessage(in);
143: return exchange;
144: }
145:
146: public RobustInOnly createRobustInOnlyExchange(
147: EndpointResolver resolver) throws JBIException {
148: RobustInOnly exchange = getExchangeFactory()
149: .createRobustInOnlyExchange();
150: configureEndpoint(exchange, resolver);
151: return exchange;
152: }
153:
154: public Destination createDestination(String uri)
155: throws MessagingException {
156: return new DefaultDestination(this , uri);
157: }
158:
159: public void send(MessageExchange exchange)
160: throws MessagingException {
161: getDeliveryChannel().send(exchange);
162: }
163:
164: public void send(Message message) throws MessagingException {
165: send(message.getExchange());
166: }
167:
168: public boolean sendSync(MessageExchange exchange)
169: throws MessagingException {
170: return getDeliveryChannel().sendSync(exchange);
171: }
172:
173: public boolean sendSync(MessageExchange exchange, long timeout)
174: throws MessagingException {
175: return getDeliveryChannel().sendSync(exchange, timeout);
176: }
177:
178: public MessageExchange receive() throws MessagingException {
179: return getDeliveryChannel().accept();
180: }
181:
182: public MessageExchange receive(long timeout)
183: throws MessagingException {
184: return getDeliveryChannel().accept(timeout);
185: }
186:
187: public ComponentContext getContext() {
188: return super .getContext();
189: }
190:
191: public DeliveryChannel getDeliveryChannel()
192: throws MessagingException {
193: return super .getDeliveryChannel();
194: }
195:
196: public MessageExchangeFactory getExchangeFactory()
197: throws MessagingException {
198: return super .getExchangeFactory();
199: }
200:
201: public void done(MessageExchange exchange)
202: throws MessagingException {
203: super .done(exchange);
204: }
205:
206: public void fail(MessageExchange exchange, Fault fault)
207: throws MessagingException {
208: super .fail(exchange, fault);
209: }
210:
211: public void fail(MessageExchange exchange, Exception error)
212: throws MessagingException {
213: super .fail(exchange, error);
214: }
215:
216: // Helper methods to make JBI a little more concise to use from a client
217: //-------------------------------------------------------------------------
218: public Object request(Map inMessageProperties, Object content)
219: throws JBIException {
220: return request(null, null, inMessageProperties, content);
221: }
222:
223: public void send(Map inMessageProperties, Object content)
224: throws JBIException {
225: send(null, null, inMessageProperties, content);
226: }
227:
228: public boolean sendSync(Map inMessageProperties, Object content)
229: throws JBIException {
230: return sendSync(null, null, inMessageProperties, content);
231: }
232:
233: public void send(EndpointResolver resolver, Map exchangeProperties,
234: Map inMessageProperties, Object content)
235: throws JBIException {
236: InOnly exchange = createInOnlyExchange(resolver);
237: populateMessage(exchange, exchangeProperties,
238: inMessageProperties, content);
239: send(exchange);
240: }
241:
242: public boolean sendSync(EndpointResolver resolver,
243: Map exchangeProperties, Map inMessageProperties,
244: Object content) throws JBIException {
245: InOnly exchange = createInOnlyExchange(resolver);
246: populateMessage(exchange, exchangeProperties,
247: inMessageProperties, content);
248: return sendSync(exchange);
249: }
250:
251: public Object request(EndpointResolver resolver,
252: Map exchangeProperties, Map inMessageProperties,
253: Object content) throws JBIException {
254: InOut exchange = createInOutExchange(resolver);
255: populateMessage(exchange, exchangeProperties,
256: inMessageProperties, content);
257: boolean answer = sendSync(exchange);
258: if (!answer) {
259: throw new JBIException("Exchange aborted");
260: }
261: Exception error = exchange.getError();
262: if (error != null) {
263: throw new JBIException(error);
264: }
265: if (exchange.getFault() != null) {
266: throw FaultException.newInstance(exchange);
267: }
268:
269: NormalizedMessage outMessage = exchange.getOutMessage();
270: if (outMessage == null) {
271: throw new NoOutMessageAvailableException(exchange);
272: }
273: return getMarshaler().unmarshal(exchange, outMessage);
274: }
275:
276: /**
277: * Resolves a WS-Addressing endpoint reference String into a JBI {@link ServiceEndpoint}
278: * reference so that message exchanges can be directed to an endpoint
279: */
280: public ServiceEndpoint resolveEndpointReference(String uri) {
281: DocumentFragment epr = URIResolver.createWSAEPR(uri);
282: return getContext().resolveEndpointReference(epr);
283: }
284:
285: public EndpointResolver createResolverForService(QName service) {
286: return new ServiceNameEndpointResolver(service);
287: }
288:
289: public EndpointResolver createResolverInterface(QName interfaceName) {
290: return new InterfaceNameEndpointResolver(interfaceName);
291: }
292:
293: public EndpointResolver createResolverForExternalService(
294: QName service) {
295: return new ExternalServiceNameEndpointResolver(service);
296: }
297:
298: public EndpointResolver createResolverForExternalInterface(
299: QName interfaceName) {
300: return new ExternalInterfaceNameEndpointResolver(interfaceName);
301: }
302:
303: public EndpointResolver createResolverForExternalInterface(
304: QName service, String endpoint) {
305: return new ServiceAndEndpointNameResolver(service, endpoint);
306: }
307:
308: public void close() throws JBIException {
309: if (container != null) {
310: container.deactivateComponent(activationSpec
311: .getComponentName());
312: }
313: }
314:
315: // Properties
316: //-------------------------------------------------------------------------
317: public EndpointFilter getFilter() {
318: return filter;
319: }
320:
321: /**
322: * Sets the filter used to exclude possible endpoints based on their capabilities
323: *
324: * @param filter
325: */
326: public void setFilter(EndpointFilter filter) {
327: this .filter = filter;
328: }
329:
330: public PojoMarshaler getMarshaler() {
331: return marshaler;
332: }
333:
334: /**
335: * Sets the marshaler used to convert objects which are not already JAXP {@link Source} instances
336: * into the normalized message content.
337: *
338: * @param marshaler
339: */
340: public void setMarshaler(PojoMarshaler marshaler) {
341: this .marshaler = marshaler;
342: }
343:
344: // Implementation methods
345: //-------------------------------------------------------------------------
346:
347: protected void configureEndpoint(MessageExchange exchange,
348: EndpointResolver resolver) throws JBIException {
349: if (resolver != null) {
350: exchange.setEndpoint(resolver.resolveEndpoint(getContext(),
351: exchange, filter));
352: }
353: }
354:
355: protected void populateMessage(MessageExchange exchange,
356: Map exchangeProperties, Map inMessageProperties,
357: Object content) throws MessagingException {
358: NormalizedMessage in = exchange.getMessage("in");
359: populateExchangeProperties(exchange, exchangeProperties);
360: populateMessageProperties(in, inMessageProperties);
361: getMarshaler().marshal(exchange, in, content);
362: }
363:
364: protected void populateExchangeProperties(MessageExchange exchange,
365: Map properties) {
366: if (properties != null) {
367: for (Iterator iter = properties.entrySet().iterator(); iter
368: .hasNext();) {
369: Map.Entry entry = (Map.Entry) iter.next();
370: exchange.setProperty((String) entry.getKey(), entry
371: .getValue());
372: }
373: }
374: }
375:
376: protected void populateMessageProperties(NormalizedMessage message,
377: Map properties) {
378: if (properties != null) {
379: for (Iterator iter = properties.entrySet().iterator(); iter
380: .hasNext();) {
381: Map.Entry entry = (Map.Entry) iter.next();
382: message.setProperty((String) entry.getKey(), entry
383: .getValue());
384: }
385: }
386: }
387: }
|