001    /**
002     *
003     * Licensed to the Apache Software Foundation (ASF) under one or more
004     * contributor license agreements.  See the NOTICE file distributed with
005     * this work for additional information regarding copyright ownership.
006     * The ASF licenses this file to You under the Apache License, Version 2.0
007     * (the "License"); you may not use this file except in compliance with
008     * the License.  You may obtain a copy of the License at
009     *
010     * http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    package org.apache.camel.jms;
019    
020    import com.sun.jndi.toolkit.url.Uri;
021    import org.apache.camel.CamelContext;
022    import org.apache.camel.Component;
023    import org.apache.camel.Processor;
024    import org.apache.camel.util.ObjectHelper;
025    import org.springframework.jms.core.JmsTemplate;
026    import org.springframework.jms.listener.AbstractMessageListenerContainer;
027    import org.springframework.jms.listener.DefaultMessageListenerContainer;
028    
029    import javax.jms.ConnectionFactory;
030    import javax.jms.Session;
031    
032    /**
033     * @version $Revision: 520539 $
034     */
035    public class JmsComponent implements Component<JmsExchange> {
036        public static final String QUEUE_PREFIX = "queue/";
037        public static final String TOPIC_PREFIX = "topic/";
038    
039        private CamelContext container;
040        private JmsTemplate template;
041    
042        /**
043         * Static builder method
044         */
045        public static JmsComponent jmsComponent() {
046            return new JmsComponent();
047        }
048    
049        /**
050         * Static builder method
051         */
052        public static JmsComponent jmsComponent(JmsTemplate template) {
053            return new JmsComponent(template);
054        }
055    
056        /**
057         * Static builder method
058         */
059        public static JmsComponent jmsComponent(ConnectionFactory connectionFactory) {
060            return jmsComponent(new JmsTemplate(connectionFactory));
061        }
062    
063        /**
064         * Static builder method
065         */
066        public static JmsComponent jmsComponentClientAcknowledge(ConnectionFactory connectionFactory) {
067            JmsTemplate template = new JmsTemplate(connectionFactory);
068            template.setSessionTransacted(false);
069            template.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
070            return jmsComponent(template);
071        }
072    
073    
074        protected JmsComponent() {
075            this.template = new JmsTemplate();
076        }
077    
078        protected JmsComponent(JmsTemplate template) {
079            this.template = template;
080        }
081    
082        public JmsComponent(CamelContext container) {
083            this();
084            this.container = container;
085        }
086    
087        public JmsEndpoint createEndpoint(Uri uri) {
088            // lets figure out from the URI whether its a queue, topic etc
089    
090            String path = uri.getPath();
091            return createEndpoint(uri.toString(), path);
092        }
093    
094        public JmsEndpoint createEndpoint(String uri, String path) {
095            ObjectHelper.notNull(container, "container");
096    
097            if (path.startsWith(QUEUE_PREFIX)) {
098                template.setPubSubDomain(false);
099                path = path.substring(QUEUE_PREFIX.length());
100            }
101            else if (path.startsWith(TOPIC_PREFIX)) {
102                template.setPubSubDomain(false);
103                path = path.substring(TOPIC_PREFIX.length());
104            }
105    
106            final String subject = convertPathToActualDestination(path);
107            template.setDefaultDestinationName(subject);
108    
109            /*
110            Destination destination = (Destination) template.execute(new SessionCallback() {
111                public Object doInJms(Session session) throws JMSException {
112                    return template.getDestinationResolver().resolveDestinationName(session, subject, template.isPubSubDomain());
113                }
114            });
115            */
116    
117            AbstractMessageListenerContainer listenerContainer = createMessageListenerContainer(template);
118            listenerContainer.setDestinationName(subject);
119            listenerContainer.setPubSubDomain(template.isPubSubDomain());
120            listenerContainer.setConnectionFactory(template.getConnectionFactory());
121    
122            // TODO support optional parameters
123            // selector
124            // messageConverter
125            // durableSubscriberName 
126    
127            return new JmsEndpoint(uri, container, subject, template, listenerContainer);
128        }
129    
130        public JmsTemplate getTemplate() {
131            return template;
132        }
133    
134        public void setTemplate(JmsTemplate template) {
135            this.template = template;
136        }
137    
138    
139        public CamelContext getContainer() {
140            return container;
141        }
142    
143        public void setContext(CamelContext container) {
144            this.container = container;
145        }
146    
147        protected AbstractMessageListenerContainer createMessageListenerContainer(JmsTemplate template) {
148            // TODO use an enum to auto-switch container types?
149    
150            //return new SimpleMessageListenerContainer();
151            return new DefaultMessageListenerContainer();
152        }
153    
154        /**
155         * A strategy method allowing the URI destination to be translated into the actual JMS destination name
156         * (say by looking up in JNDI or something)
157         */
158        protected String convertPathToActualDestination(String path) {
159            return path;
160        }
161    
162        public void activate(JmsEndpoint endpoint, Processor<JmsExchange> processor) {
163            // TODO Auto-generated method stub
164        }
165    
166        public void deactivate(JmsEndpoint endpoint) {
167            // TODO Auto-generated method stub
168        }
169    }