You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by iv...@apache.org on 2010/03/17 00:30:35 UTC
svn commit: r924049 - in /wicket/trunk/wicket-guice/src:
main/java/org/apache/wicket/guice/ test/java/org/apache/wicket/guice/
Author: ivaynberg
Date: Tue Mar 16 23:30:35 2010
New Revision: 924049
URL: http://svn.apache.org/viewvc?rev=924049&view=rev
Log:
WICKET-2761 InjectorHolder.getInjector().inject(this) doesn't work with wicket-guice
Added:
wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceFieldValueFactory.java (with props)
wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/TestNoComponent.java (with props)
Removed:
wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/InjectionFlagCachingGuiceComponentInjector.java
Modified:
wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceComponentInjector.java
wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceProxyTargetLocator.java
wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/GuiceInjectorTest.java
wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/TestComponent.java
Modified: wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceComponentInjector.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceComponentInjector.java?rev=924049&r1=924048&r2=924049&view=diff
==============================================================================
--- wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceComponentInjector.java (original)
+++ wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceComponentInjector.java Tue Mar 16 23:30:35 2010
@@ -16,30 +16,19 @@
*/
package org.apache.wicket.guice;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-
import org.apache.wicket.Application;
import org.apache.wicket.Component;
-import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.application.IComponentInstantiationListener;
-import org.apache.wicket.proxy.LazyInitProxyFactory;
+import org.apache.wicket.injection.IFieldValueFactory;
-import com.google.inject.BindingAnnotation;
import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
-import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Stage;
/**
- * Injects fields/members of components using Guice.
+ * Injects field members of components using Guice.
* <p>
* Add this to your application in its {@link Application#init()} method like so:
*
@@ -53,8 +42,12 @@ import com.google.inject.Stage;
*
* @author Alastair Maw
*/
-public class GuiceComponentInjector implements IComponentInstantiationListener
+public class GuiceComponentInjector extends org.apache.wicket.injection.Injector
+ implements
+ IComponentInstantiationListener
{
+ private final IFieldValueFactory fieldValueFactory;
+
/**
* Creates a new Wicket GuiceComponentInjector instance.
* <p>
@@ -81,7 +74,15 @@ public class GuiceComponentInjector impl
{
this(app, Guice.createInjector(app.getConfigurationType().equals(Application.DEVELOPMENT)
? Stage.DEVELOPMENT
- : Stage.PRODUCTION, modules));
+ : Stage.PRODUCTION, modules), true);
+ }
+
+ /**
+ * @see GuiceComponentInjector(Application app, Injector injector, boolean wrapInProxies)
+ */
+ public GuiceComponentInjector(Application app, Injector injector)
+ {
+ this(app, injector, true);
}
/**
@@ -90,139 +91,25 @@ public class GuiceComponentInjector impl
*
* @param app
* @param injector
+ * @param wrapInProxies
+ * whether or not wicket should wrap dependencies with specialized proxies that can
+ * be safely serialized. in most cases this should be set to true.
*/
- public GuiceComponentInjector(Application app, Injector injector)
+ public GuiceComponentInjector(Application app, Injector injector, final boolean wrapInProxies)
{
app.setMetaData(GuiceInjectorHolder.INJECTOR_KEY, new GuiceInjectorHolder(injector));
+ fieldValueFactory = new GuiceFieldValueFactory(wrapInProxies);
+ bind(app);
}
+ @Override
public void inject(Object object)
{
- Class< ? > current = object.getClass();
- do
- {
- Field[] currentFields = current.getDeclaredFields();
- for (final Field field : currentFields)
- {
- Inject injectAnnotation = field.getAnnotation(Inject.class);
- if (!Modifier.isStatic(field.getModifiers()) && injectAnnotation != null)
- {
- try
- {
- Annotation bindingAnnotation = findBindingAnnotation(field.getAnnotations());
- Object proxy = LazyInitProxyFactory.createProxy(field.getType(),
- new GuiceProxyTargetLocator(field, bindingAnnotation,
- injectAnnotation.optional()));
-
- if (!field.isAccessible())
- {
- field.setAccessible(true);
- }
- field.set(object, proxy);
- }
- catch (IllegalAccessException e)
- {
- throw new WicketRuntimeException("Error Guice-injecting field " +
- field.getName() + " in " + object, e);
- }
- catch (MoreThanOneBindingException e)
- {
- throw new RuntimeException(
- "Can't have more than one BindingAnnotation on field " +
- field.getName() + " of class " +
- object.getClass().getName());
- }
- }
- }
- Method[] currentMethods = current.getDeclaredMethods();
- for (final Method method : currentMethods)
- {
- Inject injectAnnotation = method.getAnnotation(Inject.class);
- if (!Modifier.isStatic(method.getModifiers()) && injectAnnotation != null)
- {
- Annotation[][] paramAnnotations = method.getParameterAnnotations();
- Class< ? >[] paramTypes = method.getParameterTypes();
- Type[] genericParamTypes = method.getGenericParameterTypes();
- Object[] args = new Object[paramTypes.length];
- for (int i = 0; i < paramTypes.length; i++)
- {
- Type paramType;
- if (genericParamTypes[i] instanceof ParameterizedType)
- {
- paramType = ((ParameterizedType)genericParamTypes[i]).getRawType();
- }
- else
- {
- paramType = paramTypes[i];
- }
- try
- {
- Annotation bindingAnnotation = findBindingAnnotation(paramAnnotations[i]);
- args[i] = LazyInitProxyFactory.createProxy(paramTypes[i],
- new GuiceProxyTargetLocator(method, i, bindingAnnotation,
- injectAnnotation.optional()));
- }
- catch (MoreThanOneBindingException e)
- {
- throw new RuntimeException(
- "Can't have more than one BindingAnnotation on parameter " + i +
- "(" + paramType + ") of method " + method.getName() +
- " of class " + object.getClass().getName());
- }
- }
- try
- {
- method.invoke(object, args);
- }
- catch (IllegalAccessException e)
- {
- throw new WicketRuntimeException(e);
- }
- catch (InvocationTargetException e)
- {
- throw new WicketRuntimeException(e);
- }
- }
- }
- current = current.getSuperclass();
- }
- // Do a null check in case Object isn't in the current classloader.
- while (current != null && current != Object.class);
+ inject(object, fieldValueFactory);
}
public void onInstantiation(Component component)
{
inject(component);
}
-
- /**
- *
- * @param annotations
- * @return
- * @throws MoreThanOneBindingException
- */
- public static Annotation findBindingAnnotation(final Annotation[] annotations)
- throws MoreThanOneBindingException
- {
- Annotation bindingAnnotation = null;
-
- // Work out if we have a BindingAnnotation on this parameter.
- for (Annotation annotation : annotations)
- {
- if (annotation.annotationType().getAnnotation(BindingAnnotation.class) != null)
- {
- if (bindingAnnotation != null)
- {
- throw new MoreThanOneBindingException();
- }
- bindingAnnotation = annotation;
- }
- }
- return bindingAnnotation;
- }
-
- public static class MoreThanOneBindingException extends Exception
- {
- private static final long serialVersionUID = 1L;
- }
}
Added: wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceFieldValueFactory.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceFieldValueFactory.java?rev=924049&view=auto
==============================================================================
--- wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceFieldValueFactory.java (added)
+++ wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceFieldValueFactory.java Tue Mar 16 23:30:35 2010
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.guice;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.injection.IFieldValueFactory;
+import org.apache.wicket.proxy.IProxyTargetLocator;
+import org.apache.wicket.proxy.LazyInitProxyFactory;
+
+import com.google.inject.BindingAnnotation;
+import com.google.inject.Inject;
+
+public class GuiceFieldValueFactory implements IFieldValueFactory
+{
+ private final boolean wrapInProxies;
+
+ GuiceFieldValueFactory(final boolean wrapInProxies)
+ {
+ this.wrapInProxies = wrapInProxies;
+ }
+
+ public Object getFieldValue(Field field, Object fieldOwner)
+ {
+ Object target = null;
+
+ if (supportsField(field))
+ {
+ Inject injectAnnotation = field.getAnnotation(Inject.class);
+ if (!Modifier.isStatic(field.getModifiers()) && injectAnnotation != null)
+ {
+ try
+ {
+ Annotation bindingAnnotation = findBindingAnnotation(field.getAnnotations());
+ final IProxyTargetLocator locator = new GuiceProxyTargetLocator(field,
+ bindingAnnotation, injectAnnotation.optional());
+
+ if (wrapInProxies)
+ {
+ target = LazyInitProxyFactory.createProxy(field.getType(), locator);
+ }
+ else
+ {
+ target = locator.locateProxyTarget();
+ }
+
+ if (!field.isAccessible())
+ {
+ field.setAccessible(true);
+ }
+
+ field.set(fieldOwner, target);
+
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new WicketRuntimeException("Error Guice-injecting field " +
+ field.getName() + " in " + fieldOwner, e);
+ }
+ catch (MoreThanOneBindingException e)
+ {
+ throw new RuntimeException(
+ "Can't have more than one BindingAnnotation on field " +
+ field.getName() + " of class " +
+ fieldOwner.getClass().getName());
+ }
+ }
+ }
+
+ return target;
+ }
+
+ public boolean supportsField(Field field)
+ {
+ return field.isAnnotationPresent(Inject.class);
+ }
+
+ private Annotation findBindingAnnotation(final Annotation[] annotations)
+ throws MoreThanOneBindingException
+ {
+ Annotation bindingAnnotation = null;
+
+ // Work out if we have a BindingAnnotation on this parameter.
+ for (Annotation annotation : annotations)
+ {
+ if (annotation.annotationType().getAnnotation(BindingAnnotation.class) != null)
+ {
+ if (bindingAnnotation != null)
+ {
+ throw new MoreThanOneBindingException();
+ }
+ bindingAnnotation = annotation;
+ }
+ }
+ return bindingAnnotation;
+ }
+
+ public static class MoreThanOneBindingException extends Exception
+ {
+ private static final long serialVersionUID = 1L;
+ }
+}
Propchange: wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceFieldValueFactory.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceProxyTargetLocator.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceProxyTargetLocator.java?rev=924049&r1=924048&r2=924049&view=diff
==============================================================================
--- wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceProxyTargetLocator.java (original)
+++ wicket/trunk/wicket-guice/src/main/java/org/apache/wicket/guice/GuiceProxyTargetLocator.java Tue Mar 16 23:30:35 2010
@@ -18,7 +18,6 @@ package org.apache.wicket.guice;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
-import java.lang.reflect.Method;
import java.lang.reflect.Type;
import org.apache.wicket.Application;
@@ -38,34 +37,16 @@ class GuiceProxyTargetLocator implements
private final boolean optional;
- private final String[] data;
+ private final String className;
- /** index of argument in the method being injected, or -1 for field */
- private final int argIndex;
+ private final String fieldName;
public GuiceProxyTargetLocator(Field field, Annotation bindingAnnotation, boolean optional)
{
this.bindingAnnotation = bindingAnnotation;
this.optional = optional;
- data = new String[2];
- data[0] = field.getDeclaringClass().getName();
- data[1] = field.getName();
- argIndex = -1;
- }
-
- public GuiceProxyTargetLocator(Method method, int argIndex, Annotation bindingAnnotation,
- boolean optional)
- {
- this.bindingAnnotation = bindingAnnotation;
- this.optional = optional;
- data = new String[2 + method.getParameterTypes().length];
- data[0] = method.getDeclaringClass().getName();
- data[1] = method.getName();
- for (int i = 0; i < method.getParameterTypes().length; i++)
- {
- data[2 + i] = method.getParameterTypes()[i].getName();
- }
- this.argIndex = argIndex;
+ className = field.getDeclaringClass().getName();
+ fieldName = field.getName();
}
public Object locateProxyTarget()
@@ -77,27 +58,14 @@ class GuiceProxyTargetLocator implements
try
{
- Class< ? > clazz = Classes.resolveClass(data[0]);
- if (argIndex < 0)
- {
- final Field field = clazz.getDeclaredField(data[1]);
- type = field.getGenericType();
- }
- else
- {
- Class< ? >[] paramTypes = new Class[data.length - 2];
- for (int i = 2; i < data.length; i++)
- {
- paramTypes[i - 2] = Classes.resolveClass(data[i]);
- }
- final Method method = clazz.getDeclaredMethod(data[1], paramTypes);
- type = method.getGenericParameterTypes()[argIndex];
- }
+ Class< ? > clazz = Classes.resolveClass(className);
+ final Field field = clazz.getDeclaredField(fieldName);
+ type = field.getGenericType();
}
catch (Exception e)
{
- throw new WicketRuntimeException("Error accessing member: " + data[1] + " of class: " +
- data[0], e);
+ throw new WicketRuntimeException("Error accessing member: " + fieldName +
+ " of class: " + className, e);
}
// using TypeLiteral to retrieve the key gives us automatic support for
Modified: wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/GuiceInjectorTest.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/GuiceInjectorTest.java?rev=924049&r1=924048&r2=924049&view=diff
==============================================================================
--- wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/GuiceInjectorTest.java (original)
+++ wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/GuiceInjectorTest.java Tue Mar 16 23:30:35 2010
@@ -89,6 +89,10 @@ public class GuiceInjectorTest extends T
TestComponent clonedComponent = (TestComponent)Objects.cloneObject(testComponent);
doChecksForComponent(clonedComponent);
+ // Test injection of a class that does not extend Component
+ TestNoComponent noncomponent = new TestNoComponent();
+ doChecksForNoComponent(noncomponent);
+
}
finally
{
@@ -97,22 +101,21 @@ public class GuiceInjectorTest extends T
}
}
+ private void doChecksForNoComponent(TestNoComponent component)
+ {
+ assertEquals(ITestService.RESULT_RED, component.getString());
+ }
+
private void doChecksForComponent(TestComponent component)
{
assertEquals(ITestService.RESULT, component.getInjectedField().getString());
assertEquals(null, component.getInjectedOptionalField());
assertEquals(ITestService.RESULT_RED, component.getInjectedFieldRed().getString());
assertEquals(ITestService.RESULT_BLUE, component.getInjectedFieldBlue().getString());
- assertEquals(ITestService.RESULT, component.getInjectedMethod().getString());
- assertEquals(ITestService.RESULT_BLUE, component.getInjectedMethodBlue().getString());
- assertEquals(ITestService.RESULT_RED, component.getInjectedMethodRed().getString());
assertEquals(ITestService.RESULT, component.getInjectedFieldProvider().get().getString());
- assertEquals(ITestService.RESULT, component.getInjectedMethodProvider().get().getString());
assertEquals(ITestService.RESULT, component.getInjectedTypeLiteralField().get(
ITestService.RESULT));
- assertEquals(ITestService.RESULT, component.getInjectedTypeLiteralMethod().get(
- ITestService.RESULT));
}
}
Modified: wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/TestComponent.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/TestComponent.java?rev=924049&r1=924048&r2=924049&view=diff
==============================================================================
--- wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/TestComponent.java (original)
+++ wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/TestComponent.java Tue Mar 16 23:30:35 2010
@@ -49,15 +49,12 @@ public class TestComponent extends Compo
@Inject
private Map<String, String> injectedTypeLiteralField;
- private ITestService injectedMethod, injectedMethodRed, injectedMethodBlue;
-
- private Provider<ITestService> injectedMethodProvider;
-
- private Map<String, String> injectedTypeLiteralMethod;
+ private final TestNoComponent noComponent;
public TestComponent(String id)
{
super(id);
+ noComponent = new TestNoComponent();
}
public ITestService getInjectedField()
@@ -75,21 +72,6 @@ public class TestComponent extends Compo
return injectedFieldRed;
}
- public ITestService getInjectedMethod()
- {
- return injectedMethod;
- }
-
- public ITestService getInjectedMethodBlue()
- {
- return injectedMethodBlue;
- }
-
- public ITestService getInjectedMethodRed()
- {
- return injectedMethodRed;
- }
-
public Provider<ITestService> getInjectedFieldProvider()
{
return injectedFieldProvider;
@@ -110,49 +92,15 @@ public class TestComponent extends Compo
return injectedTypeLiteralField;
}
- public Provider<ITestService> getInjectedMethodProvider()
- {
- return injectedMethodProvider;
- }
-
- public Map<String, String> getInjectedTypeLiteralMethod()
- {
- return injectedTypeLiteralMethod;
- }
-
- @Inject
- public void injectProvider(Provider<ITestService> provider)
- {
- injectedMethodProvider = provider;
- }
-
- @Inject
- public void injectService(ITestService service)
- {
- injectedMethod = service;
- }
-
- @Inject
- public void injectServiceBlue(@Blue ITestService service)
- {
- injectedMethodBlue = service;
- }
-
- @Inject
- public void injectServiceRed(@Red ITestService service)
+ @Override
+ protected void onRender()
{
- injectedMethodRed = service;
+ // Do nothing.
}
- @Inject
- public void injectTypeLiteral(Map<String, String> map)
+ public String getNoComponentString()
{
- injectedTypeLiteralMethod = map;
+ return noComponent.getString();
}
- @Override
- protected void onRender()
- {
- // Do nothing.
- }
}
Added: wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/TestNoComponent.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/TestNoComponent.java?rev=924049&view=auto
==============================================================================
--- wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/TestNoComponent.java (added)
+++ wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/TestNoComponent.java Tue Mar 16 23:30:35 2010
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.guice;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.IClusterable;
+import org.apache.wicket.injection.Injector;
+
+import com.google.inject.Inject;
+
+/**
+ * Tests injection of services in classes which do not extend {@link Component}
+ */
+@SuppressWarnings("serial")
+public class TestNoComponent implements IClusterable
+{
+
+ @Inject
+ @Red
+ private ITestService testService;
+
+ /**
+ *
+ * Construct.
+ */
+ public TestNoComponent()
+ {
+ Injector.get().inject(this);
+ }
+
+ /**
+ * @return if injection works should return {@link ITestService#RESULT_RED}
+ */
+ public String getString()
+ {
+ return testService.getString();
+ }
+}
Propchange: wicket/trunk/wicket-guice/src/test/java/org/apache/wicket/guice/TestNoComponent.java
------------------------------------------------------------------------------
svn:mime-type = text/plain