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    
023    import org.apache.camel.CamelContext;
024    import org.apache.camel.CamelContextAware;
025    import org.apache.camel.Component;
026    import org.apache.camel.Endpoint;
027    import org.apache.camel.Exchange;
028    import org.apache.camel.ExchangePattern;
029    import org.apache.camel.PollingConsumer;
030    import org.apache.camel.util.ObjectHelper;
031    
032    /**
033     * A default endpoint useful for implementation inheritance
034     *
035     * @version $Revision: 18369 $
036     */
037    public abstract class DefaultEndpoint implements Endpoint, CamelContextAware {
038        private String endpointUri;
039        private CamelContext camelContext;
040        private Component component;
041        private ExchangePattern exchangePattern = ExchangePattern.InOnly;
042    
043        protected DefaultEndpoint(String endpointUri, Component component) {
044            this(endpointUri, component.getCamelContext());
045            this.component = component;
046        }
047    
048        protected DefaultEndpoint(String endpointUri, CamelContext camelContext) {
049            this(endpointUri);
050            this.camelContext = camelContext;
051        }
052    
053        protected DefaultEndpoint(String endpointUri) {
054            this.setEndpointUri(endpointUri);
055        }
056    
057        protected DefaultEndpoint() {
058            super();
059        }
060    
061        public int hashCode() {
062            return getEndpointUri().hashCode() * 37 + 1;
063        }
064    
065        @Override
066        public boolean equals(Object object) {
067            if (object instanceof DefaultEndpoint) {
068                DefaultEndpoint that = (DefaultEndpoint) object;
069                return ObjectHelper.equal(this.getEndpointUri(), that.getEndpointUri());
070            }
071            return false;
072        }
073    
074        @Override
075        public String toString() {
076            return "Endpoint[" + getEndpointUri() + "]";
077        }
078    
079        public String getEndpointUri() {
080            if (endpointUri == null) {
081                endpointUri = createEndpointUri();
082                if (endpointUri == null) {
083                    throw new IllegalArgumentException("endpointUri is not specified and " + getClass().getName()
084                            + " does not implement createEndpointUri() to create a default value");
085                }
086            }
087            return endpointUri;
088        }
089    
090        public String getEndpointKey() {
091            if (isLenientProperties()) {
092                // only use the endpoint uri without parameters as the properties is lenient
093                String uri = getEndpointUri();
094                if (uri.indexOf('?') != -1) {
095                    return ObjectHelper.before(uri, "?");
096                } else {
097                    return uri;
098                }
099            } else {
100                // use the full endpoint uri
101                return getEndpointUri();
102            }
103        }
104    
105        public CamelContext getCamelContext() {
106            return camelContext;
107        }
108    
109        public Component getComponent() {
110            return component;
111        }
112    
113        public void setCamelContext(CamelContext camelContext) {
114            this.camelContext = camelContext;
115        }
116    
117        public PollingConsumer createPollingConsumer() throws Exception {
118            return new EventDrivenPollingConsumer(this);
119        }
120    
121        public Exchange createExchange(Exchange exchange) {
122            Class<Exchange> exchangeType = getExchangeType();
123            if (exchangeType != null) {
124                if (exchangeType.isInstance(exchange)) {
125                    return exchangeType.cast(exchange);
126                }
127            }
128            return exchange.copy();
129        }
130    
131        /**
132         * Returns the type of the exchange which is generated by this component
133         */
134        @SuppressWarnings("unchecked")
135        public Class<Exchange> getExchangeType() {
136            Type type = getClass().getGenericSuperclass();
137            if (type instanceof ParameterizedType) {
138                ParameterizedType parameterizedType = (ParameterizedType) type;
139                Type[] arguments = parameterizedType.getActualTypeArguments();
140                if (arguments.length > 0) {
141                    Type argumentType = arguments[0];
142                    if (argumentType instanceof Class) {
143                        return (Class<Exchange>) argumentType;
144                    }
145                }
146            }
147            return null;
148        }
149    
150        public Exchange createExchange() {
151            return createExchange(getExchangePattern());
152        }
153    
154        public Exchange createExchange(ExchangePattern pattern) {
155            return new DefaultExchange(this, pattern);
156        }
157    
158        public ExchangePattern getExchangePattern() {
159            return exchangePattern;
160        }
161    
162        public void setExchangePattern(ExchangePattern exchangePattern) {
163            this.exchangePattern = exchangePattern;
164        }
165    
166        public void configureProperties(Map<String, Object> options) {
167            // do nothing by default
168        }
169    
170        /**
171         * A factory method to lazily create the endpointUri if none is specified 
172         */
173        protected String createEndpointUri() {
174            return null;
175        }
176    
177        /**
178         * Sets the endpointUri if it has not been specified yet via some kind of dependency injection mechanism.
179         * This allows dependency injection frameworks such as Spring or Guice to set the default endpoint URI in cases
180         * where it has not been explicitly configured using the name/context in which an Endpoint is created.
181         */
182        public void setEndpointUriIfNotSpecified(String value) {
183            if (endpointUri == null) {
184                setEndpointUri(value);
185            }
186        }
187        protected void setEndpointUri(String endpointUri) {
188            this.endpointUri = endpointUri;
189        }
190    
191        public boolean isLenientProperties() {
192            // default should be false for most components
193            return false;
194        }
195    
196    }