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 2010/12/23 14:20:47 UTC
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...
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 <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@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 <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@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 <init>()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 <init>()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 <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-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 <code>null</code> if no
+ * objects are injected. This implementation returns <code>null</code>
+ * @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 <code>null</code> 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 <code>null</code>
+ * @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 <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-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 <code>-1</code> 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 <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
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 <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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 <code>null</code> 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 <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-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 <code>-1</code>
+ * if this property is not injected using constructor
+ * parameter.
+ */
+ public int getParameterIndex() {
+ return m_index;
+ }
+
+ /**
* Checks if the property has a field.
* @return <code>true</code> 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 @@
<artifactId>org.apache.felix.ipojo.metadata</artifactId>
<version>1.4.0</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.ipojo.annotations</artifactId>
+ <version>1.7.0-SNAPSHOT</version>
+ </dependency>
</dependencies>
<build>
<plugins>
@@ -109,6 +114,16 @@
<configLocation>http://felix.apache.org/ipojo/dev/checkstyle_ipojo.xml</configLocation>
</configuration>
</plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+
</plugins>
<resources>
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:
+ * <code>
+ * this(null, params...);
+ * return;
+ * </code>
+ * 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, "<init>", "()V", signature, exceptions);
- mv.visitCode();
- mv.visitVarInsn(ALOAD, 0);
- mv.visitInsn(ACONST_NULL);
- mv.visitMethodInsn(INVOKESPECIAL, m_owner, "<init>", "(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, "<init>", descriptor, signature, exceptions),
+ access, "<init>", 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, "<init>", 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, "<init>", "(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, "<init>", "(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("<init>")) {
+ 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)