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