Return-Path: Delivered-To: apmail-felix-commits-archive@www.apache.org Received: (qmail 65758 invoked from network); 23 Dec 2010 13:21:35 -0000 Received: from unknown (HELO mail.apache.org) (140.211.11.3) by 140.211.11.9 with SMTP; 23 Dec 2010 13:21:35 -0000 Received: (qmail 34093 invoked by uid 500); 23 Dec 2010 13:21:35 -0000 Delivered-To: apmail-felix-commits-archive@felix.apache.org Received: (qmail 34005 invoked by uid 500); 23 Dec 2010 13:21:35 -0000 Mailing-List: contact commits-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list commits@felix.apache.org Received: (qmail 33997 invoked by uid 99); 23 Dec 2010 13:21:34 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 23 Dec 2010 13:21:34 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 23 Dec 2010 13:21:26 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id ED94D23888CE; Thu, 23 Dec 2010 13:20:47 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1052264 [1/2] - in /felix/trunk/ipojo: ./ annotations/src/main/java/org/apache/felix/ipojo/annotations/ core/src/main/java/org/apache/felix/ipojo/ core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ core/src/main/java/org/apa... Date: Thu, 23 Dec 2010 13:20:47 -0000 To: commits@felix.apache.org From: clement@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20101223132047.ED94D23888CE@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: clement Date: Thu Dec 23 13:20:45 2010 New Revision: 1052264 URL: http://svn.apache.org/viewvc?rev=1052264&view=rev Log: Integrate the constructor-injection branch into the trunk. Added: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ConstructorInjector.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/core/src/main/java/org/apache/felix/ipojo/ConstructorInjector.java felix/trunk/ipojo/core/src/test/java/org/apache/felix/ipojo/parser/ - copied from r1052244, felix/sandbox/clement/ipojo-constructor-injection/core/src/test/java/org/apache/felix/ipojo/parser/ felix/trunk/ipojo/core/src/test/java/org/apache/felix/ipojo/parser/ManipulationMetadataTest.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/core/src/test/java/org/apache/felix/ipojo/parser/ManipulationMetadataTest.java felix/trunk/ipojo/core/src/test/java/org/apache/felix/ipojo/parser/PojoMetadataTest.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/core/src/test/java/org/apache/felix/ipojo/parser/PojoMetadataTest.java felix/trunk/ipojo/core/src/test/resources/ - copied from r1052244, felix/sandbox/clement/ipojo-constructor-injection/core/src/test/resources/ felix/trunk/ipojo/core/src/test/resources/manipulation/ - copied from r1052244, felix/sandbox/clement/ipojo-constructor-injection/core/src/test/resources/manipulation/ felix/trunk/ipojo/core/src/test/resources/manipulation/MANIFEST.MF - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/core/src/test/resources/manipulation/MANIFEST.MF felix/trunk/ipojo/manipulator/src/test/ - copied from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/ felix/trunk/ipojo/manipulator/src/test/java/ - copied from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/ felix/trunk/ipojo/manipulator/src/test/java/org/ - copied from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/org/ felix/trunk/ipojo/manipulator/src/test/java/org/apache/ - copied from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/org/apache/ felix/trunk/ipojo/manipulator/src/test/java/org/apache/felix/ - copied from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/org/apache/felix/ felix/trunk/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/ - copied from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/org/apache/felix/ipojo/ felix/trunk/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/ComponentInstance.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/org/apache/felix/ipojo/ComponentInstance.java felix/trunk/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/InstanceManager.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/org/apache/felix/ipojo/InstanceManager.java felix/trunk/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/Pojo.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/org/apache/felix/ipojo/Pojo.java felix/trunk/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/ - copied from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/ felix/trunk/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/ManipulatorTest.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/ManipulatorTest.java felix/trunk/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/PojoizationTest.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/PojoizationTest.java felix/trunk/ipojo/manipulator/src/test/java/test/ - copied from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/test/ felix/trunk/ipojo/manipulator/src/test/java/test/Child.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/test/Child.java felix/trunk/ipojo/manipulator/src/test/java/test/Constructor.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/test/Constructor.java felix/trunk/ipojo/manipulator/src/test/java/test/NoValidConstructor.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/test/NoValidConstructor.java felix/trunk/ipojo/manipulator/src/test/java/test/Parent.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/test/Parent.java felix/trunk/ipojo/manipulator/src/test/java/test/PojoWithInner.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/test/PojoWithInner.java felix/trunk/ipojo/manipulator/src/test/java/test/SimplePojo.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/java/test/SimplePojo.java felix/trunk/ipojo/manipulator/src/test/resources/ - copied from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/resources/ felix/trunk/ipojo/manipulator/src/test/resources/metadata.xml - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/resources/metadata.xml felix/trunk/ipojo/manipulator/src/test/resources/tests.manipulation-no-annotations.jar - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/resources/tests.manipulation-no-annotations.jar felix/trunk/ipojo/manipulator/src/test/resources/tests.manipulation.java5.jar - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/resources/tests.manipulation.java5.jar felix/trunk/ipojo/manipulator/src/test/resources/tests.manipulator-annotations.jar - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/manipulator/src/test/resources/tests.manipulator-annotations.jar felix/trunk/ipojo/tests/manipulator/metadata/src/main/java/org/apache/felix/ipojo/test/scenarios/component/Child.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/tests/manipulator/metadata/src/main/java/org/apache/felix/ipojo/test/scenarios/component/Child.java felix/trunk/ipojo/tests/manipulator/metadata/src/main/java/org/apache/felix/ipojo/test/scenarios/component/Multiconstructor.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/tests/manipulator/metadata/src/main/java/org/apache/felix/ipojo/test/scenarios/component/Multiconstructor.java felix/trunk/ipojo/tests/manipulator/metadata/src/main/java/org/apache/felix/ipojo/test/scenarios/component/Parent.java - copied unchanged from r1052244, felix/sandbox/clement/ipojo-constructor-injection/tests/manipulator/metadata/src/main/java/org/apache/felix/ipojo/test/scenarios/component/Parent.java Modified: felix/trunk/ipojo/ (props changed) felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Property.java felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Requires.java felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManagerFactory.java felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java felix/trunk/ipojo/handler/eventadmin/ (props changed) felix/trunk/ipojo/handler/eventadmin/metadata.xml (props changed) felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/EventUtil.java (props changed) felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/ (props changed) felix/trunk/ipojo/handler/extender/ (props changed) felix/trunk/ipojo/handler/jmx/ (props changed) felix/trunk/ipojo/handler/temporal/ (props changed) felix/trunk/ipojo/handler/whiteboard/ (props changed) felix/trunk/ipojo/manipulator/pom.xml felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/CustomAnnotationVisitor.java felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java felix/trunk/ipojo/tests/composite/composite-runtime/ (props changed) felix/trunk/ipojo/tests/composite/import-export/ (props changed) felix/trunk/ipojo/tests/composite/service-instance/ (props changed) felix/trunk/ipojo/tests/composite/service-providing/ (props changed) felix/trunk/ipojo/tests/core/annotations/ (props changed) felix/trunk/ipojo/tests/core/bad-configurations/ (props changed) felix/trunk/ipojo/tests/core/configuration/ (props changed) felix/trunk/ipojo/tests/core/external-handlers/ (props changed) felix/trunk/ipojo/tests/core/factories/ (props changed) felix/trunk/ipojo/tests/core/lifecycle-callback/ (props changed) felix/trunk/ipojo/tests/core/lifecycle-controller/ (props changed) felix/trunk/ipojo/tests/core/service-dependency/ (props changed) felix/trunk/ipojo/tests/core/service-dependency-bindingpolicy/ (props changed) felix/trunk/ipojo/tests/core/service-dependency-filter/ (props changed) felix/trunk/ipojo/tests/core/service-providing/ (props changed) felix/trunk/ipojo/tests/handler/temporal/ (props changed) felix/trunk/ipojo/tests/handler/whiteboard/ (props changed) felix/trunk/ipojo/tests/manipulator/manipulation/ (props changed) felix/trunk/ipojo/tests/manipulator/metadata/src/main/resources/metadata.xml Propchange: felix/trunk/ipojo/ ------------------------------------------------------------------------------ --- svn:mergeinfo (added) +++ svn:mergeinfo Thu Dec 23 13:20:45 2010 @@ -0,0 +1 @@ +/felix/sandbox/clement/ipojo-constructor-injection:1044402-1052244 Modified: felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Property.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Property.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Property.java (original) +++ felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Property.java Thu Dec 23 13:20:45 2010 @@ -1,4 +1,4 @@ -/* +/* * 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 @@ -26,25 +26,25 @@ import java.lang.annotation.Target; * It can target both fields and methods. * @author Felix Project Team */ -@Target({ ElementType.FIELD, ElementType.METHOD }) +@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER }) public @interface Property { - + /** * Set property name. * Default : empty */ String name() default ""; - + /** * Set property value. * Default : empty */ String value() default ""; - + /** * Is the property mandatory? * Default: false */ boolean mandatory() default false; - + } Modified: felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Requires.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Requires.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Requires.java (original) +++ felix/trunk/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Requires.java Thu Dec 23 13:20:45 2010 @@ -1,4 +1,4 @@ -/* +/* * 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 @@ -27,34 +27,34 @@ import java.util.Comparator; * This annotation declares a service requirement. * @author Felix Project Team */ -@Target(ElementType.FIELD) +@Target({ ElementType.FIELD, ElementType.PARAMETER }) @Inherited public @interface Requires { - + /** * Set the LDAP filter of the dependency. * Default : no filter */ String filter() default ""; - + /** * Set if the dependency is optional. * Default : false */ boolean optional() default false; - + /** * Set the dependency id. * Default : empty */ String id() default ""; - + /** * Enable / Disable nullable pattern. * Default : true */ boolean nullable() default true; - + /** * Set the default-implementation to use if the dependency is optional, * and no providers are available. @@ -62,31 +62,31 @@ public @interface Requires { * Default : no default-implementation */ Class defaultimplementation() default Class.class; - + /** * Set the binding policy. * Acceptable policy are dynamic, static and dynamic-priority. * Default: dynamic. */ String policy() default "dynamic"; - + /** * Set the comparator. * The indicated class must implement {@link Comparator} */ Class comparator() default Comparator.class; - + /** * Set the from attribute. */ String from() default ""; - + /** * Set the required service specification. * This attribute is required for Collection field. */ String specification() default ""; - + /** * Set to true if the service dependency is injected * as a proxy. Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java (original) +++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java Thu Dec 23 13:20:45 2010 @@ -35,6 +35,7 @@ import org.apache.felix.ipojo.parser.Poj import org.apache.felix.ipojo.util.Logger; import org.apache.felix.ipojo.util.Tracker; import org.apache.felix.ipojo.util.TrackerCustomizer; +import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; @@ -291,7 +292,7 @@ public class ComponentFactory extends IP Element[] elems = m_componentMetadata.getElements(); for (int i = 0; i < elems.length; i++) { Element current = elems[i]; - if (!"manipulation".equals(current.getName())) { + if (!"manipulation".equals(current.getName())) { // Remove the manipulation element RequiredHandler req = new RequiredHandler(current.getName(), current.getNameSpace()); if (!list.contains(req)) { list.add(req); Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java (original) +++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java Thu Dec 23 13:20:45 2010 @@ -1,4 +1,4 @@ -/* +/* * 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 @@ -82,7 +82,7 @@ public class HandlerManager extends Inst if (m_handler != null) { return; } m_handler = (Handler) createPojoObject(); } - + /** * Creates an instance of the content. * This method needs to be called once only for singleton provided service. @@ -103,9 +103,9 @@ public class HandlerManager extends Inst } m_pojoObjects.add(instance); } - + //Do not call onCreation, this will be done in the start method. - + return instance; } @@ -114,9 +114,9 @@ public class HandlerManager extends Inst */ public void start() { synchronized (this) { - if (m_state != STOPPED) { + if (m_state != STOPPED) { return; // Instance already started - } else { + } else { m_state = -2; // Temporary starting state, avoiding concurrent starts. } } @@ -126,16 +126,16 @@ public class HandlerManager extends Inst m_handlers[i].addInstanceStateListener(this); m_handlers[i].start(); } - + // Call the onCreation method. for (int i = 0; i < m_handlers.length; i++) { ((PrimitiveHandler) m_handlers[i].getHandler()).onCreation(m_handler); } - + m_handler.start(); // Call the handler start method, the instance might be invalid. - - + + for (int i = 0; i < m_handlers.length; i++) { if (!m_handlers[i].getHandler().isValid()) { setState(INVALID); @@ -147,7 +147,7 @@ public class HandlerManager extends Inst } else { setState(INVALID); } - + // Now, the state is necessary different from the temporary state. } @@ -156,10 +156,10 @@ public class HandlerManager extends Inst */ public void stop() { synchronized (this) { - if (m_state == STOPPED) { + if (m_state == STOPPED) { return; // Instance already stopped } else { - m_state = -2; // Temporary state avoiding concurrent stopping. + m_state = -2; // Temporary state avoiding concurrent stopping. } } @@ -182,7 +182,7 @@ public class HandlerManager extends Inst listeners = new ArrayList(m_listeners); // Stack confinement. } } - + if (listeners != null) { for (int i = 0; i < listeners.size(); i++) { ((InstanceStateListener) listeners.get(i)).stateChanged(this, STOPPED); @@ -190,7 +190,7 @@ public class HandlerManager extends Inst } } - /** + /** * Disposes the instance. * @see org.apache.felix.ipojo.ComponentInstance#dispose() */ @@ -211,14 +211,14 @@ public class HandlerManager extends Inst /** * State Change listener callback. * This method is notified at each time a plugged handler becomes invalid. - * @param instance the changing instance + * @param instance the changing instance * @param newState the new state * @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int) */ public void stateChanged(ComponentInstance instance, int newState) { int state; synchronized (this) { - if (m_state <= STOPPED) { + if (m_state <= STOPPED) { return; } else { state = m_state; // Stack confinement Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManagerFactory.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManagerFactory.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManagerFactory.java (original) +++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManagerFactory.java Thu Dec 23 13:20:45 2010 @@ -152,7 +152,7 @@ public class HandlerManagerFactory exten Element[] elems = m_componentMetadata.getElements(); for (int i = 0; i < elems.length; i++) { Element current = elems[i]; - if (!"manipulation".equals(current.getName())) { + if (!"manipulation".equals(current.getName())) { // Remove the manipulation element RequiredHandler req = new RequiredHandler(current.getName(), current.getNameSpace()); if (!list.contains(req)) { Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java (original) +++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java Thu Dec 23 13:20:45 2010 @@ -105,12 +105,20 @@ public class InstanceManager implements private Map m_fieldRegistration; /** - * the map [method identifier, {@link MethodInterceptor} list] storing handlers interested by the method. - * Once configure this map can't change. + * the map [method identifier, {@link MethodInterceptor} list] interested + * by the method. + * Once configured, this map can't change. */ private Map m_methodRegistration; /** + * the map (sorted by parameter index) or {@link ConstructorInjector} interested by + * injecting constructor parameter. + * Once configured, this list can't change. + */ + private Map m_constructorRegistration; + + /** * The manipulated class. * Once set, this field doesn't change. */ @@ -197,6 +205,15 @@ public class InstanceManager implements for (int i = 0; i < m_handlers.length; i++) { m_handlers[i].init(this, metadata, configuration); } + + // Check that the constructor parameter are continuous. + if (m_constructorRegistration != null) { + for (int i = 0; i < m_constructorRegistration.size(); i++) { + if (! m_constructorRegistration.containsKey(new Integer(i))) { + throw new ConfigurationException("The constructor parameter " + i + " is not managed"); + } + } + } } /** @@ -416,6 +433,7 @@ public class InstanceManager implements m_fields.clear(); m_fieldRegistration = new HashMap(); m_methodRegistration = new HashMap(); + m_constructorRegistration = new HashMap(); m_clazz = null; } } @@ -595,29 +613,65 @@ public class InstanceManager implements if (m_factoryMethod == null) { // No factory-method, we use the constructor. try { - // Try to find if there is a constructor with a bundle context as parameter : - try { - Constructor cst = m_clazz.getDeclaredConstructor(new Class[] { InstanceManager.class, BundleContext.class }); - if (! cst.isAccessible()) { + // Try to find the correct constructor. + if (m_constructorRegistration != null) { + // Initialize the injected values and types + // We have the IM first. + Object[] values = new Object[m_constructorRegistration.size() + 1]; + Class[] types = new Class[m_constructorRegistration.size() + 1]; + values[0] = this; + types[0] = InstanceManager.class; + + // Iterate over the constructor injector + for (int i = 0; i < m_constructorRegistration.size(); i++) { + ConstructorInjector injector = (ConstructorInjector) + m_constructorRegistration.get(new Integer(i)); + Object v = injector.getConstructorParameter(i); + if (v != null) { + values[i + 1] = v; + Class t = injector.getConstructorParameterType(i); + if (t == null) { + t = v.getClass(); + } + types[i + 1] = t; + } + } + // Find the constructor. + Constructor cst = m_clazz.getDeclaredConstructor(types); + if (! cst.isAccessible()) { cst.setAccessible(true); } - Object[] args = new Object[] { this, m_context }; - onEntry(null, MethodMetadata.BC_CONSTRUCTOR_ID, new Object[] {m_context}); - instance = cst.newInstance(args); - onExit(instance, MethodMetadata.BC_CONSTRUCTOR_ID, instance); - } catch (NoSuchMethodException e) { - // Create an instance if no instance are already created with ()BundleContext - if (instance == null) { - Constructor cst = m_clazz.getDeclaredConstructor(new Class[] { InstanceManager.class }); + String methodId = MethodMetadata.computeMethodId(cst); + onEntry(null, methodId, values); + instance = cst.newInstance(values); + onExit(instance, methodId, instance); + } else { + // Old semantic + // Try to find if there is a constructor with a bundle context as parameter : + try { + Constructor cst = m_clazz.getDeclaredConstructor(new Class[] { InstanceManager.class, BundleContext.class }); if (! cst.isAccessible()) { cst.setAccessible(true); } - Object[] args = new Object[] {this}; - onEntry(null, MethodMetadata.EMPTY_CONSTRUCTOR_ID, new Object[0]); + Object[] args = new Object[] { this, m_context }; + onEntry(null, MethodMetadata.BC_CONSTRUCTOR_ID, new Object[] {m_context}); instance = cst.newInstance(args); - onExit(instance, MethodMetadata.EMPTY_CONSTRUCTOR_ID, instance); + onExit(instance, MethodMetadata.BC_CONSTRUCTOR_ID, instance); + } catch (NoSuchMethodException e) { + // Create an instance if no instance are already created with ()BundleContext + if (instance == null) { + Constructor cst = m_clazz.getDeclaredConstructor(new Class[] { InstanceManager.class }); + if (! cst.isAccessible()) { + cst.setAccessible(true); + } + Object[] args = new Object[] {this}; + onEntry(null, MethodMetadata.EMPTY_CONSTRUCTOR_ID, new Object[0]); + instance = cst.newInstance(args); + onExit(instance, MethodMetadata.EMPTY_CONSTRUCTOR_ID, instance); + } } - } + } + } catch (IllegalAccessException e) { m_logger.log(Logger.ERROR, "[" + m_name + "] createInstance -> The POJO constructor is not accessible : " + e.getMessage(), e); @@ -937,6 +991,29 @@ public class InstanceManager implements } /** + * Registers a constructor injector. + * The constructor injector will be called when a pojo object is going to be + * created. + * @param index the index of the parameter. Only one injector per index can + * be registered. + * @param injector the injector object. + * @throws ConfigurationException if the given index is already injected by another + * injector + */ + public void register(int index, ConstructorInjector injector) throws ConfigurationException { + Integer key = new Integer(index); + if (m_constructorRegistration == null) { + m_constructorRegistration = new HashMap(); + } + if (! m_constructorRegistration.containsKey(key)) { + m_constructorRegistration.put(key, injector); + } else { + throw new ConfigurationException("Another constructor injector " + + "manages the parameter " + index); + } + } + + /** * This method is called by the manipulated class each time that a GETFIELD instruction is executed. * The method asks to each attached handler monitoring this field which value need * to be injected (i.e. returned) by invoking the {@link PrimitiveHandler#onGet(Object, String, Object)} Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java (original) +++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java Thu Dec 23 13:20:45 2010 @@ -33,7 +33,8 @@ import org.apache.felix.ipojo.util.Logge * Classes overriding this class can change the behavior of those methods. * @author Felix Project Team */ -public abstract class PrimitiveHandler extends Handler implements FieldInterceptor, MethodInterceptor { +public abstract class PrimitiveHandler extends Handler implements FieldInterceptor, MethodInterceptor, + ConstructorInjector { /** * The "Primitive" Handler type (value). @@ -159,6 +160,32 @@ public abstract class PrimitiveHandler e } /** + * Gets the object to inject as a constructor parameter + * @param index the index of the parameter + * @return the object to inject, or null if no + * objects are injected. This implementation returns null + * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameter(int) + */ + public Object getConstructorParameter(int index) { + return null; + } + + /** + * Gets the type of the object to inject in the constructor parameter. + * This is the type looked into the Pojo class, so it must match. + * Returning null will try to get the class from the + * injected object, however this can be wrong (implementation instead of interface, + * boxed objects...) and error-prone. + * @param index the parameter index + * @return the Class object (must fit for primitive type), this implementation + * just returns null + * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameterType(int) + */ + public Class getConstructorParameterType(int index) { + return null; + } + + /** * Callback method called when a method will be invoked. * This default implementation does nothing. * @param pojo the pojo on which the method is called. Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java (original) +++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java Thu Dec 23 13:20:45 2010 @@ -123,17 +123,21 @@ public class ConfigurationHandler extend for (int i = 0; configurables != null && i < configurables.length; i++) { String fieldName = configurables[i].getAttribute("field"); String methodName = configurables[i].getAttribute("method"); + String paramIndex = configurables[i].getAttribute("constructor-parameter"); - if (fieldName == null && methodName == null) { - throw new ConfigurationException("Malformed property : The property needs to contain at least a field or a method"); + if (fieldName == null && methodName == null && paramIndex == null) { + throw new ConfigurationException("Malformed property : The property needs to contain" + + " at least a field, a method or a constructor-parameter"); } String name = configurables[i].getAttribute("name"); if (name == null) { - if (fieldName == null) { + if (fieldName == null && methodName != null) { name = methodName; + } else if (fieldName == null && paramIndex != null) { + name = paramIndex; } else { - name = fieldName; + name = fieldName; } configurables[i].addAttribute(new Attribute("name", name)); // Add the type to avoid configure checking } @@ -143,7 +147,7 @@ public class ConfigurationHandler extend // Detect the type of the property PojoMetadata manipulation = getFactory().getPojoMetadata(); String type = null; - if (fieldName == null) { + if (methodName != null) { MethodMetadata[] method = manipulation.getMethods(methodName); if (method.length == 0) { type = configurables[i].getAttribute("type"); @@ -157,11 +161,24 @@ public class ConfigurationHandler extend type = method[0].getMethodArguments()[0]; configurables[i].addAttribute(new Attribute("type", type)); // Add the type to avoid configure checking } - } else { + } else if (fieldName != null) { FieldMetadata field = manipulation.getField(fieldName); if (field == null) { throw new ConfigurationException("Malformed property : The field " + fieldName + " does not exist in the implementation class"); } type = field.getFieldType(); configurables[i].addAttribute(new Attribute("type", type)); // Add the type to avoid configure checking + } else if (paramIndex != null) { + int index = Integer.parseInt(paramIndex); + type = configurables[i].getAttribute("type"); + MethodMetadata[] cts = manipulation.getConstructors(); + // If we don't have a type, try to get the first constructor and get the type of the parameter + // we the index 'index'. + if (type == null && cts.length > 0 && cts[0].getMethodArguments().length > index) { + type = cts[0].getMethodArguments()[index]; + } else if (type == null) { // Applied only if type was not determined. + throw new ConfigurationException("Cannot determine the type of the property " + index + + ", please use the type attribute"); + } + configurables[i].addAttribute(new Attribute("type", type)); } // Is the property set to immutable @@ -240,13 +257,22 @@ public class ConfigurationHandler extend for (int i = 0; configurables != null && i < configurables.length; i++) { String fieldName = configurables[i].getAttribute("field"); String methodName = configurables[i].getAttribute("method"); + String paramIndex = configurables[i].getAttribute("constructor-parameter"); + int index = -1; String name = configurables[i].getAttribute("name"); // The initialize method has fixed the property name. String value = configurables[i].getAttribute("value"); String type = configurables[i].getAttribute("type"); // The initialize method has fixed the property name. - Property prop = new Property(name, fieldName, methodName, value, type, getInstanceManager(), this); + Property prop = null; + if (paramIndex == null) { + prop = new Property(name, fieldName, methodName, value, type, getInstanceManager(), this); + } else { + index = Integer.parseInt(paramIndex); + prop = new Property(name, fieldName, methodName, index, + value, type, getInstanceManager(), this); + } addProperty(prop); // Check if the instance configuration contains value for the current property : @@ -262,6 +288,10 @@ public class ConfigurationHandler extend FieldMetadata field = new FieldMetadata(fieldName, type); getInstanceManager().register(field, prop); } + + if (index != -1) { + getInstanceManager().register(index, prop); + } } m_description = new ConfigurationHandlerDescription(this, m_configurableProperties, m_managedServicePID); Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java (original) +++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java Thu Dec 23 13:20:45 2010 @@ -32,6 +32,8 @@ import java.util.List; import java.util.Set; import java.util.Vector; +import org.apache.felix.ipojo.ConfigurationException; +import org.apache.felix.ipojo.ConstructorInjector; import org.apache.felix.ipojo.FieldInterceptor; import org.apache.felix.ipojo.InstanceManager; import org.apache.felix.ipojo.MethodInterceptor; @@ -47,7 +49,8 @@ import org.osgi.framework.ServiceReferen * Represent a service dependency of the component instance. * @author Felix Project Team */ -public class Dependency extends DependencyModel implements FieldInterceptor, MethodInterceptor { +public class Dependency extends DependencyModel implements FieldInterceptor, MethodInterceptor, + ConstructorInjector { /** * Reference on the Dependency Handler. @@ -84,7 +87,7 @@ public class Dependency extends Dependen /** * Thread Local. */ - private final ServiceUsage m_usage; + private ServiceUsage m_usage; /** * Type of the object to inject. @@ -125,6 +128,12 @@ public class Dependency extends Dependen private Object m_proxyObject; /** + * Constructor paramter index. + * -1 if not used. + */ + private int m_index = -1; + + /** * Dependency constructor. After the creation the dependency is not started. * * @param handler : the dependency handler managing this dependency @@ -163,6 +172,7 @@ public class Dependency extends Dependen } else { m_id = identity; } + // Else wait the setSpecification call. } @@ -201,6 +211,13 @@ public class Dependency extends Dependen } } + + protected void addConstructorInjection(int index) throws ConfigurationException { + m_index = index; + m_usage = new ServiceUsage(); + m_handler.getInstanceManager().register(index, this); + } + /** * Stop the current dependency. * @see org.apache.felix.ipojo.util.DependencyModel#stop() @@ -998,6 +1015,53 @@ public class Dependency extends Dependen } + /** + * Gets the constructor parameter. + * @return the index of the constructor parameter, + * or -1 if not set. + */ + public int getConstructorParameterIndex() { + return m_index; + } + + /** + * Gets the object to inject in the constructor parameter. + * @param index the index of the parameter + * @return the created proxy object + * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameter(int) + */ + public Object getConstructorParameter(int index) { + if (m_index == index && m_proxyObject != null) { + return m_proxyObject; + } + return null; + } + + /** + * Gets the type of the constructor parameter. + * @param index the parameter index + * @return the class of the object. For scalar dependency, it's the + * specification, for aggregate it depends of the container object: + * {@link List} or {@link Set}. + * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameterType(int) + */ + public Class getConstructorParameterType(int index) { + if (m_index == index && m_proxyObject != null) { + if (isAggregate()) { + switch (m_type) { + case DependencyHandler.LIST: return List.class; + case DependencyHandler.SET : return Set.class; + //TODO We should also manage the Collection type. + default: return null; // Should never happen, it was checked before. + } + } else { + return getSpecification(); + } + } else { + return null; + } + } + } Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java (original) +++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java Thu Dec 23 13:20:45 2010 @@ -209,9 +209,11 @@ public class DependencyHandler extends P // Check the internal type of dependency String field = dep.getField(); DependencyCallback[] callbacks = dep.getCallbacks(); + int index = dep.getConstructorParameterIndex(); - if (callbacks == null && field == null) { - throw new ConfigurationException("A service requirement requires at least binding methods or a field"); + if (callbacks == null && field == null && index == -1) { + throw new ConfigurationException("A service requirement requires at least binding methods, " + + "a field or a constructor parameter"); } for (int i = 0; callbacks != null && i < callbacks.length; i++) { @@ -286,6 +288,41 @@ public class DependencyHandler extends P setSpecification(dep, type, true); // Throws an exception if the field type mismatch. } + // Constructor parameter + if (index != -1) { + if (! dep.isProxy()) { + throw new ConfigurationException("Services injected into constructor must be proxied"); + } + + MethodMetadata[] cts = manipulation.getConstructors(); + // If we don't have a type, try to get the first constructor and get the type of the parameter + // we the index 'index'. + if (cts.length > 0 && cts[0].getMethodArguments().length > index) { + String type = cts[0].getMethodArguments()[index]; + if (type.endsWith("[]")) { + throw new ConfigurationException("Services injected into constructor cannot be arrays"); + } else if (type.equals(List.class.getName()) || type.equals(Collection.class.getName())) { + dep.setType(LIST); + type = null; + } else if (type.equals(Vector.class.getName())) { + throw new ConfigurationException("Services injected into constructor cannot be Vectors"); + } else if (type.equals(Set.class.getName())) { + dep.setType(SET); + type = null; + } else { + if (dep.isAggregate()) { + throw new ConfigurationException("A required service is not correct : the constructor parameter " + + index + + " must be an aggregate type to support aggregate injections"); + } + } + setSpecification(dep, type, true); // Throws an exception if the field type mismatch. + } else { + throw new ConfigurationException("Cannot determine the specification of the dependency " + index + + ", please use the specification attribute"); + } + } + // Disable proxy on scalar dependency targeting non-interface specification if (! dep.isAggregate() && dep.isProxy()) { if (! dep.getSpecification().isInterface()) { @@ -317,7 +354,14 @@ public class DependencyHandler extends P // No found type (list and vector) if (dep.getSpecification() == null) { if (error) { - throw new ConfigurationException("Cannot discover the required specification for " + dep.getField()); + String id = dep.getId(); + if (id == null) { + id = dep.getField(); + if (id == null) { + id = Integer.toString(dep.getConstructorParameterIndex()); + } + } + throw new ConfigurationException("Cannot discover the required specification for " + id); } else { // If the specification is different, warn that we will override it. info("Cannot discover the required specification for " + dep.getField()); @@ -502,6 +546,13 @@ public class DependencyHandler extends P dep.addDependencyCallback(callback); } + // Add the constructor parameter if needed + String paramIndex = deps[i].getAttribute("constructor-parameter"); + if (paramIndex != null) { + int index = Integer.parseInt(paramIndex); + dep.addConstructorInjection(index); + } + // Check the dependency : if (checkDependency(dep, manipulation)) { addDependency(dep); Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java (original) +++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java Thu Dec 23 13:20:45 2010 @@ -1,4 +1,4 @@ -/* +/* * 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 @@ -18,6 +18,7 @@ */ package org.apache.felix.ipojo.parser; +import java.lang.reflect.Constructor; import java.lang.reflect.Method; import org.apache.felix.ipojo.metadata.Element; @@ -28,7 +29,7 @@ import org.apache.felix.ipojo.metadata.E * @author Felix Project Team */ public class MethodMetadata { - + /** * Empty Constructor Method Id. */ @@ -38,7 +39,7 @@ public class MethodMetadata { * Bundle Context Constructor Method Id. */ public static final String BC_CONSTRUCTOR_ID = "$init$org_osgi_framework_BundleContext"; - + /** * Constructor Prefix. */ @@ -50,12 +51,12 @@ public class MethodMetadata { private String m_name; /** - * The argument type array. + * The argument type array. */ private String[] m_arguments = new String[0]; /** - * The returned type. + * The returned type. */ private String m_return = "void"; @@ -110,7 +111,7 @@ public class MethodMetadata { } /** - * Computes the method id for the given Method object. + * Computes the method id for the given Method object. * @param method the Method object. * @return the method id. */ @@ -140,4 +141,36 @@ public class MethodMetadata { } return identifier.toString(); } + + /** + * Computes the method id for the given Constructor object. + * @param method the Method object. + * @return the method id. + */ + public static String computeMethodId(Constructor method) { + StringBuffer identifier = new StringBuffer("$init"); + Class[] args = method.getParameterTypes(); + for (int i = 0; i < args.length; i++) { + identifier.append('$'); // Argument separator. + if (args[i].isArray()) { + if (args[i].getComponentType().isPrimitive()) { + // Primitive array + identifier.append(FieldMetadata.getPrimitiveTypeByClass(args[i].getComponentType())); + } else { + // Object array + identifier.append(args[i].getComponentType().getName().replace('.', '_')); // Replace '.' by '_' + } + identifier.append("__"); // Add __ (array) + } else { + if (args[i].isPrimitive()) { + // Primitive type + identifier.append(FieldMetadata.getPrimitiveTypeByClass(args[i])); + } else { + // Object type + identifier.append(args[i].getName().replace('.', '_')); // Replace '.' by '_' + } + } + } + return identifier.toString(); + } } Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java (original) +++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java Thu Dec 23 13:20:45 2010 @@ -1,4 +1,4 @@ -/* +/* * 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 @@ -24,25 +24,25 @@ import org.apache.felix.ipojo.metadata.E /** * Manipulation Metadata allows getting information about the implementation class * without using reflection such as implemented interfaces, super class, - * methods and fields. + * methods and fields. * This method allows getting object to register {@link org.apache.felix.ipojo.FieldInterceptor} and * {@link org.apache.felix.ipojo.MethodInterceptor}. * @author Felix Project Team */ public class PojoMetadata { - + /** * The list of implemented interfaces. */ private String[] m_interfaces = new String[0]; - + /** * The list of fields. */ private FieldMetadata[] m_fields = new FieldMetadata[0]; - + /** - * The list of methods. + * The list of methods. */ private MethodMetadata[] m_methods = new MethodMetadata[0]; @@ -50,8 +50,8 @@ public class PojoMetadata { * The Super class (if null for {@link Object}). */ private String m_super; - - + + /** * Creates Pojo metadata. * Manipulation Metadata object are created from component type metadata by @@ -62,7 +62,7 @@ public class PojoMetadata { public PojoMetadata(Element metadata) throws ConfigurationException { Element[] elems = metadata.getElements("manipulation", ""); if (elems == null) { - throw new ConfigurationException("The component " + metadata.getAttribute("classname") + " has no manipulation metadata"); + throw new ConfigurationException("The component " + metadata.getAttribute("classname") + " has no manipulation metadata"); } Element manip = elems[0]; m_super = manip.getAttribute("super"); @@ -81,38 +81,38 @@ public class PojoMetadata { addInterface(itfs[i].getAttribute("name")); } } - + public MethodMetadata[] getMethods() { return m_methods; } - + public FieldMetadata[] getFields() { return m_fields; } - + public String[] getInterfaces() { return m_interfaces; } - + /** - * Gets the field metadata for the given name. + * Gets the field metadata for the given name. * @param name : the name of the field * @return the corresponding field metadata or null if not found */ - public FieldMetadata getField(String name) { + public FieldMetadata getField(String name) { for (int i = 0; i < m_fields.length; i++) { if (m_fields[i].getFieldName().equalsIgnoreCase(name)) { return m_fields[i]; } } return null; } - + /** - * Gets the field metadata for the given name and type. + * Gets the field metadata for the given name and type. * @param name : the name of the field * @param type : the type of the field * @return the corresponding field metadata or null if not found */ - public FieldMetadata getField(String name, String type) { + public FieldMetadata getField(String name, String type) { for (int i = 0; i < m_fields.length; i++) { if (m_fields[i].getFieldName().equalsIgnoreCase(name) && m_fields[i].getFieldType().equalsIgnoreCase(type)) { return m_fields[i]; } } return null; } - + /** * Checks if the given interface name is implemented. * This methods checks on interface directly implemented @@ -127,7 +127,7 @@ public class PojoMetadata { } return false; } - + /** * Gets the MethodMetadata corresponding to the method * (contained in the implementation class) with @@ -142,11 +142,11 @@ public class PojoMetadata { } return null; } - + /** * Gets the MethodMetadata list corresponding to the method * (contained in the implementation class) to given name. - * All methods contained in the implementation class matching + * All methods contained in the implementation class matching * with the name are in the returned list. * @param name the name of the method to look for. * @return the Method Metadata array or an empty array if not found @@ -154,7 +154,7 @@ public class PojoMetadata { 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 (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); @@ -167,13 +167,22 @@ public class PojoMetadata { } return mms; } - + + /** + * Gets the MethodMetadata list corresponding to the constructors + * (contained in the implementation class). + * @return the Method Metadata array or an empty array if not found + */ + public MethodMetadata[] getConstructors() { + return getMethods("$init"); + } + /** * Gets the MethodMetadata corresponding to the method - * (contained in the implementation class) to given name + * (contained in the implementation class) to given name * and argument types. * @param name the name of the method to look for. - * @param types the array of the argument types of the method + * @param types the array of the argument types of the method * @return the Method Metadata or null if not found */ public MethodMetadata getMethod(String name, String[] types) { @@ -190,7 +199,16 @@ public class PojoMetadata { } return null; } - + + /** + * Gets the constructor corresponding to the given argument types. + * @param types the argument types + * @return the matching constructor or null if not found. + */ + public MethodMetadata getConstructor(String[] types) { + return getMethod("$init", types); // Constructors are named $init in the manipulation metadata + } + /** * Adds a method to the list. * This method is used during the creation of the {@link PojoMetadata} @@ -207,7 +225,7 @@ public class PojoMetadata { m_methods = new MethodMetadata[] { method }; } } - + /** * Adds a field to the list. * This method is used during the creation of the {@link PojoMetadata} @@ -224,7 +242,7 @@ public class PojoMetadata { m_fields = new FieldMetadata[] { field }; } } - + /** * Adds the interface to the list. * This method is used during the creation of the {@link PojoMetadata} Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java (original) +++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java Thu Dec 23 13:20:45 2010 @@ -25,6 +25,7 @@ import java.lang.reflect.Method; import org.apache.felix.ipojo.ComponentInstance; import org.apache.felix.ipojo.ConfigurationException; +import org.apache.felix.ipojo.ConstructorInjector; import org.apache.felix.ipojo.FieldInterceptor; import org.apache.felix.ipojo.Handler; import org.apache.felix.ipojo.InstanceManager; @@ -33,10 +34,11 @@ import org.osgi.framework.BundleContext; /** * Property class managing a managed value. - * This class managed the method invocation as well as field injection. + * This class managed the method invocation, field injection + * and constructor injection. * @author Felix Project Team */ -public class Property implements FieldInterceptor { +public class Property implements FieldInterceptor, ConstructorInjector { /** * Object used for an unvalued property. @@ -62,6 +64,12 @@ public class Property implements FieldIn private final Callback m_method; /** + * The index of the parameter in case of + * constructor injection. + */ + private int m_index = -1; + + /** * The value of the property. */ private Object m_value = NO_VALUE; @@ -125,7 +133,12 @@ public class Property implements FieldIn } else { m_method = null; } + } + public Property(String name, String field, String method, int index, + String value, String type, InstanceManager manager, Handler handler) throws ConfigurationException { + this(name, field, method, value, type, manager, handler); + m_index = index; } /** @@ -258,6 +271,16 @@ public class Property implements FieldIn } /** + * Gets the parameter index. + * @return the parameter index or -1 + * if this property is not injected using constructor + * parameter. + */ + public int getParameterIndex() { + return m_index; + } + + /** * Checks if the property has a field. * @return true if the property has a field. */ @@ -567,6 +590,36 @@ public class Property implements FieldIn } /** + * Gets the object to inject as constructor parameter. + * @param index the constructor parameter index + * @return the object to inject, so the property value. + * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameter(int) + */ + public Object getConstructorParameter(int index) { + if (m_index != index) { + return null; + } + + if (m_value == NO_VALUE) { + return getNoValue(m_type); + } + return m_value; + } + + /** + * Gets the type of the constructor parameter to inject. + * @param index the parameter index + * @return the Class of the property. + * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameterType(int) + */ + public Class getConstructorParameterType(int index) { + if (m_index != index) { + return null; + } + return m_type; + } + + /** * Gets the handler managing the property. * @return the configuration handler. */ Propchange: felix/trunk/ipojo/handler/eventadmin/ ('svn:mergeinfo' removed) Propchange: felix/trunk/ipojo/handler/eventadmin/metadata.xml ('svn:mergeinfo' removed) Propchange: felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/EventUtil.java ('svn:mergeinfo' removed) Propchange: felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/ ('svn:mergeinfo' removed) Propchange: felix/trunk/ipojo/handler/extender/ ('svn:mergeinfo' removed) Propchange: felix/trunk/ipojo/handler/jmx/ ('svn:mergeinfo' removed) Propchange: felix/trunk/ipojo/handler/temporal/ ('svn:mergeinfo' removed) Propchange: felix/trunk/ipojo/handler/whiteboard/ ('svn:mergeinfo' removed) Modified: felix/trunk/ipojo/manipulator/pom.xml URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/pom.xml?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/manipulator/pom.xml (original) +++ felix/trunk/ipojo/manipulator/pom.xml Thu Dec 23 13:20:45 2010 @@ -51,6 +51,11 @@ org.apache.felix.ipojo.metadata 1.4.0 + + org.apache.felix + org.apache.felix.ipojo.annotations + 1.7.0-SNAPSHOT + @@ -109,6 +114,16 @@ http://felix.apache.org/ipojo/dev/checkstyle_ipojo.xml + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.5 + 1.5 + + + Modified: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java (original) +++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java Thu Dec 23 13:20:45 2010 @@ -191,15 +191,14 @@ public class MethodCreator extends Class newDesc = "(Lorg/apache/felix/ipojo/InstanceManager;" + newDesc; Type[] args = Type.getArgumentTypes(desc); + + // TODO HERE ! => All constructor matches, no distinction between the different constructors. + generateConstructor(access, desc, signature, exceptions, md.getAnnotations(), md.getParameterAnnotations()); + if (args.length == 0) { - generateEmptyConstructor(access, signature, exceptions, md.getAnnotations()); // No parameters, so no annotations parameters m_foundSuitableConstructor = true; } else if (args.length == 1 && args[0].getClassName().equals("org.osgi.framework.BundleContext")) { - generateBCConstructor(access, signature, exceptions, md.getAnnotations()); // One parameter, so no annotations parameters m_foundSuitableConstructor = true; - } else { - // Do nothing, the constructor does not match. - return cv.visitMethod(access, name, desc, signature, exceptions); } // Insert the new constructor @@ -297,64 +296,56 @@ public class MethodCreator extends Class } /** - * Create a constructor to call the manipulated constructor. - * This constructor does not have any argument. It will call the manipulated - * constructor with a null instance manager. + * Modify the given constructor to be something like: + * + * this(null, params...); + * return; + * + * The actual constructor is modified to support the instance manager argument. * @param access : access flag + * @param descriptor : the original constructor descriptor * @param signature : method signature * @param exceptions : declared exception * @param annotations : the annotations to move to this constructor. */ - private void generateEmptyConstructor(int access, String signature, String[] exceptions, List annotations) { - MethodVisitor mv = cv.visitMethod(access, "", "()V", signature, exceptions); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitInsn(ACONST_NULL); - mv.visitMethodInsn(INVOKESPECIAL, m_owner, "", "(Lorg/apache/felix/ipojo/InstanceManager;)V"); - mv.visitInsn(RETURN); + private void generateConstructor(int access, String descriptor, String signature, String[] exceptions, List annotations, Map paramAnnotations) { + GeneratorAdapter mv = new GeneratorAdapter( + cv.visitMethod(access, "", descriptor, signature, exceptions), + access, "", descriptor); + // Compute the new signature + String newDesc = descriptor.substring(1); // Remove the first ( + newDesc = "(Lorg/apache/felix/ipojo/InstanceManager;" + newDesc; + + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitInsn(ACONST_NULL); + mv.loadArgs(); + mv.visitMethodInsn(INVOKESPECIAL, m_owner, "", newDesc); + mv.visitInsn(RETURN); + + // Move annotations + if (annotations != null) { + for (int i = 0; i < annotations.size(); i++) { + AnnotationDescriptor ad = (AnnotationDescriptor) annotations.get(i); + ad.visitAnnotation(mv); + } + } + + // Move parameter annotations if any + if (paramAnnotations != null && ! paramAnnotations.isEmpty()) { + Iterator ids = paramAnnotations.keySet().iterator(); + while(ids.hasNext()) { + Integer id = (Integer) ids.next(); + List ads = (List) paramAnnotations.get(id); + for (int i = 0; i < ads.size(); i++) { + AnnotationDescriptor ad = (AnnotationDescriptor) ads.get(i); + ad.visitParameterAnnotation(id.intValue(), mv); + } + } + } - // Move annotations - if (annotations != null) { - for (int i = 0; i < annotations.size(); i++) { - AnnotationDescriptor ad = (AnnotationDescriptor) annotations.get(i); - ad.visitAnnotation(mv); - } - } - - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - /** - * Create a constructor to call the manipulated constructor. - * This constructor has one argument (the bundle context). It will call the manipulated - * constructor with a null instance manager. - * @param access : access flag - * @param signature : method signature - * @param exceptions : declared exception - * @param annotations : the annotations to move to this constructor. - */ - private void generateBCConstructor(int access, String signature, String[] exceptions, List annotations) { - MethodVisitor mv = cv.visitMethod(access, "", "(Lorg/osgi/framework/BundleContext;)V", signature, exceptions); - mv.visitCode(); - Label l0 = new Label(); - mv.visitLabel(l0); - mv.visitVarInsn(ALOAD, 0); - mv.visitInsn(ACONST_NULL); - mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKESPECIAL, m_owner, "", "(Lorg/apache/felix/ipojo/InstanceManager;Lorg/osgi/framework/BundleContext;)V"); - mv.visitInsn(RETURN); - - // Move annotations - if (annotations != null) { - for (int i = 0; i < annotations.size(); i++) { - AnnotationDescriptor ad = (AnnotationDescriptor) annotations.get(i); - ad.visitAnnotation(mv); - } - } - - mv.visitMaxs(0, 0); - mv.visitEnd(); + mv.visitMaxs(0, 0); + mv.visitEnd(); } /** Modified: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/CustomAnnotationVisitor.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/CustomAnnotationVisitor.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/CustomAnnotationVisitor.java (original) +++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/CustomAnnotationVisitor.java Thu Dec 23 13:20:45 2010 @@ -1,4 +1,4 @@ -/* +/* * 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 @@ -23,6 +23,7 @@ import java.lang.reflect.Array; import org.apache.felix.ipojo.metadata.Attribute; import org.apache.felix.ipojo.metadata.Element; import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Type; import org.objectweb.asm.commons.EmptyVisitor; /** @@ -31,8 +32,6 @@ import org.objectweb.asm.commons.EmptyVi */ public class CustomAnnotationVisitor extends EmptyVisitor implements AnnotationVisitor { - //TODO manage enum annotations. - /** * Parent element. */ @@ -54,7 +53,7 @@ public class CustomAnnotationVisitor ext * Is the custom annotation a first-order annotation. */ private boolean m_root; - + /** * Is the visit annotation a class annotation? */ @@ -64,7 +63,22 @@ public class CustomAnnotationVisitor ext * Metadata collector. */ private MetadataCollector m_collector; - + + /** + * Flag sets to true for parameter annotation. + */ + private boolean m_isParameterAnnotation = false; + + /** + * For parameter annotations, the index of the parameter. + */ + private int m_index = -1; + + /** + * For parameter annotation, the descriptor of the method. + */ + private String m_desc; + /** * Constructor. * @param elem the parent element @@ -78,7 +92,26 @@ public class CustomAnnotationVisitor ext m_collector = collector; m_classAnnotation = clazz; } - + + /** + * Constructor used for parameter annotations + * @param elem the parent element + * @param collector the metadata collector + * @param root is the annotation a root + * @param clazz the annotation is a class annotation. + * @param index the index of the argument + * @param the descriptor of the method + */ + public CustomAnnotationVisitor(Element elem, MetadataCollector collector, boolean root, boolean clazz, int index, String descriptor) { + m_elem = elem; + m_root = root; + m_collector = collector; + m_classAnnotation = clazz; + m_isParameterAnnotation = true; + m_index = index; + m_desc = descriptor; + } + /** * Check if the given annotation descriptor is an iPOJO custom annotation. * A valid iPOJO custom annotation must contains 'ipojo' or 'handler' in its qualified name. @@ -92,7 +125,7 @@ public class CustomAnnotationVisitor ext } return false; } - + /** * Build the element object from the given descriptor. * @param desc : annotation descriptor @@ -109,7 +142,7 @@ public class CustomAnnotationVisitor ext /** * Visit a 'simple' annotation attribute. - * This method is used for primitive arrays too. + * This method is used for primitive arrays too. * @param arg0 : attribute name * @param arg1 : attribute value * @see org.objectweb.asm.commons.EmptyVisitor#visit(java.lang.String, java.lang.Object) @@ -164,7 +197,7 @@ public class CustomAnnotationVisitor ext public AnnotationVisitor visitArray(String arg0) { return new SubArrayVisitor(m_elem, arg0); } - + /** * Visits an enumeration attribute. * @param arg0 the attribute name @@ -186,6 +219,7 @@ public class CustomAnnotationVisitor ext if (m_id != null) { m_collector.getIds().put(m_id, m_elem); } else { + m_id = m_elem.getNameSpace(); if (! m_collector.getIds().containsKey(m_elem.getNameSpace()) && m_classAnnotation) { // If the namespace is not already used, add the annotation as the // root element of this namespace. @@ -197,8 +231,15 @@ public class CustomAnnotationVisitor ext } } } - + m_collector.getElements().put(m_elem, m_parent); + + if (m_isParameterAnnotation) { + String t = Type.getArgumentTypes(m_desc)[m_index].getClassName(); + m_elem.addAttribute(new Attribute("type", t)); + m_elem.addAttribute( + new Attribute("constructor-parameter", Integer.toString(m_index))); + } } } Modified: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java (original) +++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java Thu Dec 23 13:20:45 2010 @@ -210,7 +210,7 @@ public class MetadataCollector extends E * @see org.objectweb.asm.ClassAdapter#visitMethod(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[]) */ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - return new MethodCollector(name, this); + return new MethodCollector(name, desc, this); } /** Modified: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java?rev=1052264&r1=1052263&r2=1052264&view=diff ============================================================================== --- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java (original) +++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java Thu Dec 23 13:20:45 2010 @@ -18,6 +18,8 @@ */ package org.apache.felix.ipojo.manipulation.annotations; +import java.awt.image.renderable.ParameterBlock; + import org.apache.felix.ipojo.metadata.Attribute; import org.apache.felix.ipojo.metadata.Element; import org.objectweb.asm.AnnotationVisitor; @@ -41,16 +43,47 @@ public class MethodCollector extends Emp private String m_name; /** + * Method Descriptor. + */ + private String m_descriptor; + + /** * Constructor. * @param name : name of the method. * @param collector : parent collector. */ - public MethodCollector(String name, MetadataCollector collector) { + public MethodCollector(String name, String descriptor, MetadataCollector collector) { m_collector = collector; m_name = name; + m_descriptor = descriptor; } /** + * Visit a parameter annotation. + * @see org.objectweb.asm.commons.EmptyVisitor#visitParameterAnnotation(int, java.lang.String, boolean) + */ + public AnnotationVisitor visitParameterAnnotation(int index, String annotation, + boolean visible) { + if (m_name.equals("")) { + if (annotation.equals("Lorg/apache/felix/ipojo/annotations/Property;")) { + return processProperty(true, index); + } + if (annotation.equals("Lorg/apache/felix/ipojo/annotations/Requires;")) { + return new BindAnnotationParser(index); + } + + if (CustomAnnotationVisitor.isCustomAnnotation(annotation)) { + Element elem = CustomAnnotationVisitor.buildElement(annotation); + elem.addAttribute(new Attribute("index", "" + index)); + return new CustomAnnotationVisitor(elem, m_collector, true, false, index, m_descriptor); + } + } + return super.visitParameterAnnotation(index, annotation, visible); + } + + + + /** * Visit method annotations. * @param arg0 : annotation name. * @param arg1 : is the annotation visible at runtime. @@ -59,7 +92,7 @@ public class MethodCollector extends Emp */ public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) { if (arg0.equals("Lorg/apache/felix/ipojo/annotations/Property;")) { - return processProperty(); + return processProperty(false, -1); } if (arg0.equals("Lorg/apache/felix/ipojo/annotations/Validate;")) { return processValidate(); @@ -181,9 +214,11 @@ public class MethodCollector extends Emp /** * Process @property annotation. + * @param parameter true if we're processing a parameter + * @param index the index, meaningful only if parameter is true * @return the visitor parsing the visited annotation. */ - private AnnotationVisitor processProperty() { + private AnnotationVisitor processProperty(boolean parameter, int index) { Element prop = null; if (! m_collector.getIds().containsKey("properties")) { prop = new Element("Properties", ""); @@ -192,7 +227,7 @@ public class MethodCollector extends Emp } else { prop = (Element) m_collector.getIds().get("properties"); } - return new PropertyAnnotationParser(prop, m_name); + return new PropertyAnnotationParser(prop, m_name, parameter, index); } /** @@ -251,6 +286,12 @@ public class MethodCollector extends Emp private String m_from; /** + * For annotation parameter, + * the parameter index. + */ + private int m_index = -1; + + /** * Constructor. * @param bind : method name. * @param type : is the callback a bind or an unbind method. @@ -260,6 +301,10 @@ public class MethodCollector extends Emp m_type = type; } + private BindAnnotationParser(int index) { + m_index = index; + } + /** * Visit annotation attribute. * @param arg0 : annotation name @@ -310,17 +355,20 @@ public class MethodCollector extends Emp */ public void visitEnd() { if (m_id == null) { - if (m_name.startsWith("bind")) { + if (m_name != null && m_name.startsWith("bind")) { m_id = m_name.substring("bind".length()); - } else if (m_name.startsWith("unbind")) { + } else if (m_name != null && m_name.startsWith("unbind")) { m_id = m_name.substring("unbind".length()); - } else if (m_name.startsWith("modified")) { + } else if (m_name != null && m_name.startsWith("modified")) { m_id = m_name.substring("modified".length()); - } else { + } else if (m_index != -1) { + m_id = "" + m_index; + } else { System.err.println("Cannot determine the id of the " + m_type + " method : " + m_name); return; } } + // Check if it is a full-determined requirement Element req = (Element) m_collector.getIds().get(m_id); if (req == null) { @@ -422,17 +470,22 @@ public class MethodCollector extends Emp } } - Element method = new Element("callback", ""); - method.addAttribute(new Attribute("method", m_name)); - method.addAttribute(new Attribute("type", m_type)); - req.addElement(method); + if (m_name != null) { + Element method = new Element("callback", ""); + method.addAttribute(new Attribute("method", m_name)); + method.addAttribute(new Attribute("type", m_type)); + req.addElement(method); + } else { + req.addAttribute(new Attribute("constructor-parameter", Integer.toString(m_index))); + } + m_collector.getIds().put(m_id, req); m_collector.getElements().put(req, null); return; } } - private static final class PropertyAnnotationParser extends EmptyVisitor implements AnnotationVisitor { + private final class PropertyAnnotationParser extends EmptyVisitor implements AnnotationVisitor { /** * Parent element. @@ -450,6 +503,11 @@ public class MethodCollector extends Emp private String m_name; /** + * Property id. + */ + private String m_id; + + /** * Property value. */ private String m_value; @@ -460,13 +518,27 @@ public class MethodCollector extends Emp private String m_mandatory; /** + * Flag set to true if we're processing an annotation parameter. + */ + private boolean m_isParameterAnnotation = false; + + /** + * If this is a parameter annotation, the index of the parameter. + */ + private int m_index = -1; + + /** * Constructor. * @param parent : parent element. * @param method : attached method. + * @param param : we're processing a parameter + * @param index : the parameter index */ - private PropertyAnnotationParser(Element parent, String method) { + private PropertyAnnotationParser(Element parent, String method, boolean param, int index) { m_parent = parent; m_method = method; + m_isParameterAnnotation = param; + m_index = index; } /** @@ -488,6 +560,10 @@ public class MethodCollector extends Emp m_mandatory = arg1.toString(); return; } + if (arg0.equals("id")) { + m_id = arg1.toString(); + return; + } } /** @@ -496,9 +572,17 @@ public class MethodCollector extends Emp * @see org.objectweb.asm.commons.EmptyVisitor#visitEnd() */ public void visitEnd() { - if (m_name == null && m_method.startsWith("set")) { + // If neither name not id, try to extract the name + if (m_name == null && m_id == null && m_method.startsWith("set")) { m_name = m_method.substring("set".length()); + m_id = m_name; + // Else align the two values + } else if (m_name != null && m_id == null) { + m_id = m_name; + } else if (m_id != null && m_name == null) { + m_name = m_id; } + Element[] props = m_parent.getElements("Property"); Element prop = null; for (int i = 0; props != null && prop == null && i < props.length; i++) { @@ -516,7 +600,6 @@ public class MethodCollector extends Emp } } - prop.addAttribute(new Attribute("method", m_method)); if (m_value != null) { prop.addAttribute(new Attribute("value", m_value)); } @@ -524,6 +607,14 @@ public class MethodCollector extends Emp prop.addAttribute(new Attribute("mandatory", m_mandatory)); } + if (m_isParameterAnnotation) { + String t = Type.getArgumentTypes(m_descriptor)[m_index].getClassName(); + prop.addAttribute(new Attribute("type", t)); + prop.addAttribute(new Attribute("constructor-parameter", Integer.toString(m_index))); + } else { + prop.addAttribute(new Attribute("method", m_method)); + } + } } } Propchange: felix/trunk/ipojo/tests/composite/composite-runtime/ ('svn:mergeinfo' removed) Propchange: felix/trunk/ipojo/tests/composite/import-export/ ('svn:mergeinfo' removed) Propchange: felix/trunk/ipojo/tests/composite/service-instance/ ('svn:mergeinfo' removed) Propchange: felix/trunk/ipojo/tests/composite/service-providing/ ('svn:mergeinfo' removed) Propchange: felix/trunk/ipojo/tests/core/annotations/ ('svn:mergeinfo' removed)