blob: bce8098c260244044f6903590a9e17764ca781b8 [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
crazyboblee10a3b022007-02-10 01:49:38 +000017package com.google.inject;
18
limpbizkit4f6274a2009-02-19 21:57:55 +000019import com.google.inject.internal.BytecodeGen;
limpbizkit47062f12008-07-03 20:53:24 +000020import com.google.inject.internal.BytecodeGen.Visibility;
limpbizkit53664a72009-02-21 00:25:27 +000021import com.google.inject.internal.ImmutableMap;
limpbizkita98bc7a2008-08-29 16:52:44 +000022import com.google.inject.spi.InjectionPoint;
limpbizkit916f5482008-04-16 20:51:14 +000023import java.lang.reflect.Constructor;
24import java.lang.reflect.InvocationTargetException;
limpbizkit696c5cd2008-12-30 21:48:17 +000025import java.lang.reflect.Method;
limpbizkit916f5482008-04-16 20:51:14 +000026import java.lang.reflect.Modifier;
limpbizkit696c5cd2008-12-30 21:48:17 +000027import java.util.List;
limpbizkit916f5482008-04-16 20:51:14 +000028
crazybobleee3adfd62007-02-02 21:30:08 +000029/**
limpbizkit03b81a62009-03-18 05:34:39 +000030 * Produces construction proxies that invoke the class constructor.
crazybobleee3adfd62007-02-02 21:30:08 +000031 *
32 * @author crazybob@google.com (Bob Lee)
33 */
limpbizkit03b81a62009-03-18 05:34:39 +000034class DefaultConstructionProxyFactory<T> implements ConstructionProxyFactory<T> {
crazybobleee3adfd62007-02-02 21:30:08 +000035
limpbizkit03b81a62009-03-18 05:34:39 +000036 private final InjectionPoint injectionPoint;
37
38 /**
39 * @param injectionPoint an injection point whose member is a constructor of {@code T}.
40 */
41 DefaultConstructionProxyFactory(InjectionPoint injectionPoint) {
42 this.injectionPoint = injectionPoint;
43 }
44
45 public ConstructionProxy<T> create() {
limpbizkita6e0e782008-09-03 06:19:56 +000046 @SuppressWarnings("unchecked") // the injection point is for a constructor of T
47 final Constructor<T> constructor = (Constructor<T>) injectionPoint.getMember();
limpbizkit916f5482008-04-16 20:51:14 +000048
limpbizkitbf0d8762009-02-19 09:06:22 +000049 // Use FastConstructor if the constructor is public.
50 if (Modifier.isPublic(constructor.getModifiers())) {
limpbizkit4f6274a2009-02-19 21:57:55 +000051 /*if[AOP]*/
crazyboblee0b3189c2007-02-24 00:14:51 +000052 return new ConstructionProxy<T>() {
limpbizkitbf0d8762009-02-19 09:06:22 +000053 Class<T> classToConstruct = constructor.getDeclaringClass();
limpbizkit4f6274a2009-02-19 21:57:55 +000054 final net.sf.cglib.reflect.FastConstructor fastConstructor
55 = BytecodeGen.newFastClass(classToConstruct, Visibility.forMember(constructor))
56 .getConstructor(constructor);
limpbizkitbf0d8762009-02-19 09:06:22 +000057
58 @SuppressWarnings("unchecked")
limpbizkit06898062008-11-02 05:14:55 +000059 public T newInstance(Object... arguments) throws InvocationTargetException {
limpbizkitbf0d8762009-02-19 09:06:22 +000060 return (T) fastConstructor.newInstance(arguments);
crazyboblee0b3189c2007-02-24 00:14:51 +000061 }
limpbizkita98bc7a2008-08-29 16:52:44 +000062 public InjectionPoint getInjectionPoint() {
63 return injectionPoint;
limpbizkit916f5482008-04-16 20:51:14 +000064 }
limpbizkit477f9f92008-07-28 07:05:14 +000065 public Constructor<T> getConstructor() {
limpbizkit916f5482008-04-16 20:51:14 +000066 return constructor;
67 }
limpbizkita843a952009-04-08 22:24:55 +000068 public ImmutableMap<Method, List<org.aopalliance.intercept.MethodInterceptor>>
limpbizkit4f6274a2009-02-19 21:57:55 +000069 getMethodInterceptors() {
limpbizkit696c5cd2008-12-30 21:48:17 +000070 return ImmutableMap.of();
71 }
crazyboblee0b3189c2007-02-24 00:14:51 +000072 };
limpbizkit4f6274a2009-02-19 21:57:55 +000073 /*end[AOP]*/
74 } else {
limpbizkitbf0d8762009-02-19 09:06:22 +000075 constructor.setAccessible(true);
76 }
crazyboblee0b3189c2007-02-24 00:14:51 +000077
crazybobleee3adfd62007-02-02 21:30:08 +000078 return new ConstructionProxy<T>() {
limpbizkit9dc32d42008-06-15 11:29:10 +000079 public T newInstance(Object... arguments) throws InvocationTargetException {
limpbizkitbf0d8762009-02-19 09:06:22 +000080 try {
81 return constructor.newInstance(arguments);
82 } catch (InstantiationException e) {
83 throw new AssertionError(e); // shouldn't happen, we know this is a concrete type
84 } catch (IllegalAccessException e) {
85 throw new AssertionError(e); // a security manager is blocking us, we're hosed
86 }
crazybobleee3adfd62007-02-02 21:30:08 +000087 }
limpbizkita98bc7a2008-08-29 16:52:44 +000088 public InjectionPoint getInjectionPoint() {
89 return injectionPoint;
limpbizkit916f5482008-04-16 20:51:14 +000090 }
limpbizkit477f9f92008-07-28 07:05:14 +000091 public Constructor<T> getConstructor() {
limpbizkit7e6659c2008-05-14 01:22:21 +000092 return constructor;
limpbizkit916f5482008-04-16 20:51:14 +000093 }
limpbizkitbf0d8762009-02-19 09:06:22 +000094 /*if[AOP]*/
limpbizkita843a952009-04-08 22:24:55 +000095 public ImmutableMap<Method, List<org.aopalliance.intercept.MethodInterceptor>>
limpbizkit4f6274a2009-02-19 21:57:55 +000096 getMethodInterceptors() {
limpbizkit696c5cd2008-12-30 21:48:17 +000097 return ImmutableMap.of();
98 }
limpbizkitbf0d8762009-02-19 09:06:22 +000099 /*end[AOP]*/
crazybobleee3adfd62007-02-02 21:30:08 +0000100 };
101 }
102}