001 /** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one or more 004 * contributor license agreements. See the NOTICE file distributed with 005 * this work for additional information regarding copyright ownership. 006 * The ASF licenses this file to You under the Apache License, Version 2.0 007 * (the "License"); you may not use this file except in compliance with 008 * the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 package org.apache.camel.spring.xml; 019 020 import org.springframework.beans.SimpleTypeConverter; 021 import org.springframework.beans.factory.BeanFactory; 022 import org.springframework.beans.factory.config.RuntimeBeanReference; 023 024 import java.lang.reflect.InvocationTargetException; 025 import java.util.HashMap; 026 import java.util.List; 027 import java.util.Map; 028 029 public class BuilderAction { 030 private final MethodInfo methodInfo; 031 private final HashMap<String, Object> parameterValues; 032 033 public BuilderAction(MethodInfo methodInfo, HashMap<String, Object> parameterValues) { 034 this.methodInfo = methodInfo; 035 this.parameterValues = parameterValues; 036 } 037 038 public Object invoke(BeanFactory beanFactory, Object rootBuilder, Object contextBuilder) { 039 SimpleTypeConverter converter = new SimpleTypeConverter(); 040 Object args[] = new Object[methodInfo.parameters.size()]; 041 int pos = 0; 042 for (Map.Entry<String, Class> entry : methodInfo.parameters.entrySet()) { 043 String paramName = entry.getKey(); 044 Class paramClass = entry.getValue(); 045 Object value = parameterValues.get(paramName); 046 if (value != null) { 047 value = replaceBeanReferences(beanFactory, rootBuilder, value); 048 args[pos] = converter.convertIfNecessary(value, paramClass); 049 } 050 } 051 052 try { 053 return methodInfo.method.invoke(contextBuilder, args); 054 } 055 catch (InvocationTargetException e) { 056 throw new IllegalArgumentException(e.getCause()); 057 } 058 catch (RuntimeException e) { 059 throw e; 060 } 061 catch (Throwable e) { 062 throw new IllegalArgumentException(e); 063 } 064 } 065 066 protected Object replaceBeanReferences(BeanFactory beanFactory, Object rootBuilder, Object value) { 067 // TODO why not using instanceof?? 068 if (value.getClass() == RuntimeBeanReference.class) { 069 String beanName = ((RuntimeBeanReference) value).getBeanName(); 070 value = beanFactory.getBean(beanName); 071 } 072 if (value.getClass() == BuilderStatement.class) { 073 BuilderStatement bs = (BuilderStatement) value; 074 value = bs.create(beanFactory, rootBuilder); 075 } 076 if (value instanceof List) { 077 List list = (List) value; 078 for (int i = 0, size = list.size(); i < size; i++) { 079 list.set(i, replaceBeanReferences(beanFactory, rootBuilder, list.get(i))); 080 } 081 } 082 return value; 083 } 084 085 public String getName() { 086 return methodInfo.getName(); 087 } 088 089 public MethodInfo getMethodInfo() { 090 return methodInfo; 091 } 092 }