FELIX-566 next step in making bundle display more REST-ful:
requesting ..../bundles lists all bundles
requesting ..../bundles/<id> just lists the bundle with the given <id> and its details
bundle actions (start, stop, uninstall, refreshPackages) is now
integrated with the single BundlesServlet handling the bundles
requests
The BundlesServlet is the default start page
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@667270 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/AjaxBundleDetailsAction.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/AjaxBundleDetailsAction.java
deleted file mode 100644
index b3a312d..0000000
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/AjaxBundleDetailsAction.java
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.felix.webconsole.internal.core;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.felix.bundlerepository.R4Attribute;
-import org.apache.felix.bundlerepository.R4Export;
-import org.apache.felix.bundlerepository.R4Import;
-import org.apache.felix.bundlerepository.R4Package;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.Version;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.osgi.service.component.ComponentConstants;
-import org.osgi.service.packageadmin.ExportedPackage;
-import org.osgi.service.packageadmin.PackageAdmin;
-import org.osgi.service.startlevel.StartLevel;
-
-
-public class AjaxBundleDetailsAction extends BundleAction
-{
-
- public static final String NAME = "ajaxBundleDetails";
-
- // 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.
- // see #activate and #isBootDelegated
- private String[] bootPkgs;
-
- // a flag for each entry in bootPkgs indicating whether the respective
- // entry was declared as a wildcard or not
- // see #activate and #isBootDelegated
- private boolean[] bootPkgWildcards;
-
-
- public void activate( BundleContext bundleContext )
- {
- super.activate( bundleContext );
-
- // bootdelegation property parsing from Apache Felix R4SearchPolicyCore
- String bootDelegation = bundleContext.getProperty( Constants.FRAMEWORK_BOOTDELEGATION );
- bootDelegation = ( bootDelegation == null ) ? "java.*" : bootDelegation + ",java.*";
- StringTokenizer st = new StringTokenizer( bootDelegation, " ," );
- bootPkgs = new String[st.countTokens()];
- bootPkgWildcards = new boolean[bootPkgs.length];
- for ( int i = 0; i < bootPkgs.length; i++ )
- {
- bootDelegation = st.nextToken();
- if ( bootDelegation.endsWith( "*" ) )
- {
- bootPkgWildcards[i] = true;
- bootDelegation = bootDelegation.substring( 0, bootDelegation.length() - 1 );
- }
- bootPkgs[i] = bootDelegation;
- }
- }
-
-
- public String getName()
- {
- return NAME;
- }
-
-
- public String getLabel()
- {
- return NAME;
- }
-
-
- public boolean performAction( HttpServletRequest request, HttpServletResponse response ) throws IOException
- {
- JSONObject result = null;
- try
- {
- long bundleId = getBundleId( request );
- Bundle bundle = getBundleContext().getBundle( bundleId );
- if ( bundle != null )
- {
- Dictionary headers = bundle.getHeaders();
-
- JSONArray props = new JSONArray();
- keyVal( props, "Symbolic Name", bundle.getSymbolicName() );
- keyVal( props, "Version", headers.get( Constants.BUNDLE_VERSION ) );
- keyVal( props, "Location", bundle.getLocation() );
- keyVal( props, "Last Modification", new Date( bundle.getLastModified() ) );
-
- keyVal( props, "Vendor", headers.get( Constants.BUNDLE_VENDOR ) );
- keyVal( props, "Copyright", headers.get( Constants.BUNDLE_COPYRIGHT ) );
- keyVal( props, "Description", headers.get( Constants.BUNDLE_DESCRIPTION ) );
-
- keyVal( props, "Start Level", getStartLevel( bundle ) );
-
- if ( bundle.getState() == Bundle.INSTALLED )
- {
- listImportExportsUnresolved( props, bundle );
- }
- else
- {
- listImportExport( props, bundle );
- }
-
- listServices( props, bundle );
-
- result = new JSONObject();
- result.put( BundleListRender.BUNDLE_ID, bundleId );
- result.put( "props", props );
- }
- }
- catch ( Exception exception )
- {
- // create an empty result on problems
- result = new JSONObject();
- }
-
- // send the result
- response.setContentType( "text/javascript" );
- response.getWriter().print( result.toString() );
-
- return false;
- }
-
-
- private Integer getStartLevel( Bundle bundle )
- {
- StartLevel sl = getStartLevel();
- return ( sl != null ) ? new Integer( sl.getBundleStartLevel( bundle ) ) : null;
- }
-
-
- private void listImportExport( JSONArray props, Bundle bundle )
- {
- PackageAdmin packageAdmin = getPackageAdmin();
- if ( packageAdmin == null )
- {
- return;
- }
-
- Map usingBundles = new TreeMap();
-
- ExportedPackage[] exports = packageAdmin.getExportedPackages( bundle );
- if ( exports != null && exports.length > 0 )
- {
- // do alphabetical sort
- Arrays.sort( exports, new Comparator()
- {
- public int compare( ExportedPackage p1, ExportedPackage p2 )
- {
- return p1.getName().compareTo( p2.getName() );
- }
-
-
- public int compare( Object o1, Object o2 )
- {
- return compare( ( ExportedPackage ) o1, ( ExportedPackage ) o2 );
- }
- } );
-
- StringBuffer val = new StringBuffer();
- for ( int j = 0; j < exports.length; j++ )
- {
- ExportedPackage export = exports[j];
- printExport( val, export.getName(), export.getVersion() );
- Bundle[] ubList = export.getImportingBundles();
- if ( ubList != null )
- {
- for ( int i = 0; i < ubList.length; i++ )
- {
- Bundle ub = ubList[i];
- usingBundles.put( ub.getSymbolicName(), ub );
- }
- }
- }
- keyVal( props, "Exported Packages", val.toString() );
- }
- else
- {
- keyVal( props, "Exported Packages", "None" );
- }
-
- exports = packageAdmin.getExportedPackages( ( Bundle ) null );
- if ( exports != null && exports.length > 0 )
- {
- // collect import packages first
- final List imports = new ArrayList();
- for ( int i = 0; i < exports.length; i++ )
- {
- final ExportedPackage ep = exports[i];
- final Bundle[] importers = ep.getImportingBundles();
- for ( int j = 0; importers != null && j < importers.length; j++ )
- {
- if ( importers[j].getBundleId() == bundle.getBundleId() )
- {
- imports.add( ep );
-
- break;
- }
- }
- }
- // now sort
- StringBuffer val = new StringBuffer();
- if ( imports.size() > 0 )
- {
- final ExportedPackage[] packages = ( ExportedPackage[] ) imports.toArray( new ExportedPackage[imports
- .size()] );
- Arrays.sort( packages, new Comparator()
- {
- public int compare( ExportedPackage p1, ExportedPackage p2 )
- {
- return p1.getName().compareTo( p2.getName() );
- }
-
-
- public int compare( Object o1, Object o2 )
- {
- return compare( ( ExportedPackage ) o1, ( ExportedPackage ) o2 );
- }
- } );
- // and finally print out
- for ( int i = 0; i < packages.length; i++ )
- {
- ExportedPackage ep = packages[i];
- printImport( val, ep.getName(), ep.getVersion(), ep );
- }
- }
- else
- {
- // add description if there are no imports
- val.append( "None" );
- }
-
- keyVal( props, "Imported Packages", val.toString() );
- }
-
- if ( !usingBundles.isEmpty() )
- {
- StringBuffer val = new StringBuffer();
- for ( Iterator ui = usingBundles.values().iterator(); ui.hasNext(); )
- {
- Bundle usingBundle = ( Bundle ) ui.next();
- val.append( getBundleDescriptor( usingBundle ) );
- val.append( "<br />" );
- }
- keyVal( props, "Importing Bundles", val.toString() );
- }
- }
-
-
- private void listImportExportsUnresolved( JSONArray props, Bundle bundle )
- {
- Dictionary dict = bundle.getHeaders();
-
- String target = ( String ) dict.get( Constants.EXPORT_PACKAGE );
- if ( target != null )
- {
- R4Package[] pkgs = R4Package.parseImportOrExportHeader( target );
- if ( pkgs != null && pkgs.length > 0 )
- {
- // do alphabetical sort
- Arrays.sort( pkgs, new Comparator()
- {
- public int compare( R4Package p1, R4Package p2 )
- {
- return p1.getName().compareTo( p2.getName() );
- }
-
-
- public int compare( Object o1, Object o2 )
- {
- return compare( ( R4Package ) o1, ( R4Package ) o2 );
- }
- } );
-
- StringBuffer val = new StringBuffer();
- for ( int i = 0; i < pkgs.length; i++ )
- {
- R4Export export = new R4Export( pkgs[i] );
- printExport( val, export.getName(), export.getVersion() );
- }
- keyVal( props, "Exported Packages", val.toString() );
- }
- else
- {
- keyVal( props, "Exported Packages", "None" );
- }
- }
-
- target = ( String ) dict.get( Constants.IMPORT_PACKAGE );
- if ( target != null )
- {
- R4Package[] pkgs = R4Package.parseImportOrExportHeader( target );
- if ( pkgs != null && pkgs.length > 0 )
- {
- Map imports = new TreeMap();
- for ( int i = 0; i < pkgs.length; i++ )
- {
- R4Package pkg = pkgs[i];
- imports.put( pkg.getName(), new R4Import( pkg ) );
- }
-
- // collect import packages first
- final Map candidates = new HashMap();
- PackageAdmin packageAdmin = getPackageAdmin();
- if ( packageAdmin != null )
- {
- ExportedPackage[] exports = packageAdmin.getExportedPackages( ( Bundle ) null );
- if ( exports != null && exports.length > 0 )
- {
-
- for ( int i = 0; i < exports.length; i++ )
- {
- final ExportedPackage ep = exports[i];
-
- R4Import imp = ( R4Import ) imports.get( ep.getName() );
- if ( imp != null && imp.isSatisfied( toR4Export( ep ) ) )
- {
- candidates.put( ep.getName(), ep );
- }
- }
- }
- }
-
- // now sort
- StringBuffer val = new StringBuffer();
- if ( imports.size() > 0 )
- {
- for ( Iterator ii = imports.values().iterator(); ii.hasNext(); )
- {
- R4Import r4Import = ( R4Import ) ii.next();
- ExportedPackage ep = ( ExportedPackage ) candidates.get( r4Import.getName() );
-
- // if there is no matching export, check whether this
- // bundle has the package, ignore the entry in this case
- if ( ep == null )
- {
- String path = r4Import.getName().replace( '.', '/' );
- if ( bundle.getResource( path ) != null )
- {
- continue;
- }
- }
-
- printImport( val, r4Import.getName(), r4Import.getVersion(), ep );
- }
- }
- else
- {
- // add description if there are no imports
- val.append( "None" );
- }
-
- keyVal( props, "Imported Packages", val.toString() );
- }
- }
- }
-
-
- private void listServices( JSONArray props, Bundle bundle )
- {
- ServiceReference[] refs = bundle.getRegisteredServices();
- if ( refs == null || refs.length == 0 )
- {
- return;
- }
-
- for ( int i = 0; i < refs.length; i++ )
- {
- String key = "Service ID " + refs[i].getProperty( Constants.SERVICE_ID );
-
- StringBuffer val = new StringBuffer();
-
- appendProperty( val, refs[i], Constants.OBJECTCLASS, "Types" );
- appendProperty( val, refs[i], Constants.SERVICE_PID, "PID" );
- appendProperty( val, refs[i], ConfigurationAdmin.SERVICE_FACTORYPID, "Factory PID" );
- appendProperty( val, refs[i], ComponentConstants.COMPONENT_NAME, "Component Name" );
- appendProperty( val, refs[i], ComponentConstants.COMPONENT_ID, "Component ID" );
- appendProperty( val, refs[i], ComponentConstants.COMPONENT_FACTORY, "Component Factory" );
- appendProperty( val, refs[i], Constants.SERVICE_DESCRIPTION, "Description" );
- appendProperty( val, refs[i], Constants.SERVICE_VENDOR, "Vendor" );
-
- keyVal( props, key, val.toString() );
- }
- }
-
-
- private void appendProperty( StringBuffer dest, ServiceReference ref, String name, String label )
- {
- Object value = ref.getProperty( name );
- if ( value instanceof Object[] )
- {
- Object[] values = ( Object[] ) value;
- dest.append( label ).append( ": " );
- for ( int j = 0; j < values.length; j++ )
- {
- if ( j > 0 )
- dest.append( ", " );
- dest.append( values[j] );
- }
- dest.append( "<br />" ); // assume HTML use of result
- }
- else if ( value != null )
- {
- dest.append( label ).append( ": " ).append( value ).append( "<br />" );
- }
- }
-
-
- private void keyVal( JSONArray props, String key, Object value )
- {
- if ( key != null && value != null )
- {
- try
- {
- JSONObject obj = new JSONObject();
- obj.put( "key", key );
- obj.put( "value", value );
- props.put( obj );
- }
- catch ( JSONException je )
- {
- // don't care
- }
- }
- }
-
-
- private void printExport( StringBuffer val, String name, Version version )
- {
- boolean bootDel = isBootDelegated( name );
- if ( bootDel )
- {
- val.append( "<span style=\"color: red\">!! " );
- }
-
- val.append( name );
- val.append( ",version=" );
- val.append( version );
-
- if ( bootDel )
- {
- val.append( " -- Overwritten by Boot Delegation</span>" );
- }
-
- val.append( "<br />" );
- }
-
-
- private void printImport( StringBuffer val, String name, Version version, ExportedPackage export )
- {
- boolean bootDel = isBootDelegated( name );
- if ( bootDel || export == null )
- {
- val.append( "<span style=\"color: red\">!! " );
- }
-
- val.append( name );
- val.append( ",version=" ).append( version );
- val.append( " from " );
-
- if ( export != null )
- {
- val.append( getBundleDescriptor( export.getExportingBundle() ) );
-
- if ( bootDel )
- {
- val.append( " -- Overwritten by Boot Delegation</span>" );
- }
- }
- else
- {
- val.append( " -- Cannot be resolved" );
- if ( bootDel )
- {
- val.append( " and overwritten by Boot Delegation" );
- }
- val.append( "</span>" );
- }
-
- val.append( "<br />" );
- }
-
-
- // returns true if the package is listed in the bootdelegation property
- private boolean isBootDelegated( String pkgName )
- {
-
- // bootdelegation analysis from Apache Felix R4SearchPolicyCore
-
- // Only consider delegation if we have a package name, since
- // we don't want to promote the default package. The spec does
- // not take a stand on this issue.
- if ( pkgName.length() > 0 )
- {
-
- // Delegate any packages listed in the boot delegation
- // property to the parent class loader.
- for ( int i = 0; i < bootPkgs.length; i++ )
- {
-
- // A wildcarded boot delegation package will be in the form of
- // "foo.", so if the package is wildcarded do a startsWith() or
- // a regionMatches() to ignore the trailing "." to determine if
- // the request should be delegated to the parent class loader.
- // If the package is not wildcarded, then simply do an equals()
- // test to see if the request should be delegated to the parent
- // class loader.
- if ( ( bootPkgWildcards[i] && ( pkgName.startsWith( bootPkgs[i] ) || bootPkgs[i].regionMatches( 0,
- pkgName, 0, pkgName.length() ) ) )
- || ( !bootPkgWildcards[i] && bootPkgs[i].equals( pkgName ) ) )
- {
- return true;
- }
- }
- }
-
- return false;
- }
-
-
- private R4Export toR4Export( ExportedPackage export )
- {
- R4Attribute version = new R4Attribute( Constants.VERSION_ATTRIBUTE, export.getVersion().toString(), false );
- return new R4Export( export.getName(), null, new R4Attribute[]
- { version } );
- }
-
-
- private String getBundleDescriptor( Bundle bundle )
- {
- StringBuffer val = new StringBuffer();
- if ( bundle.getSymbolicName() != null )
- {
- // list the bundle name if not null
- val.append( bundle.getSymbolicName() );
- val.append( " (" ).append( bundle.getBundleId() );
- val.append( ")" );
- }
- else if ( bundle.getLocation() != null )
- {
- // otherwise try the location
- val.append( bundle.getLocation() );
- val.append( " (" ).append( bundle.getBundleId() );
- val.append( ")" );
- }
- else
- {
- // fallback to just the bundle id
- // only append the bundle
- val.append( bundle.getBundleId() );
- }
- return val.toString();
- }
-}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundleAction.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundleAction.java
index f68f46e..5cfb252 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundleAction.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundleAction.java
@@ -28,7 +28,7 @@
protected long getBundleId( HttpServletRequest request )
{
- String bundleIdPar = request.getParameter( BundleListRender.BUNDLE_ID );
+ String bundleIdPar = request.getParameter( BundlesServlet.BUNDLE_ID );
if ( bundleIdPar != null )
{
try
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundleListRender.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
similarity index 90%
rename from webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundleListRender.java
rename to webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
index 5418352..c775a57 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundleListRender.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/BundlesServlet.java
@@ -32,8 +32,6 @@
import java.util.TreeMap;
import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -43,7 +41,6 @@
import org.apache.felix.bundlerepository.R4Package;
import org.apache.felix.webconsole.internal.BaseWebConsolePlugin;
import org.apache.felix.webconsole.internal.Util;
-import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONWriter;
import org.osgi.framework.Bundle;
@@ -54,19 +51,19 @@
import org.osgi.framework.Version;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentConstants;
+import org.osgi.service.log.LogService;
import org.osgi.service.obr.Repository;
import org.osgi.service.obr.RepositoryAdmin;
import org.osgi.service.obr.Resource;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.startlevel.StartLevel;
-import org.osgi.util.tracker.ServiceTracker;
/**
- * The <code>BundleListRender</code> TODO
+ * The <code>BundlesServlet</code> TODO
*/
-public class BundleListRender extends BaseWebConsolePlugin
+public class BundlesServlet extends BaseWebConsolePlugin
{
public static final String NAME = "bundles";
@@ -169,12 +166,18 @@
protected void doPost( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException
{
+ String action = req.getParameter( "action" );
+ if ( "refreshPackages".equals( action ) )
+ {
+ getPackageAdmin().refreshPackages( null );
+ }
+
boolean success = false;
Bundle bundle = getBundle( req.getPathInfo() );
long bundleId = bundle.getBundleId();
+
if ( bundle != null )
{
- String action = req.getParameter( "action" );
if ( "start".equals( action ) )
{
// start bundle
@@ -185,7 +188,7 @@
}
catch ( BundleException be )
{
- // log
+ getLog().log( LogService.LOG_ERROR, "Cannot start", be );
}
}
else if ( "stop".equals( action ) )
@@ -198,7 +201,7 @@
}
catch ( BundleException be )
{
- // log
+ getLog().log( LogService.LOG_ERROR, "Cannot stop", be );
}
}
else if ( "update".equals( action ) )
@@ -217,11 +220,21 @@
}
catch ( BundleException be )
{
- // log
+ getLog().log( LogService.LOG_ERROR, "Cannot uninstall", be );
}
}
}
+ if ( "refreshPackages".equals( action ) )
+ {
+ success = true;
+ getPackageAdmin().refreshPackages( null );
+
+ // refresh completely
+ bundle = null;
+ bundleId = -1;
+ }
+
if ( success )
{
// redirect or 200
@@ -233,13 +246,20 @@
{
bundleInfo( jw, bundle, true );
}
- else
+ 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 )
{
@@ -303,7 +323,7 @@
if ( bundles != null && bundles.length > 0 )
{
- sort( bundles );
+ Util.sort( bundles );
jw.key( "bundles" );
@@ -338,7 +358,7 @@
jw.key( "bundleId" );
jw.value( bundle.getBundleId() );
jw.key( "name" );
- jw.value( getName( bundle ) );
+ jw.value( Util.getName( bundle ) );
jw.key( "state" );
jw.value( toStateString( bundle.getState() ) );
jw.key( "hasStart" );
@@ -448,32 +468,7 @@
}
- private void sort( Bundle[] bundles )
- {
- Arrays.sort( bundles, BUNDLE_NAME_COMPARATOR );
- }
-
-
- private static String getName( Bundle bundle )
- {
- String name = ( String ) bundle.getHeaders().get( Constants.BUNDLE_NAME );
- if ( name == null || name.length() == 0 )
- {
- name = bundle.getSymbolicName();
- if ( name == null )
- {
- name = bundle.getLocation();
- if ( name == null )
- {
- name = String.valueOf( bundle.getBundleId() );
- }
- }
- }
- return name;
- }
-
-
- public void performAction( JSONWriter jw, Bundle bundle ) throws JSONException
+ private void performAction( JSONWriter jw, Bundle bundle ) throws JSONException
{
jw.object();
jw.key( BUNDLE_ID );
@@ -485,7 +480,7 @@
}
- public void bundleDetails( JSONWriter jw, Bundle bundle ) throws JSONException
+ private void bundleDetails( JSONWriter jw, Bundle bundle ) throws JSONException
{
Dictionary headers = bundle.getHeaders();
@@ -942,59 +937,4 @@
return val.toString();
}
- // ---------- inner classes ------------------------------------------------
-
- private static final Comparator BUNDLE_NAME_COMPARATOR = new Comparator()
- {
- public int compare( Object o1, Object o2 )
- {
- return compare( ( Bundle ) o1, ( Bundle ) o2 );
- }
-
-
- public int compare( Bundle b1, Bundle b2 )
- {
-
- // the same bundles
- if ( b1 == b2 || b1.getBundleId() == b2.getBundleId() )
- {
- return 0;
- }
-
- // special case for system bundle, which always is first
- if ( b1.getBundleId() == 0 )
- {
- return -1;
- }
- else if ( b2.getBundleId() == 0 )
- {
- return 1;
- }
-
- // compare the symbolic names
- int snComp = getName( b1 ).compareToIgnoreCase( getName( b2 ) );
- if ( snComp != 0 )
- {
- return snComp;
- }
-
- // same names, compare versions
- Version v1 = Version.parseVersion( ( String ) b1.getHeaders().get( Constants.BUNDLE_VERSION ) );
- Version v2 = Version.parseVersion( ( String ) b2.getHeaders().get( Constants.BUNDLE_VERSION ) );
- int vComp = v1.compareTo( v2 );
- if ( vComp != 0 )
- {
- return vComp;
- }
-
- // same version ? Not really, but then, we compare by bundle id
- if ( b1.getBundleId() < b2.getBundleId() )
- {
- return -1;
- }
-
- // b1 id must be > b2 id because equality is already checked
- return 1;
- }
- };
}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/RefreshPackagesAction.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/RefreshPackagesAction.java
deleted file mode 100644
index b149d8c..0000000
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/RefreshPackagesAction.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.felix.webconsole.internal.core;
-
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-
-/**
- * The <code>RefreshPackagesAction</code> TODO
- */
-public class RefreshPackagesAction extends BundleAction
-{
-
- public static final String NAME = "refreshPackages";
-
- public static final String LABEL = "Refresh Packages";
-
-
- public String getName()
- {
- return NAME;
- }
-
-
- public String getLabel()
- {
- return LABEL;
- }
-
-
- public boolean performAction( HttpServletRequest request, HttpServletResponse response )
- {
-
- getPackageAdmin().refreshPackages( null );
-
- return true;
- }
-
-}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/StartAction.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/StartAction.java
deleted file mode 100644
index 321321b..0000000
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/StartAction.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.felix.webconsole.internal.core;
-
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
-import org.osgi.service.log.LogService;
-
-
-public class StartAction extends BundleAction
-{
-
- public static final String NAME = "start";
- public static final String LABEL = "Start";
-
-
- public String getName()
- {
- return NAME;
- }
-
-
- public String getLabel()
- {
- return LABEL;
- }
-
-
- public boolean performAction( HttpServletRequest request, HttpServletResponse response )
- {
-
- long bundleId = this.getBundleId( request );
- if ( bundleId > 0 )
- { // cannot start system bundle !!
- Bundle bundle = this.getBundleContext().getBundle( bundleId );
- if ( bundle != null )
- {
- try
- {
- bundle.start();
- }
- catch ( BundleException be )
- {
- getLog().log( LogService.LOG_ERROR, "Cannot start", be );
- }
-
- }
- }
- return true;
- }
-}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/StopAction.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/StopAction.java
deleted file mode 100644
index f876d16..0000000
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/StopAction.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.felix.webconsole.internal.core;
-
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
-import org.osgi.service.log.LogService;
-
-
-/**
- * The <code>StopAction</code> TODO
- */
-public class StopAction extends BundleAction
-{
-
- public static final String NAME = "stop";
- public static final String LABEL = "Stop";
-
-
- public String getName()
- {
- return NAME;
- }
-
-
- public String getLabel()
- {
- return LABEL;
- }
-
-
- public boolean performAction( HttpServletRequest request, HttpServletResponse response )
- {
-
- long bundleId = this.getBundleId( request );
- if ( bundleId > 0 )
- { // cannot stop system bundle !!
- Bundle bundle = this.getBundleContext().getBundle( bundleId );
- if ( bundle != null )
- {
- try
- {
- bundle.stop();
- }
- catch ( BundleException be )
- {
- getLog().log( LogService.LOG_ERROR, "Cannot stop", be );
- }
-
- }
- }
-
- return true;
- }
-}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/UninstallAction.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/UninstallAction.java
deleted file mode 100644
index 32b451e..0000000
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/UninstallAction.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.felix.webconsole.internal.core;
-
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
-import org.osgi.service.log.LogService;
-
-
-public class UninstallAction extends BundleAction
-{
-
- public static final String NAME = "uninstall";
- public static final String LABEL = "Uninstall";
-
-
- public String getName()
- {
- return NAME;
- }
-
-
- public String getLabel()
- {
- return LABEL;
- }
-
-
- public boolean performAction( HttpServletRequest request, HttpServletResponse response )
- {
-
- long bundleId = this.getBundleId( request );
- if ( bundleId > 0 )
- { // cannot stop system bundle !!
- Bundle bundle = this.getBundleContext().getBundle( bundleId );
- if ( bundle != null )
- {
- try
- {
- bundle.uninstall();
- }
- catch ( BundleException be )
- {
- getLog().log( LogService.LOG_ERROR, "Cannot uninstall", be );
- }
-
- }
- }
-
- return true;
- }
-}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/AssemblyListRender.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/AssemblyListRender.java
index 181c1bb..a4dc873 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/AssemblyListRender.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/misc/AssemblyListRender.java
@@ -20,11 +20,11 @@
import java.util.ArrayList;
import java.util.List;
-import org.apache.felix.webconsole.internal.core.BundleListRender;
+import org.apache.felix.webconsole.internal.core.BundlesServlet;
import org.osgi.framework.Bundle;
-public class AssemblyListRender extends BundleListRender
+public class AssemblyListRender extends BundlesServlet
{
public static final String NAME = "assemblyList";
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
index 4b5f4e1..f0b9933 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
@@ -44,9 +44,8 @@
import org.apache.felix.webconsole.internal.compendium.ComponentConfigurationPrinter;
import org.apache.felix.webconsole.internal.compendium.ComponentRenderAction;
import org.apache.felix.webconsole.internal.compendium.ConfigManager;
-import org.apache.felix.webconsole.internal.core.BundleListRender;
+import org.apache.felix.webconsole.internal.core.BundlesServlet;
import org.apache.felix.webconsole.internal.core.InstallAction;
-import org.apache.felix.webconsole.internal.core.RefreshPackagesAction;
import org.apache.felix.webconsole.internal.core.SetStartLevelAction;
import org.apache.felix.webconsole.internal.misc.ConfigurationRender;
import org.apache.felix.webconsole.internal.obr.BundleRepositoryRender;
@@ -90,42 +89,44 @@
private static final String PROP_MANAGER_ROOT = "manager.root";
/**
- * @scr.property value="list"
+ * @scr.property valueRef="DEFAULT_PAGE"
*/
private static final String PROP_DEFAULT_RENDER = "default.render";
/**
- * @scr.property value="OSGi Management Console"
+ * @scr.property valueRef="DEFAULT_REALM"
*/
private static final String PROP_REALM = "realm";
/**
- * @scr.property value="admin"
+ * @scr.property valueRef="DEFAULT_USER_NAME"
*/
private static final String PROP_USER_NAME = "username";
/**
- * @scr.property value="admin"
+ * @scr.property valueRef="DEFAULT_PASSWORD"
*/
private static final String PROP_PASSWORD = "password";
+ private static final String DEFAULT_PAGE = BundlesServlet.NAME;
+
+ private static final String DEFAULT_REALM = "OSGi Management Console";
+
+ private static final String DEFAULT_USER_NAME = "admin";
+
+ private static final String DEFAULT_PASSWORD = "admin";
+
/**
* The default value for the {@link #PROP_MANAGER_ROOT} configuration
* property (value is "/system/console").
*/
private static final String DEFAULT_MANAGER_ROOT = "/system/console";
- // private static final Class[] PLUGIN_CLASSES =
- // { AjaxConfigManagerAction.class, ComponentConfigurationPrinter.class, ComponentRenderAction.class,
- // ConfigManager.class, AjaxBundleDetailsAction.class, BundleListRender.class, InstallAction.class,
- // RefreshPackagesAction.class, SetStartLevelAction.class, StartAction.class, StopAction.class,
- // UninstallAction.class, UpdateAction.class, ConfigurationRender.class, GCAction.class, ShutdownAction.class,
- // ShutdownRender.class, VMStatRender.class };
private static final Class[] PLUGIN_CLASSES =
{ AjaxConfigManagerAction.class, ComponentConfigurationPrinter.class, ComponentRenderAction.class,
- ConfigManager.class, BundleListRender.class, InstallAction.class, RefreshPackagesAction.class,
- SetStartLevelAction.class, ConfigurationRender.class, GCAction.class, ShutdownAction.class,
- ShutdownRender.class, VMStatRender.class, BundleRepositoryRender.class };
+ ConfigManager.class, BundlesServlet.class, InstallAction.class, SetStartLevelAction.class,
+ ConfigurationRender.class, GCAction.class, ShutdownAction.class, ShutdownRender.class, VMStatRender.class,
+ BundleRepositoryRender.class };
private BundleContext bundleContext;
@@ -537,9 +538,9 @@
Dictionary config = getConfiguration();
// get authentication details
- String realm = this.getProperty( config, PROP_REALM, "OSGi Management Console" );
- String userId = this.getProperty( config, PROP_USER_NAME, null );
- String password = this.getProperty( config, PROP_PASSWORD, null );
+ String realm = this.getProperty( config, PROP_REALM, DEFAULT_REALM );
+ String userId = this.getProperty( config, PROP_USER_NAME, DEFAULT_USER_NAME );
+ String password = this.getProperty( config, PROP_PASSWORD, DEFAULT_PASSWORD );
// register the servlet and resources
try
@@ -670,7 +671,7 @@
configuration = config;
- defaultRenderName = ( String ) config.get( PROP_DEFAULT_RENDER );
+ defaultRenderName = getProperty( config, PROP_DEFAULT_RENDER, DEFAULT_PAGE );
if ( defaultRenderName != null && plugins.get( defaultRenderName ) != null )
{
defaultRender = ( Servlet ) plugins.get( defaultRenderName );
diff --git a/webconsole/src/main/resources/res/ui/bundles.js b/webconsole/src/main/resources/res/ui/bundles.js
index 537577f..07efab4 100644
--- a/webconsole/src/main/resources/res/ui/bundles.js
+++ b/webconsole/src/main/resources/res/ui/bundles.js
@@ -135,7 +135,7 @@
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( " " );
- document.write( "<input class='submit' style='width:auto' type='submit' value='Refresh Packages' onClick='this.form.action.value=\"refreshPackages\"; return true;'>" );
+ document.write( "<input class='submit' style='width:auto' type='button' value='Refresh Packages' onClick='changeBundle(0, \"refreshPackages\");'>" );
document.write( "</td>" );
document.write( "</tr>" );
document.write( "</form>" );
@@ -151,43 +151,47 @@
function bundleChanged(obj)
{
- var bundleId = obj.bundleId;
- if (obj.state)
+ if (obj.reload)
{
- // has status, so draw the line
- var span = document.getElementById('bundle' + bundleId);
- if (span)
- {
- span.innerHTML = bundleInternal( obj );
- }
-
- if (obj.props)
- {
- var span = document.getElementById('bundle' + bundleId + '_details');
- if (span && span.innerHTML)
- {
- span.innerHTML = bundleDetails( obj.props );
- }
- }
-
+ document.location = document.location;
}
else
{
- // no status, bundle has been uninstalled
- var span = document.getElementById('bundle' + bundleId);
- if (span)
+ var bundleId = obj.bundleId;
+ if (obj.state)
{
- span.parentNode.removeChild(span);
+ // has status, so draw the line
+ var span = document.getElementById('bundle' + bundleId);
+ if (span)
+ {
+ span.innerHTML = bundleInternal( obj );
+ }
+
+ if (obj.props)
+ {
+ var span = document.getElementById('bundle' + bundleId + '_details');
+ if (span && span.innerHTML)
+ {
+ span.innerHTML = bundleDetails( obj.props );
+ }
+ }
+
}
- var span = document.getElementById('bundle' + bundleId + '_details');
- if (span)
+ else
{
- span.parentNode.removeChild(span);
+ // no status, bundle has been uninstalled
+ var span = document.getElementById('bundle' + bundleId);
+ if (span)
+ {
+ span.parentNode.removeChild(span);
+ }
+ var span = document.getElementById('bundle' + bundleId + '_details');
+ if (span)
+ {
+ span.parentNode.removeChild(span);
+ }
}
- }
-
- // reload --- should do better and only update the bundle
- // document.location = document.location;
+ }
}