diff options
Diffstat (limited to 'p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/internal/p2/touchpoint/natives/actions/UnpackAction.java')
-rw-r--r-- | p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/internal/p2/touchpoint/natives/actions/UnpackAction.java | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/internal/p2/touchpoint/natives/actions/UnpackAction.java b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/internal/p2/touchpoint/natives/actions/UnpackAction.java new file mode 100644 index 00000000000..9953449665c --- /dev/null +++ b/p2/org.eclipse.cdt.p2/src/org/eclipse/cdt/internal/p2/touchpoint/natives/actions/UnpackAction.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2015 QNX Software Systems 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: + * QNX Software Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.p2.touchpoint.natives.actions; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Map; + +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; +import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; +import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; +import org.apache.commons.compress.compressors.xz.XZCompressorInputStream; +import org.eclipse.cdt.internal.p2.Activator; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.equinox.p2.engine.IProfile; +import org.eclipse.equinox.p2.engine.spi.ProvisioningAction; + +/** + * Unpack the artifact with a choice of compression + * + * syntax: unpack(source:<url>, targetDir:${installFolder}/<subdir>, compression:[gz|bz2]) + */ +public class UnpackAction extends ProvisioningAction { + + private static final String ACTION_NAME = "unpack"; //$NON-NLS-1$ + private static final String PARM_SOURCE = "source"; //$NON-NLS-1$ + private static final String PARM_TARGET_DIR = "targetDir"; //$NON-NLS-1$ + private static final String PARM_FORMAT = "format"; //$NON-NLS-1$ + + @Override + public IStatus execute(Map<String, Object> parameters) { + try { + String source = (String)parameters.get(PARM_SOURCE); + if (source == null) { + return Activator.getStatus(IStatus.ERROR, String.format(Messages.UnpackAction_ParmNotPresent, PARM_SOURCE, ACTION_NAME)); + } + + String targetDir = (String)parameters.get(PARM_TARGET_DIR); + if (targetDir == null) { + return Activator.getStatus(IStatus.ERROR, String.format(Messages.UnpackAction_ParmNotPresent, PARM_TARGET_DIR, ACTION_NAME)); + } + + String format = (String)parameters.get(PARM_FORMAT); + if (format == null) { + return Activator.getStatus(IStatus.ERROR, String.format(Messages.UnpackAction_ParmNotPresent, PARM_FORMAT, ACTION_NAME)); + } + + IProfile profile = (IProfile) parameters.get("profile"); //$NON-NLS-1$ + File installFolder = new File(profile.getProperty(IProfile.PROP_INSTALL_FOLDER)); + File destDir = new File(installFolder, targetDir); + if (destDir.exists()) { + return Activator.getStatus(IStatus.ERROR, String.format(org.eclipse.cdt.internal.p2.touchpoint.natives.actions.Messages.UnpackAction_TargetDirExists, destDir.getAbsolutePath())); + } + + URL url = new URL(source); + InputStream fileIn = new BufferedInputStream(url.openStream()); + + switch (format) { + case "tar.gz": //$NON-NLS-1$ + InputStream gzIn = new GzipCompressorInputStream(fileIn); + untar(gzIn, destDir); + break; + case "tar.bz2": //$NON-NLS-1$ + InputStream bzIn = new BZip2CompressorInputStream(fileIn); + untar(bzIn, destDir); + break; + case "tar.xz": //$NON-NLS-1$ + InputStream xzIn = new XZCompressorInputStream(fileIn); + untar(xzIn, destDir); + break; + case "zip": //$NON-NLS-1$ + + } + + return Status.OK_STATUS; + } catch (Throwable e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getLocalizedMessage(), e); + } + } + + private void untar(InputStream in, File destDir) throws IOException { + byte[] buff = new byte[4096]; + try (TarArchiveInputStream tarIn = new TarArchiveInputStream(in)) { + for (TarArchiveEntry entry = tarIn.getNextTarEntry(); entry != null; entry = tarIn.getNextTarEntry()) { + String name = entry.getName(); + File destFile = new File(destDir, name); + if (entry.isSymbolicLink()) { + Files.createSymbolicLink(destFile.toPath(), Paths.get(name)); + } else { + try (FileOutputStream out = new FileOutputStream(destFile)) { + long size = entry.getSize(); + while (size > 0) { + int n = tarIn.read(buff, 0, (int)Math.min(size, buff.length)); + out.write(buff, 0, n); + size -= n; + } + } + chmod(destFile, entry.getMode()); + } + } + } + } + + private void chmod(File file, int mode) { + file.setExecutable((mode & 0111) != 0, (mode & 0110) == 0); + file.setWritable((mode & 0222) != 0, (mode & 0220) == 0); + file.setReadable((mode & 0444) != 0, (mode & 0440) == 0); + } + + @Override + public IStatus undo(Map<String, Object> parameters) { + try { + return CleanupUntarAction.cleanup(parameters); + } catch (Exception e) { + return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getLocalizedMessage(), e); + } + } + +} |