[345406]
Fixed bug - 345406 listBundles performance is really poor
A new method has been introduced that can serve in case of huge bundle numbers. Application developer can control via mask which data can be retrieved by the MBean
diff --git a/org.eclipse.gemini.mgmt/META-INF/MANIFEST.MF b/org.eclipse.gemini.mgmt/META-INF/MANIFEST.MF
index 4c5d35c..03fab44 100644
--- a/org.eclipse.gemini.mgmt/META-INF/MANIFEST.MF
+++ b/org.eclipse.gemini.mgmt/META-INF/MANIFEST.MF
@@ -6,15 +6,18 @@
Bundle-Vendor: Oracle
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: org.osgi.framework;version="1.3.0",
- org.osgi.util.tracker,
+ org.osgi.jmx,
+ org.osgi.jmx.framework,
+ org.osgi.jmx.service.cm,
+ org.osgi.jmx.service.permissionadmin,
+ org.osgi.jmx.service.provisioning,
+ org.osgi.jmx.service.useradmin,
org.osgi.service.cm,
org.osgi.service.packageadmin,
org.osgi.service.permissionadmin,
org.osgi.service.provisioning,
org.osgi.service.startlevel,
org.osgi.service.useradmin,
- org.osgi.jmx.framework,
- org.osgi.jmx.service.cm,
- org.osgi.jmx.service.permissionadmin,
- org.osgi.jmx.service.provisioning,
- org.osgi.jmx.service.useradmin
+ org.osgi.util.tracker
+Bundle-Activator: org.eclipse.gemini.mgmt.Activator
+Bundle-ActivationPolicy: lazy
diff --git a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/Activator.java b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/Activator.java
index d17048f..82f3de0 100644
--- a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/Activator.java
+++ b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/Activator.java
@@ -29,18 +29,18 @@
import javax.management.ObjectName;
import javax.management.StandardMBean;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
import org.eclipse.gemini.mgmt.cm.ConfigAdminManager;
import org.eclipse.gemini.mgmt.framework.BundleState;
+import org.eclipse.gemini.mgmt.framework.CustomBundleStateMBean;
import org.eclipse.gemini.mgmt.framework.Framework;
import org.eclipse.gemini.mgmt.framework.PackageState;
import org.eclipse.gemini.mgmt.framework.ServiceState;
import org.eclipse.gemini.mgmt.permissionadmin.PermissionManager;
import org.eclipse.gemini.mgmt.provisioning.Provisioning;
import org.eclipse.gemini.mgmt.useradmin.UserManager;
-import org.osgi.jmx.framework.BundleStateMBean;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
import org.osgi.jmx.framework.FrameworkMBean;
import org.osgi.jmx.framework.PackageStateMBean;
import org.osgi.jmx.framework.ServiceStateMBean;
@@ -99,7 +99,7 @@
public void start(BundleContext bundleContext) throws Exception {
this.bundleContext = bundleContext;
frameworkName = new ObjectName(FrameworkMBean.OBJECTNAME);
- bundlesStateName = new ObjectName(BundleStateMBean.OBJECTNAME);
+ bundlesStateName = new ObjectName(CustomBundleStateMBean.OBJECTNAME);
serviceStateName = new ObjectName(ServiceStateMBean.OBJECTNAME);
packageStateName = new ObjectName(PackageStateMBean.OBJECTNAME);
configAdminName = new ObjectName(ConfigurationAdminMBean.OBJECTNAME);
@@ -256,7 +256,7 @@
}
try {
bundleState = new StandardMBean(new BundleState(bundleContext, sl,
- admin), BundleStateMBean.class);
+ admin), CustomBundleStateMBean.class);
} catch (NotCompliantMBeanException e) {
log.log(Level.SEVERE,
"Unable to create StandardMBean for BundleState", e);
diff --git a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/BundleState.java b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/BundleState.java
index a5ecfdd..19d01cd 100644
--- a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/BundleState.java
+++ b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/BundleState.java
@@ -39,7 +39,7 @@
/**
*
*/
-public class BundleState extends Monitor implements BundleStateMBean {
+public class BundleState extends Monitor implements CustomBundleStateMBean {
public BundleState(BundleContext bc, StartLevel sl, PackageAdmin admin) {
this.bc = bc;
this.sl = sl;
@@ -52,12 +52,22 @@
* @see org.osgi.jmx.core.BundleStateMBean#getBundles()
*/
public TabularData listBundles() throws IOException {
+ return listBundles(CustomBundleStateMBean.DEFAULT);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.gemini.mgmt.framework.CustomBundleStateMBean#listBundles(int)
+ */
+ public TabularData listBundles(int mask) throws IOException {
+ if (mask < 1 || mask > 1048575) {
+ throw new IllegalArgumentException("Mask out of range!");
+ }
try {
ArrayList<OSGiBundle> bundles = new ArrayList<OSGiBundle>();
for (Bundle bundle : bc.getBundles()) {
bundles.add(new OSGiBundle(bc, admin, sl, bundle));
}
- TabularData table = OSGiBundle.tableFrom(bundles);
+ TabularData table = OSGiBundle.tableFrom(bundles, mask);
return table;
} catch (Throwable e) {
e.printStackTrace();
diff --git a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/CustomBundleStateMBean.java b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/CustomBundleStateMBean.java
new file mode 100644
index 0000000..1498770
--- /dev/null
+++ b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/CustomBundleStateMBean.java
@@ -0,0 +1,152 @@
+package org.eclipse.gemini.mgmt.framework;
+
+import java.io.IOException;
+
+import javax.management.openmbean.TabularData;
+
+import org.osgi.jmx.framework.BundleStateMBean;
+
+public interface CustomBundleStateMBean extends BundleStateMBean{
+
+ /**
+ * Mask for listBundles method, that requires bundle location attribute to be
+ * included in the returned data.
+ *
+ */
+ public final static int LOCATION = 1;
+
+ /**
+ * Mask for listBundles method, that requires bundle id attribute to be
+ * included in the returned data.
+ */
+ public final static int IDENTIFIER = 2;
+
+ /**
+ * Mask for listBundles method, that requires bundle symbolic name attribute to be
+ * included in the returned data.
+ */
+ public final static int SYMBOLIC_NAME = 2 << 1;
+
+ /**
+ * Mask for listBundles method, that requires bundle version attribute to be
+ * included in the returned data.
+ */
+ public final static int VERSION = 2 << 2;
+
+ /**
+ * Mask for listBundles method, that requires bundle start level attribute to be
+ * included in the returned data.
+ */
+ public final static int START_LEVEL = 2 << 3;
+
+ /**
+ * Mask for listBundles method, that requires bundle state attribute to be
+ * included in the returned data.
+ */
+ public final static int STATE = 2 << 4;
+
+ /**
+ * Mask for listBundles method, that requires bundle last modified attribute to be
+ * included in the returned data.
+ */
+ public final static int LAST_MODIFIED = 2 << 5;
+
+ /**
+ * Mask for listBundles method, that requires bundle persistently started attribute to be
+ * included in the returned data.
+ */
+ public final static int PERSISTENTLY_STARTED = 2 << 6;
+
+ /**
+ * Mask for listBundles method, that requires bundle removal pending attribute to be
+ * included in the returned data.
+ */
+ public final static int REMOVAL_PENDING = 2 << 7;
+
+ /**
+ * Mask for listBundles method, that requires bundle required attribute to be
+ * included in the returned data.
+ */
+ public final static int REQUIRED = 2 << 8;
+
+ /**
+ * Mask for listBundles method, that requires bundle fragment attribute to be
+ * included in the returned data.
+ */
+ public final static int FRAGMENT = 2 << 9;
+
+ /**
+ * Mask for listBundles method, that requires bundle registered services attribute to be
+ * included in the returned data.
+ */
+ public final static int REGISTERED_SERVICES = 2 << 10;
+
+ /**
+ * Mask for listBundles method, that requires bundle services in use attribute to be
+ * included in the returned data.
+ */
+ public final static int SERVICES_IN_USE = 2 << 11;
+
+ /**
+ * Mask for listBundles method, that requires bundle headers attribute to be
+ * included in the returned data.
+ */
+ public final static int HEADERS = 2 << 12;
+
+ /**
+ * Mask for listBundles method, that requires bundle exported packages attribute to be
+ * included in the returned data.
+ */
+ public final static int EXPORTED_PACKAGES = 2 << 13;
+
+ /**
+ * Mask for listBundles method, that requires bundle imported packages attribute to be
+ * included in the returned data.
+ */
+ public final static int IMPORTED_PACKAGES = 2 << 14;
+
+ /**
+ * Mask for listBundles method, that requires bundle fragments attribute to be
+ * included in the returned data.
+ */
+ public final static int FRAGMENTS = 2 << 15;
+
+ /**
+ * Mask for listBundles method, that requires bundle hosts attribute to be
+ * included in the returned data.
+ */
+ public final static int HOSTS = 2 << 16;
+
+ /**
+ * Mask for listBundles method, that requires bundle "requiring bundles" attribute to be
+ * included in the returned data.
+ */
+ public final static int REQUIRING_BUNDLES = 2 << 17;
+
+ /**
+ * Mask for listBundles method, that requires bundle "required bundles" attribute to be
+ * included in the returned data.
+ */
+ public final static int REQUIRED_BUNDLES = 2 << 18;
+
+ /**
+ * Mask for listBundles method, that returns all available data. Equivalent to listBundles()
+ */
+ public final static int DEFAULT = LOCATION + IDENTIFIER
+ + SYMBOLIC_NAME + VERSION + START_LEVEL + STATE + LAST_MODIFIED
+ + PERSISTENTLY_STARTED + REMOVAL_PENDING + REQUIRED + FRAGMENT + REGISTERED_SERVICES
+ + SERVICES_IN_USE + HEADERS + EXPORTED_PACKAGES + IMPORTED_PACKAGES + FRAGMENTS
+ + HOSTS + REQUIRING_BUNDLES + REQUIRED_BUNDLES;
+
+ /**
+ * Answer the bundle state of the system in tabular form depending on the mask.
+ *
+ * Each row of the returned table represents a single bundle. The Tabular
+ * Data consists of Composite Data that is type by {@link #BUNDLES_TYPE}.
+ *
+ * @param mask - representing the information that will be contained in the result
+ * @return the tabular representation of the bundle state
+ * @throws IOException
+ */
+ TabularData listBundles(int mask) throws IOException;
+}
diff --git a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/codec/OSGiBundle.java b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/codec/OSGiBundle.java
index f4653fc..73de7ea 100644
--- a/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/codec/OSGiBundle.java
+++ b/org.eclipse.gemini.mgmt/src/org/eclipse/gemini/mgmt/framework/codec/OSGiBundle.java
@@ -40,6 +40,7 @@
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
@@ -47,11 +48,14 @@
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
+import org.osgi.jmx.Item;
import org.osgi.jmx.framework.BundleStateMBean;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.startlevel.StartLevel;
import org.eclipse.gemini.mgmt.codec.Util;
+import org.eclipse.gemini.mgmt.framework.CustomBundleStateMBean;
+
/**
* <p>
@@ -142,13 +146,17 @@
* </table>
*/
public class OSGiBundle {
-
+
private static final String VALUE = "Value";
private static final String KEY = "Key";
private static final String[] HEADER_PROPERTY_ITEM_NAMES = new String[] {
KEY, VALUE };
+ private BundleContext bc;
+ private PackageAdmin admin;
+ private StartLevel sl;
+ private Bundle b;
/**
* Construct an OSGiBundle from the encoded CompositeData
@@ -199,18 +207,11 @@
*/
public OSGiBundle(BundleContext bc, PackageAdmin admin, StartLevel sl,
Bundle b) {
- this(b.getLocation(), b.getBundleId(), b.getSymbolicName(), b
- .getVersion().toString(), sl.getBundleStartLevel(b),
- getBundleState(b), b.getLastModified(),
- isBundlePersistentlyStarted(b, sl),
- isRequiredBundleRemovalPending(b, bc, admin), isBundleRequired(
- b, bc, admin), isBundleFragment(b, admin), serviceIds(b
- .getRegisteredServices()), serviceIds(b
- .getServicesInUse()), getBundleHeaders(b),
- getBundleExportedPackages(b, admin), getBundleImportedPackages(
- b, bc, admin), getBundleFragments(b, admin), Util
- .bundleIds(admin.getHosts(b)), getDependencies(b,
- admin), getBundlesRequiring(b, bc, admin));
+ this.bc = bc;
+ this.admin = admin;
+ this.sl = sl;
+ this.b = b;
+
}
/**
@@ -272,17 +273,87 @@
*
* @param bundles
* - the list of bundles to represent
+ * @param mask
*
* @return the Tabular data which represents the list of bundles
*/
- public static TabularData tableFrom(ArrayList<OSGiBundle> bundles) {
+ public static TabularData tableFrom(ArrayList<OSGiBundle> bundles, int mask) {
TabularDataSupport table = new TabularDataSupport(
- BundleStateMBean.BUNDLES_TYPE);
+ Item.tabularType("BUNDLES", "A list of bundles",
+ OSGiBundle.computeBundleType(mask), new String[] { BundleStateMBean.IDENTIFIER }));
for (OSGiBundle bundle : bundles) {
- table.put(bundle.asCompositeData());
+ table.put(bundle.asCompositeData(mask));
}
return table;
}
+
+ private static CompositeType computeBundleType(int mask) {
+ List<Item> bundleTypes = new ArrayList<Item>();
+ if((mask | CustomBundleStateMBean.LOCATION) == mask) {
+ bundleTypes.add(BundleStateMBean.LOCATION_ITEM);
+ }
+// if((mask | IDENTIFIER) == mask) {
+ bundleTypes.add(BundleStateMBean.IDENTIFIER_ITEM);
+// }
+ if((mask | CustomBundleStateMBean.SYMBOLIC_NAME) == mask) {
+ bundleTypes.add(BundleStateMBean.SYMBOLIC_NAME_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.VERSION) == mask) {
+ bundleTypes.add(BundleStateMBean.VERSION_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.START_LEVEL) == mask) {
+ bundleTypes.add(BundleStateMBean.START_LEVEL_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.STATE) == mask) {
+ bundleTypes.add(BundleStateMBean.STATE_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.LAST_MODIFIED) == mask) {
+ bundleTypes.add(BundleStateMBean.LAST_MODIFIED_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.PERSISTENTLY_STARTED) == mask) {
+ bundleTypes.add(BundleStateMBean.PERSISTENTLY_STARTED_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.REMOVAL_PENDING) == mask) {
+ bundleTypes.add(BundleStateMBean.REMOVAL_PENDING_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.REQUIRED) == mask) {
+ bundleTypes.add(BundleStateMBean.REQUIRED_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.FRAGMENT) == mask) {
+ bundleTypes.add(BundleStateMBean.FRAGMENT_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.REGISTERED_SERVICES) == mask) {
+ bundleTypes.add(BundleStateMBean.REGISTERED_SERVICES_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.SERVICES_IN_USE) == mask) {
+ bundleTypes.add(BundleStateMBean.SERVICES_IN_USE_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.HEADERS) == mask) {
+ bundleTypes.add(BundleStateMBean.HEADERS_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.EXPORTED_PACKAGES) == mask) {
+ bundleTypes.add(BundleStateMBean.EXPORTED_PACKAGES_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.IMPORTED_PACKAGES) == mask) {
+ bundleTypes.add(BundleStateMBean.IMPORTED_PACKAGES_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.FRAGMENTS) == mask) {
+ bundleTypes.add(BundleStateMBean.FRAGMENTS_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.HOSTS) == mask) {
+ bundleTypes.add(BundleStateMBean.HOSTS_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.REQUIRING_BUNDLES) == mask) {
+ bundleTypes.add(BundleStateMBean.REQUIRING_BUNDLES_ITEM);
+ }
+ if((mask | CustomBundleStateMBean.REQUIRED_BUNDLES) == mask) {
+ bundleTypes.add(BundleStateMBean.REQUIRED_BUNDLES_ITEM);
+ }
+
+ CompositeType currentCompositeType = Item.compositeType("BUNDLE",
+ "This type encapsulates OSGi bundles",bundleTypes.toArray(new Item[]{}));
+ return currentCompositeType;
+ }
/**
* Answer the TabularData representing the list of bundle headers for a
@@ -334,39 +405,80 @@
/**
* Answer the receiver encoded as CompositeData
+ * @param mask
*
* @return the CompositeData encoding of the receiver.
*/
@SuppressWarnings("boxing")
- public CompositeData asCompositeData() {
+ public CompositeData asCompositeData(int mask) {
Map<String, Object> items = new HashMap<String, Object>();
- items.put(BundleStateMBean.LOCATION, location);
- items.put(BundleStateMBean.IDENTIFIER, identifier);
- items.put(BundleStateMBean.SYMBOLIC_NAME, symbolicName);
- items.put(BundleStateMBean.VERSION, version);
- items.put(BundleStateMBean.START_LEVEL, startLevel);
- items.put(BundleStateMBean.STATE, state);
- items.put(BundleStateMBean.LAST_MODIFIED, lastModified);
- items.put(BundleStateMBean.PERSISTENTLY_STARTED, persistentlyStarted);
- items.put(BundleStateMBean.REMOVAL_PENDING, removalPending);
- items.put(BundleStateMBean.REQUIRED, required);
- items.put(BundleStateMBean.FRAGMENT, fragment);
+ if((mask | CustomBundleStateMBean.LOCATION) == mask) {
+ items.put(BundleStateMBean.LOCATION, getLocation());
+ }
+// if((mask | IDENTIFIER) == mask) {
+ items.put(BundleStateMBean.IDENTIFIER, getIdentifier());
+// }
+ if((mask | CustomBundleStateMBean.SYMBOLIC_NAME) == mask) {
+ items.put(BundleStateMBean.SYMBOLIC_NAME, getSymbolicName());
+ }
+ if((mask | CustomBundleStateMBean.VERSION) == mask) {
+ items.put(BundleStateMBean.VERSION, getVersion());
+ }
+ if((mask | CustomBundleStateMBean.START_LEVEL) == mask) {
+ items.put(BundleStateMBean.START_LEVEL, getStartLevel());
+ }
+ if((mask | CustomBundleStateMBean.STATE) == mask) {
+ items.put(BundleStateMBean.STATE, getState());
+ }
+ if((mask | CustomBundleStateMBean.LAST_MODIFIED) == mask) {
+ items.put(BundleStateMBean.LAST_MODIFIED, getLastModified());
+ }
+ if((mask | CustomBundleStateMBean.PERSISTENTLY_STARTED) == mask) {
+ items.put(BundleStateMBean.PERSISTENTLY_STARTED, isPersistentlyStarted());
+ }
+ if((mask | CustomBundleStateMBean.REMOVAL_PENDING) == mask) {
+ items.put(BundleStateMBean.REMOVAL_PENDING, isRemovalPending());
+ }
+ if((mask | CustomBundleStateMBean.REQUIRED) == mask) {
+ items.put(BundleStateMBean.REQUIRED, isRequired());
+ }
+ if((mask | CustomBundleStateMBean.FRAGMENT) == mask) {
+ items.put(BundleStateMBean.FRAGMENT, isFragment());
+ }
+ if((mask | CustomBundleStateMBean.REGISTERED_SERVICES) == mask) {
items.put(BundleStateMBean.REGISTERED_SERVICES,
- LongArrayFrom(registeredServices));
+ LongArrayFrom(getRegisteredServices()));
+ }
+ if((mask | CustomBundleStateMBean.SERVICES_IN_USE) == mask) {
items.put(BundleStateMBean.SERVICES_IN_USE,
- LongArrayFrom(servicesInUse));
- items.put(BundleStateMBean.HEADERS, headerTable(headers));
- items.put(BundleStateMBean.EXPORTED_PACKAGES, exportedPackages);
- items.put(BundleStateMBean.IMPORTED_PACKAGES, importedPackages);
- items.put(BundleStateMBean.FRAGMENTS, LongArrayFrom(fragments));
- items.put(BundleStateMBean.HOSTS, LongArrayFrom(hosts));
+ LongArrayFrom(getServicesInUse()));
+ }
+ if((mask | CustomBundleStateMBean.HEADERS) == mask) {
+ items.put(BundleStateMBean.HEADERS, headerTable(getHeaders()));
+ }
+ if((mask | CustomBundleStateMBean.EXPORTED_PACKAGES) == mask) {
+ items.put(BundleStateMBean.EXPORTED_PACKAGES, getExportedPackages());
+ }
+ if((mask | CustomBundleStateMBean.IMPORTED_PACKAGES) == mask) {
+ items.put(BundleStateMBean.IMPORTED_PACKAGES, getImportedPackages());
+ }
+ if((mask | CustomBundleStateMBean.FRAGMENTS) == mask) {
+ items.put(BundleStateMBean.FRAGMENTS, LongArrayFrom(getFragments()));
+ }
+ if((mask | CustomBundleStateMBean.HOSTS) == mask) {
+ items.put(BundleStateMBean.HOSTS, LongArrayFrom(getHosts()));
+ }
+ if((mask | CustomBundleStateMBean.REQUIRING_BUNDLES) == mask) {
items.put(BundleStateMBean.REQUIRING_BUNDLES,
- LongArrayFrom(requiringBundles));
+ LongArrayFrom(getRequiringBundles()));
+ }
+ if((mask | CustomBundleStateMBean.REQUIRED_BUNDLES) == mask) {
items.put(BundleStateMBean.REQUIRED_BUNDLES,
- LongArrayFrom(requiredBundles));
+ LongArrayFrom(getRequiredBundles()));
+ }
try {
- return new CompositeDataSupport(BundleStateMBean.BUNDLE_TYPE, items);
+ return new CompositeDataSupport(OSGiBundle.computeBundleType(mask), items);
} catch (OpenDataException e) {
throw new IllegalStateException("Cannot form bundle open data", e);
}
@@ -378,6 +490,9 @@
*
*/
public String[] getExportedPackages() {
+ if (exportedPackages == null) {
+ exportedPackages = getBundleExportedPackages(b, admin);
+ }
return exportedPackages;
}
@@ -386,6 +501,9 @@
* bundle as a host
*/
public long[] getFragments() {
+ if (fragments == null) {
+ fragments = getBundleFragments(b, admin);
+ }
return fragments;
}
@@ -393,6 +511,9 @@
* @return the map of headers for this bundle
*/
public Map<String, String> getHeaders() {
+ if (headers == null) {
+ headers = getBundleHeaders(b);
+ }
return headers;
}
@@ -400,6 +521,9 @@
* @return list of identifiers of the bundles which host this fragment
*/
public long[] getHosts() {
+ if (hosts == null) {
+ hosts = Util.bundleIds(admin.getHosts(b));
+ }
return hosts;
}
@@ -407,6 +531,9 @@
* @return the identifier of this bundle
*/
public long getIdentifier() {
+ if (identifier == 0) {
+ identifier = b.getBundleId();
+ }
return identifier;
}
@@ -415,6 +542,9 @@
* <packageName>;<version>
*/
public String[] getImportedPackages() {
+ if (importedPackages == null) {
+ importedPackages = getBundleImportedPackages(b, bc, admin);
+ }
return importedPackages;
}
@@ -422,6 +552,9 @@
* @return the last modified time of this bundle
*/
public long getLastModified() {
+ if (lastModified == 0) {
+ lastModified = b.getLastModified();
+ }
return lastModified;
}
@@ -429,6 +562,9 @@
* @return the name of this bundle
*/
public String getLocation() {
+ if (location == null) {
+ location = b.getLocation();
+ }
return location;
}
@@ -436,6 +572,9 @@
* @return the list of identifiers of the services registered by this bundle
*/
public long[] getRegisteredServices() {
+ if (registeredServices == null) {
+ registeredServices = serviceIds(b.getRegisteredServices());
+ }
return registeredServices;
}
@@ -443,6 +582,9 @@
* @return the list of identifiers of bundles required by this bundle
*/
public long[] getRequiredBundles() {
+ if (requiredBundles == null) {
+ requiredBundles = getDependencies(b,admin);
+ }
return requiredBundles;
}
@@ -450,6 +592,9 @@
* @return the list of identifiers of bundles which require this bundle
*/
public long[] getRequiringBundles() {
+ if (requiringBundles == null) {
+ requiringBundles = getBundlesRequiring(b, bc, admin);
+ }
return requiringBundles;
}
@@ -457,6 +602,9 @@
* @return the list of identifiers of services in use by this bundle
*/
public long[] getServicesInUse() {
+ if (servicesInUse == null) {
+ servicesInUse = serviceIds(b.getServicesInUse());
+ }
return servicesInUse;
}
@@ -464,6 +612,9 @@
* @return the start level of this bundle
*/
public int getStartLevel() {
+ if (startLevel == 0) {
+ startLevel = sl.getBundleStartLevel(b);
+ }
return startLevel;
}
@@ -471,6 +622,9 @@
* @return the state of this bundle
*/
public String getState() {
+ if (state == null) {
+ state = getBundleState(b);
+ }
return state;
}
@@ -478,6 +632,9 @@
* @return the symbolic name of this bundle
*/
public String getSymbolicName() {
+ if (symbolicName == null) {
+ symbolicName = b.getSymbolicName();
+ }
return symbolicName;
}
@@ -485,6 +642,9 @@
* @return the version of this bundle
*/
public String getVersion() {
+ if (version == null) {
+ version = b.getVersion().toString();
+ }
return version;
}
@@ -492,6 +652,9 @@
* @return true if this bundle represents a fragment
*/
public boolean isFragment() {
+ if (fragment == null) {
+ fragment = isBundleFragment(b, admin);
+ }
return fragment;
}
@@ -499,6 +662,9 @@
* @return true if this bundle is persistently started
*/
public boolean isPersistentlyStarted() {
+ if (persistentlyStarted == null) {
+ persistentlyStarted = isBundlePersistentlyStarted(b, sl);
+ }
return persistentlyStarted;
}
@@ -506,6 +672,9 @@
* @return true if this bundle is pending removal
*/
public boolean isRemovalPending() {
+ if (removalPending == null) {
+ isRequiredBundleRemovalPending(b, bc, admin);
+ }
return removalPending;
}
@@ -513,6 +682,9 @@
* @return true if this bundle is required
*/
public boolean isRequired() {
+ if (required == null) {
+ required = isBundleRequired(b, bc, admin);
+ }
return required;
}
@@ -529,7 +701,7 @@
}
private String[] exportedPackages;
- private boolean fragment;
+ private Boolean fragment;
private long[] fragments;
private Map<String, String> headers;
private long[] hosts;
@@ -537,10 +709,10 @@
private String[] importedPackages;
private long lastModified;
private String location;
- private boolean persistentlyStarted;
+ private Boolean persistentlyStarted;
private long[] registeredServices;
- private boolean removalPending;
- private boolean required;
+ private Boolean removalPending;
+ private Boolean required;
private long[] requiredBundles;
private long[] requiringBundles;
private long[] servicesInUse;