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 2007/04/18 21:47:58 UTC

svn commit: r530141 [1/2] - in /incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides: ./ manipulation/

Author: rickhall
Date: Wed Apr 18 12:47:57 2007
New Revision: 530141

URL: http://svn.apache.org/viewvc?view=rev&rev=530141
Log:
Mixed part of patch (FELIX-270)...I needed to do an "svn add".

Added:
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java   (with props)
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java   (with props)
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java   (with props)
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java   (with props)
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java   (with props)
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java   (with props)
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java   (with props)
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java   (with props)
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java   (with props)
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ClassChecker.java   (with props)
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ConstructorCodeAdapter.java   (with props)
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ManipulationProperty.java   (with props)
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/Manipulator.java   (with props)
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/POJOWriter.java   (with props)
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/PreprocessClassAdapter.java   (with props)
    incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/PreprocessCodeAdapter.java   (with props)

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java?view=auto&rev=530141
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java Wed Apr 18 12:47:57 2007
@@ -0,0 +1,55 @@
+/* 
+ * 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.composite.service.provides;
+
+/**
+ * Exception throwed when a composition error occurs.
+ * 
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class CompositionException extends Exception {
+
+    /**
+     * serialVersionUID.
+     */
+    private static final long serialVersionUID = -3063353267573738105L;
+
+    /**
+     * Message.
+     */
+    private String m_message;
+
+    /**
+     * Constructor.
+     * @param message : a message.
+     */
+    public CompositionException(String message) {
+        m_message = message;
+    }
+
+    /**
+     * Get the excepttion message.
+     * @return the message.
+     * @see java.lang.Throwable#getMessage()
+     */
+    public String getMessage() {
+        return m_message;
+    }
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java?view=auto&rev=530141
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java Wed Apr 18 12:47:57 2007
@@ -0,0 +1,321 @@
+/* 
+ * 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.composite.service.provides;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.ipojo.composite.service.provides.manipulation.Manipulator;
+import org.apache.felix.ipojo.composite.service.provides.manipulation.POJOWriter;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Logger;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Check and build a compostion, i.e. a pojo containing the composition.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class CompositionMetadata {
+
+    /**
+     * Implemented composition.
+     */
+    private SpecificationMetadata m_specification;
+
+    /**
+     * Name of the composition.
+     */
+    private String m_name;
+
+    /**
+     * Bundle Context.
+     */
+    private BundleContext m_context;
+
+    /**
+     * Manipulated field of the build Pojo. 
+     */
+    private HashMap m_manipulatedFields = new HashMap();
+
+    /**
+     * Manipulated interface of the build Pojo.
+     */
+    private String[] m_manipulatedInterfaces = new String[0];
+
+    /**
+     * Reference on the handler.
+     */
+    private ProvidedServiceHandler m_handler;
+
+    /**
+     * List of Mappings.
+     */
+    private List m_mappings = new ArrayList();
+
+    /**
+     * Constructor.
+     * @param bc : bundle context
+     * @param description : 'provides' element
+     * @param psh : parent handler 
+     * @param name : name of the composition.
+     */
+    public CompositionMetadata(BundleContext bc, Element description, ProvidedServiceHandler psh, String name) {
+        m_context = bc;
+        m_handler = psh;
+        // Get the composition name
+        m_name = description.getAttribute("specification") + name;
+
+        // Get implemented service specification
+        String spec = description.getAttribute("specification");
+        m_specification = new SpecificationMetadata(spec, m_context, false, false, m_handler);
+
+        Element[] mappings = description.getElements("delegation");
+        for (int i = 0; i < mappings.length; i++) {
+            String methodName = mappings[i].getAttribute("method");
+            MethodMetadata method = m_specification.getMethodByName(methodName);
+            if (method == null) {
+                m_handler.getManager().getFactory().getLogger().log(Logger.ERROR, "The method " + methodName + " does not exist in the specicifation " + spec);
+                return;
+            }
+
+            if (mappings[i].getAttribute("policy").equalsIgnoreCase("All")) {
+                method.setAllPolicy();
+            }
+        }
+    }
+
+    protected BundleContext getBundleContext() {
+        return m_context;
+    }
+
+    public String getName() {
+        return m_name;
+    }
+
+    public SpecificationMetadata getSpecificationMetadata() {
+        return m_specification;
+    }
+
+    /**
+     * Build Available Mappings.
+     */
+    private void buildAvailableMappingList() {
+        int index = 0;
+
+        for (int i = 0; i < m_handler.getSpecifications().size(); i++) {
+            SpecificationMetadata spec = (SpecificationMetadata) m_handler.getSpecifications().get(i);
+            FieldMetadata field = new FieldMetadata(spec);
+            field.setName("_field" + index);
+            if (spec.isOptional()) {
+                field.setOptional(true);
+            }
+            if (spec.isAggregate()) {
+                field.setAggregate(true);
+            }
+            Mapping map = new Mapping(spec, field);
+            m_mappings.add(map);
+            index++;
+        }
+    }
+
+    /**
+     * Build the delegation mapping.
+     * @throws CompositionException : occurs when the mapping cannot be infers correctly
+     */
+    protected void buildMapping() throws CompositionException {
+        buildAvailableMappingList();
+
+        // Dependency closure is OK, now look for method delegation
+        Map/* <MethodMetadata, Mapping> */availableMethods = new HashMap();
+
+        for (int i = 0; i < m_mappings.size(); i++) {
+            Mapping map = (Mapping) m_mappings.get(i);
+            SpecificationMetadata spec = map.getSpecification();
+            for (int j = 0; j < spec.getMethods().size(); j++) {
+                MethodMetadata method = (MethodMetadata) spec.getMethods().get(j);
+                availableMethods.put(method, map);
+            }
+        }
+
+        // For each needed method search if available and store the mapping
+        for (int j = 0; j < m_specification.getMethods().size(); j++) {
+            MethodMetadata method = (MethodMetadata) m_specification.getMethods().get(j);
+            Set keys = availableMethods.keySet();
+            Iterator it = keys.iterator();
+            boolean found = false;
+            while (it.hasNext() & !found) {
+                MethodMetadata met = (MethodMetadata) it.next();
+                if (met.equals(method)) {
+                    found = true;
+                    FieldMetadata field = ((Mapping) availableMethods.get(met)).getField();
+                    field.setUseful(true);
+                    method.setDelegation(field);
+                    // Test optionality
+                    if (field.isOptional() && !method.getExceptions().contains("java/lang/UnsupportedOperationException")) {
+                        m_handler.getManager().getFactory().getLogger().log(Logger.WARNING, "The method " + method.getMethodName() + " could not be provided correctly : the specification " + field.getSpecification().getName() + " is optional");
+                    }
+                }
+            }
+            if (!found) {
+                throw new CompositionException("Composition non consistent : " + method.getMethodName() + " could not be delegated");
+            }
+        }
+    }
+
+    /**
+     * Build a service implementation.
+     * @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());
+        Manipulator m = new Manipulator();
+        try {
+            byte[] ff = m.process(pojo);
+            m_manipulatedFields = m.getFields();
+            m_manipulatedInterfaces = m.getInterfaces();
+            return ff;
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * Build service implementation metadata.
+     * @return Component Type metadata. 
+     */
+    protected Element buildMetadata() {
+        Element elem = new Element("component", "");
+        Attribute className = new Attribute("className", m_name);
+        Attribute factory = new Attribute("factory", "no");
+        elem.addAttribute(className);
+        elem.addAttribute(factory);
+
+        // Provides
+        Element provides = new Element("provides", "");
+        provides.addAttribute(new Attribute("specification", m_specification.getName()));
+        elem.addElement(provides);
+
+        // Dependencies
+        List fields = getFieldList();
+        for (int i = 0; i < fields.size(); i++) {
+            FieldMetadata field = (FieldMetadata) fields.get(i);
+            if (field.isUseful()) {
+                Element dep = new Element("Dependency", "");
+                dep.addAttribute(new Attribute("field", field.getName()));
+                if (field.getSpecification().isOptional()) {
+                    dep.addAttribute(new Attribute("optional", "true"));
+                }
+                elem.addElement(dep);
+            }
+        }
+
+        // Insert information to metadata
+        Element manip = new Element("Manipulation", "");
+        for (int j = 0; j < m_manipulatedInterfaces.length; j++) {
+            // Create an interface element for each implemented interface
+            Element itf = new Element("Interface", "");
+            Attribute att = new Attribute("name", m_manipulatedInterfaces[j]);
+            itf.addAttribute(att);
+            manip.addElement(itf);
+        }
+
+        Iterator it = m_manipulatedFields.keySet().iterator();
+        while (it.hasNext()) {
+            Element field = new Element("Field", "");
+            String name = (String) it.next();
+            String type = (String) m_manipulatedFields.get(name);
+            Attribute attName = new Attribute("name", name);
+            Attribute attType = new Attribute("type", type);
+            field.addAttribute(attName);
+            field.addAttribute(attType);
+            manip.addElement(field);
+        }
+
+        elem.addElement(manip);
+
+        return elem;
+    }
+
+    /**
+     * Get the field list to use for the delegation.
+     * @return the field list.
+     */
+    private List getFieldList() {
+        List list = new ArrayList();
+        for (int i = 0; i < m_mappings.size(); i++) {
+            Mapping map = (Mapping) m_mappings.get(i);
+            list.add(map.getField());
+        }
+        return list;
+    }
+
+    /**
+     * Get the method lsit contained in the implemented specification.
+     * @return the List of implemented method.
+     */
+    private List getMethodList() {
+        return m_specification.getMethods();
+    }
+    
+    /**
+     * Store links between Field and pointed Specification.
+     */
+    private class Mapping {
+
+        /**
+         * Specification.
+         */
+        private SpecificationMetadata m_spec;
+
+        /**
+         * Field.
+         */
+        private FieldMetadata m_field;
+
+        /**
+         * Constructor.
+         * @param spec : specification metadata.
+         * @param field : the field.
+         */
+        public Mapping(SpecificationMetadata spec, FieldMetadata field) {
+            m_spec = spec;
+            m_field = field;
+        }
+
+        public SpecificationMetadata getSpecification() {
+            return m_spec;
+        }
+
+        public FieldMetadata getField() {
+            return m_field;
+        }
+
+    }
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java?view=auto&rev=530141
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java Wed Apr 18 12:47:57 2007
@@ -0,0 +1,105 @@
+/* 
+ * 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.composite.service.provides;
+
+/**
+ * Field used inside a composition.
+ * This class contains all information useful for the generation.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class FieldMetadata {
+
+    /**
+     * Name of the field.
+     */
+    private String m_name;
+
+    /**
+     * Is the field an array?
+     */
+    private boolean m_isAggregate = false;
+
+    /**
+     * Interface of the field.
+     */
+    private SpecificationMetadata m_specification;
+
+    /**
+     * Is the field useful in this composition.
+     */
+    private boolean m_isUseful;
+
+    /**
+     * Is the dependency for this field optional.
+     */
+    private boolean m_isOptional = false;
+
+    /**
+     * Constructor.
+     * @param specification : interface of the field.
+     */
+    public FieldMetadata(SpecificationMetadata specification) {
+        super();
+        this.m_specification = specification;
+        if (m_specification.isAggregate()) {
+            m_isAggregate = true;
+        }
+    }
+
+    public boolean isAggregate() {
+        return m_isAggregate;
+    }
+
+    public void setAggregate(boolean aggregate) {
+        m_isAggregate = aggregate;
+    }
+
+    public String getName() {
+        return m_name;
+    }
+
+    public void setName(String name) {
+        this.m_name = name;
+    }
+
+    public SpecificationMetadata getSpecification() {
+        return m_specification;
+    }
+
+    public void setSpecification(SpecificationMetadata specification) {
+        this.m_specification = specification;
+    }
+
+    public boolean isUseful() {
+        return m_isUseful;
+    }
+
+    public void setUseful(boolean useful) {
+        m_isUseful = useful;
+    }
+
+    public boolean isOptional() {
+        return m_isOptional;
+    }
+
+    public void setOptional(boolean opt) {
+        m_isOptional = opt;
+    }
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java?view=auto&rev=530141
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java Wed Apr 18 12:47:57 2007
@@ -0,0 +1,173 @@
+/* 
+ * 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.composite.service.provides;
+
+import java.util.ArrayList;
+
+import org.apache.felix.ipojo.handlers.dependency.nullable.MethodSignature;
+
+/**
+ * Information on Method for the composition.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class MethodMetadata {
+
+    /**
+     * ONE POLICY.
+     */
+    public static final int ONE_POLICY = 1;
+
+    /**
+     * ALL POLICY. 
+     */
+    public static final int ALL_POLICY = 2;
+
+    /**
+     * Method Name.
+     */
+    private String m_methodName;
+
+    /**
+     * Internal Descriptor.
+     */
+    private String m_descriptor;
+
+    /**
+     * List of arguments. 
+     */
+    private ArrayList/* <String> */m_arguments = new ArrayList/* <String> */();
+
+    /**
+     * List of exceptions.
+     */
+    private ArrayList/* <String> */m_exceptions = new ArrayList/* <String> */();
+    
+    /**
+     * Delegator field.
+     */
+    private FieldMetadata m_delegation;
+
+    /**
+     * Delegation policy (default = ONE).
+     */
+    private int m_policy = ONE_POLICY;
+
+    /**
+     * Constructor.
+     * @param name : name of the method.
+     * @param desc : description of the method.
+     */
+    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 ArrayList/* <String> */getArguments() {
+        return m_arguments;
+    }
+
+    public ArrayList/* <String> */getExceptions() {
+        return m_exceptions;
+    }
+
+    public String getMethodName() {
+        return m_methodName;
+    }
+
+    
+
+    public void setDelegation(FieldMetadata dm) {
+        m_delegation = dm;
+    }
+
+    public FieldMetadata getDelegation() {
+        return m_delegation;
+    }
+
+    /**
+     * Check if two method metadata are equals.
+     * @param mm : the method metadata to compare with the current method metadata.
+     * @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;
+            }
+        }
+
+//        for (int i = 0; i < m_exceptions.size(); i++) {
+//            if (! mm.getExceptions().contains(m_exceptions.get(i))) { return false; }
+//        }
+
+        return true;
+    }
+
+    /**
+     * Equals method for Method Signature.
+     * @param ms : the method signatur 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())) {
+            return false;
+        }
+        if (!m_descriptor.equals(ms.getDesc())) {
+            return false;
+        }
+        
+        return true;
+    }
+
+    public int getPolicy() {
+        return m_policy;
+    }
+
+    /**
+     * Activate the all policy for this method.
+     */
+    public void setAllPolicy() {
+        m_policy = ALL_POLICY;
+    }
+    
+    public String getDescription() { return m_descriptor; }
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java?view=auto&rev=530141
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java Wed Apr 18 12:47:57 2007
@@ -0,0 +1,199 @@
+/* 
+ * 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.composite.service.provides;
+
+import java.util.Properties;
+
+import org.apache.felix.ipojo.ComponentFactory;
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.CompositeManager;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.UnacceptableConfiguration;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+
+/**
+ * Composite Provided Service.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ProvidedService {
+
+    /**
+     * Composite Manager.
+     */
+    private CompositeManager m_manager;
+
+    /**
+     * Composition Model.
+     */
+    private CompositionMetadata m_composition;
+
+    /**
+     * generated POJO class.
+     */
+    private byte[] m_clazz;
+
+    /**
+     * Metadata of the POJO. 
+     */
+    private Element m_metadata;
+
+    /**
+     * Internal context.
+     */
+    private ServiceContext m_scope;
+
+    /**
+     * External context.
+     */
+    private BundleContext m_context;
+
+    /**
+     * Created Factory.
+     */
+    private ComponentFactory m_factory;
+
+    /**
+     * Created Instance.
+     */
+    private ComponentInstance m_instance;
+
+    /**
+     * Exporter.
+     */
+    private ServiceExporter m_exports;
+
+    /**
+     * Constructor.
+     * The delegation mapping is infers in this method.
+     * @param handler : the handler.
+     * @param element : 'provides' element.
+     * @param name : name of this provided service.
+     */
+    public ProvidedService(ProvidedServiceHandler handler, Element element, String name) {
+        m_manager = handler.getManager();
+        m_scope = m_manager.getServiceContext();
+        m_context = m_manager.getContext();
+        m_composition = new CompositionMetadata(m_manager.getContext(), element, handler, name);
+        try {
+            m_composition.buildMapping();
+        } catch (CompositionException e) {
+            return;
+        }
+    }
+
+    /**
+     * Start method.
+     * Build service implementation type, factory and instance.
+     */
+    public void start() {
+        m_clazz = m_composition.buildPOJO();
+        m_metadata = m_composition.buildMetadata();
+
+        // Create the factory
+        m_factory = new ComponentFactory(m_context, m_clazz, m_metadata);
+        m_factory.start();
+
+        Properties p = new Properties();
+        String name = m_composition.getSpecificationMetadata().getName() + "Provider";
+        p.put("name", name);
+        try {
+            m_instance = m_factory.createComponentInstance(p, m_scope);
+        } catch (UnacceptableConfiguration e) {
+            return;
+        }
+        // Create the exports
+        m_exports = new ServiceExporter(m_composition.getSpecificationMetadata().getName(), "(" + Constants.SERVICE_PID + "=" + name + ")", false, false,
+                m_scope, m_context, this);
+    }
+
+    /**
+     * Stop the provided service.
+     * Kill the exporter, the instance and the factory.
+     */
+    public void stop() {
+        if (m_exports != null) {
+            m_exports.stop();
+            m_exports = null;
+        }
+        if (m_instance != null) {
+            m_instance.dispose();
+            m_instance = null;
+        }
+        if (m_factory != null) {
+            m_factory.stop();
+            m_factory = null;
+        }
+    }
+
+    protected CompositeManager getManager() {
+        return m_manager;
+    }
+
+    /**
+     * The exporter becomes valid.
+     * @param exporter : the exporter
+     */
+    public void validating(ServiceExporter exporter) {
+    }
+
+    /**
+     * The exporter becomes invalid.
+     * @param exporter : the exporter
+     */
+    public void invalidating(ServiceExporter exporter) {
+    }
+
+    /**
+     * Unregister published service.
+     */
+    protected void unregister() {
+        if (m_exports != null) {
+            m_instance.stop();
+            m_exports.stop();
+        }
+    }
+
+    /**
+     * Register published service.
+     */
+    protected void register() {
+        if (m_exports != null) {
+            m_instance.start();
+            m_exports.start();
+        }
+    }
+
+    public String getSpecification() {
+        return m_composition.getSpecificationMetadata().getName();
+    }
+
+    /**
+     * Check the provided service state.
+     * @return true if the exporter is publishing.
+     */
+    public boolean getState() {
+        if (m_exports != null && m_exports.isPublishing()) {
+            return true;
+        }
+        return false;
+    }
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java?view=auto&rev=530141
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java Wed Apr 18 12:47:57 2007
@@ -0,0 +1,192 @@
+/* 
+ * 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.composite.service.provides;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.CompositeHandler;
+import org.apache.felix.ipojo.CompositeManager;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Composite Provided Service Handler.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ProvidedServiceHandler extends CompositeHandler {
+
+    /**
+     * Reference on the instance.
+     */
+    private CompositeManager m_manager;
+
+    /**
+     * External context.
+     */
+    private BundleContext m_context;
+
+    /**
+     * List of "available" services in the internal context.
+     */
+    private List m_services = new ArrayList();
+
+    /**
+     * List of managed services.
+     */
+    private ArrayList m_managedServices = new ArrayList();
+
+    /**
+     * Configure the handler.
+     * 
+     * @param im : the instance manager
+     * @param metadata : the metadata of the component
+     * @param configuration : the instance configuration
+     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
+     * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(CompositeManager im, Element metadata, Dictionary configuration) {
+        m_manager = im;
+        m_context = im.getContext();
+
+        // Get composition metadata
+        Element[] provides = metadata.getElements("provides", "");
+        if (provides.length == 0) {
+            return;
+        }
+
+        // Compute imports and instances
+        computeAvailableServices(metadata);
+
+        for (int i = 0; i < provides.length; i++) {
+            ProvidedService ps = new ProvidedService(this, provides[i], "" + i);
+            m_managedServices.add(ps);
+            im.getComponentDescription().addProvidedServiceSpecification(ps.getSpecification());
+        }
+
+        im.register(this);
+    }
+
+    /**
+     * Start metod.
+     * Start all managed provided service.
+     * @see org.apache.felix.ipojo.CompositeHandler#start()
+     */
+    public void start() {
+        for (int i = 0; i < m_managedServices.size(); i++) {
+            ProvidedService ps = (ProvidedService) m_managedServices.get(i);
+            ps.start();
+        }
+
+    }
+
+    /**
+     * Stop method.
+     * Stop all managedprovided service.
+     * @see org.apache.felix.ipojo.CompositeHandler#stop()
+     */
+    public void stop() {
+        for (int i = 0; i < m_managedServices.size(); i++) {
+            ProvidedService ps = (ProvidedService) m_managedServices.get(i);
+            ps.stop();
+        }
+    }
+
+    /**
+     * Handler state changed.
+     * @param state : the new instance state.
+     * @see org.apache.felix.ipojo.CompositeHandler#stateChanged(int)
+     */
+    public void stateChanged(int state) {
+        if (state == ComponentInstance.INVALID) {
+            for (int i = 0; i < m_managedServices.size(); i++) {
+                ProvidedService ps = (ProvidedService) m_managedServices.get(i);
+                ps.unregister();
+            }
+            return;
+        }
+
+        // If the new state is VALID => regiter all the services
+        if (state == ComponentInstance.VALID) {
+            for (int i = 0; i < m_managedServices.size(); i++) {
+                ProvidedService ps = (ProvidedService) m_managedServices.get(i);
+                ps.register();
+            }
+            return;
+        }
+    }
+
+    protected CompositeManager getManager() {
+        return m_manager;
+    }
+
+    /**
+     * Build the list of available specification.
+     * @return the list of available specification.
+     */
+    protected List getSpecifications() {
+        return m_services;
+    }
+
+    /**
+     * Build available specification.
+     * 
+     * @param metadata : composite metadata
+     */
+    private void computeAvailableServices(Element metadata) {
+        // Get instantiated services :
+        Element[] services = metadata.getElements("service", "");
+        for (int i = 0; i < services.length; i++) {
+            String itf = services[i].getAttribute("specification");
+            boolean agg = false;
+            boolean opt = false;
+            if (services[i].containsAttribute("aggregate") && services[i].getAttribute("aggregate").equalsIgnoreCase("true")) {
+                agg = true;
+            }
+            if (services[i].containsAttribute("optional") && services[i].getAttribute("optional").equalsIgnoreCase("true")) {
+                opt = true;
+            }
+            SpecificationMetadata sm = new SpecificationMetadata(itf, m_context, agg, opt, this);
+            m_services.add(sm);
+        }
+
+        Element[] imports = metadata.getElements("import", "");
+        for (int i = 0; i < imports.length; i++) {
+            String itf = imports[i].getAttribute("specification");
+            boolean agg = false;
+            boolean opt = false;
+            if (imports[i].containsAttribute("aggregate") && imports[i].getAttribute("aggregate").equalsIgnoreCase("true")) {
+                agg = true;
+            }
+            if (imports[i].containsAttribute("optional") && imports[i].getAttribute("optional").equalsIgnoreCase("true")) {
+                opt = true;
+            }
+            SpecificationMetadata sm = new SpecificationMetadata(itf, m_context, agg, opt, this);
+            m_services.add(sm);
+        }
+    }
+
+    public HandlerDescription getDescription() {
+        return new ProvidedServiceHandlerDescription(true, m_managedServices);
+    }
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java?view=auto&rev=530141
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java Wed Apr 18 12:47:57 2007
@@ -0,0 +1,73 @@
+/* 
+ * 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.composite.service.provides;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Provided Service Handler Description for composite.
+ * 
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ProvidedServiceHandlerDescription extends HandlerDescription {
+
+    /**
+     * Provided Service Description list.
+     */
+    private List m_providedServices = new ArrayList();
+
+    /**
+     * Constructor.
+     * 
+     * @param isValid : the validity of the provided service handler.
+     * @param ps : The list of Provided Service.
+     */
+    public ProvidedServiceHandlerDescription(boolean isValid, List ps) {
+        super(ProvidedServiceHandler.class.getName(), isValid);
+        m_providedServices = ps;
+    }
+
+    /**
+     * Get the handler description.
+     * @return the provided service handler description
+     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+     */
+    public Element getHandlerInfo() {
+        Element services = super.getHandlerInfo();
+        for (int i = 0; i < m_providedServices.size(); i++) {
+            ProvidedService ps = (ProvidedService) m_providedServices.get(i);
+            Element service = new Element("service", "");
+            String state = "unregistered";
+            if (ps.getState()) {
+                state = "registered";
+            }
+            String spec = "[" + ps.getSpecification() + "]";
+            service.addAttribute(new Attribute("Specification", spec));
+            service.addAttribute(new Attribute("State", state));
+            services.addElement(service);
+        }
+        return services;
+    }
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java?view=auto&rev=530141
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java Wed Apr 18 12:47:57 2007
@@ -0,0 +1,364 @@
+/* 
+ * 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.composite.service.provides;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.ServiceContext;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Export an service from the scope to the parent context.
+ * 
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ServiceExporter implements ServiceListener {
+
+    /**
+     * Destination context.
+     */
+    private BundleContext m_destination;
+
+    /**
+     * Origin context.
+     */
+    private ServiceContext m_origin;
+
+    /**
+     * Exported specification.
+     */
+    private String m_specification;
+
+    /**
+     * LDAP filter filtering internal provider.
+     */
+    private Filter m_filter;
+
+    /**
+     * String form of the LDAP filter.
+     */
+    private String m_filterStr;
+
+    /**
+     * Should be exported several providers.
+     */
+    private boolean m_aggregate = false;
+
+    /**
+     * Is this exports optional?
+     */
+    private boolean m_optional = false;
+
+    /**
+     * Reference on the provided service.
+     */
+    private ProvidedService m_ps;
+
+    /**
+     * Is the export valid?
+     */
+    private boolean m_isValid;
+
+    private class Record {
+        /**
+         * Internal Reference.
+         */
+        private ServiceReference m_ref;
+        /**
+         * External Registration.
+         */
+        private ServiceRegistration m_reg;
+        /**
+         * Exposed object.
+         */
+        private Object m_svcObject;
+    }
+
+    /**
+     * List of managed records.
+     */
+    private List/* <Record> */m_records = new ArrayList()/* <Record> */;
+
+    /**
+     * Constructor.
+     * 
+     * @param specification : exported service specification.
+     * @param filter : LDAP filter
+     * @param multiple : is the export an aggregate export?
+     * @param optional : is the export optional?
+     * @param from : internal service context
+     * @param to : external bundle context
+     * @param exp : handler
+     */
+    public ServiceExporter(String specification, String filter, boolean multiple, boolean optional, ServiceContext from, BundleContext to, ProvidedService exp) {
+        this.m_destination = to;
+        this.m_origin = from;
+        this.m_ps = exp;
+        try {
+            this.m_filter = to.createFilter(filter);
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+            return;
+        }
+        this.m_aggregate = multiple;
+        this.m_specification = specification;
+        this.m_optional = optional;
+    }
+
+    /**
+     * Start method.
+     * Start the export and the provider tracking. 
+     */
+    public synchronized void start() {
+        try {
+            ServiceReference[] refs = m_origin.getServiceReferences(m_specification, null);
+            if (refs != null) {
+                for (int i = 0; i < refs.length; i++) {
+                    if (m_filter.match(refs[i])) {
+                        Record rec = new Record();
+                        rec.m_ref = refs[i];
+                        m_records.add(rec);
+                    }
+                }
+            }
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+        }
+
+        // Publish available services
+        if (m_records.size() > 0) {
+            if (m_aggregate) {
+                for (int i = 0; i < m_records.size(); i++) {
+                    Record rec = (Record) m_records.get(i);
+                    rec.m_svcObject = m_origin.getService(rec.m_ref);
+                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+                }
+            } else {
+                Record rec = (Record) m_records.get(0);
+                if (rec.m_reg == null) {
+                    rec.m_svcObject = m_origin.getService(rec.m_ref);
+                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+                }
+            }
+        }
+
+        // Register service listener
+        try {
+            m_origin.addServiceListener(this, "(" + Constants.OBJECTCLASS + "=" + m_specification + ")");
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+        }
+
+        m_isValid = isSatisfied();
+    }
+
+    /**
+     * Transform service reference property in a dictionary.
+     * Service.PID and Factory.PID are injected too.
+     * @param ref : the service reference.
+     * @return the dictionary containing all property of the given service reference.
+     */
+    private Dictionary getProps(ServiceReference ref) {
+        Properties prop = new Properties();
+        String[] keys = ref.getPropertyKeys();
+        for (int i = 0; i < keys.length; i++) {
+            prop.put(keys[i], ref.getProperty(keys[i]));
+        }
+
+        prop.put(Constants.SERVICE_PID, m_ps.getManager().getInstanceName());
+        prop.put("factory.pid", m_ps.getManager().getFactory().getName());
+
+        return prop;
+    }
+
+    /**
+     * Stop  method.
+     * Remove the service listener and unregister all exported service.
+     */
+    public synchronized void stop() {
+        m_origin.removeServiceListener(this);
+
+        for (int i = 0; i < m_records.size(); i++) {
+            Record rec = (Record) m_records.get(i);
+            rec.m_svcObject = null;
+            if (rec.m_reg != null) {
+                rec.m_reg.unregister();
+                m_origin.ungetService(rec.m_ref);
+                rec.m_ref = null;
+            }
+        }
+
+        m_records.clear();
+
+    }
+
+    /**
+     * Check exporter validity.
+     * @return true if the exports is optional, or a service is really exported
+     */
+    public boolean isSatisfied() {
+        return m_optional || m_records.size() > 0;
+    }
+
+    /**
+     * Check if a service is published.
+     * @return true if at least one service is published by this handler
+     */
+    public boolean isPublishing() {
+        return m_records.size() > 0;
+    }
+
+    /**
+     * Get the list of records using the given reference.
+     * @param ref : the service reference
+     * @return the list of records using the given reference, empty if no record used this reference
+     */
+    private List/* <Record> */getRecordsByRef(ServiceReference ref) {
+        List l = new ArrayList();
+        for (int i = 0; i < m_records.size(); i++) {
+            Record rec = (Record) m_records.get(i);
+            if (rec.m_ref == ref) {
+                l.add(rec);
+            }
+        }
+        return l;
+    }
+
+    /**
+     * Service Listener Implementation.
+     * @param ev : the service event
+     * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+     */
+    public void serviceChanged(ServiceEvent ev) {
+        if (ev.getType() == ServiceEvent.REGISTERED) {
+            arrivalManagement(ev.getServiceReference());
+        }
+        if (ev.getType() == ServiceEvent.UNREGISTERING) {
+            departureManagement(ev.getServiceReference());
+        }
+
+        if (ev.getType() == ServiceEvent.MODIFIED) {
+            if (m_filter.match(ev.getServiceReference())) {
+                // Test if the ref is always matching with the filter
+                List l = getRecordsByRef(ev.getServiceReference());
+                if (l.size() > 0) { // The ref is already contained => update
+                    // the properties
+                    for (int i = 0; i < l.size(); i++) { // Stop the implied
+                        // record
+                        Record rec = (Record) l.get(i);
+                        if (rec.m_reg != null) {
+                            rec.m_reg.setProperties(getProps(rec.m_ref));
+                        }
+                    }
+                } else { // it is a new mathcing service => add it
+                    arrivalManagement(ev.getServiceReference());
+                }
+            } else {
+                List l = getRecordsByRef(ev.getServiceReference());
+                if (l.size() > 0) { // The ref is already contained => the
+                    // service does no more match
+                    departureManagement(ev.getServiceReference());
+                }
+            }
+        }
+    }
+
+    /**
+     * Manage the arrival of a service.
+     * @param ref : the new service reference.
+     */
+    private synchronized void arrivalManagement(ServiceReference ref) {
+        // Check if the new service match
+        if (m_filter.match(ref)) {
+            // Add it to the record list
+            Record rec = new Record();
+            rec.m_ref = ref;
+            m_records.add(rec);
+            // Publishing ?
+            if (m_records.size() == 1 || m_aggregate) { // If the service is the
+                // first one, or if it
+                // is a multiple imports
+                rec.m_svcObject = m_origin.getService(rec.m_ref);
+                rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+            }
+            // Compute the new state
+            if (!m_isValid && isSatisfied()) {
+                m_isValid = true;
+                m_ps.validating(this);
+            }
+        }
+    }
+
+    /**
+     * Manage the departure of a service.
+     * @param ref : the new service reference.
+     */
+    private synchronized void departureManagement(ServiceReference ref) {
+        List l = getRecordsByRef(ref);
+        for (int i = 0; i < l.size(); i++) { // Stop the implied record
+            Record rec = (Record) l.get(i);
+            if (rec.m_reg != null) {
+                rec.m_svcObject = null;
+                rec.m_reg.unregister();
+                rec.m_reg = null;
+                m_origin.ungetService(rec.m_ref);
+            }
+        }
+        m_records.removeAll(l);
+
+        // Check the validity & if we need to reimport the service
+        if (m_records.size() > 0) {
+            // There is other available services
+            if (!m_aggregate) { // Import the next one
+                Record rec = (Record) m_records.get(0);
+                if (rec.m_svcObject == null) { // It is the first service who
+                    // disappears - create the next
+                    // one
+                    rec.m_svcObject = m_origin.getService(rec.m_ref);
+                    rec.m_reg = m_destination.registerService(m_specification, rec.m_svcObject, getProps(rec.m_ref));
+                }
+            }
+        } else {
+            if (!m_optional) {
+                m_isValid = false;
+                m_ps.invalidating(this);
+            }
+        }
+    }
+
+
+    protected String getSpecification() {
+        return m_specification;
+    }
+
+
+    public String getFilter() {
+        return m_filterStr;
+    }
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java?view=auto&rev=530141
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java Wed Apr 18 12:47:57 2007
@@ -0,0 +1,157 @@
+/* 
+ * 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.composite.service.provides;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+
+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;
+
+/**
+ * Represent a service specification.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class SpecificationMetadata {
+
+    /**
+     * Name of the specification, i.e. name of the interface.
+     */
+    private String m_name;
+
+    /**
+     * List of the method contained in the specification.
+     */
+    private ArrayList/* <MethodMetadata> */m_methods = new ArrayList/* <MethodMetadata> */();
+
+    /**
+     * Is the specificatino an aggregate?
+     */
+    private boolean m_isAggregate;
+
+    /**
+     * Is the specification optional?
+     */
+    private boolean m_isOptional = false;
+
+    /**
+     * Reference on the handler.
+     */
+    private ProvidedServiceHandler m_handler;
+
+    public String getName() {
+        return m_name;
+    }
+
+    public ArrayList/* <MethodMetadata> */getMethods() {
+        return m_methods;
+    }
+
+    /**
+     * 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.
+     */
+    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)) {
+                return met;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Constructor.
+     * @param name : specification name.
+     * @param bc : bundle context.
+     * @param isAggregate : is the specification aggregate.
+     * @param isOptional : is the specification optional.
+     * @param psd : the handler.
+     */
+    public SpecificationMetadata(String name, BundleContext bc, boolean isAggregate, boolean isOptional, ProvidedServiceHandler psd) {
+        m_name = name;
+        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, true);
+            is.close();
+        } catch (IOException e) {
+            m_handler.getManager().getFactory().getLogger().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;
+    }
+
+    public boolean isAggregate() {
+        return m_isAggregate;
+    }
+
+    public boolean isOptional() {
+        return m_isOptional;
+    }
+
+    public void setIsOptional(boolean optional) {
+        m_isOptional = optional;
+    }
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ClassChecker.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ClassChecker.java?view=auto&rev=530141
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ClassChecker.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ClassChecker.java Wed Apr 18 12:47:57 2007
@@ -0,0 +1,213 @@
+/* 
+ * 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.composite.service.provides.manipulation;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+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;
+import org.objectweb.asm.Type;
+
+/**
+ * Check if the class is already manipulated.
+ * 
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ClassChecker implements ClassVisitor, Opcodes {
+
+    /**
+     * True if the class is already manipulated.
+     */
+    private boolean m_isAlreadyManipulated = false;
+
+    /**
+     * Interfaces implemented by the component.
+     */
+    private String[] m_itfs = new String[0];
+
+    /**
+     * Field hashmap [field name, type] discovered in the component class.
+     */
+    private HashMap m_fields = new HashMap();
+
+    /**
+     * Method List of method descriptor discovered in the component class.
+     */
+    private List m_methods = new ArrayList()/* <MethodDesciptor> */;
+
+    /**
+     * Check if the _cm field already exists.
+     * @param access : Field visibility
+     * @param name : Field name
+     * @param desc : Field description
+     * @param signature : Field signature
+     * @param value : field default value (static only)
+     * @return The field visitor for this field
+     * @see org.objectweb.asm.ClassVisitor#visitField(int, java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.Object)
+     */
+    public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
+
+        if (access == ACC_PRIVATE && name.equals("_cm") && desc.equals("Lorg/apache/felix/ipojo/InstanceManager;")) {
+            m_isAlreadyManipulated = true;
+        }
+
+        Type type = Type.getType(desc);
+        if (type.getSort() == Type.ARRAY) {
+            if (type.getInternalName().startsWith("L")) {
+                String internalType = type.getInternalName().substring(1);
+                String nameType = internalType.replace('/', '.');
+                m_fields.put(name, nameType + "[]");
+            } else {
+                String nameType = type.getClassName().substring(0, type.getClassName().length() - 2);
+                m_fields.put(name, nameType + "[]");
+            }
+        } else {
+            m_fields.put(name, type.getClassName());
+        }
+
+        return null;
+    }
+
+    /**
+     * Check if the class is already manipulated.
+     * @return true if the class is already manipulated.
+     */
+    public boolean isalreadyManipulated() {
+        return m_isAlreadyManipulated;
+    }
+
+    /**
+     * Visit a class.
+     * @param version : Bytecode version
+     * @param access : Class visibility
+     * @param name : Class name
+     * @param signature : Class signature
+     * @param superName : Super Class
+     * @param interfaces : Interfaces imlemented by the class
+     * @see org.objectweb.asm.ClassVisitor#visit(int, int, java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String[])
+     */
+    public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
+        // Store the interfaces :
+        m_itfs = interfaces;
+    }
+
+    /**
+     * Visit source.
+     * @param arg0 : 
+     * @param arg1 : 
+     * @see org.objectweb.asm.ClassVisitor#visitSource(java.lang.String, java.lang.String)
+     */
+    public void visitSource(String arg0, String arg1) {
+    }
+
+    /**
+     * Visit a outer class.
+     * @param arg0 : 
+     * @param arg1 : 
+     * @param arg2 :
+     * @see org.objectweb.asm.ClassVisitor#visitOuterClass(java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void visitOuterClass(String arg0, String arg1, String arg2) {
+    }
+
+    /**
+     * Visit an annotation.
+     * @param arg0 : 
+     * @param arg1 : 
+     * @return The annotation visitor (null)
+     * @see org.objectweb.asm.ClassVisitor#visitAnnotation(java.lang.String, boolean)
+     */
+    public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) {
+        return null;
+    }
+
+    /**
+     * Visit an Attribute.
+     * @param arg0 :
+     * @see org.objectweb.asm.ClassVisitor#visitAttribute(org.objectweb.asm.Attribute)
+     */
+    public void visitAttribute(Attribute arg0) {
+    }
+
+    /**
+     * Visit an inner class.
+     * @param arg0 : 
+     * @param arg1 : 
+     * @param arg2 : 
+     * @param arg3 :
+     * @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) {
+    }
+
+    /**
+     * Visit a method.
+     * @param access : Method visibility
+     * @param name : Method name
+     * @param desc : Method description
+     * @param signature : Method signature
+     * @param exceptions : Method exceptions list
+     * @return The method visitor for this method
+     * @see org.objectweb.asm.ClassVisitor#visitMethod(int, java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String[])
+     */
+    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+        return null;
+    }
+
+    /**
+     * End of the visit. 
+     * @see org.objectweb.asm.ClassVisitor#visitEnd()
+     */
+    public void visitEnd() {
+    }
+
+    /**
+     * Get the interfaces implemented by the visited class.
+     * @return the interfaces implemented by the component class.
+     */
+    public String[] getInterfaces() {
+        return m_itfs;
+    }
+
+    /**
+     * Get the field contained in the visited class.
+     * @return the field hashmap [field_name, type].
+     */
+    public HashMap getFields() {
+        return m_fields;
+    }
+
+    /**
+     * Get the list of the method contained in the visited class.
+     * @return the method list of [method, signature].
+     */
+    public List getMethods() {
+        return m_methods;
+    }
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ClassChecker.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ConstructorCodeAdapter.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ConstructorCodeAdapter.java?view=auto&rev=530141
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ConstructorCodeAdapter.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ConstructorCodeAdapter.java Wed Apr 18 12:47:57 2007
@@ -0,0 +1,176 @@
+/* 
+ * 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.composite.service.provides.manipulation;
+
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodAdapter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * Constructor Adapter : add a component manager argument inside a constructor.
+ * 
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class ConstructorCodeAdapter extends MethodAdapter implements Opcodes {
+
+    /**
+     * The owner class of the field. m_owner : String
+     */
+    private String m_owner;
+
+    /**
+     * Is super constructor already invoked?
+     */
+    private boolean m_superDetected;
+
+    /**
+     * PropertyCodeAdapter constructor. A new FiledCodeAdapter should be create
+     * for each method visit.
+     * 
+     * @param mv MethodVisitor
+     * @param owner Name of the class
+     */
+    public ConstructorCodeAdapter(final MethodVisitor mv, final String owner) {
+        super(mv);
+        m_owner = owner;
+        m_superDetected = false;
+    }
+
+    /**
+     * Visit Method for Field instance (GETFIELD).
+     * 
+     * @see org.objectweb.asm.MethodVisitor#visitFieldInsn(int, String, String,
+     * String)
+     * @param opcode : visited operation code
+     * @param owner : owner of the field
+     * @param name : name of the field
+     * @param desc : decriptor of the field
+     */
+    public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) {
+        if (owner.equals(m_owner)) {
+            if (opcode == GETFIELD) {
+                String gDesc = "()" + desc;
+                visitMethodInsn(INVOKEVIRTUAL, owner, "_get" + name, gDesc);
+                return;
+            } else if (opcode == PUTFIELD) {
+                // replaces PUTFIELD f by INVOKESPECIAL _setf
+                String sDesc = "(" + desc + ")V";
+                visitMethodInsn(INVOKESPECIAL, owner, "_set" + name, sDesc);
+                return;
+            }
+        }
+        super.visitFieldInsn(opcode, owner, name, desc);
+    }
+
+    /**
+     * Visit a method instruction.
+     * Insert an invoke on _setComponentManager.
+     * @param opcode : instructino code
+     * @param owner : owning class
+     * @param name : name of the method
+     * @param desc : method description
+     * @see org.objectweb.asm.MethodAdapter#visitMethodInsn(int, java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void visitMethodInsn(int opcode, String owner, String name, String desc) {
+        // A method call is detected, check if it is the super call :
+        if (!m_superDetected) {
+            m_superDetected = true;
+            // The first invocation is the super call
+            // 1) Visit the super constructor :
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitMethodInsn(opcode, owner, name, desc); // Super constructor
+            // invocation
+
+            // 2) Load the object and the component manager argument
+            mv.visitVarInsn(ALOAD, 0);
+            // mv.visitVarInsn(ALOAD,
+            // Type.getArgumentTypes(m_constructorDesc).length);
+            mv.visitVarInsn(ALOAD, 1); // CM is always the first argument
+            // 3) Initialize the field
+            mv.visitMethodInsn(INVOKESPECIAL, m_owner, "_setComponentManager", "(Lorg/apache/felix/ipojo/InstanceManager;)V");
+            // insertion finished
+        } else {
+            mv.visitMethodInsn(opcode, owner, name, desc);
+        }
+    }
+
+    /**
+     * Visit a variable.
+     * @param opcode : instruction code
+     * @param var : visited variable
+     * @see org.objectweb.asm.MethodAdapter#visitVarInsn(int, int)
+     */
+    public void visitVarInsn(int opcode, int var) {
+        if (!m_superDetected) {
+            return; // Do nothing the ALOAD 0 will be injected by
+                    // visitMethodInsn
+        } else {
+            if (var == 0) {
+                mv.visitVarInsn(opcode, var);
+            } else { // ALOAD 0 (THIS)
+                mv.visitVarInsn(opcode, var + 1);
+            } // All other variable count
+        }
+    }
+
+    /**
+     * Visit a variable to increment it.
+     * @param var : incrementied variable
+     * @param increment : increment
+     * @see org.objectweb.asm.MethodAdapter#visitIincInsn(int, int)
+     */
+    public void visitIincInsn(int var, int increment) {
+        if (var != 0) {
+            mv.visitIincInsn(var + 1, increment);
+        } else {
+            mv.visitIincInsn(var, increment);
+        } // Increment the current object ???
+    }
+
+    /**
+     * Visit a local variable.
+     * Add a visit on m_manager.
+     * @param name : variable name
+     * @param desc : variable description
+     * @param signature : variable signature
+     * @param start : start label of the variable definition
+     * @param end : end label of the variable definition
+     * @param index : vairable nuber.
+     * @see org.objectweb.asm.MethodAdapter#visitLocalVariable(java.lang.String, java.lang.String, java.lang.String, org.objectweb.asm.Label, org.objectweb.asm.Label, int)
+     */
+    public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
+        if (index == 0) {
+            mv.visitLocalVariable(name, desc, signature, start, end, index);
+            mv.visitLocalVariable("_manager", "Lorg/apache/felix/ipojo/InstanceManager;", null, start, end, 1);
+        }
+        mv.visitLocalVariable(name, desc, signature, start, end, index + 1);
+    }
+
+    /**
+     * Computer visit max.
+     * Add a local variable.
+     * @param maxStack : stack max size.
+     * @param maxLocals : maximum of visited local variable.
+     * @see org.objectweb.asm.MethodAdapter#visitMaxs(int, int)
+     */
+    public void visitMaxs(int maxStack, int maxLocals) {
+        mv.visitMaxs(maxStack, maxLocals + 1);
+    }
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ConstructorCodeAdapter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ManipulationProperty.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ManipulationProperty.java?view=auto&rev=530141
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ManipulationProperty.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ManipulationProperty.java Wed Apr 18 12:47:57 2007
@@ -0,0 +1,59 @@
+/* 
+ * 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.composite.service.provides.manipulation;
+
+/**
+ * Store properties for the manipulation process.
+ * 
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ * 
+ */
+public class ManipulationProperty {
+
+    /**
+     * iPOJO Package name.
+     */
+    protected static final String IPOJO_PACKAGE_NAME = "org.apache.felix.ipojo";
+
+    /**
+     * Activator internal package name.
+     */
+    protected static final String IPOJO_INTERNAL_PACKAGE_NAME = "org/apache/felix/ipojo/";
+
+    /**
+     * Ipojo internal package name for internal descriptor.
+     */
+    protected static final String IPOJO_INTERNAL_DESCRIPTOR = "L" + IPOJO_INTERNAL_PACKAGE_NAME;
+
+    /**
+     * Helper array for bytecode manipulation of primitive type.
+     */
+    protected static final String[][] PRIMITIVE_BOXING_INFORMATION = new String[][] { 
+        { "V", "ILLEGAL", "ILLEGAL" }, // void type [0]
+        { "Z", "java/lang/Boolean", "booleanValue" }, // boolean [1]
+        { "C", "java/lang/Character", "charValue" }, // char [2]
+        { "B", "java/lang/Byte", "byteValue" }, // byte [3]
+        { "S", "java/lang/Short", "shortValue" }, // short [4]
+        { "I", "java/lang/Integer", "intValue" }, // int [5]
+        { "F", "java/lang/Float", "floatValue" }, // float [6]
+        { "J", "java/lang/Long", "longValue" }, // long [7]
+        { "D", "java/lang/Double", "doubleValue" } // double [8]
+    };
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/ManipulationProperty.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/Manipulator.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/Manipulator.java?view=auto&rev=530141
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/Manipulator.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/Manipulator.java Wed Apr 18 12:47:57 2007
@@ -0,0 +1,117 @@
+/* 
+ * 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.composite.service.provides.manipulation;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+
+/**
+ * iPOJO Bytecode Manipulator.
+ * 
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ * 
+ */
+public class Manipulator {
+    /**
+     * Store the visited fields : [name fo the field, type of the field].
+     */
+    private HashMap m_fields = new HashMap();
+
+    /**
+     * Store the interface implemented by the class.
+     */
+    private String[] m_interfaces = new String[0];
+
+    /**
+     * Return the hashmap [name of the field, type of the field]. This
+     * information is found when the class is manipulated It is a clone of the
+     * original hashmap to avoid modification by handlers
+     * 
+     * @return the hashmap [name of the field, type of the field].
+     */
+    public HashMap getFields() {
+        return m_fields;
+    }
+
+    /**
+     * Return the hashmap [name of the field, type of the field]. This
+     * information is found when the class is manipulated It is a clone of the
+     * original hashmap to avoid modification by handlers
+     * 
+     * @return the hashmap [name of the field, type of the field].
+     */
+    public String[] getInterfaces() {
+        return m_interfaces;
+    }
+
+    /**
+     * Manipulate the given byte array.
+     * 
+     * @param origin : original class.
+     * @return the manipulated class.
+     * @throws IOException : if an error occurs during the manipulation.
+     */
+    public byte[] process(byte[] origin) throws IOException {
+        InputStream is1 = new ByteArrayInputStream(origin);
+
+        // First check if the class is already manipulated :
+        ClassReader ckReader = new ClassReader(is1);
+        ClassChecker ck = new ClassChecker();
+        ckReader.accept(ck, true);
+        is1.close();
+
+        m_fields = ck.getFields();
+
+        // Get interface and remove POJO interface is presents
+        String[] its = ck.getInterfaces();
+        ArrayList l = new ArrayList();
+        for (int i = 0; i < its.length; i++) {
+            l.add(its[i]);
+        }
+        l.remove("org/apache/felix/ipojo/Pojo");
+
+        m_interfaces = new String[l.size()];
+        for (int i = 0; i < m_interfaces.length; i++) {
+            m_interfaces[i] = ((String) l.get(i)).replace('/', '.');
+        }
+
+        ClassWriter finalWriter = null;
+        if (!ck.isalreadyManipulated()) {
+            // Manipulation ->
+            // Add the _setComponentManager method
+            // Instrument all fields
+            InputStream is2 = new ByteArrayInputStream(origin);
+            ClassReader cr0 = new ClassReader(is2);
+            ClassWriter cw0 = new ClassWriter(true);
+            PreprocessClassAdapter preprocess = new PreprocessClassAdapter(cw0);
+            cr0.accept(preprocess, false);
+            is2.close();
+            finalWriter = cw0;
+        }
+        // The file is in the bundle
+        return finalWriter.toByteArray();
+    }
+
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/composite/service/provides/manipulation/Manipulator.java
------------------------------------------------------------------------------
    svn:eol-style = native