blob: 6bcaeef6a1093f66c900cdd024bd2e15a2879711 [file] [log] [blame]
crazybobleeb8cf1e52007-02-02 21:48:16 +00001/**
2 * Copyright (C) 2006 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 */
crazybobleee3adfd62007-02-02 21:30:08 +000016
limpbizkit5ae41eb2009-06-06 17:51:27 +000017package com.google.inject.internal;
crazyboblee10a3b022007-02-10 01:49:38 +000018
limpbizkit47062f12008-07-03 20:53:24 +000019import com.google.inject.internal.BytecodeGen.Visibility;
limpbizkita98bc7a2008-08-29 16:52:44 +000020import com.google.inject.spi.InjectionPoint;
limpbizkit916f5482008-04-16 20:51:14 +000021import java.lang.reflect.Constructor;
22import java.lang.reflect.InvocationTargetException;
limpbizkit696c5cd2008-12-30 21:48:17 +000023import java.lang.reflect.Method;
limpbizkit916f5482008-04-16 20:51:14 +000024import java.lang.reflect.Modifier;
limpbizkit696c5cd2008-12-30 21:48:17 +000025import java.util.List;
limpbizkit916f5482008-04-16 20:51:14 +000026
crazybobleee3adfd62007-02-02 21:30:08 +000027/**
limpbizkit03b81a62009-03-18 05:34:39 +000028 * Produces construction proxies that invoke the class constructor.
crazybobleee3adfd62007-02-02 21:30:08 +000029 *
30 * @author crazybob@google.com (Bob Lee)
31 */
limpbizkit5ae41eb2009-06-06 17:51:27 +000032final class DefaultConstructionProxyFactory<T> implements ConstructionProxyFactory<T> {
crazybobleee3adfd62007-02-02 21:30:08 +000033
limpbizkit03b81a62009-03-18 05:34:39 +000034 private final InjectionPoint injectionPoint;
35
36 /**
37 * @param injectionPoint an injection point whose member is a constructor of {@code T}.
38 */
39 DefaultConstructionProxyFactory(InjectionPoint injectionPoint) {
40 this.injectionPoint = injectionPoint;
41 }
42
43 public ConstructionProxy<T> create() {
limpbizkita6e0e782008-09-03 06:19:56 +000044 @SuppressWarnings("unchecked") // the injection point is for a constructor of T
45 final Constructor<T> constructor = (Constructor<T>) injectionPoint.getMember();
limpbizkit916f5482008-04-16 20:51:14 +000046
limpbizkitbf0d8762009-02-19 09:06:22 +000047 // Use FastConstructor if the constructor is public.
48 if (Modifier.isPublic(constructor.getModifiers())) {
limpbizkit4f6274a2009-02-19 21:57:55 +000049 /*if[AOP]*/
crazyboblee0b3189c2007-02-24 00:14:51 +000050 return new ConstructionProxy<T>() {
limpbizkitbf0d8762009-02-19 09:06:22 +000051 Class<T> classToConstruct = constructor.getDeclaringClass();
limpbizkit4f6274a2009-02-19 21:57:55 +000052 final net.sf.cglib.reflect.FastConstructor fastConstructor
53 = BytecodeGen.newFastClass(classToConstruct, Visibility.forMember(constructor))
54 .getConstructor(constructor);
limpbizkitbf0d8762009-02-19 09:06:22 +000055
56 @SuppressWarnings("unchecked")
limpbizkit06898062008-11-02 05:14:55 +000057 public T newInstance(Object... arguments) throws InvocationTargetException {
limpbizkitbf0d8762009-02-19 09:06:22 +000058 return (T) fastConstructor.newInstance(arguments);
crazyboblee0b3189c2007-02-24 00:14:51 +000059 }
limpbizkita98bc7a2008-08-29 16:52:44 +000060 public InjectionPoint getInjectionPoint() {
61 return injectionPoint;
limpbizkit916f5482008-04-16 20:51:14 +000062 }
limpbizkit477f9f92008-07-28 07:05:14 +000063 public Constructor<T> getConstructor() {
limpbizkit916f5482008-04-16 20:51:14 +000064 return constructor;
65 }
limpbizkita843a952009-04-08 22:24:55 +000066 public ImmutableMap<Method, List<org.aopalliance.intercept.MethodInterceptor>>
limpbizkit4f6274a2009-02-19 21:57:55 +000067 getMethodInterceptors() {
limpbizkit696c5cd2008-12-30 21:48:17 +000068 return ImmutableMap.of();
69 }
crazyboblee0b3189c2007-02-24 00:14:51 +000070 };
limpbizkit4f6274a2009-02-19 21:57:55 +000071 /*end[AOP]*/
72 } else {
limpbizkitbf0d8762009-02-19 09:06:22 +000073 constructor.setAccessible(true);
74 }
crazyboblee0b3189c2007-02-24 00:14:51 +000075
crazybobleee3adfd62007-02-02 21:30:08 +000076 return new ConstructionProxy<T>() {
limpbizkit9dc32d42008-06-15 11:29:10 +000077 public T newInstance(Object... arguments) throws InvocationTargetException {
limpbizkitbf0d8762009-02-19 09:06:22 +000078 try {
79 return constructor.newInstance(arguments);
80 } catch (InstantiationException e) {
81 throw new AssertionError(e); // shouldn't happen, we know this is a concrete type
82 } catch (IllegalAccessException e) {
83 throw new AssertionError(e); // a security manager is blocking us, we're hosed
84 }
crazybobleee3adfd62007-02-02 21:30:08 +000085 }
limpbizkita98bc7a2008-08-29 16:52:44 +000086 public InjectionPoint getInjectionPoint() {
87 return injectionPoint;
limpbizkit916f5482008-04-16 20:51:14 +000088 }
limpbizkit477f9f92008-07-28 07:05:14 +000089 public Constructor<T> getConstructor() {
limpbizkit7e6659c2008-05-14 01:22:21 +000090 return constructor;
limpbizkit916f5482008-04-16 20:51:14 +000091 }
limpbizkitbf0d8762009-02-19 09:06:22 +000092 /*if[AOP]*/
limpbizkita843a952009-04-08 22:24:55 +000093 public ImmutableMap<Method, List<org.aopalliance.intercept.MethodInterceptor>>
limpbizkit4f6274a2009-02-19 21:57:55 +000094 getMethodInterceptors() {
limpbizkit696c5cd2008-12-30 21:48:17 +000095 return ImmutableMap.of();
96 }
limpbizkitbf0d8762009-02-19 09:06:22 +000097 /*end[AOP]*/
crazybobleee3adfd62007-02-02 21:30:08 +000098 };
99 }
100}