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.camel;
018    
019    import java.net.URISyntaxException;
020    import java.util.Map;
021    
022    import org.apache.camel.AsyncCallback;
023    import org.apache.camel.AsyncProcessor;
024    import org.apache.camel.Consumer;
025    import org.apache.camel.Endpoint;
026    import org.apache.camel.Exchange;
027    import org.apache.camel.Processor;
028    import org.apache.camel.Producer;
029    import org.apache.camel.impl.DefaultConsumer;
030    import org.apache.camel.impl.DefaultEndpoint;
031    import org.apache.camel.impl.DefaultProducer;
032    import org.apache.camel.spi.HeaderFilterStrategy;
033    import org.apache.camel.spi.Registry;
034    import org.apache.camel.util.URISupport;
035    import org.apache.commons.logging.Log;
036    import org.apache.commons.logging.LogFactory;
037    import org.springframework.util.StringUtils;
038    
039    /**
040     * Represents an {@link org.apache.camel.Endpoint} for interacting with JBI
041     *
042     * @version $Revision: 563665 $
043     */
044    public class JbiEndpoint extends DefaultEndpoint<Exchange> {
045    
046        private static final String STRICT_SERIALIZATION = "strict";
047    
048        private String destinationUri;
049    
050        private String mep;
051    
052        private String operation;
053    
054        private JbiProducer producer;
055    
056        private boolean convertExceptions;
057    
058        private boolean strictSerialization;
059    
060        private HeaderFilterStrategy headerFilterStrategy;
061    
062        private final JbiComponent jbiComponent;
063    
064        private final JbiBinding binding;
065    
066        public JbiEndpoint(JbiComponent jbiComponent, String uri) {
067            super(uri, jbiComponent);
068            this.jbiComponent = jbiComponent;
069            parseUri(uri);
070    
071            //now create the binding based on the information read from the URI
072            this.binding = createBinding();
073        }
074    
075        public final JbiBinding createBinding() {
076            JbiBinding result = new JbiBinding(this.getCamelContext(), strictSerialization);
077            result.setConvertExceptions(convertExceptions);
078            result.addHeaderFilterStrategy(headerFilterStrategy);
079            return result;
080        }
081    
082    
083        public synchronized Producer<Exchange> createProducer() throws Exception {
084            if (producer == null) {
085                producer = new JbiProducer(this);
086            }
087            return producer;
088        }
089    
090        protected class JbiProducer extends DefaultProducer<Exchange> implements AsyncProcessor {
091            
092            private final Log log = LogFactory.getLog(JbiProducer.class);
093    
094            private CamelConsumerEndpoint consumer;
095    
096            public JbiProducer(Endpoint<Exchange> exchangeEndpoint) {
097                super(exchangeEndpoint);
098            }
099    
100            @Override
101            public void start() throws Exception {
102                consumer = new CamelConsumerEndpoint(binding, JbiEndpoint.this);
103                jbiComponent.getCamelJbiComponent().addEndpoint(consumer);
104                super.start();
105            }
106            
107            @Override
108            public void stop() throws Exception {
109                if (isStopped()) {
110                    log.debug("Camel producer for " + super.getEndpoint() + " has already been stopped");
111                } else {
112                    log.debug("Stopping Camel producer for " + super.getEndpoint());
113                    jbiComponent.getCamelJbiComponent().removeEndpoint(consumer);
114                    super.stop();
115                }
116            }
117    
118            public void process(Exchange exchange) throws Exception {
119                consumer.process(exchange);
120            }
121    
122            public boolean process(Exchange exchange, AsyncCallback asyncCallback) {
123                return consumer.process(exchange, asyncCallback);
124            }
125            
126            /*
127             * Access the underlying JBI Consumer endpoint
128             */
129            protected CamelConsumerEndpoint getCamelConsumerEndpoint() {
130                return consumer;
131            }
132        }
133    
134        @SuppressWarnings("unchecked")
135        private void parseUri(String uri) {
136            destinationUri = uri;
137            try {
138                int idx = destinationUri.indexOf('?');
139                if (idx > 0) {
140                    Map params = URISupport.parseQuery(destinationUri.substring(idx + 1));
141                    mep = (String) params.get("mep");
142                    if (mep != null && !mep.startsWith("http://www.w3.org/ns/wsdl/")) {
143                        mep = "http://www.w3.org/ns/wsdl/" + mep;
144                    }
145                    String oper = (String) params.get("operation");
146                    if (StringUtils.hasLength(oper)) {
147                        operation = oper;
148                    }
149                    this.destinationUri = destinationUri.substring(0, idx);
150    
151                    String filter = (String) params.get("headerFilterStrategy");
152                    if (StringUtils.hasLength(filter)) {
153                        Registry registry = jbiComponent.getCamelContext().getRegistry();
154                        if (filter.indexOf('#') != -1) {
155                            filter = filter.substring(1);
156                        }
157                        Object object = registry.lookup(filter);
158                        if (object instanceof HeaderFilterStrategy) {
159                            headerFilterStrategy = (HeaderFilterStrategy) object;
160                        }
161                        params.remove("headerFilterStrategy");
162                    }
163                    String convert = (String) params.get("convertExceptions");
164                    if (StringUtils.hasLength(convert)) {
165                        convertExceptions = Boolean.valueOf(convert);
166                        params.remove("convertExceptions");
167                    }
168                    String serialization = (String) params.get("serialization");
169                    if (StringUtils.hasLength(serialization)) {
170                        strictSerialization = STRICT_SERIALIZATION.equalsIgnoreCase(serialization);
171                        params.remove("serialization");
172                    }
173                    String endpointUri = this.destinationUri + URISupport.createQueryString(params);
174                    this.setEndpointUri(endpointUri);
175                }
176            } catch (URISyntaxException e) {
177                throw new JbiException(e);
178            }
179        }
180    
181        public void setMep(String str) {
182            mep = str;
183        }
184    
185        public void setOperation(String str) {
186            operation = str;
187        }
188    
189        public void setDestionationUri(String str) {
190            destinationUri = str;
191        }
192    
193        public String getMep() {
194            return mep;
195        }
196    
197        public String getOperation() {
198            return operation;
199        }
200    
201        public String getDestinationUri() {
202            return destinationUri;
203        }
204    
205        public Consumer<Exchange> createConsumer(final Processor processor) throws Exception {
206            return new DefaultConsumer<Exchange>(this, processor) {
207                CamelProviderEndpoint jbiEndpoint;
208    
209                @Override
210                protected void doStart() throws Exception {
211                    super.doStart();
212                    jbiEndpoint = jbiComponent.createJbiEndpointFromCamel(JbiEndpoint.this, processor);
213                    jbiComponent.getCamelJbiComponent().activateJbiEndpoint(jbiEndpoint);
214                }
215    
216                @Override
217                protected void doStop() throws Exception {
218                    if (jbiEndpoint != null) {
219                        jbiComponent.getCamelJbiComponent().deactivateJbiEndpoint(jbiEndpoint);
220                    }
221                    super.doStop();
222                }
223            };
224        }
225    
226        public boolean isSingleton() {
227            return true;
228        }
229             
230        public HeaderFilterStrategy getHeaderFilterStrategy() {
231            return headerFilterStrategy;
232        }
233    
234        public void setHeaderFilterStrategy(HeaderFilterStrategy strategy) {
235            this.headerFilterStrategy = strategy;
236        }
237    
238        public void setConvertExceptions(boolean convertExceptions) {
239            this.convertExceptions = convertExceptions;
240        }
241    
242        public boolean isConvertExceptions() {
243            return convertExceptions;
244        }
245    
246        public void setStrictSerialization(boolean strictSerialization) {
247            this.strictSerialization = strictSerialization;
248        }
249    
250        public boolean isStrictSerialization() {
251            return strictSerialization;
252        }
253    }