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 org.apache.camel.CamelContext;
020import org.apache.camel.NoSuchBeanException;
021import org.apache.camel.Processor;
022import org.apache.camel.spi.Registry;
023
024/**
025 * An implementation of a {@link BeanHolder} which will look up a bean from the registry and act as a cache of its metadata
026 *
027 * @version 
028 */
029public class RegistryBean implements BeanHolder {
030    private final CamelContext context;
031    private final String name;
032    private final Registry registry;
033    private volatile BeanInfo beanInfo;
034    private volatile Class<?> clazz;
035    private ParameterMappingStrategy parameterMappingStrategy;
036
037    public RegistryBean(CamelContext context, String name) {
038        this(context.getRegistry(), context, name);
039    }
040
041    public RegistryBean(Registry registry, CamelContext context, String name) {
042        this.registry = registry;
043        this.context = context;
044        if (name != null) {
045            // for ref it may have "ref:" or "bean:" as prefix by mistake
046            if (name.startsWith("ref:")) {
047                this.name = name.substring(4);
048            } else if (name.startsWith("bean:")) {
049                this.name = name.substring(5);
050            } else {
051                this.name = name;
052            }
053        } else {
054            this.name = null;
055        }
056    }
057
058    @Override
059    public String toString() {
060        return "bean: " + name;
061    }
062
063    /**
064     * Creates a cached and constant {@link org.apache.camel.component.bean.BeanHolder} from this holder.
065     *
066     * @return a new {@link org.apache.camel.component.bean.BeanHolder} that has cached the lookup of the bean.
067     */
068    public ConstantBeanHolder createCacheHolder() {
069        Object bean = getBean();
070        BeanInfo info = createBeanInfo(bean);
071        return new ConstantBeanHolder(bean, info);
072    }
073
074    public Object getBean() throws NoSuchBeanException {
075        // must always lookup bean first
076        Object value = lookupBean();
077
078        if (value != null) {
079            // could be a class then create an instance of it
080            if (value instanceof Class) {
081                // bean is a class so create an instance of it
082                value = context.getInjector().newInstance((Class<?>)value);
083            }
084            return value;
085        }
086
087        // okay bean is not in registry, so try to resolve if its a class name and create a shared instance
088        if (clazz == null) {
089            clazz = context.getClassResolver().resolveClass(name);
090        }
091
092        if (clazz == null) {
093            // no its not a class then we cannot find the bean
094            throw new NoSuchBeanException(name);
095        }
096
097        // bean is a class so create an instance of it
098        return context.getInjector().newInstance(clazz);
099    }
100
101    public Processor getProcessor() {
102        return null;
103    }
104
105    public boolean supportProcessor() {
106        return false;
107    }
108
109    public BeanInfo getBeanInfo() {
110        if (beanInfo == null) {
111            Object bean = getBean();
112            this.beanInfo = createBeanInfo(bean);
113        }
114        return beanInfo;
115    }
116
117    public BeanInfo getBeanInfo(Object bean) {
118        return createBeanInfo(bean);
119    }
120
121    public String getName() {
122        return name;
123    }
124
125    public Registry getRegistry() {
126        return registry;
127    }
128
129    public CamelContext getContext() {
130        return context;
131    }
132
133    public ParameterMappingStrategy getParameterMappingStrategy() {
134        if (parameterMappingStrategy == null) {
135            parameterMappingStrategy = createParameterMappingStrategy();
136        }
137        return parameterMappingStrategy;
138    }
139
140    public void setParameterMappingStrategy(ParameterMappingStrategy parameterMappingStrategy) {
141        this.parameterMappingStrategy = parameterMappingStrategy;
142    }
143
144    // Implementation methods
145    //-------------------------------------------------------------------------
146    protected BeanInfo createBeanInfo(Object bean) {
147        return new BeanInfo(context, bean.getClass(), getParameterMappingStrategy());
148    }
149
150    protected ParameterMappingStrategy createParameterMappingStrategy() {
151        return BeanInfo.createParameterMappingStrategy(context);
152    }
153
154    protected Object lookupBean() {
155        return registry.lookupByName(name);
156    }
157}