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 java.util.Iterator;
020 import java.util.Set;
021
022 import javax.jbi.messaging.ExchangeStatus;
023 import javax.jbi.messaging.InOut;
024 import javax.jbi.messaging.MessageExchange;
025 import javax.jbi.messaging.MessagingException;
026 import javax.jbi.messaging.NormalizedMessage;
027 import javax.xml.namespace.QName;
028
029 import org.apache.servicemix.jbi.FaultException;
030
031 /**
032 * This class allows a series of componeents to be chained together. It will
033 * invoke the first service, then take the output of that first service as the
034 * input to the next service, and return the overall results when finished.
035 *
036 * All properties and attachments are maintained.
037 *
038 * @author birchfieldj
039 * @deprecated use the StaticRoutingSlip pattern from the EIP component instead
040 *
041 */
042 public class ChainedComponent extends TransformComponentSupport {
043
044 private QName[] services = new QName[0];
045
046 protected boolean transform(MessageExchange exchange,
047 NormalizedMessage in,
048 NormalizedMessage out) throws MessagingException {
049 NormalizedMessage curIn = in;
050 MessageExchange curExchange = exchange;
051 for (int i = 0; i < services.length; i++) {
052 InOut mexchange = this.getDeliveryChannel()
053 .createExchangeFactoryForService(services[i])
054 .createInOutExchange();
055 copyProperties(curExchange, mexchange);
056 curIn = invokeService(mexchange, curIn, services[i]);
057 curExchange = mexchange;
058 }
059 getMessageTransformer().transform(exchange, curIn, out);
060 copyProperties(curExchange, exchange);
061 return true;
062 }
063
064 /**
065 * Invokes the service with the given message, and returns the output
066 *
067 * @param exchange
068 * @param in
069 * @param service
070 * @return the out message of the invoked service
071 * @throws MessagingException
072 */
073 private NormalizedMessage invokeService(InOut exchange,
074 NormalizedMessage in,
075 QName service) throws MessagingException {
076 NormalizedMessage msg = exchange.createMessage();
077 getMessageTransformer().transform(exchange, in, msg);
078 exchange.setMessage(msg, "in");
079 boolean result = this.getDeliveryChannel().sendSync(exchange);
080 if (result) {
081 if (exchange.getStatus() == ExchangeStatus.ERROR) {
082 exchange.setStatus(ExchangeStatus.DONE);
083 getDeliveryChannel().send(exchange);
084 if (exchange.getError() != null) {
085 throw new MessagingException("Received error", exchange.getError());
086 } else if (exchange.getFault() != null) {
087 throw new FaultException("Received fault", exchange, exchange.getFault());
088 } else {
089 throw new MessagingException("Received unknown error");
090 }
091 } else {
092 NormalizedMessage out = exchange.getOutMessage();
093 exchange.setStatus(ExchangeStatus.DONE);
094 getDeliveryChannel().send(exchange);
095 return out;
096 }
097 }
098 throw new MessagingException("Could not invoke service: " + service);
099 }
100
101 /**
102 *
103 * @param in
104 * echange to copy from
105 * @param out
106 * excahnge to copy to
107 */
108 private void copyProperties(MessageExchange in, MessageExchange out) {
109 Set propertyNames = in.getPropertyNames();
110 for (Iterator iter = propertyNames.iterator(); iter.hasNext();) {
111 String name = (String) iter.next();
112 out.setProperty(name, in.getProperty(name));
113 }
114 }
115
116 /**
117 * Allows the services to be set
118 *
119 * @param services
120 * a collection of QNAmes representing the services to be
121 * invoked.
122 */
123 public void setServices(QName[] services) {
124 this.services = services;
125 }
126
127 }