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.camel.impl;
018    
019    import java.lang.reflect.ParameterizedType;
020    import java.lang.reflect.Type;
021    import java.util.Map;
022    import java.util.concurrent.ScheduledExecutorService;
023    import java.util.concurrent.ScheduledThreadPoolExecutor;
024    
025    import org.apache.camel.CamelContext;
026    import org.apache.camel.CamelContextAware;
027    import org.apache.camel.Component;
028    import org.apache.camel.Endpoint;
029    import org.apache.camel.Exchange;
030    import org.apache.camel.ExchangePattern;
031    import org.apache.camel.PollingConsumer;
032    import org.apache.camel.util.ObjectHelper;
033    
034    /**
035     * A default endpoint useful for implementation inheritance
036     *
037     * @version $Revision: 71985 $
038     */
039    public abstract class DefaultEndpoint<E extends Exchange> implements Endpoint<E>, CamelContextAware {
040        private String endpointUri;
041        private CamelContext camelContext;
042        private Component component;
043        private ScheduledExecutorService executorService;
044        private ExchangePattern exchangePattern = ExchangePattern.InOnly;
045    
046        protected DefaultEndpoint(String endpointUri, Component component) {
047            this(endpointUri, component.getCamelContext());
048            this.component = component;
049        }
050    
051        protected DefaultEndpoint(String endpointUri, CamelContext camelContext) {
052            this(endpointUri);
053            this.camelContext = camelContext;
054        }
055    
056        protected DefaultEndpoint(String endpointUri) {
057            this.setEndpointUri(endpointUri);
058        }
059    
060        protected DefaultEndpoint() {
061        }
062    
063        public int hashCode() {
064            return getEndpointUri().hashCode() * 37 + 1;
065        }
066    
067        @Override
068        public boolean equals(Object object) {
069            if (object instanceof DefaultEndpoint) {
070                DefaultEndpoint that = (DefaultEndpoint) object;
071                return ObjectHelper.equal(this.getEndpointUri(), that.getEndpointUri());
072            }
073            return false;
074        }
075    
076        @Override
077        public String toString() {
078            return "Endpoint[" + getEndpointUri() + "]";
079        }
080    
081        public String getEndpointUri() {        
082            if (endpointUri == null) {
083                endpointUri = createEndpointUri();
084                if (endpointUri == null) {
085                    throw new IllegalArgumentException("endpointUri is not specified and " + getClass().getName()
086                            + " does not implement createEndpointUri() to create a default value");
087                }
088            }
089            return endpointUri;
090        }
091    
092        public CamelContext getCamelContext() {
093            return camelContext;
094        }
095    
096        public Component getComponent() {
097            return component;
098        }
099    
100        public void setCamelContext(CamelContext camelContext) {
101            this.camelContext = camelContext;
102        }
103    
104        public synchronized ScheduledExecutorService getExecutorService() {
105            if (executorService == null) {
106                Component c = getComponent();
107                if (c != null && c instanceof DefaultComponent) {
108                    DefaultComponent dc = (DefaultComponent) c;
109                    executorService = dc.getExecutorService();
110                }
111                if (executorService == null) {
112                    executorService = createExecutorService();
113                }
114            }
115            return executorService;
116        }
117    
118        public synchronized void setExecutorService(ScheduledExecutorService executorService) {
119            this.executorService = executorService;
120        }
121    
122        public PollingConsumer<E> createPollingConsumer() throws Exception {
123            return new EventDrivenPollingConsumer<E>(this);
124        }
125    
126        /**
127         * Converts the given exchange to the specified exchange type
128         */
129        public E convertTo(Class<E> type, Exchange exchange) {
130            // TODO we could infer type parameter
131            if (type.isInstance(exchange)) {
132                return type.cast(exchange);
133            }
134            return getCamelContext().getExchangeConverter().convertTo(type, exchange);
135        }
136    
137        public E createExchange(Exchange exchange) {
138            Class<E> exchangeType = getExchangeType();
139            if (exchangeType != null) {
140                if (exchangeType.isInstance(exchange)) {
141                    return exchangeType.cast(exchange);
142                }
143            }
144            E answer = createExchange();
145            answer.copyFrom(exchange);
146            return answer;
147        }
148    
149        /**
150         * Returns the type of the exchange which is generated by this component
151         */
152        public Class<E> getExchangeType() {
153            Type type = getClass().getGenericSuperclass();
154            if (type instanceof ParameterizedType) {
155                ParameterizedType parameterizedType = (ParameterizedType) type;
156                Type[] arguments = parameterizedType.getActualTypeArguments();
157                if (arguments.length > 0) {
158                    Type argumentType = arguments[0];
159                    if (argumentType instanceof Class) {
160                        return (Class<E>) argumentType;
161                    }
162                }
163            }
164            return null;
165        }
166    
167        public E createExchange() {
168            return createExchange(getExchangePattern());
169        }
170    
171        public E createExchange(ExchangePattern pattern) {
172            return (E) new DefaultExchange(getCamelContext(), pattern);
173        }
174    
175        public ExchangePattern getExchangePattern() {
176            return exchangePattern;
177        }
178    
179        public void setExchangePattern(ExchangePattern exchangePattern) {
180            this.exchangePattern = exchangePattern;
181        }
182    
183        protected ScheduledThreadPoolExecutor createExecutorService() {
184            return new ScheduledThreadPoolExecutor(10);
185        }
186    
187        public void configureProperties(Map options) {
188        }
189    
190        /**
191         * A factory method to lazily create the endpointUri if none is specified 
192         */
193        protected String createEndpointUri() {
194            return null;
195        }
196    
197        protected void setEndpointUri(String endpointUri) {
198            this.endpointUri = endpointUri;
199        }
200        
201        /**
202         * Sets the endpointUri if it has not been specified yet via some kind of dependency injection mechanism.
203         * This allows dependency injection frameworks such as Spring or Guice to set the default endpoint URI in cases
204         * where it has not been explicitly configured using the name/context in which an Endpoint is created.
205         */
206        public void setEndpointUriIfNotSpecified(String value) {
207            if (endpointUri == null) {
208                setEndpointUri(value);
209            }
210        }
211        
212        @Deprecated
213        public CamelContext getContext() {
214            return getCamelContext();
215        }
216        
217        @Deprecated
218        public void setContext(CamelContext context) {
219            setCamelContext(context);
220        }
221    
222        public boolean isLenientProperties() {
223            // default should be false for most components
224            return false;
225        }
226    
227    }