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 2007/12/02 14:40:57 UTC

svn commit: r600287 - in /felix/trunk/ipojo: core/src/main/java/org/apache/felix/ipojo/ core/src/main/java/org/apache/felix/ipojo/architecture/ core/src/main/java/org/apache/felix/ipojo/composite/service/provides/ core/src/main/java/org/apache/felix/ip...

Author: clement
Date: Sun Dec  2 05:40:55 2007
New Revision: 600287

URL: http://svn.apache.org/viewvc?rev=600287&view=rev
Log:
Fix the issue #Felix-427.
Nullable object are now created with a dynamic proxy (instead of a bytecode generation).
Avoid useless object creation in the instance manager.
Change the composition creation to use Class introspection instead of Class visit (class is already loaded to compute service dependencies).

Added:
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java
Removed:
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/nullable/
Modified:
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
    felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java?rev=600287&r1=600286&r2=600287&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java Sun Dec  2 05:40:55 2007
@@ -119,7 +119,9 @@
 
         setState(INVALID);
         
-        m_handler.stop();
+        if (m_handler != null) {
+            m_handler.stop();
+        }
         
         // Stop all the handlers
         for (int i = m_handlers.length - 1; i > -1; i--) {
@@ -128,8 +130,10 @@
         }
 
         m_state = STOPPED;
-        for (int i = 0; i < m_instanceListeners.size(); i++) {
-            ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, STOPPED);
+        if (m_instanceListeners != null) {
+            for (int i = 0; i < m_instanceListeners.size(); i++) {
+                ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, STOPPED);
+            }
         }
     }
     

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=600287&r1=600286&r2=600287&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 Sun Dec  2 05:40:55 2007
@@ -55,7 +55,7 @@
     /**
      * Handler list.
      */
-    protected HandlerManager[] m_handlers = new HandlerManager[0];
+    protected HandlerManager[] m_handlers = null;
 
     /**
      * Component state (STOPPED at the beginning).
@@ -65,7 +65,7 @@
     /**
      * Instance State Listener List.
      */
-    protected List m_instanceListeners = new ArrayList();
+    protected List m_instanceListeners = null;
     
     /**
      * Parent factory (ComponentFactory).
@@ -85,7 +85,7 @@
     /**
      * Map [method identifier, handler list] storing handlers interested by the method.
      */
-    private Map m_methodRegistration = new HashMap();
+    private Map m_methodRegistration;
 
     /**
      * Manipulated class.
@@ -95,7 +95,7 @@
     /**
      * Instances of the components.
      */
-    private Object[] m_pojoObjects = new Object[0];
+    private Object[] m_pojoObjects = null;
 
    /**
     * Is the component instance state changing?
@@ -154,11 +154,13 @@
         int componentState = getState();
         InstanceDescription instanceDescription = new InstanceDescription(m_name, componentState, getContext().getBundle().getBundleId(), m_factory.getComponentDescription());
 
-        String[] objects = new String[getPojoObjects().length];
-        for (int i = 0; i < getPojoObjects().length; i++) {
-            objects[i] = "" + getPojoObjects()[i];
+        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();
+            }
+            instanceDescription.setCreatedObjects(objects);
         }
-        instanceDescription.setCreatedObjects(objects);
 
         Handler[] handlers = getRegistredHandlers();
         for (int i = 0; i < handlers.length; i++) {
@@ -234,11 +236,13 @@
             m_handlers[i].stop();
         }
         
-        m_pojoObjects = new Object[0];
+        m_pojoObjects = null;
 
         m_state = STOPPED;
-        for (int i = 0; i < m_instanceListeners.size(); i++) {
-            ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, STOPPED);
+        if (m_instanceListeners != null) {
+            for (int i = 0; i < m_instanceListeners.size(); i++) {
+                ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, STOPPED);
+            }
         }
     }
     
@@ -253,8 +257,11 @@
         
         m_state = DISPOSED;
         
-        for (int i = 0; i < m_instanceListeners.size(); i++) {
-            ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, 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;
         }
         
         m_factory.disposed(this);
@@ -269,7 +276,6 @@
         m_methodRegistration = new HashMap();
         m_clazz = null;
         m_inTransition = false;
-        m_instanceListeners.clear();
     }
     
     /**
@@ -280,9 +286,11 @@
         if (m_state > STOPPED) {
             stop();
         }
-        
-        for (int i = 0; i < m_instanceListeners.size(); i++) {
-            ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, 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;
         }
 
         // Cleaning
@@ -298,7 +306,7 @@
         m_methodRegistration = new HashMap();
         m_clazz = null;
         m_inTransition = false;
-        m_instanceListeners.clear();
+        
     }
     
     /**
@@ -331,8 +339,10 @@
                 }
             }
             
-            for (int i = 0; i < m_instanceListeners.size(); i++) {
-                ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, state);
+            if (m_instanceListeners != null) {
+                for (int i = 0; i < m_instanceListeners.size(); i++) {
+                    ((InstanceStateListener) m_instanceListeners.get(i)).stateChanged(this, state);
+                }
             }
         }
         
@@ -367,6 +377,9 @@
      * @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();
+        }
         synchronized (m_instanceListeners) {
             m_instanceListeners.add(listener);
         }
@@ -378,8 +391,13 @@
      * @see org.apache.felix.ipojo.ComponentInstance#removeInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
      */
     public void removeInstanceStateListener(InstanceStateListener listener) {
-        synchronized (m_instanceListeners) {
-            m_instanceListeners.remove(listener);
+        if (m_instanceListeners != null) {
+            synchronized (m_instanceListeners) {
+                m_instanceListeners.remove(listener);
+                if (m_instanceListeners.size() == 0) {
+                    m_instanceListeners = null;
+                }
+            }
         }
     }
 
@@ -410,13 +428,7 @@
      * @param o : the instance to add
      */
     private synchronized void addInstance(Object o) {
-        for (int i = 0; (m_pojoObjects != null) && (i < m_pojoObjects.length); i++) {
-            if (m_pojoObjects[i] == o) {
-                return;
-            }
-        }
-
-        if (m_pojoObjects.length > 0) {
+        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;
@@ -451,7 +463,7 @@
 
         if (idx >= 0) {
             if ((m_pojoObjects.length - 1) == 0) {
-                m_pojoObjects = new Object[0];
+                m_pojoObjects = null;
             } else {
                 Object[] newInstances = new Object[m_pojoObjects.length - 1];
                 System.arraycopy(m_pojoObjects, 0, newInstances, 0, idx);
@@ -531,7 +543,7 @@
      * @return the instance of the component instance to use for singleton component
      */
     public synchronized Object getPojoObject() {
-        if (m_pojoObjects.length == 0) {
+        if (m_pojoObjects == null) {
             createPojoObject();
         }
         return m_pojoObjects[0];
@@ -574,97 +586,27 @@
             }
         }
         for (int i = 0; methods != null && i < methods.length; i++) {
-            if (m_methodRegistration.get(methods[i].getMethodIdentifier()) == null) {
+            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());
-                for (int j = 0; j < list.length; j++) {
-                    if (list[j] == h) {
-                        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);
-            }
-        }
-        
-    }
-
-    /**
-     * Unregister an handler for the field list. The handler will not be
-     * notified of field access but is always register on the instance manager.
-     * 
-     * @param h : the handler to unregister.
-     * @param fields : the field metadata list
-     * @param methods : the method metadata list
-     */
-    public void unregister(PrimitiveHandler h, FieldMetadata[] fields, MethodMetadata[] methods) {
-        for (int i = 0; i < fields.length; i++) {
-            if (m_fieldRegistration.get(fields[i].getFieldName()) == null) {
-                break;
-            } else {
-                PrimitiveHandler[] list = (PrimitiveHandler[]) m_fieldRegistration.get(fields[i].getFieldName());
-                int idx = -1;
-                for (int j = 0; j < list.length; j++) {
-                    if (list[j] == h) {
-                        idx = j;
-                        break;
-                    }
-                }
-
-                if (idx >= 0) {
-                    if ((list.length - 1) == 0) {
-                        list = new PrimitiveHandler[0];
-                    } else {
-                        PrimitiveHandler[] newList = new PrimitiveHandler[list.length - 1];
-                        System.arraycopy(list, 0, newList, 0, idx);
-                        if (idx < newList.length) {
-                            System.arraycopy(list, idx + 1, newList, idx, newList.length - idx);
-                        }
-                        list = newList;
-                    }
-                    m_fieldRegistration.put(fields[i].getFieldName(), list);
-                }
-            }
-        }
-        for (int i = 0; i < methods.length; i++) {
-            if (m_methodRegistration.get(methods[i].getMethodIdentifier()) == null) {
-                break;
-            } else {
+            } else { 
                 PrimitiveHandler[] list = (PrimitiveHandler[]) m_methodRegistration.get(methods[i].getMethodIdentifier());
-                int idx = -1;
-                for (int j = 0; j < list.length; j++) {
-                    if (list[j] == h) {
-                        idx = j;
-                        break;
-                    }
-                }
-
-                if (idx >= 0) {
-                    if ((list.length - 1) == 0) {
-                        list = new PrimitiveHandler[0];
-                    } else {
-                        PrimitiveHandler[] newList = new PrimitiveHandler[list.length - 1];
-                        System.arraycopy(list, 0, newList, 0, idx);
-                        if (idx < newList.length) {
-                            System.arraycopy(list, idx + 1, newList, idx, newList.length - idx);
+                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;
                         }
-                        list = newList;
                     }
-                    m_methodRegistration.put(methods[i].getMethodIdentifier(), list);
+                    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);
                 }
             }
         }
-    }
-    
-    public Set getRegistredFields() {
-        return m_fieldRegistration.keySet();
-    }
-    
-    public Set getRegistredMethods() {
-        return m_methodRegistration.keySet();
+        
     }
 
     /**
@@ -829,5 +771,31 @@
             setState(VALID);
             return;
         }        
+    }
+    
+    /**
+     * 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 {
+            return null;
+        }
+    }
+    
+    /**
+     * 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 {
+            return null;
+        }
     }
 }

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=600287&r1=600286&r2=600287&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 Sun Dec  2 05:40:55 2007
@@ -149,7 +149,7 @@
     public void addInstance(InstanceDescription inst) {
         // Verify that the dependency description is not already in the array.
         for (int i = 0; i < m_containedInstances.length; i++) {
-            if (m_containedInstances[i] == inst) {
+            if (m_containedInstances[i].getName().equals(inst.getName())) {
                 return; // NOTHING TO DO, the description is already in the array
             }
         }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java?rev=600287&r1=600286&r2=600287&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java Sun Dec  2 05:40:55 2007
@@ -19,7 +19,6 @@
 package org.apache.felix.ipojo.composite.service.provides;
 
 import java.io.IOException;
-import java.net.URL;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -166,7 +165,7 @@
 
     /**
      * Build the delegation mapping.
-     * @throws CompositionException : occurs when the mapping cannot be infers correctly
+     * @throws CompositionException : occurs when the mapping cannot be inferred correctly
      */
     protected void buildMapping() throws CompositionException {
         buildAvailableMappingList();
@@ -214,14 +213,14 @@
                         field.setUseful(true);
                         method.setDelegation(field);
                         // Test optional
-                        if (field.isOptional() && !method.getExceptions().contains("java/lang/UnsupportedOperationException")) {
-                            m_handler.log(Logger.WARNING, "The method " + method.getMethodName() + " could not be provided correctly : the specification " + field.getSpecification().getName() + " is optional");
+                        if (field.isOptional() && !method.throwsUnsupportedOperationException()) {
+                            m_handler.log(Logger.WARNING, "The method " + method.getMethod().getName() + " could not be provided correctly : the specification " + field.getSpecification().getName() + " is optional");
                         }
                     }
                 }
             }
             if (!found) {
-                throw new CompositionException("Inconsistent composition - the method " + method.getMethodName() + " could not be delegated");
+                throw new CompositionException("Inconsistent composition - the method " + method.getMethod() + " could not be delegated");
             }
         }
     }
@@ -231,9 +230,14 @@
      * @return the byte[] of the POJO.
      */
     protected byte[] buildPOJO() {
-        String resource = m_specification.getName().replace('.', '/') + ".class";
-        URL url = getBundleContext().getBundle().getResource(resource);
-        byte[] pojo = POJOWriter.dump(url, m_specification.getName(), m_name, getFieldList(), getMethodList());
+        Class clazz = null;
+        try {
+            clazz = getBundleContext().getBundle().loadClass(m_specification.getName());
+        } catch (ClassNotFoundException e1) {
+            //TODO
+            e1.printStackTrace();
+        }
+        byte[] pojo = POJOWriter.dump(clazz, m_name, getFieldList(), getMethodList());
         Manipulator m = new Manipulator();
         try {
             byte[] ff = m.manipulate(pojo);
@@ -242,7 +246,7 @@
         } catch (IOException e) {
             e.printStackTrace();
         }
-        return new byte[0];
+        return null;
     }
 
     /**
@@ -257,7 +261,7 @@
         elem.addAttribute(className);
         elem.addAttribute(factory);
         
-        // Add architcture for debug
+        // Add architecture for debug
         elem.addAttribute(new Attribute("architecture", "true"));
 
         // Provides

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java?rev=600287&r1=600286&r2=600287&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java Sun Dec  2 05:40:55 2007
@@ -18,10 +18,7 @@
  */
 package org.apache.felix.ipojo.composite.service.provides;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.felix.ipojo.handlers.dependency.nullable.MethodSignature;
+import java.lang.reflect.Method;
 
 /**
  * Information on Method for the composition.
@@ -40,24 +37,9 @@
     public static final int ALL_POLICY = 2;
 
     /**
-     * Method Name.
-     */
-    private String m_methodName;
-
-    /**
-     * Internal Descriptor.
-     */
-    private String m_descriptor;
-
-    /**
-     * List of arguments. 
-     */
-    private List/* <String> */m_arguments = new ArrayList/* <String> */();
-
-    /**
-     * List of exceptions.
+     * Method Object.
      */
-    private List/* <String> */m_exceptions = new ArrayList/* <String> */();
+    private Method m_method;
     
     /**
      * Delegation field.
@@ -71,40 +53,14 @@
 
     /**
      * Constructor.
-     * @param name : name of the method.
-     * @param desc : description of the method.
+     * @param method : method object.
      */
-    public MethodMetadata(String name, String desc) {
-        m_methodName = name;
-        m_descriptor = desc;
-    }
-
-    /**
-     * Add an argument.
-     * @param type : type of the argument.
-     */
-    public void addArgument(String type) {
-        m_arguments.add(type);
-    }
-
-    /**
-     * Add an exception.
-     * @param exception : name of the exception.
-     */
-    public void addException(String exception) {
-        m_exceptions.add(exception);
-    }
-
-    public List/* <String> */getArguments() {
-        return m_arguments;
+    public MethodMetadata(Method method) {
+        m_method = method;
     }
 
-    public List/* <String> */getExceptions() {
-        return m_exceptions;
-    }
-
-    public String getMethodName() {
-        return m_methodName;
+    public Method getMethod() {
+        return m_method;
     }
 
     public void setDelegation(FieldMetadata dm) {
@@ -121,34 +77,26 @@
      * @return true if the two method are equals
      */
     public boolean equals(MethodMetadata mm) {
-        // Test if the name are the same, #args and #exception are the same.
-        if (!mm.getMethodName().equals(m_methodName) || mm.getArguments().size() != m_arguments.size()) {
-            return false;
-        }
-
-        for (int i = 0; i < m_arguments.size(); i++) {
-            if (!m_arguments.get(i).equals(mm.getArguments().get(i))) {
-                return false;
-            }
-        }
-
-        return true;
+        Method met = mm.getMethod();
+        return equals(met);
     }
 
     /**
-     * Equals method for Method Signature.
-     * @param ms : the method signature to compare.
+     * Equals method for Method object.
+     * @param met : the method object to compare.
      * @return true if the given method signature is equals to the current method metadata.
      */
-    public boolean equals(MethodSignature ms) {
-        // the method is equals to the method signature if the name and the desc are similar.
-        if (!m_methodName.equals(ms.getName())) {
+    public boolean equals(Method met) {
+        if (! met.getName().equals(m_method.getName()) || met.getParameterTypes().length != m_method.getParameterTypes().length) {
             return false;
         }
-        if (!m_descriptor.equals(ms.getDesc())) {
-            return false;
+
+        for (int i = 0; i < m_method.getParameterTypes().length; i++) {
+            if (!m_method.getParameterTypes()[i].getName().equals(met.getParameterTypes()[i].getName())) {
+                return false;
+            }
         }
-        
+
         return true;
     }
 
@@ -163,6 +111,17 @@
         m_policy = ALL_POLICY;
     }
     
-    public String getDescription() { return m_descriptor; }
+    /**
+     * Check if the method can throw UnsupportedOperationException.
+     * @return true if the method has declared the UnsupportedOperationException.
+     */
+    boolean throwsUnsupportedOperationException() {
+        for (int i = 0; i < m_method.getExceptionTypes().length; i++) {
+            if (m_method.getExceptionTypes()[i].getName().equals(UnsupportedOperationException.class.getName())) {
+                return true;
+            }
+        }
+        return false;
+    }
 
 }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java?rev=600287&r1=600286&r2=600287&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java Sun Dec  2 05:40:55 2007
@@ -18,14 +18,9 @@
  */
 package org.apache.felix.ipojo.composite.service.provides;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
+import java.lang.reflect.Method;
 import java.util.List;
 
-import org.apache.felix.ipojo.handlers.dependency.nullable.MethodSignature;
-import org.apache.felix.ipojo.handlers.dependency.nullable.MethodSignatureVisitor;
-import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassWriter;
 import org.objectweb.asm.Label;
 import org.objectweb.asm.MethodVisitor;
@@ -76,72 +71,53 @@
 
     /**
      * Return the proxy 'classname' for the contract 'contractname' by delegating on available service.
-     * @param url URL of the needed contract
-     * @param contractName : The interface to implement
+     * @param clazz : Specification class
      * @param className : The class name to create
      * @param fields : the list of fields on which delegate
      * @param methods : the list of method on which delegate
      * @return byte[] : the build class
      */
-    public static byte[] dump(URL url, String contractName, String className, List fields, List methods) {
+    public static byte[] dump(Class clazz, String className, List fields, List methods) {
+        Method[] itfmethods = clazz.getMethods();
 
-        ClassReader cr = null;
-        InputStream is = null;
-        byte[] b = null;
-        try {
-            is = url.openStream();
-            cr = new ClassReader(is);
-            MethodSignatureVisitor msv = new MethodSignatureVisitor();
-            cr.accept(msv, ClassReader.SKIP_FRAMES);
-            is.close();
-
-            MethodSignature[] methodsSign = msv.getMethods();
-
-            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
-
-            // Create the class
-            className = className.replace('.', '/');
-            createClass(cw, className, contractName);
-
-            // Inject fields inside the POJO
-            injectFields(cw, fields);
-
-            // 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();
-
-            for (int i = 0; i < methodsSign.length; ++i) {
-                MethodSignature method = methodsSign[i];
-
-                // Get the field for this method
-                // 1) find the MethodMetadata
-                FieldMetadata delegator = null; // field to delegate
-                MethodMetadata methodDelegator = null; // field to delegate
-                for (int j = 0; j < methods.size(); j++) {
-                    MethodMetadata methodMeta = (MethodMetadata) methods.get(j);
-                    if (methodMeta.equals(method)) {
-                        delegator = methodMeta.getDelegation();
-                        methodDelegator = methodMeta;
-                    }
+        // Create the class
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+        className = className.replace('.', '/');
+        createClass(cw, className, clazz.getName());
+
+        // Inject fields inside the POJO
+        injectFields(cw, fields);
+
+        // 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();
+
+        for (int i = 0; i < itfmethods.length; ++i) {
+            Method method = itfmethods[i];
+
+            // Get the field for this method
+            // 1) find the MethodMetadata
+            FieldMetadata delegator = null; // field to delegate
+            MethodMetadata methodDelegator = null; // field to delegate
+            for (int j = 0; j < methods.size(); j++) {
+                MethodMetadata methodMeta = (MethodMetadata) methods.get(j);
+                if (methodMeta.equals(method)) {
+                    delegator = methodMeta.getDelegation();
+                    methodDelegator = methodMeta;
                 }
-
-                generateOneMethod(cw, className, methodDelegator, method, delegator);
-
             }
 
-            // End process
-            cw.visitEnd();
-            b = cw.toByteArray();
+            generateOneMethod(cw, className, methodDelegator, method, delegator);
 
-        } catch (IOException e) {
-            e.printStackTrace();
         }
 
-        return b;
+        // End process
+        cw.visitEnd();
+        return cw.toByteArray();
     }
 
     /**
@@ -152,13 +128,15 @@
      * @param sign : method signature to generate
      * @param delegator : the field on which delegate
      */
-    private static void generateOneMethod(ClassWriter cw, String className, MethodMetadata method, MethodSignature sign, FieldMetadata delegator) {
-        String desc = sign.getDesc();
+    private static void generateOneMethod(ClassWriter cw, String className, MethodMetadata method, Method sign, FieldMetadata delegator) {
+        String desc = Type.getMethodDescriptor(sign);
         String name = sign.getName();
-        String signa = sign.getSignature();
-        String[] exc = sign.getException();
+        String[] exc = new String[sign.getExceptionTypes().length];
+        for (int i = 0; i < sign.getExceptionTypes().length; i++) {
+            exc[i] = Type.getType(sign.getExceptionTypes()[i]).getInternalName();
+        }
 
-        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, name, desc, signa, exc);
+        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, name, desc, null, exc);
 
         if (delegator.isOptional()) {
             if (!delegator.isAggregate()) {

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java?rev=600287&r1=600286&r2=600287&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java Sun Dec  2 05:40:55 2007
@@ -18,18 +18,11 @@
  */
 package org.apache.felix.ipojo.composite.service.provides;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.lang.reflect.Method;
-import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.felix.ipojo.handlers.dependency.nullable.MethodSignature;
-import org.apache.felix.ipojo.handlers.dependency.nullable.MethodSignatureVisitor;
 import org.apache.felix.ipojo.util.Logger;
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.Type;
 import org.osgi.framework.BundleContext;
 
 /**
@@ -86,39 +79,18 @@
         m_handler = psd;
     
         // Populate methods :
-        URL url = bc.getBundle().getResource(name.replace('.', '/') + ".class");
-        InputStream is = null;
-        ClassReader cr = null;
-        MethodSignatureVisitor msv = null;
         try {
-            is = url.openStream();
-            cr = new ClassReader(is);
-            msv = new MethodSignatureVisitor();
-            cr.accept(msv, ClassReader.SKIP_FRAMES);
-            is.close();
-        } catch (IOException e) {
+            Class clazz = bc.getBundle().loadClass(name);
+            Method[] methods = clazz.getMethods();
+            for (int i = 0; i < methods.length; i++) {
+                MethodMetadata method = new MethodMetadata(methods[i]);
+                m_methods.add(method);
+            }
+        } catch (ClassNotFoundException e) {
             m_handler.log(Logger.ERROR, "Cannot open " + name + " : " + e.getMessage());
             return;
         }
     
-        MethodSignature[] containsMethods = msv.getMethods();
-        for (int i = 0; i < containsMethods.length; i++) {
-            MethodSignature met = containsMethods[i];
-            String desc = met.getDesc();
-            MethodMetadata method = new MethodMetadata(met.getName(), desc);
-    
-            Type[] args = Type.getArgumentTypes(desc);
-            String[] exceptionClasses = met.getException();
-            for (int j = 0; j < args.length; j++) {
-                method.addArgument(args[j].getClassName());
-            }
-            for (int j = 0; j < exceptionClasses.length; j++) {
-                method.addException(exceptionClasses[j]);
-            }
-    
-            addMethod(method);
-        }
-    
         m_isAggregate = isAggregate;
         m_isOptional = isOptional;
     }
@@ -137,18 +109,8 @@
         m_name = c.getName();
         Method[] methods = c.getMethods();
         for (int i = 0; i < methods.length; i++) {
-            String desc = Type.getMethodDescriptor(methods[i]);
-            MethodMetadata method = new MethodMetadata(methods[i].getName(), desc);
-            Type[] args = Type.getArgumentTypes(desc);
-            Class[] exceptionClasses = methods[i].getExceptionTypes();
-            for (int j = 0; j < args.length; j++) {
-                method.addArgument(args[j].getClassName());
-            }
-            for (int j = 0; j < exceptionClasses.length; j++) {
-                method.addException(exceptionClasses[j].getName());
-            }
-    
-            addMethod(method);
+            MethodMetadata method = new MethodMetadata(methods[i]);    
+            m_methods.add(method);
         }
         m_isInterface = false;
     }
@@ -162,14 +124,6 @@
     }
 
     /**
-     * Add a method metadata to the current specification.
-     * @param mm : the method metadata to add.
-     */
-    public void addMethod(MethodMetadata mm) {
-        m_methods.add(mm);
-    }
-
-    /**
      * Get a method by its name.
      * @param name : method name
      * @return the method metadata contained in the current specification with the given name. Null if the method is not found.
@@ -177,7 +131,7 @@
     public MethodMetadata getMethodByName(String name) {
         for (int i = 0; i < m_methods.size(); i++) {
             MethodMetadata met = (MethodMetadata) m_methods.get(i);
-            if (met.getMethodName().equals(name)) {
+            if (met.getMethod().getName().equals(name)) {
                 return met;
             }
         }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java?rev=600287&r1=600286&r2=600287&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java Sun Dec  2 05:40:55 2007
@@ -20,6 +20,7 @@
 
 import java.lang.reflect.Array;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Proxy;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -27,6 +28,7 @@
 import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.IPojoContext;
 import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.Nullable;
 import org.apache.felix.ipojo.PolicyServiceContext;
 import org.apache.felix.ipojo.ServiceContext;
 import org.apache.felix.ipojo.composite.CompositeServiceContext;
@@ -40,7 +42,6 @@
 
 /**
  * Represent a service dependency of the component instance.
- * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 public class Dependency implements TrackerCustomizer {
@@ -175,9 +176,14 @@
     private boolean m_activated = false;
     
     /**
-     * Biding Policy.
+     * Binding Policy.
      */
     private int m_bindingPolicy;
+    
+    /**
+     * Nullable object.
+     */
+    private Object m_nullable;
 
     /**
      * Dependency constructor. After the creation the dependency is not started.
@@ -191,12 +197,29 @@
      * @param id : id of the dependency, may be null
      * @param policy : resolution policy
      * @param bindingPolicy : binding policy
+     * @param di : default-implementation class
      */
-    public Dependency(DependencyHandler dh, String field, String spec, String filter, boolean isOptional, boolean isAggregate, String id, int policy, int bindingPolicy) {
+    public Dependency(DependencyHandler dh, String field, String spec, String filter, boolean isOptional, boolean isAggregate, String id, int policy, int bindingPolicy, String di) {
         m_handler = dh;
         m_field = field;
         m_specification = spec;
         m_isOptional = isOptional;
+        if (m_isOptional) {
+            if (di != null) {
+                try {
+                    Class c = getHandler().getInstanceManager().getContext().getBundle().loadClass(di);
+                    m_nullable = c.newInstance();
+                } catch (IllegalAccessException e) {
+                    m_handler.log(Logger.ERROR, "Cannot load the default-implementation " + di + " : " + e.getMessage());
+                } catch (InstantiationException e) {
+                    m_handler.log(Logger.ERROR, "Cannot load the default-implementation " + di + " : " + e.getMessage());
+                } catch (ClassNotFoundException e) {
+                    m_handler.log(Logger.ERROR, "Cannot load the default-implementation " + di + " : " + e.getMessage());
+                }
+            } else {
+                m_nullable = Proxy.newProxyInstance(getHandler().getInstanceManager().getClazz().getClassLoader(), new Class[] {m_clazz, Nullable.class}, new NullableObject());
+            }
+        }
         m_strFilter = filter;
         m_isAggregate = isAggregate;
         if (m_id == null) {
@@ -319,14 +342,11 @@
                 }
             } else {
                 if (m_references.size() == 0) {
-                    Object nullable = m_handler.getNullableObject(this);
-
-                    if (nullable == null) {
-                        m_handler.log(Logger.WARNING, "[" + m_handler.getInstanceManager().getClassName() + "] Cannot load the nullable class to return a dependency object for " + m_field + " -> " + m_specification);
+                    if (m_nullable == null) {
+                        m_handler.log(Logger.WARNING, "[" + m_handler.getInstanceManager().getInstanceName() + "] The dependency is not optional, however no service object can be injected in " + m_field + " -> " + m_specification);
                         return null;
                     }
-
-                    m_usage.getObjects().add(nullable);
+                    m_usage.getObjects().add(m_nullable);
                 } else {
                     ServiceReference ref = (ServiceReference) m_references.get(0);
                     m_usage.getReferences().add(ref); // Get the first one
@@ -348,7 +368,7 @@
      * @param ref : reference to send (if accepted) to the method
      */
     private void callUnbindMethod(ServiceReference ref) {
-        if (m_handler.getInstanceManager().getState() > InstanceManager.STOPPED && m_handler.getInstanceManager().getPojoObjects().length > 0) {
+        if (m_handler.getInstanceManager().getState() > InstanceManager.STOPPED && m_handler.getInstanceManager().getPojoObjects() != null) {
             for (int i = 0; i < m_callbacks.length; i++) {
                 if (m_callbacks[i].getMethodType() == DependencyCallback.UNBIND) {
                     try {
@@ -447,7 +467,7 @@
     private void callBindMethod(ServiceReference ref) {
         // call bind method :
         // if (m_handler.getInstanceManager().getState() == InstanceManager.VALID) {
-        if (m_handler.getInstanceManager().getState() > InstanceManager.STOPPED && m_handler.getInstanceManager().getPojoObjects().length > 0) {
+        if (m_handler.getInstanceManager().getState() > InstanceManager.STOPPED && m_handler.getInstanceManager().getPojoObjects() != null) {
             for (int i = 0; i < m_callbacks.length; i++) {
                 if (m_callbacks[i].getMethodType() == DependencyCallback.BIND) {
                     try {

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java?rev=600287&r1=600286&r2=600287&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java Sun Dec  2 05:40:55 2007
@@ -18,19 +18,15 @@
  */
 package org.apache.felix.ipojo.handlers.dependency;
 
-import java.net.URL;
 import java.util.ArrayList;
 import java.util.Dictionary;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.ConfigurationException;
 import org.apache.felix.ipojo.PolicyServiceContext;
 import org.apache.felix.ipojo.PrimitiveHandler;
 import org.apache.felix.ipojo.architecture.HandlerDescription;
-import org.apache.felix.ipojo.handlers.dependency.nullable.NullableObjectWriter;
 import org.apache.felix.ipojo.metadata.Element;
 import org.apache.felix.ipojo.parser.FieldMetadata;
 import org.apache.felix.ipojo.parser.ManipulationMetadata;
@@ -50,11 +46,6 @@
     private Dependency[] m_dependencies = new Dependency[0];
 
     /**
-     * Map of dependency - nullable objects for optional dependencies.
-     */
-    private Map m_nullableObjects;
-
-    /**
      * State of the handler.
      * Lifecycle controller.
      */
@@ -216,7 +207,6 @@
      */
     public void configure(Element componentMetadata, Dictionary configuration) throws ConfigurationException {
         m_dependencies = new Dependency[0];
-        m_nullableObjects = new HashMap();
 
         ManipulationMetadata manipulation = new ManipulationMetadata(componentMetadata);
         List fl = new ArrayList();
@@ -234,6 +224,7 @@
             String filter = deps[i].getAttribute("filter");
             String opt = deps[i].getAttribute("optional");
             boolean optional = opt != null && opt.equalsIgnoreCase("true");
+            String di = deps[i].getAttribute("default-implementation");
             
             String agg = deps[i].getAttribute("aggregate");
             boolean aggregate = agg != null && agg.equalsIgnoreCase("true");
@@ -270,7 +261,7 @@
                 }
             }
             
-            Dependency dep = new Dependency(this, field, serviceSpecification, filter, optional, aggregate, id, scopePolicy, bindingPolicy);
+            Dependency dep = new Dependency(this, field, serviceSpecification, filter, optional, aggregate, id, scopePolicy, bindingPolicy, di);
 
             // Look for dependency callback :
             for (int j = 0; j < (deps[i].getElements("Callback", "")).length; j++) {
@@ -297,13 +288,6 @@
                     fl.add(manipulation.getField(dep.getField()));
                 }
             }
-            
-            if (optional) {
-                String defaultImpl = deps[i].getAttribute("default-implementation");
-                if (defaultImpl != null) {
-                    m_nullableObjects.put(dep, defaultImpl);
-                }
-            }
         }
 
         if (deps.length > 0) {
@@ -314,62 +298,6 @@
     }
 
     /**
-     * Create a nullable class for the given dependency.
-     * @param dep : the service dependency
-     */
-    private void createNullableObject(Dependency  dep) {
-        String spec = dep.getSpecification();
-        String className = spec + "Nullable";
-        String resource = spec.replace('.', '/') + ".class";
-        URL url = getInstanceManager().getContext().getBundle().getResource(resource);
-
-        byte[] b = NullableObjectWriter.dump(url, spec);
-        Class c = getInstanceManager().getFactory().defineClass(className, b, null);
-        try {
-            Object o = c.newInstance();
-            m_nullableObjects.put(dep, o);
-        } catch (InstantiationException e) {
-            log(Logger.ERROR, "The nullable object for " + dep.getSpecification() + " cannot be instantiate : " + e.getMessage());
-            getInstanceManager().setState(ComponentInstance.INVALID); 
-        } catch (IllegalAccessException e) {
-            log(Logger.ERROR, "The nullable object for " + dep.getSpecification() + " cannot be instantiate : " + e.getMessage());
-            getInstanceManager().setState(ComponentInstance.INVALID);
-        }
-    }
-
-    /**
-     * Return the nullable class corresponding to the given name.
-     * @param dep the dependency which require the nullable class.
-     * @return the class corresponding to the name, or null if the class does not exist.
-     */
-    protected Object getNullableObject(Dependency dep) {
-        Object obj = m_nullableObjects.get(dep);
-        if (obj == null) { return null; } // Should not happen
-        if (obj instanceof String) { 
-            try {
-                Class c = getInstanceManager().getContext().getBundle().loadClass((String) obj);
-                obj = c.newInstance();
-                m_nullableObjects.put(dep, obj);
-                return obj;
-            } catch (ClassNotFoundException e) {
-                // A default-implementation class cannot be loaded
-                log(Logger.ERROR, "The default-implementation class " + obj + " cannot be loaded : " + e.getMessage());
-                getInstanceManager().setState(ComponentInstance.INVALID);
-                return null;
-            } catch (InstantiationException e) {
-                log(Logger.ERROR, "The default-implementation class " + obj + " cannot be instantiated : " + e.getMessage());
-                getInstanceManager().setState(ComponentInstance.INVALID);
-            } catch (IllegalAccessException e) {
-                log(Logger.ERROR, "The default-implementation class " + obj + " cannot be instantiated : " + e.getMessage());
-                getInstanceManager().setState(ComponentInstance.INVALID);
-            }
-            return null;
-        } else {
-            return obj;
-        }
-    }
-
-    /**
      * GetterCallback Method.
      * @param fieldName : the field name.
      * @param value : the value passed to the field (by the previous handler).
@@ -423,12 +351,9 @@
      * @see org.apache.felix.ipojo.Handler#start()
      */
     public void start() {
-        // Start the dependencies, for optional dependencies create Nullable class
+        // Start the dependencies
         for (int i = 0; i < m_dependencies.length; i++) {
             Dependency dep = m_dependencies[i];
-            if (dep.isOptional() && !dep.isAggregate() && ! m_nullableObjects.containsKey(dep)) {
-                createNullableObject(dep);
-            }
             dep.start();
         }
         // Check the state

Added: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java?rev=600287&view=auto
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java (added)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java Sun Dec  2 05:40:55 2007
@@ -0,0 +1,93 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.InvocationHandler;
+import java.lang.reflect.Method;
+
+/**
+ * Default nullable object.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class NullableObject implements InvocationHandler {
+    
+    /**
+     * Default boolean value.
+     */
+    private static final Boolean DEFAULT_BOOLEAN = Boolean.FALSE;
+    /**
+     * Default byte value.
+     */
+    private static final Byte DEFAULT_BYTE = new Byte((byte) 0);
+    
+    /**
+     * Default short value.
+     */
+    private static final Short DEFAULT_SHORT = new Short((short) 0);
+    
+    /**
+     * Default integer value.
+     */
+    private static final Integer DEFAULT_INT = new Integer(0);
+    
+    /**
+     * Default long value.
+     */
+    private static final Long DEFAULT_LONG = new Long(0);
+    
+    /**
+     * Default float value.
+     */
+    private static final Float DEFAULT_FLOAT = new Float(0.0f);
+    
+    /**
+     * Default double value.
+     */
+    private static final Double DEFAULT_DOUBLE = new Double(0.0);
+    
+    /**
+     * Invokes a method on this null object. The method will return a default
+     * value without doing anything.
+     * @param proxy : proxy object
+     * @param method : invoked method
+     * @param args : arguments.
+     * @return the returned value.
+     * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+     */
+    public Object invoke(Object proxy, Method method, Object[] args) {
+        Class returnType = method.getReturnType();
+        if (returnType.equals(Boolean.TYPE)) {
+            return DEFAULT_BOOLEAN;
+        } else if (returnType.equals(Byte.TYPE)) {
+            return DEFAULT_BYTE;
+        } else if (returnType.equals(Short.TYPE)) {
+            return DEFAULT_SHORT;
+        } else if (returnType.equals(Integer.TYPE)) {
+            return DEFAULT_INT;
+        } else if (returnType.equals(Long.TYPE)) {
+            return DEFAULT_LONG;
+        } else if (returnType.equals(Float.TYPE)) {
+            return DEFAULT_FLOAT;
+        } else if (returnType.equals(Double.TYPE)) {
+            return DEFAULT_DOUBLE;
+        } else {
+            return null;
+        }
+    }
+}

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java?rev=600287&r1=600286&r2=600287&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java Sun Dec  2 05:40:55 2007
@@ -153,7 +153,7 @@
         }
         
         // Manage immediate component
-        if (m_immediate && transition == LifecycleCallback.VALIDATE && getInstanceManager().getPojoObjects().length == 0) {
+        if (m_immediate && transition == LifecycleCallback.VALIDATE && getInstanceManager().getPojoObjects() == null) {
             getInstanceManager().getPojoObject();
         }
 

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java?rev=600287&r1=600286&r2=600287&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java Sun Dec  2 05:40:55 2007
@@ -216,15 +216,9 @@
      */
     protected synchronized void registerService() {
         if (m_serviceRegistration == null) {
-            String spec = "";
-            for (int i = 0; i < m_serviceSpecification.length; i++) {
-                spec = spec + m_serviceSpecification[i] + ", ";
-            }
             // Build the service properties list
             Properties serviceProperties = getServiceProperties();
-           
             m_serviceRegistration = m_handler.getInstanceManager().getContext().registerService(m_serviceSpecification, this, serviceProperties);
-           
         }
     }
 

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java?rev=600287&r1=600286&r2=600287&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Callback.java Sun Dec  2 05:40:55 2007
@@ -288,7 +288,7 @@
             // Two cases :
             // - if instances already exists : call on each instances
             // - if no instance exists : create an instance
-            if (m_manager.getPojoObjects().length == 0) {
+            if (m_manager.getPojoObjects() == null) {
                 return m_methodObj.invoke(m_manager.getPojoObject(), arg);
             } else {
                 Object r = null;

Modified: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java?rev=600287&r1=600286&r2=600287&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java (original)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java Sun Dec  2 05:40:55 2007
@@ -79,8 +79,10 @@
         if (access == ACC_PRIVATE && name.equals("_cm")
                 && desc.equals("Lorg/apache/felix/ipojo/InstanceManager;")) {
             m_isAlreadyManipulated = true;
-        }
-
+        } else if (name.startsWith("class$")) { // Does not add class$* field generated by 'x.class'
+            return null;
+        } 
+        
         Type type = Type.getType(desc);
         if (type.getSort() == Type.ARRAY) {
             if (type.getInternalName().startsWith("L")) {

Modified: felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java?rev=600287&r1=600286&r2=600287&view=diff
==============================================================================
--- felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java (original)
+++ felix/trunk/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/PojoAdapter.java Sun Dec  2 05:40:55 2007
@@ -326,6 +326,9 @@
         mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getRegistredFields", "()Ljava/util/Set;");
         mv.visitVarInsn(ASTORE, 2);
 
+        mv.visitVarInsn(ALOAD, 2);
+        Label endif = new Label();
+        mv.visitJumpInsn(IFNULL, endif);
         Iterator it = m_fields.iterator();
         while (it.hasNext()) {
             String field = (String) it.next();
@@ -339,11 +342,16 @@
             mv.visitFieldInsn(PUTFIELD, m_owner, "_F" + field, "Z");
             mv.visitLabel(l3);
         }
-
+        mv.visitLabel(endif);
+        
         mv.visitVarInsn(ALOAD, 0);
         mv.visitFieldInsn(GETFIELD, m_owner, "_cm", "Lorg/apache/felix/ipojo/InstanceManager;");
         mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/felix/ipojo/InstanceManager", "getRegistredMethods", "()Ljava/util/Set;");
         mv.visitVarInsn(ASTORE, 2);
+        
+        mv.visitVarInsn(ALOAD, 2);
+        Label endif2 = new Label();
+        mv.visitJumpInsn(IFNULL, endif2);
 
         for (int i = 0; i < m_methods.size(); i++) {
             String methodId = (String) m_methods.get(i);
@@ -357,6 +365,8 @@
             mv.visitFieldInsn(PUTFIELD, m_owner, "_M" + methodId, "Z");
             mv.visitLabel(l3);
         }
+        
+        mv.visitLabel(endif2);
 
         mv.visitInsn(RETURN);