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 }