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 import java.lang.annotation.Annotation; 23 import java.lang.reflect.Constructor; 24 import java.lang.reflect.InvocationTargetException; 25 import java.lang.reflect.Type; 26 import java.util.ArrayList; 27 import java.util.Arrays; 28 import java.util.HashSet; 29 import java.util.List; 30 import java.util.Set; 31 32 /** 33 * Internal respresentation of a constructor annotated with {@link AssistedInject} 34 * 35 * @author jmourits@google.com (Jerome Mourits) 36 * @author jessewilson@google.com (Jesse Wilson) 37 */ 38 class AssistedConstructor<T> { 39 40 private final Constructor<T> constructor; 41 private final ParameterListKey assistedParameters; 42 private final List<Parameter> allParameters; 43 create( Constructor<T> constructor, List<TypeLiteral<?>> parameterTypes)44 public static <T> AssistedConstructor<T> create( 45 Constructor<T> constructor, List<TypeLiteral<?>> parameterTypes) { 46 return new AssistedConstructor<T>(constructor, parameterTypes); 47 } 48 AssistedConstructor(Constructor<T> constructor, List<TypeLiteral<?>> parameterTypes)49 private AssistedConstructor(Constructor<T> constructor, List<TypeLiteral<?>> parameterTypes) { 50 this.constructor = constructor; 51 52 Annotation[][] annotations = constructor.getParameterAnnotations(); 53 54 List<Type> typeList = Lists.newArrayList(); 55 allParameters = new ArrayList<>(); 56 57 // categorize params as @Assisted or @Injected 58 for (int i = 0; i < parameterTypes.size(); i++) { 59 Parameter parameter = new Parameter(parameterTypes.get(i).getType(), annotations[i]); 60 allParameters.add(parameter); 61 if (parameter.isProvidedByFactory()) { 62 typeList.add(parameter.getType()); 63 } 64 } 65 this.assistedParameters = new ParameterListKey(typeList); 66 } 67 68 /** 69 * Returns the {@link ParameterListKey} for this constructor. The {@link ParameterListKey} is 70 * created from the ordered list of {@link Assisted} constructor parameters. 71 */ getAssistedParameters()72 public ParameterListKey getAssistedParameters() { 73 return assistedParameters; 74 } 75 76 /** 77 * Returns an ordered list of all constructor parameters (both {@link Assisted} and {@link 78 * Inject}ed). 79 */ getAllParameters()80 public List<Parameter> getAllParameters() { 81 return allParameters; 82 } 83 getDeclaredExceptions()84 public Set<Class<?>> getDeclaredExceptions() { 85 return new HashSet<Class<?>>(Arrays.asList(constructor.getExceptionTypes())); 86 } 87 88 /** Returns an instance of T, constructed using this constructor, with the supplied arguments. */ newInstance(Object[] args)89 public T newInstance(Object[] args) throws Throwable { 90 constructor.setAccessible(true); 91 try { 92 return constructor.newInstance(args); 93 } catch (InvocationTargetException e) { 94 throw e.getCause(); 95 } 96 } 97 98 @Override toString()99 public String toString() { 100 return constructor.toString(); 101 } 102 } 103