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 */
017package org.apache.camel.component.bean;
018
019import java.util.Map;
020
021import org.apache.camel.Component;
022import org.apache.camel.Consumer;
023import org.apache.camel.ExchangePattern;
024import org.apache.camel.Processor;
025import org.apache.camel.Producer;
026import org.apache.camel.impl.DefaultEndpoint;
027import org.apache.camel.spi.Metadata;
028import org.apache.camel.spi.UriEndpoint;
029import org.apache.camel.spi.UriParam;
030import org.apache.camel.spi.UriPath;
031
032/**
033 * The <a href="http://camel.apache.org/bean.html">bean component</a> is for invoking Java beans from Camel.
034 */
035@UriEndpoint(firstVersion = "1.0.0", scheme = "bean", title = "Bean", syntax = "bean:beanName", producerOnly = true, label = "core,java")
036public class BeanEndpoint extends DefaultEndpoint {
037    private transient BeanHolder beanHolder;
038    private transient BeanProcessor processor;
039    @UriPath(description = "Sets the name of the bean to invoke") @Metadata(required = "true")
040    private String beanName;
041    @UriParam(description = "Sets the name of the method to invoke on the bean")
042    private String method;
043    @UriParam(label = "advanced", description = "If enabled, Camel will cache the result of the first Registry look-up."
044            + " Cache can be enabled if the bean in the Registry is defined as a singleton scope.")
045    private boolean cache;
046    @UriParam(label = "advanced", description = "How to treat the parameters which are passed from the message body."
047            + "true means the message body should be an array of parameters.")
048    @Deprecated @Metadata(deprecationNode = "This option is used internally by Camel, and is not intended for end users to use.")
049    private boolean multiParameterArray;
050    @UriParam(prefix = "bean.", label = "advanced", description = "Used for configuring additional properties on the bean", multiValue = true)
051    private Map<String, Object> parameters;
052
053    public BeanEndpoint() {
054        setExchangePattern(ExchangePattern.InOut);
055    }
056
057    public BeanEndpoint(String endpointUri, Component component, BeanProcessor processor) {
058        super(endpointUri, component);
059        this.processor = processor;
060        setExchangePattern(ExchangePattern.InOut);
061    }
062
063    public BeanEndpoint(String endpointUri, Component component) {
064        super(endpointUri, component);
065        setExchangePattern(ExchangePattern.InOut);
066    }
067
068    @Override
069    public Producer createProducer() throws Exception {
070        return new BeanProducer(this, processor);
071    }
072
073    @Override
074    public Consumer createConsumer(Processor processor) throws Exception {
075        throw new UnsupportedOperationException("You cannot consume from a bean endpoint");
076    }
077
078    @Override
079    public boolean isSingleton() {
080        return true;
081    }
082
083    public BeanProcessor getProcessor() {
084        return processor;
085    }
086
087    @Override
088    protected void doStart() throws Exception {
089        super.doStart();
090
091        if (processor == null) {
092            BeanHolder holder = getBeanHolder();
093            if (holder == null) {
094                RegistryBean registryBean = new RegistryBean(getCamelContext(), beanName);
095                if (cache) {
096                    holder = registryBean.createCacheHolder();
097                } else {
098                    holder = registryBean;
099                }
100            }
101            processor = new BeanProcessor(holder);
102            if (method != null) {
103                processor.setMethod(method);
104            }
105            processor.setMultiParameterArray(isMultiParameterArray());
106            if (parameters != null) {
107                setProperties(processor, parameters);
108            }
109        }
110    }
111
112    @Override
113    protected void doStop() throws Exception {
114        super.doStop();
115        // noop
116    }
117
118    // Properties
119    //-------------------------------------------------------------------------
120
121    public String getBeanName() {
122        return beanName;
123    }
124
125    /**
126     * Sets the name of the bean to invoke
127     */
128    public void setBeanName(String beanName) {
129        this.beanName = beanName;
130    }
131
132    public boolean isMultiParameterArray() {
133        return multiParameterArray;
134    }
135
136    /**
137     * How to treat the parameters which are passed from the message body;
138     * if it is true, the message body should be an array of parameters.
139     * <p/>
140     * Note: This option is used internally by Camel, and is not intended for end users to use.
141     *
142     * @deprecated this option is used internally by Camel, and is not intended for end users to use
143     */
144    @Deprecated
145    public void setMultiParameterArray(boolean mpArray) {
146        multiParameterArray = mpArray;
147    }
148
149    public boolean isCache() {
150        return cache;
151    }
152
153    /**
154     * If enabled, Camel will cache the result of the first Registry look-up.
155     * Cache can be enabled if the bean in the Registry is defined as a singleton scope.
156     */
157    public void setCache(boolean cache) {
158        this.cache = cache;
159    }
160
161    public String getMethod() {
162        return method;
163    }
164
165    /**
166     * Sets the name of the method to invoke on the bean
167     */
168    public void setMethod(String method) {
169        this.method = method;
170    }
171
172    public BeanHolder getBeanHolder() {
173        return beanHolder;
174    }
175
176    public void setBeanHolder(BeanHolder beanHolder) {
177        this.beanHolder = beanHolder;
178    }
179
180    public Map<String, Object> getParameters() {
181        return parameters;
182    }
183
184    /**
185     * Used for configuring additional properties on the bean
186     */
187    public void setParameters(Map<String, Object> parameters) {
188        this.parameters = parameters;
189    }
190
191    // Implementation methods
192    //-------------------------------------------------------------------------
193
194    @Override
195    protected String createEndpointUri() {
196        return "bean:" + getBeanName() + (method != null ? "?method=" + method : "");
197    }
198}