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.model.language; 018 019import javax.xml.bind.annotation.XmlAccessType; 020import javax.xml.bind.annotation.XmlAccessorType; 021import javax.xml.bind.annotation.XmlAttribute; 022import javax.xml.bind.annotation.XmlRootElement; 023import javax.xml.bind.annotation.XmlTransient; 024 025import org.apache.camel.AfterPropertiesConfigured; 026import org.apache.camel.CamelContext; 027import org.apache.camel.Expression; 028import org.apache.camel.Predicate; 029import org.apache.camel.RuntimeCamelException; 030import org.apache.camel.spi.Language; 031import org.apache.camel.spi.Metadata; 032import org.apache.camel.util.ObjectHelper; 033 034/** 035 * To use a Java bean (aka method call) in Camel expressions or predicates. 036 */ 037@Metadata(firstVersion = "1.3.0", label = "language,core,java", title = "Bean method") 038@XmlRootElement(name = "method") 039@XmlAccessorType(XmlAccessType.FIELD) 040public class MethodCallExpression extends ExpressionDefinition { 041 @XmlAttribute 042 private String ref; 043 @XmlAttribute 044 private String method; 045 @XmlAttribute(name = "beanType") 046 private String beanTypeName; 047 @XmlTransient 048 private Class<?> beanType; 049 @XmlTransient 050 private Object instance; 051 052 public MethodCallExpression() { 053 } 054 055 public MethodCallExpression(String beanName) { 056 this(beanName, null); 057 } 058 059 public MethodCallExpression(String beanName, String method) { 060 super((String)null); // we dont use @XmlValue but the attributes instead 061 if (beanName != null && beanName.startsWith("ref:")) { 062 beanName = beanName.substring(4); 063 } else if (beanName != null && beanName.startsWith("bean:")) { 064 beanName = beanName.substring(5); 065 } 066 setRef(beanName); 067 setMethod(method); 068 } 069 070 public MethodCallExpression(Object instance) { 071 this(instance, null); 072 } 073 074 public MethodCallExpression(Object instance, String method) { 075 super((String)null); // we dont use @XmlValue but the attributes instead 076 // must use setter as they have special logic 077 setInstance(instance); 078 setMethod(method); 079 } 080 081 public MethodCallExpression(Class<?> type) { 082 this(type, null); 083 } 084 085 public MethodCallExpression(Class<?> type, String method) { 086 super((String)null); // we dont use @XmlValue but the attributes instead 087 setBeanType(type); 088 setBeanTypeName(type.getName()); 089 setMethod(method); 090 } 091 092 @Override 093 public String getLanguage() { 094 return "bean"; 095 } 096 097 public String getRef() { 098 return ref; 099 } 100 101 /** 102 * Reference to bean to lookup in the registry 103 */ 104 public void setRef(String ref) { 105 this.ref = ref; 106 } 107 108 public String getMethod() { 109 return method; 110 } 111 112 /** 113 * Name of method to call 114 */ 115 public void setMethod(String method) { 116 this.method = method; 117 } 118 119 public Class<?> getBeanType() { 120 return beanType; 121 } 122 123 public void setBeanType(Class<?> beanType) { 124 this.beanType = beanType; 125 this.instance = null; 126 } 127 128 public String getBeanTypeName() { 129 return beanTypeName; 130 } 131 132 /** 133 * Class name of the bean to use 134 */ 135 public void setBeanTypeName(String beanTypeName) { 136 this.beanTypeName = beanTypeName; 137 } 138 139 public Object getInstance() { 140 return instance; 141 } 142 143 public void setInstance(Object instance) { 144 // people may by mistake pass in a class type as the instance 145 if (instance instanceof Class) { 146 this.beanType = (Class<?>)instance; 147 this.instance = null; 148 } else { 149 this.beanType = null; 150 this.instance = instance; 151 } 152 } 153 154 @Override 155 public Expression createExpression(CamelContext camelContext) { 156 if (beanType == null && beanTypeName != null) { 157 try { 158 beanType = camelContext.getClassResolver().resolveMandatoryClass(beanTypeName); 159 } catch (ClassNotFoundException e) { 160 throw RuntimeCamelException.wrapRuntimeCamelException(e); 161 } 162 } 163 164 // special for bean language where we need to configure it first 165 Language lan = camelContext.resolveLanguage("bean"); 166 configureLanguage(camelContext, lan); 167 // .. and create expression with null value as we use the configured 168 // properties instead 169 Expression exp = lan.createExpression(null); 170 if (exp instanceof AfterPropertiesConfigured) { 171 ((AfterPropertiesConfigured)exp).afterPropertiesConfigured(camelContext); 172 } 173 return exp; 174 } 175 176 protected void configureLanguage(CamelContext camelContext, Language language) { 177 if (instance != null) { 178 setProperty(camelContext, language, "bean", instance); 179 } 180 if (beanType != null) { 181 setProperty(camelContext, language, "beanType", beanType); 182 } 183 if (ref != null) { 184 setProperty(camelContext, language, "ref", ref); 185 } 186 if (method != null) { 187 setProperty(camelContext, language, "method", method); 188 } 189 } 190 191 @Override 192 public Predicate createPredicate(CamelContext camelContext) { 193 return (Predicate)createExpression(camelContext); 194 } 195 196 private String beanName() { 197 if (ref != null) { 198 return ref; 199 } else if (instance != null) { 200 return ObjectHelper.className(instance); 201 } 202 return getExpression(); 203 } 204 205 @Override 206 public String toString() { 207 boolean isRef = ref != null; 208 return "bean[" + (isRef ? "ref:" : "") + beanName() + (method != null ? " method:" + method : "") + "]"; 209 } 210 211}