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 ead97d031c7def96ca0836cf9ecba2dff72d3d05 Author: Justin Edelson <[email protected]> AuthorDate: Sun Aug 24 19:09:39 2014 +0000 SLING-3715 - adding sling object injector. Thanks to Stefan for the patch! git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/models/impl@1620175 13f79535-47bb-0310-9956-ffa450edef68 --- .../models/impl/injectors/SlingObjectInjector.java | 196 +++++++++++++++++++++ .../injectors/SlingObjectInjectorRequestTest.java | 120 +++++++++++++ .../SlingObjectInjectorResourceResolverTest.java | 87 +++++++++ .../injectors/SlingObjectInjectorResourceTest.java | 102 +++++++++++ 4 files changed, 505 insertions(+) diff --git a/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java b/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java new file mode 100644 index 0000000..79e081b --- /dev/null +++ b/src/main/java/org/apache/sling/models/impl/injectors/SlingObjectInjector.java @@ -0,0 +1,196 @@ +/* + * 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 javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +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.SlingHttpServletResponse; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.scripting.SlingBindings; +import org.apache.sling.api.scripting.SlingScriptHelper; +import org.apache.sling.models.annotations.injectorspecific.SlingObject; +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; + +/** + * Injects common Sling objects that can be derived from either a SlingHttpServletRequest, a ResourceResolver or a + * Resource. + * The injection is class-based. + * <p> + * Supports the following objects: + * <table> + * <tr> + * <th style="text-align:left">Class</th> + * <th style="text-align:left">Description</th> + * <th style="text-align:center">Request</th> + * <th style="text-align:center">ResourceResolver</th> + * <th style="text-align:center">Resource</th> + * </tr> + * <tr style="background-color:#eee"> + * <td>{@link ResourceResolver}</td> + * <td>Resource resolver</td> + * <td style="text-align:center">X</td> + * <td style="text-align:center">X</td> + * <td style="text-align:center">X</td> + * </tr> + * <tr> + * <td>{@link Resource}</td> + * <td>Resource</td> + * <td style="text-align:center">X</td> + * <td></td> + * <td style="text-align:center">X</td> + * </tr> + * <tr style="background-color:#eee"> + * <td>{@link SlingHttpServletRequest}</td> + * <td>Sling request</td> + * <td style="text-align:center">X</td> + * <td></td> + * <td></td> + * </tr> + * <tr> + * <td>{@link SlingHttpServletResponse}</td> + * <td>Sling response</td> + * <td style="text-align:center">X</td> + * <td></td> + * <td></td> + * </tr> + * <tr style="background-color:#eee"> + * <td>{@link SlingScriptHelper}</td> + * <td>Sling script helper</td> + * <td style="text-align:center">X</td> + * <td></td> + * <td></td> + * </tr> + * </table> + */ +@Component +@Service +@Property(name = Constants.SERVICE_RANKING, intValue = Integer.MAX_VALUE) +public final class SlingObjectInjector implements Injector, InjectAnnotationProcessorFactory, AcceptsNullName { + + /** + * Injector name + */ + public static final String NAME = "sling-object"; + + @Override + public String getName() { + return NAME; + } + + @Override + public Object getValue(final Object adaptable, final String name, final Type type, final AnnotatedElement element, + final DisposalCallbackRegistry callbackRegistry) { + + // only class types are supported + if (!(type instanceof Class<?>)) { + return null; + } + Class<?> requestedClass = (Class<?>) type; + + // validate input + if (adaptable instanceof SlingHttpServletRequest) { + SlingHttpServletRequest request = (SlingHttpServletRequest) adaptable; + if (requestedClass.equals(ResourceResolver.class)) { + return request.getResourceResolver(); + } + if (requestedClass.equals(Resource.class) && element.isAnnotationPresent(SlingObject.class)) { + return request.getResource(); + } + if (requestedClass.equals(SlingHttpServletRequest.class) || requestedClass.equals(HttpServletRequest.class)) { + return request; + } + if (requestedClass.equals(SlingHttpServletResponse.class) + || requestedClass.equals(HttpServletResponse.class)) { + return getSlingHttpServletResponse(request); + } + if (requestedClass.equals(SlingScriptHelper.class)) { + return getSlingScriptHelper(request); + } + } else if (adaptable instanceof ResourceResolver) { + ResourceResolver resourceResolver = (ResourceResolver) adaptable; + if (requestedClass.equals(ResourceResolver.class)) { + return resourceResolver; + } + } else if (adaptable instanceof Resource) { + Resource resource = (Resource) adaptable; + if (requestedClass.equals(ResourceResolver.class)) { + return resource.getResourceResolver(); + } + if (requestedClass.equals(Resource.class) && element.isAnnotationPresent(SlingObject.class)) { + return resource; + } + } + + return null; + } + + private SlingScriptHelper getSlingScriptHelper(final SlingHttpServletRequest request) { + SlingBindings bindings = (SlingBindings) request.getAttribute(SlingBindings.class.getName()); + if (bindings != null) { + return bindings.getSling(); + } + return null; + } + + private SlingHttpServletResponse getSlingHttpServletResponse(final SlingHttpServletRequest request) { + SlingScriptHelper scriptHelper = getSlingScriptHelper(request); + if (scriptHelper != null) { + return scriptHelper.getResponse(); + } + return null; + } + + @Override + public InjectAnnotationProcessor createAnnotationProcessor(final Object adaptable, final AnnotatedElement element) { + // check if the element has the expected annotation + SlingObject annotation = element.getAnnotation(SlingObject.class); + if (annotation != null) { + return new SlingObjectAnnotationProcessor(annotation); + } + return null; + } + + private static class SlingObjectAnnotationProcessor extends AbstractInjectAnnotationProcessor { + + private final SlingObject annotation; + + public SlingObjectAnnotationProcessor(final SlingObject annotation) { + this.annotation = annotation; + } + + @Override + public Boolean isOptional() { + return this.annotation.optional(); + } + } + +} diff --git a/src/test/java/org/apache/sling/models/impl/injectors/SlingObjectInjectorRequestTest.java b/src/test/java/org/apache/sling/models/impl/injectors/SlingObjectInjectorRequestTest.java new file mode 100644 index 0000000..89e72fd --- /dev/null +++ b/src/test/java/org/apache/sling/models/impl/injectors/SlingObjectInjectorRequestTest.java @@ -0,0 +1,120 @@ +/* + * 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 static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import java.lang.reflect.AnnotatedElement; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.scripting.SlingBindings; +import org.apache.sling.api.scripting.SlingScriptHelper; +import org.apache.sling.models.annotations.injectorspecific.SlingObject; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +@SuppressWarnings("javadoc") +public class SlingObjectInjectorRequestTest { + + private final SlingObjectInjector injector = new SlingObjectInjector(); + + @Mock + private AnnotatedElement annotatedElement; + @Mock + private SlingHttpServletRequest request; + @Mock + private SlingHttpServletResponse response; + @Mock + private SlingScriptHelper scriptHelper; + @Mock + private ResourceResolver resourceResolver; + @Mock + private Resource resource; + + @Before + public void setUp() { + SlingBindings bindings = new SlingBindings(); + bindings.put(SlingBindings.SLING, this.scriptHelper); + when(this.request.getResourceResolver()).thenReturn(this.resourceResolver); + when(this.request.getResource()).thenReturn(this.resource); + when(this.request.getAttribute(SlingBindings.class.getName())).thenReturn(bindings); + when(this.scriptHelper.getResponse()).thenReturn(this.response); + } + + @Test + public void testResourceResolver() { + Object result = this.injector.getValue(this.request, null, ResourceResolver.class, this.annotatedElement, null); + assertSame(this.resourceResolver, result); + } + + @Test + public void testResource() { + Object result = this.injector.getValue(this.request, null, Resource.class, this.annotatedElement, null); + assertNull(result); + + when(annotatedElement.isAnnotationPresent(SlingObject.class)).thenReturn(true); + result = this.injector.getValue(this.request, null, Resource.class, this.annotatedElement, null); + assertSame(resource, result); + } + + @Test + public void testRequest() { + Object result = this.injector.getValue(this.request, null, SlingHttpServletRequest.class, + this.annotatedElement, null); + assertSame(this.request, result); + + result = this.injector.getValue(this.request, null, HttpServletRequest.class, this.annotatedElement, null); + assertSame(this.request, result); + } + + @Test + public void testResponse() { + Object result = this.injector.getValue(this.request, null, SlingHttpServletResponse.class, + this.annotatedElement, null); + assertSame(this.response, result); + + result = this.injector.getValue(this.request, null, HttpServletResponse.class, this.annotatedElement, null); + assertSame(this.response, result); + } + + @Test + public void testScriptHelper() { + Object result = this.injector + .getValue(this.request, null, SlingScriptHelper.class, this.annotatedElement, null); + assertSame(this.scriptHelper, result); + } + + @Test + public void testInvalid() { + Object result = this.injector.getValue(this, null, SlingScriptHelper.class, this.annotatedElement, null); + assertNull(result); + } + +} diff --git a/src/test/java/org/apache/sling/models/impl/injectors/SlingObjectInjectorResourceResolverTest.java b/src/test/java/org/apache/sling/models/impl/injectors/SlingObjectInjectorResourceResolverTest.java new file mode 100644 index 0000000..c9338fa --- /dev/null +++ b/src/test/java/org/apache/sling/models/impl/injectors/SlingObjectInjectorResourceResolverTest.java @@ -0,0 +1,87 @@ +/* + * 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 static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; + +import java.lang.reflect.AnnotatedElement; + +import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.scripting.SlingScriptHelper; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +@SuppressWarnings("javadoc") +public class SlingObjectInjectorResourceResolverTest { + + private final SlingObjectInjector injector = new SlingObjectInjector(); + + @Mock + private AnnotatedElement annotatedElement; + @Mock + private ResourceResolver resourceResolver; + + @Test + public void testResourceResolver() { + Object result = this.injector.getValue(this.resourceResolver, null, ResourceResolver.class, + this.annotatedElement, null); + assertSame(this.resourceResolver, result); + } + + @Test + public void testResource() { + Object result = this.injector + .getValue(this.resourceResolver, null, Resource.class, this.annotatedElement, null); + assertNull(result); + } + + @Test + public void testRequest() { + Object result = this.injector.getValue(this.resourceResolver, null, SlingHttpServletResponse.class, + this.annotatedElement, null); + assertNull(result); + } + + @Test + public void testResponse() { + Object result = this.injector.getValue(this.resourceResolver, null, SlingHttpServletResponse.class, + this.annotatedElement, null); + assertNull(result); + } + + @Test + public void testScriptHelper() { + Object result = this.injector.getValue(this.resourceResolver, null, SlingScriptHelper.class, + this.annotatedElement, null); + assertNull(result); + } + + @Test + public void testInvalid() { + Object result = this.injector.getValue(this, null, SlingScriptHelper.class, this.annotatedElement, null); + assertNull(result); + } + +} diff --git a/src/test/java/org/apache/sling/models/impl/injectors/SlingObjectInjectorResourceTest.java b/src/test/java/org/apache/sling/models/impl/injectors/SlingObjectInjectorResourceTest.java new file mode 100644 index 0000000..7ffb698 --- /dev/null +++ b/src/test/java/org/apache/sling/models/impl/injectors/SlingObjectInjectorResourceTest.java @@ -0,0 +1,102 @@ +/* + * 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 static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.mockito.Mockito.when; + +import java.lang.reflect.AnnotatedElement; + +import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.api.scripting.SlingScriptHelper; +import org.apache.sling.models.annotations.injectorspecific.SlingObject; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +@SuppressWarnings("javadoc") +public class SlingObjectInjectorResourceTest { + + private final SlingObjectInjector injector = new SlingObjectInjector(); + + @Mock + private AnnotatedElement annotatedElement; + + @Mock + private ResourceResolver resourceResolver; + + @Mock + private Resource resource; + + @Before + public void setUp() { + when(this.resource.getResourceResolver()).thenReturn(this.resourceResolver); + } + + @Test + public void testResourceResolver() { + Object result = this.injector + .getValue(this.resource, null, ResourceResolver.class, this.annotatedElement, null); + assertSame(this.resourceResolver, result); + } + + @Test + public void testResource() { + Object result = this.injector.getValue(this.resource, null, Resource.class, this.annotatedElement, null); + assertNull(result); + + when(annotatedElement.isAnnotationPresent(SlingObject.class)).thenReturn(true); + result = this.injector.getValue(this.resource, null, Resource.class, this.annotatedElement, null); + assertSame(resource, result); + } + + @Test + public void testRequest() { + Object result = this.injector.getValue(this.resource, null, SlingHttpServletResponse.class, + this.annotatedElement, null); + assertNull(result); + } + + @Test + public void testResponse() { + Object result = this.injector.getValue(this.resource, null, SlingHttpServletResponse.class, + this.annotatedElement, null); + assertNull(result); + } + + @Test + public void testScriptHelper() { + Object result = this.injector.getValue(this.resource, null, SlingScriptHelper.class, this.annotatedElement, + null); + assertNull(result); + } + + @Test + public void testInvalid() { + Object result = this.injector.getValue(this, null, SlingScriptHelper.class, this.annotatedElement, null); + assertNull(result); + } + +} -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
