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: 641159 $ 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 }