FELIX-3139 Implemented first version of uninstall. Does not follow the spec yet to the letter, but functionally does the right thing.
FELIX-1829 Fixed the NPE.
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1177325 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/AbstractDeploymentPackage.java b/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/AbstractDeploymentPackage.java
index f0288c3..4a9cd33 100644
--- a/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/AbstractDeploymentPackage.java
+++ b/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/AbstractDeploymentPackage.java
@@ -41,7 +41,11 @@
* deployment package data is obtained, this should be handled by extending classes.
*/
public abstract class AbstractDeploymentPackage implements DeploymentPackage {
+ private static final String[] STRINGS = new String[] {};
+ private static final ResourceInfoImpl[] RESOURCE_INFO_IMPLS = new ResourceInfoImpl[] {};
+ private static final BundleInfoImpl[] BUNDLE_INFO_IMPLS = new BundleInfoImpl[] {};
private final BundleContext m_bundleContext;
+ private final DeploymentAdminImpl m_deploymentAdmin;
private final DeploymentPackageManifest m_manifest;
private final Map m_nameToBundleInfo = new HashMap();
private final Map m_pathToEntry = new HashMap();
@@ -49,26 +53,28 @@
private final ResourceInfoImpl[] m_resourceInfos;
private final String[] m_resourcePaths;
private final boolean m_isFixPackage;
- protected static final AbstractDeploymentPackage emptyPackage = new AbstractDeploymentPackage() {
+ private boolean m_isStale;
+ protected static final AbstractDeploymentPackage EMPTY_PACKAGE = new AbstractDeploymentPackage() {
public String getHeader(String header) {
if (Constants.DEPLOYMENTPACKAGE_SYMBOLICMAME.equals(header)) { return ""; }
else if (Constants.DEPLOYMENTPACKAGE_VERSION.equals(header)) { return Version.emptyVersion.toString(); }
else { return null; }
}
public Bundle getBundle(String symbolicName) { return null; }
- public BundleInfo[] getBundleInfos() { return new BundleInfoImpl[] {}; }
- public BundleInfoImpl[] getBundleInfoImpls() { return new BundleInfoImpl[] {}; }
+ public BundleInfo[] getBundleInfos() { return BUNDLE_INFO_IMPLS; }
+ public BundleInfoImpl[] getBundleInfoImpls() { return BUNDLE_INFO_IMPLS; }
+ public ResourceInfoImpl[] getResourceInfos() { return RESOURCE_INFO_IMPLS; }
public String getName() { return ""; }
public String getResourceHeader(String resource, String header) { return null; }
public ServiceReference getResourceProcessor(String resource) { return null; }
- public String[] getResources() { return new String[] {}; }
+ public String[] getResources() { return STRINGS; }
public Version getVersion() { return Version.emptyVersion; }
public boolean isStale() { return true; }
public void uninstall() throws DeploymentException { throw new IllegalStateException("Can not uninstall stale DeploymentPackage"); }
public boolean uninstallForced() throws DeploymentException { throw new IllegalStateException("Can not uninstall stale DeploymentPackage"); }
public InputStream getBundleStream(String symbolicName) throws IOException { return null; }
- public BundleInfoImpl[] getOrderedBundleInfos() { return new BundleInfoImpl[] {}; }
- public ResourceInfoImpl[] getOrderedResourceInfos() { return new ResourceInfoImpl[] {}; }
+ public BundleInfoImpl[] getOrderedBundleInfos() { return BUNDLE_INFO_IMPLS; }
+ public ResourceInfoImpl[] getOrderedResourceInfos() { return RESOURCE_INFO_IMPLS; }
public InputStream getCurrentEntryStream() { throw new UnsupportedOperationException(); }
public AbstractInfo getNextEntry() throws IOException { throw new UnsupportedOperationException(); }
public String getDisplayName() { return ""; }
@@ -83,6 +89,7 @@
m_resourceInfos = null;
m_resourcePaths = null;
m_isFixPackage = false;
+ m_deploymentAdmin = null;
}
/**
@@ -92,10 +99,11 @@
* @param bundleContext The bundle context.
* @throws DeploymentException Thrown if the specified manifest does not describe a valid deployment package.
*/
- public AbstractDeploymentPackage(Manifest manifest, BundleContext bundleContext) throws DeploymentException {
+ public AbstractDeploymentPackage(Manifest manifest, BundleContext bundleContext, DeploymentAdminImpl deploymentAdmin) throws DeploymentException {
m_manifest = new DeploymentPackageManifest(manifest);
m_isFixPackage = m_manifest.getFixPackage() != null;
m_bundleContext = bundleContext;
+ m_deploymentAdmin = deploymentAdmin;
m_bundleInfos = (BundleInfoImpl[]) m_manifest.getBundleInfos().toArray(new BundleInfoImpl[0]);
for(int i = 0; i < m_bundleInfos.length; i++) {
m_nameToBundleInfo.put(m_bundleInfos[i].getSymbolicName(), m_bundleInfos[i]);
@@ -115,7 +123,7 @@
if (m_nameToBundleInfo.containsKey(symbolicName)) {
Bundle[] bundles = m_bundleContext.getBundles();
for (int i = 0; i < bundles.length; i++) {
- if (bundles[i].getSymbolicName().equals(symbolicName)) {
+ if (symbolicName.equals(bundles[i].getSymbolicName())) {
return bundles[i];
}
}
@@ -236,15 +244,23 @@
}
public boolean isStale() {
- return false;
+ return m_isStale;
+ }
+
+ public void setStale(boolean isStale) {
+ m_isStale = isStale;
}
public void uninstall() throws DeploymentException {
- throw new IllegalStateException("Not implemented");
+ if (isStale()) {
+ throw new IllegalStateException("Deployment package is stale, cannot uninstall.");
+ }
+ m_deploymentAdmin.uninstallDeploymentPackage(this);
+ setStale(true);
}
public boolean uninstallForced() throws DeploymentException {
- throw new IllegalStateException("Not implemented");
+ throw new IllegalStateException("Not implemented, use uninstall() for now.");
}
/**
diff --git a/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/DeploymentAdminImpl.java b/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/DeploymentAdminImpl.java
index 2c30654..b099016 100644
--- a/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/DeploymentAdminImpl.java
+++ b/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/DeploymentAdminImpl.java
@@ -104,7 +104,7 @@
try {
File index = new File(packages[i], PACKAGEINDEX_FILE);
File contents = new File(packages[i], PACKAGECONTENTS_DIR);
- FileDeploymentPackage dp = new FileDeploymentPackage(index, contents, m_context);
+ FileDeploymentPackage dp = new FileDeploymentPackage(index, contents, m_context, this);
m_packages.put(dp.getName(), dp);
}
catch (IOException e) {
@@ -155,7 +155,7 @@
}
try {
if (!m_semaphore.tryAcquire(TIMEOUT)) {
- throw new DeploymentException(DeploymentException.CODE_TIMEOUT, "Timeout exceeded while waiting to install deployment package (" + TIMEOUT + "msec)");
+ throw new DeploymentException(DeploymentException.CODE_TIMEOUT, "Timeout exceeded while waiting to install deployment package (" + TIMEOUT + " ms)");
}
}
catch (InterruptedException ie) {
@@ -191,13 +191,13 @@
m_log.log(LogService.LOG_ERROR, "Stream does not contain a valid Jar", e);
throw new DeploymentException(DeploymentException.CODE_NOT_A_JAR, "Stream does not contain a valid Jar", e);
}
- source = new StreamDeploymentPackage(jarInput, m_context);
+ source = new StreamDeploymentPackage(jarInput, m_context, this);
sendStartedEvent(source.getName());
AbstractDeploymentPackage target = (AbstractDeploymentPackage) getDeploymentPackage(source.getName());
boolean newPackage = (target == null);
if (newPackage) {
- target = AbstractDeploymentPackage.emptyPackage;
+ target = AbstractDeploymentPackage.EMPTY_PACKAGE;
}
if (source.isFixPackage() && ((newPackage) || (!source.getVersionRange().isInRange(target.getVersion())))) {
succeeded = false;
@@ -238,7 +238,7 @@
}
FileDeploymentPackage fileDeploymentPackage = null;
try {
- fileDeploymentPackage = new FileDeploymentPackage(targetIndex, targetContents, m_context);
+ fileDeploymentPackage = new FileDeploymentPackage(targetIndex, targetContents, m_context, this);
m_packages.put(source.getName(), fileDeploymentPackage);
}
catch (IOException e) {
@@ -259,6 +259,41 @@
m_semaphore.release();
}
}
+
+ public void uninstallDeploymentPackage(DeploymentPackage dp) throws DeploymentException {
+ try {
+ if (!m_semaphore.tryAcquire(TIMEOUT)) {
+ throw new DeploymentException(DeploymentException.CODE_TIMEOUT, "Timeout exceeded while waiting to uninstall deployment package (" + TIMEOUT + " ms)");
+ }
+ }
+ catch (InterruptedException ie) {
+ throw new DeploymentException(DeploymentException.CODE_TIMEOUT, "Thread interrupted");
+ }
+ boolean succeeded = false;
+ AbstractDeploymentPackage source = AbstractDeploymentPackage.EMPTY_PACKAGE;
+ AbstractDeploymentPackage target = (AbstractDeploymentPackage) dp;
+ try {
+ try {
+ m_session = new DeploymentSessionImpl(source, target, m_commandChain, this);
+ m_session.call();
+ }
+ catch (DeploymentException de) {
+ succeeded = false;
+ throw de;
+ }
+
+ File targetPackage = m_context.getDataFile(PACKAGE_DIR + File.separator + source.getName());
+ delete(targetPackage);
+ m_packages.remove(dp.getName());
+ succeeded = true;
+ }
+ finally {
+ if (source != null) {
+ sendCompleteEvent(source.getName(), succeeded);
+ }
+ m_semaphore.release();
+ }
+ }
private void delete(File target) {
if (target.isDirectory()) {
diff --git a/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/FileDeploymentPackage.java b/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/FileDeploymentPackage.java
index 8e37b54..a369d04 100644
--- a/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/FileDeploymentPackage.java
+++ b/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/FileDeploymentPackage.java
@@ -34,8 +34,7 @@
/**
* Implementation of a <code>DeploymentPackage</code> that is persisted on disk.
*/
-class FileDeploymentPackage extends AbstractDeploymentPackage {
-
+public class FileDeploymentPackage extends AbstractDeploymentPackage {
private final List m_index;
private final File m_contentsDir;
@@ -48,12 +47,12 @@
* @throws DeploymentException Thrown if the disk contents do not resemble a valid deployment package.
* @throws IOException Thrown if there was a problem reading the resources from disk.
*/
- public FileDeploymentPackage(File index, File packageDir, BundleContext bundleContext) throws DeploymentException, IOException {
- this(ExplodingOutputtingInputStream.readIndex(index), packageDir, bundleContext);
+ public FileDeploymentPackage(File index, File packageDir, BundleContext bundleContext, DeploymentAdminImpl deploymentAdmin) throws DeploymentException, IOException {
+ this(ExplodingOutputtingInputStream.readIndex(index), packageDir, bundleContext, deploymentAdmin);
}
- private FileDeploymentPackage(List index, File packageDir, BundleContext bundleContext) throws DeploymentException, IOException {
- super(new Manifest(new GZIPInputStream(new FileInputStream(new File(packageDir, (String) index.remove(0))))), bundleContext);
+ private FileDeploymentPackage(List index, File packageDir, BundleContext bundleContext, DeploymentAdminImpl deploymentAdmin) throws DeploymentException, IOException {
+ super(new Manifest(new GZIPInputStream(new FileInputStream(new File(packageDir, (String) index.remove(0))))), bundleContext, deploymentAdmin);
m_index = index;
m_contentsDir = packageDir;
}
@@ -95,5 +94,4 @@
public AbstractInfo getNextEntry() throws IOException {
throw new UnsupportedOperationException("Not implemented for file-based deployment package");
}
-
}
\ No newline at end of file
diff --git a/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/StreamDeploymentPackage.java b/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/StreamDeploymentPackage.java
index 4c5b851..887628b 100644
--- a/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/StreamDeploymentPackage.java
+++ b/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/StreamDeploymentPackage.java
@@ -32,8 +32,7 @@
/**
* This class represents a deployment package that is read from a jar stream.
*/
-class StreamDeploymentPackage extends AbstractDeploymentPackage {
-
+public class StreamDeploymentPackage extends AbstractDeploymentPackage {
private final JarInputStream m_input;
private final List m_names = new ArrayList();
@@ -44,8 +43,8 @@
* @param bundleContext The bundle context.
* @throws DeploymentException If it was not possible to read a valid deployment package from the specified stream.
*/
- public StreamDeploymentPackage(JarInputStream input, BundleContext bundleContext) throws DeploymentException {
- super(input.getManifest(), bundleContext);
+ public StreamDeploymentPackage(JarInputStream input, BundleContext bundleContext, DeploymentAdminImpl deploymentAdmin) throws DeploymentException {
+ super(input.getManifest(), bundleContext, deploymentAdmin);
m_input = input;
}
@@ -94,5 +93,4 @@
public InputStream getCurrentEntryStream() {
return new NonCloseableStream(m_input);
}
-
}
\ No newline at end of file
diff --git a/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/StartBundleCommand.java b/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/StartBundleCommand.java
index f94eb30..8bc7056 100644
--- a/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/StartBundleCommand.java
+++ b/deploymentadmin/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/StartBundleCommand.java
@@ -21,7 +21,6 @@
import org.apache.felix.deploymentadmin.AbstractDeploymentPackage;
import org.apache.felix.deploymentadmin.BundleInfoImpl;
import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.FrameworkEvent;
import org.osgi.framework.FrameworkListener;
@@ -32,21 +31,19 @@
* Command that starts all bundles described in the source deployment package of a deployment session.
*/
public class StartBundleCommand extends Command {
-
private final RefreshPackagesMonitor m_refreshMonitor = new RefreshPackagesMonitor();
private static final int REFRESH_TIMEOUT = 10000;
public void execute(DeploymentSessionImpl session) {
AbstractDeploymentPackage source = session.getSourceAbstractDeploymentPackage();
- BundleContext context = session.getBundleContext();
PackageAdmin packageAdmin = session.getPackageAdmin();
RefreshPackagesListener listener = new RefreshPackagesListener();
LogService log = session.getLog();
- context.addFrameworkListener(listener);
+ session.getBundleContext().addFrameworkListener(listener);
packageAdmin.refreshPackages(null);
m_refreshMonitor.waitForRefresh();
- context.removeFrameworkListener(listener);
+ session.getBundleContext().removeFrameworkListener(listener);
// start source bundles
BundleInfoImpl[] bundleInfos = source.getOrderedBundleInfos();
@@ -76,7 +73,6 @@
private class RefreshPackagesListener implements FrameworkListener {
public void frameworkEvent(FrameworkEvent event) {
if (event.getType() == FrameworkEvent.PACKAGES_REFRESHED) {
- // TODO: m_log.log(LogService.LOG_INFO, "Packages refreshed event received");
m_refreshMonitor.proceed();
}
}
@@ -97,20 +93,16 @@
*/
public synchronized void waitForRefresh() {
if (!m_alreadyNotified) {
- // TODO: m_log.log(LogService.LOG_DEBUG, "wait for Packages refreshed event");
try {
wait(REFRESH_TIMEOUT);
}
catch (InterruptedException ie) {
- // TODO: m_log.log(LogService.LOG_INFO, "interrupted while waiting for packages refreshed event", ie);
}
finally {
- // just reset the misted notification variable, this Monitor object might be reused.
m_alreadyNotified = false;
}
}
else {
- // TODO: m_log.log(LogService.LOG_DEBUG, "won't wait for Packages refreshed event, event is already received");
// just reset the misted notification variable, this Monitor object might be reused.
m_alreadyNotified = false;
}
@@ -125,5 +117,4 @@
notifyAll();
}
}
-
}