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 (isCache()) {
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            processor.setCache(cache);
107            if (parameters != null) {
108                setProperties(processor, parameters);
109            }
110        }
111    }
112
113    @Override
114    protected void doStop() throws Exception {
115        super.doStop();
116        // noop
117    }
118
119    // Properties
120    //-------------------------------------------------------------------------
121
122    public String getBeanName() {
123        return beanName;
124    }
125
126    /**
127     * Sets the name of the bean to invoke
128     */
129    public void setBeanName(String beanName) {
130        this.beanName = beanName;
131    }
132
133    public boolean isMultiParameterArray() {
134        return multiParameterArray;
135    }
136
137    /**
138     * How to treat the parameters which are passed from the message body;
139     * if it is true, the message body should be an array of parameters.
140     * <p/>
141     * Note: This option is used internally by Camel, and is not intended for end users to use.
142     *
143     * @deprecated this option is used internally by Camel, and is not intended for end users to use
144     */
145    @Deprecated
146    public void setMultiParameterArray(boolean mpArray) {
147        multiParameterArray = mpArray;
148    }
149
150    public boolean isCache() {
151        return cache != null ? cache : false;
152    }
153
154    public Boolean getCache() {
155        return cache;
156    }
157
158    /**
159     * If enabled, Camel will cache the result of the first Registry look-up.
160     * Cache can be enabled if the bean in the Registry is defined as a singleton scope.
161     */
162    public void setCache(Boolean cache) {
163        this.cache = cache;
164    }
165
166    public String getMethod() {
167        return method;
168    }
169
170    /**
171     * Sets the name of the method to invoke on the bean
172     */
173    public void setMethod(String method) {
174        this.method = method;
175    }
176
177    public BeanHolder getBeanHolder() {
178        return beanHolder;
179    }
180
181    public void setBeanHolder(BeanHolder beanHolder) {
182        this.beanHolder = beanHolder;
183    }
184
185    public Map<String, Object> getParameters() {
186        return parameters;
187    }
188
189    /**
190     * Used for configuring additional properties on the bean
191     */
192    public void setParameters(Map<String, Object> parameters) {
193        this.parameters = parameters;
194    }
195
196    // Implementation methods
197    //-------------------------------------------------------------------------
198
199    @Override
200    protected String createEndpointUri() {
201        return "bean:" + getBeanName() + (method != null ? "?method=" + method : "");
202    }
203}