1 /** 2 * Copyright (C) 2007 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.inject.assistedinject; 18 19 import com.google.common.collect.Lists; 20 import com.google.inject.Inject; 21 import com.google.inject.TypeLiteral; 22 23 import java.lang.annotation.Annotation; 24 import java.lang.reflect.Constructor; 25 import java.lang.reflect.InvocationTargetException; 26 import java.lang.reflect.Type; 27 import java.util.ArrayList; 28 import java.util.Arrays; 29 import java.util.HashSet; 30 import java.util.List; 31 import java.util.Set; 32 33 /** 34 * Internal respresentation of a constructor annotated with 35 * {@link AssistedInject} 36 * 37 * @author jmourits@google.com (Jerome Mourits) 38 * @author jessewilson@google.com (Jesse Wilson) 39 */ 40 class AssistedConstructor<T> { 41 42 private final Constructor<T> constructor; 43 private final ParameterListKey assistedParameters; 44 private final List<Parameter> allParameters; 45 create( Constructor<T> constructor, List<TypeLiteral<?>> parameterTypes)46 public static <T> AssistedConstructor<T> create( 47 Constructor<T> constructor, List<TypeLiteral<?>> parameterTypes) { 48 return new AssistedConstructor<T>(constructor, parameterTypes); 49 } 50 AssistedConstructor(Constructor<T> constructor, List<TypeLiteral<?>> parameterTypes)51 private AssistedConstructor(Constructor<T> constructor, List<TypeLiteral<?>> parameterTypes) { 52 this.constructor = constructor; 53 54 Annotation[][] annotations = constructor.getParameterAnnotations(); 55 56 List<Type> typeList = Lists.newArrayList(); 57 allParameters = new ArrayList<Parameter>(); 58 59 // categorize params as @Assisted or @Injected 60 for (int i = 0; i < parameterTypes.size(); i++) { 61 Parameter parameter = new Parameter(parameterTypes.get(i).getType(), annotations[i]); 62 allParameters.add(parameter); 63 if (parameter.isProvidedByFactory()) { 64 typeList.add(parameter.getType()); 65 } 66 } 67 this.assistedParameters = new ParameterListKey(typeList); 68 } 69 70 /** 71 * Returns the {@link ParameterListKey} for this constructor. The 72 * {@link ParameterListKey} is created from the ordered list of {@link Assisted} 73 * constructor parameters. 74 */ getAssistedParameters()75 public ParameterListKey getAssistedParameters() { 76 return assistedParameters; 77 } 78 79 /** 80 * Returns an ordered list of all constructor parameters (both 81 * {@link Assisted} and {@link Inject}ed). 82 */ getAllParameters()83 public List<Parameter> getAllParameters() { 84 return allParameters; 85 } 86 getDeclaredExceptions()87 public Set<Class<?>> getDeclaredExceptions() { 88 return new HashSet<Class<?>>(Arrays.asList(constructor.getExceptionTypes())); 89 } 90 91 /** 92 * Returns an instance of T, constructed using this constructor, with the 93 * supplied arguments. 94 */ newInstance(Object[] args)95 public T newInstance(Object[] args) throws Throwable { 96 constructor.setAccessible(true); 97 try { 98 return constructor.newInstance(args); 99 } catch (InvocationTargetException e) { 100 throw e.getCause(); 101 } 102 } 103 104 @Override toString()105 public String toString() { 106 return constructor.toString(); 107 } 108 } 109