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 2010/07/12 19:36:51 UTC

svn commit: r963381 - in /felix/trunk/ipojo/webconsole-plugin: ./ src/main/java/org/apache/felix/ipojo/webconsole/ src/main/resources/res/ src/main/resources/res/ui/

Author: clement
Date: Mon Jul 12 17:36:50 2010
New Revision: 963381

URL: http://svn.apache.org/viewvc?rev=963381&view=rev
Log:
Modify the pom to include 'res'
Add the factories template
Add the instances template
Add the ipojo,js retrieving the instance list
Add the factories.js retrieving the factory list
Modify the IPOJOPlugin to support the factories and
instances template as well as the JSON messages
to retrives the lists.

Added:
    felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/
    felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/factories.html
    felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/instances.html
    felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/ui/
    felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/ui/factory.js
    felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/ui/ipojo.js
Modified:
    felix/trunk/ipojo/webconsole-plugin/pom.xml
    felix/trunk/ipojo/webconsole-plugin/src/main/java/org/apache/felix/ipojo/webconsole/IPOJOPlugin.java

Modified: felix/trunk/ipojo/webconsole-plugin/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/webconsole-plugin/pom.xml?rev=963381&r1=963380&r2=963381&view=diff
==============================================================================
--- felix/trunk/ipojo/webconsole-plugin/pom.xml (original)
+++ felix/trunk/ipojo/webconsole-plugin/pom.xml Mon Jul 12 17:36:50 2010
@@ -48,7 +48,7 @@
       <plugin>
         <groupId>org.apache.felix</groupId>
         <artifactId>maven-bundle-plugin</artifactId>
-        <version>1.4.3</version>
+        <version>2.0.1</version>
         <extensions>true</extensions>
         <configuration>
           <instructions>
@@ -62,15 +62,19 @@
             </Private-Package>
             <Import-Package>*</Import-Package>
             <Include-Resource> META-INF/LICENSE=LICENSE,
-              META-INF/NOTICE=NOTICE
+              META-INF/NOTICE=NOTICE, res=src/main/resources/res
              </Include-Resource>
+             <Embed-Dependency>
+                <!-- Required for JSON data transfer -->
+                json
+              </Embed-Dependency>
           </instructions>
         </configuration>
       </plugin>
       <plugin>
         <groupId>org.apache.felix</groupId>
         <artifactId>maven-ipojo-plugin</artifactId>
-        <version>1.4.0</version>
+        <version>1.6.0</version>
         <executions>
           <execution>
             <goals>
@@ -133,5 +137,11 @@
         <version>2.3</version>
         <scope>provided</scope>
     </dependency>
+     <dependency>
+        <groupId>org.json</groupId>
+        <artifactId>json</artifactId>
+        <version>20070829</version>
+        <scope>compile</scope>
+     </dependency>
   </dependencies>
 </project>

Modified: felix/trunk/ipojo/webconsole-plugin/src/main/java/org/apache/felix/ipojo/webconsole/IPOJOPlugin.java
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/webconsole-plugin/src/main/java/org/apache/felix/ipojo/webconsole/IPOJOPlugin.java?rev=963381&r1=963380&r2=963381&view=diff
==============================================================================
--- felix/trunk/ipojo/webconsole-plugin/src/main/java/org/apache/felix/ipojo/webconsole/IPOJOPlugin.java (original)
+++ felix/trunk/ipojo/webconsole-plugin/src/main/java/org/apache/felix/ipojo/webconsole/IPOJOPlugin.java Mon Jul 12 17:36:50 2010
@@ -1,12 +1,17 @@
 package org.apache.felix.ipojo.webconsole;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.net.URL;
 import java.util.List;
 
 import javax.servlet.ServletException;
 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;
@@ -16,12 +21,23 @@ import org.apache.felix.ipojo.annotation
 import org.apache.felix.ipojo.annotations.ServiceProperty;
 import org.apache.felix.ipojo.architecture.Architecture;
 import org.apache.felix.webconsole.AbstractWebConsolePlugin;
+import org.apache.felix.webconsole.DefaultVariableResolver;
+import org.apache.felix.webconsole.SimpleWebConsolePlugin;
+import org.apache.felix.webconsole.WebConsoleUtil;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
 
-@Component
+@Component(immediate=true)
 @Provides
 @Instantiate
 public class IPOJOPlugin extends AbstractWebConsolePlugin {
+    
+    private static final String CSS[] = { "/res/ui/bundles.css" };
 
+    private final String INSTANCES;
+    private final String FACTORIES;
+    
     /**
      * Label used by the web console.
      */
@@ -33,6 +49,9 @@ public class IPOJOPlugin extends Abstrac
      */
     @ServiceProperty(name = "felix.webconsole.title")
     private String m_title = "iPOJO_2";  // TODO CHANGE
+    
+    @ServiceProperty(name= "felix.webconsole.css")
+    private String m_css = CSS[0];
 
     /**
      * List of available Architecture service.
@@ -52,21 +71,325 @@ public class IPOJOPlugin extends Abstrac
     @Requires(optional = true, specification = "org.apache.felix.ipojo.HandlerFactory")
     private List<HandlerFactory> m_handlers;
     
+    public IPOJOPlugin() {
+        INSTANCES = readTemplateFile(this.getClass(), "/res/instances.html" );
+        FACTORIES = readTemplateFile(this.getClass(), "/res/factories.html" );
+
+    }
+    
+    private final String readTemplateFile(final Class clazz, final String templateFile)
+    {
+        InputStream templateStream = getClass().getResourceAsStream(templateFile);
+        if (templateStream != null)
+        {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            byte[] data = new byte[1024];
+            try
+            {
+                int len = 0;
+                while ((len = templateStream.read(data)) > 0)
+                {
+                    baos.write(data, 0, len);
+                }
+                return baos.toString("UTF-8");
+            }
+            catch (IOException e)
+            {
+                // don't use new Exception(message, cause) because cause is 1.4+
+                throw new RuntimeException("readTemplateFile: Error loading "
+                    + templateFile + ": " + e);
+            }
+            finally
+            {
+                try
+                {
+                    templateStream.close();
+                }
+                catch (IOException e)
+                {
+                    /* ignore */
+                }
+
+            }
+        }
+
+        // template file does not exist, return an empty string
+        log("readTemplateFile: File '" + templateFile + "' not found through class "
+            + clazz);
+        return "";
+    }
+
+    @Override
+    protected void renderContent(HttpServletRequest request, HttpServletResponse response)
+            throws ServletException, IOException {
+        // get request info from request attribute
+        final RequestInfo reqInfo = getRequestInfo(request);
+        // prepare variables
+        DefaultVariableResolver vars = ( ( DefaultVariableResolver ) WebConsoleUtil.getVariableResolver( request ) );
+        String view = request.getParameter("view");
+        
+        if (view == null || view.equals("instances")) {
+            response.getWriter().print( INSTANCES );
+        } else if (view.equals("factories")) {
+            response.getWriter().print( FACTORIES );
+        }                
+    }
+    
+    private void renderAllInstances(PrintWriter pw) {
+        try {
+            JSONObject resp = new JSONObject();
+            resp.put("count", m_archs.size());
+            resp.put("valid_count", getValidCount());
+            resp.put("invalid_count", getInvalidCount());
+            
+            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()));
+                instances.put(instance);
+            }
+            resp.put("data", instances);
+            
+            pw.print(resp.toString());
+        } catch (JSONException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+    
+    private void renderAllFactories(PrintWriter pw) {
+        try {
+            JSONObject resp = new JSONObject();
+            resp.put("count", m_factories.size());
+            resp.put("valid_count", getValidFactoriesCount());
+            resp.put("invalid_count", getValidFactoriesCount());
+            
+            JSONArray factories = new JSONArray();
+            for (Factory factory : m_factories) {
+                String version = factory.getVersion();
+                String name = factory.getName();
+                
+                String state = getFactoryState(factory.getState());
+                String bundle = factory.getBundleContext().getBundle().getSymbolicName()
+                    + " (" + factory.getBundleContext().getBundle().getBundleId() + ")";
+                JSONObject fact = new JSONObject();
+                fact.put("name", name);
+                if (version != null) {
+                    fact.put("version", version);
+                }
+                fact.put("bundle", bundle);
+                fact.put("state", state);
+                factories.put(fact);
+            }
+            resp.put("data", factories);
+            
+            pw.print(resp.toString());
+        } catch (JSONException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+    
+    @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.instances) {
+                if (reqInfo.name == null) {
+                    this.renderAllInstances(response.getWriter());
+                    return;
+                } else {
+                    // TODO
+                    return;
+                }
+            }
+            
+            if (reqInfo.factories) {
+                if (reqInfo.name == null) {
+                    this.renderAllFactories(response.getWriter());
+                    return;
+                } else {
+                    // TODO
+                    return;
+                }
+            }
+            
+            if (reqInfo.handlers) {
+                //TODO
+                return;
+            }
+            // nothing more to do
+            return;
+        }
+        super.doGet( request, response );
+    }
+    
+    public URL getResource(String path) {
+        if (path.contains("/res/ui/")) {
+            return this.getClass().getResource(
+                    path.substring(m_label.length() + 1));
+        }
+        return null;
+    }
+    
+    /**
+     * Gets the number of valid instances.
+     * @return the number of valid instances.
+     */
+    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;
+    }
+
+    /**
+     * Gets the number of invalid instances.
+     * @return the number of invalid instances.
+     */
+    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;
+    }
+    
+    /**
+     * Gets the instance state as a String.
+     * @param state the state.
+     * @return the String form of the state.
+     */
+    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";
+        }
+    }
+
+    /**
+     * Gets the factory state as a String.
+     * @param state the state.
+     * @return the String form of the state.
+     */
+    private static String getFactoryState(int state) {
+        switch(state) {
+            case Factory.VALID :
+                return "valid";
+            case Factory.INVALID :
+                return "invalid";
+            default :
+                return "unknown";
+        }
+    }
+    
+    private final class RequestInfo {
+        public final String extension;
+        public final String path;
+        public final boolean instances;
+        public final boolean factories;
+        public final boolean handlers;
+        
+        public final String name;
+
+        
+        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";
+                info = info.substring(0, info.length() - 5);
+            } else {
+                extension = "html";
+            }
+
+            if (info.startsWith("/")) {
+                path = info.substring(1);
+                instances = path.startsWith("instances");
+                factories = path.startsWith("factories");
+                handlers = path.startsWith("handlers");
+               
+                
+                if (instances  && path.startsWith("instances/")) {
+                    name = path.substring(0, "instances".length() + 1);
+                } else if (factories  && path.startsWith("factories/")) {
+                    name = path.substring(0, "factories".length() + 1);
+                } else {
+                    name = null;
+                }
+            } else {
+                path = null;
+                name = null;
+                instances = false;
+                factories = false;
+                handlers = false;
+            }
+           
+            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;
+       return m_label;
     }
 
     @Override
     public String getTitle() {
         return m_title;
     }
-
+    
     @Override
-    protected void renderContent(HttpServletRequest req, HttpServletResponse res)
-            throws ServletException, IOException {
-        // TODO Auto-generated method stub
-        
+    protected String[] getCssReferences() {
+        return CSS;
     }
 
 }

Added: felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/factories.html
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/factories.html?rev=963381&view=auto
==============================================================================
--- felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/factories.html (added)
+++ felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/factories.html Mon Jul 12 17:36:50 2010
@@ -0,0 +1,43 @@
+<script type="text/javascript" src="${pluginRoot}/res/ui/factory.js"></script>
+
+
+<!-- status line -->
+<p class="statline">&nbsp;</p>
+
+<!-- top header -->
+<form method="post" enctype="multipart/form-data" action="">
+	<div class="ui-widget-header ui-corner-top buttonGroup">
+		<button class="instancesButton" type="button">Instances</button>
+		<button class="factoriesButton" type="button">Factories</button>
+		<button class="handlersButton" type="button">Handlers</button>
+	</div>
+</form>
+
+<table id="plugin_table" class="tablesorter nicetable noauto">
+	<thead>
+		<tr>
+			<th class="col_Name">Factory Name</th>
+			<th class="col_Factory">Bundle</th>
+			<th class="col_State">State</th>
+		</tr>
+	</thead>
+	<tbody>
+		<tr><!-- template -->
+			<td class="name">&nbsp;	</td>
+			<td class="bundle">&nbsp;</td><!-- factory -->
+			<td class="state">&nbsp;</td><!-- state -->
+		</tr>
+	</tbody>
+</table>
+
+<!-- bottom header -->
+<form method="post" enctype="multipart/form-data" action="">
+    <div class="ui-widget-header ui-corner-bottom buttonGroup">
+        <button class="instancesButton" type="button">Instances</button>
+        <button class="factoriesButton" type="button">Factories</button>
+        <button class="handlersButton" type="button">Handlers</button>
+    </div>
+</form>
+
+<!-- status line -->
+<p class="statline">&nbsp;</p>

Added: felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/instances.html
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/instances.html?rev=963381&view=auto
==============================================================================
--- felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/instances.html (added)
+++ felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/instances.html Mon Jul 12 17:36:50 2010
@@ -0,0 +1,42 @@
+<script type="text/javascript" src="${pluginRoot}/res/ui/ipojo.js"></script>
+
+<!-- status line -->
+<p class="statline">&nbsp;</p>
+
+<!-- top header -->
+<form method="post" enctype="multipart/form-data" action="">
+	<div class="ui-widget-header ui-corner-top buttonGroup">
+		<button class="instancesButton" type="button">Instances</button>
+		<button class="factoriesButton" type="button">Factories</button>
+		<button class="handlersButton" type="button">Handlers</button>
+	</div>
+</form>
+
+<table id="plugin_table" class="tablesorter nicetable noauto">
+	<thead>
+		<tr>
+			<th class="col_Name">Instance Name</th>
+			<th class="col_Factory">Factory</th>
+			<th class="col_State">State</th>
+		</tr>
+	</thead>
+	<tbody>
+		<tr><!-- template -->
+			<td class="name">&nbsp;	</td>
+			<td class="factory">&nbsp;</td><!-- factory -->
+			<td class="state">&nbsp;</td><!-- state -->
+		</tr>
+	</tbody>
+</table>
+
+<!-- bottom header -->
+<form method="post" enctype="multipart/form-data" action="">
+    <div class="ui-widget-header ui-corner-bottom buttonGroup">
+        <button class="instancesButton" type="button">Instances</button>
+        <button class="factoriesButton" type="button">Factories</button>
+        <button class="handlersButton" type="button">Handlers</button>
+    </div>
+</form>
+
+<!-- status line -->
+<p class="statline">&nbsp;</p>

Added: felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/ui/factory.js
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/ui/factory.js?rev=963381&view=auto
==============================================================================
--- felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/ui/factory.js (added)
+++ felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/ui/factory.js Mon Jul 12 17:36:50 2010
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+function renderFactoriesData(factories)  {
+    $(".statline").html(getFactoriesStatLine(factories));
+    tableBody.empty();
+    for ( var idx in factories.data ) {
+        factoriesEntry( factories.data[idx] );
+    }
+    $("#plugin_table").trigger("update");
+}
+
+function getFactoriesStatLine(factories) {
+    return factories.count + " factories in total, "
+        + factories.valid_count + " valid factories, "
+        + factories.invalid_count + " invalid factories.";
+}
+
+function factoriesEntry(factory) {
+    var name = factory.name;
+    var state = factory.state;
+    var bundle = factory.bundle;
+
+    console.log("Create entry : " + factory);
+
+    var _ = tableEntryTemplate.clone().appendTo(tableBody).attr('id', 'factory-' + factory.name);
+
+    _.find('td.name').html('<a href="' + window.location.pathname + '/factories/' + name + '">' + name + '</a>');
+    _.find('td.bundle').text(bundle);
+    _.find('td.state').text(state);
+}
+
+
+function loadFactoriesData() {
+    console.log("Load factories data");
+	$.get(pluginRoot + "/factories.json", null, function(data) {
+		renderFactoriesData(data);
+	}, "json");	
+}
+
+function loadInstancesData() {
+    console.log("Go to instances"); 
+    window.location=window.location.pathname + "?view=instances"
+}
+
+function loadHandlersData() {
+    console.log("Load handlers data"); 
+}
+
+var tableBody = false;
+var tableEntryTemplate = false;
+
+$(document).ready(function(){
+	tableBody = $('#plugin_table tbody');
+	tableEntryTemplate = tableBody.find('tr').clone();
+
+    loadFactoriesData();
+	
+    $(".instancesButton").click(loadInstancesData);
+    $(".factoriesButton").click(loadFactoriesData);
+    $(".handlersButton").click(loadHandlersData);
+
+	var extractMethod = function(node) {
+		var link = node.getElementsByTagName("a");
+		if ( link && link.length == 1 ) {
+			return link[0].innerHTML;
+		}
+		return node.innerHTML;
+	};
+	$("#plugin_table").tablesorter({
+		sortList: [[1,0]],
+		textExtraction:extractMethod
+	});
+});
+

Added: felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/ui/ipojo.js
URL: http://svn.apache.org/viewvc/felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/ui/ipojo.js?rev=963381&view=auto
==============================================================================
--- felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/ui/ipojo.js (added)
+++ felix/trunk/ipojo/webconsole-plugin/src/main/resources/res/ui/ipojo.js Mon Jul 12 17:36:50 2010
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+function renderInstancesData(instances)  {
+    $(".statline").html(getInstancesStatLine(instances));
+    tableBody.empty();
+    for ( var idx in instances.data ) {
+        instancesEntry( instances.data[idx] );
+    }
+    $("#plugin_table").trigger("update");
+}
+
+function getInstancesStatLine(instances) {
+    return instances.count + " instances in total, "
+        + instances.valid_count + " valid instances, "
+        + instances.invalid_count + " invalid instances.";
+}
+
+function instancesEntry(instance) {
+    var name = instance.name;
+    var state = instance.state;
+    var factory = instance.factory;
+
+    var _ = tableEntryTemplate.clone().appendTo(tableBody).attr('id', 'instance-' + instance.name);
+
+    _.find('td.name').html('<a href="' + window.location.pathname + '/instance/' + name + '">' + name + '</a>');
+    _.find('td.factory').html('<a href="' + window.location.pathname + '/factory/' + factory + '">' + factory + '</a>');;
+    _.find('td.state').text(state);
+}
+
+
+function loadInstancesData() {
+	$.get(pluginRoot + "/instances.json", null, function(data) {
+		renderInstancesData(data);
+	}, "json");	
+}
+
+function loadFactoriesData() {
+    console.log("Go to factories data");
+    window.location=window.location.pathname + '?view=factories'; 
+}
+
+function loadHandlersData() {
+    console.log("Load handlers data"); 
+}
+
+var tableBody = false;
+var tableEntryTemplate = false;
+
+$(document).ready(function(){
+	tableBody = $('#plugin_table tbody');
+	tableEntryTemplate = tableBody.find('tr').clone();
+
+    loadInstancesData();
+	
+    $(".instancesButton").click(loadInstancesData);
+    $(".factoriesButton").click(loadFactoriesData);
+    $(".handlersButton").click(loadHandlersData);
+
+	var extractMethod = function(node) {
+		var link = node.getElementsByTagName("a");
+		if ( link && link.length == 1 ) {
+			return link[0].innerHTML;
+		}
+		return node.innerHTML;
+	};
+	$("#plugin_table").tablesorter({
+		sortList: [[1,0]],
+		textExtraction:extractMethod
+	});
+});
+