Author: justin
Date: Mon Dec 23 16:27:50 2013
New Revision: 1553145
URL: http://svn.apache.org/r1553145
Log:
adding a source annotation which ties a specific injection point to a specific
injector. also works as a meta annotation, see e.g. @Filter
Added:
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Source.java
- copied, changed from r1553144,
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/test/java/org/apache/sling/yamf/impl/MultipleInjectorTest.java
Modified:
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/YamfAdapterFactory.java
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/BindingsInjector.java
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/OSGiServiceInjector.java
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/RequestAttributeInjector.java
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/ValueMapInjector.java
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/spi/Injector.java
Modified:
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java?rev=1553145&r1=1553144&r2=1553145&view=diff
==============================================================================
---
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java
(original)
+++
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java
Mon Dec 23 16:27:50 2013
@@ -26,6 +26,7 @@ import java.lang.annotation.Target;
*/
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
+@Source("osgi-services")
public @interface Filter {
public String value();
Copied:
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Source.java
(from r1553144,
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java)
URL:
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Source.java?p2=sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Source.java&p1=sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java&r1=1553144&r2=1553145&rev=1553145&view=diff
==============================================================================
---
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Filter.java
(original)
+++
sling/whiteboard/justin/yamf/org.apache.sling.yamf.api/src/main/java/org/apache/sling/yamf/annotations/Source.java
Mon Dec 23 16:27:50 2013
@@ -22,12 +22,13 @@ import java.lang.annotation.RetentionPol
import java.lang.annotation.Target;
/**
- * Provide a filter on an @Inject.
+ * Annotation which indicates the specific injector which will populate this
injection.
+ * Can also be used as a meta-annotation to declare that some other annotation
implies
+ * a source.
*/
-@Target({ ElementType.FIELD, ElementType.METHOD })
+@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
-public @interface Filter {
-
- public String value();
+public @interface Source {
+ String value();
}
Modified:
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/YamfAdapterFactory.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/YamfAdapterFactory.java?rev=1553145&r1=1553144&r2=1553145&view=diff
==============================================================================
---
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/YamfAdapterFactory.java
(original)
+++
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/YamfAdapterFactory.java
Mon Dec 23 16:27:50 2013
@@ -16,6 +16,7 @@
*/
package org.apache.sling.yamf.impl;
+import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
@@ -49,8 +50,8 @@ import org.apache.sling.yamf.annotations
import org.apache.sling.yamf.annotations.Model;
import org.apache.sling.yamf.annotations.Optional;
import org.apache.sling.yamf.annotations.Projection;
+import org.apache.sling.yamf.annotations.Source;
import org.apache.sling.yamf.spi.Injector;
-import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
@@ -157,13 +158,16 @@ public class YamfAdapterFactory implemen
Iterator<Method> it = injectableMethods.iterator();
while (it.hasNext()) {
Method method = it.next();
- String name = getName(method);
- Type returnType =
mapPrimitiveClasses(method.getGenericReturnType());
- Object injectionAdaptable = getAdaptable(adaptable, method);
- if (injectionAdaptable != null) {
- Object value = injector.getValue(injectionAdaptable, name,
returnType, method);
- if (setMethod(method, methods, value)) {
- it.remove();
+ String source = getSource(method);
+ if (source == null || source.equals(injector.getName())) {
+ String name = getName(method);
+ Type returnType =
mapPrimitiveClasses(method.getGenericReturnType());
+ Object injectionAdaptable = getAdaptable(adaptable,
method);
+ if (injectionAdaptable != null) {
+ Object value = injector.getValue(injectionAdaptable,
name, returnType, method);
+ if (setMethod(method, methods, value)) {
+ it.remove();
+ }
}
}
}
@@ -202,6 +206,21 @@ public class YamfAdapterFactory implemen
}
}
+ private String getSource(AnnotatedElement element) {
+ Source source = element.getAnnotation(Source.class);
+ if (source != null) {
+ return source.value();
+ } else {
+ for (Annotation ann : element.getAnnotations()) {
+ source = ann.annotationType().getAnnotation(Source.class);
+ if (source != null) {
+ return source.value();
+ }
+ }
+ }
+ return null;
+ }
+
private <AdapterType> AdapterType createObject(Object adaptable,
Class<AdapterType> type)
throws InstantiationException, IllegalAccessException {
Set<Field> injectableFields = collectInjectableFields(type);
@@ -212,13 +231,16 @@ public class YamfAdapterFactory implemen
Iterator<Field> it = injectableFields.iterator();
while (it.hasNext()) {
Field field = it.next();
- String name = getName(field);
- Type fieldType = mapPrimitiveClasses(field.getGenericType());
- Object injectionAdaptable = getAdaptable(adaptable, field);
- if (injectionAdaptable != null) {
- Object value = injector.getValue(injectionAdaptable, name,
fieldType, field);
- if (setField(field, object, value)) {
- it.remove();
+ String source = getSource(field);
+ if (source == null || source.equals(injector.getName())) {
+ String name = getName(field);
+ Type fieldType =
mapPrimitiveClasses(field.getGenericType());
+ Object injectionAdaptable = getAdaptable(adaptable, field);
+ if (injectionAdaptable != null) {
+ Object value = injector.getValue(injectionAdaptable,
name, fieldType, field);
+ if (setField(field, object, value)) {
+ it.remove();
+ }
}
}
}
Modified:
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/BindingsInjector.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/BindingsInjector.java?rev=1553145&r1=1553144&r2=1553145&view=diff
==============================================================================
---
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/BindingsInjector.java
(original)
+++
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/BindingsInjector.java
Mon Dec 23 16:27:50 2013
@@ -34,6 +34,11 @@ public class BindingsInjector implements
private static final Logger log =
LoggerFactory.getLogger(BindingsInjector.class);
+ @Override
+ public String getName() {
+ return "script-bindings";
+ }
+
private static Object getValue(SlingBindings bindings, String name,
Class<?> type) {
Object value = bindings.get(name);
if (type.isInstance(value)) {
Modified:
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/OSGiServiceInjector.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/OSGiServiceInjector.java?rev=1553145&r1=1553144&r2=1553145&view=diff
==============================================================================
---
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/OSGiServiceInjector.java
(original)
+++
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/OSGiServiceInjector.java
Mon Dec 23 16:27:50 2013
@@ -27,8 +27,10 @@ import java.util.List;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.yamf.annotations.Filter;
+import org.apache.sling.yamf.annotations.Source;
import org.apache.sling.yamf.spi.Injector;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
@@ -44,6 +46,11 @@ public class OSGiServiceInjector impleme
private static final Logger log =
LoggerFactory.getLogger(OSGiServiceInjector.class);
private BundleContext bundleContext;
+
+ @Override
+ public String getName() {
+ return "osgi-services";
+ }
@Activate
public void activate(ComponentContext ctx) {
@@ -98,9 +105,7 @@ public class OSGiServiceInjector impleme
private Object getValue(Type type, String filterString) {
if (type instanceof Class) {
Class<?> injectedClass = (Class<?>) type;
- if (injectedClass == BundleContext.class) {
- return bundleContext;
- } else if (injectedClass.isArray()) {
+ if (injectedClass.isArray()) {
Object[] services =
getServices(injectedClass.getComponentType(), filterString);
Object arr =
Array.newInstance(injectedClass.getComponentType(), services.length);
for (int i = 0; i < services.length; i++) {
Modified:
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/RequestAttributeInjector.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/RequestAttributeInjector.java?rev=1553145&r1=1553144&r2=1553145&view=diff
==============================================================================
---
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/RequestAttributeInjector.java
(original)
+++
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/RequestAttributeInjector.java
Mon Dec 23 16:27:50 2013
@@ -22,7 +22,9 @@ import java.lang.reflect.Type;
import javax.servlet.ServletRequest;
import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.yamf.annotations.Source;
import org.apache.sling.yamf.spi.Injector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,6 +34,11 @@ import org.slf4j.LoggerFactory;
public class RequestAttributeInjector implements Injector {
private static final Logger log =
LoggerFactory.getLogger(RequestAttributeInjector.class);
+
+ @Override
+ public String getName() {
+ return "request-attributes";
+ }
@Override
public Object getValue(Object adaptable, String name, Type declaredType,
AnnotatedElement element) {
Modified:
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/ValueMapInjector.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/ValueMapInjector.java?rev=1553145&r1=1553144&r2=1553145&view=diff
==============================================================================
---
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/ValueMapInjector.java
(original)
+++
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/impl/injectors/ValueMapInjector.java
Mon Dec 23 16:27:50 2013
@@ -32,6 +32,11 @@ import org.slf4j.LoggerFactory;
public class ValueMapInjector implements Injector {
private static final Logger log =
LoggerFactory.getLogger(ValueMapInjector.class);
+
+ @Override
+ public String getName() {
+ return "valuemap";
+ }
public Object getValue(Object adaptable, String name, Type type,
AnnotatedElement element) {
ValueMap map = getMap(adaptable);
Modified:
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/spi/Injector.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/spi/Injector.java?rev=1553145&r1=1553144&r2=1553145&view=diff
==============================================================================
---
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/spi/Injector.java
(original)
+++
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/main/java/org/apache/sling/yamf/spi/Injector.java
Mon Dec 23 16:27:50 2013
@@ -21,5 +21,7 @@ import java.lang.reflect.Type;
public interface Injector {
+ String getName();
+
Object getValue(Object adaptable, String name, Type declaredType,
AnnotatedElement element);
}
\ No newline at end of file
Added:
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/test/java/org/apache/sling/yamf/impl/MultipleInjectorTest.java
URL:
http://svn.apache.org/viewvc/sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/test/java/org/apache/sling/yamf/impl/MultipleInjectorTest.java?rev=1553145&view=auto
==============================================================================
---
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/test/java/org/apache/sling/yamf/impl/MultipleInjectorTest.java
(added)
+++
sling/whiteboard/justin/yamf/org.apache.sling.yamf.impl/src/test/java/org/apache/sling/yamf/impl/MultipleInjectorTest.java
Mon Dec 23 16:27:50 2013
@@ -0,0 +1,118 @@
+/*
+ * 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.sling.yamf.impl;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Collections;
+
+import javax.inject.Inject;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.scripting.SlingBindings;
+import org.apache.sling.yamf.annotations.Model;
+import org.apache.sling.yamf.annotations.Source;
+import org.apache.sling.yamf.impl.injectors.BindingsInjector;
+import org.apache.sling.yamf.impl.injectors.RequestAttributeInjector;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.osgi.framework.Constants;
+
+@RunWith(MockitoJUnitRunner.class)
+public class MultipleInjectorTest {
+
+ @Spy
+ private BindingsInjector bindingsInjector;
+
+ @Spy
+ private RequestAttributeInjector attributesInjector;
+
+ @Mock
+ private SlingHttpServletRequest request;
+
+ private YamfAdapterFactory factory;
+
+ private SlingBindings bindings;
+
+ @Before
+ public void setup() {
+ bindings = new SlingBindings();
+
+ factory = new YamfAdapterFactory();
+ factory.bindInjector(bindingsInjector, Collections.<String, Object>
singletonMap(Constants.SERVICE_ID, 2L));
+ factory.bindInjector(attributesInjector,
+ Collections.<String, Object>
singletonMap(Constants.SERVICE_ID, 1L));
+
+
when(request.getAttribute(SlingBindings.class.getName())).thenReturn(bindings);
+ }
+
+ @Test
+ public void testInjectorOrder() {
+ String bindingsValue = "bindings value";
+ bindings.put("firstAttribute", bindingsValue);
+
+ String attributeValue = "attribute value";
+
when(request.getAttribute("firstAttribute")).thenReturn(attributeValue);
+
+ ForTwoInjectors obj = factory.getAdapter(request,
ForTwoInjectors.class);
+
+ assertNotNull(obj);
+ assertEquals(obj.firstAttribute, bindingsValue);
+
+ verifyNoMoreInteractions(attributesInjector);
+ }
+
+ @Test
+ public void testInjectorOrderWithSource() {
+ String bindingsValue = "bindings value";
+ bindings.put("firstAttribute", bindingsValue);
+
+ String attributeValue = "attribute value";
+
when(request.getAttribute("firstAttribute")).thenReturn(attributeValue);
+
+ ForTwoInjectorsWithSource obj = factory.getAdapter(request,
ForTwoInjectorsWithSource.class);
+
+ assertNotNull(obj);
+ assertEquals(obj.firstAttribute, attributeValue);
+
+ verify(bindingsInjector).getName();
+ verifyNoMoreInteractions(bindingsInjector);
+ }
+
+ @Model(adaptables = SlingHttpServletRequest.class)
+ public static class ForTwoInjectors {
+
+ @Inject
+ private String firstAttribute;
+
+ }
+
+ @Model(adaptables = SlingHttpServletRequest.class)
+ public static class ForTwoInjectorsWithSource {
+
+ @Inject
+ @Source("request-attributes")
+ private String firstAttribute;
+
+ }
+
+}