Code refactoring (header, javadoc, cosmetic fixes...)

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@963746 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/webconsole-plugin/src/main/java/org/apache/felix/ipojo/webconsole/IPOJOPlugin.java b/ipojo/webconsole-plugin/src/main/java/org/apache/felix/ipojo/webconsole/IPOJOPlugin.java
index ff0dd2c..7e69c48 100644
--- a/ipojo/webconsole-plugin/src/main/java/org/apache/felix/ipojo/webconsole/IPOJOPlugin.java
+++ b/ipojo/webconsole-plugin/src/main/java/org/apache/felix/ipojo/webconsole/IPOJOPlugin.java
@@ -1,3 +1,21 @@
+/* 
+ * 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.webconsole;
 
 import java.io.ByteArrayOutputStream;
@@ -5,7 +23,6 @@
 import java.io.InputStream;
 import java.io.PrintWriter;
 import java.net.URL;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.List;
@@ -15,7 +32,6 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.felix.ipojo.ComponentInstance;
 import org.apache.felix.ipojo.Factory;
 import org.apache.felix.ipojo.HandlerFactory;
 import org.apache.felix.ipojo.annotations.Component;
@@ -29,10 +45,8 @@
 import org.apache.felix.ipojo.architecture.PropertyDescription;
 import org.apache.felix.ipojo.handlers.dependency.DependencyDescription;
 import org.apache.felix.ipojo.handlers.dependency.DependencyHandlerDescription;
-import org.apache.felix.ipojo.handlers.providedservice.ProvidedService;
 import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceDescription;
 import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandlerDescription;
-import org.apache.felix.ipojo.util.DependencyModel;
 import org.apache.felix.webconsole.AbstractWebConsolePlugin;
 import org.apache.felix.webconsole.DefaultVariableResolver;
 import org.apache.felix.webconsole.WebConsoleUtil;
@@ -42,33 +56,61 @@
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 
+/**
+ * iPOJO Web Console plugin.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@SuppressWarnings("serial")
 @Component(immediate=true)
 @Provides
 @Instantiate
 public class IPOJOPlugin extends AbstractWebConsolePlugin {
     
+    /**
+     * Used CSS files.
+     */
     private static final String CSS[] = { "/res/ui/bundles.css" , "/iPOJO/res/ui/ipojo.css" };
 
+    /**
+     * Template : Instance list.
+     */
     private final String INSTANCES;
+    
+    /**
+     * Template : Factory list.
+     */
     private final String FACTORIES;
+    
+    /**
+     * Template : Handler list. 
+     */
     private final String HANDLERS;
+    
+    /**
+     * Template : Factory details. 
+     */
     private final String FACTORY_DETAILS;
+    
+    /**
+     * Template : Instance details. 
+     */
     private final String INSTANCE_DETAILS;
 
-
-    
     /**
      * Label used by the web console.
      */
     @ServiceProperty(name = "felix.webconsole.label")
-    private String m_label = "iPOJO"; // TODO CHANGE
+    private String m_label = "iPOJO";
 
     /**
      * Title used by the web console.
      */
     @ServiceProperty(name = "felix.webconsole.title")
-    private String m_title = "iPOJO";  // TODO CHANGE
+    private String m_title = "iPOJO"; 
     
+    /**
+     * CSS files used by the plugin.
+     */
     @ServiceProperty(name= "felix.webconsole.css")
     protected String[] m_css = CSS;
 
@@ -90,16 +132,24 @@
     @Requires(optional = true, specification = "org.apache.felix.ipojo.HandlerFactory")
     private List<HandlerFactory> m_handlers;
     
+    /**
+     * Instantiates the plugin.
+     * This method loads all template files.
+     */
     public IPOJOPlugin() {
-        INSTANCES = readTemplateFile(this.getClass(), "/res/instances.html" );
-        FACTORIES = readTemplateFile(this.getClass(), "/res/factories.html" );
-        HANDLERS = readTemplateFile(this.getClass(), "/res/handlers.html" );
-        FACTORY_DETAILS = readTemplateFile(this.getClass(), "/res/factory.html" );
-        INSTANCE_DETAILS = readTemplateFile(this.getClass(), "/res/instance.html" );
+        INSTANCES = readTemplate("/res/instances.html" );
+        FACTORIES = readTemplate("/res/factories.html" );
+        HANDLERS = readTemplate("/res/handlers.html" );
+        FACTORY_DETAILS = readTemplate("/res/factory.html" );
+        INSTANCE_DETAILS = readTemplate("/res/instance.html" );
     }
     
-    private final String readTemplateFile(final Class clazz,
-            final String templateFile) {
+    /**
+     * Helper method loading a template file.
+     * @param templateFile the template file name
+     * @return the template
+     */
+    private final String readTemplate(final String templateFile) {
         InputStream templateStream = getClass().getResourceAsStream(
                 templateFile);
         if (templateStream != null) {
@@ -127,80 +177,102 @@
 
         // template file does not exist, return an empty string
         log("readTemplateFile: File '" + templateFile
-                + "' not found through class " + clazz);
+                + "' not found through class " + this.getClass());
         return "";
     }
 
+    /**
+     * This methods is called by the web console when the plugin is required.
+     * This methods writes the corresponding page (loads template and set variables).
+     * @param request the request
+     * @param response the response
+     * @throws ServletException something bad happened
+     * @throws IOException something bad happened
+     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#renderContent(
+     *  javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
     @Override
     protected void renderContent(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
         // get request info from request attribute
-        final RequestInfo reqInfo = getRequestInfo(request);
+        final RequestInfo reqInfo = new RequestInfo(request);
         // prepare variables
         DefaultVariableResolver vars = ( ( DefaultVariableResolver ) WebConsoleUtil.getVariableResolver( request ) );
-        
-        System.out.println("Render content for " + request.getPathInfo());
-        
-        if (reqInfo.instances) {
-            if (reqInfo.name == null) {
+                
+        if (reqInfo.instances) { // Instance
+            if (reqInfo.name == null) { // All
                 response.getWriter().print( INSTANCES );
-            } else {
-                System.out.println("Details for " + reqInfo.name);
-                vars.put("name", reqInfo.name);
+            } else { // Specific
+                vars.put("name", reqInfo.name); // Inject the name variable.
                 response.getWriter().print( INSTANCE_DETAILS );
             }
-        } else if (reqInfo.factories) {
-            if (reqInfo.name == null) {
+        } else if (reqInfo.factories) { // Factory
+            if (reqInfo.name == null) { // All
                 response.getWriter().print( FACTORIES );
-            } else {
-                vars.put("name", reqInfo.name);
+            } else { // Specific
+                vars.put("name", reqInfo.name); // Inject the name variable.
                 response.getWriter().print( FACTORY_DETAILS );
             }
-        } else if (reqInfo.handlers) {
+        } else if (reqInfo.handlers) { // Handlers
             response.getWriter().print( HANDLERS );
+            // No detailed view for handlers.
         } else {
             // Default
             response.getWriter().print( INSTANCES );
         }
     }
     
-    private void renderAllInstances(PrintWriter pw) {
+    /**
+     * Writes the JSON object containing the info for all instances.
+     * @param pw the writer where the json object is printed.
+     * @throws IOException the JSON object cannot be written
+     */
+    private void getAllInstances(PrintWriter pw) throws IOException {
         try {
             JSONObject resp = new JSONObject();
+            // Statline:
             resp.put("count", m_archs.size());
-            resp.put("valid_count", getValidCount());
-            resp.put("invalid_count", getInvalidCount());
+            resp.put("valid_count", StateUtils.getValidInstancesCount(m_archs));
+            resp.put("invalid_count", StateUtils.getInvalidInstancesCount(m_archs));
+            // End statline
             
             JSONArray instances = new JSONArray();
             for (Architecture arch : m_archs) {
                 JSONObject instance = new JSONObject();
                 instance.put("name", arch.getInstanceDescription().getName());
                 instance.put("factory", arch.getInstanceDescription().getComponentDescription().getName());
-                instance.put("state", getInstanceState(arch.getInstanceDescription().getState()));
+                instance.put("state", StateUtils.getInstanceState(arch.getInstanceDescription().getState()));
                 instances.put(instance);
             }
             resp.put("data", instances);
             
             pw.print(resp.toString());
         } catch (JSONException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            // Propagate the exception.
+            throw new IOException(e.toString());
         }
     }
     
-    private void renderAllFactories(PrintWriter pw) {
+    /**
+     * Writes the JSON object containing the info for all factories.
+     * @param pw the writer when the json object is printed
+     * @throws IOException the JSON object cannot be written
+     */
+    private void getAllFactories(PrintWriter pw) throws IOException {
         try {
             JSONObject resp = new JSONObject();
+            // Statline:
             resp.put("count", m_factories.size());
-            resp.put("valid_count", getValidFactoriesCount());
-            resp.put("invalid_count", getInvalidFactoriesCount());
-            
+            resp.put("valid_count", StateUtils.getValidFactoriesCount(m_factories));
+            resp.put("invalid_count", StateUtils.getInvalidFactoriesCount(m_factories));
+            // End statline
+
             JSONArray factories = new JSONArray();
             for (Factory factory : m_factories) {
                 String version = factory.getVersion();
                 String name = factory.getName();
                 
-                String state = getFactoryState(factory.getState());
+                String state = StateUtils.getFactoryState(factory.getState());
                 String bundle = factory.getBundleContext().getBundle().getSymbolicName()
                     + " (" + factory.getBundleContext().getBundle().getBundleId() + ")";
                 JSONObject fact = new JSONObject();
@@ -216,24 +288,32 @@
             
             pw.print(resp.toString());
         } catch (JSONException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            // Propagate the exception.
+            throw new IOException(e.toString());
         }
     }
     
-    private void renderAllHandlers(PrintWriter pw) {
+    /**
+     * Writes the JSON object containing the info for all handlers.
+     * @param pw the writer when the json object is printed
+     * @throws IOException the JSON object cannot be written
+     */
+    private void getAllHandlers(PrintWriter pw) throws IOException {
         try {
             JSONObject resp = new JSONObject();
+
+            // Statline:
             resp.put("count", m_handlers.size());
-            resp.put("valid_count", getValidHandlersCount());
-            resp.put("invalid_count", getInvalidHandlersCount());
+            resp.put("valid_count", StateUtils.getValidHandlersCount(m_handlers));
+            resp.put("invalid_count", StateUtils.getInvalidHandlersCount(m_handlers));
+            // End statline
             
             JSONArray factories = new JSONArray();
             for (HandlerFactory factory : m_handlers) {
                 String version = factory.getVersion();
                 String name = factory.getHandlerName();
                 
-                String state = getFactoryState(factory.getState());
+                String state = StateUtils.getFactoryState(factory.getState());
                 String bundle = factory.getBundleContext().getBundle().getSymbolicName()
                     + " (" + factory.getBundleContext().getBundle().getBundleId() + ")";
                 JSONObject fact = new JSONObject();
@@ -253,13 +333,18 @@
             
             pw.print(resp.toString());
         } catch (JSONException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            // Propagate the exception.
+            throw new IOException(e.toString());
         }
     }
     
-    private void renderFactoryDetail(PrintWriter pw, String name) {
-        System.out.println("Render factory detail for " + name);
+    /**
+     * Writes the JSON object containing details about a specific factory.
+     * @param pw the writer
+     * @param name the factory name
+     * @throws IOException if the json object cannot be written.
+     */
+    private void getFactoryDetail(PrintWriter pw, String name) throws IOException{
         // Find the factory
         Factory factory = null;
         for (Factory fact : m_factories) {
@@ -269,32 +354,37 @@
         }
         
         if (factory == null) {
+            // This will be used a error message (cannot be interpreted as json)
             pw.println("The factory " + name + " does not exist or is private");
-            System.err.println("factory " + name + "  not found");
             return;
         }
         
         try {
             JSONObject resp = new JSONObject();
+            
+            // Statline.
             resp.put("count", m_factories.size());
-            resp.put("valid_count", getValidFactoriesCount());
-            resp.put("invalid_count", getInvalidFactoriesCount());
+            resp.put("valid_count", StateUtils.getValidFactoriesCount(m_factories));
+            resp.put("invalid_count", StateUtils.getInvalidFactoriesCount(m_factories));
+            // End of the statline
             
             // Factory object
             JSONObject data = new JSONObject();
             data.put("name", factory.getName());
-            data.put("state", getFactoryState(factory.getState()));
+            data.put("state", StateUtils.getFactoryState(factory.getState()));
             
             String bundle = factory.getBundleContext().getBundle().getSymbolicName()
             + " (" + factory.getBundleContext().getBundle().getBundleId() + ")";
             data.put("bundle", bundle);
             
+            // Provided service specifications
             if (factory.getComponentDescription().getprovidedServiceSpecification().length != 0) {
                 JSONArray services = new JSONArray
                     (Arrays.asList(factory.getComponentDescription().getprovidedServiceSpecification()));
                 data.put("services", services);
             }
             
+            // Properties
             PropertyDescription[] props = factory.getComponentDescription().getProperties();
             if (props != null  && props.length != 0) {
                 JSONArray properties = new JSONArray();
@@ -324,7 +414,7 @@
                 data.put("missingHandlers", req);
             }
             
-            List instances = getInstanceList(name);
+            List<?> instances = StateUtils.getInstanceList(m_archs, name);
             if (! instances.isEmpty()) {
                 JSONArray req = new JSONArray(instances);
                 data.put("instances", req);
@@ -335,14 +425,19 @@
             
             pw.print(resp.toString());
         } catch (JSONException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            // Propagate the exception.
+            throw new IOException(e.toString());
         }
         
     }
     
-    private void renderInstanceDetail(PrintWriter pw, String name) {
-        System.out.println("Render instance detail for " + name);
+    /**
+     * Writes the JSON object containing details about a specific instance.
+     * @param pw the writer
+     * @param name the instance name
+     * @throws IOException if the json object cannot be written.
+     */
+    private void getInstanceDetail(PrintWriter pw, String name) throws IOException {
         // Find the factory
         InstanceDescription instance = null;
         for (Architecture arch : m_archs) {
@@ -352,21 +447,22 @@
         }
         
         if (instance == null) {
-            pw.println("The instance " + name + " does not exist or does not exposed its architecture");
-            System.err.println("instance " + name + "  not found");
+            // This will be used a error message (cannot be interpreted as json)
+            pw.println("The instance " + name + " does not exist or " +
+            		"does not exposed its architecture");
             return;
         }
         
         try {
             JSONObject resp = new JSONObject();
             resp.put("count", m_factories.size());
-            resp.put("valid_count", getValidFactoriesCount());
-            resp.put("invalid_count", getInvalidFactoriesCount());
+            resp.put("valid_count", StateUtils.getValidFactoriesCount(m_factories));
+            resp.put("invalid_count", StateUtils.getInvalidFactoriesCount(m_factories));
             
             // instance object
             JSONObject data = new JSONObject();
             data.put("name", instance.getName());
-            data.put("state", getInstanceState(instance.getState()));
+            data.put("state", StateUtils.getInstanceState(instance.getState()));
             data.put("factory", instance.getComponentDescription().getName());
             
             JSONArray services = getProvidedServiceDetail(instance.getHandlerDescription("org.apache.felix.ipojo:provides"));
@@ -384,51 +480,63 @@
             
             pw.print(resp.toString());
         } catch (JSONException e) {
-            // TODO Auto-generated catch block
-            e.printStackTrace();
+            // Propagate the exception.
+            throw new IOException(e.toString());
         }
         
     }
     
+    /**
+     * Endpoint dealing with JSON requests.
+     * @param request the request
+     * @param response the response
+     * @throws ServletException if an error occurred
+     * @throws IOException if an error occurred
+     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#doGet
+     *  (javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+     */
     @Override
     protected void doGet(HttpServletRequest request,
             HttpServletResponse response) throws ServletException, IOException {
         final RequestInfo reqInfo = new RequestInfo(request);
         
-        if ( reqInfo.extension.equals("json")  )
-        {
-            response.setContentType( "application/json" );
-            //response.setCharacterEncoding( "UTF-8" );
+        if (reqInfo.extension.equals("json")) {
+            response.setContentType("application/json");
             if (reqInfo.instances) {
                 if (reqInfo.name == null) {
-                    this.renderAllInstances(response.getWriter());
+                    this.getAllInstances(response.getWriter());
                     return;
                 } else {
-                    this.renderInstanceDetail(response.getWriter(), reqInfo.name);
+                    this.getInstanceDetail(response.getWriter(), reqInfo.name);
                     return;
                 }
             }
-            
+
             if (reqInfo.factories) {
                 if (reqInfo.name == null) {
-                    this.renderAllFactories(response.getWriter());
+                    this.getAllFactories(response.getWriter());
                     return;
                 } else {
-                    System.out.println("Render details for " + reqInfo.name);
-                    this.renderFactoryDetail(response.getWriter(), reqInfo.name);
+                    this.getFactoryDetail(response.getWriter(), reqInfo.name);
                     return;
                 }
             }
-            
+
             if (reqInfo.handlers) {
-                this.renderAllHandlers(response.getWriter());
+                this.getAllHandlers(response.getWriter());
             }
             // nothing more to do
             return;
         }
-        super.doGet( request, response );
+        // Otherwise, delegate to super.
+        super.doGet(request, response);
     }
     
+    /**
+     * Allows loading the 'ui' folder as web resource.
+     * @param path the resource path
+     * @return the internal resource url.
+     */
     public URL getResource(String path) {
         if (path.contains("/res/ui/")) {
             return this.getClass().getResource(
@@ -437,6 +545,12 @@
         return null;
     }
     
+    /**
+     * Creates the JSON Array describing the provided services.
+     * @param hd the provided service handler
+     * @return the JSON Array or null if no provided service
+     * @throws JSONException if the array cannot be created.
+     */
     private JSONArray getProvidedServiceDetail(HandlerDescription hd) throws JSONException {
         if (hd == null) {
             return null;
@@ -452,7 +566,7 @@
                 spec = spec.substring(1, spec.length() - 1);
             }
             svc.put("specification", spec);
-            svc.put("state", getProvidedServiceState(ps.getState()));
+            svc.put("state", StateUtils.getProvidedServiceState(ps.getState()));
             
             if (ps.getServiceReference() != null) {
                 svc.put("id", (Long) ps.getServiceReference().getProperty(Constants.SERVICE_ID));
@@ -468,6 +582,13 @@
         return array;
     }
     
+    /**
+     * Builds the JSON Array containing object representing the given properties
+     * (name / value pair).
+     * @param properties the properties
+     * @return the JSON Array
+     * @throws JSONException if the array cannot be created correctly
+     */
     private JSONArray getServiceProperties(Properties properties) throws JSONException {
         JSONArray array = new JSONArray();
         Enumeration<Object> e = properties.keys();
@@ -489,6 +610,13 @@
         return array;
     }
     
+    /**
+     * Builds the JSON Array representing the required services.
+     * @param hd the dependency handler
+     * @return the array containing JSON object representing service
+     * dependencies, or null if there is no service dependency.
+     * @throws JSONException if the JSON array cannot be created.
+     */
     private JSONArray getRequiredServiceDetail(
             HandlerDescription hd) throws JSONException {
         if (hd == null) {
@@ -500,8 +628,8 @@
             JSONObject req = new JSONObject();
             req.put("specification",dep.getSpecification());
             req.put("id", dep.getId());
-            req.put("state", getDependencyState(dep.getState()));
-            req.put("policy", getDependencyBindingPolicy(dep.getPolicy()));
+            req.put("state", StateUtils.getDependencyState(dep.getState()));
+            req.put("policy", StateUtils.getDependencyBindingPolicy(dep.getPolicy()));
             req.put("optional", dep.isOptional());
             req.put("aggregate", dep.isMultiple());
             if (dep.getFilter() != null) {
@@ -521,6 +649,15 @@
         return array;
     }
     
+    /**
+     * Builds the JSON Array representing the given service reference list.
+     * The array contains JSON objects. Those object contains the service id (id)
+     * as well as the instance name (instance) if the property is set in the service
+     * reference.
+     * @param refs the service reference list
+     * @return the JSON Array
+     * @throws JSONException if the array cannot be created.
+     */
     private JSONArray getServiceReferenceList(List<ServiceReference> refs) throws JSONException {
         JSONArray array = new JSONArray();
         if (refs != null) {
@@ -539,140 +676,77 @@
     }
     
     /**
-     * Gets the number of valid instances.
-     * @return the number of valid instances.
+     * Gets the plugin label.
+     * @return the label.
+     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#getLabel()
      */
-    private int getValidCount() {
-        int i = 0;
-        for (Architecture a : m_archs) { // Cannot be null, an empty list is returned.
-            if (a.getInstanceDescription().getState() == ComponentInstance.VALID) {
-                i ++;
-            }
-        }
-        return i;
+    @Override
+    public String getLabel() {
+       return m_label;
     }
 
     /**
-     * Gets the number of invalid instances.
-     * @return the number of invalid instances.
+     * Gets the plugin title.
+     * @return the title
+     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#getTitle()
      */
-    private int getInvalidCount() {
-        int i = 0;
-        for (Architecture a : m_archs) {  // Cannot be null, an empty list is returned.
-            if (a.getInstanceDescription().getState() == ComponentInstance.INVALID) {
-                i ++;
-            }
-        }
-        return i;
-    }
-    
-    private int getValidFactoriesCount() {
-        int i = 0;
-        for (Factory a : m_factories) { // Cannot be null, an empty list is returned.
-            if (a.getState() == Factory.VALID) {
-                i ++;
-            }
-        }
-        return i;
-    }
-    
-    private int getInvalidFactoriesCount() {
-        int i = 0;
-        for (Factory a : m_factories) { // Cannot be null, an empty list is returned.
-            if (a.getState() == Factory.INVALID) {
-                i ++;
-            }
-        }
-        return i;
-    }
-    
-    private int getValidHandlersCount() {
-        int i = 0;
-        for (Factory a : m_handlers) { // Cannot be null, an empty list is returned.
-            if (a.getState() == Factory.VALID) {
-                i ++;
-            }
-        }
-        return i;
-    }
-    
-    private int getInvalidHandlersCount() {
-        int i = 0;
-        for (Factory a : m_handlers) { // Cannot be null, an empty list is returned.
-            if (a.getState() == Factory.INVALID) {
-                i ++;
-            }
-        }
-        return i;
+    @Override
+    public String getTitle() {
+        return m_title;
     }
     
     /**
-     * Gets the instance state as a String.
-     * @param state the state.
-     * @return the String form of the state.
+     * Get the CSS used by the plugin.
+     * @return the list of CSS
+     * @see org.apache.felix.webconsole.AbstractWebConsolePlugin#getCssReferences()
      */
-    private static String getInstanceState(int state) {
-        switch(state) {
-            case ComponentInstance.VALID :
-                return "valid";
-            case ComponentInstance.INVALID :
-                return "invalid";
-            case ComponentInstance.DISPOSED :
-                return "disposed";
-            case ComponentInstance.STOPPED :
-                return "stopped";
-            default :
-                return "unknown";
-        }
+    @Override
+    protected String[] getCssReferences() {
+        return CSS;
     }
 
+
+
     /**
-     * Gets the factory state as a String.
-     * @param state the state.
-     * @return the String form of the state.
+     * Parse request to extract the query.
      */
-    private static String getFactoryState(int state) {
-        switch(state) {
-            case Factory.VALID :
-                return "valid";
-            case Factory.INVALID :
-                return "invalid";
-            default :
-                return "unknown";
-        }
-    }
-    
-    /**
-     * Gets the instance list created by the given factory.
-     * @param factory the factory name
-     * @return the list containing the created instances (name)
-     */
-    private List getInstanceList(String factory) {
-        List list = new ArrayList();
-        for (Architecture arch : m_archs) { // Cannot be null, an empty list is returned.
-            String n = arch.getInstanceDescription().getComponentDescription().getName();
-            if (factory.equals(n)) {
-                list.add(arch.getInstanceDescription().getName());
-            }
-        }
-        return list;
-    }
-    
     private final class RequestInfo {
+        /**
+         * The extension.
+         */
         public final String extension;
+        /**
+         * The path.
+         */
         public final String path;
+        /**
+         * The instances.
+         */
         public final boolean instances;
+        /**
+         * The factories.
+         */
         public final boolean factories;
+        /**
+         * The handlers.
+         */
         public final boolean handlers;
         
+        /**
+         * The specific factory or instance name.
+         */
         public final String name;
-
+    
         
+        /**
+         * Creates a RequestInfo.
+         * @param request the request
+         */
         protected RequestInfo( final HttpServletRequest request ) {
             String info = request.getPathInfo();
             // remove label and starting slash
             info = info.substring(getLabel().length() + 1);
-
+    
             // get extension
             if (info.endsWith(".json")) {
                 extension = "json";
@@ -680,16 +754,13 @@
             } else {
                 extension = "html";
             }
-
+    
             if (info.startsWith("/")) {
                 path = info.substring(1);
-                System.out.println("Info " + info);
-
+    
                 instances = path.startsWith("instances");
                 factories = path.startsWith("factories");
                 handlers = path.startsWith("handlers");
-               
-                System.out.println("Path " + path);
                 
                 if (instances  && path.startsWith("instances/")) {
                     name = path.substring("instances".length() + 1);
@@ -708,78 +779,7 @@
            
             request.setAttribute(IPOJOPlugin.class.getName(), this);
         }
-
-    }
-
-    static RequestInfo getRequestInfo(final HttpServletRequest request) {
-        return (RequestInfo) request.getAttribute(IPOJOPlugin.class.getName());
-    }
-
-    @Override
-    public String getLabel() {
-       return m_label;
-    }
-
-    @Override
-    public String getTitle() {
-        return m_title;
-    }
     
-    @Override
-    protected String[] getCssReferences() {
-        return CSS;
-    }
-    
-    /**
-     * Gets the dependency state as a String.
-     * @param state the state.
-     * @return the String form of the state.
-     */
-    private static String getDependencyState(int state) {
-        switch(state) {
-            case DependencyModel.RESOLVED :
-                return "resolved";
-            case DependencyModel.UNRESOLVED :
-                return "unresolved";
-            case DependencyModel.BROKEN :
-                return "broken";
-            default :
-                return "unknown (" + state + ")";
-        }
-    }
-
-    /**
-     * Gets the dependency binding policy as a String.
-     * @param policy the policy.
-     * @return the String form of the policy.
-     */
-    private static String getDependencyBindingPolicy(int policy) {
-        switch(policy) {
-            case DependencyModel.DYNAMIC_BINDING_POLICY :
-                return "dynamic";
-            case DependencyModel.DYNAMIC_PRIORITY_BINDING_POLICY :
-                return "dynamic-priority";
-            case DependencyModel.STATIC_BINDING_POLICY :
-                return "static";
-            default :
-                return "unknown (" + policy + ")";
-        }
-    }
-
-    /**
-     * Gets the provided service state as a String.
-     * @param state the state.
-     * @return the String form of the state.
-     */
-    private static String getProvidedServiceState(int state) {
-        switch(state) {
-            case ProvidedService.REGISTERED :
-                return "registered";
-            case ProvidedService.UNREGISTERED :
-                return "unregistered";
-            default :
-                return "unknown (" + state + ")";
-        }
     }
 
 }
diff --git a/ipojo/webconsole-plugin/src/main/java/org/apache/felix/ipojo/webconsole/StateUtils.java b/ipojo/webconsole-plugin/src/main/java/org/apache/felix/ipojo/webconsole/StateUtils.java
new file mode 100644
index 0000000..c4eec56
--- /dev/null
+++ b/ipojo/webconsole-plugin/src/main/java/org/apache/felix/ipojo/webconsole/StateUtils.java
@@ -0,0 +1,233 @@
+/* 
+ * 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.webconsole;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.HandlerFactory;
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.handlers.providedservice.ProvidedService;
+import org.apache.felix.ipojo.util.DependencyModel;
+
+
+/**
+ * Helper class dealing with instance and factory states.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class StateUtils {
+    
+    /**
+     * Gets the number of valid instances.
+     * @param archs the instance architecture list
+     * @return the number of valid instances.
+     */
+    public static int getValidInstancesCount(List<Architecture> archs) {
+        int i = 0;
+        for (Architecture a : archs) { // Cannot be null, an empty list is returned.
+            if (a.getInstanceDescription().getState() == ComponentInstance.VALID) {
+                i ++;
+            }
+        }
+        return i;
+    }
+
+    /**
+     * Gets the number of invalid instances.
+     * @param archs the instance architecture list
+     * @return the number of invalid instances.
+     */
+    public static int getInvalidInstancesCount(List<Architecture> archs) {
+        int i = 0;
+        for (Architecture a : archs) {  // Cannot be null, an empty list is returned.
+            if (a.getInstanceDescription().getState() == ComponentInstance.INVALID) {
+                i ++;
+            }
+        }
+        return i;
+    }
+    
+    /**
+     * Gets the number of valid factories.
+     * @param factories the factory list
+     * @return the number of valid factories.
+     */
+    public static int getValidFactoriesCount(List<Factory> factories) {
+        int i = 0;
+        for (Factory a : factories) { // Cannot be null, an empty list is returned.
+            if (a.getState() == Factory.VALID) {
+                i ++;
+            }
+        }
+        return i;
+    }
+    
+    /**
+     * Gets the number of invalid factories.
+     * @param factories the factory list
+     * @return the number of invalid factories.
+     */
+    public static int getInvalidFactoriesCount(List<Factory> factories) {
+        int i = 0;
+        for (Factory a : factories) { // Cannot be null, an empty list is returned.
+            if (a.getState() == Factory.INVALID) {
+                i ++;
+            }
+        }
+        return i;
+    }
+    
+    /**
+     * Gets the number of valid handlers.
+     * @param handlers the handler factory list
+     * @return the number of valid handlers.
+     */
+    public static int getValidHandlersCount(List<HandlerFactory> handlers) {
+        int i = 0;
+        for (Factory a : handlers) { // Cannot be null, an empty list is returned.
+            if (a.getState() == Factory.VALID) {
+                i ++;
+            }
+        }
+        return i;
+    }
+    
+    /**
+     * Gets the number of invalid handlers.
+     * @param handlers the handler factory list
+     * @return the number of invalid handlers.
+     */
+    public static int getInvalidHandlersCount(List<HandlerFactory> handlers) {
+        int i = 0;
+        for (Factory a : handlers) { // Cannot be null, an empty list is returned.
+            if (a.getState() == Factory.INVALID) {
+                i ++;
+            }
+        }
+        return i;
+    }
+    
+    /**
+     * Gets the instance state as a String.
+     * @param state the state.
+     * @return the String form of the state.
+     */
+    public static String getInstanceState(int state) {
+        switch(state) {
+            case ComponentInstance.VALID :
+                return "valid";
+            case ComponentInstance.INVALID :
+                return "invalid";
+            case ComponentInstance.DISPOSED :
+                return "disposed";
+            case ComponentInstance.STOPPED :
+                return "stopped";
+            default :
+                return "unknown";
+        }
+    }
+
+    /**
+     * Gets the factory state as a String.
+     * @param state the state.
+     * @return the String form of the state.
+     */
+    public static String getFactoryState(int state) {
+        switch(state) {
+            case Factory.VALID :
+                return "valid";
+            case Factory.INVALID :
+                return "invalid";
+            default :
+                return "unknown";
+        }
+    }
+    
+    /**
+     * Gets the instance list created by the given factory.
+     * @param archs the list of instance architectures
+     * @param factory the factory name
+     * @return the list containing the created instances (name)
+     */
+    public static List<String> getInstanceList(List<Architecture> archs, String factory) {
+        List<String> list = new ArrayList<String>();
+        for (Architecture arch : archs) { // Cannot be null, an empty list is returned.
+            String n = arch.getInstanceDescription().getComponentDescription().getName();
+            if (factory.equals(n)) {
+                list.add(arch.getInstanceDescription().getName());
+            }
+        }
+        return list;
+    }
+    
+    /**
+     * Gets the dependency state as a String.
+     * @param state the state.
+     * @return the String form of the state.
+     */
+    public static String getDependencyState(int state) {
+        switch(state) {
+            case DependencyModel.RESOLVED :
+                return "resolved";
+            case DependencyModel.UNRESOLVED :
+                return "unresolved";
+            case DependencyModel.BROKEN :
+                return "broken";
+            default :
+                return "unknown (" + state + ")";
+        }
+    }
+
+    /**
+     * Gets the dependency binding policy as a String.
+     * @param policy the policy.
+     * @return the String form of the policy.
+     */
+    public static String getDependencyBindingPolicy(int policy) {
+        switch(policy) {
+            case DependencyModel.DYNAMIC_BINDING_POLICY :
+                return "dynamic";
+            case DependencyModel.DYNAMIC_PRIORITY_BINDING_POLICY :
+                return "dynamic-priority";
+            case DependencyModel.STATIC_BINDING_POLICY :
+                return "static";
+            default :
+                return "unknown (" + policy + ")";
+        }
+    }
+
+    /**
+     * Gets the provided service state as a String.
+     * @param state the state.
+     * @return the String form of the state.
+     */
+    public static String getProvidedServiceState(int state) {
+        switch(state) {
+            case ProvidedService.REGISTERED :
+                return "registered";
+            case ProvidedService.UNREGISTERED :
+                return "unregistered";
+            default :
+                return "unknown (" + state + ")";
+        }
+    }
+
+}