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