You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ti...@apache.org on 2012/02/02 10:22:22 UTC

svn commit: r1239498 [2/2] - in /aries/trunk/proxy/proxy-impl/src: main/java/org/apache/aries/proxy/impl/ main/java/org/apache/aries/proxy/impl/common/ main/java/org/apache/aries/proxy/impl/interfaces/ main/java/org/apache/aries/proxy/impl/weaving/ tes...

Added: aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenSubclassGeneratorTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenSubclassGeneratorTest.java?rev=1239498&view=auto
==============================================================================
--- aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenSubclassGeneratorTest.java (added)
+++ aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenSubclassGeneratorTest.java Thu Feb  2 09:22:21 2012
@@ -0,0 +1,291 @@
+/*
+ * 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.aries.blueprint.proxy;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import org.apache.aries.proxy.FinalModifierException;
+import org.apache.aries.proxy.InvocationListener;
+import org.apache.aries.proxy.UnableToProxyException;
+import org.apache.aries.proxy.impl.SingleInstanceDispatcher;
+import org.apache.aries.proxy.impl.gen.ProxySubclassGenerator;
+import org.apache.aries.proxy.impl.gen.ProxySubclassMethodHashSet;
+import org.apache.aries.proxy.impl.interfaces.InterfaceProxyGenerator;
+import org.apache.aries.proxy.weaving.WovenProxy;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * This class uses the {@link ProxySubclassGenerator} to test
+ */
+public class WovenSubclassGeneratorTest extends AbstractProxyTest
+{
+  private static final Class<?> FINAL_METHOD_CLASS = ProxyTestClassFinalMethod.class;
+  private static final Class<?> FINAL_CLASS = ProxyTestClassFinal.class;
+  private static final Class<?> GENERIC_CLASS = ProxyTestClassGeneric.class;
+  private static final Class<?> COVARIANT_CLASS = ProxyTestClassCovariantOverride.class;
+  private static ProxySubclassMethodHashSet<String> expectedMethods = new ProxySubclassMethodHashSet<String>(
+      12);
+  private Callable<Object> testCallable = null;
+
+
+  /**
+   * Test that the methods found declared on the generated proxy subclass are
+   * the ones that we expect.
+   */
+  @Test
+  public void testExpectedMethods() throws Exception
+  {
+    Class<?> superclass = getTestClass();
+
+    do {
+      Method[] declaredMethods = superclass.getDeclaredMethods();
+      List<Method> listOfDeclaredMethods = new ArrayList<Method>();
+      for (Method m : declaredMethods) {
+    	
+        if(m.getName().equals("clone") || m.getName().equals("finalize"))
+        	continue;
+    	
+        int i = m.getModifiers();
+        if (Modifier.isPrivate(i) || Modifier.isFinal(i)) {
+          // private or final don't get added
+        } else if (!(Modifier.isPublic(i) || Modifier.isPrivate(i) || Modifier.isProtected(i))) {
+          // the method is default visibility, check the package
+          if (m.getDeclaringClass().getPackage().equals(getTestClass().getPackage())) {
+            // default vis with same package gets added
+            listOfDeclaredMethods.add(m);
+          }
+        } else {
+          listOfDeclaredMethods.add(m);
+        }
+      }
+
+      declaredMethods = listOfDeclaredMethods.toArray(new Method[] {});
+      ProxySubclassMethodHashSet<String> foundMethods = new ProxySubclassMethodHashSet<String>(
+          declaredMethods.length);
+      foundMethods.addMethodArray(declaredMethods);
+      // as we are using a set we shouldn't get duplicates
+      expectedMethods.addAll(foundMethods);
+      superclass = superclass.getSuperclass();
+    } while (superclass != null);
+
+    
+    
+    Method[] subclassMethods = getProxyClass(getTestClass()).getDeclaredMethods();
+    List<Method> listOfDeclaredMethods = new ArrayList<Method>();
+    for (Method m : subclassMethods) {
+      if(m.getName().startsWith(WovenProxy.class.getName().replace('.', '_')))
+        continue;
+      
+      listOfDeclaredMethods.add(m);
+    }
+    subclassMethods = listOfDeclaredMethods.toArray(new Method[] {});
+    
+    ProxySubclassMethodHashSet<String> generatedMethods = new ProxySubclassMethodHashSet<String>(
+    		subclassMethods.length);
+        generatedMethods.addMethodArray(subclassMethods);
+        
+    // check that all the methods we have generated were expected
+    for (String gen : generatedMethods) {
+      assertTrue("Unexpected method: " + gen, expectedMethods.contains(gen));
+    }
+    // check that all the expected methods were generated
+    for (String exp : expectedMethods) {
+      assertTrue("Method was not generated: " + exp, generatedMethods.contains(exp));
+    }
+    // check the sets were the same
+    assertEquals("Sets were not the same", expectedMethods, generatedMethods);
+
+  }
+
+  /**
+   * Test a method marked final
+   */
+  @Test
+  public void testFinalMethod() throws Exception
+  {
+    try {
+      InterfaceProxyGenerator.getProxyInstance(null, FINAL_METHOD_CLASS, Collections.EMPTY_SET, 
+          new Callable<Object>() {
+        public Object call() throws Exception {
+          return null;
+        }} , null).getClass();
+    } catch (RuntimeException re) {
+      FinalModifierException e = (FinalModifierException) re.getCause();
+      assertFalse("Should have found final method not final class", e.isFinalClass());
+    }
+  }
+
+  /**
+   * Test a class marked final
+   */
+  @Test
+  public void testFinalClass() throws Exception
+  {
+    try {
+      InterfaceProxyGenerator.getProxyInstance(null, FINAL_CLASS, Collections.EMPTY_SET, 
+          new Callable<Object>() {
+        public Object call() throws Exception {
+          return null;
+        }} , null).getClass();
+    } catch (FinalModifierException e) {
+      assertTrue("Should have found final class", e.isFinalClass());
+    }
+  }
+
+  /**
+   * Test a covariant override method
+   */
+  @Test
+  public void testCovariant() throws Exception
+  {
+    testCallable = new SingleInstanceDispatcher(COVARIANT_CLASS.newInstance());
+    Object o = setDelegate(getProxyInstance(getProxyClass(COVARIANT_CLASS)), testCallable);
+    Class<?> generatedProxySubclass = o.getClass();
+    Method m = generatedProxySubclass.getDeclaredMethod("getCovariant", new Class[] {});
+    Object returned = m.invoke(o);
+    assertTrue("Object was of wrong type: " + returned.getClass().getSimpleName(), COVARIANT_CLASS
+        .isInstance(returned));
+  }
+  
+  /**
+   * Test a covariant override method
+   */
+  @Test
+  public void testGenerics() throws Exception
+  {
+    testCallable = new SingleInstanceDispatcher(GENERIC_CLASS.newInstance());
+    super.testGenerics();
+  }
+  
+  @Test
+  public void testInner() {
+	  //This implementation can never pass this test. It doesn't support classes with no no-args constructor.
+  }
+   
+  
+  @Test
+  public void testAddingInterfacesToClass() throws Exception {
+	  
+    Object proxy = InterfaceProxyGenerator.getProxyInstance(null, getTestClass(), Arrays.asList(Map.class, Iterable.class), new Callable<Object>() {
+
+        int calls = 0;
+        private Map<String, String> map = new HashMap<String, String>();
+        
+        {
+          map.put("key", "value");
+        }
+
+        public Object call() throws Exception {
+          switch(++calls) {
+            case 1 :
+              return getTestClass().newInstance();
+            case 2 :
+              return map;
+            default :
+              return map.values();
+          }
+		}
+    	
+    }, null);
+    
+    
+    assertEquals(17, ((ProxyTestClassGeneralWithNoDefaultOrProtectedAccess)proxy).testReturnInt());
+    assertEquals("value", ((Map<String, String>)proxy).put("key", "value2"));
+    Iterator<?> it = ((Iterable<?>)proxy).iterator();
+    assertEquals("value2", it.next());
+    assertFalse(it.hasNext());
+	  
+  }
+  
+  @Override
+  protected Object getProxyInstance(Class<?> proxyClass) {
+	 
+    if(proxyClass == ProxyTestClassChildOfAbstract.class) {
+    	return new ProxyTestClassChildOfAbstract();
+    }
+	  
+    try {
+      Constructor<?> con = proxyClass.getDeclaredConstructor(Callable.class, InvocationListener.class);
+      con.setAccessible(true);
+      return con.newInstance((testCallable == null) ? new SingleInstanceDispatcher(getTestClass().newInstance()) : testCallable, null);
+    } catch (Exception e) {
+      return null;
+    }
+  }
+  
+
+  @Override
+  protected Class<?> getTestClass() {
+	return ProxyTestClassGeneralWithNoDefaultOrProtectedAccess.class;
+  }
+
+
+@Override
+  protected Class<?> getProxyClass(Class<?> clazz) {
+    try {
+      return InterfaceProxyGenerator.getProxyInstance(null, clazz, Collections.EMPTY_SET, 
+          new Callable<Object>() {
+        public Object call() throws Exception {
+          return null;
+        }} , null).getClass();
+    } catch (UnableToProxyException e) {
+      return null;
+    } catch (RuntimeException re) {
+      if(re.getCause() instanceof UnableToProxyException)
+        return null;
+      else
+        throw re;
+    }
+  }
+
+
+  @Override
+  protected Object setDelegate(Object proxy, Callable<Object> dispatcher) {
+    return ((WovenProxy)proxy).org_apache_aries_proxy_weaving_WovenProxy_createNewProxyInstance(
+        dispatcher, null);
+  }
+
+  @Override
+  protected Object getProxyInstance(Class<?> proxyClass,
+      InvocationListener listener) {
+    WovenProxy proxy = (WovenProxy) getProxyInstance(proxyClass);
+    proxy = proxy.org_apache_aries_proxy_weaving_WovenProxy_createNewProxyInstance(
+        new SingleInstanceDispatcher(proxy), listener);
+    return proxy;
+  }
+  
+  protected Object getP3() throws Exception {
+    return getTestClass().newInstance();
+  }
+}
\ No newline at end of file

Propchange: aries/trunk/proxy/proxy-impl/src/test/java/org/apache/aries/blueprint/proxy/WovenSubclassGeneratorTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain