Author: cziegeler
Date: Wed Mar 10 16:41:53 2010
New Revision: 921443

URL: http://svn.apache.org/viewvc?rev=921443&view=rev
Log:
FELIX-569 : Improve Configuration Page - Apply patch from Valentin Valchev

Modified:
    
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
    felix/trunk/webconsole/src/main/resources/OSGI-INF/l10n/bundle.properties
    felix/trunk/webconsole/src/main/resources/res/ui/config.css
    felix/trunk/webconsole/src/main/resources/res/ui/config.js
    felix/trunk/webconsole/src/main/resources/templates/config.html

Modified: 
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java?rev=921443&r1=921442&r2=921443&view=diff
==============================================================================
--- 
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
 (original)
+++ 
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/compendium/ConfigManager.java
 Wed Mar 10 16:41:53 2010
@@ -41,6 +41,7 @@ import javax.servlet.http.HttpServletRes
 
 import org.apache.felix.webconsole.DefaultVariableResolver;
 import org.apache.felix.webconsole.WebConsoleUtil;
+import org.apache.felix.webconsole.internal.Util;
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
@@ -131,6 +132,11 @@ public class ConfigManager extends Confi
 
                 WebConsoleUtil.sendRedirect(request, response, redirect);
             }
+            else
+            {
+                response.setContentType("text/plain");
+                response.getWriter().print("true");
+            }
 
             return;
         }
@@ -144,7 +150,8 @@ public class ConfigManager extends Confi
         if ( request.getParameter( "unbind" ) != null )
         {
             config.setBundleLocation( null );
-            WebConsoleUtil.sendRedirect( request, response, config.getPid() );
+            response.setContentType("text/plain");
+            response.getWriter().print("true");
             return;
         }
 
@@ -212,7 +219,7 @@ public class ConfigManager extends Confi
                 while ( i.hasNext() ) {
                     final String servicePid = i.next().toString();
 
-                    final Configuration config = this.getConfiguration(ca, 
servicePid);
+                    final Configuration config = getConfiguration(ca, 
servicePid);
                     if ( config != null ) {
                         if ( printColon ) {
                             pw.print(',');
@@ -283,7 +290,7 @@ public class ConfigManager extends Confi
         try
         {
             json.put("status", ca != null ? Boolean.TRUE : Boolean.FALSE);
-            listConfigurations(json, ca, pidFilter, locale);
+            listConfigurations(json, ca, pidFilter, locale, loc);
             listFactoryConfigurations(json, pidFilter, locale);
         }
         catch (JSONException e)
@@ -313,7 +320,7 @@ public class ConfigManager extends Confi
     }
 
 
-    private Configuration getConfiguration( ConfigurationAdmin ca, String pid )
+    private static final Configuration getConfiguration( ConfigurationAdmin 
ca, String pid )
     {
         if ( ca != null && pid != null )
         {
@@ -367,7 +374,7 @@ public class ConfigManager extends Confi
     }
 
     private final void listConfigurations(JSONObject json, ConfigurationAdmin 
ca,
-        String pidFilter, String locale)
+        String pidFilter, String locale, Locale loc)
     {
         try
         {
@@ -411,7 +418,26 @@ public class ConfigManager extends Confi
             {
                 String id = (String) i.next();
                 Object name = optionsPlain.get(id);
-                json.append("pids", new JSONObject().put("id", id).put("name", 
name));
+
+                final Configuration config = getConfiguration(ca, id);
+                JSONObject data = new JSONObject().put("id", id).put("name", 
name);
+                if (null != config)
+                {
+                    final String fpid = config.getFactoryPid();
+                    if (null != fpid)
+                    {
+                        data.put("fpid", fpid);
+                    }
+
+                    final Bundle bundle = getBoundBundle(config);
+                    if (null != bundle)
+                    {
+                        data.put("bundle", bundle.getBundleId());
+                        data.put("bundle_name", Util.getName(bundle, loc));
+                    }
+                }
+
+                json.append("pids", data);
             }
         }
         catch (Exception e)
@@ -420,6 +446,24 @@ public class ConfigManager extends Confi
         }
     }
 
+    private final Bundle getBoundBundle(Configuration config)
+    {
+        if (null == config)
+            return null;
+        final String location = config.getBundleLocation();
+        if (null == location)
+            return null;
+
+        final Bundle bundles[] = getBundleContext().getBundles();
+        for (int i = 0; bundles != null && i < bundles.length; i++)
+        {
+            if (bundles[i].getLocation().equals(location))
+                return bundles[i];
+
+        }
+        return null;
+    }
+
     private SortedMap getServices( String serviceClass, String serviceFilter, 
String locale, boolean ocdRequired )
         throws InvalidSyntaxException
     {
@@ -767,7 +811,7 @@ public class ConfigManager extends Confi
                 Configuration config = ca.getConfiguration( pid, null );
                 config.delete();
             }
-            return request.getHeader( "Referer" );
+            return null; // return request.getHeader( "Referer" );
         }
 
         String factoryPid = request.getParameter( ConfigManager.factoryPID );

Modified: 
felix/trunk/webconsole/src/main/resources/OSGI-INF/l10n/bundle.properties
URL: 
http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/OSGI-INF/l10n/bundle.properties?rev=921443&r1=921442&r2=921443&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/resources/OSGI-INF/l10n/bundle.properties 
(original)
+++ felix/trunk/webconsole/src/main/resources/OSGI-INF/l10n/bundle.properties 
Wed Mar 10 16:41:53 2010
@@ -170,7 +170,10 @@ config.del.ask=Are you sure to delete th
 config.del.config=Configuration: 
 config.del.bundle=Bundle: 
 config.unbind.ask=Are you sure to unbind this configuration ?
-
+config.factories.title=Factory Configurations
+config.configurations.title=Configurations
+config.create.tip=Create new factory configuration
+config.edit.tip=Edit the configuration values
 
 # License plugin
 license.status.ok=The following bundles contains license files.

Modified: felix/trunk/webconsole/src/main/resources/res/ui/config.css
URL: 
http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/ui/config.css?rev=921443&r1=921442&r2=921443&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/resources/res/ui/config.css (original)
+++ felix/trunk/webconsole/src/main/resources/res/ui/config.css Wed Mar 10 
16:41:53 2010
@@ -27,6 +27,8 @@ html>select { width: auto; min-width: 50
        margin:0;
        padding:0
 }
-.multiselect {
-    display: block;
-}
+.multiselect { display: block }
+.col_Actions { width: 6em !important }
+.pointer { cursor: pointer }
+#editor, div.ui-dialog-buttonpane button { font-size: 50% }
+#factoryTableCaption { margin-top: 1.5em }

Modified: felix/trunk/webconsole/src/main/resources/res/ui/config.js
URL: 
http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/res/ui/config.js?rev=921443&r1=921442&r2=921443&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/resources/res/ui/config.js (original)
+++ felix/trunk/webconsole/src/main/resources/res/ui/config.js Wed Mar 10 
16:41:53 2010
@@ -14,58 +14,40 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+// tables container - will get hidden, when no config service available
+var configContent = false;
 
-
-function configure() {
-    var select = document.getElementById('configSelection_pid');
-    var pid = select.options[select.selectedIndex].value;
-    var parm = pluginRoot + '/' + pid;
-       $.post(parm, null, displayConfigForm, "json");
-}
-
-
-function create() {
-    var select = document.getElementById('configSelection_factory');
-    var pid = select.options[select.selectedIndex].value;
-    var parm = pluginRoot + '/' + pid + '?create=true';
-       $.post(parm, null, displayConfigForm, "json");
+// config table list
+var configTable = false;
+var configBody  = false;
+var configRow = false;
+
+// factories table list
+var factoryTable = false;
+var factoryBody  = false;
+var factoryRow = false;
+
+
+// editor dialog
+var editor = false;
+
+function configure(pid, create) {
+       var uri = pluginRoot + '/' + pid;
+       $.post(create ? uri + '?create=1' : uri, null, displayConfigForm, 
'json');
 }
 
 function displayConfigForm(obj) {
-       var span1 = document.getElementById('configField');
-       var span2 = document.getElementById('factoryField');
-       if (!span1 && !span2) {
-               return;
-       } 
-    
-    var parent = span1 ? span1.parentNode : span2.parentNode;
-    
-    clearChildren( parent );
-    
-    if (span1) {
-        parent.appendChild( span1 );
-    }
-    if (span2) {
-        parent.appendChild( span2 );
-    }
-    
-    var trEl = tr( null );
-    var tdEl = createElement( "th", null, { colSpan: "2" } );
-    addText( tdEl, obj.title );
-    trEl.appendChild( tdEl );
-    parent.appendChild( trEl );
+       var parent = document.getElementById('editorTable');
+       clearChildren( parent )
 
-    trEl = tr( );
+    var trEl = tr( );
     parent.appendChild( trEl );
     
-    tdEl = td( );
-    addText( tdEl, "\u00a0" );
-    trEl.appendChild( tdEl );
-    
-    tdEl = td( );
+    var tdEl = td( null, { colSpan: "2" } );
     trEl.appendChild( tdEl );
     
     var formEl = createElement( "form", null, {
+                       id    : "editorForm",
             method: "POST",
             action: pluginRoot + "/" + obj.pid
         });
@@ -133,28 +115,9 @@ function displayConfigForm(obj) {
     {
         printForm(bodyEl, obj);
     }
-    
-    trEl = tr( );
-    bodyEl.appendChild( trEl );
-    
-    tdEl = td( );
-    addText( tdEl, "\u00a0" );
-    trEl.appendChild( tdEl );
-    
-    tdEl = td( );
-    trEl.appendChild( tdEl );
-
-    // define this TD as innerHTML otherwise the onClick event handler
-    // of the Delete button is not accepted by IE6 (!)...    
-    var innerHTML = '<input type="submit" name="submit" value="'+i18n.save+'" 
/>';
-    innerHTML += '&nbsp;&nbsp;&nbsp;';
-    innerHTML += '<input type="reset" name="reset" value="'+i18n.reset+'" />';
-    innerHTML += '&nbsp;&nbsp;&nbsp;';
-    innerHTML += '<input type="submit" name="delete" value="'+i18n.del+'" 
onClick="return confirmDelete(\'' + obj.pid + '\', \'' + obj.bundleLocation + 
'\');"/>';
-    tdEl.innerHTML = innerHTML;
 
     printConfigurationInfo(parent, obj);
-       initStaticWidgets($(parent));
+       initStaticWidgets(editor.attr('__pid', obj.pid).dialog('option', 
'title', obj.title).dialog('open'));
 }
 
 function printTextArea(/* Element */ parent, props )
@@ -291,29 +254,7 @@ function printConfigurationInfo( /* Elem
             ])
         ])
     );
-    
-    if (obj.bundleLocation)
-    {         
-        var form = createElement( "form", null, {
-                        method: "POST",
-                        action: pluginRoot + "/" + obj.pid
-                    });
-
-        // define this form contents as innerHTML otherwise the onClick
-        // event handler of the Unbind button is not accepted by IE6 (!)...
-        var formInner = '<input type="hidden" name="unbind" value="true"/>';
-        formInner += '<input type="submit" name="submit" 
value="'+i18n.unbind_btn+'" class="ui-state-default ui-corner-all" 
title="'+i18n.unbind_tip+'"  onClick="return confirmUnbind(\'' + obj.pid + '\', 
\'' + obj.bundleLocation + '\');"/>';
-        form.innerHTML = formInner;
-    
-        parent.appendChild( tr( null, null, [
-                td( null, null, [
-                    text( " " )
-                ]),
-                td( null, null, [ form ] )
-            ])
-        );
-    }
-       //$(form).ready(initStaticWidgets);
+
 }
 
 
@@ -475,7 +416,7 @@ function configConfirm(/* String */ mess
 
 function confirmDelete(/* String */ title, /* String */ location)
 {
-    return configConfirm(i18n.unbind_ask, title, location);
+    return configConfirm(i18n.del_ask, title, location);
 }
 
 function confirmUnbind(/* String */ title, /* String */ location)
@@ -483,26 +424,95 @@ function confirmUnbind(/* String */ titl
     return configConfirm(i18n.unbind_ask, title, location);
 }
 
-function addOption(list, target) 
-{
-       var html = "";
-       for (i in list) {
-               var sel = list[i].id == selectedPid ? '" selected="selected' : 
'';
-               html += '<option value="' + list[i].id + sel + '">' + 
list[i].name + '</option>';
-       }
-       if (html) target.html(html);
+function addConfig(conf) {
+       var tr = configRow.clone().appendTo(configBody);
+       tr.find('td:eq(0)').text(conf.fpid ? conf.fpid : '-'); // fpid
+       tr.find('td:eq(1)').text(conf.name).click(function() { // name & edit
+               configure(conf.id);
+       });
+       tr.find('td:eq(2)').html(conf.bundle ? '<a href="' + pluginRoot + 
'/../bundles/' + conf.bundle + '">' + conf.bundle_name + '</a>' : '-'); // 
binding
+       
+       // buttons
+       tr.find('li:eq(0)').click(function() { // edit
+               configure(conf.id);
+       });
+       tr.find('li:eq(2)').click(function() { // delete
+               if ( confirmDelete(conf.id, conf.bundle_name) ) {
+                       $.post(pluginRoot + '/' + conf.id + 
'?apply=1&delete=1', null, function() {
+                               document.location.href = pluginRoot;
+                       }, 'json');
+               }
+       });
+       if (conf.bundle) tr.find('li:eq(1)').click(function() { // unbind
+               if ( confirmUnbind(conf.id, conf.bundle_name) ) {
+                       $.post(pluginRoot + '/' + conf.id + 
'?apply=1&delete=1', null, function() {
+                               document.location.href = pluginRoot + '/' + 
conf.id;
+                       }, 'json');
+               }
+       }).removeClass('ui-state-disabled');
+}
+
+function addFactoryConfig(conf) {
+       var tr = factoryRow.clone().appendTo(factoryBody);
+       tr.find('td:eq(0)').text(conf.id); // fpid
+       tr.find('td:eq(1)').text(conf.name).click(function() { // name & edit
+               configure(conf.id, true);
+       });
+       // buttons
+       tr.find('li:eq(0)').click(function() { // edit
+               configure(conf.id, true);
+       });
 }
 
-var configSelection_pid = false;
-var configSelection_factory = false;
 $(document).ready(function() {
-       configSelection_pid = $('#configSelection_pid');
-       configSelection_factory = $('#configSelection_factory');
+       configContent = $('#configContent');
+       // config table list
+       configTable   = configContent.find('table:eq(0)').tablesorter({
+               headers: { 3: { sorter: false } },
+               textExtraction:mixedLinksExtraction
+       });
+       configBody    = configTable.find('tbody');
+       configRow     = configBody.find('tr').clone();
+
+       // factories table list
+       factoryTable  = configContent.find('table:eq(1)').tablesorter({
+               headers: { 2: { sorter: false } }
+       });
+       factoryBody   = factoryTable.find('tbody');
+       factoryRow    = factoryBody.find('tr').clone();
+       
+       // setup button - cannot inline in dialog option because of i18n
+       var _buttons = {};
+       _buttons[i18n.abort] = function() {
+               $(this).dialog('close');
+       }
+       _buttons[i18n.reset] = function() {
+               var form = document.getElementById('editorForm');
+               if (form) form.reset();
+       }
+       _buttons[i18n.save] = function() {
+               $.post(pluginRoot + '/' + $(this).attr('__pid') + '?' + 
$(this).find('form').serialize());
+               $(this).dialog('close');
+       }
+       // prepare editor, but don't open yet!
+       editor = $('#editor').dialog({
+               autoOpen : false,
+               modal    : true,
+               width    : '90%',
+               closeText: i18n.abort,
+               buttons  : _buttons
+       });
+
+       // display the configuration data
        $(".statline").html(configData.status ? i18n.stat_ok : 
i18n.stat_missing);
-       $("#config_content").css("display", configData.status ? "block" : 
"none");
        if (configData.status) {
-               addOption(configData.pids, $("#configSelection_pid"));
-               addOption(configData.fpids, $("#configSelection_factory"));
+               configBody.empty(); factoryBody.empty();
+
+               for(var i in configData.pids) addConfig(configData.pids[i]);
+               for(var i in configData.fpids) 
addFactoryConfig(configData.fpids[i]);
+               initStaticWidgets(configContent);
+       } else {
+               configContent.addClass('ui-helper-hidden');
        }
-       if (selectedPid) configure();
+       if (selectedPid) configure(selectedPid);
 });
\ No newline at end of file

Modified: felix/trunk/webconsole/src/main/resources/templates/config.html
URL: 
http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/resources/templates/config.html?rev=921443&r1=921442&r2=921443&view=diff
==============================================================================
--- felix/trunk/webconsole/src/main/resources/templates/config.html [UTF-8] 
(original)
+++ felix/trunk/webconsole/src/main/resources/templates/config.html [UTF-8] Wed 
Mar 10 16:41:53 2010
@@ -1,4 +1,4 @@
-<script type="text/javascript" src="res/ui/config.js"></script>
+<script type="text/javascript" src="res/ui/config.js"></script>
 <script type="text/javascript">
 // <![CDATA[
 // data
@@ -10,6 +10,7 @@ var i18n = { // i18n
        save         : '${save}',
        reset        : '${reset}',
        del          : '${delete}',
+       abort        : '${abort}',
        props_title  : '${config.properties}',
        props_enter  : '${config.properties.enter}', // "Enter Name-Value pairs 
of configuration properties"
        cfg_title    : '${config.info.title}', // "Configuration Information"
@@ -22,10 +23,7 @@ var i18n = { // i18n
        del_ask      : '${config.del.ask}', // "Are you sure to delete this 
configuration ?";
        del_config   : '${config.del.config}', // "Configuration: ";
        del_bundle   : '${config.del.bundle}', // "Bundle: ";
-       unbind_ask   : '${config.unbind.ask}', // "Are you sure to unbind this 
configuration ?"
-       'xx' : '${config.form.properties}',
-       'xx' : '${config.form.properties}',
-
+       unbind_ask   : '${config.unbind.ask}' // "Are you sure to unbind this 
configuration ?"
 }
 // ]]>
 </script>
@@ -33,27 +31,65 @@ var i18n = { // i18n
 <!-- status line -->
 <p class="statline">&nbsp;</p>
 
-<div id="config_content" >
-       <table class="nicetable">
-       <tr id="configField">
-               <td>Configurations</td>
-               <td>
-                       <select name="pid" id="configSelection_pid" 
onchange="configure();">
-                               <option>&nbsp;</option>
-                       </select>
-                       &nbsp;
-                       <button onclick="configure();">Configure</button>
-               </td>
-       </tr>
-       <tr id="factoryField">
-               <td>Factory Configurations</td>
-               <td>
-                       <select name="pid" id="configSelection_factory" 
onchange="create();">
-                               <option>&nbsp;</option>
-                       </select>
-                       &nbsp;
-                       <button onclick="create();">Create</button>
-               </td>
-       </tr>
+
+<div id="configContent" >
+       <div id="fPidsSelect" class="ui-widget-header ui-corner-top 
buttonGroup">
+               ${config.configurations.title}
+       </div>
+       <table class="tablesorter nicetable noauto">
+               <thead>
+                       <tr>
+                               <th class="col_FPID">Factory PID</th>
+                               <th class="col_Name">Name</th>
+                               <th class="col_Binding">Bundle</th>
+                               <th class="col_Actions" style="width: 
7em">Actions</th>
+                       </tr>
+               </thead>
+               <tbody>
+                       <tr>
+                               <td>&nbsp;</td>
+                               <td class="pointer">&nbsp;</td>
+                               <td>&nbsp;</td>
+                               <td>
+                                       <ul class="icons">
+                                               <li class="dynhover" 
title="${config.edit.tip}"><span class="ui-icon 
ui-icon-pencil">&nbsp;</span></li>
+                                               <li class="ui-state-disabled 
dynhover" title="${config.unbind.tip}"><span class="ui-icon 
ui-icon-transferthick-e-w">&nbsp;</span></li>
+                                               <li class="dynhover" 
title="${delete}"><span class="ui-icon ui-icon-trash">&nbsp;</span></li>
+                                       </ul>
+                               </td>
+                       </tr>
+               </tbody>
+       </table>
+
+       <div id="factoryTableCaption" class="ui-widget-header ui-corner-top 
buttonGroup">
+               ${config.factories.title}
+       </div>
+       <table class="tablesorter nicetable noauto">
+               <thead>
+                       <tr>
+                               <th class="col_FPID">Factory PID</th>
+                               <th class="col_Name">Name</th>
+                               <th class="col_Actions" style="width: 
7em">Actions</th>
+                       </tr>
+               </thead>
+               <tbody>
+                       <tr>
+                               <td>&nbsp;</td>
+                               <td class="pointer">&nbsp;</td>
+                               <td>
+                                       <ul class="icons">
+                                               <li class="dynhover" 
title="${config.create.tip}"><span class="ui-icon 
ui-icon-plusthick">&nbsp;</span></li>
+                                       </ul>
+                               </td>
+                       </tr>
+               </tbody>
+       </table>
+       
+</div>
+
+<!-- placeholder for property editor -->
+<div id="editor" class="ui-helper-hidden">
+       <table id="editorTable" class="nicetable">
+               <tr><td>&nbsp;</td></tr>
        </table>
 </div>


Reply via email to