Author: nfilotto
Date: 2010-06-16 08:54:31 -0400 (Wed, 16 Jun 2010)
New Revision: 2632
Added:
kernel/trunk/exo.kernel.container/src/test/java/org/exoplatform/container/configuration/TestComponentPlugin.java
kernel/trunk/exo.kernel.container/src/test/resources/org/exoplatform/container/configuration/test-component-plugin-configuration.xml
Modified:
kernel/trunk/exo.kernel.container/src/main/java/org/exoplatform/container/jmx/MX4JComponentAdapter.java
Log:
EXOJCR-786: The method that registers plugins should be overloadable.
Now we can use the same method name to register different plugin types, the kernel will
use the method that matches the best with the type of the plugin
Modified:
kernel/trunk/exo.kernel.container/src/main/java/org/exoplatform/container/jmx/MX4JComponentAdapter.java
===================================================================
---
kernel/trunk/exo.kernel.container/src/main/java/org/exoplatform/container/jmx/MX4JComponentAdapter.java 2010-06-16
12:49:06 UTC (rev 2631)
+++
kernel/trunk/exo.kernel.container/src/main/java/org/exoplatform/container/jmx/MX4JComponentAdapter.java 2010-06-16
12:54:31 UTC (rev 2632)
@@ -137,13 +137,19 @@
try
{
- Class clazz = Class.forName(plugin.getType());
- ComponentPlugin cplugin = (ComponentPlugin)container.createComponent(clazz,
plugin.getInitParams());
+ Class pluginClass = Class.forName(plugin.getType());
+ ComponentPlugin cplugin =
(ComponentPlugin)container.createComponent(pluginClass, plugin.getInitParams());
cplugin.setName(plugin.getName());
cplugin.setDescription(plugin.getDescription());
- clazz = component.getClass();
+ Class clazz = component.getClass();
- Method m = getSetMethod(clazz, plugin.getSetMethod());
+ Method m = getSetMethod(clazz, plugin.getSetMethod(), pluginClass);
+ if (m == null)
+ {
+ log.error("Cannot find the method '" + plugin.getSetMethod()
+ "' that has only one parameter of type '"
+ + pluginClass.getName() + "' in the class '" +
clazz.getName() + "'.");
+ continue;
+ }
Object[] params = {cplugin};
m.invoke(component, params);
if (debug)
@@ -160,9 +166,18 @@
}
}
- private Method getSetMethod(Class clazz, String name)
+ /**
+ * Finds the best "set method" according to the given method name and type
of plugin
+ * @param clazz the {@link Class} of the target component
+ * @param name the name of the method
+ * @param pluginClass the {@link Class} of the plugin
+ * @return the "set method" corresponding to the given context
+ */
+ private Method getSetMethod(Class clazz, String name, Class pluginClass)
{
Method[] methods = clazz.getMethods();
+ Method bestCandidate = null;
+ int depth = -1;
for (Method m : methods)
{
if (name.equals(m.getName()))
@@ -170,13 +185,51 @@
Class[] types = m.getParameterTypes();
if (types != null && types.length == 1 &&
ComponentPlugin.class.isAssignableFrom(types[0]))
{
- return m;
+ int currentDepth = getClosestMatchDepth(pluginClass, types[0]);
+ if (currentDepth == 0)
+ {
+ return m;
+ }
+ else if (depth == -1 || depth > currentDepth)
+ {
+ bestCandidate = m;
+ depth = currentDepth;
+ }
}
}
}
- return null;
+ return bestCandidate;
}
+ /**
+ * Check if the given plugin class is assignable from the given type, if not we
recheck with its parent class
+ * until we find the closest match.
+ * @param pluginClass the class of the plugin
+ * @param type the class from which the plugin must be assignable
+ * @return The total amount of times we had to up the hierarchy of the plugin
+ */
+ private static int getClosestMatchDepth(Class pluginClass, Class type)
+ {
+ return getClosestMatchDepth(pluginClass, type, 0);
+ }
+
+ /**
+ * Check if the given plugin class is assignable from the given type, if not we
recheck with its parent class
+ * until we find the closest match.
+ * @param pluginClass the class of the plugin
+ * @param type the class from which the plugin must be assignable
+ * @param depth the current amount of times that we had to up the hierarchy of the
plugin
+ * @return The total amount of times we had to up the hierarchy of the plugin
+ */
+ private static int getClosestMatchDepth(Class pluginClass, Class type, int depth)
+ {
+ if (pluginClass == null || pluginClass.isAssignableFrom(type))
+ {
+ return depth;
+ }
+ return getClosestMatchDepth(pluginClass.getSuperclass(), type, depth + 1);
+ }
+
public void verify(PicoContainer container)
{
}
Added:
kernel/trunk/exo.kernel.container/src/test/java/org/exoplatform/container/configuration/TestComponentPlugin.java
===================================================================
---
kernel/trunk/exo.kernel.container/src/test/java/org/exoplatform/container/configuration/TestComponentPlugin.java
(rev 0)
+++
kernel/trunk/exo.kernel.container/src/test/java/org/exoplatform/container/configuration/TestComponentPlugin.java 2010-06-16
12:54:31 UTC (rev 2632)
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.exoplatform.container.configuration;
+
+import org.exoplatform.container.RootContainer;
+import org.exoplatform.container.component.ComponentPlugin;
+import org.exoplatform.container.jmx.AbstractTestContainer;
+
+/**
+ * @author <a href="mailto:nicolas.filotto@exoplatform.com">Nicolas
Filotto</a>
+ * @version $Id$
+ *
+ */
+public class TestComponentPlugin extends AbstractTestContainer
+{
+ public void testComponentPluginOverloading()
+ {
+ RootContainer rootContainer =
createRootContainer("test-component-plugin-configuration.xml");
+ A a = (A)rootContainer.getComponentInstanceOfType(A.class);
+ assertNotNull(a);
+ assertEquals(1, a.countRegisterCP);
+ assertEquals(1, a.countRegisterACP);
+ assertEquals(2, a.countRegisterCP1);
+ }
+
+ public static class A
+ {
+ public int countRegisterCP;
+
+ public int countRegisterACP;
+
+ public int countRegisterCP1;
+
+ public void register(ComponentPlugin plugin)
+ {
+ countRegisterCP++;
+ }
+
+ public void register(AComponentPlugin plugin)
+ {
+ countRegisterACP++;
+ }
+
+ public void register(ComponentPlugin1 plugin)
+ {
+ countRegisterCP1++;
+ }
+
+ }
+
+ public static abstract class AComponentPlugin implements ComponentPlugin
+ {
+
+ public String getDescription()
+ {
+ return null;
+ }
+
+ public String getName()
+ {
+ return null;
+ }
+
+ public void setDescription(String s)
+ {
+ }
+
+ public void setName(String s)
+ {
+ }
+ }
+
+ public static class ComponentPlugin1 extends AComponentPlugin
+ {
+ }
+
+ public static class ComponentPlugin2 extends AComponentPlugin
+ {
+ }
+
+ public static class ComponentPlugin3 extends ComponentPlugin1
+ {
+ }
+
+ public static class ComponentPlugin4 implements ComponentPlugin
+ {
+
+ public String getDescription()
+ {
+ return null;
+ }
+
+ public String getName()
+ {
+ return null;
+ }
+
+ public void setDescription(String s)
+ {
+ }
+
+ public void setName(String s)
+ {
+ }
+ }
+}
Added:
kernel/trunk/exo.kernel.container/src/test/resources/org/exoplatform/container/configuration/test-component-plugin-configuration.xml
===================================================================
---
kernel/trunk/exo.kernel.container/src/test/resources/org/exoplatform/container/configuration/test-component-plugin-configuration.xml
(rev 0)
+++
kernel/trunk/exo.kernel.container/src/test/resources/org/exoplatform/container/configuration/test-component-plugin-configuration.xml 2010-06-16
12:54:31 UTC (rev 2632)
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+
+ Copyright (C) 2009 eXo Platform SAS.
+
+ This is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ This software is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this software; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+
+-->
+<configuration
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd
http://www.exoplaform.org/xml/ns/kernel_1_1.xsd"
+
xmlns="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd">
+
+ <component>
+
<type>org.exoplatform.container.configuration.TestComponentPlugin$A</type>
+ <component-plugins>
+ <component-plugin>
+ <name>Plugin1</name>
+ <set-method>register</set-method>
+
<type>org.exoplatform.container.configuration.TestComponentPlugin$ComponentPlugin1</type>
+ </component-plugin>
+ <component-plugin>
+ <name>Plugin2</name>
+ <set-method>register</set-method>
+
<type>org.exoplatform.container.configuration.TestComponentPlugin$ComponentPlugin2</type>
+ </component-plugin>
+ <component-plugin>
+ <name>Plugin3</name>
+ <set-method>register</set-method>
+
<type>org.exoplatform.container.configuration.TestComponentPlugin$ComponentPlugin3</type>
+ </component-plugin>
+ <component-plugin>
+ <name>Plugin4</name>
+ <set-method>register</set-method>
+
<type>org.exoplatform.container.configuration.TestComponentPlugin$ComponentPlugin4</type>
+ </component-plugin>
+ </component-plugins>
+ </component>
+
+</configuration>
\ No newline at end of file