/******************************************************************************* * Copyright (c) 2008, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * 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$ public IStatus execute(Map<String, Object> parameters) { return cleanupzip(parameters, true); } public IStatus undo(Map<String, Object> parameters) { return 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<File>(); 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 Collections.sort(directories, new Comparator<File>() { public int compare(File f1, File f2) { if (f1 == f2) return 0; if (f1 != null && f2 == null) return -1; if (f1 == null) return 1; try { return new Integer(f2.getCanonicalPath().length()).compareTo(f1.getCanonicalPath().length()); } catch (IOException e) { // did our best. try an absolute path compare return new Integer(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(); } }