summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Rapicault2012-04-25 09:40:46 (EDT)
committerPascal Rapicault2012-04-27 21:17:38 (EDT)
commit85f365d1c3e178bde1ae62dd343bf782edcd7264 (patch)
tree53b808c1e6f7fcd57fd5270309616feba6db357c
parent48addd2f57b4cb4299e7353d6d8061fc97c13585 (diff)
downloadrt.equinox.p2-85f365d1c3e178bde1ae62dd343bf782edcd7264.zip
rt.equinox.p2-85f365d1c3e178bde1ae62dd343bf782edcd7264.tar.gz
rt.equinox.p2-85f365d1c3e178bde1ae62dd343bf782edcd7264.tar.bz2
Bug 307580 - [native] Add support for include/exclude patterns in unzip
action
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/touchpoint/natives/UnzipActionTest.java163
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/testData/nativeTouchpoint/dirFolder/a.txt2
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/testData/nativeTouchpoint/dirFolder/foo/b.txt2
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/testData/nativeTouchpoint/dirFolder/foo/bar/car/c.txt2
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/Util.java135
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/ActionConstants.java2
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/UnzipAction.java13
7 files changed, 297 insertions, 22 deletions
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/touchpoint/natives/UnzipActionTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/touchpoint/natives/UnzipActionTest.java
index cc63961..9c8fd12 100644
--- a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/touchpoint/natives/UnzipActionTest.java
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/touchpoint/natives/UnzipActionTest.java
@@ -189,4 +189,167 @@ public class UnzipActionTest extends AbstractProvisioningTest {
backup.discard();
}
+
+ /**
+ * Test that when a path is used only files from that path down are unzipped to target as well as undo works.
+ */
+ public void testPath() {
+ String a = "a.txt";
+ String b = "foo/b.txt";
+ String c = "foo/bar/car/c.txt";
+ String b1 = "b.txt";
+ String c1 = "bar/car/c.txt";
+ String c2 = "car/c.txt";
+
+ {
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(ActionConstants.PARM_PATH, "foo");
+ testUnzip(parameters, getTempFolder(), new String[] {b1, c1}, new String[] {a, b, c});
+ }
+ {
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(ActionConstants.PARM_PATH, "foo/");
+ testUnzip(parameters, getTempFolder(), new String[] {b1, c1}, new String[] {a, b, c});
+ }
+ {
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(ActionConstants.PARM_PATH, "**/bar");
+ testUnzip(parameters, getTempFolder(), new String[] {c2}, new String[] {a, b, c, b1});
+ }
+ }
+
+ /**
+ * Tests that only the files specified by inclusion path are unzipped as well as undo works.
+ */
+ public void testInclusion() {
+ String a = "a.txt";
+ String b = "foo/b.txt";
+ String c = "foo/bar/car/c.txt";
+
+ // full path
+ {
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(ActionConstants.PARM_INCLUDE, "foo/b.txt");
+ testUnzip(parameters, getTempFolder(), new String[] {b}, new String[] {a, c});
+ }
+ // wildcarded path
+ {
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(ActionConstants.PARM_INCLUDE, "*/b.txt");
+ testUnzip(parameters, getTempFolder(), new String[] {b}, new String[] {a, c});
+ }
+ // subdir wildcarded path
+ {
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(ActionConstants.PARM_INCLUDE, "**/c.txt");
+ testUnzip(parameters, getTempFolder(), new String[] {c}, new String[] {a, b});
+ }
+ }
+
+ /**
+ * Tests that only the files specified by exclusion path are not unzipped as well as undo works.
+ */
+ public void testExclusion() {
+ String a = "a.txt";
+ String b = "foo/b.txt";
+ String c = "foo/bar/car/c.txt";
+
+ // full path
+ {
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(ActionConstants.PARM_EXCLUDE, "foo/b.txt");
+ testUnzip(parameters, getTempFolder(), new String[] {a, c}, new String[] {b});
+ }
+ // wildcarded path
+ {
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(ActionConstants.PARM_EXCLUDE, "*/b.txt");
+ testUnzip(parameters, getTempFolder(), new String[] {a, c}, new String[] {b});
+ }
+ // subdir wildcarded path
+ {
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(ActionConstants.PARM_EXCLUDE, "**/c.txt");
+ testUnzip(parameters, getTempFolder(), new String[] {a, b}, new String[] {c});
+ }
+ }
+
+ /**
+ * Tests that only the files specified by inclusion path and not in exclusion path are unzipped as well as undo works.
+ */
+ public void testInclusionAndExclusion() {
+ String a = "a.txt";
+ String b = "foo/b.txt";
+ String c = "foo/bar/car/c.txt";
+
+ Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put(ActionConstants.PARM_INCLUDE, "*.txt");
+ parameters.put(ActionConstants.PARM_EXCLUDE, "**/c.txt");
+ testUnzip(parameters, getTempFolder(), new String[] {a, b}, new String[] {c});
+ }
+
+ private void testUnzip(Map<String, String> params, File installFolder, String[] shoudlExistNames, String[] shoudlNotExistNames) {
+
+ ArrayList<File> shoudlExist = new ArrayList<File>();
+ ArrayList<File> shoudlNotExist = new ArrayList<File>();
+
+ // first check that are no files in install folder
+ for (String fileName : shoudlExistNames) {
+ File file = new File(installFolder, fileName);
+ shoudlExist.add(file);
+ assertFalse("File " + file.getPath() + " should not exist", file.exists());
+ }
+ for (String fileName : shoudlNotExistNames) {
+ File file = new File(installFolder, fileName);
+ shoudlNotExist.add(file);
+ assertFalse("File " + file.getPath() + " should not exist", file.exists());
+ }
+
+ Properties profileProperties = new Properties();
+ profileProperties.setProperty(IProfile.PROP_INSTALL_FOLDER, installFolder.toString());
+ IProfile profile = createProfile("test", profileProperties);
+
+ File zipSource = getTestData("1.0", "/testData/nativeTouchpoint/a.dir.zip");
+ File zipTarget = new File(installFolder, "a.dir.zip");
+ copy("2.0", zipSource, zipTarget);
+
+ InstallableUnitDescription iuDesc = new MetadataFactory.InstallableUnitDescription();
+ iuDesc.setId("test");
+ iuDesc.setVersion(DEFAULT_VERSION);
+ IArtifactKey key = PublisherHelper.createBinaryArtifactKey("test", DEFAULT_VERSION);
+ iuDesc.setArtifacts(new IArtifactKey[] {key});
+ iuDesc.setTouchpointType(PublisherHelper.TOUCHPOINT_NATIVE);
+ IInstallableUnit iu = MetadataFactory.createInstallableUnit(iuDesc);
+
+ Map parameters = new HashMap();
+ parameters.put(ActionConstants.PARM_PROFILE, profile);
+ parameters.put("iu", iu);
+ parameters.put(ActionConstants.PARM_PROFILE, profile);
+ NativeTouchpoint touchpoint = new NativeTouchpoint();
+ touchpoint.initializePhase(null, profile, "test", parameters);
+
+ parameters.put(ActionConstants.PARM_SOURCE, zipTarget.getAbsolutePath());
+ parameters.put(ActionConstants.PARM_TARGET, installFolder.getAbsolutePath());
+ parameters.putAll(params);
+ parameters = Collections.unmodifiableMap(parameters);
+
+ UnzipAction action = new UnzipAction();
+ action.execute(parameters);
+ for (File file : shoudlExist) {
+ assertTrue("File " + file.getPath() + " should exist", file.exists());
+ }
+ for (File file : shoudlNotExist) {
+ assertFalse("File " + file.getPath() + " should not exist", file.exists());
+ }
+
+ // does nothing so should not alter parameters
+ action.undo(parameters);
+ // check that undo removed all files
+ for (File file : shoudlExist) {
+ assertFalse("File " + file.getPath() + " should not exist", file.exists());
+ }
+ for (File file : shoudlNotExist) {
+ assertFalse("File " + file.getPath() + " should not exist", file.exists());
+ }
+ }
} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/nativeTouchpoint/dirFolder/a.txt b/bundles/org.eclipse.equinox.p2.tests/testData/nativeTouchpoint/dirFolder/a.txt
new file mode 100644
index 0000000..c78a316
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/testData/nativeTouchpoint/dirFolder/a.txt
@@ -0,0 +1,2 @@
+A
+// This a.txt should have the first line being a single A
diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/nativeTouchpoint/dirFolder/foo/b.txt b/bundles/org.eclipse.equinox.p2.tests/testData/nativeTouchpoint/dirFolder/foo/b.txt
new file mode 100644
index 0000000..11e42f9
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/testData/nativeTouchpoint/dirFolder/foo/b.txt
@@ -0,0 +1,2 @@
+B
+// This b.txt should have the first line being a single B
diff --git a/bundles/org.eclipse.equinox.p2.tests/testData/nativeTouchpoint/dirFolder/foo/bar/car/c.txt b/bundles/org.eclipse.equinox.p2.tests/testData/nativeTouchpoint/dirFolder/foo/bar/car/c.txt
new file mode 100644
index 0000000..afdfac6
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/testData/nativeTouchpoint/dirFolder/foo/bar/car/c.txt
@@ -0,0 +1,2 @@
+C
+// This c.txt should have the first line being a single C
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/Util.java b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/Util.java
index 432dad5..3696bc1 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/Util.java
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/Util.java
@@ -13,6 +13,8 @@ package org.eclipse.equinox.internal.p2.touchpoint.natives;
import java.io.*;
import java.net.URI;
import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.eclipse.core.runtime.*;
@@ -81,9 +83,19 @@ public class Util {
* monitor and backup store may be null.
*/
public static File[] unzipFile(File zipFile, File outputDir, IBackupStore store, String taskName, IProgressMonitor monitor) throws IOException {
+ return unzipFile(zipFile, outputDir, null /*path*/, null /*includes*/, null /*excludes*/, store, taskName, monitor);
+ }
+
+ /**
+ * Unzip from a File to an output directory, with progress indication and backup.
+ * monitor and backup store may be null.
+ * It takes in count exclude/exclude pattern (that can be null, case when everything is unzipped).
+ * If a path is specified, the path is consider as entry point in zip, as when the to directory in zip would have been the specified path.
+ */
+ public static File[] unzipFile(File zipFile, File outputDir, String path, String[] includePatterns, String[] excludePatterns, IBackupStore store, String taskName, IProgressMonitor monitor) throws IOException {
InputStream in = new FileInputStream(zipFile);
try {
- return unzipStream(in, zipFile.length(), outputDir, store, taskName, monitor);
+ return unzipStream(in, zipFile.length(), outputDir, path, includePatterns, excludePatterns, store, taskName, monitor);
} catch (IOException e) {
// add the file name to the message
throw new IOException(NLS.bind(Messages.Util_Error_Unzipping, zipFile, e.getMessage()));
@@ -97,6 +109,16 @@ public class Util {
* if backup store is not null.
*/
public static File[] unzipStream(InputStream stream, long size, File outputDir, IBackupStore store, String taskName, IProgressMonitor monitor) throws IOException {
+ return unzipStream(stream, size, outputDir, null /*path*/, null /*includes*/, null /*excludes*/, store, taskName, monitor);
+ }
+
+ /**
+ * Unzip from an InputStream to an output directory using backup of overwritten files
+ * if backup store is not null.
+ * It takes in count exclude/exclude pattern (that can be null, case when everything is unzipped).
+ * If a path is specified, the path is consider as entry point in zip, as when the to directory in zip would have been the specified path.
+ */
+ public static File[] unzipStream(InputStream stream, long size, File outputDir, String path, String[] includePatterns, String[] excludePatterns, IBackupStore store, String taskName, IProgressMonitor monitor) throws IOException {
InputStream is = monitor == null ? stream : stream; // new ProgressMonitorInputStream(stream, size, size, taskName, monitor); TODO Commented code
ZipInputStream in = new ZipInputStream(new BufferedInputStream(is));
ZipEntry ze = in.getNextEntry();
@@ -106,28 +128,76 @@ public class Util {
in.close();
throw new IOException(Messages.Util_Invalid_Zip_File_Format);
}
+
+ if (path != null && path.trim().length() == 0)
+ path = null;
+ Pattern pathRegex = path == null ? null : createAntStylePattern("(" + path + ")(*)"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ Collection<Pattern> includeRegexp = new ArrayList<Pattern>();
+ Collection<Pattern> excludeRegexp = new ArrayList<Pattern>();
+ if (includePatterns != null) {
+ for (String pattern : includePatterns) {
+ if (pattern != null) {
+ includeRegexp.add(createAntStylePattern(pattern));
+ }
+ }
+ }
+ if (excludePatterns != null) {
+ for (String pattern : excludePatterns) {
+ if (pattern != null) {
+ excludeRegexp.add(createAntStylePattern(pattern));
+ }
+ }
+ }
ArrayList<File> unzippedFiles = new ArrayList<File>();
do {
- File outFile = new File(outputDir, ze.getName());
- unzippedFiles.add(outFile);
- if (ze.isDirectory()) {
- outFile.mkdirs();
- } else {
- if (outFile.exists()) {
- if (store != null)
- store.backup(outFile);
- else
- outFile.delete();
- } else {
- outFile.getParentFile().mkdirs();
+ String name = ze.getName();
+ if (pathRegex == null || pathRegex.matcher(name).matches()) {
+ boolean unzip = includeRegexp.isEmpty();
+ for (Pattern pattern : includeRegexp) {
+ unzip = pattern.matcher(name).matches();
+ if (unzip)
+ break;
+ }
+ if (unzip && !excludeRegexp.isEmpty()) {
+ for (Pattern pattern : excludeRegexp) {
+ if (pattern.matcher(name).matches()) {
+ unzip = false;
+ break;
+ }
+ }
}
- try {
- copyStream(in, false, new FileOutputStream(outFile), true);
- } catch (FileNotFoundException e) {
- // TEMP: ignore this for now in case we're trying to replace
- // a running eclipse.exe
+ if (unzip) {
+ if (pathRegex != null) {
+ Matcher matcher = pathRegex.matcher(name);
+ if (matcher.matches()) {
+ name = matcher.group(2);
+ if (name.startsWith("/")) //$NON-NLS-1$
+ name = name.substring(1);
+ }
+ }
+ File outFile = new File(outputDir, name);
+ unzippedFiles.add(outFile);
+ if (ze.isDirectory()) {
+ outFile.mkdirs();
+ } else {
+ if (outFile.exists()) {
+ if (store != null)
+ store.backup(outFile);
+ else
+ outFile.delete();
+ } else {
+ outFile.getParentFile().mkdirs();
+ }
+ try {
+ copyStream(in, false, new FileOutputStream(outFile), true);
+ } catch (FileNotFoundException e) {
+ // TEMP: ignore this for now in case we're trying to replace
+ // a running eclipse.exe
+ }
+ outFile.setLastModified(ze.getTime());
+ }
}
- outFile.setLastModified(ze.getTime());
}
in.closeEntry();
} while ((ze = in.getNextEntry()) != null);
@@ -163,4 +233,31 @@ public class Util {
}
}
}
+
+ private static Pattern createAntStylePattern(String pattern) {
+ StringBuffer sb = new StringBuffer();
+ for (int c = 0; c < pattern.length(); c++) {
+ switch (pattern.charAt(c)) {
+ case '.' :
+ sb.append("\\."); //$NON-NLS-1$
+ break;
+ case '*' :
+ sb.append(".*"); //$NON-NLS-1$
+ break;
+ case '?' :
+ sb.append(".?"); //$NON-NLS-1$
+ break;
+ default :
+ sb.append(pattern.charAt(c));
+ break;
+ }
+ }
+ String string = sb.toString();
+ if (string.endsWith("\\..*")) { //$NON-NLS-1$
+ sb.append("|"); //$NON-NLS-1$
+ sb.append(string.substring(0, string.length() - 4));
+ }
+ return Pattern.compile(sb.toString());
+ }
+
}
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/ActionConstants.java b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/ActionConstants.java
index 0818a1e..daa448b 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/ActionConstants.java
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/ActionConstants.java
@@ -19,6 +19,8 @@ public class ActionConstants {
public static final String PARM_TARGET_DIR = "targetDir"; //$NON-NLS-1$
public static final String PARM_TARGET = "target"; //$NON-NLS-1$
public static final String PARM_SOURCE = "source"; //$NON-NLS-1$
+ public static final String PARM_INCLUDE = "include"; //$NON-NLS-1$
+ public static final String PARM_EXCLUDE = "exclude"; //$NON-NLS-1$
public static final String PARM_IU = "iu"; //$NON-NLS-1$
public static final String PIPE = "|"; //$NON-NLS-1$
public static final String PARM_AT_ARTIFACT = "@artifact"; //$NON-NLS-1$
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/UnzipAction.java b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/UnzipAction.java
index c2a9150..0d87a57 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/UnzipAction.java
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/actions/UnzipAction.java
@@ -62,7 +62,12 @@ public class UnzipAction extends ProvisioningAction {
source = artifactLocation;
}
IBackupStore store = restoreable ? (IBackupStore) parameters.get(NativeTouchpoint.PARM_BACKUP) : null;
- File[] unzippedFiles = unzip(source, target, store);
+
+ String path = (String) parameters.get(ActionConstants.PARM_PATH);
+ String includePattern = (String) parameters.get(ActionConstants.PARM_INCLUDE);
+ String excludePattern = (String) parameters.get(ActionConstants.PARM_EXCLUDE);
+
+ File[] unzippedFiles = unzip(source, target, path, includePattern, excludePattern, store);
StringBuffer unzippedFileNameBuffer = new StringBuffer();
for (int i = 0; i < unzippedFiles.length; i++)
unzippedFileNameBuffer.append(unzippedFiles[i].getAbsolutePath()).append(ActionConstants.PIPE);
@@ -76,14 +81,16 @@ public class UnzipAction extends ProvisioningAction {
* Unzips a source zip into the given destination. Any existing contents in the destination
* are backed up in the provided backup store.
*/
- private static File[] unzip(String source, String destination, IBackupStore store) {
+ private static File[] unzip(String source, String destination, String path, String includePattern, String excludePattern, IBackupStore store) {
File zipFile = new File(source);
if (zipFile == null || !zipFile.exists()) {
Util.log(UnzipAction.class.getName() + " the files to be unzipped is not here"); //$NON-NLS-1$
}
try {
String taskName = NLS.bind(Messages.unzipping, source);
- return Util.unzipFile(zipFile, new File(destination), store, taskName, new NullProgressMonitor());
+ String[] includes = includePattern == null ? null : includePattern.split("\\s+"); //$NON-NLS-1$
+ String[] excludes = excludePattern == null ? null : excludePattern.split("\\s+"); //$NON-NLS-1$
+ return Util.unzipFile(zipFile, new File(destination), path, includes, excludes, store, taskName, new NullProgressMonitor());
} catch (IOException e) {
Util.log(UnzipAction.class.getName() + " error unzipping zipfile: " + zipFile.getAbsolutePath() + "destination: " + destination); //$NON-NLS-1$ //$NON-NLS-2$
}