Author: fmeschbe
Date: Mon Mar 4 08:01:44 2013
New Revision: 1452202
URL: http://svn.apache.org/r1452202
Log:
FELIX-3946 Prevent NPE in BundlesServlet.bundleDetails
* BundleInfoProvider: Clarify webConsoleRoot may be null
* BundlesServlet: Guard pluginRoot against null (only get substring if not null)
* BundlesServlet: Fix rendition of "nfo" structure generated based
on BundleInforProvider data
* ServicesUsedInfoProvider: Generate BundleInfo of type VALUE if
webConsoleRoot is null
Modified:
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/bundleinfo/BundleInfoProvider.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/core/ServicesUsedInfoProvider.java
Modified:
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/bundleinfo/BundleInfoProvider.java
URL:
http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/bundleinfo/BundleInfoProvider.java?rev=1452202&r1=1452201&r2=1452202&view=diff
==============================================================================
---
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/bundleinfo/BundleInfoProvider.java
(original)
+++
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/bundleinfo/BundleInfoProvider.java
Mon Mar 4 08:01:44 2013
@@ -25,16 +25,16 @@ import org.osgi.framework.Bundle;
/**
* The bundle info provider allows the user to supply additional information
* that will be used by the Web Console bundle plugin.
- *
+ *
* The API allows the user to register a special service, that could bind a
* custom, implementation-specific information to a bundle.
- *
+ *
* A typical use-case for that API would be the Declarative Services, that
could
* provide information about the components provided by this bundle (and link
to
* the component plugin too). Another usage could be the ProSyst resource
* manager, that would provide information about the memory and CPU usage of
the
* bundle.
- *
+ *
* @author Valentin Valchev
*/
public interface BundleInfoProvider
@@ -49,7 +49,7 @@ public interface BundleInfoProvider
/**
* Gets the name of the bundle info provider as localized string.
- *
+ *
* @param locale
* the locale in which the name should be returned
* @return the name of the bundle info provider.
@@ -60,11 +60,18 @@ public interface BundleInfoProvider
/**
* Gets the associated bundle information with the specified bundle (by
it's
* ID)
- *
+ *
+ * The Service may also be called outside through the new Inventory bundle
+ * due to mapping the BundlesServlet to an InventoryPrinter and for example
+ * calling it from a Gogo Shell. In this case the {@code webConsoleRoot}
+ * parameter will be null a {@link BundleInfo} objects of type
+ * {@link BundleInfoType#LINK} must not be generated.
+ *
* @param bundle
* the bundle, for which additional information is requested.
* @param webConsoleRoot
- * the root alias of the web console itself.
+ * the root alias of the web console itself or {@code null}
+ * if this method is not called through the Web Console itself.
* @param locale
* the locale in which the key-value pair should be returned.
* @return array of available {@link BundleInfo} or empty array if none.
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=1452202&r1=1452201&r2=1452202&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
Mon Mar 4 08:01:44 2013
@@ -219,25 +219,50 @@ public class BundlesServlet extends Simp
if ( !props.isNull( pi ) )
{
JSONObject entry = props.getJSONObject( pi );
-
- pw.print( " " + entry.get( "key" ) + ": " );
-
- Object entryValue = entry.get( "value" );
- if ( entryValue instanceof JSONArray )
+ String key = ( String ) entry.get( "key" );
+ if ( "nfo".equals( key ) )
{
- pw.println();
- JSONArray entryArray = ( JSONArray )
entryValue;
- for ( int ei = 0; ei < entryArray.length();
ei++ )
+ // BundleInfo (see #bundleInfo &
#bundleInfoDetails
+ JSONObject infos = ( JSONObject ) entry.get(
"value" );
+ Iterator infoKeys = infos.keys();
+ while ( infoKeys.hasNext() )
{
- if ( !entryArray.isNull( ei ) )
+ String infoKey = ( String )
infoKeys.next();
+ pw.println( " " + infoKey + ": " );
+
+ JSONArray infoA = infos.getJSONArray(
infoKey );
+ for ( int iai = 0; iai < infoA.length();
iai++ )
{
- pw.println( " " +
entryArray.get( ei ) );
+ if ( !infoA.isNull( iai ) )
+ {
+ JSONObject info =
infoA.getJSONObject( iai );
+ pw.println( " " + info.get(
"name" ) );
+ }
}
}
}
else
{
- pw.println( entryValue );
+ // regular data
+ pw.print( " " + key + ": " );
+
+ Object entryValue = entry.get( "value" );
+ if ( entryValue instanceof JSONArray )
+ {
+ pw.println();
+ JSONArray entryArray = ( JSONArray )
entryValue;
+ for ( int ei = 0; ei <
entryArray.length(); ei++ )
+ {
+ if ( !entryArray.isNull( ei ) )
+ {
+ pw.println( " " +
entryArray.get( ei ) );
+ }
+ }
+ }
+ else
+ {
+ pw.println( entryValue );
+ }
}
}
}
@@ -803,7 +828,8 @@ public class BundlesServlet extends Simp
}
listHeaders( jw, bundle );
- bundleInfoDetails(jw, bundle, pluginRoot.substring(0,
pluginRoot.lastIndexOf("/")), locale);
+ final String appRoot = ( pluginRoot == null ) ? null :
pluginRoot.substring( 0, pluginRoot.lastIndexOf( "/" ) );
+ bundleInfoDetails( jw, bundle, appRoot, locale );
jw.endArray();
}
@@ -837,20 +863,22 @@ public class BundlesServlet extends Simp
jw.endObject();
}
+
private static final void bundleInfo( JSONWriter jw, BundleInfo info )
throws JSONException
{
- jw.object();
- jw.key("name");
- jw.value( info.getName() );
- jw.key("description");
- jw.value( info.getDescription() );
- jw.key("type");
- jw.value( info.getType().getName() );
- jw.key("value");
- jw.value( info.getValue() );
- jw.endObject();
+ jw.object();
+ jw.key( "name" );
+ jw.value( info.getName() );
+ jw.key( "description" );
+ jw.value( info.getDescription() );
+ jw.key( "type" );
+ jw.value( info.getType().getName() );
+ jw.key( "value" );
+ jw.value( info.getValue() );
+ jw.endObject();
}
+
private final Integer getStartLevel( Bundle bundle )
{
if ( bundle.getState() != Bundle.UNINSTALLED )
Modified:
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesUsedInfoProvider.java
URL:
http://svn.apache.org/viewvc/felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesUsedInfoProvider.java?rev=1452202&r1=1452201&r2=1452202&view=diff
==============================================================================
---
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesUsedInfoProvider.java
(original)
+++
felix/trunk/webconsole/src/main/java/org/apache/felix/webconsole/internal/core/ServicesUsedInfoProvider.java
Mon Mar 4 08:01:44 2013
@@ -18,6 +18,7 @@
*/
package org.apache.felix.webconsole.internal.core;
+
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Locale;
@@ -32,60 +33,67 @@ import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
-final class ServicesUsedInfoProvider implements
- BundleInfoProvider {
-
+
+final class ServicesUsedInfoProvider implements BundleInfoProvider
+{
+
private final LocalizationHelper localization;
-
- ServicesUsedInfoProvider(Bundle bundle)
+
+
+ ServicesUsedInfoProvider( Bundle bundle )
{
- localization = new LocalizationHelper(bundle);
+ localization = new LocalizationHelper( bundle );
}
+
/*
* (non-Javadoc)
- *
+ *
* @see
* org.apache.felix.webconsole.bundleinfo.BundleInfoProvider#getName(java
* .util.Locale)
*/
- public String getName(Locale locale)
+ public String getName( Locale locale )
{
- return
localization.getResourceBundle(locale).getString("services.info.name");
//$NON-NLS-1$;
+ return localization.getResourceBundle( locale ).getString(
"services.info.name" ); //$NON-NLS-1$;
}
- public BundleInfo[] getBundleInfo(Bundle bundle, String webConsoleRoot,
- Locale locale)
+
+ public BundleInfo[] getBundleInfo( Bundle bundle, String webConsoleRoot,
Locale locale )
{
- final ServiceReference[] refs = bundle.getServicesInUse();
- if (null == refs || refs.length == 0)
- return NO_INFO;
-
- BundleInfo[] ret = new BundleInfo[refs.length];
- for ( int i=0; i < refs.length; i++ )
- {
- ret[i] = toInfo(refs[i], webConsoleRoot, locale);
- }
- return ret;
+ final ServiceReference[] refs = bundle.getServicesInUse();
+ if ( null == refs || refs.length == 0 )
+ return NO_INFO;
+
+ BundleInfo[] ret = new BundleInfo[refs.length];
+ for ( int i = 0; i < refs.length; i++ )
+ {
+ ret[i] = toInfo( refs[i], webConsoleRoot, locale );
+ }
+ return ret;
}
- private BundleInfo toInfo(ServiceReference ref, String webConsoleRoot,
Locale locale)
+
+ private BundleInfo toInfo( ServiceReference ref, String webConsoleRoot,
Locale locale )
{
- final String[] classes = (String[]) ref
- .getProperty(Constants.OBJECTCLASS);
- final Object id = ref.getProperty(Constants.SERVICE_ID);
- final String descr =
localization.getResourceBundle(locale).getString("services.info.descr");
//$NON-NLS-1$;
- String name =
localization.getResourceBundle(locale).getString("services.info.key");
//$NON-NLS-1$;
- name = MessageFormat.format(name, new Object[] {
- id, Arrays.asList(classes).toString()
- });
- return new BundleInfo(name, webConsoleRoot + "/services/" + id,
//$NON-NLS-1$
- BundleInfoType.LINK, descr);
+ final String[] classes = ( String[] ) ref.getProperty(
Constants.OBJECTCLASS );
+ final Object id = ref.getProperty( Constants.SERVICE_ID );
+ final String descr = localization.getResourceBundle( locale
).getString( "services.info.descr" ); //$NON-NLS-1$;
+ String name = localization.getResourceBundle( locale ).getString(
"services.info.key" ); //$NON-NLS-1$;
+ name = MessageFormat.format( name, new Object[]
+ { id, Arrays.asList( classes ).toString() } );
+ if ( webConsoleRoot == null )
+ {
+ return new BundleInfo( name, id, BundleInfoType.VALUE, descr );
+ }
+ return new BundleInfo( name, webConsoleRoot + "/services/" + id,
//$NON-NLS-1$
+ BundleInfoType.LINK, descr );
}
-
+
+
ServiceRegistration register( BundleContext context )
{
- return context.registerService(BundleInfoProvider.class.getName(),
this, null);
+ return context.registerService( BundleInfoProvider.class.getName(),
this, null );
}
}