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.net.URI;
020 import java.util.Map;
021 import java.util.concurrent.ScheduledExecutorService;
022 import java.util.concurrent.ScheduledThreadPoolExecutor;
023 import java.util.concurrent.ThreadFactory;
024
025 import org.apache.camel.CamelContext;
026 import org.apache.camel.Component;
027 import org.apache.camel.Endpoint;
028 import org.apache.camel.Exchange;
029 import org.apache.camel.spi.Injector;
030 import org.apache.camel.spi.Registry;
031 import org.apache.camel.util.CamelContextHelper;
032 import org.apache.camel.util.IntrospectionSupport;
033 import org.apache.camel.util.ObjectHelper;
034 import org.apache.camel.util.URISupport;
035 import org.apache.camel.util.UnsafeUriCharactersEncoder;
036
037
038
039 /**
040 * @version $Revision: 36507 $
041 */
042 public abstract class DefaultComponent<E extends Exchange> extends ServiceSupport implements Component<E> {
043
044 private int defaultThreadPoolSize = 5;
045 private CamelContext camelContext;
046 private ScheduledExecutorService executorService;
047
048 public DefaultComponent() {
049 }
050
051 public DefaultComponent(CamelContext context) {
052 this.camelContext = context;
053 }
054
055 public Endpoint<E> createEndpoint(String uri) throws Exception {
056 ObjectHelper.notNull(getCamelContext(), "camelContext");
057 //endcode uri string to the unsafe URI characters
058 URI u = new URI(UnsafeUriCharactersEncoder.encode(uri));
059 String path = u.getSchemeSpecificPart();
060
061 // lets trim off any query arguments
062 if (path.startsWith("//")) {
063 path = path.substring(2);
064 }
065 int idx = path.indexOf('?');
066 if (idx > 0) {
067 path = path.substring(0, idx);
068 }
069 Map parameters = URISupport.parseParamters(u);
070
071 Endpoint<E> endpoint = createEndpoint(uri, path, parameters);
072 if (endpoint == null) {
073 return null;
074 }
075 if (parameters != null) {
076 endpoint.configureProperties(parameters);
077 if (useIntrospectionOnEndpoint()) {
078 setProperties(endpoint, parameters);
079 }
080 }
081 return endpoint;
082 }
083
084 public CamelContext getCamelContext() {
085 return camelContext;
086 }
087
088 public void setCamelContext(CamelContext context) {
089 this.camelContext = context;
090 }
091
092 public ScheduledExecutorService getExecutorService() {
093 if (executorService == null) {
094 executorService = createExecutorService();
095 }
096 return executorService;
097 }
098
099 public void setExecutorService(ScheduledExecutorService executorService) {
100 this.executorService = executorService;
101 }
102
103 /**
104 * A factory method to create a default thread pool and executor
105 */
106 protected ScheduledExecutorService createExecutorService() {
107 return new ScheduledThreadPoolExecutor(defaultThreadPoolSize, new ThreadFactory() {
108 int counter;
109
110 public synchronized Thread newThread(Runnable runnable) {
111 Thread thread = new Thread(runnable);
112 thread.setName("Thread: " + (++counter) + " " + DefaultComponent.this.toString());
113 return thread;
114 }
115 });
116 }
117
118 protected void doStart() throws Exception {
119 }
120
121 protected void doStop() throws Exception {
122 if (executorService != null) {
123 executorService.shutdown();
124 }
125 }
126
127 /**
128 * A factory method allowing derived components to create a new endpoint
129 * from the given URI, remaining path and optional parameters
130 *
131 * @param uri the full URI of the endpoint
132 * @param remaining the remaining part of the URI without the query
133 * parameters or component prefix
134 * @param parameters the optional parameters passed in
135 * @return a newly created endpoint or null if the endpoint cannot be
136 * created based on the inputs
137 */
138 protected abstract Endpoint<E> createEndpoint(String uri, String remaining, Map parameters)
139 throws Exception;
140
141 /**
142 * Sets the bean properties on the given bean
143 */
144 protected void setProperties(Object bean, Map parameters) throws Exception {
145 IntrospectionSupport.setProperties(getCamelContext().getTypeConverter(), bean, parameters);
146 }
147
148 /**
149 * Derived classes may wish to overload this to prevent the default introspection of URI parameters
150 * on the created Endpoint instance
151 */
152 protected boolean useIntrospectionOnEndpoint() {
153 return true;
154 }
155
156
157 // Some helper methods
158 //-------------------------------------------------------------------------
159
160 /**
161 * Converts the given value to the requested type
162 */
163 public <T> T convertTo(Class<T> type, Object value) {
164 return CamelContextHelper.convertTo(getCamelContext(), type, value);
165 }
166
167 /**
168 * Converts the given value to the specified type throwing an {@link IllegalArgumentException}
169 * if the value could not be converted to a non null value
170 */
171 public <T> T mandatoryConvertTo(Class<T> type, Object value) {
172 return CamelContextHelper.mandatoryConvertTo(getCamelContext(), type, value);
173 }
174
175 /**
176 * Creates a new instance of the given type using the {@link Injector} on the given
177 * {@link CamelContext}
178 */
179 public <T> T newInstance(Class<T> beanType) {
180 return getCamelContext().getInjector().newInstance(beanType);
181 }
182
183 /**
184 * Look up the given named bean in the {@link Registry} on the
185 * {@link CamelContext}
186 */
187 public Object lookup(String name) {
188 return getCamelContext().getRegistry().lookup(name);
189 }
190
191 /**
192 * Look up the given named bean of the given type in the {@link Registry} on the
193 * {@link CamelContext}
194 */
195 public <T> T lookup(String name, Class<T> beanType) {
196 return getCamelContext().getRegistry().lookup(name, beanType);
197 }
198
199 /**
200 * Look up the given named bean in the {@link Registry} on the
201 * {@link CamelContext} or throws
202 */
203 public Object mandatoryLookup(String name) {
204 return CamelContextHelper.mandatoryLookup(getCamelContext(), name);
205 }
206
207 /**
208 * Look up the given named bean of the given type in the {@link Registry} on the
209 * {@link CamelContext}
210 */
211 public <T> T mandatoryLookup(String name, Class<T> beanType) {
212 return CamelContextHelper.mandatoryLookup(getCamelContext(), name, beanType);
213 }
214
215
216 }