felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject svn commit: r741071 [1/2] - in /felix/trunk/webconsole: ./ src/main/java/org/apache/felix/webconsole/ src/main/java/org/apache/felix/webconsole/internal/ src/main/java/org/apache/felix/webconsole/internal/core/ src/main/java/org/apache/felix/webconsole...
Date Thu, 05 Feb 2009 10:45:36 GMT
Author: cziegeler
Date: Thu Feb  5 10:45:35 2009
New Revision: 741071

URL: http://svn.apache.org/viewvc?rev=741071&view=rev
Log:
FELIX-858 : Use new table layout for the bundles list. Several UI improvements and cleanups.

Added:
    felix/trunk/webconsole/src/main/resources/res/imgs/arrow_down.png   (with props)
    felix/trunk/webconsole/src/main/resources/res/imgs/arrow_left.png   (with props)
    felix/trunk/webconsole/src/main/resources/res/imgs/arrow_right.png   (with props)
    felix/trunk/webconsole/src/main/resources/res/imgs/bundle_delete.png   (with props)
    felix/trunk/webconsole/src/main/resources/res/imgs/bundle_refresh.png   (with props)
    felix/trunk/webconsole/src/main/resources/res/imgs/bundle_start.png   (with props)
    felix/trunk/webconsole/src/main/resources/res/imgs/bundle_stop.png   (with props)
    felix/trunk/webconsole/src/main/resources/res/ui/jquery-1.3.1.min.js   (with props)
Removed:
    felix/trunk/webconsole/src/main/resources/res/ui/jquery-1.2.6.min.js
Modified:
    felix/trunk/webconsole/NOTICE
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/Util.java
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
    felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/EventAdminServlet.java
    felix/trunk/webconsole/src/main/resources/res/ui/admin.css
    felix/trunk/webconsole/src/main/resources/res/ui/bundles.js
    felix/trunk/webconsole/src/main/resources/res/ui/datatable.js

Modified: felix/trunk/webconsole/NOTICE
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/NOTICE?rev=741071&r1=741070&r2=741071&view=diff
==============================================================================
--- felix/trunk/webconsole/NOTICE (original)
+++ felix/trunk/webconsole/NOTICE Thu Feb  5 10:45:35 2009
@@ -23,6 +23,10 @@
 This product includes software from http://www.jquery.com
 Licensed under the MIT License
 
+This product includes icons from Mark James
+(http://www.famfamfam.com/lab/icons/silk/) licensed
+under the Creative Commons Attribution 2.5 License.
+
 
 II. Used Software
 

Modified: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java?rev=741071&r1=741070&r2=741071&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
(original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/AbstractWebConsolePlugin.java
Thu Feb  5 10:45:35 2009
@@ -20,18 +20,10 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.text.MessageFormat;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedMap;
-import java.util.TreeMap;
+import java.util.*;
 
 import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.*;
 
 import org.apache.commons.fileupload.FileItem;
 import org.apache.commons.fileupload.FileUploadException;

Modified: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/Util.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/Util.java?rev=741071&r1=741070&r2=741071&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/Util.java (original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/Util.java Thu
Feb  5 10:45:35 2009
@@ -17,18 +17,14 @@
 package org.apache.felix.webconsole.internal;
 
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintWriter;
+import java.io.*;
 import java.util.Arrays;
 import java.util.Comparator;
 
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.io.IOUtils;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
+import org.osgi.framework.*;
 
 
 /**
@@ -72,6 +68,10 @@
         pw.println( "</script>" );
     }
 
+    public static void script( PrintWriter pw, String appRoot, String scriptName )
+    {
+        pw.println( "<script src='" + appRoot + "/res/ui/" + scriptName + "' language='JavaScript'></script>"
);
+    }
 
     public static void spool( String res, HttpServletResponse resp ) throws IOException
     {

Modified: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java?rev=741071&r1=741070&r2=741071&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
(original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
Thu Feb  5 10:45:35 2009
@@ -29,13 +29,11 @@
 import org.apache.felix.webconsole.internal.BaseWebConsolePlugin;
 import org.apache.felix.webconsole.internal.Util;
 import org.apache.felix.webconsole.internal.servlet.OsgiManager;
-import org.json.JSONException;
-import org.json.JSONWriter;
+import org.json.*;
 import org.osgi.framework.*;
 import org.osgi.service.cm.ConfigurationAdmin;
 import org.osgi.service.component.ComponentConstants;
 import org.osgi.service.log.LogService;
-import org.osgi.service.obr.RepositoryAdmin;
 import org.osgi.service.packageadmin.ExportedPackage;
 import org.osgi.service.packageadmin.PackageAdmin;
 import org.osgi.service.startlevel.StartLevel;
@@ -53,8 +51,6 @@
 
     public static final String BUNDLE_ID = "bundleId";
 
-    private static final String REPOSITORY_ADMIN_NAME = RepositoryAdmin.class.getName();
-
     // bootdelegation property entries. wildcards are converted to package
     // name prefixes. whether an entry is a wildcard or not is set as a flag
     // in the bootPkgWildcards array.
@@ -105,61 +101,40 @@
     protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws
ServletException,
         IOException
     {
-
-        String info = request.getPathInfo();
-        if ( info.endsWith( ".json" ) )
+        final RequestInfo reqInfo = new RequestInfo(request);
+        if ( reqInfo.bundle == null && reqInfo.bundleRequested ) {
+            response.setStatus(404);
+            return;
+        }
+        if ( reqInfo.extension.equals("json")  )
         {
-            info = info.substring( 0, info.length() - 5 );
-            if ( getLabel().equals( info.substring( 1 ) ) )
-            {
-                // should return info on all bundles
-            }
-            else
-            {
-                Bundle bundle = getBundle( info );
-                if ( bundle != null )
-                {
-                    // bundle properties
-
-                    response.setContentType( "application/json" );
-                    response.setCharacterEncoding( "UTF-8" );
-
-                    PrintWriter pw = response.getWriter();
-                    JSONWriter jw = new JSONWriter( pw );
-                    try
-                    {
-                        performAction( jw, bundle );
-                    }
-                    catch ( JSONException je )
-                    {
-                        throw new IOException( je.toString() );
-                    }
-                }
-            }
+            this.renderJSON(response, reqInfo.bundle);
 
             // nothing more to do
             return;
         }
 
+
         super.doGet( request, response );
     }
 
 
     protected void doPost( HttpServletRequest req, HttpServletResponse resp ) throws ServletException,
IOException
     {
-        String action = req.getParameter( "action" );
-        if ( "refreshPackages".equals( action ) )
-        {
-            getPackageAdmin().refreshPackages( null );
+        final RequestInfo reqInfo = new RequestInfo(req);
+        if ( reqInfo.bundle == null && reqInfo.bundleRequested ) {
+            resp.setStatus(404);
+            return;
         }
 
         boolean success = false;
+
+        final String action = req.getParameter( "action" );
+
         Bundle bundle = getBundle( req.getPathInfo() );
-        long bundleId = -1;
 
         if ( bundle != null )
         {
-            bundleId = bundle.getBundleId();
             if ( action == null )
             {
                 success = true;
@@ -214,46 +189,20 @@
 
         if ( "refreshPackages".equals( action ) )
         {
-            success = true;
             getPackageAdmin().refreshPackages( null );
-
-            // refresh completely
-            bundle = null;
-            bundleId = -1;
+            success = true;
         }
 
         if ( success )
         {
-            // redirect or 200
-            resp.setStatus( HttpServletResponse.SC_OK );
-            resp.setContentType( "application/json" );
-            resp.setCharacterEncoding( "UTF-8" );
-            JSONWriter jw = new JSONWriter( resp.getWriter() );
-            try
-            {
-                if ( bundle != null )
-                {
-                    bundleInfo( jw, bundle, true );
-                }
-                else if ( bundleId >= 0 )
-                {
-                    jw.object();
-                    jw.key( "bundleId" );
-                    jw.value( bundleId );
-                    jw.endObject();
-                }
-                else
-                {
-                    jw.object();
-                    jw.key( "reload" );
-                    jw.value( true );
-                    jw.endObject();
-                }
-            }
-            catch ( JSONException je )
-            {
-                throw new IOException( je.toString() );
+            // let's wait a little bit to give the framework time
+            // to process our request
+            try {
+                Thread.sleep(800);
+            } catch (InterruptedException e) {
+                // we ignore this
             }
+            this.renderJSON(resp, null);
         }
         else
         {
@@ -311,96 +260,80 @@
     }
 
 
-    private void renderBundleInfoCount( final PrintWriter pw, String msg, int count )
+    private void appendBundleInfoCount( final StringBuffer buf, String msg, int count )
     {
-        pw.print( "<td class='content'>" );
-        pw.print( msg );
-        pw.print( " : " );
-        pw.print( count );
-        pw.print( " Bundle" );
+        buf.append(count);
+        buf.append(" Bundle");
         if ( count != 1 )
-            pw.print( 's' );
-        pw.println( "</td>" );
+            buf.append( 's' );
+        buf.append(' ');
+        buf.append(msg);
     }
 
-
     protected void renderContent( HttpServletRequest request, HttpServletResponse response
) throws IOException
     {
-        Bundle bundle = getBundle( request.getPathInfo() );
-        Bundle[] bundles = ( bundle != null ) ? new Bundle[]
-            { bundle } : this.getBundles();
-
-        PrintWriter pw = response.getWriter();
-
-        String appRoot = ( String ) request.getAttribute( OsgiManager.ATTR_APP_ROOT );
-        pw.println( "<script src='" + appRoot + "/res/ui/datatable.js' language='JavaScript'></script>"
);
-        pw.println( "<script src='" + appRoot + "/res/ui/bundles.js' language='JavaScript'></script>"
);
+        // get request info from request attribute
+        final RequestInfo reqInfo = getRequestInfo(request);
+        final PrintWriter pw = response.getWriter();
+
+        final String appRoot = ( String ) request.getAttribute( OsgiManager.ATTR_APP_ROOT
);
+        Util.script(pw, appRoot, "jquery-1.3.1.min.js");
+        Util.script(pw, appRoot, "jquery.tablesorter-2.0.3.min.js");
+        Util.script(pw, appRoot, "bundles.js");
 
-        if ( bundles != null )
-        {
-            int active = 0, installed = 0, resolved = 0;
-            for ( int i = 0; i < bundles.length; i++ )
-            {
-                switch ( bundles[i].getState() )
-                {
-                    case Bundle.ACTIVE:
-                        active++;
-                        break;
-                    case Bundle.INSTALLED:
-                        installed++;
-                        break;
-                    case Bundle.RESOLVED:
-                        resolved++;
-                        break;
-                }
-            }
+        Util.startScript( pw );
+        pw.println( "var imgRoot = '" + appRoot + "/res/imgs';");
+        pw.println( "var startLevel = " + getStartLevel().getInitialBundleStartLevel() +
";");
+        pw.println( "var drawDetails = " + reqInfo.bundleRequested + ";");
+        Util.endScript( pw );
 
-            pw.println( "<table class='content' cellpadding='0' cellspacing='0' width='100%'><tbody>"
);
-            pw.println( "<tr class='content'>" );
-            renderBundleInfoCount( pw, "Total", bundles.length );
-            renderBundleInfoCount( pw, "Active", active );
-            renderBundleInfoCount( pw, "Resolved", resolved );
-            renderBundleInfoCount( pw, "Installed", installed );
-            pw.println( "</tr></tbody></table>" );
-        }
+        Util.script(pw, appRoot, "bundles.js");
 
+        pw.println( "<div id='plugin_content'/>");
         Util.startScript( pw );
-        pw.println( "var bundleListData = " );
-        JSONWriter jw = new JSONWriter( pw );
-        try
-        {
-            jw.object();
+        pw.print( "renderBundles(");
+        writeJSON(pw, reqInfo.bundle);
+        pw.println(");" );
+        Util.endScript( pw );
+    }
 
-            jw.key( "startLevel" );
-            jw.value( getStartLevel().getInitialBundleStartLevel() );
+    private void renderJSON( final HttpServletResponse response, final Bundle bundle ) throws
IOException
+    {
+        response.setContentType( "application/json" );
+        response.setCharacterEncoding( "UTF-8" );
 
-            jw.key( "numActions" );
-            jw.value( 4 );
+        final PrintWriter pw = response.getWriter();
+        writeJSON(pw, bundle);
+    }
 
-            boolean details = ( bundle != null );
+    private void writeJSON( final PrintWriter pw, final Bundle bundle) throws IOException
+    {
+        final Bundle[] allBundles = this.getBundles();
+        final String statusLine = this.getStatusLine(allBundles);
+        final Bundle[] bundles = ( bundle != null ) ? new Bundle[]
+            { bundle } : allBundles;
+        Util.sort( bundles );
 
-            if ( bundles != null && bundles.length > 0 )
-            {
-                Util.sort( bundles );
+        final JSONWriter jw = new JSONWriter( pw );
 
-                jw.key( "data" );
+        try
+        {
+            jw.object();
 
-                jw.array();
+            jw.key( "status" );
+            jw.value( statusLine );
 
-                for ( int i = 0; i < bundles.length; i++ )
-                {
-                    bundleInfo( jw, bundles[i], details );
-                }
+            jw.key( "data" );
 
-                jw.endArray();
+            jw.array();
 
-            }
-            else
+            for ( int i = 0; i < bundles.length; i++ )
             {
-                jw.key( "error" );
-                jw.value( "No Bundles installed currently" );
+                bundleInfo( jw, bundles[i], bundle != null );
             }
 
+            jw.endArray();
+
             jw.endObject();
 
         }
@@ -409,11 +342,54 @@
             throw new IOException( je.toString() );
         }
 
-        pw.println( ";" );
-        pw.println( "renderBundle( bundleListData );" );
-        Util.endScript( pw );
     }
 
+    private String getStatusLine(final Bundle[] bundles)
+    {
+        int active = 0, installed = 0, resolved = 0;
+        for ( int i = 0; i < bundles.length; i++ )
+        {
+            switch ( bundles[i].getState() )
+            {
+                case Bundle.ACTIVE:
+                    active++;
+                    break;
+                case Bundle.INSTALLED:
+                    installed++;
+                    break;
+                case Bundle.RESOLVED:
+                    resolved++;
+                    break;
+            }
+        }
+        final StringBuffer buffer = new StringBuffer();
+        buffer.append("Bundle information: ");
+        appendBundleInfoCount(buffer, "in total", bundles.length);
+        if ( active == bundles.length )
+        {
+            buffer.append(" - all active.");
+        }
+        else
+        {
+            if ( active != 0 )
+            {
+                buffer.append(", ");
+                appendBundleInfoCount(buffer, "active", active);
+            }
+            if ( resolved != 0 )
+            {
+                buffer.append(", ");
+                appendBundleInfoCount(buffer, "resolved", resolved);
+            }
+            if ( installed != 0 )
+            {
+                buffer.append(", ");
+                appendBundleInfoCount(buffer, "installed", installed);
+            }
+            buffer.append('.');
+        }
+        return buffer.toString();
+    }
 
     private void bundleInfo( JSONWriter jw, Bundle bundle, boolean details ) throws JSONException
     {
@@ -428,19 +404,18 @@
         jw.key( "actions" );
         jw.array();
 
-        if ( bundle.getBundleId() == 0 )
-        {
-            jw.value( false );
-            jw.value( false );
-            jw.value( false );
-            jw.value( false );
-        }
-        else
+        if ( bundle.getBundleId() != 0 )
         {
-            action( jw, hasStart( bundle ), "start", "Start", null );
-            action( jw, hasStop( bundle ), "stop", "Stop", null );
-            action( jw, true, "refresh", "Refresh", "Refresh Package Imports" );
-            action( jw, hasUninstall( bundle ), "uninstall", "Uninstall", null );
+            if ( hasStart(bundle) )
+            {
+                action( jw, hasStart( bundle ), "start", "Start", "start" );
+            }
+            else
+            {
+                action( jw, hasStop( bundle ), "stop", "Stop", "stop" );
+            }
+            action( jw, true, "refresh", "Refresh Package Imports", "refresh" );
+            action( jw, hasUninstall( bundle ), "uninstall", "Uninstall", "delete" );
         }
         jw.endArray();
 
@@ -481,15 +456,13 @@
     }
 
 
-    private void action( JSONWriter jw, boolean enabled, String op, String opLabel, String
title ) throws JSONException
+    private void action( JSONWriter jw, boolean enabled, String op, String opLabel, String
image ) throws JSONException
     {
         jw.object();
         jw.key( "enabled" ).value( enabled );
         jw.key( "name" ).value( opLabel );
         jw.key( "link" ).value( op );
-        if (title != null) {
-            jw.key( "title" ).value( title );
-        }
+        jw.key( "image" ).value( image );
         jw.endObject();
     }
 
@@ -514,18 +487,6 @@
     }
 
 
-    private void performAction( JSONWriter jw, Bundle bundle ) throws JSONException
-    {
-        jw.object();
-        jw.key( BUNDLE_ID );
-        jw.value( bundle.getBundleId() );
-
-        bundleDetails( jw, bundle );
-
-        jw.endObject();
-    }
-
-
     private void bundleDetails( JSONWriter jw, Bundle bundle ) throws JSONException
     {
         Dictionary headers = bundle.getHeaders();
@@ -540,7 +501,6 @@
         String docUrl = ( String ) headers.get( Constants.BUNDLE_DOCURL );
         if ( docUrl != null )
         {
-            docUrl = "<a href=\"" + docUrl + "\" target=\"_blank\">" + docUrl + "</a>";
             keyVal( jw, "Bundle Documentation", docUrl );
         }
 
@@ -602,11 +562,11 @@
                 }
             } );
 
-            StringBuffer val = new StringBuffer();
+            JSONArray val = new JSONArray();
             for ( int j = 0; j < exports.length; j++ )
             {
                 ExportedPackage export = exports[j];
-                printExport( val, export.getName(), export.getVersion() );
+                collectExport( val, export.getName(), export.getVersion() );
                 Bundle[] ubList = export.getImportingBundles();
                 if ( ubList != null )
                 {
@@ -617,7 +577,7 @@
                     }
                 }
             }
-            keyVal( jw, "Exported Packages", val.toString() );
+            keyVal( jw, "Exported Packages", val );
         }
         else
         {
@@ -644,7 +604,7 @@
                 }
             }
             // now sort
-            StringBuffer val = new StringBuffer();
+            JSONArray val = new JSONArray();
             if ( imports.size() > 0 )
             {
                 final ExportedPackage[] packages = ( ExportedPackage[] ) imports.toArray(
new ExportedPackage[imports
@@ -666,28 +626,27 @@
                 for ( int i = 0; i < packages.length; i++ )
                 {
                     ExportedPackage ep = packages[i];
-                    printImport( val, ep.getName(), ep.getVersion(), false, ep );
+                    collectImport( val, ep.getName(), ep.getVersion(), false, ep );
                 }
             }
             else
             {
                 // add description if there are no imports
-                val.append( "None" );
+                val.put( "None" );
             }
 
-            keyVal( jw, "Imported Packages", val.toString() );
+            keyVal( jw, "Imported Packages", val );
         }
 
         if ( !usingBundles.isEmpty() )
         {
-            StringBuffer val = new StringBuffer();
+            JSONArray val = new JSONArray();
             for ( Iterator ui = usingBundles.values().iterator(); ui.hasNext(); )
             {
                 Bundle usingBundle = ( Bundle ) ui.next();
-                val.append( getBundleDescriptor( usingBundle ) );
-                val.append( "<br />" );
+                val.put( getBundleDescriptor( usingBundle ) );
             }
-            keyVal( jw, "Importing Bundles", val.toString() );
+            keyVal( jw, "Importing Bundles", val );
         }
     }
 
@@ -717,13 +676,13 @@
                     }
                 } );
 
-                StringBuffer val = new StringBuffer();
+                JSONArray val = new JSONArray();
                 for ( int i = 0; i < pkgs.length; i++ )
                 {
                     R4Export export = new R4Export( pkgs[i] );
-                    printExport( val, export.getName(), export.getVersion() );
+                    collectExport( val, export.getName(), export.getVersion() );
                 }
-                keyVal( jw, "Exported Packages", val.toString() );
+                keyVal( jw, "Exported Packages", val );
             }
             else
             {
@@ -767,7 +726,7 @@
                 }
 
                 // now sort
-                StringBuffer val = new StringBuffer();
+                JSONArray val = new JSONArray();
                 if ( imports.size() > 0 )
                 {
                     for ( Iterator ii = imports.values().iterator(); ii.hasNext(); )
@@ -786,16 +745,16 @@
                             }
                         }
 
-                        printImport( val, r4Import.getName(), r4Import.getVersion(), r4Import.isOptional(),
ep );
+                        collectImport( val, r4Import.getName(), r4Import.getVersion(), r4Import.isOptional(),
ep );
                     }
                 }
                 else
                 {
                     // add description if there are no imports
-                    val.append( "None" );
+                    val.put( "None" );
                 }
 
-                keyVal( jw, "Imported Packages", val.toString() );
+                keyVal( jw, "Imported Packages", val );
             }
         }
     }
@@ -813,7 +772,7 @@
         {
             String key = "Service ID " + refs[i].getProperty( Constants.SERVICE_ID );
 
-            StringBuffer val = new StringBuffer();
+            JSONArray val = new JSONArray();
 
             appendProperty( val, refs[i], Constants.OBJECTCLASS, "Types" );
             appendProperty( val, refs[i], Constants.SERVICE_PID, "PID" );
@@ -824,13 +783,14 @@
             appendProperty( val, refs[i], Constants.SERVICE_DESCRIPTION, "Description" );
             appendProperty( val, refs[i], Constants.SERVICE_VENDOR, "Vendor" );
 
-            keyVal( jw, key, val.toString() );
+            keyVal( jw, key, val);
         }
     }
 
 
-    private void appendProperty( StringBuffer dest, ServiceReference ref, String name, String
label )
+    private void appendProperty( JSONArray array, ServiceReference ref, String name, String
label )
     {
+        StringBuffer dest = new StringBuffer();
         Object value = ref.getProperty( name );
         if ( value instanceof Object[] )
         {
@@ -842,11 +802,12 @@
                     dest.append( ", " );
                 dest.append( values[j] );
             }
-            dest.append( "<br />" ); // assume HTML use of result
+            array.put(dest.toString());
         }
         else if ( value != null )
         {
-            dest.append( label ).append( ": " ).append( value ).append( "<br />" );
+            dest.append( label ).append( ": " ).append( value );
+            array.put(dest.toString());
         }
     }
 
@@ -865,8 +826,9 @@
     }
 
 
-    private void printExport( StringBuffer val, String name, Version version )
+    private void collectExport( JSONArray array, String name, Version version )
     {
+        StringBuffer val = new StringBuffer();
         boolean bootDel = isBootDelegated( name );
         if ( bootDel )
         {
@@ -882,12 +844,13 @@
             val.append( " -- Overwritten by Boot Delegation" );
         }
 
-        val.append( "<br />" );
+        array.put(val.toString());
     }
 
 
-    private void printImport( StringBuffer val, String name, Version version, boolean optional,
ExportedPackage export )
+    private void collectImport( JSONArray array, String name, Version version, boolean optional,
ExportedPackage export )
     {
+        StringBuffer val = new StringBuffer();
         boolean bootDel = isBootDelegated( name );
         boolean isSpan = bootDel || export == null;
 
@@ -924,7 +887,7 @@
             }
         }
 
-        val.append( "<br />" );
+        array.put(val);
     }
 
 
@@ -1005,4 +968,53 @@
         getPackageAdmin().refreshPackages( new Bundle[]
             { bundle } );
     }
+
+    private final class RequestInfo
+    {
+        public final String extension;
+        public final Bundle bundle;
+        public final boolean bundleRequested;
+
+        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";
+            }
+
+            // we only accept direct requests to a bundle if they have a slash after the
label
+            String bundleInfo = null;
+            if (info.startsWith("/") )
+            {
+                bundleInfo = info.substring(1);
+            }
+            if ( bundleInfo == null )
+            {
+                bundle = null;
+                bundleRequested = false;
+            }
+            else
+            {
+                bundle = getBundle(bundleInfo);
+                bundleRequested = true;
+            }
+            request.setAttribute(BundlesServlet.class.getName(), this);
+        }
+
+    }
+
+    public static RequestInfo getRequestInfo(final HttpServletRequest request)
+    {
+        return (RequestInfo)request.getAttribute(BundlesServlet.class.getName());
+    }
 }

Modified: felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/EventAdminServlet.java
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/EventAdminServlet.java?rev=741071&r1=741070&r2=741071&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/EventAdminServlet.java
(original)
+++ felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/EventAdminServlet.java
Thu Feb  5 10:45:35 2009
@@ -233,11 +233,10 @@
     {
         final PrintWriter pw = response.getWriter();
 
-        String appRoot = ( String ) request.getAttribute( OsgiManager.ATTR_APP_ROOT );
-        pw.println( "<script src='" + appRoot + "/res/ui/jquery-1.2.6.min.js' language='JavaScript'></script>"
);
-        pw.println( "<script src='" + appRoot
-            + "/res/ui/jquery.tablesorter-2.0.3.min.js' language='JavaScript'></script>"
);
-        pw.println( "<script src='" + appRoot + "/res/ui/events.js' language='JavaScript'></script>"
);
+        final String appRoot = ( String ) request.getAttribute( OsgiManager.ATTR_APP_ROOT
);
+        Util.script(pw, appRoot, "jquery-1.3.1.min.js");
+        Util.script(pw, appRoot, "jquery.tablesorter-2.0.3.min.js");
+        Util.script(pw, appRoot, "events.js");
 
         Util.startScript( pw );
         pw.println( "renderEvents( );" );

Added: felix/trunk/webconsole/src/main/resources/res/imgs/arrow_down.png
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/imgs/arrow_down.png?rev=741071&view=auto
==============================================================================
Binary file - no diff available.

Propchange: felix/trunk/webconsole/src/main/resources/res/imgs/arrow_down.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: felix/trunk/webconsole/src/main/resources/res/imgs/arrow_left.png
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/imgs/arrow_left.png?rev=741071&view=auto
==============================================================================
Binary file - no diff available.

Propchange: felix/trunk/webconsole/src/main/resources/res/imgs/arrow_left.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: felix/trunk/webconsole/src/main/resources/res/imgs/arrow_right.png
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/imgs/arrow_right.png?rev=741071&view=auto
==============================================================================
Binary file - no diff available.

Propchange: felix/trunk/webconsole/src/main/resources/res/imgs/arrow_right.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: felix/trunk/webconsole/src/main/resources/res/imgs/bundle_delete.png
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/imgs/bundle_delete.png?rev=741071&view=auto
==============================================================================
Binary file - no diff available.

Propchange: felix/trunk/webconsole/src/main/resources/res/imgs/bundle_delete.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: felix/trunk/webconsole/src/main/resources/res/imgs/bundle_refresh.png
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/imgs/bundle_refresh.png?rev=741071&view=auto
==============================================================================
Binary file - no diff available.

Propchange: felix/trunk/webconsole/src/main/resources/res/imgs/bundle_refresh.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: felix/trunk/webconsole/src/main/resources/res/imgs/bundle_start.png
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/imgs/bundle_start.png?rev=741071&view=auto
==============================================================================
Binary file - no diff available.

Propchange: felix/trunk/webconsole/src/main/resources/res/imgs/bundle_start.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: felix/trunk/webconsole/src/main/resources/res/imgs/bundle_stop.png
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/imgs/bundle_stop.png?rev=741071&view=auto
==============================================================================
Binary file - no diff available.

Propchange: felix/trunk/webconsole/src/main/resources/res/imgs/bundle_stop.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Modified: felix/trunk/webconsole/src/main/resources/res/ui/admin.css
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/ui/admin.css?rev=741071&r1=741070&r2=741071&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/resources/res/ui/admin.css (original)
+++ felix/trunk/webconsole/src/main/resources/res/ui/admin.css Thu Feb  5 10:45:35 2009
@@ -637,3 +637,12 @@
 table.tablelayout thead tr .headerSortDown, table.tablelayout thead tr .headerSortUp {
 background-color: #8dbdd8;
 }
+.col_Id {
+    width: 40px;
+}
+.col_Status {
+	width: 50px;
+}
+.col_Actions {
+    width: 95px;
+}
\ No newline at end of file

Modified: felix/trunk/webconsole/src/main/resources/res/ui/bundles.js
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/ui/bundles.js?rev=741071&r1=741070&r2=741071&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/resources/res/ui/bundles.js (original)
+++ felix/trunk/webconsole/src/main/resources/res/ui/bundles.js Thu Feb  5 10:45:35 2009
@@ -14,48 +14,210 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+function renderStatusLine() {
+	$("#plugin_content").append( "<div class='fullwidth'><div class='statusline'/></div>"
);
+}
 
-function renderBundle( /* Array of Data Objects */ bundleData )
-{
+function renderView( /* Array of String */ columns, /* Array of String */ buttons ) {
+    renderStatusLine();
+    renderButtons(buttons);
+    var txt = "<div class='table'><table id='bundles' class='tablelayout'><thead><tr>";
+    for ( var name in columns ) {
+    	txt = txt + "<th class='col_" + columns[name] + "'>" + columns[name] + "</th>";
+    }
+    txt = txt + "</tr></thead><tbody></tbody></table></div>";
+    $("#plugin_content").append( txt );
+    renderButtons(buttons);
+    renderStatusLine();	
+}
 
-    // number of actions plus 3 -- id, name and state
-    var columns = bundleData.numActions + 3;
-    var startLevel = bundleData.startLevel;
-    
-    header( columns );
+function renderButtons( buttons ) {
+	$("#plugin_content").append( "<div class='fullwidth'><div class='buttons'>"
+
+	                             "<form method='post' enctype='multipart/form-data'><div
style='padding-top:5px;'>" +
+	                             buttons + "</div></form></div></div>"
);
+}
+
+function renderData( eventData )  {
+	$(".statusline").empty().append(eventData.status);
+	$("#bundles > tbody > tr").remove();
+    for ( var idx in eventData.data ) {
+        entry( eventData.data[idx] );
+    }
+    $("#bundles").trigger("update");
+    if ( drawDetails ) {
+	    renderDetails(eventData);
+    }
+}
+
+function entry( /* Object */ dataEntry ) {
+    var trElement = tr( null, { id: "entry" + dataEntry.id } );
+    entryInternal( trElement,  dataEntry );
+	$("#bundles > tbody").append(trElement);	
+}
+
+function actionButton( /* Element */ parent, /* string */ id, /* Obj */ action ) {
+	var enabled = action.enabled;
+	var op = action.link;
+	var opLabel = action.name;
+	var img = action.image;
+	
+	var input = createElement( "input", null, {
+            type: 'image',
+            title: opLabel,
+            alt: opLabel,
+            src: imgRoot + '/bundle_' + img + '.png',
+            onClick: 'changeDataEntryState(' + id + ', "' + op + '");'
+        });
+		
+    if (!enabled) {
+        input.setAttribute( "disabled", true );
+    }
+    var div = createElement("div");
+    div.setAttribute("style", "float:left; margin-left:10px;");
+    div.appendChild(input);
+    parent.appendChild( div );
+}
 
-    installForm( startLevel );
+function entryInternal( /* Element */ parent, /* Object */ dataEntry ) {
+    var id = dataEntry.id;
+    var name = dataEntry.name;
+    var state = dataEntry.state;
+    
+    var inputElement = createElement("img", "rightButton", {
+    	src: appRoot + "/res/imgs/arrow_right.png",
+    	border: "none",
+    	id: 'img' + id,
+    	title: "Back",
+    	alt: "Back",
+    	width: 14,
+    	height: 14,
+        onClick: 'showDetails(' + id + ');'
+    });
+    var titleElement;
+    if ( drawDetails ) {
+    	titleElement = text(name);
+    } else {
+        titleElement = createElement ("a", null, {
+    	    href: window.location.pathname + "/" + id
+        });
+        titleElement.appendChild(text(name));
+    }
     
-    if (bundleData.error)
-    {
-        error( columns, bundleData.error );
-    }
-    else
-    {
-        data ( bundleData.data );
-    }
-
-    installForm( startLevel );
-
-    footer( columns );
-}
-
-function installForm( /* int */ startLevel )
-{
-    document.write( "<form method='post' enctype='multipart/form-data'>" );
-    document.write( "<tr class='content'>" );
-    document.write( "<td class='content'>&nbsp;</td>" );
-    document.write( "<td class='content'>" );
-    document.write( "<input type='hidden' name='action' value='install' />" );
-    document.write( "<input class='input' type='file' name='bundlefile' size='50'>"
);
-    document.write( " - Start <input class='checkradio' type='checkbox' name='bundlestart'
value='start'>" );
-    document.write( " - Start Level <input class='input' type='input' name='bundlestartlevel'
value='" + startLevel + "' size='4'>" );
-    document.write( "</td>" );
-    document.write( "<td class='content' align='right' colspan='5' noWrap>" );
-    document.write( "<input class='submit' style='width:auto' type='submit' value='Install
or Update'>" );
-    document.write( "&nbsp;" );
-    document.write( "<input class='submit' style='width:auto' type='button' value='Refresh
Packages' onClick='changeDataEntryState(0, \"refreshPackages\");'>" );
-    document.write( "</td>" );
-    document.write( "</tr>" );
-    document.write( "</form>" );
+    parent.appendChild( td( null, null, [ text( id ) ] ) );
+    parent.appendChild( td( null, null, [ inputElement, text(" "), titleElement ] ) );
+    parent.appendChild( td( null, null, [ text( state ) ] ) );
+    var actionsTd = td( null, null );
+    
+    for ( var a in dataEntry.actions ) {
+    	actionButton( actionsTd, id, dataEntry.actions[a] );
+    }
+    parent.appendChild( actionsTd );
+}
+
+function loadData() {
+	$.get(pluginRoot + "/.json", null, function(data) {
+	    renderData(data);
+	}, "json");	
+}
+
+function changeDataEntryState(/* long */ id, /* String */ action) {
+	$.post(pluginRoot + "/" + id, {"action":action}, function(data) {
+	    renderData(data);
+	}, "json");	
+}
+
+function refreshPackages() {
+	$.post(window.location.pathname, {"action": "refreshPackages"}, function(data) {
+	    renderData(data);
+	}, "json");	
+}
+
+function showDetails( id ) {
+    $.get(pluginRoot + "/" + id + ".json", null, function(data) {
+    	renderDetails(data);
+    }, "json");
+}
+
+function hideDetails( id ) {
+	$("#img" + id).each(function() {
+		$("#bundleInlineDetails").remove();
+        this.setAttribute("src", appRoot + "/res/imgs/arrow_right.png");
+        this.setAttribute("onClick", "showDetails('" + id + "')");
+        this.setAttribute("title", "Details");
+        this.setAttribute("alt", "Details");
+	});
+}
+
+function renderDetails( data ) {
+	data = data.data[0];
+	$("#entry" + data.id + " > td").eq(1).append("<div id='bundleInlineDetails'/>");
+	$("#img" + data.id).each(function() {
+		if ( drawDetails ) {
+            this.setAttribute("src", appRoot + "/res/imgs/arrow_left.png");
+    	    var ref = window.location.pathname;
+    	    ref = ref.substring(0, ref.lastIndexOf('/'));
+            this.setAttribute("onClick", "window.location = '" + ref + "';");
+            this.setAttribute("title", "Back");
+            this.setAttribute("alt", "Back");
+		} else {
+            this.setAttribute("src", appRoot + "/res/imgs/arrow_down.png");
+            this.setAttribute("onClick", "hideDetails('" + data.id + "')");
+            this.setAttribute("title", "Hide Details");
+            this.setAttribute("alt", "Hide Details");
+		}
+	});
+	$("#bundleInlineDetails").append("<table border='0'><tbody></tbody></table>");
+    var details = data.props;
+    for (var idx in details) {
+        var prop = details[idx];
+        
+        var txt = "<tr><td class='aligntop' noWrap='true' style='border:0px none'>"
+ prop.key + "</td><td class='aligntop' style='border:0px none'>";	        
+        if (prop.value) {
+        	if ( prop.key == 'Bundle Documentation' )  {
+        		txt = txt + "<a href='" + prop.value + "' target='_blank'>" + prop.value
+ "</a>";
+        	} else  {
+        		if ( $.isArray(prop.value) ) {
+	        		var i = 0;
+	        		for(var pi in prop.value) {
+	        			var value = prop.value[pi];
+		                if (i > 0) { txt = txt + "<br/>"; }
+		                var span;
+		                if (value.substring(0, 2) == "!!") {
+		                	txt = txt + "<span style='{color: \"red\"}'>" + value + "</span>";
+		                } else {
+		                	txt = txt + value;
+		                }
+		                i++;
+	        		}
+        		} else {
+        			txt = txt + prop.value;
+        		}
+        	}
+        } else {
+        	txt = txt + "\u00a0";
+        }
+        txt = txt + "</td></tr>";
+        $("#bundleInlineDetails > table > tbody").append(txt);
+	}
+}
+
+function renderBundles(data) {	
+    $(document).ready(function(){
+    	renderView( ["Id", "Name", "Status", "Actions"],
+        		"<input type='hidden' name='action' value='install' style='margin-left:20px;'/>"
+
+                "<input class='input' type='file' name='bundlefile' size='50' style='margin-left:10px;'/>"
+
+         		" - Start <input class='checkradio' type='checkbox' name='bundlestart' value='start'
style='vertical-align:middle;'/>" +
+        		" - Start Level <input class='input' type='input' name='bundlestartlevel' value='"
+ startLevel + "' size='4'/>" +
+         		"<input type='submit' value='Install or Update' style='margin-left:60px'/>"
+
+        		"<button id='refreshPackages' type='button' name='refresh' style='margin-left:10px'>Refresh
Packages</button>"
+        		 );
+        $("#refreshPackages").click(refreshPackages);
+        renderData(data);
+        
+        $("#bundles").tablesorter({
+            headers: { 
+                3: { sorter: false }
+            } 
+        });
+    });
 }

Modified: felix/trunk/webconsole/src/main/resources/res/ui/datatable.js
URL: http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/ui/datatable.js?rev=741071&r1=741070&r2=741071&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/resources/res/ui/datatable.js (original)
+++ felix/trunk/webconsole/src/main/resources/res/ui/datatable.js Thu Feb  5 10:45:35 2009
@@ -144,19 +144,26 @@
     var buttonTd = td( "content", { align: "right" } );
     if ( op )
     {
-        var input = createElement( "input", "submit", {
-                type: 'button',
-                value: opLabel,
+    	var input;
+    	if ( title ) {
+	        input = createElement( "input", null, {
+                type: 'image',
+                alt: opLabel,
+                src: imgRoot + '/bundle_' + title + '.gif', 
                 onClick: 'changeDataEntryState(' + id + ', "' + op + '");'
             });
+    		
+    	} else {
+	        var input = createElement( "input", "submit", {
+	                type: 'button',
+	                value: opLabel,
+	                onClick: 'changeDataEntryState(' + id + ', "' + op + '");'
+	            });
+    	}
         if (!enabled)
         {
             input.setAttribute( "disabled", true );
         }
-        if (title)
-        {
-            input.setAttribute( "title", title );
-        }
         buttonTd.appendChild( input );
     }
     else



Mime
View raw message