incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bdelacre...@apache.org
Subject svn commit: r1498324 - in /sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter: pom.xml src/main/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImpl.java src/test/java/org/apache/sling/adapter/internal/AdapterMethodManagerIT.java
Date Mon, 01 Jul 2013 09:04:14 GMT
Author: bdelacretaz
Date: Mon Jul  1 09:04:14 2013
New Revision: 1498324

URL: http://svn.apache.org/r1498324
Log:
SLING-2938 - AdapterMethodsManager implementation and tests, in my whiteboard for now

Added:
    sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/main/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImpl.java
  (with props)
    sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodManagerIT.java
  (with props)
Modified:
    sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/pom.xml

Modified: sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/pom.xml
URL: http://svn.apache.org/viewvc/sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/pom.xml?rev=1498324&r1=1498323&r2=1498324&view=diff
==============================================================================
--- sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/pom.xml (original)
+++ sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/pom.xml Mon Jul  1 09:04:14
2013
@@ -47,11 +47,26 @@
     <properties>
         <site.jira.version.id>12314288</site.jira.version.id>
         <site.javadoc.exclude>**.impl.**</site.javadoc.exclude>
+        <exam.version>3.0.3</exam.version>
+        <url.version>1.5.2</url.version>
+        <pax.exam.log.level>INFO</pax.exam.log.level>
     </properties>
 
     <build>
         <plugins>
             <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <systemProperties>
+                        <property>
+                            <name>pax.exam.log.level</name>
+                            <value>${pax.exam.log.level}</value>
+                        </property>
+                    </systemProperties>
+                </configuration>
+            </plugin>
+            <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-scr-plugin</artifactId>
             </plugin>
@@ -74,6 +89,18 @@
                     </instructions>
                 </configuration>
             </plugin>
+            <plugin>
+                <artifactId>maven-failsafe-plugin</artifactId>
+                <version>2.12</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>integration-test</goal>
+                            <goal>verify</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
     </build>
     <reporting>
@@ -93,7 +120,7 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.api</artifactId>
-            <version>2.2.0</version>
+            <version>2.4.3-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
@@ -111,10 +138,14 @@
         <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.core</artifactId>
+            <version>4.2.0</version>
+            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.compendium</artifactId>
+            <version>4.2.0</version>
+            <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.felix</groupId>
@@ -153,5 +184,35 @@
             <version>2.5</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-container-native</artifactId>
+            <version>${exam.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-junit4</artifactId>
+            <version>${exam.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.exam</groupId>
+            <artifactId>pax-exam-link-mvn</artifactId>
+            <version>${exam.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.ops4j.pax.url</groupId>
+            <artifactId>pax-url-aether</artifactId>
+            <version>${url.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.framework</artifactId>
+            <version>3.2.2</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>

Added: 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=1498324&view=auto
==============================================================================
--- sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/main/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImpl.java
(added)
+++ sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/main/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImpl.java
Mon Jul  1 09:04:14 2013
@@ -0,0 +1,153 @@
+/*
+ * 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 java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.sling.api.adapter.AdapterFactory;
+import org.apache.sling.api.adapter.AdapterMethod;
+import org.apache.sling.api.adapter.AdapterMethodsProvider;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.util.tracker.ServiceTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Manages {@link AdapterMethodsProvider} services by generating
+ * {@link AdapterFactory} proxies for their adapter methods.
+ */
+@Component(immediate=true)
+public class AdapterMethodsManagerImpl {
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private ServiceTracker tracker;
+    private final List<AdapterProxy> proxies = new LinkedList<AdapterProxy>();
+    private BundleContext bundleContext;
+
+    private class Tracker extends ServiceTracker {
+        
+        Tracker() {
+            super(bundleContext, AdapterMethodsProvider.class.getName(), null);
+        }
+
+        @Override
+        public Object addingService(ServiceReference reference) {
+            // Extract adapter methods from service object
+            // and create an AdapterProxy for each of them
+            final AdapterMethodsProvider p = (AdapterMethodsProvider)bundleContext.getService(reference);
+            for(Method m : p.getClass().getMethods()) {
+                if(m.getAnnotation(AdapterMethod.class) != null) {
+                    proxies.add(new AdapterProxy(reference, p, m));
+                }
+            }
+            return super.addingService(reference);
+        }
+
+        @Override
+        public void removedService(ServiceReference reference, Object service) {
+            // Unregister the corresponding AdapterProxies
+            final List<AdapterProxy> toRemove = new ArrayList<AdapterProxy>();
+            for(AdapterProxy p : proxies) {
+                if(reference.equals(p.getProxiedServiceReference())) {
+                    p.unregister();
+                    toRemove.add(p);
+                }
+            }
+            for(AdapterProxy p : toRemove) {
+                proxies.remove(p);
+            }
+            super.removedService(reference, service);
+        }
+    }
+    
+    private class AdapterProxy implements AdapterFactory {
+        private final ServiceReference proxiedServiceReference;
+        private final ServiceRegistration serviceRegistration;
+        private final Method method;
+        private final Object provider;
+        
+        AdapterProxy(ServiceReference ref, Object methodProvider, Method m) {
+            proxiedServiceReference = ref;
+            provider = methodProvider;
+            method = m;
+            
+            final Class<?> fromClass = m.getParameterTypes()[0];
+            final Class<?> toClass = m.getReturnType();
+            final Dictionary<String, Object> props = new Hashtable<String, Object>();
+            props.put(AdapterFactory.ADAPTABLE_CLASSES, new String[] { fromClass.getName()
});
+            props.put(AdapterFactory.ADAPTER_CLASSES, new String[] { toClass.getName() });
+            
+            final AdapterFactory factory = new AdapterFactory() {
+                @SuppressWarnings("unchecked")
+                public <AdapterType> AdapterType getAdapter(Object adaptable, Class<AdapterType>
type) {
+                    if(adaptable.getClass().equals(fromClass) && type.equals(toClass))
{
+                        try {
+                            log.debug("Adapting using method {} from {}", method, provider);
+                            return (AdapterType)method.invoke(provider, adaptable);
+                        } catch (Exception e) {
+                            throw new RuntimeException("Exception in AdapterProxy", e);
+                        }
+                    } else {
+                        return null;
+                    }
+                }
+            };
+            
+            serviceRegistration = bundleContext.registerService(AdapterFactory.class.getName(),
factory, props);
+            log.debug("Registered AdapterFactory proxy for {}", provider);
+        }
+        
+        ServiceReference getProxiedServiceReference() {
+            return proxiedServiceReference;
+        }
+        
+        void unregister() {
+            if(serviceRegistration != null) {
+                serviceRegistration.unregister();
+            }
+        }
+        
+        public <AdapterType> AdapterType getAdapter(Object from, Class<AdapterType>
toType) {
+            return null;
+        }
+        
+    }
+    
+    @Activate
+    public void activate(ComponentContext ctx) {
+        bundleContext = ctx.getBundleContext();
+        tracker = new Tracker();
+        tracker.open();
+    }
+    
+    @Deactivate
+    public void deactivate(ComponentContext ctx) {
+        tracker.close();
+    }
+}

Propchange: sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/main/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/main/java/org/apache/sling/adapter/internal/AdapterMethodsManagerImpl.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: 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=1498324&view=auto
==============================================================================
--- sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodManagerIT.java
(added)
+++ sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodManagerIT.java
Mon Jul  1 09:04:14 2013
@@ -0,0 +1,185 @@
+/*
+ * 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.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.inject.Inject;
+
+import org.apache.sling.api.adapter.AdapterMethod;
+import org.apache.sling.api.adapter.AdapterMethodsProvider;
+import org.apache.sling.api.adapter.SlingAdaptable;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+/** Test the AdapterMethodsManager */
+@RunWith(PaxExam.class)
+public class AdapterMethodManagerIT {
+    
+    @Inject
+    BundleContext bundleContext;
+    
+    static class TestAdaptable extends SlingAdaptable {
+        final long value;
+        
+        TestAdaptable(long value) {
+            this.value = value;
+        }
+    }
+    
+    /** Example/test AdapterMethodsProvider that converts TestAdaptable to Long */
+    public static class SingleMethodProvider implements AdapterMethodsProvider {
+        
+        private final ServiceRegistration reg;
+        
+        SingleMethodProvider(BundleContext ctx) {
+            reg = ctx.registerService(AdapterMethodsProvider.class.getName(), this, null);
+        }
+        
+        @AdapterMethod
+        public Long adapt(TestAdaptable src) {
+            return new Long(src.value);
+        }
+        
+        public void unregister() {
+            reg.unregister();
+        }
+    }
+    
+    /** Example/test AdapterMethodsProvider that converts TestAdaptable to Integer and URL
*/
+    public static class MultipleMethodsProvider implements AdapterMethodsProvider {
+        
+        private final ServiceRegistration reg;
+        
+        MultipleMethodsProvider(BundleContext ctx) {
+            reg = ctx.registerService(AdapterMethodsProvider.class.getName(), this, null);
+        }
+        
+        @AdapterMethod
+        public Integer adaptToInt(TestAdaptable src) {
+            return new Integer((int)src.value);
+        }
+        
+        @AdapterMethod
+        public URL adaptToURL(TestAdaptable src) {
+            final String url = "http://example.com/" + src.value;
+            try {
+                return new URL(url);
+            } catch(MalformedURLException mfu) {
+                throw new RuntimeException("Invalid URL " + url, mfu);
+            }
+        }
+        
+        public void unregister() {
+            reg.unregister();
+        }
+    }
+    
+    @org.ops4j.pax.exam.Configuration
+    public Option[] config() {
+        final String paxLogLevel = System.getProperty("pax.exam.log.level", "INFO");
+        
+        return options(
+                junitBundles(),
+                systemProperty( "org.ops4j.pax.logging.DefaultServiceLog.level" ).value(paxLogLevel),
+                provision(
+                        mavenBundle("org.apache.felix", "org.apache.felix.scr", "1.6.0"),
+                        mavenBundle("org.apache.felix", "org.apache.felix.configadmin", "1.2.8"),
+                        mavenBundle("org.apache.felix", "org.apache.felix.metatype", "1.0.2"),
+                        mavenBundle("org.apache.felix", "org.apache.felix.http.jetty", "2.2.0"),
+                        mavenBundle("commons-io", "commons-io", "1.4"),
+                        mavenBundle("commons-lang", "commons-lang", "2.5"),
+                        mavenBundle("javax.jcr", "jcr", "2.0"),
+                        
+                        // TODO use newer API bundle when released
+                        mavenBundle("org.apache.sling", "org.apache.sling.api", "2.4.3-SNAPSHOT"),
+                        
+                        mavenBundle("org.apache.sling", "org.apache.sling.commons.json",
"2.0.6"),
+                        mavenBundle("org.apache.sling", "org.apache.sling.commons.osgi",
"2.1.0"),
+                        mavenBundle("org.apache.sling", "org.apache.sling.adapter")
+                )); 
+    }
+    
+    @Test
+    public void testWithoutAdapter() {
+        final Long result = new TestAdaptable(12).adaptTo(Long.class);
+        assertNull("Expecting null adapted Long", result);
+    }
+    
+    @Test
+    public void testWithSingleAdapter() {
+        final SingleMethodProvider tamp = new SingleMethodProvider(bundleContext);
+        try {
+            final long value = System.currentTimeMillis();
+            final Long result = new TestAdaptable(value).adaptTo(Long.class);
+            assertNotNull("Expecting non-null adapted Long", result);
+            assertEquals("Expecting correct adapted value", value, result.longValue());
+        } finally {
+            tamp.unregister();
+        }
+    }
+    
+    @Test
+    public void testWithMultipleAdapters() throws MalformedURLException {
+        final SingleMethodProvider smp = new SingleMethodProvider(bundleContext);
+        final MultipleMethodsProvider mmp = new MultipleMethodsProvider(bundleContext);
+        try {
+            final int value = (int)System.currentTimeMillis();
+            final TestAdaptable ta = new TestAdaptable(value);
+            
+            {
+                final Long result = ta.adaptTo(Long.class);
+                assertNotNull("Expecting non-null adapted Long", result);
+                assertEquals("Expecting correct Long adapted value", value, result.longValue());
+            }
+            
+            {
+                final Integer result = ta.adaptTo(Integer.class);
+                assertNotNull("Expecting non-null adapted Integer", result);
+                assertEquals("Expecting correct Integer adapted value", value, result.intValue());
+            }
+            
+            {
+                final URL result = ta.adaptTo(URL.class);
+                final URL expected = new URL("http://example.com/" + value);
+                assertNotNull("Expecting non-null adapted URL", result);
+                assertEquals("Expecting correctly adapted URL", expected, result);
+            }
+            
+            
+        } finally {
+            smp.unregister();
+            mmp.unregister();
+        }
+    }
+}

Propchange: sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodManagerIT.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sling/whiteboard/bdelacretaz/adapter-methods/extensions-adapter/src/test/java/org/apache/sling/adapter/internal/AdapterMethodManagerIT.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL



Mime
View raw message