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