You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cl...@apache.org on 2008/10/28 10:35:37 UTC

svn commit: r708492 - in /felix/trunk/ipojo: arch/src/main/java/org/apache/felix/ipojo/arch/ core/ core/src/main/java/org/apache/felix/ipojo/ core/src/main/java/org/apache/felix/ipojo/architecture/ core/src/main/java/org/apache/felix/ipojo/context/ cor...

Author: clement
Date: Tue Oct 28 02:35:36 2008
New Revision: 708492

URL: http://svn.apache.org/viewvc?rev=708492&view=rev
Log:
Fix issue Felix-796.
Define the "ipojo.internal.dispatcher" property (true or false) enabling / disabling the internal event dispatcher. This property can also be set from the iPOJO bundle manifest (ipojo-internal-dispatcher entry).

Refactor some code to prepare next improvements and fix cosmetic bugs.

Modified:
    felix/trunk/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java
    felix/trunk/ipojo/core/   (props changed)
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/EventDispatcher.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistry.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java
    felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java
    felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/EventUtil.java
    felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherMetadata.java
    felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberMetadata.java
    felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/DynamicMBeanImpl.java
    felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/MBeanHandler.java
    felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/MethodField.java
    felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/PropertyField.java

Modified: felix/trunk/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java (original)
+++ felix/trunk/ipojo/arch/src/main/java/org/apache/felix/ipojo/arch/ArchCommandImpl.java Tue Oct 28 02:35:36 2008
@@ -123,7 +123,7 @@
      */
     private void printStats(PrintStream out) {
         try {
-            Field field = IPojoFactory.class.getDeclaredField("m_instancesName");
+            Field field = IPojoFactory.class.getDeclaredField("INSTANCE_NAME");
             field.setAccessible(true); // The field is not accessible.
             List names = (List) field.get(null);
             out.println("Number of living instances : " + names.size());

Propchange: felix/trunk/ipojo/core/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Tue Oct 28 02:35:36 2008
@@ -20,3 +20,4 @@
 *.patch
 .externalToolBuilders
 maven-eclipse.xml
+.fbprefs

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/EventDispatcher.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/EventDispatcher.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/EventDispatcher.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/EventDispatcher.java Tue Oct 28 02:35:36 2008
@@ -37,7 +37,7 @@
  * @see Extender
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-public class EventDispatcher implements ServiceListener {
+public final class EventDispatcher implements ServiceListener {
     
     /**
      * The internal event dispatcher.
@@ -60,11 +60,34 @@
      * @param bc the bundle context used to register and unregister
      * {@link ServiceListener}.
      */
-    public EventDispatcher(BundleContext bc) {
+    private EventDispatcher(BundleContext bc) {
         m_context = bc;
         m_listeners = new HashMap();
+        // Only one thread can call the start method.
+        m_context.addServiceListener(this);
+    }
+    
+    /**
+     * Creates the internal event
+     * dispatcher.
+     * @param bc the iPOJO bundle context to send to the 
+     * internal event dispatcher.
+     */
+    public static void create(BundleContext bc) {
+        m_dispatcher = new EventDispatcher(bc);
+    }
+    
+    /**
+     * Stops and delete the internal event dispatcher.
+     * This method must be call only
+     * if iPOJO is stopping.
+     */
+    public static void dispose() {
+        m_dispatcher.stop();
+        m_dispatcher = null;
     }
     
+    
     /**
      * Gets the iPOJO event dispatcher.
      * @return the event dispatcher or
@@ -74,17 +97,6 @@
         return m_dispatcher;
     }
     
-    /**
-     * Starts the event dispatcher.
-     * This method sets the {@link EventDispatcher#m_dispatcher}.
-     * This method also registers the iPOJO {@link ServiceListener}
-     * receiving events to dispatch them to iPOJO instances.
-     */
-    public void start() {
-        // Only one thread can call the start method.
-        m_context.addServiceListener(this);
-        m_dispatcher = this; // Set the dispatcher.
-    }
     
     /**
      * Stops the event dispatcher.
@@ -92,9 +104,8 @@
      * This methods must be called only when the iPOJO bundle
      * stops.
      */
-    public void stop() {
+    private void stop() {
         synchronized (this) {
-            m_dispatcher = null; 
             m_context.removeServiceListener(this);
             m_listeners.clear();
         }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/Extender.java Tue Oct 28 02:35:36 2008
@@ -56,7 +56,13 @@
      * This internal dispatcher helps the OSGi framework to support large
      * scale applications. The internal dispatcher is disabled by default.
      */
-    protected static final boolean DISPATCHER_ENABLED = false;
+    protected static boolean DISPATCHER_ENABLED = true;
+    
+    /**
+     * Property allowing to set if the internal dispatcher is enabled or disabled.
+     * Possible value are either <code>true</code> or <code>false</code>.
+     */
+    private static final String ENABLING_DISPATCHER = "ipojo.internal.dispatcher";
     
     /**
      * iPOJO Component Type and Instance declaration header.
@@ -104,11 +110,6 @@
      * The thread analyzing arriving bundles and creating iPOJO contributions.
      */
     private final CreatorThread m_thread = new CreatorThread();
-    
-    /**
-     * The internal iPOJO dispatcher.
-     */
-    private EventDispatcher m_dispatcher;
 
     /**
      * Bundle Listener Notification.
@@ -281,9 +282,13 @@
 
         m_logger = new Logger(m_context, "IPOJO-Extender");
         
-        m_dispatcher = new EventDispatcher(context);
-        m_dispatcher.start();
-
+        enablingDispatcher(context, m_logger);
+        
+        // Create the dispatcher only if required.
+        if (DISPATCHER_ENABLED) {
+            EventDispatcher.create(context);
+        }
+        
         // Begin by initializing core handlers
         startManagementFor(m_bundle);
         
@@ -309,7 +314,10 @@
     public void stop(BundleContext context) {
         m_thread.stop(); // Stop the thread processing bundles.
         m_context.removeBundleListener(this);
-        m_dispatcher.stop();
+        
+        if (DISPATCHER_ENABLED) {
+            EventDispatcher.dispose();
+        }
 
         for (int k = 0; k < m_factoryTypes.size(); k++) {
             ManagedAbstractFactoryType mft = (ManagedAbstractFactoryType) m_factoryTypes.get(k);
@@ -331,6 +339,41 @@
         m_factoryTypes = null;
         m_creator = null;
     }
+    
+    /**
+     * Enables or disables the internal dispatcher, so sets the
+     * {@link Extender#DISPATCHER_ENABLED} flag.
+     * This method checks if the {@link Extender#ENABLING_DISPATCHER}
+     * property is set to <code>true</code>. Otherwise, the internal
+     * dispatcher is disabled. The property can be set as a system
+     * property (<code>ipojo.internal.dispatcher</code>) or inside the
+     * iPOJO bundle manifest (<code>ipojo-internal-dispatcher</code>).
+     * @param context the bundle context.
+     * @param logger the logger to indicates if the internal dispatcher is set.
+     */
+    private static void enablingDispatcher(BundleContext context, Logger logger) {
+        // First check in the framework and in the system properties
+        String flag = context.getProperty(ENABLING_DISPATCHER);
+        
+        // If null, look in bundle manifest
+        if (flag == null) {
+            String key = ENABLING_DISPATCHER.replace('.', '-');
+            flag = (String) context.getBundle().getHeaders().get(key);
+        }
+        
+        if (flag != null) {
+            if (flag.equalsIgnoreCase("true")) {
+                Extender.DISPATCHER_ENABLED = true;
+                logger.log(Logger.INFO, "iPOJO Internal Event Dispatcher enables");
+                return;
+            }
+        }
+        
+        // Either l is null, or the specified value was false
+        Extender.DISPATCHER_ENABLED = false;
+        logger.log(Logger.INFO, "iPOJO Internal Event Dispatcher disables");
+        
+    }
 
     /**
      * Adds a component factory to the factory list.
@@ -402,7 +445,7 @@
     /**
      * Structure storing an iPOJO extension.
      */
-    private final class ManagedAbstractFactoryType {
+    private static final class ManagedAbstractFactoryType {
         /**
          * The type (i.e.) name of the extension.
          */
@@ -440,7 +483,7 @@
      * Structure storing unbound component type declarations.
      * Unbound means that there is no extension able to manage the extension.
      */
-    private final class UnboundComponentType {
+    private static final class UnboundComponentType {
         /**
          * The component type description.
          */
@@ -594,7 +637,11 @@
          */
         public void run() {
             m_logger.log(Logger.INFO, "Creator thread is starting");
-            while (m_started) {
+            boolean started;
+            synchronized (this) {
+                started = m_started;
+            }
+            while (started) {
                 Bundle bundle;
                 synchronized (this) {
                     while (m_started && m_bundles.isEmpty()) {
@@ -624,6 +671,9 @@
                     // To be sure to not kill the thread, we catch all exceptions and errors
                     m_logger.log(Logger.ERROR, "An error occurs when analyzing the content or starting the management of " + bundle.getBundleId(), e);
                 }
+                synchronized (this) {
+                    started = m_started;
+                }
             }
         }
 

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java Tue Oct 28 02:35:36 2008
@@ -55,13 +55,6 @@
      * The service context used to access to the service registry.
      */
     private ServiceContext m_serviceContext;
-    
-    /**
-     * The internal event dispatcher used to avoid the multiplication
-     * of service listeners. The dispatcher is only used when the service context is
-     * not specified and if the internal dispatching is enabled ({@link Extender#DISPATCHER_ENABLED}
-     */
-    private EventDispatcher m_dispatcher;
 
     /**
      * Creates an iPOJO Context.
@@ -72,7 +65,6 @@
      */
     public IPojoContext(BundleContext context) {
         m_bundleContext = context;
-        m_dispatcher = EventDispatcher.getDispatcher();
     }
 
     /**
@@ -86,7 +78,6 @@
     public IPojoContext(BundleContext bundleContext, ServiceContext serviceContext) {
         m_bundleContext = bundleContext;
         m_serviceContext = serviceContext;
-        m_dispatcher = EventDispatcher.getDispatcher();
     }
 
     /**
@@ -122,10 +113,11 @@
      */
     public void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException {
         if (m_serviceContext == null) {
-            if (Extender.DISPATCHER_ENABLED) {
+            EventDispatcher dispatcher = EventDispatcher.getDispatcher();
+            if (dispatcher != null) { // getDispatcher returns null if not enable.
                 String itf = match(filter);
                 if (itf != null) {
-                    m_dispatcher.addListener(itf, listener);
+                    dispatcher.addListener(itf, listener);
                 } else {
                     m_bundleContext.addServiceListener(listener, filter);
                 }
@@ -394,7 +386,8 @@
      */
     public void removeServiceListener(ServiceListener listener) {
         if (m_serviceContext == null) {
-            if (! Extender.DISPATCHER_ENABLED || ! m_dispatcher.removeListener(listener)) {
+            EventDispatcher dispatcher = EventDispatcher.getDispatcher();
+            if (dispatcher == null || ! dispatcher.removeListener(listener)) {
                 m_bundleContext.removeServiceListener(listener);
             }
         } else {

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java Tue Oct 28 02:35:36 2008
@@ -54,7 +54,7 @@
      * This list is shared by all factories and is
      * used to assert name unicity.
      */
-    protected static List m_instancesName = new ArrayList();
+    protected static final List INSTANCE_NAME = new ArrayList();
 
     /**
      * The component type description exposed by the {@link Factory} service.
@@ -267,7 +267,7 @@
                 getLogger().log(Logger.WARNING, "The 'name' (" + name + ") attribute, used as the instance name, is deprecated, please use the 'instance.name' attribute");
                 configuration.put("instance.name", name);
             }
-            if (m_instancesName.contains(name)) {
+            if (INSTANCE_NAME.contains(name)) {
                 m_logger.log(Logger.ERROR, "The configuration is not acceptable : Name already used");
                 throw new UnacceptableConfiguration(getFactoryName() + " : Name already used : " + name);
             }
@@ -281,7 +281,7 @@
 
         try {
             ComponentInstance instance = createInstance(configuration, context, handlers); // This method is called with the lock.
-            m_instancesName.add(name);
+            INSTANCE_NAME.add(name);
             m_componentInstances.put(name, instance);
             return instance;
         } catch (ConfigurationException e) {
@@ -616,7 +616,7 @@
      * @see org.osgi.service.cm.ManagedServiceFactory#deleted(java.lang.String)
      */
     public synchronized void deleted(String name) {
-        m_instancesName.remove(name);
+        INSTANCE_NAME.remove(name);
         ComponentInstance instance = (ComponentInstance) m_componentInstances.remove(name);
         if (instance != null) {
             instance.dispose();
@@ -630,7 +630,7 @@
     public void disposed(ComponentInstance instance) {
         String name = instance.getInstanceName();
         synchronized (this) {
-            m_instancesName.remove(name);
+            INSTANCE_NAME.remove(name);
             m_componentInstances.remove(name);
         }
     }
@@ -712,7 +712,7 @@
                     if (instance.getState() != ComponentInstance.DISPOSED) {
                         instance.dispose();
                     }
-                    m_instancesName.remove(instance.getInstanceName());
+                    INSTANCE_NAME.remove(instance.getInstanceName());
                 }
 
                 m_componentInstances.clear();
@@ -781,7 +781,7 @@
      */
     protected String generateName() {
         String name = m_factoryName + "-" + m_index;
-        while (m_instancesName.contains(name)) {
+        while (INSTANCE_NAME.contains(name)) {
             m_index = m_index + 1;
             name = m_factoryName + "-" + m_index;
         }
@@ -849,6 +849,16 @@
             }
 
         }
+        
+        /**
+         * Hashcode method.
+         * This method delegates to the {@link Object#hashCode()}.
+         * @return the object hashcode.
+         * @see java.lang.Object#hashCode()
+         */
+        public int hashCode() {
+            return super.hashCode();
+        }
 
         /**
          * Gets the factory object used for this handler. 

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java Tue Oct 28 02:35:36 2008
@@ -70,6 +70,7 @@
     /**
      * Gets the implementation class of this component type.
      * @return the component type implementation class name.
+     * @deprecated
      */
     public String getClassName() {
         return m_factory.getClassName();

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistry.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistry.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistry.java Tue Oct 28 02:35:36 2008
@@ -68,7 +68,7 @@
     /**
      * Listener info structure.
      */
-    private class ListenerInfo {
+    private static class ListenerInfo {
         /**
          * Listener object.
          */

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java Tue Oct 28 02:35:36 2008
@@ -18,8 +18,10 @@
  */
 package org.apache.felix.ipojo.handlers.configuration;
 
+import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.Enumeration;
+import java.util.List;
 import java.util.Properties;
 
 import org.apache.felix.ipojo.ConfigurationException;
@@ -47,7 +49,7 @@
     /**
      * List of the configurable fields.
      */
-    private Property[] m_configurableProperties = new Property[0];
+    private List/*<Property>*/ m_configurableProperties = new ArrayList(1);
 
     /**
      * ProvidedServiceHandler of the component. It is useful to propagate
@@ -137,9 +139,6 @@
                     if (method[0].getMethodArguments().length != 1) {
                         throw new ConfigurationException("Malformed property :  The method " + methodName + " does not have one argument");
                     }
-                    if (type != null && !type.equals(method[0].getMethodArguments()[0])) {
-                        throw new ConfigurationException("Malformed property :   The field type (" + type + ") and the type of the argument of the setter method (" + method[0].getMethodArguments()[0] + ") are not the same.");
-                    }
                     type = method[0].getMethodArguments()[0];
                     configurables[i].addAttribute(new Attribute("type", type)); // Add the type to avoid configure checking
                 }
@@ -166,18 +165,16 @@
     }
 
     /**
-     * Configure the handler.
-     * 
-     * @param metadata : the metadata of the component
-     * @param configuration : the instance configuration
-     * @throws ConfigurationException : one property metadata is not correct 
+     * Configures the handler.
+     * Access to field does not require synchronization as this method is executed
+     * before any thread access to this object.
+     * @param metadata the metadata of the component
+     * @param configuration the instance configuration
+     * @throws ConfigurationException one property metadata is not correct 
      * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager,
      * org.apache.felix.ipojo.metadata.Element)
      */
     public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
-        // Store the component manager
-        m_configurableProperties = new Property[0];
-
         // Build the map
         Element[] confs = metadata.getElements("Properties", "");
         Element[] configurables = confs[0].getElements("Property");
@@ -251,8 +248,9 @@
 
         // Propagation
         if (m_mustPropagate) {
-            for (int i = 0; i < m_configurableProperties.length; i++) {
-                m_toPropagate.put(m_configurableProperties[i].getName(), m_configurableProperties[i].getValue());
+            for (int i = 0; i < m_configurableProperties.size(); i++) {
+                Property prop = (Property) m_configurableProperties.get(i);
+                m_toPropagate.put(prop.getName(), prop.getValue());
             }
             reconfigure(m_toPropagate);
         }
@@ -283,34 +281,23 @@
 //    }
 
     /**
-     * Add the given property metadata to the property metadata list.
+     * Adds the given property metadata to the property metadata list.
      * 
      * @param prop : property metadata to add
      */
     protected void addProperty(Property prop) {
-        for (int i = 0; (m_configurableProperties != null) && (i < m_configurableProperties.length); i++) {
-            if (m_configurableProperties[i].getName().equals(prop.getName())) { return; }
-        }
-
-        if (m_configurableProperties.length > 0) {
-            Property[] newProp = new Property[m_configurableProperties.length + 1];
-            System.arraycopy(m_configurableProperties, 0, newProp, 0, m_configurableProperties.length);
-            newProp[m_configurableProperties.length] = prop;
-            m_configurableProperties = newProp;
-        } else {
-            m_configurableProperties = new Property[] { prop };
-        }
+        m_configurableProperties.add(prop);
     }
 
     /**
-     * Check if the list contains the property.
+     * Checks if the list contains the property.
      * 
      * @param name : name of the property
      * @return true if the property exist in the list
      */
     protected boolean containsProperty(String name) {
-        for (int i = 0; (m_configurableProperties != null) && (i < m_configurableProperties.length); i++) {
-            if (m_configurableProperties[i].getName().equals(name)) { return true; }
+        for (int i = 0; i < m_configurableProperties.size(); i++) {
+            if (((Property) m_configurableProperties.get(i)).getName().equals(name)) { return true; }
         }
         return false;
     }
@@ -342,30 +329,16 @@
             Object value = configuration.get(name);
             boolean found = false;
             // Check if the name is a configurable property
-            for (int i = 0; i < m_configurableProperties.length; i++) {
-                if (m_configurableProperties[i].getName().equals(name)) {
-                    if (m_configurableProperties[i].hasField()) {
-                        if (m_configurableProperties[i].getValue() == null || ! m_configurableProperties[i].getValue().equals(value)) {
-                            m_configurableProperties[i].setValue(value);
-                            getInstanceManager().onSet(null, m_configurableProperties[i].getField(), m_configurableProperties[i].getValue()); // Notify other handler of the field value change.
-                            if (m_configurableProperties[i].hasMethod()) {
-                                if (getInstanceManager().getPojoObjects() != null) {
-                                    m_configurableProperties[i].invoke(null); // Call on all created pojo objects.
-                                }
-                            }
-                        }
-                    } else if (m_configurableProperties[i].hasMethod()) { // Method but no field
-                        m_configurableProperties[i].setValue(value);
-                        if (getInstanceManager().getPojoObjects() != null) {
-                            m_configurableProperties[i].invoke(null); // Call on all created pojo objects.
-                        }
-                    }
+            for (int i = 0; i < m_configurableProperties.size(); i++) {
+                Property prop = (Property) m_configurableProperties.get(i);
+                if (prop.getName().equals(name)) {
+                    reconfigureProperty(prop, value);
                     found = true;
-                    break;
+                    break; // Exit the search loop
                 }
             }
             if (!found) { 
-                // The property is not a configurable property, at it to the toPropagate list.
+                // The property is not a configurable property, aadd it to the toPropagate list.
                 toPropagate.put(name, value);
             }
         }
@@ -373,6 +346,28 @@
         return toPropagate;
 
     }
+
+    /**
+     * Reconfigures the given property with the given value.
+     * This methods handles {@link InstanceManager#onSet(Object, String, Object)}
+     * call and the callback invocation.
+     * The reconfiguration occurs only if the value changes.
+     * @param prop the property object to reconfigure
+     * @param value the new value.
+     */
+    private void reconfigureProperty(Property prop, Object value) {
+        if (prop.getValue() == null || ! prop.getValue().equals(value)) {
+            prop.setValue(value);
+            if (prop.hasField()) {
+                getInstanceManager().onSet(null, prop.getField(), prop.getValue()); // Notify other handler of the field value change.
+            }
+            if (prop.hasMethod()) {
+                if (getInstanceManager().getPojoObjects() != null) {
+                    prop.invoke(null); // Call on all created pojo objects.
+                }
+            }
+        }
+    }
     
     /**
      * Removes the old properties from the provided services and propagate new properties.
@@ -403,9 +398,10 @@
      * @see org.apache.felix.ipojo.Handler#onCreation(java.lang.Object)
      */
     public void onCreation(Object instance) {
-        for (int i = 0; i < m_configurableProperties.length; i++) {
-            if (m_configurableProperties[i].hasMethod()) {
-                m_configurableProperties[i].invoke(instance);
+        for (int i = 0; i < m_configurableProperties.size(); i++) {
+            Property prop = (Property) m_configurableProperties.get(i);
+            if (prop.hasMethod()) {
+                prop.invoke(instance);
             }
         }
     }
@@ -426,7 +422,7 @@
             propagate(props, m_propagatedFromCA);
             m_propagatedFromCA = props;
             m_configurationAlreadyPushed = true;
-        } else if (conf == null && m_configurationAlreadyPushed) { // Configuration deletion
+        } else if (m_configurationAlreadyPushed) { // Configuration deletion
             propagate(null, m_propagatedFromCA);
             m_propagatedFromCA = null;
             m_configurationAlreadyPushed = false;

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java Tue Oct 28 02:35:36 2008
@@ -195,14 +195,6 @@
         super.stop();
     }
 
-    /**
-     * Get the string form of the filter.
-     * @return : the string form of the filter.
-     */
-    public String getStringFilter() {
-        return getFilter().toString();
-    }
-
     public DependencyHandler getHandler() {
         return m_handler;
     }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java Tue Oct 28 02:35:36 2008
@@ -29,7 +29,7 @@
     /**
      * Structure contained in the Thread Local.
      */
-    public class Usage {
+    public static class Usage {
         
         /**
          * Stack Size.

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java Tue Oct 28 02:35:36 2008
@@ -18,8 +18,10 @@
  */
 package org.apache.felix.ipojo.handlers.providedservice;
 
+import java.util.Arrays;
 import java.util.Dictionary;
 import java.util.Enumeration;
+import java.util.List;
 import java.util.Properties;
 
 import org.apache.felix.ipojo.ConfigurationException;
@@ -204,7 +206,8 @@
                 svc = m_handler.getInstanceManager().createPojoObject();
                 break;
             default:
-                m_handler.error("[" + m_handler.getInstanceManager().getClassName() + "] Unknown factory policy for " + m_serviceSpecification + " : " + m_factoryPolicy);
+                List specs = Arrays.asList(m_serviceSpecification);
+                m_handler.error("[" + m_handler.getInstanceManager().getClassName() + "] Unknown factory policy for " + specs + " : " + m_factoryPolicy);
                 getInstanceManager().stop();
                 break;
         }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java Tue Oct 28 02:35:36 2008
@@ -283,7 +283,7 @@
         // If not found or no id, look for a dependency with the same specification
         String requirement = element.getAttribute("specification");
         for (int i = 0; i < handler.getDependencies().length; i++) {
-            if (handler.getDependencies()[i].getSpecification().equals(requirement)) { return handler.getDependencies()[i]; }
+            if ((handler.getDependencies()[i].getSpecification().getName()).equals(requirement)) { return handler.getDependencies()[i]; }
         }
 
         return null;
@@ -514,7 +514,7 @@
                 List itfs = ParseUtils.parseArraysAsList(serviceSpecificationStr);
                 for (int j = 0; j < itfs.size(); j++) {
                     if (! all.contains(itfs.get(j))) {
-                        throw new ConfigurationException("The specification " + itfs.get(j) + " is not implemented by " + desc.getClassName());
+                        throw new ConfigurationException("The specification " + itfs.get(j) + " is not implemented by " + metadata.getAttribute("classname"));
                     }
                 }
                 all = new HashSet(itfs);

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java Tue Oct 28 02:35:36 2008
@@ -108,7 +108,7 @@
                 Element prop = new Element("property", null);
                 String name = (String) iterator.next();
                 prop.addAttribute(new Attribute("name", name));
-                prop.addAttribute(new Attribute("value", m_providedServices[i].getProperties().getProperty(name).toString()));
+                prop.addAttribute(new Attribute("value", m_providedServices[i].getProperties().getProperty(name)));
                 service.addElement(prop);
             }
             services.addElement(service);

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java Tue Oct 28 02:35:36 2008
@@ -198,12 +198,6 @@
      * @param method the Method Metadata to add.
      */
     private void addMethod(MethodMetadata method) {
-        for (int i = 0; (m_methods != null) && (i < m_methods.length); i++) {
-            if (m_methods[i] == method) {
-                return;
-            }
-        }
-
         if (m_methods.length > 0) {
             MethodMetadata[] newInstances = new MethodMetadata[m_methods.length + 1];
             System.arraycopy(m_methods, 0, newInstances, 0, m_methods.length);
@@ -221,12 +215,6 @@
      * @param field the Field Metadata to add.
      */
     private void addField(FieldMetadata field) {
-        for (int i = 0; (m_fields != null) && (i < m_fields.length); i++) {
-            if (m_fields[i] == field) {
-                return;
-            }
-        }
-
         if (m_fields.length > 0) {
             FieldMetadata[] newInstances = new FieldMetadata[m_fields.length + 1];
             System.arraycopy(m_fields, 0, newInstances, 0, m_fields.length);
@@ -244,12 +232,6 @@
      * @param itf the interface name to add.
      */
     private void addInterface(String itf) {
-        for (int i = 0; (m_interfaces != null) && (i < m_interfaces.length); i++) {
-            if (m_interfaces[i] == itf) {
-                return;
-            }
-        }
-
         if (m_interfaces.length > 0) {
             String[] newInstances = new String[m_interfaces.length + 1];
             System.arraycopy(m_interfaces, 0, newInstances, 0, m_interfaces.length);

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java Tue Oct 28 02:35:36 2008
@@ -740,7 +740,7 @@
         }
     }
 
-    public boolean isAggregate() {
+    public synchronized boolean isAggregate() {
         return m_aggregate;
     }
 
@@ -787,7 +787,7 @@
      * <code>Null</code> if no comparator (i.e. the OSGi one is used).
      * @return the comparator class name or <code>null</code> if the dependency doesn't use a comparator.
      */
-    public String getComparator() {
+    public synchronized String getComparator() {
         if (m_comparator != null) {
             return m_comparator.getClass().getName();
         } else {

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Property.java Tue Oct 28 02:35:36 2008
@@ -490,7 +490,7 @@
      * @param value the new value
      * @see org.apache.felix.ipojo.FieldInterceptor#onSet(java.lang.Object, java.lang.String, java.lang.Object)
      */
-    public void onSet(Object pojo, String fieldName, Object value) {
+    public synchronized void onSet(Object pojo, String fieldName, Object value) {
         if (m_value == null || ! m_value.equals(value)) {
             setValue(value);
         }

Modified: felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java (original)
+++ felix/trunk/ipojo/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java Tue Oct 28 02:35:36 2008
@@ -23,6 +23,7 @@
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.felix.ipojo.context.ServiceReferenceImpl;
 import org.osgi.framework.BundleContext;
@@ -374,10 +375,11 @@
         synchronized (tracked) {
             int length = tracked.size();
             List references = new ArrayList();
-            Iterator keys = tracked.keySet().iterator();
+            Iterator keys = tracked.entrySet().iterator();
             for (int i = 0; i < length; i++) {
-                Object key = keys.next(); 
-                if (tracked.get(key) != null) {
+                Map.Entry entry = (Map.Entry) keys.next();
+                Object key = entry.getKey();
+                if (entry.getValue() != null) {
                     references.add(key);
                 }
             }

Modified: felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/EventUtil.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/EventUtil.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/EventUtil.java (original)
+++ felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/EventUtil.java Tue Oct 28 02:35:36 2008
@@ -27,153 +27,147 @@
  */
 public class EventUtil {
 
-	/**
-	 * The separator between topics.
-	 */
-	public static final String TOPIC_SEPARATOR = ",";
-
-	/**
-	 * The separator between topics.
-	 */
-	public static final String TOPIC_TOKEN_SEPARATOR = "/";
-
-	/**
-	 * The topic token alphabet.
-	 */
-	private static final String tokenAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
-
-	/**
-	 * Tests that the given topic match with the given topic pattern.
-	 * 
-	 * @param topic
-	 *            the topic to test
-	 * @param topicPattern
-	 *            the topic pattern
-	 * @return true if it matches.
-	 */
-	public static final boolean matches(String topic, String topicPattern) {
-		if (topicPattern.equals("*")) {
-			return true;
-		}
-		int star;
-		if ((star = topicPattern.indexOf("*")) > 0) {
-			return topic.startsWith(topicPattern.substring(0, star - 1));
-		} else {
-			return topic.equals(topicPattern);
-		}
-	}
-
-	/**
-	 * Tests that the given topic match with the given topic patterns.
-	 * 
-	 * @param topic
-	 *            the topic to test
-	 * @param topicPatterns
-	 *            the topic patterns
-	 * @return true if it matches.
-	 */
-	public static final boolean matches(String topic, String[] topicPatterns) {
-		int n = topicPatterns.length;
-		for (int i = 0; i < n; i++) {
-			if (matches(topic, topicPatterns[i])) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * Check the given topic scope is valid.
-	 * 
-	 * topicScope ::= "*" | ( topic "/*" ? )
-	 * 
-	 * @param topicScope
-	 *            the topic scope to check.
-	 * 
-	 * @return {@code true} if the given topic scope is valid, {@code false}
-	 *         otherwise.
-	 */
-	public static final boolean isValidTopicScope(String topicScope) {
-		if (topicScope.equals("*")) {
-			// Wildcard character only accepted.
-			return true;
-		}
-		
-		// Remove trailing "/*" if present, to check the topic radix.
-		String topicWithoutWildcard;
-		if (topicScope.endsWith("/*")) {
-			topicWithoutWildcard = topicScope.substring(0, topicScope.length() - 2);
-		} else {
-			topicWithoutWildcard = topicScope;
-		}
-		
-		// Validate the topic radix.
-		return isValidTopic(topicWithoutWildcard);
-	}
-
-	/**
-	 * Check the given topic is valid.
-	 * 
-	 * topic ::= token ( ’/’ token ) *
-	 * 
-	 * @param topic
-	 *            the topic to check.
-	 * 
-	 * @return {@code true} if the given topic is valid, {@code false}
-	 *         otherwise.
-	 */
-	public static final boolean isValidTopic(String topic) {
-		if (topic.startsWith(TOPIC_TOKEN_SEPARATOR)
-				|| topic.endsWith(TOPIC_TOKEN_SEPARATOR)) {
-			// A topic cannot start nor end with '/'.
-			return false;
-		}
-
-		String[] tokens = ParseUtils.split(topic, TOPIC_TOKEN_SEPARATOR);
-		if (tokens.length < 1) {
-			// A topic must contain at least one token.
-			return false;
-		}
-
-		// Check each token is valid.
-		for (int i = 0; i < tokens.length; i++) {
-			String token = tokens[i];
-			if (!isValidToken(token)) {
-				return false;
-			}
-		}
-
-		// The topic is valid.
-		return true;
-	}
-
-	/**
-	 * Check the given token is valid.
-	 * 
-	 * token ::= ( alphanum | "_" | "-" )+
-	 * 
-	 * @param token
-	 *            the token to check.
-	 * 
-	 * @return {@code true} if the given topic token is valid, {@code false}
-	 *         otherwise.
-	 */
-	private static boolean isValidToken(String token) {
-		int length = token.length();
-		if (length < 1) {
-			// Token must contain at least one character.
-			return false;
-		}
-
-		for (int i = 0; i < length; i++) {
-			// Each character in the token must belong to the token alphabet.
-			if (tokenAlphabet.indexOf(token.charAt(i)) == -1) {
-				return false;
-			}
-		}
-
-		// The token is valid.
-		return true;
-	}
+    /**
+     * The separator between topics.
+     */
+    public static final String TOPIC_SEPARATOR = ",";
+
+    /**
+     * The separator between topics.
+     */
+    public static final String TOPIC_TOKEN_SEPARATOR = "/";
+
+    /**
+     * The topic token alphabet.
+     */
+    private static final String TOKEN_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
+
+    /**
+     * Tests that the given topic match with the given topic pattern.
+     * 
+     * @param topic the topic to test
+     * @param topicPattern the topic pattern
+     * @return true if it matches.
+     */
+    public static final boolean matches(String topic, String topicPattern) {
+        if (topicPattern.equals("*")) {
+            return true;
+        }
+        int star;
+        if ((star = topicPattern.indexOf("*")) > 0) {
+            return topic.startsWith(topicPattern.substring(0, star - 1));
+        } else {
+            return topic.equals(topicPattern);
+        }
+    }
+
+    /**
+     * Tests that the given topic match with the given topic patterns.
+     * 
+     * @param topic the topic to test
+     * @param topicPatterns the topic patterns
+     * @return true if it matches.
+     */
+    public static final boolean matches(String topic, String[] topicPatterns) {
+        int n = topicPatterns.length;
+        for (int i = 0; i < n; i++) {
+            if (matches(topic, topicPatterns[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Check the given topic scope is valid.
+     * 
+     * topicScope ::= "*" | ( topic "/*" ? )
+     * 
+     * @param topicScope the topic scope to check.
+     * 
+     * @return {@code true} if the given topic scope is valid, {@code false}
+     *         otherwise.
+     */
+    public static final boolean isValidTopicScope(String topicScope) {
+        if (topicScope.equals("*")) {
+            // Wildcard character only accepted.
+            return true;
+        }
+
+        // Remove trailing "/*" if present, to check the topic radix.
+        String topicWithoutWildcard;
+        if (topicScope.endsWith("/*")) {
+            topicWithoutWildcard = topicScope.substring(0,
+                    topicScope.length() - 2);
+        } else {
+            topicWithoutWildcard = topicScope;
+        }
+
+        // Validate the topic radix.
+        return isValidTopic(topicWithoutWildcard);
+    }
+
+    /**
+     * Check the given topic is valid.
+     * 
+     * topic ::= token ( ’/’ token ) *
+     * 
+     * @param topic the topic to check.
+     * 
+     * @return {@code true} if the given topic is valid, {@code false}
+     *         otherwise.
+     */
+    public static final boolean isValidTopic(String topic) {
+        if (topic.startsWith(TOPIC_TOKEN_SEPARATOR)
+                || topic.endsWith(TOPIC_TOKEN_SEPARATOR)) {
+            // A topic cannot start nor end with '/'.
+            return false;
+        }
+
+        String[] tokens = ParseUtils.split(topic, TOPIC_TOKEN_SEPARATOR);
+        if (tokens.length < 1) {
+            // A topic must contain at least one token.
+            return false;
+        }
+
+        // Check each token is valid.
+        for (int i = 0; i < tokens.length; i++) {
+            String token = tokens[i];
+            if (!isValidToken(token)) {
+                return false;
+            }
+        }
+
+        // The topic is valid.
+        return true;
+    }
+
+    /**
+     * Check the given token is valid.
+     * 
+     * token ::= ( alphanum | "_" | "-" )+
+     * 
+     * @param token the token to check.
+     * 
+     * @return {@code true} if the given topic token is valid, {@code false}
+     *         otherwise.
+     */
+    private static boolean isValidToken(String token) {
+        int length = token.length();
+        if (length < 1) {
+            // Token must contain at least one character.
+            return false;
+        }
+
+        for (int i = 0; i < length; i++) {
+            // Each character in the token must belong to the token alphabet.
+            if (TOKEN_ALPHABET.indexOf(token.charAt(i)) == -1) {
+                return false;
+            }
+        }
+
+        // The token is valid.
+        return true;
+    }
 
 }

Modified: felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherMetadata.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherMetadata.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherMetadata.java (original)
+++ felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/publisher/EventAdminPublisherMetadata.java Tue Oct 28 02:35:36 2008
@@ -30,212 +30,207 @@
  */
 class EventAdminPublisherMetadata {
 
-	// Names of metadata attributes
+    // Names of metadata attributes
 
-	/**
-	 * The name attribute in the component metadata.
-	 */
-	public static final String NAME_ATTRIBUTE = "name";
-
-	/**
-	 * The field attribute in the component metadata.
-	 */
-	public static final String FIELD_ATTRIBUTE = "field";
-
-	/**
-	 * The topics attribute in the component metadata.
-	 */
-	public static final String TOPICS_ATTRIBUTE = "topics";
-
-	/**
-	 * The synchronous attribute in the component metadata.
-	 */
-	public static final String SYNCHRONOUS_ATTRIBUTE = "synchronous";
-
-	/**
-	 * The data key attribute in the component metadata.
-	 */
-	public static final String DATA_KEY_ATTRIBUTE = "data-key";
-
-	// Default values
-
-	/**
-	 * The data key attribute's default value.
-	 */
-	public static final String DEFAULT_DATA_KEY_VALUE = "user.data";
-
-	/**
-	 * The synchronous attribute's default value.
-	 */
-	public static final boolean DEFAULT_SYNCHRONOUS_VALUE = false;
-
-	/**
-	 * The name which acts as an identifier.
-	 */
-	private final String m_name;
-
-	/**
-	 * The name of the field representing the publisher in the component.
-	 */
-	private final String m_field;
-
-	/**
-	 * Topics to which events are sent.
-	 */
-	private String[] m_topics;
-
-	/**
-	 * Events sending mode.
-	 */
-	private final boolean m_synchronous;
-
-	/**
-	 * The key where user data are stored in the event dictionary.
-	 */
-	private final String m_dataKey;
-
-	/**
-	 * Constructs a publisher from its metadata description.
-	 * 
-	 * @param publisher
-	 *            the publisher metadata description.
-	 * @throws ConfigurationException
-	 *             if the configuration of the component or the instance is
-	 *             invalid.
-	 */
-	public EventAdminPublisherMetadata(Element publisher)
-			throws ConfigurationException {
-
-		/**
-		 * Setup required attributes
-		 */
-
-		// NAME_ATTRIBUTE
-		if (publisher.containsAttribute(NAME_ATTRIBUTE)) {
-			m_name = publisher.getAttribute(NAME_ATTRIBUTE);
-		} else {
-			throw new ConfigurationException(
-					"Missing required attribute in component configuration : "
-							+ NAME_ATTRIBUTE);
-		}
-
-		// FIELD_ATTRIBUTE
-		if (publisher.containsAttribute(FIELD_ATTRIBUTE)) {
-			m_field = publisher.getAttribute(FIELD_ATTRIBUTE);
-		} else {
-			throw new ConfigurationException(
-					"Missing required attribute in component configuration : "
-							+ FIELD_ATTRIBUTE);
-		}
-
-		// TOPICS_ATTRIBUTE
-		if (publisher.containsAttribute(TOPICS_ATTRIBUTE)) {
-			setTopics(publisher.getAttribute(TOPICS_ATTRIBUTE));
-		} else {
-			m_topics = null;
-			// Nothing to do if TOPICS_ATTRIBUTE is not present as it can be
-			// overridden in the instance configuration.
-		}
-
-		/**
-		 * Setup optional attributes
-		 */
-
-		// SYNCHRONOUS_ATTRIBUTE
-		if (publisher.containsAttribute(SYNCHRONOUS_ATTRIBUTE)) {
-			m_synchronous = "true".equalsIgnoreCase(publisher
-					.getAttribute(SYNCHRONOUS_ATTRIBUTE));
-		} else {
-			m_synchronous = DEFAULT_SYNCHRONOUS_VALUE;
-		}
-
-		// DATA_KEY_ATTRIBUTE
-		if (publisher.containsAttribute(DATA_KEY_ATTRIBUTE)) {
-			m_dataKey = publisher.getAttribute(DATA_KEY_ATTRIBUTE);
-		} else {
-			m_dataKey = DEFAULT_DATA_KEY_VALUE;
-		}
-	}
-
-	/**
-	 * Sets the topics attribute of the publisher.
-	 * 
-	 * @param topicsString
-	 *            the comma separated list of the topics on which events are
-	 *            sent
-	 * @throws ConfigurationException
-	 *             the specified topic string is malformed
-	 */
-	public void setTopics(String topicsString) throws ConfigurationException {
-		String[] newTopics = ParseUtils.split(topicsString,
-				EventUtil.TOPIC_SEPARATOR);
-		// Check each topic is valid
-		for (int i = 0; i < newTopics.length; i++) {
-			String topic = newTopics[i];
-			if (!EventUtil.isValidTopic(topic)) {
-				throw new ConfigurationException("Invalid topic : \"" + topic
-						+ "\".");
-			}
-		}
-		m_topics = newTopics;
-	}
-
-	/**
-	 * Checks that the required instance configurable attributes are all set.
-	 * 
-	 * @throws ConfigurationException
-	 *             if a required attribute is missing
-	 */
-	public void check() throws ConfigurationException {
-		if (m_topics == null || m_topics.length == 0) {
-			throw new ConfigurationException(
-					"Missing required attribute in component or instance configuration : "
-							+ TOPICS_ATTRIBUTE);
-		}
-	}
-
-	/**
-	 * Gets the name attribute of the publisher.
-	 * 
-	 * @return the name
-	 */
-	public String getName() {
-		return m_name;
-	}
-
-	/**
-	 * Gets the field attribute of the publisher.
-	 * 
-	 * @return the field
-	 */
-	public String getField() {
-		return m_field;
-	}
-
-	/**
-	 * Gets the topics attribute of the publisher.
-	 * 
-	 * @return the topics
-	 */
-	public String[] getTopics() {
-		return m_topics;
-	}
-
-	/**
-	 * Gets the synchronous attribute of the publisher.
-	 * 
-	 * @return the synchronous mode
-	 */
-	public boolean isSynchronous() {
-		return m_synchronous;
-	}
-
-	/**
-	 * Gets the dataKey attribute of the publisher.
-	 * 
-	 * @return the data key
-	 */
-	public String getDataKey() {
-		return m_dataKey;
-	}
+    /**
+     * The name attribute in the component metadata.
+     */
+    public static final String NAME_ATTRIBUTE = "name";
+
+    /**
+     * The field attribute in the component metadata.
+     */
+    public static final String FIELD_ATTRIBUTE = "field";
+
+    /**
+     * The topics attribute in the component metadata.
+     */
+    public static final String TOPICS_ATTRIBUTE = "topics";
+
+    /**
+     * The synchronous attribute in the component metadata.
+     */
+    public static final String SYNCHRONOUS_ATTRIBUTE = "synchronous";
+
+    /**
+     * The data key attribute in the component metadata.
+     */
+    public static final String DATA_KEY_ATTRIBUTE = "data-key";
+
+    // Default values
+
+    /**
+     * The data key attribute's default value.
+     */
+    public static final String DEFAULT_DATA_KEY_VALUE = "user.data";
+
+    /**
+     * The synchronous attribute's default value.
+     */
+    public static final boolean DEFAULT_SYNCHRONOUS_VALUE = false;
+
+    /**
+     * The name which acts as an identifier.
+     */
+    private final String m_name;
+
+    /**
+     * The name of the field representing the publisher in the component.
+     */
+    private final String m_field;
+
+    /**
+     * Topics to which events are sent.
+     */
+    private String[] m_topics;
+
+    /**
+     * Events sending mode.
+     */
+    private final boolean m_synchronous;
+
+    /**
+     * The key where user data are stored in the event dictionary.
+     */
+    private final String m_dataKey;
+
+    /**
+     * Constructs a publisher from its metadata description.
+     * 
+     * @param publisher the publisher metadata description.
+     * @throws ConfigurationException if the configuration of the component or
+     *             the instance is invalid.
+     */
+    public EventAdminPublisherMetadata(Element publisher)
+            throws ConfigurationException {
+
+        /**
+         * Setup required attributes
+         */
+
+        // NAME_ATTRIBUTE
+        if (publisher.containsAttribute(NAME_ATTRIBUTE)) {
+            m_name = publisher.getAttribute(NAME_ATTRIBUTE);
+        } else {
+            throw new ConfigurationException(
+                    "Missing required attribute in component configuration : "
+                            + NAME_ATTRIBUTE);
+        }
+
+        // FIELD_ATTRIBUTE
+        if (publisher.containsAttribute(FIELD_ATTRIBUTE)) {
+            m_field = publisher.getAttribute(FIELD_ATTRIBUTE);
+        } else {
+            throw new ConfigurationException(
+                    "Missing required attribute in component configuration : "
+                            + FIELD_ATTRIBUTE);
+        }
+
+        // TOPICS_ATTRIBUTE
+        if (publisher.containsAttribute(TOPICS_ATTRIBUTE)) {
+            setTopics(publisher.getAttribute(TOPICS_ATTRIBUTE));
+        } else {
+            m_topics = null;
+            // Nothing to do if TOPICS_ATTRIBUTE is not present as it can be
+            // overridden in the instance configuration.
+        }
+
+        /**
+         * Setup optional attributes
+         */
+
+        // SYNCHRONOUS_ATTRIBUTE
+        if (publisher.containsAttribute(SYNCHRONOUS_ATTRIBUTE)) {
+            m_synchronous = "true".equalsIgnoreCase(publisher
+                    .getAttribute(SYNCHRONOUS_ATTRIBUTE));
+        } else {
+            m_synchronous = DEFAULT_SYNCHRONOUS_VALUE;
+        }
+
+        // DATA_KEY_ATTRIBUTE
+        if (publisher.containsAttribute(DATA_KEY_ATTRIBUTE)) {
+            m_dataKey = publisher.getAttribute(DATA_KEY_ATTRIBUTE);
+        } else {
+            m_dataKey = DEFAULT_DATA_KEY_VALUE;
+        }
+    }
+
+    /**
+     * Sets the topics attribute of the publisher.
+     * 
+     * @param topicsString the comma separated list of the topics on which
+     *            events are sent
+     * @throws ConfigurationException the specified topic string is malformed
+     */
+    public void setTopics(String topicsString) throws ConfigurationException {
+        String[] newTopics = ParseUtils.split(topicsString,
+                EventUtil.TOPIC_SEPARATOR);
+        // Check each topic is valid
+        for (int i = 0; i < newTopics.length; i++) {
+            String topic = newTopics[i];
+            if (!EventUtil.isValidTopic(topic)) {
+                throw new ConfigurationException("Invalid topic : \"" + topic
+                        + "\".");
+            }
+        }
+        m_topics = newTopics;
+    }
+
+    /**
+     * Checks that the required instance configurable attributes are all set.
+     * 
+     * @throws ConfigurationException if a required attribute is missing
+     */
+    public void check() throws ConfigurationException {
+        if (m_topics == null || m_topics.length == 0) {
+            throw new ConfigurationException(
+                    "Missing required attribute in component or instance configuration : "
+                            + TOPICS_ATTRIBUTE);
+        }
+    }
+
+    /**
+     * Gets the name attribute of the publisher.
+     * 
+     * @return the name
+     */
+    public String getName() {
+        return m_name;
+    }
+
+    /**
+     * Gets the field attribute of the publisher.
+     * 
+     * @return the field
+     */
+    public String getField() {
+        return m_field;
+    }
+
+    /**
+     * Gets the topics attribute of the publisher.
+     * 
+     * @return the topics
+     */
+    public String[] getTopics() {
+        return m_topics;
+    }
+
+    /**
+     * Gets the synchronous attribute of the publisher.
+     * 
+     * @return the synchronous mode
+     */
+    public boolean isSynchronous() {
+        return m_synchronous;
+    }
+
+    /**
+     * Gets the dataKey attribute of the publisher.
+     * 
+     * @return the data key
+     */
+    public String getDataKey() {
+        return m_dataKey;
+    }
 }

Modified: felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberMetadata.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberMetadata.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberMetadata.java (original)
+++ felix/trunk/ipojo/handler/eventadmin/src/main/java/org/apache/felix/ipojo/handlers/event/subscriber/EventAdminSubscriberMetadata.java Tue Oct 28 02:35:36 2008
@@ -33,255 +33,247 @@
  */
 class EventAdminSubscriberMetadata {
 
-	// Names of metadata attributes
+    // Names of metadata attributes
 
-	/**
-	 * The name attribute in the component metadata.
-	 */
-	public static final String NAME_ATTRIBUTE = "name";
-
-	/**
-	 * The callback attribute in the component metadata.
-	 */
-	public static final String CALLBACK_ATTRIBUTE = "callback";
-
-	/**
-	 * The topics attribute in the component metadata.
-	 */
-	public static final String TOPICS_ATTRIBUTE = "topics";
-
-	/**
-	 * The data key attribute in the component metadata.
-	 */
-	public static final String DATA_KEY_ATTRIBUTE = "data-key";
-
-	/**
-	 * The data type attribute in the component metadata.
-	 */
-	public static final String DATA_TYPE_ATTRIBUTE = "data-type";
-
-	/**
-	 * The filter attribute in the component metadata.
-	 */
-	public static final String FILTER_ATTRIBUTE = "filter";
-
-	// Default values
-
-	/**
-	 * The data type atttribute's default value.
-	 */
-	public static final Class DEFAULT_DATA_TYPE_VALUE = java.lang.Object.class;
-
-	/**
-	 * The name which acts as an identifier.
-	 */
-	private final String m_name;
-
-	/**
-	 * Name of the callback method.
-	 */
-	private final String m_callback;
-
-	/**
-	 * Listened topics.
-	 */
-	private String[] m_topics;
-
-	/**
-	 * The key where user data are stored in the event dictionary.
-	 */
-	private final String m_dataKey;
-
-	/**
-	 * The type of received data.
-	 */
-	private final Class m_dataType;
-
-	/**
-	 * Event filter.
-	 */
-	private Filter m_filter;
-
-	/**
-	 * The context of the bundle.
-	 */
-	private final BundleContext m_bundleContext;
-
-	/**
-	 * Constructor.
-	 * 
-	 * @param bundleContext
-	 *            the bundle context of the managed instance.
-	 * @param subscriber
-	 *            the subscriber metadata.
-	 * @throws ConfigurationException
-	 *             if the configuration of the component or the instance is
-	 *             invalid.
-	 */
-	public EventAdminSubscriberMetadata(BundleContext bundleContext,
-			Element subscriber) throws ConfigurationException {
-		m_bundleContext = bundleContext;
-
-		/**
-		 * Setup required attributes
-		 */
-
-		// NAME_ATTRIBUTE
-		if (subscriber.containsAttribute(NAME_ATTRIBUTE)) {
-			m_name = subscriber.getAttribute(NAME_ATTRIBUTE);
-		} else {
-			throw new ConfigurationException(
-					"Missing required attribute in component configuration : "
-							+ NAME_ATTRIBUTE);
-		}
-
-		// CALLBACK_ATTRIBUTE
-		if (subscriber.containsAttribute(CALLBACK_ATTRIBUTE)) {
-			m_callback = subscriber.getAttribute(CALLBACK_ATTRIBUTE);
-		} else {
-			throw new ConfigurationException(
-					"Missing required attribute in component configuration : "
-							+ CALLBACK_ATTRIBUTE);
-		}
-
-		// TOPICS_ATTRIBUTE
-		if (subscriber.containsAttribute(TOPICS_ATTRIBUTE)) {
-			setTopics(subscriber.getAttribute(TOPICS_ATTRIBUTE));
-		} else {
-			m_topics = null;
-			// Nothing to do if TOPICS_ATTRIBUTE is not present as it can be
-			// overridden in the instance configuration.
-		}
-
-		/**
-		 * Setup optional attributes
-		 */
-
-		// DATA_KEY_ATTRIBUTE
-		m_dataKey = subscriber.getAttribute(DATA_KEY_ATTRIBUTE);
-		if (subscriber.containsAttribute(DATA_TYPE_ATTRIBUTE)) {
-			Class type;
-			String typeName = subscriber.getAttribute(DATA_TYPE_ATTRIBUTE);
-			try {
-				type = m_bundleContext.getBundle().loadClass(typeName);
-			} catch (ClassNotFoundException e) {
-				throw new ConfigurationException("Data type class not found : "
-						+ typeName);
-			}
-			m_dataType = type;
-		} else {
-			m_dataType = DEFAULT_DATA_TYPE_VALUE;
-		}
-
-		// FILTER_ATTRIBUTE
-		if (subscriber.containsAttribute(FILTER_ATTRIBUTE)) {
-			setFilter(subscriber.getAttribute(FILTER_ATTRIBUTE));
-		}
-	}
-
-	/**
-	 * Sets the topics attribute of the subscriber.
-	 * 
-	 * @param topicsString
-	 *            the comma separated list of the topics to listen
-	 * @throws ConfigurationException
-	 *             if the specified topic list is malformed
-	 */
-	public void setTopics(String topicsString) throws ConfigurationException {
-		String[] newTopics = ParseUtils.split(topicsString,
-				EventUtil.TOPIC_SEPARATOR);
-		// Check each topic is valid
-		for (int i = 0; i < newTopics.length; i++) {
-			String topicScope = newTopics[i];
-			if (!EventUtil.isValidTopicScope(topicScope)) {
-				throw new ConfigurationException("Invalid topic scope : \""
-						+ topicScope + "\".");
-			}
-		}
-		m_topics = newTopics;
-	}
-
-	/**
-	 * Sets the filter attribute of the subscriber.
-	 * 
-	 * @param filterString
-	 *            the string representation of the event filter
-	 * @throws ConfigurationException
-	 *             if the LDAP filter is malformed
-	 */
-	public void setFilter(String filterString) throws ConfigurationException {
-		try {
-			m_filter = m_bundleContext.createFilter(filterString);
-		} catch (InvalidSyntaxException e) {
-			throw new ConfigurationException("Invalid filter syntax");
-		}
-	}
-
-	/**
-	 * Checks that the required instance configurable attributes are all set.
-	 * 
-	 * @throws ConfigurationException
-	 *             if a required attribute is missing
-	 */
-	public void check() throws ConfigurationException {
-		if (m_topics == null || m_topics.length == 0) {
-			throw new ConfigurationException(
-					"Missing required attribute in component or instance configuration : "
-							+ TOPICS_ATTRIBUTE);
-		}
-	}
-
-	/**
-	 * Gets the name attribute of the subscriber.
-	 * 
-	 * @return the name
-	 */
-	public String getName() {
-		return m_name;
-	}
-
-	/**
-	 * Gets the topics attribute of the subscriber.
-	 * 
-	 * @return the topics
-	 */
-	public String[] getTopics() {
-		return m_topics;
-	}
-
-	/**
-	 * Gets the callback attribute of the subscriber.
-	 * 
-	 * @return the callback
-	 */
-	public String getCallback() {
-		return m_callback;
-	}
-
-	/**
-	 * Gets the data key attribute of the subscriber.
-	 * 
-	 * @return the dataKey
-	 */
-	public String getDataKey() {
-		return m_dataKey;
-	}
-
-	/**
-	 * Gets the data type attribute of the subscriber.
-	 * 
-	 * @return the dataType
-	 */
-	public Class getDataType() {
-		return m_dataType;
-	}
-
-	/**
-	 * Gets the filter attribute of the subscriber.
-	 * 
-	 * @return the filter
-	 */
-	public Filter getFilter() {
-		return m_filter;
-	}
+    /**
+     * The name attribute in the component metadata.
+     */
+    public static final String NAME_ATTRIBUTE = "name";
+
+    /**
+     * The callback attribute in the component metadata.
+     */
+    public static final String CALLBACK_ATTRIBUTE = "callback";
+
+    /**
+     * The topics attribute in the component metadata.
+     */
+    public static final String TOPICS_ATTRIBUTE = "topics";
+
+    /**
+     * The data key attribute in the component metadata.
+     */
+    public static final String DATA_KEY_ATTRIBUTE = "data-key";
+
+    /**
+     * The data type attribute in the component metadata.
+     */
+    public static final String DATA_TYPE_ATTRIBUTE = "data-type";
+
+    /**
+     * The filter attribute in the component metadata.
+     */
+    public static final String FILTER_ATTRIBUTE = "filter";
+
+    // Default values
+
+    /**
+     * The data type atttribute's default value.
+     */
+    public static final Class DEFAULT_DATA_TYPE_VALUE = java.lang.Object.class;
+
+    /**
+     * The name which acts as an identifier.
+     */
+    private final String m_name;
+
+    /**
+     * Name of the callback method.
+     */
+    private final String m_callback;
+
+    /**
+     * Listened topics.
+     */
+    private String[] m_topics;
+
+    /**
+     * The key where user data are stored in the event dictionary.
+     */
+    private final String m_dataKey;
+
+    /**
+     * The type of received data.
+     */
+    private final Class m_dataType;
+
+    /**
+     * Event filter.
+     */
+    private Filter m_filter;
+
+    /**
+     * The context of the bundle.
+     */
+    private final BundleContext m_bundleContext;
+
+    /**
+     * Constructor.
+     * 
+     * @param bundleContext the bundle context of the managed instance.
+     * @param subscriber the subscriber metadata.
+     * @throws ConfigurationException if the configuration of the component or
+     *             the instance is invalid.
+     */
+    public EventAdminSubscriberMetadata(BundleContext bundleContext,
+            Element subscriber) throws ConfigurationException {
+        m_bundleContext = bundleContext;
+
+        /**
+         * Setup required attributes
+         */
+
+        // NAME_ATTRIBUTE
+        if (subscriber.containsAttribute(NAME_ATTRIBUTE)) {
+            m_name = subscriber.getAttribute(NAME_ATTRIBUTE);
+        } else {
+            throw new ConfigurationException(
+                    "Missing required attribute in component configuration : "
+                            + NAME_ATTRIBUTE);
+        }
+
+        // CALLBACK_ATTRIBUTE
+        if (subscriber.containsAttribute(CALLBACK_ATTRIBUTE)) {
+            m_callback = subscriber.getAttribute(CALLBACK_ATTRIBUTE);
+        } else {
+            throw new ConfigurationException(
+                    "Missing required attribute in component configuration : "
+                            + CALLBACK_ATTRIBUTE);
+        }
+
+        // TOPICS_ATTRIBUTE
+        if (subscriber.containsAttribute(TOPICS_ATTRIBUTE)) {
+            setTopics(subscriber.getAttribute(TOPICS_ATTRIBUTE));
+        } else {
+            m_topics = null;
+            // Nothing to do if TOPICS_ATTRIBUTE is not present as it can be
+            // overridden in the instance configuration.
+        }
+
+        /**
+         * Setup optional attributes
+         */
+
+        // DATA_KEY_ATTRIBUTE
+        m_dataKey = subscriber.getAttribute(DATA_KEY_ATTRIBUTE);
+        if (subscriber.containsAttribute(DATA_TYPE_ATTRIBUTE)) {
+            Class type;
+            String typeName = subscriber.getAttribute(DATA_TYPE_ATTRIBUTE);
+            try {
+                type = m_bundleContext.getBundle().loadClass(typeName);
+            } catch (ClassNotFoundException e) {
+                throw new ConfigurationException("Data type class not found : "
+                        + typeName);
+            }
+            m_dataType = type;
+        } else {
+            m_dataType = DEFAULT_DATA_TYPE_VALUE;
+        }
+
+        // FILTER_ATTRIBUTE
+        if (subscriber.containsAttribute(FILTER_ATTRIBUTE)) {
+            setFilter(subscriber.getAttribute(FILTER_ATTRIBUTE));
+        }
+    }
+
+    /**
+     * Sets the topics attribute of the subscriber.
+     * 
+     * @param topicsString the comma separated list of the topics to listen
+     * @throws ConfigurationException if the specified topic list is malformed
+     */
+    public void setTopics(String topicsString) throws ConfigurationException {
+        String[] newTopics = ParseUtils.split(topicsString,
+                EventUtil.TOPIC_SEPARATOR);
+        // Check each topic is valid
+        for (int i = 0; i < newTopics.length; i++) {
+            String topicScope = newTopics[i];
+            if (!EventUtil.isValidTopicScope(topicScope)) {
+                throw new ConfigurationException("Invalid topic scope : \""
+                        + topicScope + "\".");
+            }
+        }
+        m_topics = newTopics;
+    }
+
+    /**
+     * Sets the filter attribute of the subscriber.
+     * 
+     * @param filterString the string representation of the event filter
+     * @throws ConfigurationException if the LDAP filter is malformed
+     */
+    public void setFilter(String filterString) throws ConfigurationException {
+        try {
+            m_filter = m_bundleContext.createFilter(filterString);
+        } catch (InvalidSyntaxException e) {
+            throw new ConfigurationException("Invalid filter syntax");
+        }
+    }
+
+    /**
+     * Checks that the required instance configurable attributes are all set.
+     * 
+     * @throws ConfigurationException if a required attribute is missing
+     */
+    public void check() throws ConfigurationException {
+        if (m_topics == null || m_topics.length == 0) {
+            throw new ConfigurationException(
+                    "Missing required attribute in component or instance configuration : "
+                            + TOPICS_ATTRIBUTE);
+        }
+    }
+
+    /**
+     * Gets the name attribute of the subscriber.
+     * 
+     * @return the name
+     */
+    public String getName() {
+        return m_name;
+    }
+
+    /**
+     * Gets the topics attribute of the subscriber.
+     * 
+     * @return the topics
+     */
+    public String[] getTopics() {
+        return m_topics;
+    }
+
+    /**
+     * Gets the callback attribute of the subscriber.
+     * 
+     * @return the callback
+     */
+    public String getCallback() {
+        return m_callback;
+    }
+
+    /**
+     * Gets the data key attribute of the subscriber.
+     * 
+     * @return the dataKey
+     */
+    public String getDataKey() {
+        return m_dataKey;
+    }
+
+    /**
+     * Gets the data type attribute of the subscriber.
+     * 
+     * @return the dataType
+     */
+    public Class getDataType() {
+        return m_dataType;
+    }
+
+    /**
+     * Gets the filter attribute of the subscriber.
+     * 
+     * @return the filter
+     */
+    public Filter getFilter() {
+        return m_filter;
+    }
 }

Modified: felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/DynamicMBeanImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/DynamicMBeanImpl.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/DynamicMBeanImpl.java (original)
+++ felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/DynamicMBeanImpl.java Tue Oct 28 02:35:36 2008
@@ -294,7 +294,6 @@
      * value doesn't change further.
      */
     private void buildMBeanInfo() {
-        String dDescription = m_configMap.getDecription();
 
         // generate infos for attributes
         MBeanAttributeInfo[] dAttributes = null;
@@ -302,6 +301,8 @@
         if (m_configMap == null) {
             return;
         }
+        
+        String dDescription = m_configMap.getDecription();
 
         if (m_configMap.getProperties() != null) {
             List < MBeanAttributeInfo > lAttributes = null;

Modified: felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/MBeanHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/MBeanHandler.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/MBeanHandler.java (original)
+++ felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/MBeanHandler.java Tue Oct 28 02:35:36 2008
@@ -28,7 +28,6 @@
 import javax.management.ObjectInstance;
 import javax.management.ObjectName;
 
-import org.apache.felix.ipojo.FieldInterceptor;
 import org.apache.felix.ipojo.InstanceManager;
 import org.apache.felix.ipojo.PrimitiveHandler;
 import org.apache.felix.ipojo.architecture.HandlerDescription;

Modified: felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/MethodField.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/MethodField.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/MethodField.java (original)
+++ felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/MethodField.java Tue Oct 28 02:35:36 2008
@@ -52,7 +52,7 @@
     }
 
     /**
-     * Gets the method
+     * Gets the method.
      * @return the method
      */
     public MethodMetadata getMethod() {
@@ -60,7 +60,7 @@
     }
 
     /**
-     * Gets the description
+     * Gets the description.
      * @return the description
      */
     public String getDescription() {
@@ -68,7 +68,7 @@
     }
 
     /**
-     * Gets the name
+     * Gets the name.
      * @return the name
      */
     public String getName() {

Modified: felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/PropertyField.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/PropertyField.java?rev=708492&r1=708491&r2=708492&view=diff
==============================================================================
--- felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/PropertyField.java (original)
+++ felix/trunk/ipojo/handler/jmx/src/main/java/org/apache/felix/ipojo/handlers/jmx/PropertyField.java Tue Oct 28 02:35:36 2008
@@ -71,7 +71,7 @@
     }
 
     /**
-     * Returns the field
+     * Returns the field.
      * @return the field
      */
     public String getField() {
@@ -79,7 +79,7 @@
     }
 
     /**
-     * Modify the field
+     * Modifies the field.
      * @param field the new field
      */
     public void setField(String field) {
@@ -87,7 +87,7 @@
     }
 
     /**
-     * Returns the name
+     * Returns the name.
      * @return the name
      */
     public String getName() {
@@ -95,7 +95,7 @@
     }
 
     /**
-     * Modify the name
+     * Modifies the name.
      * @param name the new name
      */
     public void setName(String name) {
@@ -103,7 +103,7 @@
     }
 
     /**
-     * Returns the rights
+     * Returns the rights.
      * @return the rights
      */
     public String getRights() {
@@ -111,7 +111,7 @@
     }
 
     /**
-     * Modify the rights
+     * Modifies the rights.
      * @param rights the new rights
      */
     public void setRights(String rights) {
@@ -119,7 +119,7 @@
     }
 
     /**
-     * Returns the value
+     * Returns the value.
      * @return the value
      */
     public Object getValue() {
@@ -127,7 +127,7 @@
     }
 
     /**
-     * Modify the value
+     * Modifies the value.
      * @param value the new value
      */
     public void setValue(Object value) {
@@ -135,7 +135,7 @@
     }
 
     /**
-     * Returns the type
+     * Returns the type.
      * @return the type
      */
     public String getType() {
@@ -143,11 +143,11 @@
     }
 
     /**
-     * Returns the description
+     * Returns the description.
      * @return the description
      */
     public String getDescription() {
-        // TODO Auto-generated method stub
+        //TODO Implement this method.
         return null;
     }