You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2013/09/30 21:43:21 UTC

svn commit: r1527749 - in /felix/trunk/ipojo: manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/ manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/...

Author: clement
Date: Mon Sep 30 19:43:21 2013
New Revision: 1527749

URL: http://svn.apache.org/r1527749
Log:
Fix FELIX-4253 Add methods from inner classes in the metadata collected during the manipulation

Parse the inner class metadata stored in the manifest.

Added:
    felix/trunk/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/ComponentWithInnerClasses.java
Modified:
    felix/trunk/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManipulationMetadata.java
    felix/trunk/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManipulationMetadataAPI.java
    felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java

Added: felix/trunk/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/ComponentWithInnerClasses.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/ComponentWithInnerClasses.java?rev=1527749&view=auto
==============================================================================
--- felix/trunk/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/ComponentWithInnerClasses.java (added)
+++ felix/trunk/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/ComponentWithInnerClasses.java Mon Sep 30 19:43:21 2013
@@ -0,0 +1,75 @@
+/*
+ * 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.felix.ipojo.runtime.core.components;
+
+import org.apache.felix.ipojo.annotations.Component;
+
+/**
+ **
+ * A component containing inner classes.
+ */
+@Component
+public class ComponentWithInnerClasses{
+
+    public String doSomething() {
+        MyInnerWithANativeMethod nat = new MyInnerWithANativeMethod();
+        MyInnerClass inn = new MyInnerClass();
+        Runnable compute = new Runnable() {
+
+            public void run() {
+                // ...
+            }
+        };
+        return "foo";
+    }
+
+    private String foo = "foo";
+
+    private class MyInnerWithANativeMethod {
+
+        public String foo() {
+            return ComponentWithInnerClasses.this.foo;
+        }
+
+        public native void baz();
+
+    }
+
+    public static class MyStaticInnerClass {
+
+        public static String foo() {
+            return "foo";
+        }
+
+        public String bar() {
+            return "bar";
+        }
+
+        public native void baz();
+    }
+
+    private class MyInnerClass {
+        public String foo() {
+            return ComponentWithInnerClasses.this.foo;
+        }
+    }
+
+
+}

Modified: felix/trunk/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManipulationMetadata.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManipulationMetadata.java?rev=1527749&r1=1527748&r2=1527749&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManipulationMetadata.java (original)
+++ felix/trunk/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManipulationMetadata.java Mon Sep 30 19:43:21 2013
@@ -25,11 +25,14 @@ import org.apache.felix.ipojo.parser.Par
 import org.apache.felix.ipojo.parser.ParseUtils;
 import org.apache.felix.ipojo.runtime.core.services.BarService;
 import org.apache.felix.ipojo.runtime.core.services.FooService;
+import org.junit.Assert;
 import org.junit.Test;
 import org.ow2.chameleon.testing.helpers.BaseTest;
 
 import static junit.framework.Assert.assertEquals;
-import static org.junit.Assert.*;
+import static junit.framework.Assert.assertNotNull;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
 
 /**
  * Check manipulation metadata written in the manifest.
@@ -199,6 +202,45 @@ public class TestManipulationMetadata ex
         assertEquals("Check return", method.getAttribute("return"), "java.lang.Object");
     }
 
+    @Test
+    public void testInnerClasses() {
+        String comp_name = "org.apache.felix.ipojo.runtime.core.components.ComponentWithInnerClasses";
+        Element manipulation = getManipulationForComponent(comp_name);
+        Element[] inners = manipulation.getElements("inner");
+        assertEquals(inners.length, 3);
+
+        Element inner = getInnerClassMetadataByName(inners, "MyInnerWithANativeMethod");
+        Assert.assertNotNull(inner);
+        Assert.assertNotNull(getMethodByName(inner.getElements("method"), "foo"));
+
+        inner = getInnerClassMetadataByName(inners, "MyInnerClass");
+        assertNotNull(inner);
+        assertNotNull(getMethodByName(inner.getElements("method"), "foo"));
+
+        inner = getInnerClassMetadataByName(inners, "1");
+        assertNotNull(inner);
+        assertNotNull(getMethodByName(inner.getElements("method"), "run"));
+    }
+
+    private static Element getInnerClassMetadataByName(Element[] inners, String name) {
+        for (Element element : inners) {
+            if (name.equals(element.getAttribute("name"))) {
+                return element;
+            }
+        }
+        return null;
+    }
+
+    private static Element getMethodByName(Element[] methods, String name) {
+        for (Element element : methods) {
+            if (name.equals(element.getAttribute("name"))) {
+                return element;
+            }
+        }
+        return null;
+    }
+
+
     private Element getManipulationForComponent(Element metadata, String comp_name) {
         Element[] comps = metadata.getElements("component");
         for (Element comp : comps) {

Modified: felix/trunk/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManipulationMetadataAPI.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManipulationMetadataAPI.java?rev=1527749&r1=1527748&r2=1527749&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManipulationMetadataAPI.java (original)
+++ felix/trunk/ipojo/manipulator/manipulator-it/ipojo-manipulator-manipulation-metadata-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestManipulationMetadataAPI.java Mon Sep 30 19:43:21 2013
@@ -28,7 +28,10 @@ import org.junit.Before;
 import org.junit.Test;
 import org.ow2.chameleon.testing.helpers.BaseTest;
 
+import java.util.Arrays;
+
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
 import static org.junit.Assert.*;
 
 public class TestManipulationMetadataAPI extends BaseTest {
@@ -101,6 +104,34 @@ public class TestManipulationMetadataAPI
     }
 
     @Test
+    public void testInnerClasses() {
+        String comp_name = "org.apache.felix.ipojo.runtime.core.components.ComponentWithInnerClasses";
+        PojoMetadata metadata = getManipulationMetadataForComponent(comp_name);
+        assertEquals(metadata.getInnerClasses().length, 3);
+        assertNotNull(metadata.getMethodsFromInnerClass("MyInnerWithANativeMethod"));
+        assertNotNull(
+                getMethodMetadata(metadata.getMethodsFromInnerClass("MyInnerWithANativeMethod"),
+                        "foo"));
+
+        assertNotNull(
+                getMethodMetadata(metadata.getMethodsFromInnerClass("MyInnerClass"),
+                        "foo"));
+
+        assertNotNull(
+                getMethodMetadata(metadata.getMethodsFromInnerClass("1"),
+                        "run"));
+    }
+
+    public static MethodMetadata getMethodMetadata(MethodMetadata[] methods, String name) {
+        for (MethodMetadata m : methods) {
+            if (m.getMethodName().equals(name)) {
+                return m;
+            }
+        }
+        return null;
+    }
+
+    @Test
     public void testFields() {
         PojoMetadata manip = FooProviderTypeDyn;
 
@@ -275,7 +306,6 @@ public class TestManipulationMetadataAPI
         return null;
     }
 
-
     private PojoMetadata getManipulationMetadataForComponent(String comp_name) {
         String header = (String) getTestBundle().getHeaders().get("iPOJO-Components");
         Element elem = null;

Modified: felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java?rev=1527749&r1=1527748&r2=1527749&view=diff
==============================================================================
--- felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java (original)
+++ felix/trunk/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java Mon Sep 30 19:43:21 2013
@@ -21,6 +21,8 @@ package org.apache.felix.ipojo.parser;
 import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.metadata.Element;
 
+import java.util.*;
+
 /**
  * Manipulation Metadata allows getting information about the implementation class
  * without using reflection such as implemented interfaces, super class,
@@ -44,13 +46,23 @@ public class PojoMetadata {
     /**
      * The list of methods.
      */
-    private MethodMetadata[] m_methods = new MethodMetadata[0];
+    private List<MethodMetadata> m_methods = new ArrayList<MethodMetadata>();
 
     /**
      * The Super class (if <code>null</code> for {@link Object}).
      */
     private String m_super;
 
+    /**
+     * The manipulated class name.
+     */
+    private String m_className;
+
+    /**
+     * The inner classes and their methods.
+     */
+    private Map<String, List<MethodMetadata>> m_innerClasses = new HashMap<String, List<MethodMetadata>>();
+
 
     /**
      * Creates Pojo metadata.
@@ -65,29 +77,80 @@ public class PojoMetadata {
             throw new ConfigurationException("The component " + metadata.getAttribute("classname") + " has no manipulation metadata");
         }
         Element manip = elems[0];
+        m_className = manip.getAttribute("classname");
         m_super = manip.getAttribute("super");
+
         Element[] fields = manip.getElements("field");
-        for (int i = 0; fields != null && i < fields.length; i++) {
-            FieldMetadata field = new FieldMetadata(fields[i]);
-            addField(field);
+        if (fields != null) {
+            for (Element field : fields) {
+                addField(new FieldMetadata(field));
+            }
         }
+
         Element[] methods = manip.getElements("method");
-        for (int i = 0; methods != null && i < methods.length; i++) {
-            MethodMetadata method = new MethodMetadata(methods[i]);
-            addMethod(method);
+        if (methods != null) {
+            for (Element method : methods) {
+                m_methods.add(new MethodMetadata(method));
+            }
         }
+
         Element[] itfs = manip.getElements("interface");
-        for (int i = 0; itfs != null && i < itfs.length; i++) {
-            addInterface(itfs[i].getAttribute("name"));
+        if (itfs != null) {
+            for (Element itf : itfs) {
+                addInterface(itf.getAttribute("name"));
+            }
+        }
+
+        Element[] inners = manip.getElements("inner");
+        if (inners != null) {
+            for (Element inner : inners) {
+                String name = inner.getAttribute("name");
+                List<MethodMetadata> list = m_innerClasses.get(name);
+                if (list == null) {
+                    list = new ArrayList<MethodMetadata>();
+                    m_innerClasses.put(name, list);
+                }
+                methods = inner.getElements("method");
+                if (methods != null) {
+                    for (Element m : methods) {
+                        list.add(new MethodMetadata(m));
+                    }
+                }
+            }
         }
     }
 
-    public MethodMetadata[] getMethods() { return m_methods; }
+    public MethodMetadata[] getMethods() { return m_methods.toArray(new MethodMetadata[m_methods.size()]); }
 
     public FieldMetadata[] getFields() { return m_fields; }
 
     public String[] getInterfaces() { return m_interfaces; }
 
+    public String getClassName() { return m_className; }
+
+    /**
+     * Gets the inner classes from the manipulated class
+     * @return the list of the inner class names.
+     */
+    public String[] getInnerClasses() {
+        Set<String> classes = m_innerClasses.keySet();
+        return classes.toArray(new String[classes.size()]);
+    }
+
+    /**
+     * Gets the methods from the given inner class.
+     * @param inner the inner class name
+     * @return the list of method, empty if none.
+     */
+    public MethodMetadata[] getMethodsFromInnerClass(String inner) {
+        List<MethodMetadata> methods = m_innerClasses.get(inner);
+        if (inner != null) {
+            return methods.toArray(new MethodMetadata[methods.size()]);
+        } else {
+            return new MethodMetadata[0];
+        }
+    }
+
     /**
      * Gets the field metadata for the given name.
      * @param name : the name of the field
@@ -137,8 +200,8 @@ public class PojoMetadata {
      * @return the method metadata object or <code>null</code> if not found
      */
     public MethodMetadata getMethod(String name) {
-        for (int i = 0; i < m_methods.length; i++) {
-            if (m_methods[i].getMethodName().equalsIgnoreCase(name)) { return m_methods[i]; }
+        for (MethodMetadata metadata : m_methods) {
+            if (metadata.getMethodName().equalsIgnoreCase(name)) { return metadata; }
         }
         return null;
     }
@@ -152,20 +215,13 @@ public class PojoMetadata {
      * @return the Method Metadata array or an empty array if not found
      */
     public MethodMetadata[] getMethods(String name) {
-        MethodMetadata[] mms = new MethodMetadata[0];
-        for (int i = 0; i < m_methods.length; i++) {
-            if (m_methods[i].getMethodName().equalsIgnoreCase(name)) {
-                if (mms.length > 0) {
-                    MethodMetadata[] newInstances = new MethodMetadata[mms.length + 1];
-                    System.arraycopy(mms, 0, newInstances, 0, mms.length);
-                    newInstances[mms.length] = m_methods[i];
-                    mms = newInstances;
-                } else {
-                    mms = new MethodMetadata[] { m_methods[i] };
-                }
+        List<MethodMetadata> list = new ArrayList<MethodMetadata>();
+        for (MethodMetadata metadata : m_methods) {
+            if (metadata.getMethodName().equalsIgnoreCase(name)) {
+                list.add(metadata);
             }
         }
-        return mms;
+        return list.toArray(new MethodMetadata[list.size()]);
     }
 
     /**
@@ -186,15 +242,15 @@ public class PojoMetadata {
      * @return the Method Metadata or <code>null</code> if not found
      */
     public MethodMetadata getMethod(String name, String[] types) {
-        for (int i = 0; i < m_methods.length; i++) {
-            if (m_methods[i].getMethodName().equalsIgnoreCase(name) && m_methods[i].getMethodArguments().length == types.length) {
+        for (MethodMetadata metadata : m_methods) {
+            if (metadata.getMethodName().equalsIgnoreCase(name) && metadata.getMethodArguments().length == types.length) {
                 int argIndex = 0;
                 for (; argIndex < types.length; argIndex++) {
-                    if (! types[argIndex].equals(m_methods[i].getMethodArguments()[argIndex])) {
+                    if (! types[argIndex].equals(metadata.getMethodArguments()[argIndex])) {
                         break;
                     }
                 }
-                if (argIndex == types.length) { return m_methods[i]; } // No mismatch detected.
+                if (argIndex == types.length) { return metadata; } // No mismatch detected.
             }
         }
         return null;
@@ -210,23 +266,6 @@ public class PojoMetadata {
     }
 
      /**
-     * Adds a method to the list.
-     * This method is used during the creation of the {@link PojoMetadata}
-     * object.
-     * @param method the Method Metadata to add.
-     */
-    private void addMethod(MethodMetadata method) {
-        if (m_methods.length > 0) {
-            MethodMetadata[] newInstances = new MethodMetadata[m_methods.length + 1];
-            System.arraycopy(m_methods, 0, newInstances, 0, m_methods.length);
-            newInstances[m_methods.length] = method;
-            m_methods = newInstances;
-        } else {
-            m_methods = new MethodMetadata[] { method };
-        }
-    }
-
-     /**
      * Adds a field to the list.
      * This method is used during the creation of the {@link PojoMetadata}
      * object.