This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.models.impl-1.1.0
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-models-impl.git

commit a6b32c144322c49ff20c34af0111ef985339f556
Author: Justin Edelson <[email protected]>
AuthorDate: Fri Aug 22 15:50:07 2014 +0000

    SLING-3877 - adding a resource path injector. also did some minor 
refactoring to avoid code duplication between injectors.
    
    git-svn-id: 
https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/models/impl@1619848
 13f79535-47bb-0310-9956-ffa450edef68
---
 .../models/impl/injectors/AbstractInjector.java    |  53 ++++++++++
 .../impl/injectors/ResourcePathInjector.java       | 117 +++++++++++++++++++++
 .../impl/injectors/ResourceResolverInjector.java   |  10 +-
 .../models/impl/injectors/ValueMapInjector.java    |  16 +--
 .../models/impl/ResourcePathInjectionTest.java     | 107 +++++++++++++++++++
 .../testmodels/classes/ResourcePathModel.java      |  62 +++++++++++
 6 files changed, 343 insertions(+), 22 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/models/impl/injectors/AbstractInjector.java 
b/src/main/java/org/apache/sling/models/impl/injectors/AbstractInjector.java
new file mode 100644
index 0000000..a472d14
--- /dev/null
+++ b/src/main/java/org/apache/sling/models/impl/injectors/AbstractInjector.java
@@ -0,0 +1,53 @@
+/*
+ * 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.models.impl.injectors;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.adapter.Adaptable;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
+
+/**
+ * Abstract base class for injectors to consolidate common functionality.
+ */
+abstract class AbstractInjector {
+
+    protected ResourceResolver getResourceResolver(Object adaptable) {
+        ResourceResolver resolver = null;
+        if (adaptable instanceof Resource) {
+            resolver = ((Resource) adaptable).getResourceResolver();
+        } else if (adaptable instanceof SlingHttpServletRequest) {
+            resolver = ((SlingHttpServletRequest) 
adaptable).getResourceResolver();
+        }
+        return resolver;
+    }
+
+    protected ValueMap getValueMap(Object adaptable) {
+        if (adaptable instanceof ValueMap) {
+            return (ValueMap) adaptable;
+        } else if (adaptable instanceof Adaptable) {
+            ValueMap map = ((Adaptable) adaptable).adaptTo(ValueMap.class);
+            return map;
+        } else {
+            return null;
+        }
+    }
+
+}
diff --git 
a/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java
 
b/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java
new file mode 100644
index 0000000..3bc08b9
--- /dev/null
+++ 
b/src/main/java/org/apache/sling/models/impl/injectors/ResourcePathInjector.java
@@ -0,0 +1,117 @@
+/*
+ * 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.models.impl.injectors;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Type;
+
+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.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.models.annotations.Path;
+import org.apache.sling.models.annotations.injectorspecific.ResourcePath;
+import org.apache.sling.models.spi.AcceptsNullName;
+import org.apache.sling.models.spi.DisposalCallbackRegistry;
+import org.apache.sling.models.spi.Injector;
+import 
org.apache.sling.models.spi.injectorspecific.AbstractInjectAnnotationProcessor;
+import org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessor;
+import 
org.apache.sling.models.spi.injectorspecific.InjectAnnotationProcessorFactory;
+import org.osgi.framework.Constants;
+
+@Component
+@Service
+@Property(name = Constants.SERVICE_RANKING, intValue = 2500)
+public class ResourcePathInjector extends AbstractInjector implements 
Injector, AcceptsNullName,
+        InjectAnnotationProcessorFactory {
+
+    @Override
+    public String getName() {
+        return "resource-path";
+    }
+
+    @Override
+    public Object getValue(Object adaptable, String name, Type declaredType, 
AnnotatedElement element,
+            DisposalCallbackRegistry callbackRegistry) {
+        String resourcePath = null;
+        Path pathAnnotation = element.getAnnotation(Path.class);
+        if (pathAnnotation != null) {
+            resourcePath = pathAnnotation.value();
+        } else {
+            ResourcePath resourcePathAnnotation = 
element.getAnnotation(ResourcePath.class);
+            if (resourcePathAnnotation != null) {
+                resourcePath = resourcePathAnnotation.path();
+                if (resourcePath.isEmpty()) {
+                    resourcePath = null;
+                }
+            }
+
+            if (resourcePath == null && name != null) {
+                // try to get from value map
+                ValueMap map = getValueMap(adaptable);
+                resourcePath = map.get(name, String.class);
+            }
+        }
+
+        if (resourcePath != null) {
+            ResourceResolver resolver = getResourceResolver(adaptable);
+            if (resolver != null) {
+                return resolver.getResource(resourcePath);
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public InjectAnnotationProcessor createAnnotationProcessor(Object 
adaptable, AnnotatedElement element) {
+        // check if the element has the expected annotation
+        ResourcePath annotation = element.getAnnotation(ResourcePath.class);
+        if (annotation != null) {
+            return new ResourcePathAnnotationProcessor(annotation, adaptable);
+        }
+        return null;
+    }
+
+    private static class ResourcePathAnnotationProcessor extends 
AbstractInjectAnnotationProcessor {
+
+        private final ResourcePath annotation;
+
+        public ResourcePathAnnotationProcessor(ResourcePath annotation, Object 
adaptable) {
+            this.annotation = annotation;
+        }
+
+        @Override
+        public String getName() {
+            // since null is not allowed as default value in annotations, the 
empty string means, the default should be
+            // used!
+            if (annotation.name().isEmpty()) {
+                return null;
+            }
+            return annotation.name();
+        }
+
+        @Override
+        public Boolean isOptional() {
+            return annotation.optional();
+        }
+    }
+
+}
diff --git 
a/src/main/java/org/apache/sling/models/impl/injectors/ResourceResolverInjector.java
 
b/src/main/java/org/apache/sling/models/impl/injectors/ResourceResolverInjector.java
index a84bd89..58c992e 100644
--- 
a/src/main/java/org/apache/sling/models/impl/injectors/ResourceResolverInjector.java
+++ 
b/src/main/java/org/apache/sling/models/impl/injectors/ResourceResolverInjector.java
@@ -24,8 +24,6 @@ import java.lang.reflect.Type;
 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.api.SlingHttpServletRequest;
-import org.apache.sling.api.resource.Resource;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
 import org.apache.sling.models.spi.Injector;
 import org.osgi.framework.Constants;
@@ -33,7 +31,7 @@ import org.osgi.framework.Constants;
 @Component
 @Service
 @Property(name = Constants.SERVICE_RANKING, intValue = 900)
-public class ResourceResolverInjector implements Injector {
+public class ResourceResolverInjector extends AbstractInjector implements 
Injector {
 
     private static final String NAME_RESOURCE_RESOLVER = "resourceResolver";
 
@@ -46,11 +44,7 @@ public class ResourceResolverInjector implements Injector {
     public Object getValue(Object adaptable, String name, Type declaredType, 
AnnotatedElement element,
             DisposalCallbackRegistry callbackRegistry) {
         if (NAME_RESOURCE_RESOLVER.equals(name)) {
-            if (adaptable instanceof Resource) {
-                return ((Resource) adaptable).getResourceResolver();
-            } else if (adaptable instanceof SlingHttpServletRequest) {
-                return ((SlingHttpServletRequest) 
adaptable).getResourceResolver();
-            }
+            return getResourceResolver(adaptable);
         }
         return null;
     }
diff --git 
a/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java 
b/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java
index 9c4a123..bda12b6 100644
--- a/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java
+++ b/src/main/java/org/apache/sling/models/impl/injectors/ValueMapInjector.java
@@ -30,7 +30,6 @@ 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.api.SlingHttpServletRequest;
-import org.apache.sling.api.adapter.Adaptable;
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
 import org.apache.sling.models.spi.DisposalCallbackRegistry;
@@ -45,7 +44,7 @@ import org.slf4j.LoggerFactory;
 @Component
 @Service
 @Property(name = Constants.SERVICE_RANKING, intValue = 2000)
-public class ValueMapInjector implements Injector, 
InjectAnnotationProcessorFactory {
+public class ValueMapInjector extends AbstractInjector implements Injector, 
InjectAnnotationProcessorFactory {
 
     private static final Logger log = 
LoggerFactory.getLogger(ValueMapInjector.class);
 
@@ -56,7 +55,7 @@ public class ValueMapInjector implements Injector, 
InjectAnnotationProcessorFact
 
     public Object getValue(Object adaptable, String name, Type type, 
AnnotatedElement element,
             DisposalCallbackRegistry callbackRegistry) {
-        ValueMap map = getMap(adaptable);
+        ValueMap map = getValueMap(adaptable);
         if (map == null) {
             return null;
         } else if (type instanceof Class<?>) {
@@ -112,17 +111,6 @@ public class ValueMapInjector implements Injector, 
InjectAnnotationProcessorFact
         }
     }
 
-    private ValueMap getMap(Object adaptable) {
-        if (adaptable instanceof ValueMap) {
-            return (ValueMap) adaptable;
-        } else if (adaptable instanceof Adaptable) {
-            ValueMap map = ((Adaptable) adaptable).adaptTo(ValueMap.class);
-            return map;
-        } else {
-            return null;
-        }
-    }
-
     private Object unwrapArray(Object wrapperArray, Class<?> primitiveType) {
         int length = Array.getLength(wrapperArray);
         Object primitiveArray = Array.newInstance(primitiveType, length);
diff --git 
a/src/test/java/org/apache/sling/models/impl/ResourcePathInjectionTest.java 
b/src/test/java/org/apache/sling/models/impl/ResourcePathInjectionTest.java
new file mode 100644
index 0000000..8280584
--- /dev/null
+++ b/src/test/java/org/apache/sling/models/impl/ResourcePathInjectionTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.models.impl;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.api.wrappers.ValueMapDecorator;
+import org.apache.sling.models.impl.injectors.ResourcePathInjector;
+import org.apache.sling.models.impl.injectors.SelfInjector;
+import org.apache.sling.models.impl.injectors.ValueMapInjector;
+import org.apache.sling.models.testmodels.classes.ResourcePathModel;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentContext;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ResourcePathInjectionTest {
+
+    @Mock
+    private ComponentContext componentCtx;
+
+    @Mock
+    private BundleContext bundleContext;
+
+    private ModelAdapterFactory factory;
+
+    @Mock
+    private Resource adaptable;
+
+    @Mock
+    private Resource byPathResource;
+
+    @Mock
+    private Resource byPathResource2;
+
+    @Mock
+    private Resource byPropertyValueResource;
+
+    @Mock
+    private Resource byPropertyValueResource2;
+
+    @Mock
+    private ResourceResolver resourceResolver;
+
+    @Before
+    public void setup() {
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put("propertyContainingAPath", "/some/other/path");
+        map.put("anotherPropertyContainingAPath", "/some/other/path2");
+
+        ValueMap properties = new ValueMapDecorator(map);
+
+        when(componentCtx.getBundleContext()).thenReturn(bundleContext);
+        when(adaptable.getResourceResolver()).thenReturn(resourceResolver);
+        when(adaptable.adaptTo(ValueMap.class)).thenReturn(properties);
+
+        
when(resourceResolver.getResource("/some/path")).thenReturn(byPathResource);
+        
when(resourceResolver.getResource("/some/path2")).thenReturn(byPathResource2);
+        
when(resourceResolver.getResource("/some/other/path")).thenReturn(byPropertyValueResource);
+        
when(resourceResolver.getResource("/some/other/path2")).thenReturn(byPropertyValueResource2);
+
+        factory = new ModelAdapterFactory();
+        factory.activate(componentCtx);
+        factory.bindInjector(new SelfInjector(), new ServicePropertiesMap(1, 
Integer.MAX_VALUE));
+        factory.bindInjector(new ValueMapInjector(), new 
ServicePropertiesMap(2, 2000));
+        factory.bindInjector(new ResourcePathInjector(), new 
ServicePropertiesMap(3, 2500));
+        factory.bindInjectAnnotationProcessorFactory(new 
ResourcePathInjector(), new ServicePropertiesMap(3, 2500));
+    }
+
+    @Test
+    public void testPathInjection() {
+        ResourcePathModel model = factory.getAdapter(adaptable, 
ResourcePathModel.class);
+        assertNotNull(model);
+        assertEquals(byPathResource, model.getFromPath());
+        assertEquals(byPropertyValueResource, model.getByDerefProperty());
+        assertEquals(byPathResource2, model.getFromPath2());
+        assertEquals(byPropertyValueResource2, model.getByDerefProperty2());
+    }
+
+}
\ No newline at end of file
diff --git 
a/src/test/java/org/apache/sling/models/testmodels/classes/ResourcePathModel.java
 
b/src/test/java/org/apache/sling/models/testmodels/classes/ResourcePathModel.java
new file mode 100644
index 0000000..d18d4fe
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/models/testmodels/classes/ResourcePathModel.java
@@ -0,0 +1,62 @@
+/*
+ * 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.models.testmodels.classes;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.models.annotations.Model;
+import org.apache.sling.models.annotations.Path;
+import org.apache.sling.models.annotations.injectorspecific.ResourcePath;
+
+@Model(adaptables = Resource.class)
+public class ResourcePathModel {
+
+    @Inject
+    @Path("/some/path")
+    private Resource fromPath;
+
+    @Inject
+    @Named("propertyContainingAPath")
+    private Resource derefProperty;
+
+    @ResourcePath(path = "/some/path2")
+    private Resource fromPath2;
+
+    @ResourcePath(name = "anotherPropertyContainingAPath")
+    private Resource derefProperty2;
+
+    public Resource getFromPath() {
+        return fromPath;
+    }
+
+    public Resource getByDerefProperty() {
+        return derefProperty;
+    }
+
+    public Resource getFromPath2() {
+        return fromPath2;
+    }
+
+    public Resource getByDerefProperty2() {
+        return derefProperty2;
+    }
+
+}

-- 
To stop receiving notification emails like this one, please contact
"[email protected]" <[email protected]>.

Reply via email to