You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ri...@apache.org on 2006/06/14 17:22:08 UTC

svn commit: r414287 [4/6] - in /incubator/felix/trunk: org.apache.felix.ipojo.arch/ org.apache.felix.ipojo.arch/src/ org.apache.felix.ipojo.arch/src/main/ org.apache.felix.ipojo.arch/src/main/java/ org.apache.felix.ipojo.arch/src/main/java/org/ org.apa...

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,498 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.ComponentManager;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Represent a service dependency either for a componenet dependency either for
+ * a provided service dependency. Date : 3 déc. 2005
+ * @author clément
+ */
+public class Dependency implements ServiceListener {
+
+    /**
+     * Dependency State : RESOLVED.
+     */
+    public static final int RESOLVED = 1;
+
+    /**
+     * Dependency State : UNRESOLVED.
+     */
+    public static final int UNRESOLVED = 2;
+
+    /**
+     * Link to the Component Manager.
+     * m_handler : ComponentManager
+     */
+    private DependencyHandler m_handler;
+
+
+    /**
+     * Metadata of the dependency.
+     * m_metadata : dependency metadata
+     */
+    private DependencyMetadata m_metadata;
+
+    /**
+     * Array of Service Objects.
+     * When cardinality = 1 : just the first element is returned
+     * When cardinality = ?..n : all the array is returned
+     * m_services : Array
+     */
+    private Object[] m_services = new Object[0];
+
+    /**
+     * Array of service references.
+     * m_ref : Array
+     */
+    private ServiceReference[] m_ref = new ServiceReference[0];
+
+    /**
+     * State of the dependency.
+     * 0 : stopped, 1 : valid, 2 : invalid.
+     * m_state : int
+     */
+    private int m_state;
+
+    /**
+     * True if the reference list change after the creation of a service object array.
+     */
+    private boolean m_change;
+
+    /**
+     * Class of the dependency.
+     * Usefull to create in the case of multiple dependency
+     */
+    private Class m_clazz;
+
+
+    /**
+     * Dependency contructor. After the creation the dependency is not started.
+     * @param dh : the dependency handler managing this dependency
+     * @param dm : the depednency metadata
+     */
+    public Dependency(DependencyHandler dh, DependencyMetadata dm) {
+    	m_handler = dh;
+        m_metadata = dm;
+    }
+
+    /**
+     * @return the dependency metadata.
+     */
+    public DependencyMetadata getMetadata() { return m_metadata; }
+
+    /**
+     * @return the dependency handler of this dependency.
+     */
+    public DependencyHandler getDependencyHandler() { return m_handler; }
+
+    /**
+     * @return the used service.
+     */
+    public HashMap getUsedServices() {
+    	HashMap hm = new HashMap();
+    	if (m_metadata.isMultiple()) {
+    		for (int i = 0; i < m_ref.length; i++) {
+    			if (i < m_services.length) { hm.put(((Object)m_services[i]).toString(), m_ref[i]); }
+    		}
+    	} else {
+    		if (m_ref.length != 0 && m_services.length != 0) { hm.put(((Object)m_services[0]).toString(), m_ref[0]); }
+    	}
+    	return hm;
+    }
+
+    /**
+     * A dependency is satisfied if it is optional of ref.length != 0.
+     * @return true is the dependency is satified
+     */
+    protected boolean isSatisfied() {
+        return m_metadata.isOptional() || m_ref.length != 0;
+    }
+
+    /**
+     * This method is called by the replaced code in the component implementation class.
+     * Construct the service object list is necessary.
+     * @return null or a service object or a list of service object according to the dependency.
+     */
+    protected Object get() {
+        Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Call get for a dependency on : " + m_metadata.getServiceSpecification()
+                        + " Multiple : " + m_metadata.isMultiple() + " Optional : " + m_metadata.isOptional());
+        try {
+
+            // 1 : Test if there is any change in the reference list :
+            if (!m_change) {
+                if (!m_metadata.isMultiple()) {
+                    if (m_services.length > 0) {
+                        return m_services[0]; }
+                    }
+                else {
+                    return m_services;
+               }
+            }
+
+            // 2 : Else there is a change in the list -> recompute the m_services array
+            Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Create a service array of " + m_clazz.getName());
+            m_services = (Object[])Array.newInstance(m_clazz, m_ref.length);
+
+            for (int i = 0; i < m_ref.length; i++) {
+                m_services[i] = m_handler.getComponentManager().getContext().getService(m_ref[i]);
+            }
+
+            m_change = false;
+            Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Create an array with the size " + m_services.length);
+
+
+            // 3 : The service object list is populated, I return either the first service object, either the array.
+            // Return null or an empty array if no service are found.
+            if (!m_metadata.isMultiple()) {
+                if (m_services.length > 0) {
+                    return m_services[0];
+                } else {
+                		// Load the nullable class
+                		String[] segment = m_metadata.getServiceSpecification().split("[.]");
+                		String className = "org.apache.felix.ipojo." + segment[segment.length - 1] + "Nullable";
+                		Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Try to load the nullable class for " + getMetadata().getServiceSpecification() + " -> " + className);
+                		Class nullableClazz = m_handler.getNullableClass(className);
+
+                		if (nullableClazz == null) {
+                			Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Cannot load the nullable class to return a dependency object for " + m_metadata.getField() + " -> " + m_metadata.getServiceSpecification());
+                			return null;
+                		}
+
+                		// The nullable class is loaded, create the object and return it
+                		Object instance = nullableClazz.newInstance();
+                		Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Nullable object created for " + getMetadata().getServiceSpecification() + " -> " + instance);
+                		return instance;
+                	}
+            }
+            else { // Multiple dependency
+                    return m_services;
+            }
+        } catch (Exception e) {
+            // There is a problem in the dependency resolving (like in stopping method)
+            if (!m_metadata.isMultiple()) {
+            	Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Return null, an exception was throwed in the get method -> " + e.getMessage());
+                return null; }
+            else {
+            	Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Return an empty array, an exception was throwed in the get method" + e.getMessage());
+                return Array.newInstance(m_clazz, 0); }
+        }
+    }
+
+    /**
+     * Method calld when a service event is throwed.
+     * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+     * @param event : the received service event
+     */
+    public void serviceChanged(ServiceEvent event) {
+        synchronized (this) {
+
+            // If a service goes way.
+            if (event.getType() == ServiceEvent.UNREGISTERING) {
+                Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] A service is gone -> " + event.getServiceReference().getBundle());
+                if (containsSR(event.getServiceReference())) {
+                		// Call unbind method
+                		callUnbindMethod(event.getServiceReference());
+                		// Unget the service reference
+                    	m_handler.getComponentManager().getContext().ungetService(event.getServiceReference());
+                        int index = removeReference(event.getServiceReference());
+
+                        // Is the state valid or invalid
+                        if (m_ref.length == 0 && !m_metadata.isOptional()) {
+                            m_state = UNRESOLVED;
+                        }
+                        if (m_ref.length == 0 && m_metadata.isOptional()) {
+                            m_state = RESOLVED;
+                        }
+                        // Is there any change ?
+                        if (!m_metadata.isMultiple() && index == 0) { m_change = true; }
+                        if (!m_metadata.isMultiple() && index != 0) { m_change = false; }
+                        if (m_metadata.isMultiple()) { m_change = true;  }
+                    }
+                    m_handler.checkContext();
+                    return;
+            }
+
+            // If a service arrives
+            if (event.getType() == ServiceEvent.REGISTERED) {
+                // Add the new service inside the ref list
+                Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Add a service for a dependency");
+                addReference(event.getServiceReference());
+                if (isSatisfied()) {
+                    m_state = RESOLVED;
+                    if (m_metadata.isMultiple() || m_ref.length == 1) { m_change = true; }
+                    callBindMethod(event.getServiceReference());
+                }
+                m_handler.checkContext();
+            }
+
+        }
+    }
+
+    private void callUnbindMethod(ServiceReference ref) {
+        if (m_handler.getComponentManager().getState() == ComponentManager.VALID && m_metadata.isMultiple()) {
+        	for (int i = 0; i < m_metadata.getCallbacks().length; i++) {
+        		if (m_metadata.getCallbacks()[i].getMethodType() == DependencyCallback.UNBIND) {
+        			// Try to call the bind method with a service reference inside
+        			try {
+						m_metadata.getCallbacks()[i].call(new Object[] {ref});
+					} catch (NoSuchMethodException e) {
+						// The method was not found : try without service reference
+						try {
+							m_metadata.getCallbacks()[i].call();
+						} catch (NoSuchMethodException e1) {
+							// The method was not found : try with the service object
+							try {
+								m_metadata.getCallbacks()[i].call(new Object[] {m_handler.getComponentManager().getContext().getService(ref)});
+							} catch (NoSuchMethodException e2) {
+								Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Unbind method not found : " + e1.getMessage());
+								return;
+							} catch (IllegalAccessException e2) {
+								Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on unbind method : " + e2.getMessage());
+								return;
+							} catch (InvocationTargetException e2) {
+								Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the unbind method " + e2.getMessage());
+								return;
+							}
+						} catch (IllegalAccessException e1) {
+							Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on unbind method : " + e1.getMessage());
+							return;
+						} catch (InvocationTargetException e1) {
+							Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the unbind method " + e1.getMessage());
+							return;
+						}
+
+					} catch (IllegalAccessException e) {
+						Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on bind method : " + e.getMessage());
+						return;
+					} catch (InvocationTargetException e) {
+						Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the bind method " + e.getMessage());
+						return;
+					}
+        		}
+        	}
+        }
+    }
+
+    private void callBindMethod(ServiceReference ref) {
+    	// call bind method :
+        if (m_handler.getComponentManager().getState() == ComponentManager.VALID && m_metadata.isMultiple()) {
+        	for (int i = 0; i < m_metadata.getCallbacks().length; i++) {
+        		if (m_metadata.getCallbacks()[i].getMethodType() == DependencyCallback.BIND) {
+        			// Try to call the bind method with a service reference inside
+        			try {
+						m_metadata.getCallbacks()[i].call(new Object[] {ref});
+					} catch (NoSuchMethodException e) {
+						// The method was not found : try without service reference
+						try {
+							m_metadata.getCallbacks()[i].call();
+						} catch (NoSuchMethodException e1) {
+							// The method was not found : try with the service object
+							try {
+								m_metadata.getCallbacks()[i].call(new Object[] {m_handler.getComponentManager().getContext().getService(ref)});
+							} catch (NoSuchMethodException e2) {
+								Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Bind method not found : " + e1.getMessage());
+								return;
+							} catch (IllegalAccessException e2) {
+								Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on bind method : " + e2.getMessage());
+								return;
+							} catch (InvocationTargetException e2) {
+								Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the bind method " + e2.getMessage());
+								return;
+							}
+						} catch (IllegalAccessException e1) {
+							Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on bind method : " + e1.getMessage());
+							return;
+						} catch (InvocationTargetException e1) {
+							Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the bind method " + e1.getMessage());
+							return;
+						}
+
+					} catch (IllegalAccessException e) {
+						Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Illegal access on bind method : " + e.getMessage());
+						return;
+					} catch (InvocationTargetException e) {
+						Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Dependency Callback Error : Invocation Target Exception in the bind method " + e.getMessage());
+						return;
+					}
+        		}
+        	}
+        }
+    }
+
+    /**
+     * Start the dependency.
+     */
+    public void start() {
+        // Construct the filter with the objectclass + filter
+        String classnamefilter = "(objectClass=" + m_metadata.getServiceSpecification() + ")";
+        String filter = "";
+        if (!m_metadata.getFilter().equals("")) {
+            filter = "(&" + classnamefilter + m_metadata.getFilter() + ")";
+        }
+        else {
+            filter = classnamefilter;
+        }
+
+        Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Start a dependency on : " + m_metadata.getServiceSpecification() + " with " + m_metadata.getFilter());
+        m_state = UNRESOLVED;
+
+        try {
+            m_clazz = m_handler.getComponentManager().getContext().getBundle().loadClass(m_metadata.getServiceSpecification());
+        } catch (ClassNotFoundException e) {
+            System.err.println("Cannot load the interface class for the dependency " + m_metadata.getField() + " [" + m_metadata.getServiceSpecification() + "]");
+            e.printStackTrace();
+        }
+
+        try {
+            // Look if the service is already present :
+            ServiceReference[] sr = m_handler.getComponentManager().getContext().getServiceReferences(
+            		m_metadata.getServiceSpecification(), filter);
+            if (sr != null) {
+                for (int i = 0; i < sr.length; i++) { addReference(sr[i]); }
+                m_state = RESOLVED;
+                }
+            // Register a listener :
+            m_handler.getComponentManager().getContext().addServiceListener(this, filter);
+            m_change = true;
+        }
+        catch (InvalidSyntaxException e1) {
+            Activator.getLogger().log(Level.SEVERE, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] A filter is malformed : " + filter);
+            e1.printStackTrace();
+        }
+    }
+
+    /**
+     * Stop the dependency.
+     */
+    public void stop() {
+        Activator.getLogger().log(Level.INFO, "[" + m_handler.getComponentManager().getComponentMetatada().getClassName() + "] Stop a dependency on : " + m_metadata.getServiceSpecification() + " with " + m_metadata.getFilter());
+        m_state = UNRESOLVED;
+
+        // Unget all services references
+        for (int i = 0; i < m_ref.length; i++) {
+        	m_handler.getComponentManager().getContext().ungetService(m_ref[i]);
+        }
+
+        m_ref = new ServiceReference[0];
+        m_handler.getComponentManager().getContext().removeServiceListener(this);
+        m_clazz = null;
+        m_services = null;
+    }
+
+    /**
+     * Return the state of the dependency.
+     * @return the state of the dependency (1 : valid, 2 : invalid)
+     */
+    public int getState() {
+        return m_state;
+    }
+
+    /**
+     * Return the list of service reference.
+     * @return the service reference list.
+     */
+    public ServiceReference[] getServiceReferences() {
+        return m_ref;
+    }
+
+    /**
+     * Add a service reference in the current list.
+     * @param r : the new service reference to add
+     */
+    private void addReference(ServiceReference r) {
+        for (int i = 0; (m_ref != null) && (i < m_ref.length); i++) {
+            if (m_ref[i] == r) {
+                return;
+            }
+        }
+
+        if (m_ref != null) {
+            ServiceReference[] newSR = new ServiceReference[m_ref.length + 1];
+            System.arraycopy(m_ref, 0, newSR, 0, m_ref.length);
+            newSR[m_ref.length] = r;
+            m_ref = newSR;
+        }
+        else {
+            m_ref = new ServiceReference[] {r};
+        }
+    }
+
+    /**
+     * Find if a service registration il already registred.
+     * @param sr : the service registration to find.
+     * @return true if the service registration is already in the array
+     */
+    private boolean containsSR(ServiceReference sr) {
+        for (int i = 0; i < m_ref.length; i++) {
+            if (m_ref[i] == sr) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Remove a service reference in the current list.
+     * @param r : the new service reference to remove
+     * @return the index of the founded element, or -1 if the element is not found
+     */
+    private int removeReference(ServiceReference r) {
+        if (m_ref == null) {
+            m_ref = new ServiceReference[0];
+        }
+
+        int idx = -1;
+        for (int i = 0; i < m_ref.length; i++) {
+            if (m_ref[i] == r) {
+                idx = i;
+                break;
+            }
+        }
+
+        if (idx >= 0) {
+            // If this is the module, then point to empty list.
+            if ((m_ref.length - 1) == 0) {
+                m_ref = new ServiceReference[0];
+            }
+            // Otherwise, we need to do some array copying.
+            else {
+                ServiceReference[] newSR = new ServiceReference[m_ref.length - 1];
+                System.arraycopy(m_ref, 0, newSR, 0, idx);
+                if (idx < newSR.length)             {
+                    System.arraycopy(
+                            m_ref, idx + 1, newSR, idx, newSR.length - idx);
+                }
+                m_ref = newSR;
+            }
+        }
+        return idx;
+    }
+
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,88 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.felix.ipojo.Callback;
+
+
+/**
+ * This class allwos the creation of callback when service dependency arrives or disappear.
+ * @author escoffie
+ *
+ */
+public class DependencyCallback {
+
+	/**
+	 * Bind method (called when a service arrives).
+	 */
+	public static final int BIND = 0;
+
+	/**
+	 * Unbind method (called when a service disappears).
+	 */
+	public static final int UNBIND = 1;
+
+	/**
+	 * Is the method a bind method or an unbind method ?
+	 */
+	private int m_methodType;
+
+    /**
+     * Callback object.
+     */
+    private Callback m_callback;
+
+
+    /**
+     * Constructor.
+     * @param dep : the dependency attached to this depednency callback
+     * @param method : the method to call
+     * @param methodType : is the method to call a bind method or an unbind method
+     * @param isStatic : is the method to call static ?
+     */
+    public DependencyCallback(Dependency dep, String method, int methodType, boolean isStatic) {
+    	m_methodType = methodType;
+        m_callback = new Callback(method, isStatic, dep.getDependencyHandler().getComponentManager());
+    }
+
+    /**
+     * @return the method type.
+     */
+    public int getMethodType() { return m_methodType; }
+
+    /**
+     * Call the callback method.
+     * @throws NoSuchMethodException : Method is not found in the class
+     * @throws InvocationTargetException : The method is not static
+     * @throws IllegalAccessException : The method can not be invoked
+     */
+    protected void call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	m_callback.call();
+    }
+
+    /**
+     * Call the callback method.
+     * @throws NoSuchMethodException : Method is not found in the class
+     * @throws InvocationTargetException : The method is not static
+     * @throws IllegalAccessException : The method can not be invoked
+     */
+    protected void call(Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	m_callback.call(arg);
+    }
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,361 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.ComponentManager;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.handlers.dependency.nullable.NullableObjectWriter;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * The dependency handler manages a list of dependencies.
+ * @author clément
+ */
+public class DependencyHandler implements Handler {
+
+	/**
+	 * The component manager using this handler.
+	 */
+	private ComponentManager m_componentManager;
+
+	/**
+	 * List of depednencies of the component.
+	 */
+	private Dependency[] m_dependencies = new Dependency[0];
+
+	/**
+	 * List of nullable class for optional dependencies.
+	 */
+	private Class[] m_nullableClasses = new Class[0];
+
+	/**
+	 * Classloader to use to load nullable classes.
+	 */
+	private NullableClassloader m_classloader;
+
+	/**
+	 * State of the handler.
+	 */
+	private int m_state;
+
+//	 ===================== Fields getters & setters =====================
+
+	private void addDependency(Dependency dep) {
+        for (int i = 0; (m_dependencies != null) && (i < m_dependencies.length); i++) {
+            if (m_dependencies[i] == dep) {
+                return;
+            }
+        }
+        if (m_dependencies.length > 0) {
+            Dependency[] newDep = new Dependency[m_dependencies.length + 1];
+            System.arraycopy(m_dependencies, 0, newDep, 0, m_dependencies.length);
+            newDep[m_dependencies.length] = dep;
+            m_dependencies = newDep;
+        }
+        else {
+        	m_dependencies = new Dependency[] {dep};
+        }
+	}
+
+	private void addNullableClass(Class clazz) {
+		for (int i = 0; (m_nullableClasses != null) && (i < m_nullableClasses.length); i++) {
+            if (m_nullableClasses[i] == clazz) {
+                return;
+            }
+        }
+        if (m_nullableClasses.length > 0) {
+            Class[] newClass = new Class[m_nullableClasses.length + 1];
+            System.arraycopy(m_nullableClasses, 0, newClass, 0, m_nullableClasses.length);
+            newClass[m_nullableClasses.length] = clazz;
+            m_nullableClasses = newClass;
+        }
+        else {
+        	m_nullableClasses = new Class[] {clazz};
+        }
+	}
+
+	/**
+	 * @return the dependency list
+	 */
+	public Dependency[] getDependencies() { return m_dependencies; }
+
+	/**
+	 * @return the component manager
+	 */
+	protected ComponentManager getComponentManager() { return m_componentManager; }
+
+//	 ===================== Handler implementation =====================
+
+	/**
+	 * Check the validity of the dependencies.
+	 */
+	protected void checkContext() {
+
+		synchronized (this) {
+
+			Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Check Context ...");
+
+			// Store the initial state
+			int initialState = m_state;
+
+			// Check the component dependencies
+			if (!validateComponentDependencies()) {
+				// The dependencies are not valid
+				if (initialState == ComponentManager.VALID) {
+					//There is a state change
+					m_state = ComponentManager.INVALID;
+					m_componentManager.check();
+				}
+				// Else do nothing, the component state stay UNRESOLVED
+			}
+			else {
+				// The dependencies are valid
+				if (initialState == ComponentManager.INVALID) {
+					//There is a state change
+					m_state = ComponentManager.VALID;
+					m_componentManager.check();
+				}
+				// Else do nothing, the component state stay VALID
+			}
+
+		}
+	}
+
+	private boolean checkDependency(Dependency dep) {
+        // Check the internal type of dependency
+            String field = dep.getMetadata().getField();
+
+            Element manipulation = m_componentManager.getComponentMetatada().getMetadata().getElements("Manipulation")[0];
+        	String type = null;
+        	for (int i = 0; i < manipulation.getElements("Field").length; i++) {
+        		if (field.equals(manipulation.getElements("Field")[i].getAttribute("name"))) {
+        			type = manipulation.getElements("Field")[i].getAttribute("type");
+        			break;
+        		}
+        	}
+
+            if (type == null) {
+            	Activator.getLogger().log(Level.SEVERE, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] A declared dependency was not found in the class : " + dep.getMetadata().getField());
+            	return false;
+            }
+
+            if (type != null) {
+                if (type.endsWith("[]")) {
+                	// Set the dependency to multiple
+                	dep.getMetadata().setMultiple();
+                	type = type.substring(0, type.length() - 2);
+                	}
+
+                if (dep.getMetadata().getServiceSpecification() == null) { dep.getMetadata().setServiceSpecification(type); }
+
+                if (!dep.getMetadata().getServiceSpecification().equals(type)) {
+                    Activator.getLogger().log(Level.WARNING, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] The field type [" + type + "] and the needed service interface [" + dep.getMetadata().getServiceSpecification() + "] are not the same");
+                    dep.getMetadata().setServiceSpecification(type);
+                }
+            }
+            else {
+                Activator.getLogger().log(Level.WARNING, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] The declared dependency " + dep.getMetadata().getField() + "  does not exist in the code");
+            }
+		return true;
+	}
+
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.ComponentManager, org.apache.felix.ipojo.metadata.Element)
+	 */
+	public void configure(ComponentManager cm, Element componentMetadata) {
+		// Fix the component manager
+		m_componentManager = cm;
+		m_dependencies = new Dependency[0];
+		m_nullableClasses = new Class[0];
+
+		// Create the dependency according to the component metadata
+		Element[] deps = componentMetadata.getElements("Dependency");
+		for (int i = 0; i < deps.length; i++) {
+			// Create the dependency metadata
+			String field = deps[i].getAttribute("field");
+			String serviceSpecification = null;
+			if (deps[i].containsAttribute("interface")) { serviceSpecification = deps[i].getAttribute("interface"); }
+			String filter = "";
+			if (deps[i].containsAttribute("filter")) { filter = deps[i].getAttribute("filter"); }
+			boolean optional = false;
+			if (deps[i].containsAttribute("optional") && deps[i].getAttribute("optional").equals("true")) { optional = true; }
+			DependencyMetadata dm = new DependencyMetadata(field, serviceSpecification, filter, optional);
+
+
+			Dependency dep = new Dependency(this, dm);
+			// Check the dependency :
+			if (checkDependency(dep)) { addDependency(dep); }
+			else { Activator.getLogger().log(Level.SEVERE, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] The dependency on " + dep.getMetadata().getField() + " is not valid"); }
+
+			// Look for dependency callback :
+			for (int j = 0; j < (deps[i].getElements("Callback", "")).length; j++) {
+				String method = deps[i].getElements("Callback", "")[j].getAttribute("method");
+				String type = deps[i].getElements("Callback", "")[j].getAttribute("type");
+				int methodType = 0;
+				if (type.equals("bind")) { methodType = DependencyCallback.BIND; }
+				else { methodType = DependencyCallback.UNBIND; }
+				boolean isStatic = false;
+				if (deps[i].getElements("Callback", "")[j].containsAttribute("isStatic") && deps[i].getElements("Callback", "")[j].getAttribute("isStatic").equals("true")) { isStatic = true; }
+				DependencyCallback dc = new DependencyCallback(dep, method, methodType, isStatic);
+				dep.getMetadata().addDependencyCallback(dc);
+			}
+		}
+
+		if (deps.length > 0) {
+			m_componentManager.register(this);
+
+			// Create the nullable classloader
+			m_classloader = new NullableClassloader(m_componentManager.getContext().getBundle());
+
+		}
+	}
+
+	private void createNullableClass(Dependency dep) {
+		Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Try to load the nullable class for " + dep.getMetadata().getServiceSpecification());
+		// Try to load the nullable object :
+        String[] segment = dep.getMetadata().getServiceSpecification().split("[.]");
+        String className = "org/apache/felix/ipojo/" + segment[segment.length - 1] + "Nullable";
+
+        String resource = dep.getMetadata().getServiceSpecification().replace('.', '/') + ".class";
+        URL url =  m_componentManager.getContext().getBundle().getResource(resource);
+
+            try {
+                byte[] b = NullableObjectWriter.dump(url,  dep.getMetadata().getServiceSpecification());
+
+//                // DEBUG :
+//                try {
+//                    File file = new File("P:\\workspace\\iPOJO\\adapted\\" + className.replace('/', '.') + ".class");
+//                    file.createNewFile();
+//                    FileOutputStream fos = new FileOutputStream(file);
+//                    fos.write(b);
+//                    fos.close();
+//                } catch (Exception e3) {
+//                    System.err.println("Problem to write the adapted class on the file system  : " + e3.getMessage());
+//
+//                }
+
+                addNullableClass(m_classloader.defineClass(className.replace('/', '.'), b, null));
+                Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Nullable class created for " + dep.getMetadata().getServiceSpecification());
+
+            } catch (IOException e1) {
+                Activator.getLogger().log(Level.SEVERE, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Cannot open a stream of an interface to generate the nullable class for " + dep.getMetadata().getServiceSpecification() + " -> " + e1.getMessage());
+            } catch (Exception e2) {
+            	Activator.getLogger().log(Level.SEVERE, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Cannot load the nullable class for  " + dep.getMetadata().getServiceSpecification() + " -> " + e2.getMessage());
+            }
+	}
+
+	/**
+     * Return the nullable class corresponding to the given name.
+	 * @param name the needed type
+	 * @return the class correspondig to the name, or null if the class does not exist.
+	 */
+	protected Class getNullableClass(String name) {
+		for (int i = 0; i < m_nullableClasses.length; i++) {
+			Class c = m_nullableClasses[i];
+			if (c.getName().equals(name)) {
+				return c;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String, java.lang.Object)
+	 */
+	public Object getterCallback(String fieldName, Object value) {
+		for (int i = 0; i < m_dependencies.length; i++) {
+			Dependency dep = m_dependencies[i];
+			if (dep.getMetadata().getField().equals(fieldName)) {
+				// The field name is a dependency, return the get
+				return dep.get();
+			}
+		}
+		// Else return the value
+		return value;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#isValid()
+	 */
+	public boolean isValid() {
+		return (m_state == ComponentManager.VALID);
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String, java.lang.Object)
+	 */
+	public void setterCallback(String fieldName, Object value) {
+	    // Do nothing
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#start()
+	 */
+	public void start() {
+		Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Start the dependency handler");
+
+		// Start the dependencies, for optional dependencies create Nullable class
+		for (int i = 0; i < m_dependencies.length; i++) {
+			Dependency dep = m_dependencies[i];
+			if (dep.getMetadata().isOptional() && !dep.getMetadata().isMultiple()) { createNullableClass(dep); }
+			dep.start();
+		}
+		// Check the state
+		m_state = m_componentManager.getState();
+		checkContext();
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#stateChanged(int)
+	 */
+	public void stateChanged(int state) {
+		// Another handler or the component manager itself change the state
+		if (m_state == ComponentManager.VALID && state == ComponentManager.INVALID) {
+			// The component is stopped => Stop the dependency tracking
+			stop();
+		}
+		m_state = state;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#stop()
+	 */
+	public void stop() {
+		for (int i = 0; i < m_dependencies.length; i++) { m_dependencies[i].stop(); }
+	}
+
+	private boolean validateComponentDependencies() {
+		boolean valide = true;
+        for (int i = 0; i < m_dependencies.length; i++) {
+            Dependency dep = m_dependencies[i];
+            valide = valide & dep.isSatisfied();
+            if (!valide) {
+                Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Component Dependencies are not valid : " + dep.getMetadata().getServiceSpecification());
+                return false;
+            }
+        }
+        Activator.getLogger().log(Level.INFO, "[DependencyHandler on " + m_componentManager.getComponentMetatada().getClassName() + "] Component Dependencies are valid");
+        return valide;
+	}
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,148 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency;
+
+/**
+ * Dependency Metadata.
+ * @author Clement Escoffier
+ */
+public class DependencyMetadata {
+
+	/**
+	 * Service Specification <=> Service contract (or interface in OSGi).
+	 */
+	private String m_serviceSpecification;
+
+	/**
+	 * LDAP filter.
+	 */
+	private String m_filter;
+
+	/**
+	 * is the dependency optional ?
+	 */
+	private boolean m_isOptional;
+
+	/**
+	 * is the dependency multiple ?
+	 */
+	private boolean m_isMultiple = false;
+
+	/**
+	 * List of dependency callbacks attached to this dependency.
+	 */
+	private DependencyCallback[] m_callbacks = new DependencyCallback[0];
+
+	/**
+	 * The field linking the metadata and the component implementation.
+	 */
+	private String m_field;
+
+	// Constructor
+
+	/**
+     * Constructor.
+	 * @param field : the field name
+	 * @param service : the interface name.
+	 * @param filter : the filter of the dependency
+	 * @param isOptional : is the dependency optional
+	 */
+	public DependencyMetadata(String field, String service, String filter, boolean isOptional) {
+		m_field = field;
+		m_serviceSpecification = service;
+		m_isOptional = isOptional;
+		m_filter = filter;
+	}
+
+	/**
+	 * Add a callback to the dependency.
+	 * @param cb : callback to add
+	 */
+	public void addDependencyCallback(DependencyCallback cb) {
+		 for (int i = 0; (m_callbacks != null) && (i < m_callbacks.length); i++) {
+	            if (m_callbacks[i] == cb) { return; }
+	        }
+
+	        if (m_callbacks.length > 0) {
+	        	DependencyCallback[] newCallbacks = new DependencyCallback[m_callbacks.length + 1];
+	            System.arraycopy(m_callbacks, 0, newCallbacks, 0, m_callbacks.length);
+	            newCallbacks[m_callbacks.length] = cb;
+	            m_callbacks = newCallbacks;
+	        }
+	        else {
+	        	m_callbacks = new DependencyCallback[] {cb};
+	        }
+	}
+
+	// Getter
+
+	/**
+	 * @return Returns the m_field.
+	 */
+	public String getField() {
+		return m_field;
+	}
+
+	/**
+	 * @return Returns the m_filter.
+	 */
+	public String getFilter() {
+		return m_filter;
+	}
+
+	/**
+	 * @return Returns the m_isMultiple.
+	 */
+	public boolean isMultiple() {
+		return m_isMultiple;
+	}
+
+	/**
+	 * @return Returns the m_isOptional.
+	 */
+	public boolean isOptional() {
+		return m_isOptional;
+	}
+
+	/**
+	 * @return Returns the m_serviceSpecification.
+	 */
+	public String getServiceSpecification() {
+		return m_serviceSpecification;
+	}
+
+	/**
+	 * return true if the dependency is multiple.
+	 */
+	public void setMultiple() {
+		m_isMultiple = true;
+	}
+
+	/**
+     * Set the service specification.
+	 * @param serviceSpecification : the dependency service specification
+	 */
+	public void setServiceSpecification(String serviceSpecification) {
+		m_serviceSpecification = serviceSpecification;
+	}
+
+	/**
+	 * @return the list of the callbacks
+	 */
+	public DependencyCallback[] getCallbacks() { return m_callbacks; }
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyMetadata.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,103 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency;
+
+import java.io.IOException;
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.Enumeration;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * iPOJO Classloader.
+ * This classloadert is used to load manipulated class.
+ * @author Clement Escoffier
+ */
+public class NullableClassloader extends ClassLoader {
+
+	 /**
+     * The owner bundle.
+     * m_bundle : Bundle
+     */
+    private Bundle  m_bundle;
+
+    /**
+     * Constructor.
+     * @param b : the owner bundle
+     */
+    public NullableClassloader(Bundle b) {
+        m_bundle = b;
+    }
+
+    /**
+     * load the class.
+     * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
+     * @param name : the name of the class
+     * @param resolve : should be the class resolve now ?
+     * @return : the loaded class
+     * @throws ClassNotFoundException : the class to load is not found
+     */
+    protected synchronized Class loadClass(final String name,
+            final boolean resolve) throws ClassNotFoundException {
+
+        Class clazz = null;
+        //Activator.getLogger().log(Level.WARNING, "Bundle " + m_bundle.getBundleId() + " -> Try to load : " + name);
+
+        if (m_bundle != null) { clazz = m_bundle.loadClass(name); }
+
+        return clazz;
+    }
+
+
+    /**
+     * Return the URL of the asked ressource.
+     * @param arg : the name of the resource to find.
+     * @return the URL of the resource.
+     * @see java.lang.ClassLoader#getResource(java.lang.String)
+     */
+    public URL getResource(String arg) {
+        return m_bundle.getResource(arg);
+    }
+
+    /**
+     * .
+     * @param arg : resource to find
+     * @return : the enumeration found
+     * @throws IOException : if the lookup failed.
+     * @see java.lang.ClassLoader#getResources(java.lang.String)
+     */
+    public Enumeration getRessources(String arg) throws IOException {
+        return m_bundle.getResources(arg);
+    }
+
+    /**
+     * The defineClass method for GenClassLoader.
+     * @param name : name of the class
+     * @param b : the byte array of the class
+     * @param domain : the protection domain
+     * @return : the defined class.
+     * @throws Exception : if a problem is detected during the loading
+     */
+    public Class defineClass(String name, byte[] b,
+            ProtectionDomain domain) throws Exception {
+    	Class clazz =  super.defineClass(name, b, 0, b.length, domain);
+    	return clazz;
+    }
+
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableClassloader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignature.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignature.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignature.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignature.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,89 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency.nullable;
+
+/**
+ * Reprensent of method description.
+ * The goal of this class, is to be able to generate a proxy class, or a nullable class from an interface.
+ * @author Clement Escoffier
+ *
+ */
+public class MethodSignature {
+
+    /**
+     * Nmae of the method.
+     */
+    private String m_name;
+
+    /**
+     * Descriptor of the method.
+     */
+    private String m_desc;
+
+    /**
+     * Signature of the method.
+     */
+    private String m_signature;
+
+    /**
+     * Exception thored by the method.
+     */
+    private String[] m_exception;
+
+    /**
+     * MethodSignature constructor.
+     * Describe a method.
+     * @param name : name of the method
+     * @param desc : descriptor of the method
+     * @param sign : signature of the method
+     * @param exc : exception throwed by the method
+     */
+    public MethodSignature(String name, String desc, String sign, String[] exc) {
+        m_name = name;
+        m_desc = desc;
+        m_signature = sign;
+        m_exception = exc;
+    }
+
+    /**
+     * @return the description of the method.
+     */
+    public String getDesc() {
+        return m_desc;
+    }
+
+    /**
+     * @return the String array of exception throwed by the method.
+     */
+    public String[] getException() {
+        return m_exception;
+    }
+
+    /**
+     * @return the name of the method.
+     */
+    public String getName() {
+        return m_name;
+    }
+
+    /**
+     * @return the signature of the method.
+     */
+    public String getSignature() {
+        return m_signature;
+    }
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignature.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignatureVisitor.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignatureVisitor.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignatureVisitor.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignatureVisitor.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,129 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency.nullable;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/** This class implement a class visitor. It store all method signature of
+ * the visited interface. Then it returns these class signatures for the proxy
+ * generation or the nullable class.
+ * Date : 4/9/2005
+ * @author Clement Escoffier
+ */
+public class MethodSignatureVisitor implements ClassVisitor, Opcodes {
+
+    /**
+     * Array of method signature.
+     */
+    private MethodSignature[] m_methods;
+
+
+    /**
+     * Constructor.
+     */
+    public MethodSignatureVisitor() { }
+
+    /**
+     * Visit a method, store the information about the method.
+     * @see org.objectweb.asm.ClassVisitor#visitMethod(int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
+     * @param access : Access modifier
+     * @param name : name of the visited method
+     * @param signature : singature of the visited element (null if not generic)
+     * @param desc : descriptor of the method
+     * @param exceptions : execption clause
+     * @return always null (not code visitor needed)
+     */
+    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+        //Store method signature for each visited method
+        m_methods = addMethod(m_methods, new MethodSignature(name, desc, signature, exceptions));
+        return null;
+    }
+
+    /**
+     * @return the mthod signature array.
+     */
+    public MethodSignature[] getMethods() {
+        return m_methods;
+    }
+
+    /**
+     * Return the new array of Method Signature by adding the given list and the given element.
+     * @param list : the current array
+     * @param method : the element to add
+     * @return the new array
+     */
+    public static MethodSignature[] addMethod(MethodSignature[] list, MethodSignature method) {
+        if (list != null) {
+            MethodSignature[] newList = new MethodSignature[list.length + 1];
+            System.arraycopy(list, 0, newList, 0, list.length);
+            newList[list.length] = method;
+            return newList;
+        }
+        else {
+            list = new MethodSignature[] {method};
+            return list;
+        }
+
+    }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visit(int, int, java.lang.String, java.lang.String, java.lang.String, java.lang.String[])
+     */
+    public void visit(int arg0, int arg1, String arg2, String arg3, String arg4, String[] arg5) { }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visitSource(java.lang.String, java.lang.String)
+     */
+    public void visitSource(String arg0, String arg1) { }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visitOuterClass(java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void visitOuterClass(String arg0, String arg1, String arg2) { }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visitAnnotation(java.lang.String, boolean)
+     */
+    public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) { return null; }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visitAttribute(org.objectweb.asm.Attribute)
+     */
+    public void visitAttribute(Attribute arg0) { }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visitInnerClass(java.lang.String, java.lang.String, java.lang.String, int)
+     */
+    public void visitInnerClass(String arg0, String arg1, String arg2, int arg3) { }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visitField(int, java.lang.String, java.lang.String, java.lang.String, java.lang.Object)
+     */
+    public FieldVisitor visitField(int arg0, String arg1, String arg2, String arg3, Object arg4) { return null; }
+
+    /**
+     * @see org.objectweb.asm.ClassVisitor#visitEnd()
+     */
+    public void visitEnd() { }
+
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/MethodSignatureVisitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,124 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.dependency.nullable;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/** Create the proxy class.
+ * @author clément
+ */
+public class NullableObjectWriter implements Opcodes {
+
+    /** Return the proxy classname for the contract contractname
+     * on the service object soc.
+     * @param url URL of the needed contract
+     * @param contractName String
+     * @return byte[]
+     */
+    public static byte[] dump(URL url,
+            String contractName) {
+
+        ClassReader cr = null;
+        InputStream is = null;
+        byte[] b = null;
+        try {
+            is = url.openStream();
+            cr = new ClassReader(is);
+            MethodSignatureVisitor msv = new MethodSignatureVisitor();
+            cr.accept(msv, true);
+            is.close();
+
+            ClassWriter cw = new ClassWriter(true);
+
+            String[] segment = contractName.split("[.]");
+            String className = "org/apache/felix/ipojo/" + segment[segment.length - 1] + "Nullable";
+
+
+            // Create the class
+            cw.visit(V1_2, ACC_PUBLIC + ACC_SUPER, className, null,
+                    "java/lang/Object", new String[]{contractName.replace('.', '/'), "org/apache/felix/ipojo/Nullable"});
+
+            // Inject a constructor <INIT>()V
+                MethodVisitor cst = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+                cst.visitVarInsn(ALOAD, 0);
+                cst.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+                cst.visitInsn(RETURN);
+                cst.visitMaxs(0, 0);
+                cst.visitEnd();
+
+            // Methods Generation :
+            MethodSignature[] methods = msv.getMethods();
+
+            for (int i = 0; i < methods.length; ++i) {
+                MethodSignature method = methods[i];
+                String desc = method.getDesc();
+                String name = method.getName();
+                String sign = method.getSignature();
+                String[] exc = method.getException();
+
+                MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, name, desc, sign, exc);
+
+                Type returnType = Type.getReturnType(desc);
+                    // TODO : manage the other type primitive
+                    // Primitive type :
+                    switch (returnType.getSort()) {
+                    case Type.BOOLEAN:
+                    case Type.INT:
+                        // Integer or Boolean : return 0 ( false)
+                        mv.visitInsn(ICONST_0);
+                        mv.visitInsn(IRETURN);
+                        break;
+                    case Type.DOUBLE:
+                        // Double : return 0.0
+                        mv.visitInsn(DCONST_0);
+                        mv.visitInsn(DRETURN);
+                        break;
+                    case Type.ARRAY :
+                    case Type.OBJECT :
+                        // Return always null for array and object
+                        mv.visitInsn(ACONST_NULL);
+                        mv.visitInsn(ARETURN);
+                        break;
+                    case Type.VOID :
+                        mv.visitInsn(RETURN);
+                        break;
+                    default :
+                        System.err.println("Type not yet managed : " + returnType);
+                    }
+                mv.visitMaxs(0, 0);
+                mv.visitEnd();
+            }
+
+            // End process
+            cw.visitEnd();
+            b =  cw.toByteArray();
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return b;
+    }
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/NullableObjectWriter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,67 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.lifecycle.callback;
+
+import java.lang.reflect.InvocationTargetException;
+import org.apache.felix.ipojo.Callback;
+
+/**
+ * This class is the implementation of callback on lifecycle transition.
+ * @author Clement Escoffier
+ *
+ */
+public class LifecycleCallback {
+
+
+    /**
+     * Metadata of the callback.
+     */
+    private LifecycleCallbackMetadata m_metadata;
+
+    /**
+     * Callback object.
+     */
+    private Callback m_callback;
+
+    /**
+     * LifecycleCallback constructor.
+     * @param hh : the callback handler calling the callback
+     * @param hm : the callback metadata
+     */
+    public LifecycleCallback(LifecycleCallbackHandler hh, LifecycleCallbackMetadata hm) {
+        m_metadata = hm;
+        m_callback = new Callback(hm.getMethod(), hm.isStatic(), hh.getComponentManager());
+    }
+
+    /**
+     * @return : the metadata of the hook
+     */
+    public LifecycleCallbackMetadata getMetadata() {
+        return m_metadata;
+    }
+
+    /**
+     * Call the hook method when the transition from inital to final state is detected.
+     * @throws NoSuchMethodException : Method is not found in the class
+     * @throws InvocationTargetException : The method is not static
+     * @throws IllegalAccessException : The method can not be invoked
+     */
+    protected void call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	m_callback.call();
+    }
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,160 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.lifecycle.callback;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.ComponentManager;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Lifecycle callback handler.
+ * @author Clement Escoffier
+ */
+public class LifecycleCallbackHandler implements Handler {
+
+	/**
+	 * The list of the callback of the component.
+	 */
+	private LifecycleCallback[] m_callbacks = new LifecycleCallback[0];
+
+	/**
+	 * State of the component manager (unresolved at the beginning).
+	 */
+	private int m_state = ComponentManager.INVALID;
+
+	/**
+	 * The component manager.
+	 */
+	private ComponentManager m_componentManager;
+
+	 /**
+     * Add the given Hook to the hook list.
+     * @param hk : the element to add
+     */
+    private void addCallback(LifecycleCallback hk) {
+        for (int i = 0; (m_callbacks != null) && (i < m_callbacks.length); i++) {
+            if (m_callbacks[i] == hk) { return; }
+        }
+
+        if (m_callbacks.length > 0) {
+            LifecycleCallback[] newHk = new LifecycleCallback[m_callbacks.length + 1];
+            System.arraycopy(m_callbacks, 0, newHk, 0, m_callbacks.length);
+            newHk[m_callbacks.length] = hk;
+            m_callbacks = newHk;
+        }
+        else {
+        	m_callbacks = new LifecycleCallback[] {hk};
+        }
+
+    }
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.ComponentManager, org.apache.felix.ipojo.metadata.Element)
+	 */
+	public void configure(ComponentManager cm, Element metadata) {
+		m_componentManager = cm;
+		m_callbacks = new LifecycleCallback[0];
+
+		Element[] hooksMetadata = metadata.getElements("callback");
+		for (int i = 0; i < hooksMetadata.length; i++) {
+			// Create an HookMetadata object
+			String initialState = hooksMetadata[i].getAttribute("initial");
+			String finalState = hooksMetadata[i].getAttribute("final");
+			String method = hooksMetadata[i].getAttribute("method");
+			boolean isStatic = false;
+			if (hooksMetadata[i].containsAttribute("isStatic") && hooksMetadata[i].getAttribute("isStatic").equals("true")) { isStatic = true; }
+
+			LifecycleCallbackMetadata hm = new LifecycleCallbackMetadata(initialState, finalState, method, isStatic);
+
+			LifecycleCallback hk = new LifecycleCallback(this, hm);
+			addCallback(hk);
+		}
+		if (m_callbacks.length > 0) { m_componentManager.register(this); }
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#stop()
+	 */
+	public void stop() {
+		m_state = ComponentManager.INVALID;
+	}
+
+	/**
+	 * @see org.apache.felix.ipojo.Handler#start()
+	 */
+	public void start() {
+		Activator.getLogger().log(Level.INFO, "[" + m_componentManager.getComponentMetatada().getClassName() + "] Start the life cycle callback handler");
+	}
+
+	/**
+	 * Do nothing.
+	 * @see org.apache.felix.ipojo.Handler#setterCallback(java.lang.String, java.lang.Object)
+	 */
+	public void setterCallback(String fieldName, Object value) {
+		// Do nothing
+	}
+
+	/**
+	 * Do nothing, return the initial value.
+	 * @see org.apache.felix.ipojo.Handler#getterCallback(java.lang.String, java.lang.Object)
+	 */
+	public Object getterCallback(String fieldName, Object value) {
+		return value;
+	}
+
+	/**
+	 * Return true.
+	 * @see org.apache.felix.ipojo.Handler#isValid()
+	 */
+	public boolean isValid() {
+		return true;
+	}
+
+	/**
+	 * @return the component manager
+	 */
+	protected ComponentManager getComponentManager() { return m_componentManager; }
+
+	/**
+	 * When the state change call the associated hooks.
+	 * @see org.apache.felix.ipojo.Handler#stateChanged(int)
+	 */
+	public void stateChanged(int state) {
+		Activator.getLogger().log(Level.INFO, "[" + m_componentManager.getComponentMetatada().getClassName() + "] State changed in callback handler, check " + m_callbacks.length + " callbacks. Transition : " + m_state + " -> " + state);
+		for (int i = 0; i < m_callbacks.length; i++) {
+			if (m_callbacks[i].getMetadata().getInitialState() == m_state && m_callbacks[i].getMetadata().getFinalState() == state) {
+				try {
+					Activator.getLogger().log(Level.INFO, "[" + m_componentManager.getComponentMetatada().getClassName() + "] Call the callback : " + m_callbacks[i].getMetadata().getMethod());
+					m_callbacks[i].call();
+				} catch (NoSuchMethodException e) {
+					Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The callback method " + m_callbacks[i].getMetadata().getMethod() + " is not found : " + e.getMessage());
+				} catch (IllegalAccessException e) {
+					Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The callback method " + m_callbacks[i].getMetadata().getMethod() + " is not accessible : " + e.getMessage());
+				} catch (InvocationTargetException e) {
+					Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The callback method " + m_callbacks[i].getMetadata().getMethod() + " has throws an exception : " + e.getMessage() + " -> " + e.getCause());
+				}
+			}
+		}
+		// Update to internal state
+		m_state = state;
+	}
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackMetadata.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackMetadata.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackMetadata.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackMetadata.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,96 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.lifecycle.callback;
+
+import org.apache.felix.ipojo.ComponentManager;
+
+/**
+ * Lifecycle callback metadata.
+ * @author Clement Escoffier
+ */
+public class LifecycleCallbackMetadata {
+
+	/**
+	 * Initial state of the transition.
+	 */
+	private int m_initialState;
+
+	/**
+	 * Final state of the transition.
+	 */
+	private int m_finalState;
+
+	/**
+	 * Method to call.
+	 */
+	private String m_method;
+
+	/**
+	 * is the method a static method ?
+	 */
+	private boolean m_isStatic;
+
+	// Constructor
+
+	/**
+     * Constructor.
+	 * @param initialState : initial state
+	 * @param finalState : final state
+	 * @param method : method name
+	 * @param isStatic : is the method a static method ?
+	 */
+	public LifecycleCallbackMetadata(String initialState, String finalState, String method, boolean isStatic) {
+		if (initialState.equals("VALID")) { m_initialState = ComponentManager.VALID; }
+		if (initialState.equals("INVALID")) { m_initialState = ComponentManager.INVALID; }
+		if (finalState.equals("VALID")) { m_finalState = ComponentManager.VALID; }
+		if (finalState.equals("INVALID")) { m_finalState = ComponentManager.INVALID; }
+
+		m_method = method;
+		m_isStatic = isStatic;
+	}
+
+	// Getters
+
+	/**
+	 * @return Returns the m_finalState.
+	 */
+	public int getFinalState() {
+		return m_finalState;
+	}
+
+	/**
+	 * @return Returns the m_initialState.
+	 */
+	public int getInitialState() {
+		return m_initialState;
+	}
+
+	/**
+	 * @return Returns the m_isStatic.
+	 */
+	public boolean isStatic() {
+		return m_isStatic;
+	}
+
+	/**
+	 * @return Returns the m_method.
+	 */
+	public String getMethod() {
+		return m_method;
+	}
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackMetadata.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/Property.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/Property.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/Property.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/Property.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,177 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.providedService;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.logging.Level;
+
+import org.apache.felix.ipojo.Activator;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Represent a property i.e. a set : [name, type, value].
+ * A property can be attached to a field.
+ * The value of the property is thefield value.
+ * When the value change, the published value change too.
+ * Date : 5 févr. 2006
+ * @author clément
+ */
+public class Property {
+
+    /**
+     * A property is link with a service.
+     * This field represent this provided service.
+     * m_providedService : ProvidedService
+     */
+    private ProvidedService m_providedService;
+
+    /**
+     * Value of the property (before we know the type).
+     */
+    private Object m_value;
+
+    /**
+     * Metadata of the property.
+     */
+    private PropertyMetadata m_metadata;
+
+    /**
+     * Property constructor.
+     * @param ps : the provided service
+     * @param pm : metadata of the property
+     */
+    public Property(ProvidedService ps, PropertyMetadata pm) {
+    	m_providedService = ps;
+    	m_metadata = pm;
+
+    	// Fix the type of the property if null
+    	if (pm.getType() == null) {
+    		// If the type is not found, it is a dynamic property
+    		Element manipulation = m_providedService.getComponentManager().getComponentMetatada().getMetadata().getElements("Manipulation")[0];
+        	String type = null;
+        	String field = m_metadata.getField();
+        	for (int i = 0; i < manipulation.getElements("Field").length; i++) {
+        		if (field.equals(manipulation.getElements("Field")[i].getAttribute("name"))) {
+        			type = manipulation.getElements("Field")[i].getAttribute("type");
+        			break;
+        		}
+        	}
+
+    		pm.setType(type);
+    	}
+
+    	if (pm.getValue() != null) { setValue(pm.getValue()); }
+    }
+
+    /**
+     * @return the Object value of the property
+     */
+    protected Object get() {
+        if (m_value == null) {
+            Activator.getLogger().log(Level.INFO, "[" + m_providedService.getComponentManager().getComponentMetatada().getClassName() + "] A property " + m_metadata.getName() + " can not be returned : no value assigned");
+        }
+        return m_value;
+    }
+
+
+    /**
+     * @return the property metadata.
+     */
+    public PropertyMetadata getMetadata() {
+    	return m_metadata;
+    }
+
+    /**
+     * This method is automaticaly called when the value of the property is changed.
+     * Set the value of a property.
+     * @param s : the new value of the property (in String)
+     */
+    protected void set(String s) {
+        setValue(s);
+        m_providedService.update();
+    }
+
+    /**
+     * This method is called when the value of the property is changed.
+     * Set the value of a property.
+     * @param o : the new value of the property (object)
+     */
+    protected void set(Object o) {
+        m_value = o;
+        m_providedService.update();
+    }
+
+    /**
+     * Set the provided service of this property.
+     * @param ps : the provided service to attached.
+     */
+    void setProvidedService(ProvidedService ps) {
+        m_providedService = ps;
+    }
+
+    /**
+     * Set the value of the property.
+     * @param value : value of the property (String)
+     */
+    private void setValue(String value) {
+    	String type = m_metadata.getType();
+
+    	Activator.getLogger().log(Level.INFO, "[" + m_providedService.getComponentManager().getComponentMetatada().getClassName() + "] Set the value of the property " + m_metadata.getName() + " [" + m_metadata.getType() + "] " + " with the value : " + value);
+
+        if (type.equals("string") || type.equals("String")) { m_value = new String(value); return; }
+        if (type.equals("boolean")) { m_value = new Boolean(value); return; }
+        if (type.equals("byte")) { m_value = new Byte(value); return; }
+        if (type.equals("short")) { m_value = new Short(value); return; }
+        if (type.equals("int")) { m_value = new Integer(value); return; }
+        if (type.equals("long")) { m_value = new Long(value); return; }
+        if (type.equals("float")) { m_value = new Float(value); return; }
+        if (type.equals("double")) { m_value = new Double(value); return; }
+
+        // Else it is a neither a primitive type neither a String -> create the object by calling a constructor with a string in argument.
+        try {
+            Class c = m_providedService.getComponentManager().getContext().getBundle().loadClass(type);
+            //Class string = m_providedService.getComponentManager().getContext().getBundle().loadClass("java.lang.String");
+            Constructor cst = c.getConstructor(new Class[] {String.class});
+            m_value = cst.newInstance(new Object[] {value});
+        } catch (ClassNotFoundException e) {
+            System.err.println("Class not found exception in setValue on " + type);
+            e.printStackTrace();
+        } catch (SecurityException e) {
+            e.printStackTrace();
+        } catch (NoSuchMethodException e) {
+            System.err.println("Constructor not found exeption in setValue on " + type);
+            e.printStackTrace();
+        } catch (IllegalArgumentException e) {
+            System.err.println("Argument problem to call the constructor of the type " + type);
+            e.printStackTrace();
+        } catch (InstantiationException e) {
+            System.err.println("Instantiation problem  " + type);
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        } catch (InvocationTargetException e) {
+            System.err.println("Invocation problem " + type);
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * @return the value of the property.
+     */
+    public Object getValue() { return m_value; }
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/Property.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/PropertyMetadata.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/PropertyMetadata.java?rev=414287&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/PropertyMetadata.java (added)
+++ incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/PropertyMetadata.java Wed Jun 14 08:22:03 2006
@@ -0,0 +1,93 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.ipojo.handlers.providedService;
+
+/**
+ * Property metadata : either static either dynamic.
+ * @author Clement Escoffier
+ */
+public class PropertyMetadata {
+
+	/**
+	 * Field of the property.
+	 */
+	private String m_field;
+
+	/**
+	 * Name of the property.
+	 */
+	private String m_name;
+
+	/**
+	 * Type of the property.
+	 */
+	private String m_type;
+
+	/**
+	 * String value of the property (initial value).
+	 */
+	private String m_value;
+
+	//Constructor
+
+	/**
+     * Constructor.
+	 * @param name : name of the property
+	 * @param field : field of the property
+	 * @param type : type of the property
+	 * @param value : initial value of the property
+	 */
+	public PropertyMetadata(String name, String field, String type, String value) {
+		m_name = name;
+		m_field = field;
+		m_type = type;
+		m_value = value;
+
+		// Dynamic property case :
+		if (m_field != null) {
+			if (m_name == null) { m_name = m_field; }
+		}
+	}
+
+	/**
+	 * @return the field name.
+	 */
+	public String getField() { return m_field; };
+
+	/**
+	 * @return the property name.
+	 */
+	public String getName() { return m_name; };
+
+	/**
+	 * @return the type of the property.
+	 */
+	public String getType() { return m_type; };
+
+	/**
+	 * @return the initial value.
+	 */
+	public String getValue() { return m_value; }
+
+	/**
+     * Set the type of the property (dynamic property only).
+	 * @param type : the type of the property.
+	 */
+	public void setType(String type) { m_type = type; }
+
+
+}

Propchange: incubator/felix/trunk/org.apache.felix.ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedService/PropertyMetadata.java
------------------------------------------------------------------------------
    svn:eol-style = native