You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by rf...@apache.org on 2009/10/24 06:16:45 UTC

svn commit: r829305 - in /tuscany/java/sca/modules/extensibility: META-INF/ src/main/java/org/apache/tuscany/sca/extensibility/ src/test/java/org/apache/tuscany/sca/extensibility/ src/test/java/org/apache/tuscany/sca/extensibility/test/ src/test/resour...

Author: rfeng
Date: Sat Oct 24 04:16:43 2009
New Revision: 829305

URL: http://svn.apache.org/viewvc?rev=829305&view=rev
Log:
Add a utility for JDK proxy based lazy instantiation

Added:
    tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ServiceHelperTestCase.java   (with props)
Modified:
    tuscany/java/sca/modules/extensibility/META-INF/MANIFEST.MF
    tuscany/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceHelper.java
    tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/Test2Impl.java
    tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestImpl.java
    tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestInterface.java
    tuscany/java/sca/modules/extensibility/src/test/resources/META-INF/services/org.apache.tuscany.sca.extensibility.test.TestInterface

Modified: tuscany/java/sca/modules/extensibility/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/extensibility/META-INF/MANIFEST.MF?rev=829305&r1=829304&r2=829305&view=diff
==============================================================================
--- tuscany/java/sca/modules/extensibility/META-INF/MANIFEST.MF (original)
+++ tuscany/java/sca/modules/extensibility/META-INF/MANIFEST.MF Sat Oct 24 04:16:43 2009
@@ -1,7 +1,6 @@
 Manifest-Version: 1.0
 Tuscany-Comment1: Export the META-INF.services under an "internal" attribute 
- so that it can be seen only by the bundle itself without following the 
- DynamicImport-Package * 
+ so that it can be seen only by the bundle itself without following the DynamicImport-Package * 
 Export-Package: org.apache.tuscany.sca.core;version="2.0.0";
  uses:="org.apache.tuscany.sca.extensibility",
  org.apache.tuscany.sca.extensibility;version="2.0.0"
@@ -14,7 +13,8 @@
 Bundle-ManifestVersion: 2
 Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
 Bundle-Description: Apache Tuscany SCA Extensibility
-Import-Package: org.apache.tuscany.sca.core;version="2.0.0",
+Import-Package: javax.xml.namespace,
+ org.apache.tuscany.sca.core;version="2.0.0",
  org.apache.tuscany.sca.extensibility;version="2.0.0"
 Bundle-SymbolicName: org.apache.tuscany.sca.extensibility
 Bundle-DocURL: http://www.apache.org/

Modified: tuscany/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceHelper.java
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceHelper.java?rev=829305&r1=829304&r2=829305&view=diff
==============================================================================
--- tuscany/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceHelper.java (original)
+++ tuscany/java/sca/modules/extensibility/src/main/java/org/apache/tuscany/sca/extensibility/ServiceHelper.java Sat Oct 24 04:16:43 2009
@@ -20,6 +20,9 @@
 package org.apache.tuscany.sca.extensibility;
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
 import java.util.Collection;
 import java.util.Map;
 
@@ -137,4 +140,86 @@
         return instance;
     }
 
+    public static <T> T newLazyInstance(ExtensionPointRegistry registry, ServiceDeclaration sd, Class<T> serviceType) {
+        return serviceType.cast(Proxy.newProxyInstance(serviceType.getClassLoader(),
+                                                       new Class<?>[] {serviceType, LifeCycleListener.class},
+                                                       new InvocationHandlerImpl(registry, serviceType, sd)));
+    }
+
+    private static class InvocationHandlerImpl implements InvocationHandler {
+        private ExtensionPointRegistry registry;
+        private Class<?> type;
+        private ServiceDeclaration sd;
+        private Object instance;
+
+        private final static Method STOP_METHOD = getMethod(LifeCycleListener.class, "stop");
+        private final static Method START_METHOD = getMethod(LifeCycleListener.class, "start");
+        private final static Method EQUALS_METHOD = getMethod(Object.class, "equals");
+        private final static Method HASHCODE_METHOD = getMethod(Object.class, "hashCode");
+        private final static Method TOSTRING_METHOD = getMethod(Object.class, "toString");
+
+        private static Method getMethod(Class<?> type, String name) {
+            Method[] methods = type.getMethods();
+            for (Method method : methods) {
+                if (name.equals(method.getName())) {
+                    return method;
+                }
+            }
+            return null;
+        }
+
+        public InvocationHandlerImpl(ExtensionPointRegistry registry, Class<?> type, ServiceDeclaration sd) {
+            super();
+            this.registry = registry;
+            this.sd = sd;
+            this.type = type;
+        }
+
+        private Object getAttribute(Method method) throws Exception {
+            if (method.getParameterTypes().length != 0) {
+                return null;
+            }
+            String name = method.getName();
+            if (name.equals("getModelType") && method.getReturnType() == Class.class) {
+                return sd.loadClass(sd.getAttributes().get("model"));
+            } else if (name.equals("getArtifactType")) {
+                return ServiceDeclarationParser.getQName(sd.getAttributes().get("qname"));
+            }
+            return null;
+        }
+
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+            synchronized (this) {
+                // Check if the method is to get the qname/model attribute
+                Object value = getAttribute(method);
+                if (value != null) {
+                    return value;
+                }
+                if (instance == null && method.getDeclaringClass() == type) {
+                    // Only initialize the instance when a method on the service type is invoked
+                    instance = newInstance(registry, sd);
+                    start(instance);
+                }
+                if (method.equals(EQUALS_METHOD)) {
+                    return proxy == args[0];
+                } else if (method.equals(HASHCODE_METHOD)) {
+                    return System.identityHashCode(proxy);
+                } else if (method.equals(TOSTRING_METHOD)) {
+                    return "Proxy: " + sd.toString();
+                }
+                if (instance == null) {
+                    return null;
+                }
+            }
+            if (method.equals(STOP_METHOD)) {
+                stop(instance);
+                return null;
+            } else if (method.equals(START_METHOD)) {
+                // Skip the start()
+                return null;
+            } else {
+                return method.invoke(instance, args);
+            }
+        }
+    }
 }

Added: tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ServiceHelperTestCase.java
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ServiceHelperTestCase.java?rev=829305&view=auto
==============================================================================
--- tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ServiceHelperTestCase.java (added)
+++ tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ServiceHelperTestCase.java Sat Oct 24 04:16:43 2009
@@ -0,0 +1,79 @@
+/*
+ * 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.tuscany.sca.extensibility;
+
+import java.lang.reflect.Proxy;
+import java.util.Collection;
+import java.util.Iterator;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.LifeCycleListener;
+import org.apache.tuscany.sca.extensibility.test.Test2Impl;
+import org.apache.tuscany.sca.extensibility.test.TestImpl;
+import org.apache.tuscany.sca.extensibility.test.TestInterface;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ServiceHelperTestCase {
+    @Test
+    public void testNewInstance() throws Exception {
+        Test2Impl implA = ServiceHelper.newInstance(Test2Impl.class);
+        Assert.assertNull(implA.getRegistry());
+
+        TestImpl impl1 = ServiceHelper.newInstance(TestImpl.class);
+        Assert.assertNotNull(impl1);
+    }
+
+    @Test
+    public void testNewInstance2() throws Exception {
+        Collection<ServiceDeclaration> sds =
+            ServiceDiscovery.getInstance().getServiceDeclarations(TestInterface.class, true);
+        ExtensionPointRegistry registry = new DefaultExtensionPointRegistry();
+        Iterator<ServiceDeclaration> iterator = sds.iterator();
+        Test2Impl implA = ServiceHelper.newInstance(registry, iterator.next());
+        Assert.assertSame(registry, implA.getRegistry());
+
+        TestImpl impl1 = ServiceHelper.newInstance(registry, iterator.next());
+        Assert.assertNotNull(impl1);
+    }
+
+    @Test
+    public void testNewLazyInstance() throws Exception {
+        Collection<ServiceDeclaration> sds =
+            ServiceDiscovery.getInstance().getServiceDeclarations(TestInterface.class, true);
+        ExtensionPointRegistry registry = new DefaultExtensionPointRegistry();
+        Iterator<ServiceDeclaration> iterator = sds.iterator();
+        TestInterface ti = ServiceHelper.newLazyInstance(registry, iterator.next(), TestInterface.class);
+        Assert.assertTrue(Proxy.isProxyClass(ti.getClass()));
+        Assert.assertTrue(ti instanceof LifeCycleListener);
+        Assert.assertTrue(ti.toString().startsWith("Proxy"));
+        Assert.assertEquals(System.identityHashCode(ti), ti.hashCode());
+        ServiceHelper.start(ti);
+        ServiceHelper.stop(ti);
+        QName name = ti.getArtifactType();
+        Assert.assertEquals(new QName("http://sample", "Test2"), name);
+        String str = ti.test("ABC");
+        Assert.assertEquals("Test 2: ABC", str);
+        ServiceHelper.stop(ti);
+    }
+}

Propchange: tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ServiceHelperTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/ServiceHelperTestCase.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/Test2Impl.java
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/Test2Impl.java?rev=829305&r1=829304&r2=829305&view=diff
==============================================================================
--- tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/Test2Impl.java (original)
+++ tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/Test2Impl.java Sat Oct 24 04:16:43 2009
@@ -19,16 +19,85 @@
 
 package org.apache.tuscany.sca.extensibility.test;
 
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.LifeCycleListener;
+
 /**
  * 
  */
-public class Test2Impl implements TestInterface {
+public class Test2Impl implements TestInterface, LifeCycleListener {
+    private ExtensionPointRegistry registry;
+    public int state = 0;
+
+    public Test2Impl(ExtensionPointRegistry registry) {
+        this.registry = registry;
+    }
+
+    public Test2Impl() {
+    }
 
-    /* (non-Javadoc)
+    /**
      * @see org.apache.tuscany.sca.extensibility.test.TestInterface#test(java.lang.String)
      */
-    public void test(String str) {
+    public String test(String str) {
         System.out.println("Test 2: " + str);
+        return "Test 2: " + str;
+    }
+
+    public ExtensionPointRegistry getRegistry() {
+        return registry;
+    }
+
+    public void start() {
+        state = 1;
+    }
+
+    public void stop() {
+        state = -1;
+    }
+
+    public int getState() {
+        return state;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((registry == null) ? 0 : registry.hashCode());
+        result = prime * result + state;
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        Test2Impl other = (Test2Impl)obj;
+        if (registry == null) {
+            if (other.registry != null)
+                return false;
+        } else if (!registry.equals(other.registry))
+            return false;
+        if (state != other.state)
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "Test2Impl [state=" + state + "]";
+    }
+
+    public QName getArtifactType() {
+        // TODO Auto-generated method stub
+        return new QName("http://sample", "Test2");
     }
 
 }

Modified: tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestImpl.java
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestImpl.java?rev=829305&r1=829304&r2=829305&view=diff
==============================================================================
--- tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestImpl.java (original)
+++ tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestImpl.java Sat Oct 24 04:16:43 2009
@@ -19,6 +19,8 @@
 
 package org.apache.tuscany.sca.extensibility.test;
 
+import javax.xml.namespace.QName;
+
 /**
  * 
  */
@@ -27,8 +29,14 @@
     /* (non-Javadoc)
      * @see org.apache.tuscany.sca.extensibility.test.TestInterface#test(java.lang.String)
      */
-    public void test(String str) {
+    public String test(String str) {
         System.out.println("Test: " + str);
+        return "Test: " + str;
+    }
+
+    public QName getArtifactType() {
+        // TODO Auto-generated method stub
+        return null;
     }
 
 }

Modified: tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestInterface.java
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestInterface.java?rev=829305&r1=829304&r2=829305&view=diff
==============================================================================
--- tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestInterface.java (original)
+++ tuscany/java/sca/modules/extensibility/src/test/java/org/apache/tuscany/sca/extensibility/test/TestInterface.java Sat Oct 24 04:16:43 2009
@@ -19,9 +19,12 @@
 
 package org.apache.tuscany.sca.extensibility.test;
 
+import javax.xml.namespace.QName;
+
 /**
  * 
  */
 public interface TestInterface {
-    void test(String str);
+    String test(String str);
+    QName getArtifactType();
 }

Modified: tuscany/java/sca/modules/extensibility/src/test/resources/META-INF/services/org.apache.tuscany.sca.extensibility.test.TestInterface
URL: http://svn.apache.org/viewvc/tuscany/java/sca/modules/extensibility/src/test/resources/META-INF/services/org.apache.tuscany.sca.extensibility.test.TestInterface?rev=829305&r1=829304&r2=829305&view=diff
==============================================================================
--- tuscany/java/sca/modules/extensibility/src/test/resources/META-INF/services/org.apache.tuscany.sca.extensibility.test.TestInterface (original)
+++ tuscany/java/sca/modules/extensibility/src/test/resources/META-INF/services/org.apache.tuscany.sca.extensibility.test.TestInterface Sat Oct 24 04:16:43 2009
@@ -15,5 +15,5 @@
 # specific language governing permissions and limitations
 # under the License. 
 org.apache.tuscany.sca.extensibility.test.TestImpl;ranking=10;attr=123
-org.apache.tuscany.sca.extensibility.test.Test2Impl;ranking=20;attr=abc
+org.apache.tuscany.sca.extensibility.test.Test2Impl;ranking=20,attr=abc,qname=http://sample#Test2,model=org.apache.tuscany.sca.extensibility.test.TestInterface
 org.apache.tuscany.sca.extensibility.test.DummyImpl
\ No newline at end of file