001/* 002 * Copyright 2002-2014 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.expression.spel.support; 018 019import java.lang.reflect.Constructor; 020 021import org.springframework.expression.AccessException; 022import org.springframework.expression.ConstructorExecutor; 023import org.springframework.expression.EvaluationContext; 024import org.springframework.expression.TypedValue; 025import org.springframework.util.ReflectionUtils; 026 027/** 028 * A simple ConstructorExecutor implementation that runs a constructor using reflective 029 * invocation. 030 * 031 * @author Andy Clement 032 * @author Juergen Hoeller 033 * @since 3.0 034 */ 035public class ReflectiveConstructorExecutor implements ConstructorExecutor { 036 037 private final Constructor<?> ctor; 038 039 private final Integer varargsPosition; 040 041 042 public ReflectiveConstructorExecutor(Constructor<?> ctor) { 043 this.ctor = ctor; 044 if (ctor.isVarArgs()) { 045 Class<?>[] paramTypes = ctor.getParameterTypes(); 046 this.varargsPosition = paramTypes.length - 1; 047 } 048 else { 049 this.varargsPosition = null; 050 } 051 } 052 053 @Override 054 public TypedValue execute(EvaluationContext context, Object... arguments) throws AccessException { 055 try { 056 if (arguments != null) { 057 ReflectionHelper.convertArguments(context.getTypeConverter(), arguments, this.ctor, this.varargsPosition); 058 } 059 if (this.ctor.isVarArgs()) { 060 arguments = ReflectionHelper.setupArgumentsForVarargsInvocation(this.ctor.getParameterTypes(), arguments); 061 } 062 ReflectionUtils.makeAccessible(this.ctor); 063 return new TypedValue(this.ctor.newInstance(arguments)); 064 } 065 catch (Exception ex) { 066 throw new AccessException("Problem invoking constructor: " + this.ctor, ex); 067 } 068 } 069 070 public Constructor<?> getConstructor() { 071 return this.ctor; 072 } 073 074}