blob: e3dbccac94ae3c81feff48f6b295cfd3dacf586b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2020 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.internal.p2.touchpoint.natives.actions;
import java.io.File;
import java.io.IOException;
import java.util.*;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.equinox.internal.p2.engine.Profile;
import org.eclipse.equinox.internal.p2.touchpoint.natives.*;
import org.eclipse.equinox.p2.engine.spi.ProvisioningAction;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.osgi.util.NLS;
public class CleanupzipAction extends ProvisioningAction {
private static final String UNZIPPED = "unzipped"; //$NON-NLS-1$
public static final String ACTION_CLEANUPZIP = "cleanupzip"; //$NON-NLS-1$
@Override
public IStatus execute(Map<String, Object> parameters) {
return cleanupzip(parameters, true);
}
@Override
public IStatus undo(Map<String, Object> parameters) {
return new UnzipAction().unzip(parameters, false);
}
public static IStatus cleanupzip(Map<String, Object> parameters, boolean restoreable) {
String source = (String) parameters.get(ActionConstants.PARM_SOURCE);
if (source == null)
return Util.createError(NLS.bind(Messages.param_not_set, ActionConstants.PARM_SOURCE, ACTION_CLEANUPZIP));
String target = (String) parameters.get(ActionConstants.PARM_TARGET);
if (target == null)
return Util.createError(NLS.bind(Messages.param_not_set, ActionConstants.PARM_TARGET, ACTION_CLEANUPZIP));
IInstallableUnit iu = (IInstallableUnit) parameters.get(ActionConstants.PARM_IU);
Profile profile = (Profile) parameters.get(ActionConstants.PARM_PROFILE);
String iuPropertyKey = UNZIPPED + ActionConstants.PIPE + source + ActionConstants.PIPE + target;
String unzipped = profile.getInstallableUnitProperty(iu, iuPropertyKey);
if (unzipped == null) {
// best effort
// we try to substitute the current target with what was written.
Map<String, String> iuProperties = profile.getInstallableUnitProperties(iu);
String sourcePrefix = UNZIPPED + ActionConstants.PIPE + source + ActionConstants.PIPE;
for (String key : iuProperties.keySet()) {
if (key.startsWith(sourcePrefix)) {
if (unzipped == null) {
iuPropertyKey = key;
String storedTarget = key.substring(sourcePrefix.length());
unzipped = substituteTarget(storedTarget, target, iuProperties.get(key));
} else
return Status.OK_STATUS; // possible two unzips of this source - give up on best effort
}
}
// no match
if (unzipped == null)
return Status.OK_STATUS;
}
IBackupStore store = restoreable ? (IBackupStore) parameters.get(NativeTouchpoint.PARM_BACKUP) : null;
StringTokenizer tokenizer = new StringTokenizer(unzipped, ActionConstants.PIPE);
List<File> directories = new ArrayList<>();
while (tokenizer.hasMoreTokens()) {
String fileName = tokenizer.nextToken();
File file = new File(fileName);
if (!file.exists())
continue;
if (file.isDirectory())
directories.add(file);
else {
if (store != null)
try {
store.backup(file);
} catch (IOException e) {
return new Status(IStatus.ERROR, Activator.ID, IStatus.OK,
NLS.bind(Messages.backup_file_failed, file.getPath()), e);
}
else
file.delete();
}
}
// sort directories by path length longest path is in top
// this will make sure that a sub folder will be removed before its parent
directories.sort((f1, f2) -> {
if (f1 == f2)
return 0;
if (f1 != null && f2 == null)
return -1;
if (f1 == null)
return 1;
try {
return Integer.valueOf(f2.getCanonicalPath().length()).compareTo(f1.getCanonicalPath().length());
} catch (IOException e) {
// did our best. try an absolute path compare
return Integer.valueOf(f2.getAbsolutePath().length()).compareTo(f1.getAbsolutePath().length());
}
});
for (File directory : directories) {
if (store != null) {
File[] children = directory.listFiles();
// Since backup will deny backup of non empty directory a check must be made
if (children == null || children.length == 0)
try {
store.backupDirectory(directory);
} catch (IOException e) {
return new Status(IStatus.ERROR, Activator.ID, IStatus.OK,
NLS.bind(Messages.backup_file_failed, directory.getPath()), e);
}
} else
directory.delete();
}
profile.removeInstallableUnitProperty(iu, iuPropertyKey);
return Status.OK_STATUS;
}
private static String substituteTarget(String oldTarget, String newTarget, String value) {
StringBuffer buffer = new StringBuffer();
StringTokenizer tokenizer = new StringTokenizer(value, ActionConstants.PIPE);
while (tokenizer.hasMoreTokens()) {
String fileName = tokenizer.nextToken().trim();
if (fileName.length() == 0)
continue;
if (fileName.startsWith(oldTarget))
fileName = newTarget + fileName.substring(oldTarget.length());
buffer.append(fileName).append(ActionConstants.PIPE);
}
return buffer.toString();
}
}