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 2008/03/28 16:35:29 UTC
svn commit: r642265 [4/11] - in /felix/trunk/ipojo: ./ annotations/ ant/
ant/src/main/java/org/apache/felix/ipojo/task/ arch/
arch/src/main/java/org/apache/felix/ipojo/arch/ arch/src/main/resources/
composite/ composite/src/ composite/src/main/ composi...
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=642265&r1=642264&r2=642265&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 Fri Mar 28 08:33:36 2008
@@ -19,7 +19,9 @@
package org.apache.felix.ipojo;
import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.HashMap;
@@ -35,13 +37,10 @@
import org.osgi.framework.BundleContext;
/**
- * The instance manager class manages one instance of a component type. It
- * manages component lifecycle, component instance creation and handlers.
- *
+ * The instance manager class manages one instance of a component type. It manages component lifecycle, component instance creation and handlers.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class InstanceManager implements ComponentInstance, InstanceStateListener {
-
/**
* Name of the component instance.
*/
@@ -51,7 +50,7 @@
* Name of the component type implementation class.
*/
protected String m_className;
-
+
/**
* Handler list.
*/
@@ -61,12 +60,12 @@
* Component state (STOPPED at the beginning).
*/
protected int m_state = STOPPED;
-
+
/**
* Instance State Listener List.
*/
- protected List m_instanceListeners = null;
-
+ protected List m_listeners = null;
+
/**
* Parent factory (ComponentFactory).
*/
@@ -78,12 +77,12 @@
private BundleContext m_context;
/**
- * Map [field, handler list] storing handlers interested by the field.
+ * Map [field, field interceptor list] storing handlers interested by the field.
*/
- private Map m_fieldRegistration = new HashMap();
-
+ private Map m_fieldRegistration;
+
/**
- * Map [method identifier, handler list] storing handlers interested by the method.
+ * Map [method identifier, method interceptor list] storing handlers interested by the method.
*/
private Map m_methodRegistration;
@@ -95,78 +94,89 @@
/**
* Instances of the components.
*/
- private Object[] m_pojoObjects = null;
+ private List m_pojoObjects;
+
+ /**
+ * Factory method. Contains the name of the static method used to create POJO objects.
+ */
+ private String m_factoryMethod = null;
- /**
- * Is the component instance state changing?
- */
+ /**
+ * Is the component instance state changing?
+ */
private boolean m_inTransition = false;
-
+
/**
- * Queue of stored state changed.
+ * Queue of stored state changed.
*/
private List m_stateQueue = new ArrayList();
-
+
/**
* Map of [field, value], storing POJO field value.
*/
- private Map m_map = new HashMap();
+ private Map m_fields = new HashMap();
+
+ /**
+ * Map method [id=>method].
+ */
+ private Map m_methods = new HashMap();
/**
* Construct a new Component Manager.
- *
* @param factory : the factory managing the instance manager
- * @param bc : the bundle context to give to the instance
+ * @param context : the bundle context to give to the instance
* @param handlers : handlers array
*/
- public InstanceManager(ComponentFactory factory, BundleContext bc, HandlerManager[] handlers) {
+ public InstanceManager(ComponentFactory factory, BundleContext context, HandlerManager[] handlers) {
m_factory = factory;
- m_context = bc;
+ m_context = context;
m_handlers = handlers;
}
/**
- * Configure the instance manager. Stop the existing handler, clear the
- * handler list, change the metadata, recreate the handlers
- *
- * @param cm : the component type metadata
+ * Configure the instance manager. Stop the existing handler, clear the handler list, change the metadata, recreate the handlers
+ * @param metadata : the component type metadata
* @param configuration : the configuration of the instance
* @throws ConfigurationException : occurs if the metadata are not correct
*/
- public void configure(Element cm, Dictionary configuration) throws ConfigurationException {
- m_className = cm.getAttribute("className");
-
+ public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
+ m_className = metadata.getAttribute("className");
+
// Add the name
m_name = (String) configuration.get("name");
-
+
+ // Get the factory method if presents.
+ m_factoryMethod = (String) metadata.getAttribute("factory-method");
+
// Create the standard handlers and add these handlers to the list
for (int i = 0; i < m_handlers.length; i++) {
- m_handlers[i].init(this, cm, configuration);
+ m_handlers[i].init(this, metadata, configuration);
}
}
/**
- * Get the description of the current instance.
+ * Get the description of the current instance.
* @return the instance description.
* @see org.apache.felix.ipojo.ComponentInstance#getInstanceDescription()
*/
public InstanceDescription getInstanceDescription() {
int componentState = getState();
- InstanceDescription instanceDescription = new InstanceDescription(m_name, componentState, getContext().getBundle().getBundleId(), m_factory.getComponentDescription());
+ InstanceDescription desc =
+ new InstanceDescription(m_name, componentState, getContext().getBundle().getBundleId(), m_factory.getComponentDescription());
if (m_pojoObjects != null) {
- String[] objects = new String[m_pojoObjects.length];
- for (int i = 0; i < m_pojoObjects.length; i++) {
- objects[i] = m_pojoObjects[i].toString();
+ String[] objects = new String[m_pojoObjects.size()];
+ for (int i = 0; i < m_pojoObjects.size(); i++) {
+ objects[i] = m_pojoObjects.get(i).toString();
}
- instanceDescription.setCreatedObjects(objects);
+ desc.setCreatedObjects(objects);
}
Handler[] handlers = getRegistredHandlers();
for (int i = 0; i < handlers.length; i++) {
- instanceDescription.addHandler(handlers[i].getDescription());
+ desc.addHandler(handlers[i].getDescription());
}
- return instanceDescription;
+ return desc;
}
/**
@@ -174,22 +184,21 @@
* @return the handler array of plugged handlers.
*/
public Handler[] getRegistredHandlers() {
- Handler[] h = new Handler[m_handlers.length];
+ Handler[] handler = new Handler[m_handlers.length];
for (int i = 0; i < m_handlers.length; i++) {
- h[i] = m_handlers[i].getHandler();
+ handler[i] = m_handlers[i].getHandler();
}
- return h;
+ return handler;
}
/**
* Return a specified handler.
- *
* @param name : class name of the handler to find or its qualified name (namespace:name)
* @return : the handler, or null if not found
*/
public Handler getHandler(String name) {
for (int i = 0; i < m_handlers.length; i++) {
- HandlerFactory fact = (HandlerFactory) m_handlers[i].getHandler().getInstance().getFactory();
+ HandlerFactory fact = (HandlerFactory) m_handlers[i].getHandler().getHandlerManager().getFactory();
if (fact.getHandlerName().equals(name)) {
return m_handlers[i].getHandler();
}
@@ -198,24 +207,83 @@
}
/**
+ * Give access to a field value to the first created pojo.
+ * This method process by analyzing both managed fields and pojo fields (by reflection).
+ * If no pojo were already created try only on managed fields.
+ * @param fieldName : field name.
+ * @return the field value, null is returned if the value is managed and not already set.
+ */
+ public synchronized Object getFieldValue(String fieldName) {
+ if (m_pojoObjects == null) {
+ return getFieldValue(fieldName, null);
+ } else {
+ return getFieldValue(fieldName, m_pojoObjects.get(0)); // Use the first pojo.
+ }
+ }
+
+ /**
+ * Give access to a field value to the given created pojo.
+ * This method process by analyzing both managed fields and pojo fields (by reflection).
+ * If the given pojo is null, try only on managed fields.
+ * @param fieldName : field name.
+ * @param pojo : the pojo on which computing field value.
+ * @return the field value, null is returned if the value is managed and not already set.
+ */
+ public synchronized Object getFieldValue(String fieldName, Object pojo) {
+ Object setByContainer = null;
+
+ if (m_fields != null) {
+ setByContainer = m_fields.get(fieldName);
+ }
+
+ if (setByContainer == null && pojo != null) { // In the case of no given pojo, return null.
+ // If null either the value was not already set or has the null value.
+ try {
+ Field field = pojo.getClass().getDeclaredField(fieldName);
+ if (!field.isAccessible()) {
+ field.setAccessible(true);
+ }
+ return field.get(pojo);
+ } catch (SecurityException e) {
+ m_factory.getLogger().log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+ } catch (NoSuchFieldException e) {
+ m_factory.getLogger().log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+ } catch (IllegalArgumentException e) {
+ m_factory.getLogger().log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+ } catch (IllegalAccessException e) {
+ m_factory.getLogger().log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+ }
+ return null;
+ } else {
+ return setByContainer;
+ }
+ }
+
+ /**
* Start the instance manager.
*/
public synchronized void start() {
if (m_state != STOPPED) { // Instance already started
return;
- }
-
+ }
+
for (int i = 0; i < m_handlers.length; i++) {
m_handlers[i].addInstanceStateListener(this);
- m_handlers[i].start();
+ try {
+ m_handlers[i].start();
+ } catch (IllegalStateException e) {
+ m_factory.getLogger().log(Logger.ERROR, e.getMessage());
+ stop();
+ throw e;
+ }
}
-
+
for (int i = 0; i < m_handlers.length; i++) {
-
if (m_handlers[i].getState() != VALID) {
setState(INVALID);
return;
}
+
}
setState(VALID);
}
@@ -227,26 +295,27 @@
if (m_state == STOPPED) {
return;
} // Instance already stopped
-
+
setState(INVALID);
-
+
+ m_state = STOPPED;
+
// Stop all the handlers
for (int i = m_handlers.length - 1; i > -1; i--) {
m_handlers[i].removeInstanceStateListener(this);
m_handlers[i].stop();
}
-
+
m_pojoObjects = null;
- m_state = STOPPED;
- if (m_instanceListeners != null) {
- for (int i = 0; i < m_instanceListeners.size(); i++) {
- ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, STOPPED);
+ if (m_listeners != null) {
+ for (int i = 0; i < m_listeners.size(); i++) {
+ ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, STOPPED);
}
}
}
-
- /**
+
+ /**
* Dispose the instance.
* @see org.apache.felix.ipojo.ComponentInstance#dispose()
*/
@@ -254,100 +323,79 @@
if (m_state > STOPPED) { // Valid or invalid
stop();
}
-
+
m_state = DISPOSED;
-
- if (m_instanceListeners != null) {
- for (int i = 0; i < m_instanceListeners.size(); i++) {
- ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
- }
- m_instanceListeners = null;
+
+ for (int i = 0; m_listeners != null && i < m_listeners.size(); i++) {
+ ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, DISPOSED);
}
-
- m_factory.disposed(this);
-
+ m_listeners = null;
+
for (int i = m_handlers.length - 1; i > -1; i--) {
m_handlers[i].dispose();
}
-
- m_map.clear();
- m_handlers = new HandlerManager[0];
- m_fieldRegistration = new HashMap();
- m_methodRegistration = new HashMap();
- m_clazz = null;
- m_inTransition = false;
- }
-
- /**
- * Kill the current instance.
- * Only the factory of this instance can call this method.
- */
- protected void kill() {
- if (m_state > STOPPED) {
- stop();
- }
- if (m_instanceListeners != null) {
- for (int i = 0; i < m_instanceListeners.size(); i++) {
- ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, DISPOSED);
- }
- m_instanceListeners = null;
- }
- // Cleaning
- m_state = DISPOSED;
-
- for (int i = 0; i < m_handlers.length; i++) {
- m_handlers[i].dispose();
- }
-
- m_map.clear();
m_handlers = new HandlerManager[0];
+ m_factory.disposed(this);
+ m_fields.clear();
m_fieldRegistration = new HashMap();
m_methodRegistration = new HashMap();
m_clazz = null;
m_inTransition = false;
-
}
-
+
/**
- * Set the state of the component instance.
- * if the state changed call the stateChanged(int) method on the handlers.
- * This method has a reentrant mechanism. If in the flow of the first call the method is called another times,
- * the second call is stored and executed after the first one is finished.
+ * Set the state of the component instance. if the state changed call the stateChanged(int) method on the handlers. This method has a reentrant
+ * mechanism. If in the flow of the first call the method is called another times, the second call is stored and executed after the first one is
+ * finished.
* @param state : the new state
*/
public synchronized void setState(int state) {
if (m_inTransition) {
- m_stateQueue.add(new Integer(state));
+ m_stateQueue.add(new Integer(state));
return;
}
-
+
if (m_state != state) {
m_inTransition = true;
if (state > m_state) {
// The state increases (Stopped = > IV, IV => V) => invoke handlers from the higher priority to the lower
m_state = state;
- for (int i = 0; i < m_handlers.length; i++) {
- m_handlers[i].getHandler().stateChanged(state);
+ try {
+ for (int i = 0; i < m_handlers.length; i++) {
+ m_handlers[i].getHandler().stateChanged(state);
+ }
+ } catch (IllegalStateException e) {
+ // When an illegal state exception happens, the instance manager must be stopped immediately.
+ m_stateQueue.clear();
+ stop();
+ return;
}
} else {
// The state decreases (V => IV, IV = > Stopped, Stopped => Disposed)
m_state = state;
- for (int i = m_handlers.length - 1; i > -1; i--) {
- m_handlers[i].getHandler().stateChanged(state);
+ try {
+ for (int i = m_handlers.length - 1; i > -1; i--) {
+ m_handlers[i].getHandler().stateChanged(state);
+ }
+ } catch (IllegalStateException e) {
+ // When an illegal state exception happens, the instance manager must be stopped immediately.
+ m_stateQueue.clear();
+ stop();
+ return;
}
}
-
- if (m_instanceListeners != null) {
- for (int i = 0; i < m_instanceListeners.size(); i++) {
- ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, state);
+
+ if (m_listeners != null) {
+ for (int i = 0; i < m_listeners.size(); i++) {
+ ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, state);
}
}
}
-
+
m_inTransition = false;
- if (! m_stateQueue.isEmpty()) {
+ if (!m_stateQueue.isEmpty()) {
int newState = ((Integer) (m_stateQueue.remove(0))).intValue();
setState(newState);
}
@@ -370,18 +418,18 @@
public boolean isStarted() {
return m_state > STOPPED;
}
-
+
/**
* Register an instance state listener.
* @param listener : listener to register.
* @see org.apache.felix.ipojo.ComponentInstance#addInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
*/
- public void addInstanceStateListener(InstanceStateListener listener) {
- if (m_instanceListeners == null) {
- m_instanceListeners = new ArrayList();
+ public synchronized void addInstanceStateListener(InstanceStateListener listener) {
+ if (m_listeners == null) {
+ m_listeners = new ArrayList();
}
- synchronized (m_instanceListeners) {
- m_instanceListeners.add(listener);
+ synchronized (m_listeners) {
+ m_listeners.add(listener);
}
}
@@ -390,12 +438,12 @@
* @param listener : listener to unregister.
* @see org.apache.felix.ipojo.ComponentInstance#removeInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
*/
- public void removeInstanceStateListener(InstanceStateListener listener) {
- if (m_instanceListeners != null) {
- synchronized (m_instanceListeners) {
- m_instanceListeners.remove(listener);
- if (m_instanceListeners.size() == 0) {
- m_instanceListeners = null;
+ public synchronized void removeInstanceStateListener(InstanceStateListener listener) {
+ if (m_listeners != null) {
+ synchronized (m_listeners) {
+ m_listeners.remove(listener);
+ if (m_listeners.isEmpty()) {
+ m_listeners = null;
}
}
}
@@ -424,129 +472,186 @@
}
/**
- * Add an instance to the created instance list.
- * @param o : the instance to add
- */
- private synchronized void addInstance(Object o) {
- if (m_pojoObjects != null) {
- Object[] newInstances = new Object[m_pojoObjects.length + 1];
- System.arraycopy(m_pojoObjects, 0, newInstances, 0, m_pojoObjects.length);
- newInstances[m_pojoObjects.length] = o;
- m_pojoObjects = newInstances;
- } else {
- m_pojoObjects = new Object[] { o };
- }
- }
-
- /**
* Get the array of object created by the instance.
* @return the created instance of the component instance.
*/
public Object[] getPojoObjects() {
- return m_pojoObjects;
- }
-
- /**
- * Delete the created instance (remove it from the list, to allow the
- * garbage collector to eat the instance).
- *
- * @param o : the instance to delete
- */
- public synchronized void deletePojoObject(Object o) {
- int idx = -1;
- for (int i = 0; i < m_pojoObjects.length; i++) {
- if (m_pojoObjects[i] == o) {
- idx = i;
- break;
- }
- }
-
- if (idx >= 0) {
- if ((m_pojoObjects.length - 1) == 0) {
- m_pojoObjects = null;
- } else {
- Object[] newInstances = new Object[m_pojoObjects.length - 1];
- System.arraycopy(m_pojoObjects, 0, newInstances, 0, idx);
- if (idx < newInstances.length) {
- System.arraycopy(m_pojoObjects, idx + 1, newInstances, idx, newInstances.length - idx);
- }
- m_pojoObjects = newInstances;
- }
+ if (m_pojoObjects == null) {
+ return null;
}
+ return m_pojoObjects.toArray(new Object[m_pojoObjects.size()]);
}
/**
- * Create an instance of the component. This method need to be called one
- * time only for singleton provided service
- *
+ * Create an instance of the component. This method need to be called one time only for singleton provided service
* @return a new instance
*/
public Object createPojoObject() {
-
if (m_clazz == null) {
load();
}
+
Object instance = null;
- try {
- // Try to find if there is a constructor with a bundle context as
- // parameter :
+
+ if (m_factoryMethod == null) {
+ // No factory-method, we use the constructor.
try {
- Constructor constructor = m_clazz.getConstructor(new Class[] { InstanceManager.class, BundleContext.class });
- constructor.setAccessible(true);
- instance = constructor.newInstance(new Object[] { this, m_context });
+ // 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, m_context };
+ onEntry(null, m_className, new Object[] {m_context});
+ instance = cst.newInstance(args);
+ onExit(null, m_className, 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, m_className, new Object[0]);
+ instance = cst.newInstance(args);
+ onExit(null, m_className, instance);
+ }
+ }
+ } catch (IllegalAccessException e) {
+ m_factory.getLogger().log(Logger.ERROR,
+ "[" + m_name + "] createInstance -> The POJO constructor is not accessible : " + e.getMessage());
+ stop();
+ } catch (SecurityException e) {
+ m_factory.getLogger().log(
+ Logger.ERROR,
+ "["
+ + m_name
+ + "] createInstance -> The Component Instance is not accessible (security reason) : "
+ + e.getMessage());
+ stop();
+ } catch (InvocationTargetException e) {
+ m_factory.getLogger().log(
+ Logger.ERROR,
+ "["
+ + m_name
+ + "] createInstance -> Cannot invoke the constructor method (illegal target) : "
+ + e.getTargetException().getMessage());
+ onError(null, m_className, e.getTargetException());
+ stop();
} catch (NoSuchMethodException e) {
- instance = null;
+ m_factory.getLogger().log(Logger.ERROR,
+ "[" + m_name + "] createInstance -> Cannot invoke the constructor (method not found) : " + e.getMessage());
+ stop();
+ } catch (IllegalArgumentException e) {
+ m_factory.getLogger().log(Logger.ERROR,
+ "[" + m_name + "] createInstance -> The POJO constructor invocation failed : " + e.getMessage());
+ stop();
+ } catch (InstantiationException e) {
+ m_factory.getLogger().log(Logger.ERROR,
+ "[" + m_name + "] createInstance -> The POJO constructor invocation failed : " + e.getMessage());
+ stop();
}
+ } else {
+ try {
+ // Build the pojo object with the factory-method.
+ Method factory = null;
+ // Try with the bundle context
+ try {
+ factory = m_clazz.getDeclaredMethod(m_factoryMethod, new Class[] { BundleContext.class });
+ if (! factory.isAccessible()) {
+ factory.setAccessible(true);
+ }
+ Object[] args = new Object[] { m_context };
+ onEntry(null, m_className, args);
+ instance = factory.invoke(null, new Object[] { m_context });
+ } catch (NoSuchMethodException e1) {
+ // Try without the bundle context
+ try {
+ factory = m_clazz.getDeclaredMethod(m_factoryMethod, new Class[0]);
+ if (! factory.isAccessible()) {
+ factory.setAccessible(true);
+ }
+ Object[] args = new Object[0];
+ onEntry(null, m_className, args);
+ instance = factory.invoke(null, args);
+ } catch (NoSuchMethodException e2) {
+ // Error : factory-method not found
+ m_factory.getLogger().log(
+ Logger.ERROR,
+ "["
+ + m_name
+ + "] createInstance -> Cannot invoke the factory-method (method not found) : "
+ + e2.getMessage());
+ stop();
+ }
+ }
+
+ // Now call the setInstanceManager method.
+ Method method = instance.getClass().getDeclaredMethod("_setInstanceManager", new Class[] { InstanceManager.class });
+ if (!method.isAccessible()) {
+ method.setAccessible(true);
+ }
+ method.invoke(instance, new Object[] { this });
+ onExit(null, m_className, instance);
- // Create an instance if no instance are already created with
- // <init>()BundleContext
- if (instance == null) {
- Constructor constructor = m_clazz.getConstructor(new Class[] { InstanceManager.class });
- constructor.setAccessible(true);
- instance = constructor.newInstance(new Object[] { this });
+ } catch (SecurityException e) {
+ // Error : invocation failed
+ m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the factory-method : " + e.getMessage());
+ stop();
+ } catch (IllegalArgumentException e) {
+ // Error : arguments mismatch
+ m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the factory-method : " + e.getMessage());
+ stop();
+ } catch (IllegalAccessException e) {
+ // Error : illegal access
+ m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the factory-method : " + e.getMessage());
+ stop();
+ } catch (InvocationTargetException e) {
+ // Error : invocation failed
+ m_factory.getLogger().log(Logger.ERROR,
+ "[" + m_name + "] createInstance -> The factory-method returns an exception : " + e.getTargetException());
+ onError(null, m_className, e.getTargetException());
+ stop();
+ } catch (NoSuchMethodException e) {
+ // Error : _setInstanceManager method is missing
+ m_factory.getLogger()
+ .log(
+ Logger.ERROR,
+ "["
+ + m_name
+ + "] createInstance -> Cannot invoke the factory-method (the _setInstanceManager method does not exist) : "
+ + e.getMessage());
+ stop();
}
- } catch (InstantiationException e) {
- m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> The Component Instance cannot be instancied : " + e.getMessage());
- stop();
- } catch (IllegalAccessException e) {
- m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> The Component Instance is not accessible : " + e.getMessage());
- stop();
- } catch (SecurityException e) {
- m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> The Component Instance is not accessible (security reason) : " + e.getMessage());
- stop();
- } catch (InvocationTargetException e) {
- m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the constructor method (illegal target) : " + e.getTargetException().getMessage());
- e.printStackTrace();
- stop();
- } catch (NoSuchMethodException e) {
- m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot invoke the constructor (method not found) : " + e.getMessage());
- stop();
- }
- if (instance == null) {
- m_factory.getLogger().log(Logger.ERROR, "[" + m_name + "] createInstance -> Cannot create the instance");
- stop();
}
- // Register the new instance
- addInstance(instance);
- // Call createInstance on Handlers :
- for (int i = 0; i < m_handlers.length; i++) {
- ((PrimitiveHandler) m_handlers[i].getHandler()).objectCreated(instance);
+ // Register the new instance in not already present.
+ if (m_pojoObjects == null) {
+ m_pojoObjects = new ArrayList(1);
}
+ if (!m_pojoObjects.contains(instance)) {
+ m_pojoObjects.add(instance);
+ // Call createInstance on Handlers :
+ for (int i = 0; i < m_handlers.length; i++) {
+ ((PrimitiveHandler) m_handlers[i].getHandler()).onCreation(instance);
+ }
+ }
+
return instance;
}
/**
- * Get the first object created by the instance.
- * If no object created, create and return one object.
+ * Get the first object created by the instance. If no object created, create and return one object.
* @return the instance of the component instance to use for singleton component
*/
public synchronized Object getPojoObject() {
if (m_pojoObjects == null) {
- createPojoObject();
+ return createPojoObject();
}
- return m_pojoObjects[0];
+ return m_pojoObjects.get(0);
}
/**
@@ -561,134 +666,219 @@
}
/**
- * Register an handler. The handler will be notified of event on each field
- * given in the list.
- *
- * @param h : the handler to register
+ * Register an handler. The handler will be notified of event on each field given in the list.
+ * @param handler : the handler to register
* @param fields : the field metadata list
* @param methods : the method metadata list
+ * @deprecated use register(FieldMetadata fm, FieldInterceptor fi) and register(MethodMetadata mm, MethodInterceptor mi) instead.
*/
- public void register(PrimitiveHandler h, FieldMetadata[] fields, MethodMetadata[] methods) {
+ public void register(PrimitiveHandler handler, FieldMetadata[] fields, MethodMetadata[] methods) {
for (int i = 0; fields != null && i < fields.length; i++) {
- if (m_fieldRegistration.get(fields[i].getFieldName()) == null) {
- m_fieldRegistration.put(fields[i].getFieldName(), new PrimitiveHandler[] { h });
+ register(fields[i], handler);
+ }
+ for (int i = 0; methods != null && i < methods.length; i++) {
+ register(methods[i], handler);
+ }
+
+ }
+
+ /**
+ * Register a field interceptor.
+ * @param field : intercepted field
+ * @param interceptor : interceptor
+ */
+ public void register(FieldMetadata field, FieldInterceptor interceptor) {
+ if (m_fieldRegistration == null) {
+ m_fieldRegistration = new HashMap();
+ m_fieldRegistration.put(field.getFieldName(), new FieldInterceptor[] { interceptor });
+ } else {
+ FieldInterceptor[] list = (FieldInterceptor[]) m_fieldRegistration.get(field.getFieldName());
+ if (list == null) {
+ m_fieldRegistration.put(field.getFieldName(), new FieldInterceptor[] { interceptor });
} else {
- PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fields[i].getFieldName());
for (int j = 0; j < list.length; j++) {
- if (list[j] == h) {
+ if (list[j] == interceptor) {
return;
}
}
- PrimitiveHandler[] newList = new PrimitiveHandler[list.length + 1];
+ FieldInterceptor[] newList = new FieldInterceptor[list.length + 1];
System.arraycopy(list, 0, newList, 0, list.length);
- newList[list.length] = h;
- m_fieldRegistration.put(fields[i].getFieldName(), newList);
+ newList[list.length] = interceptor;
+ m_fieldRegistration.put(field.getFieldName(), newList);
}
}
- for (int i = 0; methods != null && i < methods.length; i++) {
- if (m_methodRegistration == null) {
- m_methodRegistration = new HashMap();
- m_methodRegistration.put(methods[i].getMethodIdentifier(), new PrimitiveHandler[] { h });
- } else {
- PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methods[i].getMethodIdentifier());
- if (list == null) {
- m_methodRegistration.put(methods[i].getMethodIdentifier(), new PrimitiveHandler[] { h });
- } else {
- for (int j = 0; j < list.length; j++) {
- if (list[j] == h) {
- return;
- }
+ }
+
+ /**
+ * Register a method interceptor.
+ * @param method : intercepted method
+ * @param interceptor : interceptor
+ */
+ public void register(MethodMetadata method, MethodInterceptor interceptor) {
+ if (m_methodRegistration == null) {
+ m_methodRegistration = new HashMap();
+ m_methodRegistration.put(method.getMethodIdentifier(), new MethodInterceptor[] { interceptor });
+ } else {
+ MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(method.getMethodIdentifier());
+ if (list == null) {
+ m_methodRegistration.put(method.getMethodIdentifier(), new MethodInterceptor[] { interceptor });
+ } else {
+ for (int j = 0; j < list.length; j++) {
+ if (list[j] == interceptor) {
+ return;
}
- PrimitiveHandler[] newList = new PrimitiveHandler[list.length + 1];
- System.arraycopy(list, 0, newList, 0, list.length);
- newList[list.length] = h;
- m_methodRegistration.put(methods[i].getMethodIdentifier(), newList);
}
+ MethodInterceptor[] newList = new MethodInterceptor[list.length + 1];
+ System.arraycopy(list, 0, newList, 0, list.length);
+ newList[list.length] = interceptor;
+ m_methodRegistration.put(method.getMethodIdentifier(), newList);
}
}
-
}
/**
- * This method is called by the manipulated class each time that a GETFIELD
- * instruction is found. The method ask to each handler which value need to
- * be returned.
- *
- * @param fieldName : the field name on which the GETFIELD instruction is
- * called
- * @return the value decided by the last asked handler (throw a warning if
- * two fields decide two different values)
+ * This method is called by the manipulated class each time that a GETFIELD instruction is found. The method ask to each handler which value need
+ * to be returned.
+ * @param pojo : the pojo object on which the field was get
+ * @param fieldName : the field name on which the GETFIELD instruction is called
+ * @return the value decided by the last asked handler (throw a warning if two fields decide two different values)
*/
- public Object getterCallback(String fieldName) {
- Object initialValue = m_map.get(fieldName);
+ public Object onGet(Object pojo, String fieldName) {
+ Object initialValue = m_fields.get(fieldName);
Object result = initialValue;
// Get the list of registered handlers
- PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fieldName);
+
+ FieldInterceptor[] list = (FieldInterceptor[]) m_fieldRegistration.get(fieldName);
for (int i = 0; list != null && i < list.length; i++) {
- Object handlerResult = list[i].getterCallback(fieldName, initialValue);
+ Object handlerResult = list[i].onGet(null, fieldName, initialValue);
if (handlerResult == initialValue) {
continue; // Non-binding case (default implementation).
} else {
if (result != initialValue) {
- if ((handlerResult != null && ! handlerResult.equals(result)) || (result != null && handlerResult == null)) {
- m_factory.getLogger().log(Logger.WARNING, "A conflict was detected on the injection of " + fieldName + " - return the last value from " + list[i].getInstance().getInstanceName());
+ if ((handlerResult != null && !handlerResult.equals(result)) || (result != null && handlerResult == null)) {
+ m_factory.getLogger().log(
+ Logger.WARNING,
+ "A conflict was detected on the injection of "
+ + fieldName);
}
}
result = handlerResult;
}
}
-
- if ((result != null && ! result.equals(initialValue)) || (result == null && initialValue != null)) {
+
+ if ((result != null && !result.equals(initialValue)) || (result == null && initialValue != null)) {
// A change occurs => notify the change
- m_map.put(fieldName, result);
+ m_fields.put(fieldName, result);
for (int i = 0; list != null && i < list.length; i++) {
- list[i].setterCallback(fieldName, result);
+ list[i].onSet(null, fieldName, result);
}
}
-
- return result;
+
+ return result;
}
-
+
/**
* Dispatch entry method event on registered handler.
+ * @param pojo : the pojo object on which method is invoked.
+ * @param methodId : method id
+ * @param args : argument array
+ */
+ public void onEntry(Object pojo, String methodId, Object[] args) {
+ if (m_methodRegistration == null) {
+ return;
+ }
+ MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(methodId);
+ Method method = getMethodById(methodId);
+ for (int i = 0; list != null && i < list.length; i++) {
+ list[i].onEntry(pojo, method, args);
+ }
+ }
+
+ /**
+ * Dispatch exit method event on registered handler. The given returned object is an instance of Exception if the method has launched an
+ * exception. If the given object is null, either the method returns void, either the method has returned null.
+ * @param pojo : the pojo object on which the method was invoked
* @param methodId : method id
+ * @param result : returned object.
*/
- public void entryCallback(String methodId) {
- PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methodId);
+ public void onExit(Object pojo, String methodId, Object result) {
+ if (m_methodRegistration == null) {
+ return;
+ }
+ MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(methodId);
+ Method method = getMethodById(methodId);
+ for (int i = 0; list != null && i < list.length; i++) {
+ list[i].onExit(pojo, method, result);
+ }
for (int i = 0; list != null && i < list.length; i++) {
- list[i].entryCallback(methodId);
+ list[i].onFinally(pojo, method);
}
}
/**
- * Dispatch exit method event on registered handler.
- * The given returned object is an instance of Exception if the method has launched an exception.
+ * Dispatch error method event on registered handler. The given returned object is an instance of Exception if the method has thrown an exception.
* If the given object is null, either the method returns void, either the method has returned null.
+ * @param pojo : the pojo object on which the method was invoked
* @param methodId : method id
- * @param e : returned object.
+ * @param error : throwable object.
*/
- public void exitCallback(String methodId, Object e) {
- PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methodId);
+ public void onError(Object pojo, String methodId, Throwable error) {
+ if (m_methodRegistration == null) {
+ return;
+ }
+ MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(methodId);
+ Method method = getMethodById(methodId);
+ for (int i = 0; list != null && i < list.length; i++) {
+ list[i].onError(pojo, method, error);
+ }
for (int i = 0; list != null && i < list.length; i++) {
- list[i].exitCallback(methodId, e);
+ list[i].onFinally(pojo, method);
}
}
/**
- * This method is called by the manipulated class each time that a PUTFILED
- * instruction is found. the method send to each handler the new value.
- *
- * @param fieldName : the field name on which the PUTFIELD instruction is
- * called
+ * Get method object by id.
+ * @param methodId : method id
+ * @return : the method object or null if the method cannot be found.
+ */
+ private Method getMethodById(String methodId) {
+ Method method = (Method) m_methods.get(methodId);
+ if (method == null) {
+ Method[] mets = m_clazz.getDeclaredMethods();
+ for (int i = 0; i < mets.length; i++) {
+ // Check if the method was not already computed. If not, compute the Id and check.
+ if (!m_methods.containsValue(mets[i]) && (MethodMetadata.computeMethodId(mets[i]).equals(methodId))) {
+ // Store the new methodId
+ m_methods.put(methodId, mets[i]);
+ return mets[i];
+ }
+ }
+ // If not found, it is a constructor, return null in this case.
+ if (methodId.equals(m_clazz.getName())) {
+ // Constructor.
+ return null;
+ }
+ // Cannot happen
+ m_factory.getLogger().log(Logger.ERROR, "A methodID cannot be associate with a POJO method : " + methodId);
+ return null;
+ } else {
+ return method;
+ }
+ }
+
+ /**
+ * This method is called by the manipulated class each time that a PUTFILED instruction is found. the method send to each handler the new value.
+ * @param pojo : the pojo object on which the field was set
+ * @param fieldName : the field name on which the PUTFIELD instruction is called
* @param objectValue : the value of the field
*/
- public void setterCallback(String fieldName, Object objectValue) {
- Object o = m_map.get(fieldName);
- if ((o != null && ! o.equals(objectValue)) || (o == null && objectValue != null)) {
- m_map.put(fieldName, objectValue);
- PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fieldName);
+ public void onSet(Object pojo, String fieldName, Object objectValue) {
+ Object value = m_fields.get(fieldName);
+ if ((value != null && !value.equals(objectValue)) || (value == null && objectValue != null)) {
+ m_fields.put(fieldName, objectValue);
+ FieldInterceptor[] list = (FieldInterceptor[]) m_fieldRegistration.get(fieldName);
for (int i = 0; list != null && i < list.length; i++) {
- list[i].setterCallback(fieldName, objectValue);
+ list[i].onSet(null, fieldName, objectValue);
}
}
}
@@ -701,11 +891,11 @@
public BundleContext getContext() {
return m_context;
}
-
+
public BundleContext getGlobalContext() {
return ((IPojoContext) m_context).getGlobalContext();
}
-
+
public ServiceContext getLocalServiceContext() {
return ((IPojoContext) m_context).getServiceContext();
}
@@ -748,15 +938,16 @@
}
/**
- * State Change listener callback.
- * This method is notified at each time a plugged handler becomes invalid.
- * @param instance : changing instance
+ * State Change listener callback. This method is notified at each time a plugged handler becomes invalid.
+ * @param instance : changing instance
* @param newState : new state
* @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
*/
public synchronized void stateChanged(ComponentInstance instance, int newState) {
- if (m_state <= STOPPED) { return; }
-
+ if (m_state <= STOPPED) {
+ return;
+ }
+
// Update the component state if necessary
if (newState == INVALID && m_state == VALID) {
// Need to update the state to UNRESOLVED
@@ -766,36 +957,35 @@
if (newState == VALID && m_state == INVALID) {
// An handler becomes valid => check if all handlers are valid
for (int i = 0; i < m_handlers.length; i++) {
- if (m_handlers[i].getState() != VALID) { return; }
+ if (m_handlers[i].getState() != VALID) {
+ return;
+ }
}
setState(VALID);
return;
- }
+ }
}
-
+
/**
- * Get the list of registered fields.
- * This method is invoked by the POJO itself.
+ * Get the list of registered fields. This method is invoked by the POJO itself.
* @return the set of registered fields.
*/
public Set getRegistredFields() {
- if (m_fieldRegistration != null) {
- return m_fieldRegistration.keySet();
- } else {
+ if (m_fieldRegistration == null) {
return null;
}
+ return m_fieldRegistration.keySet();
}
-
+
/**
- * Get the list of registered methods.
- * This method is invoked by the POJO itself.
+ * Get the list of registered methods. This method is invoked by the POJO itself.
* @return the set of registered methods.
*/
public Set getRegistredMethods() {
- if (m_methodRegistration != null) {
- return m_methodRegistration.keySet();
- } else {
+ if (m_methodRegistration == null) {
return null;
+ } else {
+ return m_methodRegistration.keySet();
}
}
}
Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java Fri Mar 28 08:33:36 2008
@@ -42,6 +42,7 @@
* @param missing : list of missing handlers.
*/
public MissingHandlerException(List missing) {
+ super();
m_message = "Missing handlers : ";
for (int i = 0; i < missing.size(); i++) {
m_message += (String) missing.get(i) + " ";
Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java Fri Mar 28 08:33:36 2008
@@ -22,7 +22,6 @@
import java.io.InputStream;
import java.util.Dictionary;
-import org.apache.felix.ipojo.composite.ServiceReferenceImpl;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
@@ -85,7 +84,11 @@
public PolicyServiceContext(BundleContext global, ServiceContext local, int policy) {
m_global = global;
m_local = local;
- m_policy = policy;
+ if (m_local == null) {
+ m_policy = GLOBAL;
+ } else {
+ m_policy = policy;
+ }
}
/**
@@ -137,23 +140,7 @@
case LOCAL_AND_GLOBAL:
ServiceReference[] refLocal = m_local.getAllServiceReferences(clazz, filter);
ServiceReference[] refGlobal = m_global.getAllServiceReferences(clazz, filter);
- if (refLocal != null && refGlobal != null) {
- ServiceReference[] refs = new ServiceReference[refLocal.length + refGlobal.length];
- int j = 0;
- for (int i = 0; i < refLocal.length; i++) {
- refs[j] = refLocal[i];
- j++;
- }
- for (int i = 0; i < refGlobal.length; i++) {
- refs[j] = refGlobal[i];
- j++;
- }
- return refs;
- } else if (refLocal != null && refGlobal == null) {
- return refLocal;
- } else {
- return refGlobal;
- }
+ return computeServiceReferencesFromBoth(refLocal, refGlobal);
default:
return null;
}
@@ -166,7 +153,7 @@
* @see org.apache.felix.ipojo.ServiceContext#getService(org.osgi.framework.ServiceReference)
*/
public Object getService(ServiceReference ref) {
- switch(m_policy) {
+ switch(m_policy) { // NOPMD No break needed as we return in each branch.
case LOCAL:
// The reference comes from the local scope
return m_local.getService(ref);
@@ -174,8 +161,7 @@
// The reference comes from the global registry
return m_global.getService(ref);
case LOCAL_AND_GLOBAL:
- if (ref instanceof org.apache.felix.ipojo.composite.ServiceReferenceImpl) {
- // The reference comes from a composite, i.e. necessary the local composite
+ if (ref instanceof org.apache.felix.ipojo.context.ServiceReferenceImpl) {
return m_local.getService(ref);
} else {
return m_global.getService(ref);
@@ -192,17 +178,17 @@
* @see org.apache.felix.ipojo.ServiceContext#getServiceReference(java.lang.String)
*/
public ServiceReference getServiceReference(String clazz) {
- switch (m_policy) {
+ switch (m_policy) { // NOPMD No break needed as we return in each branch.
case LOCAL:
return m_local.getServiceReference(clazz);
case GLOBAL:
return m_global.getServiceReference(clazz);
case LOCAL_AND_GLOBAL:
ServiceReference refLocal = m_local.getServiceReference(clazz);
- if (refLocal != null) {
- return refLocal;
+ if (refLocal == null) {
+ return m_global.getServiceReference(clazz);
} else {
- return m_global.getServiceReference(clazz);
+ return refLocal;
}
default:
return null;
@@ -226,28 +212,31 @@
case LOCAL_AND_GLOBAL:
ServiceReference[] refLocal = m_local.getServiceReferences(clazz, filter);
ServiceReference[] refGlobal = m_global.getServiceReferences(clazz, filter);
- if (refLocal != null && refGlobal != null) {
- ServiceReference[] refs = new ServiceReference[refLocal.length + refGlobal.length];
- int j = 0;
- for (int i = 0; i < refLocal.length; i++) {
- refs[j] = refLocal[i];
- j++;
- }
- for (int i = 0; i < refGlobal.length; i++) {
- refs[j] = refGlobal[i];
- j++;
- }
- return refs;
- } else if (refLocal != null && refGlobal == null) {
- return refLocal;
- } else {
- return refGlobal;
- }
+ return computeServiceReferencesFromBoth(refLocal, refGlobal);
default:
return null;
}
}
+
+ /**
+ * Compute the service reference array from the two given set of service references.
+ * @param refLocal : local references
+ * @param refGlobal : global references
+ * @return the set of service reference
+ */
+ private ServiceReference[] computeServiceReferencesFromBoth(ServiceReference[] refLocal, ServiceReference[] refGlobal) {
+ if (refLocal == null) {
+ return refGlobal; // If refGlobal is null, return null, else return refGlobal
+ } else if (refGlobal == null) { // refLocal != null && refGlobal == null
+ return refLocal;
+ } else { // Both refGlobal and refLocal are not null
+ ServiceReference[] refs = new ServiceReference[refLocal.length + refGlobal.length];
+ System.arraycopy(refLocal, 0, refs, 0, refLocal.length);
+ System.arraycopy(refGlobal, 0, refs, refLocal.length, refGlobal.length);
+ return refs;
+ }
+ }
/**
* This method is not supported.
@@ -294,7 +283,7 @@
* @see org.apache.felix.ipojo.ServiceContext#ungetService(org.osgi.framework.ServiceReference)
*/
public boolean ungetService(ServiceReference reference) {
- if (reference instanceof ServiceReferenceImpl) {
+ if (reference instanceof org.apache.felix.ipojo.context.ServiceReferenceImpl) {
return m_local.ungetService(reference);
} else {
return m_global.ungetService(reference);
@@ -343,12 +332,12 @@
/**
* Get the bundle object with the given id.
- * @param id : bundle id
+ * @param bundleId : bundle id
* @return the bundle object
* @see org.osgi.framework.BundleContext#getBundle(long)
*/
- public Bundle getBundle(long id) {
- return m_global.getBundle(id);
+ public Bundle getBundle(long bundleId) {
+ return m_global.getBundle(bundleId);
}
/**
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=642265&r1=642264&r2=642265&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 Fri Mar 28 08:33:36 2008
@@ -18,6 +18,12 @@
*/
package org.apache.felix.ipojo;
+import java.lang.reflect.Method;
+
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.Logger;
+
/**
@@ -25,7 +31,7 @@
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-public abstract class PrimitiveHandler extends Handler {
+public abstract class PrimitiveHandler extends Handler implements FieldInterceptor, MethodInterceptor {
/**
* "Primitive" Handler type (value).
@@ -37,20 +43,45 @@
*/
private InstanceManager m_manager;
+
+ /**
+ * Factory of the instance manager.
+ */
+ private ComponentFactory m_factory;
+
/**
* Attach the current handler to the given instance.
- * @param im ! the instance on which the current handler will be attached.
+ * @param manager ! the instance on which the current handler will be attached.
* @see org.apache.felix.ipojo.Handler#attach(org.apache.felix.ipojo.ComponentInstance)
*/
- protected final void attach(ComponentInstance im) {
- m_manager = (InstanceManager) im;
- setLogger(m_manager.getFactory().getLogger());
+ protected final void attach(ComponentInstance manager) {
+ m_manager = (InstanceManager) manager;
+ }
+
+ public final void setFactory(Factory factory) {
+ m_factory = (ComponentFactory) factory;
+ }
+
+ public Logger getLogger() {
+ return m_factory.getLogger();
}
public InstanceManager getInstanceManager() {
return m_manager;
}
+ public ComponentFactory getFactory() {
+ return m_factory;
+ }
+
+ public Element[] getMetadata() {
+ return null;
+ }
+
+ public PojoMetadata getPojoMetadata() {
+ return m_factory.getPojoMetadata();
+ }
+
/**
* Get a plugged handler of the same container.
* This method must be call only in the start method (or after).
@@ -65,45 +96,76 @@
/**
* This method is called when a PUTFIELD operation is detected.
+ * @param pojo : the pojo object setting the value
* @param fieldName : the field name
* @param value : the value passed to the field
*/
- public void setterCallback(String fieldName, Object value) {
- return;
+ public void onSet(Object pojo, String fieldName, Object value) {
+ // Nothing do do in the default implementation
}
/**
* This method is called when a GETFIELD operation is detected.
+ * @param pojo : the pojo object getting the value
* @param fieldName : the field name
* @param value : the value passed to the field (by the previous call)
* @return : the managed value of the field
*/
- public Object getterCallback(String fieldName, Object value) {
+ public Object onGet(Object pojo, String fieldName, Object value) {
return value;
}
/**
* This method is called when the execution enter in a method.
- * @param methodId : the method identifier
+ * @param pojo : pojo on which the method is called.
+ * @param method : method invoked.
+ * @param args arguments array.
*/
- public void entryCallback(String methodId) { }
+ public void onEntry(Object pojo, Method method, Object[] args) {
+ // Nothing do do in the default implementation
+ }
/**
* This method is called when the execution exit a method (before a return or a throw).
- * If the given returned object is an instance of Exception, this means that the method throwed this exception.
* If the given returned object is null, either the method is void, either it returns null.
* You must not modified the returned object.
- * @param methodId : the method identifier
+ * @param pojo : the pojo on which the method exits.
+ * @param method : exiting method.
* @param returnedObj : the returned object (boxed for primitive type)
*/
- public void exitCallback(String methodId, Object returnedObj) { }
+ public void onExit(Object pojo, Method method, Object returnedObj) {
+ // Nothing do do in the default implementation
+ }
+
+ /**
+ * This method is called when the execution throw an exception in the given method.
+ * @param pojo : the pojo on which the method was accessed.
+ * @param method : invoked method.
+ * @param throwable : the thrown exception
+ */
+ public void onError(Object pojo, Method method, Throwable throwable) {
+ // Nothing do do in the default implementation
+ }
+
+ /**
+ * This method is called when the execution of a method will terminate :
+ * just before to throw an exception or before to return.
+ * OnError or OnExit was already called.
+ * @param pojo : the pojo on which the method was accessed.
+ * @param method : invoked method.
+ */
+ public void onFinally(Object pojo, Method method) {
+ // Nothing do do in the default implementation
+ }
/**
* This method is called when an instance of the component is created, but
* before someone can use it.
* @param instance : the created instance
*/
- public void objectCreated(Object instance) { }
+ public void onCreation(Object instance) {
+ // Nothing do do in the default implementation
+ }
Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java Fri Mar 28 08:33:36 2008
@@ -18,7 +18,6 @@
*/
package org.apache.felix.ipojo.architecture;
-import org.apache.felix.ipojo.CompositeHandler;
import org.apache.felix.ipojo.Handler;
import org.apache.felix.ipojo.metadata.Attribute;
import org.apache.felix.ipojo.metadata.Element;
@@ -43,21 +42,11 @@
/**
* Constructor.
*
- * @param h : handler.
+ * @param handler : handler.
*/
- public HandlerDescription(Handler h) {
- m_handlerName = h.getClass().getName();
- m_isValid = h.isValid();
- }
-
- /**
- * Constructor.
- *
- * @param h : composite handler.
- */
- public HandlerDescription(CompositeHandler h) {
- m_handlerName = h.getClass().getName();
- m_isValid = h.isValid();
+ public HandlerDescription(Handler handler) {
+ m_handlerName = handler.getClass().getName();
+ m_isValid = handler.isValid();
}
/**
Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java Fri Mar 28 08:33:36 2008
@@ -57,7 +57,7 @@
/**
* Component Type of the instance.
*/
- private ComponentDescription m_type;
+ private ComponentTypeDescription m_type;
/**
* COntained instance list.
@@ -70,16 +70,16 @@
* @param name : the name of the component instance.
* @param state : the state of the instance.
* @param bundleId : bundle id owning this instance.
- * @param cd : the component type description of this instance.
+ * @param desc : the component type description of this instance.
*/
- public InstanceDescription(String name, int state, long bundleId, ComponentDescription cd) {
+ public InstanceDescription(String name, int state, long bundleId, ComponentTypeDescription desc) {
m_name = name;
m_state = state;
m_createdObjects = new String[0];
m_handlers = new HandlerDescription[0];
m_containedInstances = new InstanceDescription[0];
m_bundleId = bundleId;
- m_type = cd;
+ m_type = desc;
}
/**
@@ -110,7 +110,7 @@
* Get the component type description of the described instance.
* @return : the component type description of this instance.
*/
- public ComponentDescription getComponentDescription() {
+ public ComponentTypeDescription getComponentDescription() {
return m_type;
}
@@ -124,12 +124,12 @@
/**
* Add an handler description to the list.
- * @param hd : the handler description to add
+ * @param desc : the handler description to add
*/
- public void addHandler(HandlerDescription hd) {
+ public void addHandler(HandlerDescription desc) {
// Verify that the dependency description is not already in the array.
for (int i = 0; i < m_handlers.length; i++) {
- if (m_handlers[i] == hd) {
+ if (m_handlers[i] == desc) {
return; // NOTHING TO DO, the description is already in the
// array
}
@@ -137,7 +137,7 @@
// The component Description is not in the array, add it
HandlerDescription[] newHd = new HandlerDescription[m_handlers.length + 1];
System.arraycopy(m_handlers, 0, newHd, 0, m_handlers.length);
- newHd[m_handlers.length] = hd;
+ newHd[m_handlers.length] = desc;
m_handlers = newHd;
}
@@ -163,10 +163,10 @@
/**
* Set the state of the component.
*
- * @param i : the state
+ * @param state : the state
*/
- public void setState(int i) {
- m_state = i;
+ public void setState(int state) {
+ m_state = state;
}
/**
@@ -215,7 +215,7 @@
instance.addAttribute(new Attribute("state", "disposed"));
}
// Bundle
- instance.addAttribute(new Attribute("bundle", "" + m_bundleId));
+ instance.addAttribute(new Attribute("bundle", Long.toString(m_bundleId)));
// Component Type
instance.addAttribute(new Attribute("component.type", m_type.getName()));
Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java Fri Mar 28 08:33:36 2008
@@ -18,6 +18,10 @@
*/
package org.apache.felix.ipojo.architecture;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.util.Property;
+import org.osgi.framework.BundleContext;
+
/**
* Property Information.
*
@@ -39,6 +43,14 @@
* Default value of the property.
*/
private String m_value = null;
+
+
+ /**
+ * Immutable property flag
+ * IF true, the property cannot be override by the instance configuration.
+ * Moreover, immutable properties are exposed on the factory service too.
+ */
+ private boolean m_immutable = false;
/**
* Constructor.
@@ -52,6 +64,21 @@
m_type = type;
m_value = value;
}
+
+ /**
+ * Constructor.
+ *
+ * @param name : name of the property
+ * @param type : type of the property
+ * @param value : default value of the property
+ * @param immutable : the property is immutable.
+ */
+ public PropertyDescription(String name, String type, String value, boolean immutable) {
+ m_name = name;
+ m_type = type;
+ m_value = value;
+ m_immutable = immutable;
+ }
/**
* Get the current property name.
@@ -75,6 +102,28 @@
*/
public String getValue() {
return m_value;
+ }
+
+ /**
+ * Is the property immutable.
+ * @return true if the property is immutable.
+ */
+ public boolean isImmutable() {
+ return m_immutable;
+ }
+ /**
+ * Get the object value of the current immutable property.
+ * @param context : bundle context to use to load classes.
+ * @return the object value of the current property.
+ */
+ public Object getObjectValue(BundleContext context) {
+ Class type = null;
+ try {
+ type = Property.computeType(m_type, context);
+ return Property.create(type, m_value);
+ } catch (ConfigurationException e) {
+ return m_value; // Cannot create the object.
+ }
}
}
Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java?rev=642265&r1=642264&r2=642265&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java Fri Mar 28 08:33:36 2008
@@ -24,7 +24,6 @@
import org.apache.felix.ipojo.architecture.Architecture;
import org.apache.felix.ipojo.architecture.InstanceDescription;
import org.apache.felix.ipojo.metadata.Element;
-import org.apache.felix.ipojo.util.Logger;
/**
* Architecture Handler : do reflection on your component.
@@ -52,6 +51,7 @@
* @see org.apache.felix.ipojo.Handler#stop()
*/
public void stop() {
+ // Nothing do do when stopping.
}
/**
@@ -59,7 +59,7 @@
* @see org.apache.felix.ipojo.Handler#start()
*/
public void start() {
- log(Logger.INFO, "Start architecture handler with " + m_name + " name");
+ info("Start architecture handler with " + m_name + " name");
}
/**