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.model.loadbalancer;
018    
019    
020    
021    import java.util.List;
022    
023    import javax.xml.bind.annotation.XmlAccessType;
024    import javax.xml.bind.annotation.XmlAccessorType;
025    import javax.xml.bind.annotation.XmlTransient;
026    import javax.xml.bind.annotation.XmlType;
027    
028    import org.apache.camel.Exchange;
029    import org.apache.camel.Processor;
030    import org.apache.camel.impl.RouteContext;
031    import org.apache.camel.model.IdentifiedType;
032    import org.apache.camel.processor.loadbalancer.LoadBalancer;
033    import org.apache.camel.util.IntrospectionSupport;
034    import org.apache.camel.util.ObjectHelper;
035    import static org.apache.camel.util.ObjectHelper.notNull;
036    
037    @XmlType(name = "loadBalancerType")
038    @XmlAccessorType(XmlAccessType.FIELD)
039    public class LoadBalancerType extends IdentifiedType implements LoadBalancer {
040    
041        @XmlTransient
042        private LoadBalancer loadBalancer;
043        @XmlTransient
044        private String loadBalancerTypeName;
045    
046        public LoadBalancerType() {
047        }
048    
049        public LoadBalancerType(LoadBalancer loadBalancer) {
050            this.loadBalancer = loadBalancer;
051        }
052    
053        protected LoadBalancerType(String loadBalancerTypeName) {
054            this.loadBalancerTypeName = loadBalancerTypeName;
055        }
056    
057        public static LoadBalancer getLoadBalancer(RouteContext routeContext, LoadBalancerType type, String ref) {
058            if (type == null) {
059                notNull(ref, "ref or LoadBalancerType");
060                LoadBalancer loadBalancer = routeContext.lookup(ref, LoadBalancer.class);
061                if (loadBalancer instanceof LoadBalancerType) {
062                    type = (LoadBalancerType) loadBalancer;
063                } else {
064                    return loadBalancer;
065                }
066            }
067            return type.getLoadBalancer(routeContext);
068        }
069    
070    
071        /**
072         * Sets a named property on the data format instance using introspection
073         */
074        protected void setProperty(Object bean, String name, Object value) {
075            try {
076                IntrospectionSupport.setProperty(bean, name, value);
077            } catch (Exception e) {
078                throw new IllegalArgumentException("Failed to set property " + name + " on " + bean
079                                                   + ". Reason: " + e, e);
080            }
081        }
082    
083        /**
084         * Allows derived classes to customize the load balancer
085         */
086        protected void configureLoadBalancer(LoadBalancer loadBalancer) {
087        }
088    
089        public LoadBalancer getLoadBalancer(RouteContext routeContext) {
090            if (loadBalancer == null) {
091                loadBalancer = createLoadBalancer(routeContext);
092                ObjectHelper.notNull(loadBalancer, "loadBalancer");
093                configureLoadBalancer(loadBalancer);
094            }
095            return loadBalancer;
096        }
097    
098        /**
099         * Factory method to create the load balancer instance
100         */
101        protected LoadBalancer createLoadBalancer(RouteContext routeContext) {
102            if (loadBalancerTypeName != null) {
103                Class type = ObjectHelper.loadClass(loadBalancerTypeName, getClass().getClassLoader());
104                if (type == null) {
105                    throw new IllegalArgumentException("The class " + loadBalancerTypeName + " is not on the classpath! Cannot use the loadBalancer " + this);
106                }
107                return (LoadBalancer) ObjectHelper.newInstance(type);
108            }
109            return null;
110        }
111    
112    
113        public void addProcessor(Processor processor) {
114            ObjectHelper.notNull(loadBalancer, "loadBalancer");
115            loadBalancer.addProcessor(processor);
116        }
117    
118        public List<Processor> getProcessors() {
119            ObjectHelper.notNull(loadBalancer, "loadBalancer");
120            return loadBalancer.getProcessors();
121        }
122    
123        public void removeProcessor(Processor processor) {
124            ObjectHelper.notNull(loadBalancer, "loadBalancer");
125            loadBalancer.removeProcessor(processor);
126        }
127    
128        public void process(Exchange exchange) throws Exception {
129            ObjectHelper.notNull(loadBalancer, "loadBalancer");
130            loadBalancer.process(exchange);
131        }
132    
133    }