Author: bdelacretaz Date: Mon Jul 1 16:19:04 2013 New Revision: 1498546 URL: http://svn.apache.org/r1498546 Log: SLING-2938 - AdapterMethodsManagerImpl ignores invalid Methods
Added: sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImplTest.java (with props) Modified: sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/main/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImpl.java sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodManagerIT.java sling/whiteboard/bdelacretaz/adapter-methods/sling-api/src/main/java/org/apache/sling/api/annotations/Adapter.java Modified: sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/main/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImpl.java URL: http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/main/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImpl.java?rev=1498546&r1=1498545&r2=1498546&view=diff ============================================================================== --- sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/main/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImpl.java (original) +++ sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/main/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImpl.java Mon Jul 1 16:19:04 2013 @@ -97,6 +97,14 @@ public class AdapterMethodsManagerImpl { provider = methodProvider; method = m; + try { + validateAdapterMethod(m); + } catch(IllegalArgumentException iae) { + log.error("Invalid Adapter method, will be ignored: " + m, iae); + serviceRegistration = null; + return; + } + final Class<?> fromClass = m.getParameterTypes()[0]; final Class<?> toClass = m.getReturnType(); final Dictionary<String, Object> props = new Hashtable<String, Object>(); @@ -139,6 +147,24 @@ public class AdapterMethodsManagerImpl { } + /** Verify that Method m fullfills the criteria for being an adapter method */ + static void validateAdapterMethod(Method m) throws IllegalArgumentException { + // non-void return type + if(void.class.equals(m.getReturnType())) { + throw new IllegalArgumentException("Adapter method cannot have void return type: " + m); + } + + // single argument + if(m.getParameterTypes().length != 1) { + throw new IllegalArgumentException("Adapter method must take a single argument: " + m); + } + + // no checked exceptions declared + if(m.getExceptionTypes().length > 0) { + throw new IllegalArgumentException("Adapter method must not throw any exceptions: " + m); + } + } + @Activate public void activate(ComponentContext ctx) { bundleContext = ctx.getBundleContext(); Modified: sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodManagerIT.java URL: http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodManagerIT.java?rev=1498546&r1=1498545&r2=1498546&view=diff ============================================================================== --- sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodManagerIT.java (original) +++ sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodManagerIT.java Mon Jul 1 16:19:04 2013 @@ -93,6 +93,31 @@ public class AdapterMethodManagerIT { } } + public static class ProviderWithInvalidMethods implements AdapterMethodsProvider { + + @Adapter + public Long adapt(TestAdaptable src) { + return new Long(src.value + 1); + } + + @Adapter + public void badVoid(TestAdaptable src) { + } + + @Adapter + public Long badTwoArgs(TestAdaptable src, int i) { + return new Long(src.value + 2); + } + + @Adapter + public Long badThrows(TestAdaptable src, int i) throws IllegalArgumentException { + if(src.value < 0) { + throw new IllegalArgumentException(); + } + return new Long(src.value + 3); + } + } + @org.ops4j.pax.exam.Configuration public Option[] config() { final String paxLogLevel = System.getProperty("pax.exam.log.level", "INFO"); @@ -157,6 +182,19 @@ public class AdapterMethodManagerIT { assertNull("Expecting no URL adaptation", t.adaptTo(URL.class)); } + public void testInvalidMethodsIgnored() { + registerProvider(new ProviderWithInvalidMethods()); + + final long value = System.currentTimeMillis(); + final TestAdaptable t = new TestAdaptable(value); + final Long result = t.adaptTo(Long.class); + + assertNotNull("Expecting non-null adapted Long", result); + assertEquals("Expecting correct adapted value", value + 1, result.longValue()); + assertNull("Expecting no Integer adaptation", t.adaptTo(Integer.class)); + assertNull("Expecting no URL adaptation", t.adaptTo(URL.class)); + } + @Test public void testMultipleAdapters() throws MalformedURLException { registerProvider(new SingleMethodProvider()); Added: sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImplTest.java URL: http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImplTest.java?rev=1498546&view=auto ============================================================================== --- sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImplTest.java (added) +++ sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImplTest.java Mon Jul 1 16:19:04 2013 @@ -0,0 +1,89 @@ +/* + * 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.adapter.internal; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.lang.reflect.Method; + +import org.apache.sling.api.annotations.Adapter; +import org.junit.Test; + +public class AdapterMethodsManagerImplTest { + + private static class GoodAdapterMethodsProvider { + @Adapter + public String toString(String s) { + return null; + } + + @Adapter + public Integer toInteger(String s) { + return null; + } + } + + private static class BadAdapterMethodsProvider { + @Adapter + public String twoArgumentsBAD(String s, int i) { + return null; + } + + @Adapter + public void toVoidBAD(String s) { + } + + @Adapter + public Integer throwsExceptionBAD(String s) throws IllegalArgumentException { + if(System.currentTimeMillis() % 2L == 0) throw new IllegalArgumentException(); + return Integer.MAX_VALUE; + } + } + + @Test + public void testGoodAdapterMethods () { + int count = 0; + for(Method m : GoodAdapterMethodsProvider.class.getMethods()) { + if(m.getAnnotation(Adapter.class) == null) { + continue; + } + AdapterMethodsManagerImpl.validateAdapterMethod(m); + count++; + } + assertEquals("Expecting 2 methods", 2, count); + } + + @Test + public void testBadAdapterMethods () { + int count = 0; + for(Method m : BadAdapterMethodsProvider.class.getMethods()) { + if(m.getAnnotation(Adapter.class) == null) { + continue; + } + try { + AdapterMethodsManagerImpl.validateAdapterMethod(m); + fail("Expected Method to be invalid: " + m); + } catch(IllegalArgumentException asExpected) { + } + count++; + } + assertEquals("Expecting 3 methods", 3, count); + } +} Propchange: sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImplTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImplTest.java ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Rev URL Modified: sling/whiteboard/bdelacretaz/adapter-methods/sling-api/src/main/java/org/apache/sling/api/annotations/Adapter.java URL: http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/adapter-methods/sling-api/src/main/java/org/apache/sling/api/annotations/Adapter.java?rev=1498546&r1=1498545&r2=1498546&view=diff ============================================================================== --- sling/whiteboard/bdelacretaz/adapter-methods/sling-api/src/main/java/org/apache/sling/api/annotations/Adapter.java (original) +++ sling/whiteboard/bdelacretaz/adapter-methods/sling-api/src/main/java/org/apache/sling/api/annotations/Adapter.java Mon Jul 1 16:19:04 2013 @@ -27,6 +27,10 @@ import java.lang.annotation.Target; * Annotation for Adapter methods, used to identify methods in * {@link AdapterMethodsProvider} services that are used to * adapt between types. + * + * To be usable as an adapter method, a method that has this + * annotation must have a non-void return type, take a single + * argument and declare no exception */ @Target( { ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME)