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

svn commit: r487682 [4/4] - in /incubator/felix/trunk: ipojo.arch/src/main/java/org/apache/felix/ipojo/arch/ ipojo.plugin/ ipojo.plugin/src/main/java/org/apache/felix/ipojo/manipulation/ ipojo.plugin/src/main/java/org/apache/felix/ipojo/plugin/ ipojo.p...

Modified: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java?view=diff&rev=487682&r1=487681&r2=487682
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java (original)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java Fri Dec 15 13:56:11 2006
@@ -19,14 +19,14 @@
 package org.apache.felix.ipojo.handlers.providedservice;
 
 import java.util.Dictionary;
-import java.util.logging.Level;
 
-import org.apache.felix.ipojo.Activator;
-import org.apache.felix.ipojo.ComponentInfo;
-import org.apache.felix.ipojo.ComponentManagerImpl;
 import org.apache.felix.ipojo.Handler;
-import org.apache.felix.ipojo.PropertyInfo;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.architecture.ComponentDescription;
+import org.apache.felix.ipojo.architecture.PropertyDescription;
 import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Logger;
+import org.osgi.framework.Constants;
 
 /**
  * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
@@ -40,9 +40,9 @@
     private ProvidedService[] m_providedServices = new ProvidedService[0];
 
     /**
-     * The component manager.
+     * The instance manager.
      */
-    private ComponentManagerImpl m_componentManager;
+    private InstanceManager m_manager;
 
     /**
      * Add a provided service to the list .
@@ -64,9 +64,9 @@
     }
 
     /**
-     * @return the component manager.
+     * @return the instance manager.
      */
-    public ComponentManagerImpl getComponentManager() { return m_componentManager; }
+    public InstanceManager getInstanceManager() { return m_manager; }
 
     /**
      * @return the list of the provided service.
@@ -74,17 +74,18 @@
     public ProvidedService[] getProvidedService() { return m_providedServices; }
 
     /**
-     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.ComponentManagerImpl, org.apache.felix.ipojo.metadata.Element)
+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element)
      */
-    public void configure(ComponentManagerImpl cm, Element componentMetadata, Dictionary configuration) {
-        // Fix the component manager & clean the provided service list
-        m_componentManager = cm;
+    public void configure(InstanceManager im, Element componentMetadata, Dictionary configuration) {
+        // Fix the instance manager & clean the provided service list
+        m_manager = im;
 
-        ComponentInfo ci = cm.getComponentInfo();
+        ComponentDescription cd = im.getComponentDescription();
 
         m_providedServices = new ProvidedService[0];
         // Create the dependency according to the component metadata
         Element[] providedServices = componentMetadata.getElements("Provides");
+        Element manipulation = componentMetadata.getElements("Manipulation")[0];
         for (int i = 0; i < providedServices.length; i++) {
             // Create a ProvidedServiceMetadata object
 
@@ -97,7 +98,6 @@
                 serviceSpecification = new String[spec.length];
                 for (int j = 0; j < spec.length; j++) { serviceSpecification[j] = spec[j].trim(); }
             } else {
-                Element manipulation = m_componentManager.getComponentMetatada().getMetadata().getElements("Manipulation")[0];
                 serviceSpecification = new String[manipulation.getElements("Interface").length];
                 for (int j = 0; j < manipulation.getElements("Interface").length; j++) {
                     serviceSpecification[j] = manipulation.getElements("Interface")[j].getAttribute("name");
@@ -105,13 +105,14 @@
             }
 
             // Get the factory policy
-            int factory = ProvidedServiceMetadata.SINGLETON_FACTORY;
+            int factory = ProvidedService.SINGLETON_FACTORY;
             if (providedServices[i].containsAttribute("factory") && providedServices[i].getAttribute("factory").equals("service")) { factory = ProvidedService.SERVICE_FACTORY; }
 
-            // Then create the provided service metadata
-            ProvidedServiceMetadata psm = new ProvidedServiceMetadata(serviceSpecification, factory);
+            // Then create the provided service
+            ProvidedService ps = new ProvidedService(this, serviceSpecification, factory);
 
             Element[] props = providedServices[i].getElements("Property");
+            Property[] properties = new Property[props.length];
             for (int j = 0; j < props.length; j++) {
                 String name = null;
                 if (props[j].containsAttribute("name")) { name = props[j].getAttribute("name"); }
@@ -125,24 +126,29 @@
                 if (name != null && configuration.get(name) != null && configuration.get(name) instanceof String) { value = (String) configuration.get(name); }
                 else { if (field != null &&  configuration.get(field) != null && configuration.get(field) instanceof String) { value = (String) configuration.get(field); } }
 
-                PropertyMetadata pm = new PropertyMetadata(name, field, type, value);
-                psm.addProperty(pm);
+                Property prop = new Property(ps, name, field, type, value, manipulation);
+                properties[j] = prop;
             }
 
-            // Create the provided service object
-            ProvidedService ps = new ProvidedService(this, psm);
-            if (checkProvidedService(ps)) {
+            // Attached to properties to the provided service
+            ps.setProperties(properties);
+            
+            if (checkProvidedService(ps, manipulation)) {
                 addProvidedService(ps);
                 // Change ComponentInfo
-                for (int k = 0; k < ps.getMetadata().getServiceSpecification().length; k++) { ci.addProvidedServiceSpecification(ps.getMetadata().getServiceSpecification()[k]); }
-                for (int k = 0; k < ps.getMetadata().getProperties().length; k++) { ci.addProperty(new PropertyInfo(ps.getMetadata().getProperties()[k].getName(), ps.getMetadata().getProperties()[k].getType(), ps.getMetadata().getProperties()[k].getValue())); }
+                for (int k = 0; k < ps.getServiceSpecification().length; k++) { cd.addProvidedServiceSpecification(ps.getServiceSpecification()[k]); }
+                for (int k = 0; k < ps.getProperties().length; k++) { 
+                	if(!ps.getProperties()[k].getName().equals(Constants.SERVICE_PID) && !ps.getProperties()[k].getName().equals("factory.pid")) {
+                		cd.addProperty(new PropertyDescription(ps.getProperties()[k].getName(), ps.getProperties()[k].getType(), ps.getProperties()[k].getInitialValue())); 
+                	}
+                }
             }
             else {
                 String itfs = "";
                 for (int j = 0; j < serviceSpecification.length; j++) {
                     itfs = itfs + " " + serviceSpecification[j];
                 }
-                Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The provided service" + itfs + " is not valid, it will be removed");
+                m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The provided service" + itfs + " is not valid, it will be removed");
                 ps = null;
             }
 
@@ -156,34 +162,19 @@
                     Property prop = ps.getProperties()[j];
 
                     // Check if the instance configuration has a value for this property
-                    if (prop.getMetadata().getName() != null && configuration.get(prop.getMetadata().getName()) != null && !(configuration.get(prop.getMetadata().getName()) instanceof String)) { prop.set(configuration.get(prop.getMetadata().getName())); }
-                    else { if (prop.getMetadata().getField() != null && configuration.get(prop.getMetadata().getField()) != null && !(configuration.get(prop.getMetadata().getField()) instanceof String)) { prop.set(configuration.get(prop.getMetadata().getField())); } }
+                    if (prop.getName() != null && configuration.get(prop.getName()) != null && !(configuration.get(prop.getName()) instanceof String)) { prop.set(configuration.get(prop.getName())); }
+                    else { if (prop.getField() != null && configuration.get(prop.getField()) != null && !(configuration.get(prop.getField()) instanceof String)) { prop.set(configuration.get(prop.getField())); } }
 
-                    if (prop.getMetadata().getField() != null) {
+                    if (prop.getField() != null) {
                         String[] newFields = new String[fields.length + 1];
                         System.arraycopy(fields, 0, newFields, 0, fields.length);
-                        newFields[fields.length] = prop.getMetadata().getField();
+                        newFields[fields.length] = prop.getField();
                         fields = newFields;
                     }
                 }
             }
 
-            m_componentManager.register(this, fields); }
-    }
-
-    /**
-     * Is the specicifaction s in the list ?
-     * @param s : the specitication to search
-     * @return true if s is in the list
-     */
-    private boolean containsInterface(String s) {
-        Element manipulation = m_componentManager.getComponentMetatada().getMetadata().getElements("Manipulation")[0];
-        for (int i = 0; i < manipulation.getElements("Interface").length; i++) {
-            if (manipulation.getElements("Interface")[i].getAttribute("name").equals(s)) {
-                return true;
-            }
-        }
-        return false;
+            m_manager.register(this, fields); }
     }
 
     /**
@@ -191,25 +182,30 @@
      * @param ps : the provided service to check
      * @return true if the provided service is correct
      */
-    private boolean checkProvidedService(ProvidedService ps) {
+    private boolean checkProvidedService(ProvidedService ps, Element manipulation) {
 
-        for (int i = 0; i < ps.getMetadata().getServiceSpecification().length; i++) {
-            if (!containsInterface(ps.getMetadata().getServiceSpecification()[i])) {
-                Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The service specification " + ps.getMetadata().getServiceSpecification()[i] + " is not implemented by the component class");
-                return false;
+        for (int i = 0; i < ps.getServiceSpecification().length; i++) {
+        	boolean b = false;
+        	for (int ii = 0; ii < manipulation.getElements("Interface").length; ii++) {
+                if (manipulation.getElements("Interface")[ii].getAttribute("name").equals(ps.getServiceSpecification()[i])) {
+                    b = true;
+                }
             }
+        	if(!b) { 
+        		m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] The service specification " + ps.getServiceSpecification()[i] + " is not implemented by the component class");
+        		return false; 
+        	}
+
         }
 
         // Fix internal property type
         for (int i = 0; i < ps.getProperties().length; i++) {
             Property prop = ps.getProperties()[i];
-            String field = prop.getMetadata().getField();
+            String field = prop.getField();
 
             if (field == null) {
-                // Static dependency -> Nothing to check
-                return true;
+                return true; // Static dependency -> Nothing to check
             } else {
-                Element manipulation = getComponentManager().getComponentMetatada().getMetadata().getElements("Manipulation")[0];
                 String type = null;
                 for (int j = 0; j < manipulation.getElements("Field").length; j++) {
                     if (field.equals(manipulation.getElements("Field")[j].getAttribute("name"))) {
@@ -218,26 +214,10 @@
                     }
                 }
                 if (type == null) {
-                    Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] A declared property was not found in the class : " + prop.getMetadata().getField());
+                	m_manager.getFactory().getLogger().log(Logger.ERROR, "[" + m_manager.getClassName() + "] A declared property was not found in the class : " + prop.getField());
                     return false;
                 }
-
-                if (type != null) {
-//                  if (type.endsWith("[]")) {
-//                  Activator.getLogger().log(Level.SEVERE, "[" + m_componentManager.getComponentMetatada().getClassName() + "] An array property was found in the class [Not implemented yet] : " + prop.getMetadata().getField());
-//                  return false;
-//                  }
-
-                    if (prop.getMetadata().getType() == null) { prop.getMetadata().setType(type); }
-
-                    if (!prop.getMetadata().getType().equals(type)) {
-                        Activator.getLogger().log(Level.WARNING, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The field type [" + type + "] and the declared type [" + prop.getMetadata().getType() + "] are not the same for " + prop.getMetadata().getField());
-                        prop.getMetadata().setType(type);
-                    }
-                }
-                else {
-                    Activator.getLogger().log(Level.WARNING, "[" + m_componentManager.getComponentMetatada().getClassName() + "] The declared property " + prop.getMetadata().getField() + "  does not exist in the code");
-                }
+                prop.setType(type); //Set the type
             }
         }
         return true;
@@ -259,8 +239,8 @@
      * @see org.apache.felix.ipojo.Handler#start()
      */
     public void start() {
-        Activator.getLogger().log(Level.INFO, "[" + m_componentManager.getComponentMetatada().getClassName() + "] Start the provided service handler");
-        for (int i = 0; (m_componentManager.getState() == ComponentManagerImpl.VALID) && i < m_providedServices.length; i++) {
+    	m_manager.getFactory().getLogger().log(Logger.INFO, "[" + m_manager.getClassName() + "] Start the provided service handler");
+        for (int i = 0; (m_manager.getState() == InstanceManager.VALID) && i < m_providedServices.length; i++) {
             m_providedServices[i].registerService();
         }
     }
@@ -274,7 +254,7 @@
             ProvidedService ps = m_providedServices[i];
             for (int j = 0; j < ps.getProperties().length; j++) {
                 Property prop = ps.getProperties()[j];
-                if (fieldName.equals(prop.getMetadata().getField())) {
+                if (fieldName.equals(prop.getField())) {
                     // it is the associated property
                     prop.set(value);
                 }
@@ -291,7 +271,7 @@
             ProvidedService ps = m_providedServices[i];
             for (int j = 0; j < ps.getProperties().length; j++) {
                 Property prop = ps.getProperties()[j];
-                if (fieldName.equals(prop.getMetadata().getField())) {
+                if (fieldName.equals(prop.getField())) {
                     // it is the associated property
                     return prop.get();
                 }
@@ -308,13 +288,13 @@
      */
     public void stateChanged(int state) {
         // If the new state is UNRESOLVED => unregister all the services
-        if (state == ComponentManagerImpl.INVALID) {
+        if (state == InstanceManager.INVALID) {
             stop();
             return;
         }
 
         // If the new state is VALID => regiter all the services
-        if (state == ComponentManagerImpl.VALID) {
+        if (state == InstanceManager.VALID) {
             start();
             return;
         }

Modified: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java?view=diff&rev=487682&r1=487681&r2=487682
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java (original)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java Fri Dec 15 13:56:11 2006
@@ -113,7 +113,7 @@
     }
 
     /**
-     * Parse the given dictionnary and create the components manager.
+     * Parse the given dictionnary and create the instance managers.
      * @param dict : the given headers of the manifest file
      * @throws ParseException : if any error occurs
      */

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/util/Callback.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/util/Callback.java?view=auto&rev=487682
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/util/Callback.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/util/Callback.java Fri Dec 15 13:56:11 2006
@@ -0,0 +1,156 @@
+/* 
+ * 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.util;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.felix.ipojo.InstanceManager;
+
+
+
+/**
+ * A callback allows calling a method on the component instances.
+ * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
+ */
+public class Callback {
+
+    /**
+     * Name of the method to call.
+     */
+    private String m_method;
+
+    /**
+     * Is the method a static method ?
+     */
+    private boolean m_isStatic;
+
+    /**
+     * Reference on the instance manager.
+     */
+    private InstanceManager m_manager;
+
+    /**
+     * LifecycleCallback constructor.
+     * @param method : the name of the method to call
+     * @param isStatic : is the method a static method
+     * @param im : the instance manager of the component containing the method
+     */
+    public Callback(String method, boolean isStatic, InstanceManager im) {
+        m_method = method;
+        m_isStatic = isStatic;
+        m_manager = im;
+    }
+
+    /**
+     * Call the method.
+     * @throws NoSuchMethodException : Method is not found in the class
+     * @throws InvocationTargetException : The method is not static
+     * @throws IllegalAccessException : The method can not be invoked
+     */
+    public void call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	m_manager.getFactory().getLogger().log(Logger.INFO, "[" + m_manager.getClassName() + "] Call an callback method : " + m_method);
+        Method method = m_manager.getClazz().getMethod(m_method, new Class[] {});
+        method.setAccessible(true);
+
+        if (m_isStatic) { method.invoke(null, new Object[]{}); }
+        else {
+            // Two cases :
+            // - if instances already exists : call on each instances
+            // - if no instance exists : create an instance
+            if (m_manager.getPojoObjects().length == 0) {
+            	m_manager.getFactory().getLogger().log(Logger.INFO, "[" + m_manager.getClassName() + "] Create the first instance " + m_manager.getPojoObject());
+                method.invoke(m_manager.getPojoObject(), new Object[]{});
+            } else {
+                for (int i = 0; i < m_manager.getPojoObjects().length; i++) {
+                	m_manager.getFactory().getLogger().log(Logger.INFO, "[" + m_manager.getClassName() + "] Call the callback on the instance " + m_manager.getPojoObjects()[i]);
+                    method.invoke(m_manager.getPojoObjects()[i], new Object[]{});
+                }
+            }
+        }
+    }
+
+    /**
+     * Call the current callback method on the instance given in parameter.
+     * @param instance : instance on which call the callbakc
+     * @throws NoSuchMethodException : the method was not found
+     * @throws IllegalAccessException : the method cannont be called
+     * @throws InvocationTargetException : an error happens in the method
+     */
+    public void call(Object instance) throws NoSuchMethodException,
+            IllegalAccessException, InvocationTargetException {
+        Method method = m_manager.getClazz().getMethod(m_method, new Class[] {});
+        method.setAccessible(true);
+        method.invoke(instance, new Object[] {});
+    }
+
+    /**
+     * Call the callback on the method with the argument given in parameter.
+     * @param arg : the parameters
+     * @throws NoSuchMethodException : the callback method is not found
+     * @throws IllegalAccessException : the callbback method cannot be called
+     * @throws InvocationTargetException : an error occurs inside the called method
+     */
+    public void call(Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    	m_manager.getFactory().getLogger().log(Logger.INFO, "[" + m_manager.getClassName() + "] Call an callback method : " + m_method);
+
+        // Build an array of call for arg :
+        Class[] classes = new Class[arg.length];
+        for (int i = 0; i < arg.length; i++) {
+            classes[i] = arg[i].getClass();
+        }
+        Method method = m_manager.getClazz().getMethod(m_method, classes);
+        method.setAccessible(true);
+
+        if (m_isStatic) { method.invoke(null, arg); }
+        else {
+            // Two cases :
+            // - if instances already exists : call on each instances
+            // - if no instance exists : create an instance
+            if (m_manager.getPojoObjects().length == 0) {
+                m_manager.getFactory().getLogger().log(Logger.INFO, "[" + m_manager.getClassName() + "] Create the first instance " + m_manager.getPojoObject());
+                method.invoke(m_manager.getPojoObject(), new Object[]{});
+            } else {
+                for (int i = 0; i < m_manager.getPojoObjects().length; i++) {
+                    method.invoke(m_manager.getPojoObjects()[i], arg);
+                }
+            }
+        }
+    }
+
+    /**
+     * Call the callback on the method with the argument given in parameter and with the arguments given in parameter too.
+     * @param instance : instance on which call the callback
+     * @param arg : the argument array
+     * @throws NoSuchMethodException : the callback method is not found
+     * @throws IllegalAccessException : the callbback method cannot be called
+     * @throws InvocationTargetException : an error occurs inside the called method
+     */
+    public void call(Object instance, Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+        // Build an array of call for arg :
+        Class[] classes = new Class[arg.length];
+        for (int i = 0; i < arg.length; i++) {
+            classes[i] = arg[i].getClass();
+        }
+
+        Method method = m_manager.getClazz().getMethod(m_method, classes);
+        method.setAccessible(true);
+        method.invoke(instance, arg);
+    }
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/util/Callback.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/util/Logger.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/util/Logger.java?view=auto&rev=487682
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/util/Logger.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/util/Logger.java Fri Dec 15 13:56:11 2006
@@ -0,0 +1,112 @@
+/* 
+ * 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.util;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+
+public class Logger implements ServiceListener{
+	
+	public static final int ERROR = 1;
+    public static final int WARNING = 2;
+    public static final int INFO = 3;
+    public static final int DEBUG = 4;
+    
+    private BundleContext m_context;
+    private ServiceReference m_ref;
+    private LogService m_log;
+    
+    private String m_name;
+    private int m_level;
+    
+    public Logger(BundleContext bc, String name, int level) { 
+    	m_name = name;
+    	m_level = level;
+    	m_context = bc;
+    	
+    	m_ref = m_context.getServiceReference(LogService.class.getName());
+    	if(m_ref != null) { m_log = (LogService) m_context.getService(m_ref); }
+    	
+    	try {
+			m_context.addServiceListener(this, "(objectClass="+LogService.class.getName() + ")");
+		} catch (InvalidSyntaxException e) { e.printStackTrace(); }
+    }
+    
+    public void log(int level, String msg) {
+    	if(m_level >= level) {
+    		synchronized(this) { _log(level, msg, null); }
+    	}
+    }
+    
+    public void log(int level, String msg, Throwable ex) {
+    	if(m_level >= level) { 
+    		synchronized(this) {_log(level, msg, ex); }
+    	}
+    }
+    
+    private void _log(int level, String msg, Throwable ex)
+    {
+        String s = msg;
+        s = (ex == null) ? s : s + " (" + ex.getMessage() + ")";
+        String message;
+        switch (level)
+        {
+            case DEBUG:
+            	message = "[" + m_name + "] DEBUG: " + s;
+            	if(m_log != null) { m_log.log(LogService.LOG_DEBUG, message); }
+                System.err.println(message);
+                break;
+            case ERROR:
+            	message = "[" + m_name + "] ERROR: " + s;
+            	if(m_log != null) { m_log.log(LogService.LOG_ERROR, message); }
+                System.err.println(message);
+                break;
+            case INFO:
+                message = "[" + m_name + "] INFO: " + s;
+                if(m_log != null) { m_log.log(LogService.LOG_INFO, message); }
+            	System.err.println(message);
+                break;
+            case WARNING:
+            	message = "[" + m_name + "] WARNING: " + s;
+            	if(m_log != null) { m_log.log(LogService.LOG_WARNING, message); }
+                System.err.println(message);
+                break;
+            default:
+                System.err.println("[" + m_name + "] UNKNOWN[" + level + "]: " + s);
+        }
+    }
+
+	public void serviceChanged(ServiceEvent ev) {
+		if(ev.getType() == ServiceEvent.REGISTERED && m_ref == null) {
+			m_ref = ev.getServiceReference();
+			m_log = (LogService) m_context.getService(m_ref);
+		}
+		if(ev.getType() == ServiceEvent.UNREGISTERING && m_ref == ev.getServiceReference()) {
+			m_context.ungetService(m_ref);
+			m_log = null;
+			m_ref = m_context.getServiceReference(LogService.class.getName());
+	    	if(m_ref != null) { m_log = (LogService) m_context.getService(m_ref); }
+		}
+		
+	}
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/apache/felix/ipojo/util/Logger.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogEntry.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogEntry.java?view=auto&rev=487682
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogEntry.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogEntry.java Fri Dec 15 13:56:11 2006
@@ -0,0 +1,109 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.log/src/org/osgi/service/log/LogEntry.java,v 1.9 2006/06/16 16:31:49 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.log;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Provides methods to access the information contained in an individual Log
+ * Service log entry.
+ * 
+ * <p>
+ * A <code>LogEntry</code> object may be acquired from the
+ * <code>LogReaderService.getLog</code> method or by registering a
+ * <code>LogListener</code> object.
+ * 
+ * @version $Revision: 1.9 $
+ * @see LogReaderService#getLog
+ * @see LogListener
+ */
+public interface LogEntry {
+	/**
+	 * Returns the bundle that created this <code>LogEntry</code> object.
+	 * 
+	 * @return The bundle that created this <code>LogEntry</code> object;
+	 *         <code>null</code> if no bundle is associated with this
+	 *         <code>LogEntry</code> object.
+	 */
+	public Bundle getBundle();
+
+	/**
+	 * Returns the <code>ServiceReference</code> object for the service associated
+	 * with this <code>LogEntry</code> object.
+	 * 
+	 * @return <code>ServiceReference</code> object for the service associated
+	 *         with this <code>LogEntry</code> object; <code>null</code> if no
+	 *         <code>ServiceReference</code> object was provided.
+	 */
+	public ServiceReference getServiceReference();
+
+	/**
+	 * Returns the severity level of this <code>LogEntry</code> object.
+	 * 
+	 * <p>
+	 * This is one of the severity levels defined by the <code>LogService</code>
+	 * interface.
+	 * 
+	 * @return Severity level of this <code>LogEntry</code> object.
+	 * 
+	 * @see LogService#LOG_ERROR
+	 * @see LogService#LOG_WARNING
+	 * @see LogService#LOG_INFO
+	 * @see LogService#LOG_DEBUG
+	 */
+	public int getLevel();
+
+	/**
+	 * Returns the human readable message associated with this <code>LogEntry</code>
+	 * object.
+	 * 
+	 * @return <code>String</code> containing the message associated with this
+	 *         <code>LogEntry</code> object.
+	 */
+	public String getMessage();
+
+	/**
+	 * Returns the exception object associated with this <code>LogEntry</code>
+	 * object.
+	 * 
+	 * <p>
+	 * In some implementations, the returned exception may not be the original
+	 * exception. To avoid references to a bundle defined exception class, thus
+	 * preventing an uninstalled bundle from being garbage collected, the Log
+	 * Service may return an exception object of an implementation defined
+	 * Throwable subclass. The returned object will attempt to provide as much
+	 * information as possible from the original exception object such as the
+	 * message and stack trace.
+	 * 
+	 * @return <code>Throwable</code> object of the exception associated with this
+	 *         <code>LogEntry</code>;<code>null</code> if no exception is
+	 *         associated with this <code>LogEntry</code> object.
+	 */
+	public Throwable getException();
+
+	/**
+	 * Returns the value of <code>currentTimeMillis()</code> at the time this
+	 * <code>LogEntry</code> object was created.
+	 * 
+	 * @return The system time in milliseconds when this <code>LogEntry</code>
+	 *         object was created.
+	 * @see "System.currentTimeMillis()"
+	 */
+	public long getTime();
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogEntry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogListener.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogListener.java?view=auto&rev=487682
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogListener.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogListener.java Fri Dec 15 13:56:11 2006
@@ -0,0 +1,51 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.log/src/org/osgi/service/log/LogListener.java,v 1.9 2006/06/16 16:31:49 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.log;
+
+import java.util.EventListener;
+
+/**
+ * Subscribes to <code>LogEntry</code> objects from the <code>LogReaderService</code>.
+ * 
+ * <p>
+ * A <code>LogListener</code> object may be registered with the Log Reader Service
+ * using the <code>LogReaderService.addLogListener</code> method. After the
+ * listener is registered, the <code>logged</code> method will be called for each
+ * <code>LogEntry</code> object created. The <code>LogListener</code> object may be
+ * unregistered by calling the <code>LogReaderService.removeLogListener</code>
+ * method.
+ * 
+ * @version $Revision: 1.9 $
+ * @see LogReaderService
+ * @see LogEntry
+ * @see LogReaderService#addLogListener(LogListener)
+ * @see LogReaderService#removeLogListener(LogListener)
+ */
+public interface LogListener extends EventListener {
+	/**
+	 * Listener method called for each LogEntry object created.
+	 * 
+	 * <p>
+	 * As with all event listeners, this method should return to its caller as
+	 * soon as possible.
+	 * 
+	 * @param entry A <code>LogEntry</code> object containing log information.
+	 * @see LogEntry
+	 */
+	public void logged(LogEntry entry);
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogReaderService.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogReaderService.java?view=auto&rev=487682
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogReaderService.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogReaderService.java Fri Dec 15 13:56:11 2006
@@ -0,0 +1,98 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.log/src/org/osgi/service/log/LogReaderService.java,v 1.10 2006/06/16 16:31:49 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.log;
+
+import java.util.Enumeration;
+
+/**
+ * Provides methods to retrieve <code>LogEntry</code> objects from the log.
+ * <p>
+ * There are two ways to retrieve <code>LogEntry</code> objects:
+ * <ul>
+ * <li>The primary way to retrieve <code>LogEntry</code> objects is to register a
+ * <code>LogListener</code> object whose <code>LogListener.logged</code> method will
+ * be called for each entry added to the log.
+ * <li>To retrieve past <code>LogEntry</code> objects, the <code>getLog</code>
+ * method can be called which will return an <code>Enumeration</code> of all
+ * <code>LogEntry</code> objects in the log.
+ * 
+ * @version $Revision: 1.10 $
+ * @see LogEntry
+ * @see LogListener
+ * @see LogListener#logged(LogEntry)
+ */
+public interface LogReaderService {
+	/**
+	 * Subscribes to <code>LogEntry</code> objects.
+	 * 
+	 * <p>
+	 * This method registers a <code>LogListener</code> object with the Log Reader
+	 * Service. The <code>LogListener.logged(LogEntry)</code> method will be
+	 * called for each <code>LogEntry</code> object placed into the log.
+	 * 
+	 * <p>
+	 * When a bundle which registers a <code>LogListener</code> object is stopped
+	 * or otherwise releases the Log Reader Service, the Log Reader Service must
+	 * remove all of the bundle's listeners.
+	 * 
+	 * <p>
+	 * If this Log Reader Service's list of listeners already contains a
+	 * listener <code>l</code> such that <code>(l==listener)</code>, this method
+	 * does nothing.
+	 * 
+	 * @param listener A <code>LogListener</code> object to register; the
+	 *        <code>LogListener</code> object is used to receive <code>LogEntry</code>
+	 *        objects.
+	 * @see LogListener
+	 * @see LogEntry
+	 * @see LogListener#logged(LogEntry)
+	 */
+	public void addLogListener(LogListener listener);
+
+	/**
+	 * Unsubscribes to <code>LogEntry</code> objects.
+	 * 
+	 * <p>
+	 * This method unregisters a <code>LogListener</code> object from the Log
+	 * Reader Service.
+	 * 
+	 * <p>
+	 * If <code>listener</code> is not contained in this Log Reader Service's list
+	 * of listeners, this method does nothing.
+	 * 
+	 * @param listener A <code>LogListener</code> object to unregister.
+	 * @see LogListener
+	 */
+	public void removeLogListener(LogListener listener);
+
+	/**
+	 * Returns an <code>Enumeration</code> of all <code>LogEntry</code> objects in
+	 * the log.
+	 * 
+	 * <p>
+	 * Each element of the enumeration is a <code>LogEntry</code> object, ordered
+	 * with the most recent entry first. Whether the enumeration is of all
+	 * <code>LogEntry</code> objects since the Log Service was started or some
+	 * recent past is implementation-specific. Also implementation-specific is
+	 * whether informational and debug <code>LogEntry</code> objects are included
+	 * in the enumeration.
+	 * @return An <code>Enumeration</code> of all <code>LogEntry</code> objects in
+	 * the log.
+	 */
+	public Enumeration getLog();
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogReaderService.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogService.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogService.java?view=auto&rev=487682
==============================================================================
--- incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogService.java (added)
+++ incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogService.java Fri Dec 15 13:56:11 2006
@@ -0,0 +1,156 @@
+/*
+ * $Header: /cvshome/build/org.osgi.service.log/src/org/osgi/service/log/LogService.java,v 1.9 2006/06/16 16:31:49 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.service.log;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Provides methods for bundles to write messages to the log.
+ * 
+ * <p>
+ * <code>LogService</code> methods are provided to log messages; optionally with a
+ * <code>ServiceReference</code> object or an exception.
+ * 
+ * <p>
+ * Bundles must log messages in the OSGi environment with a severity level
+ * according to the following hierarchy:
+ * <ol>
+ * <li>{@link #LOG_ERROR}
+ * <li>{@link #LOG_WARNING}
+ * <li>{@link #LOG_INFO}
+ * <li>{@link #LOG_DEBUG}
+ * </ol>
+ * 
+ * @version $Revision: 1.9 $
+ */
+public interface LogService {
+	/**
+	 * An error message (Value 1).
+	 * 
+	 * <p>
+	 * This log entry indicates the bundle or service may not be functional.
+	 */
+	public static final int	LOG_ERROR	= 1;
+	/**
+	 * A warning message (Value 2).
+	 * 
+	 * <p>
+	 * This log entry indicates a bundle or service is still functioning but may
+	 * experience problems in the future because of the warning condition.
+	 */
+	public static final int	LOG_WARNING	= 2;
+	/**
+	 * An informational message (Value 3).
+	 * 
+	 * <p>
+	 * This log entry may be the result of any change in the bundle or service
+	 * and does not indicate a problem.
+	 */
+	public static final int	LOG_INFO	= 3;
+	/**
+	 * A debugging message (Value 4).
+	 * 
+	 * <p>
+	 * This log entry is used for problem determination and may be irrelevant to
+	 * anyone but the bundle developer.
+	 */
+	public static final int	LOG_DEBUG	= 4;
+
+	/**
+	 * Logs a message.
+	 * 
+	 * <p>
+	 * The <code>ServiceReference</code> field and the <code>Throwable</code> field
+	 * of the <code>LogEntry</code> object will be set to <code>null</code>.
+	 * 
+	 * @param level The severity of the message. This should be one of the
+	 *        defined log levels but may be any integer that is interpreted in a
+	 *        user defined way.
+	 * @param message Human readable string describing the condition or
+	 *        <code>null</code>.
+	 * @see #LOG_ERROR
+	 * @see #LOG_WARNING
+	 * @see #LOG_INFO
+	 * @see #LOG_DEBUG
+	 */
+	public void log(int level, String message);
+
+	/**
+	 * Logs a message with an exception.
+	 * 
+	 * <p>
+	 * The <code>ServiceReference</code> field of the <code>LogEntry</code> object
+	 * will be set to <code>null</code>.
+	 * 
+	 * @param level The severity of the message. This should be one of the
+	 *        defined log levels but may be any integer that is interpreted in a
+	 *        user defined way.
+	 * @param message The human readable string describing the condition or
+	 *        <code>null</code>.
+	 * @param exception The exception that reflects the condition or
+	 *        <code>null</code>.
+	 * @see #LOG_ERROR
+	 * @see #LOG_WARNING
+	 * @see #LOG_INFO
+	 * @see #LOG_DEBUG
+	 */
+	public void log(int level, String message, Throwable exception);
+
+	/**
+	 * Logs a message associated with a specific <code>ServiceReference</code>
+	 * object.
+	 * 
+	 * <p>
+	 * The <code>Throwable</code> field of the <code>LogEntry</code> will be set to
+	 * <code>null</code>.
+	 * 
+	 * @param sr The <code>ServiceReference</code> object of the service that this
+	 *        message is associated with or <code>null</code>.
+	 * @param level The severity of the message. This should be one of the
+	 *        defined log levels but may be any integer that is interpreted in a
+	 *        user defined way.
+	 * @param message Human readable string describing the condition or
+	 *        <code>null</code>.
+	 * @see #LOG_ERROR
+	 * @see #LOG_WARNING
+	 * @see #LOG_INFO
+	 * @see #LOG_DEBUG
+	 */
+	public void log(ServiceReference sr, int level, String message);
+
+	/**
+	 * Logs a message with an exception associated and a
+	 * <code>ServiceReference</code> object.
+	 * 
+	 * @param sr The <code>ServiceReference</code> object of the service that this
+	 *        message is associated with.
+	 * @param level The severity of the message. This should be one of the
+	 *        defined log levels but may be any integer that is interpreted in a
+	 *        user defined way.
+	 * @param message Human readable string describing the condition or
+	 *        <code>null</code>.
+	 * @param exception The exception that reflects the condition or
+	 *        <code>null</code>.
+	 * @see #LOG_ERROR
+	 * @see #LOG_WARNING
+	 * @see #LOG_INFO
+	 * @see #LOG_DEBUG
+	 */
+	public void log(ServiceReference sr, int level, String message,
+			Throwable exception);
+}

Propchange: incubator/felix/trunk/ipojo/src/main/java/org/osgi/service/log/LogService.java
------------------------------------------------------------------------------
    svn:eol-style = native