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.blueprint;
018
019import java.util.Set;
020import javax.xml.bind.annotation.XmlAccessType;
021import javax.xml.bind.annotation.XmlAccessorType;
022import javax.xml.bind.annotation.XmlAttribute;
023import javax.xml.bind.annotation.XmlRootElement;
024import javax.xml.bind.annotation.XmlTransient;
025
026import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
027import org.apache.camel.CamelContext;
028import org.apache.camel.Endpoint;
029import org.apache.camel.FailedToCreateProducerException;
030import org.apache.camel.Producer;
031import org.apache.camel.component.bean.ProxyHelper;
032import org.apache.camel.core.xml.AbstractCamelFactoryBean;
033import org.apache.camel.util.ServiceHelper;
034
035/**
036 * A factory to create a Proxy to a a Camel Pojo Endpoint.
037 */
038@XmlRootElement(name = "proxy")
039@XmlAccessorType(XmlAccessType.FIELD)
040public class CamelProxyFactoryBean extends AbstractCamelFactoryBean<Object> {
041
042    @XmlAttribute
043    private String serviceUrl;
044    @XmlAttribute
045    private String serviceRef;
046    @XmlAttribute
047    private String serviceInterface;
048    @XmlTransient
049    private Endpoint endpoint;
050    @XmlTransient
051    private Object serviceProxy;
052    @XmlTransient
053    private Producer producer;
054    @XmlTransient
055    private ExtendedBlueprintContainer blueprintContainer;
056
057    public Object getObject() {
058        return serviceProxy;
059    }
060
061    public Class<Object> getObjectType() {
062        return Object.class;
063    }
064
065    protected CamelContext getCamelContextWithId(String camelContextId) {
066        if (blueprintContainer != null) {
067            return (CamelContext) blueprintContainer.getComponentInstance(camelContextId);
068        }
069        return null;
070    }
071
072    @Override
073    protected CamelContext discoverDefaultCamelContext() {
074        if (blueprintContainer != null) {
075            Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer);
076            if (ids.size() == 1) {
077                // there is only 1 id for a BlueprintCamelContext so fallback and use this
078                return getCamelContextWithId(ids.iterator().next());
079            }
080        }
081        return null;
082    }
083
084    public void afterPropertiesSet() throws Exception {
085        if (endpoint == null) {
086            getCamelContext();
087            if (getServiceUrl() == null && getServiceRef() == null) {
088                throw new IllegalArgumentException("serviceUrl or serviceRef must be specified.");
089            }
090            if (getServiceInterface() == null) {
091                throw new IllegalArgumentException("serviceInterface must be specified.");
092            }
093
094            // lookup endpoint or we have the url for it
095            if (getServiceRef() != null) {
096                endpoint = getCamelContext().getRegistry().lookupByNameAndType(getServiceRef(), Endpoint.class);
097            } else {
098                endpoint = getCamelContext().getEndpoint(getServiceUrl());
099            }
100
101            if (endpoint == null) {
102                throw new IllegalArgumentException("Could not resolve endpoint: " + getServiceUrl());
103            }
104        }
105
106        try {
107            producer = endpoint.createProducer();
108            ServiceHelper.startService(producer);
109            Class<?> clazz = blueprintContainer.loadClass(getServiceInterface());
110            serviceProxy = ProxyHelper.createProxy(endpoint, producer, clazz);
111        } catch (Exception e) {
112            throw new FailedToCreateProducerException(endpoint, e);
113        }
114    }
115
116    public void destroy() throws Exception {
117        ServiceHelper.stopService(producer);
118    }
119
120    public String getServiceUrl() {
121        return serviceUrl;
122    }
123
124    public void setServiceUrl(String serviceUrl) {
125        this.serviceUrl = serviceUrl;
126    }
127
128    public String getServiceRef() {
129        return serviceRef;
130    }
131
132    public void setServiceRef(String serviceRef) {
133        this.serviceRef = serviceRef;
134    }
135
136    public String getServiceInterface() {
137        return serviceInterface;
138    }
139
140    public void setServiceInterface(String serviceInterface) {
141        this.serviceInterface = serviceInterface;
142    }
143
144    public Endpoint getEndpoint() {
145        return endpoint;
146    }
147
148    public void setEndpoint(Endpoint endpoint) {
149        this.endpoint = endpoint;
150    }
151
152    public Producer getProducer() {
153        return producer;
154    }
155
156    public void setProducer(Producer producer) {
157        this.producer = producer;
158    }
159
160    public ExtendedBlueprintContainer getBlueprintContainer() {
161        return blueprintContainer;
162    }
163
164    public void setBlueprintContainer(ExtendedBlueprintContainer blueprintContainer) {
165        this.blueprintContainer = blueprintContainer;
166    }
167
168}