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.drools.model;
018    
019    import javax.jbi.component.ComponentContext;
020    import javax.jbi.messaging.DeliveryChannel;
021    import javax.jbi.messaging.Fault;
022    import javax.jbi.messaging.InOnly;
023    import javax.jbi.messaging.MessageExchange;
024    import javax.jbi.messaging.MessagingException;
025    import javax.jbi.messaging.NormalizedMessage;
026    import javax.xml.transform.Source;
027    
028    import org.apache.commons.logging.Log;
029    import org.apache.commons.logging.LogFactory;
030    import org.apache.servicemix.common.EndpointSupport;
031    import org.apache.servicemix.common.JbiConstants;
032    import org.apache.servicemix.common.util.MessageUtil;
033    import org.apache.servicemix.common.util.URIResolver;
034    import org.apache.servicemix.drools.DroolsComponent;
035    import org.apache.servicemix.drools.DroolsEndpoint;
036    import org.apache.servicemix.jbi.jaxp.SourceTransformer;
037    import org.apache.servicemix.jbi.jaxp.StringSource;
038    import org.drools.FactHandle;
039    import org.drools.WorkingMemory;
040    
041    /**
042     * A helper class for use inside a rule to forward a message to an endpoint
043     * 
044     * @version $Revision: 426415 $
045     */
046    public class JbiHelper {
047    
048        private DroolsEndpoint endpoint;
049        private Exchange exchange;
050        private WorkingMemory memory;
051        private FactHandle exchangeFactHandle;
052        private boolean exchangeHandled = false;
053    
054        public JbiHelper(DroolsEndpoint endpoint, MessageExchange exchange, WorkingMemory memory) {
055            this.endpoint = endpoint;
056            this.exchange = new Exchange(exchange, endpoint.getNamespaceContext());
057            this.memory = memory;
058            this.exchangeFactHandle = this.memory.insert(this.exchange);
059        }
060    
061        public DroolsEndpoint getEndpoint() {
062            return endpoint;
063        }
064    
065        public ComponentContext getContext() {
066            return endpoint.getContext();
067        }
068    
069        public DeliveryChannel getChannel() throws MessagingException {
070            return getContext().getDeliveryChannel();
071        }
072    
073        public Exchange getExchange() {
074            return exchange;
075        }
076    
077        public Log getLogger() {
078            return LogFactory.getLog(memory.getRuleBase().getPackages()[0].getName());
079        }
080    
081        /**
082         * Forwards the inbound message to the given target
083         * 
084         * @param uri
085         */
086        public void route(String uri) throws MessagingException {
087            Source src = null;
088            routeTo(src, uri);
089        }
090    
091        /**
092         * @see #routeTo(Source, String)
093         */
094        public void routeTo(String content, String uri) throws MessagingException {
095            if (content == null) {
096                routeTo(this.exchange.getInternalExchange().getMessage("in").getContent(), uri);
097            } else {
098                routeTo(new StringSource(content), uri);
099            }
100        }
101    
102        /**
103         * Send a message to the uri
104         *  
105         * @param content the message content
106         * @param uri the target endpoint's uri
107         * @throws MessagingException
108         */
109        public void routeTo(Source content, String uri) throws MessagingException {
110            MessageExchange me = this.exchange.getInternalExchange();
111    
112            NormalizedMessage in = null;
113            if (content == null) {
114                in = me.getMessage("in");
115            } else {
116                in = me.createMessage();
117                in.setContent(content);
118            }
119            MessageExchange newMe = getChannel().createExchangeFactory().createExchange(me.getPattern());
120            URIResolver.configureExchange(newMe, getContext(), uri);
121            MessageUtil.transferToIn(in, newMe);
122            // Set the sender endpoint property
123            String key = EndpointSupport.getKey(endpoint);
124            newMe.setProperty(JbiConstants.SENDER_ENDPOINT, key);
125            newMe.setProperty(JbiConstants.CORRELATION_ID, DroolsEndpoint.getCorrelationId(this.exchange.getInternalExchange()));
126            newMe.setProperty(DroolsComponent.DROOLS_CORRELATION_ID, me.getExchangeId());
127            getChannel().send(newMe);
128        }
129    
130        /**
131         * @see #routeToDefault(Source)
132         */
133        public void routeToDefault(String content) throws MessagingException {
134            routeTo(content, endpoint.getDefaultRouteURI());
135        }
136    
137        /**
138         * Send this content to the default routing URI ({@link DroolsEndpoint#getDefaultRouteURI()} specified on the endpoint
139         * 
140         * @param content the message body
141         * @throws MessagingException
142         */
143        public void routeToDefault(Source content) throws MessagingException {
144            routeTo(content, endpoint.getDefaultRouteURI());
145        }
146    
147        /**
148         * @see #fault(Source)
149         */
150        public void fault(String content) throws Exception {
151            MessageExchange me = this.exchange.getInternalExchange();
152            if (me instanceof InOnly) {
153                me.setError(new Exception(content));
154                getChannel().send(me);
155            } else {
156                Fault fault = me.createFault();
157                fault.setContent(new StringSource(content));
158                me.setFault(fault);
159                getChannel().send(me);
160            }
161            exchangeHandled = true;
162        }
163    
164        /**
165         * Send a JBI Error message (for InOnly) or JBI Fault message (for the other MEPs)
166         * 
167         * @param content the error content
168         * @throws Exception
169         */
170        public void fault(Source content) throws Exception {
171            MessageExchange me = this.exchange.getInternalExchange();
172            if (me instanceof InOnly) {
173                me.setError(new Exception(new SourceTransformer().toString(content)));
174                getChannel().send(me);
175            } else {
176                Fault fault = me.createFault();
177                fault.setContent(content);
178                me.setFault(fault);
179                getChannel().send(me);
180            }
181            exchangeHandled = true;
182        }
183    
184        /**
185         * @see #answer(Source)
186         */
187        public void answer(String content) throws Exception {
188            answer(new StringSource(content));
189        }
190    
191        /**
192         * Answer the exchange with the given response content
193         * 
194         * @param content the response
195         * @throws Exception
196         */    
197        public void answer(Source content) throws Exception {
198            MessageExchange me = this.exchange.getInternalExchange();
199            NormalizedMessage out = me.createMessage();
200            out.setContent(content);
201            me.setMessage(out, "out");
202            getChannel().send(me);
203            exchangeHandled = true;
204            update();
205        }
206    
207        /**
208         * Update the {@link MessageExchange} information in the rule engine's {@link WorkingMemory}
209         */
210        public void update() {
211            this.memory.update(this.exchangeFactHandle, this.exchange);
212        }
213        
214        /**
215         * Has the MessageExchange been handled by the drools endpoint?
216         * 
217         * @return
218         */
219        public boolean isExchangeHandled() {
220            return exchangeHandled;
221        }
222    
223    }