|
From: <chr...@us...> - 2009-04-16 21:26:26
|
Revision: 5295
http://jnode.svn.sourceforge.net/jnode/?rev=5295&view=rev
Author: chrisboertien
Date: 2009-04-16 21:26:19 +0000 (Thu, 16 Apr 2009)
Log Message:
-----------
More zip command implementation
Added support for -m -D -p -j -x -i
Added javadoc to Zip
Extrapolated strings from within code
Added 4 FileFilter implementations as nested classes in ADW
Signed-off-by: chrisboertien <chr...@gm...>
Modified Paths:
--------------
trunk/fs/descriptors/org.jnode.fs.command.archive.xml
trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java
trunk/fs/src/fs/org/jnode/fs/command/archive/ArchiveCommand.java
trunk/fs/src/fs/org/jnode/fs/command/archive/Zip.java
trunk/fs/src/fs/org/jnode/fs/command/archive/ZipCommand.java
Modified: trunk/fs/descriptors/org.jnode.fs.command.archive.xml
===================================================================
--- trunk/fs/descriptors/org.jnode.fs.command.archive.xml 2009-04-16 20:37:00 UTC (rev 5294)
+++ trunk/fs/descriptors/org.jnode.fs.command.archive.xml 2009-04-16 21:26:19 UTC (rev 5295)
@@ -15,6 +15,7 @@
<runtime>
<library name="jnode-fs.jar">
<export name="org.jnode.fs.command.archive.*" />
+ <export name="org.jnode.fs.command.AbstractDirectoryWalker" />
</library>
</runtime>
@@ -244,7 +245,7 @@
<option argLabel="recurse" shortName="r"/>
<!--<option argLabel="recurse-cd" shortName="R"/>-->
<option argLabel="newer" shortName="t"/>
- <!--<option argLabel="older" shortName="tt"/>-->
+ <option argLabel="older" longName="tt"/>
<!-- Zip -->
<option argLabel="no-path" shortName="j"/>
<!-- Zip Operations -->
@@ -259,14 +260,12 @@
</optionSet>
<argument argLabel="archive"/>
<repeat>
- <argument argLabel="patterns"/>
+ <alternatives>
+ <option argLabel="exclude" shortName="x"/>
+ <option argLabel="include" shortName="i"/>
+ <argument argLabel="patterns"/>
+ </alternatives>
</repeat>
- <!-- TODO
- <repeat>
- <option argLabel="include" shortName="i"/>
- <option argLabel="exclude" shortName="x"/>
- </repeat>
- -->
</sequence>
</syntax>
</extension>
Modified: trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java 2009-04-16 20:37:00 UTC (rev 5294)
+++ trunk/fs/src/fs/org/jnode/fs/command/AbstractDirectoryWalker.java 2009-04-16 21:26:19 UTC (rev 5295)
@@ -28,6 +28,10 @@
import java.util.Stack;
import java.util.List;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+import org.jnode.shell.PathnamePattern;
/**
* <p>
* <code>AbstractDirectoryWalker</code> - walk through a directory hierarchy
@@ -54,6 +58,66 @@
this.depth = depth;
}
}
+
+ public static class PathnamePatternFilter implements FileFilter {
+
+ private Matcher matcher;
+ private boolean exclude;
+
+ public PathnamePatternFilter(String pattern, boolean exclude) {
+ this.exclude = exclude;
+ this.matcher = PathnamePattern.compilePosixShellPattern(pattern, 0).matcher("");
+ }
+
+ public boolean accept(File file) {
+ return matcher.reset(file.getName()).matches() ^ exclude;
+ }
+ }
+
+ public static class RegexPatternFilter implements FileFilter {
+
+ private Matcher matcher;
+ private boolean exclude;
+
+ public RegexPatternFilter(String pattern, boolean exclude) {
+ this.exclude = exclude;
+ this.matcher = Pattern.compile(pattern).matcher("");
+ }
+
+ public boolean accept(File file) {
+ return matcher.reset(file.getName()).matches() ^ exclude;
+ }
+ }
+
+ public static class ModTimeFilter implements FileFilter {
+
+ private long modTime;
+ private boolean newer;
+
+ public ModTimeFilter(long time, boolean newer) {
+ this.modTime = time;
+ this.newer = newer;
+ }
+
+ public boolean accept(File file) {
+ return file.lastModified() == modTime || ((file.lastModified() < modTime) ^ newer);
+ }
+ }
+
+ public static class SizeFilter implements FileFilter {
+
+ private long size;
+ private boolean greater;
+
+ public SizeFilter(long size, boolean greater) {
+ this.size = size;
+ this.greater = greater;
+ }
+
+ public boolean accept(File file) {
+ return file.length() == size || ((file.length() < size) ^ greater);
+ }
+ }
private final Stack<FileObject> stack = new Stack<FileObject>();
private final Set<FileFilter> filters = new HashSet<FileFilter>();
@@ -87,7 +151,7 @@
}
public synchronized void walk(final List<File> dirs) throws IOException {
- walk(dirs.toArray(new File[0]));
+ walk(dirs.toArray(new File[dirs.size() ]));
}
private void handle(final FileObject file) throws IOException {
Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/ArchiveCommand.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/command/archive/ArchiveCommand.java 2009-04-16 20:37:00 UTC (rev 5294)
+++ trunk/fs/src/fs/org/jnode/fs/command/archive/ArchiveCommand.java 2009-04-16 21:26:19 UTC (rev 5295)
@@ -24,6 +24,7 @@
import org.jnode.shell.syntax.Argument;
import org.jnode.shell.syntax.FlagArgument;
+import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -35,6 +36,13 @@
import java.util.ArrayList;
+import org.apache.tools.zip.ZipFile;
+
+/**
+ * This is a base class that holds some convenience methods for implementing archive commands.
+ *
+ * @author chris boertien
+ */
public class ArchiveCommand extends AbstractCommand {
private static final String help_verbose = "show the compression ratio for each file compressed";
@@ -76,6 +84,7 @@
protected OutputStream stdout;
protected String commandName;
+ protected int rc;
protected boolean use_stdout;
protected boolean force;
protected boolean compress;
@@ -95,6 +104,7 @@
stdin = getInput().getInputStream();
stdout = getOutput().getOutputStream();
+ // FIXME get rid of this {
if (command.equals("zcat") || command.equals("bzcat")) return;
if (!command.equals("tar")) {
@@ -108,6 +118,7 @@
if (Verbose.isSet()) outMode |= OUT_NOTICE;
if (Debug.isSet()) outMode |= OUT_DEBUG;
}
+ // }
}
protected void createStreamBuffer(int size) {
@@ -247,14 +258,45 @@
}
/**
+ * Convenience method for closing streams and writers.
+ */
+ protected void close(Closeable obj) {
+ if (obj != null) {
+ try {
+ obj.close();
+ } catch (IOException _) {
+ //ignore
+ }
+ }
+ }
+
+ /**
+ * Convenience method for closing org.apache.tools.zip.ZipFile
+ */
+ protected void close(ZipFile zfile) {
+ if (zfile != null) {
+ try {
+ zfile.close();
+ } catch (IOException _) {
+ // ignore
+ }
+ }
+ }
+
+ /**
* Prompt the user with a question asking for a yes or no answer.
*
+ * FIXME This is unsafe as it will trigger an endless loop if stdin
+ * is not the terminal.
+ *
* @param String the question to ask the user
* @return true if the user said yes, false if the user said no
*/
protected boolean prompt_yn(String s, boolean defaultY) {
int choice;
- for (;;) {
+ // put a cap on the looping to prevent non-terminal stdin
+ // from an infinte loop
+ for (int i = 0; i < 10; i++) {
stdoutWriter.print(s);
try {
choice = stdinReader.read();
@@ -266,6 +308,8 @@
if (choice == 'n') return false;
if (choice == '\n') return defaultY;
}
+
+ return false;
}
protected void out(String s) {
Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/Zip.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/command/archive/Zip.java 2009-04-16 20:37:00 UTC (rev 5294)
+++ trunk/fs/src/fs/org/jnode/fs/command/archive/Zip.java 2009-04-16 21:26:19 UTC (rev 5295)
@@ -21,9 +21,11 @@
package org.jnode.fs.command.archive;
import java.io.File;
+import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.LineNumberReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
@@ -33,6 +35,9 @@
import org.apache.tools.zip.ZipExtraField;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
+import org.jnode.fs.command.AbstractDirectoryWalker;
+import org.jnode.fs.command.AbstractDirectoryWalker.ModTimeFilter;
+import org.jnode.fs.command.AbstractDirectoryWalker.PathnamePatternFilter;
import org.jnode.shell.PathnamePattern;
import org.jnode.shell.syntax.Argument;
import org.jnode.shell.syntax.FileArgument;
@@ -40,10 +45,17 @@
import org.jnode.shell.syntax.StringArgument;
/**
+ * TODO test return codes
+ * TODO make sure no archive is created if the creation fails
+ * TODO implement delete
+ * TODO implement update
+ * TODO implement freshen
* @author chris boeriten
*/
public class Zip extends ArchiveCommand {
+ private static final boolean DEBUG = true;
+
private static final String help_delete = "remove the list of entries from the archive";
private static final String help_freshen = "[zip] Replaces entries in the archive with files from the file " +
"system if they exist and are newer than the entry.\n[unzip] Replaces " +
@@ -60,6 +72,28 @@
private static final String help_archive = "the zip archive to use";
private static final String help_patterns = "file matching patterns(wildcards)";
+ private static final String fmt_extract = "%11s: %s";
+ private static final String fmt_footer = " %8d %8d %d files";
+ private static final String fmt_entry = " %8d %8d %d %s";
+ private static final String fmt_warn_dup = "%s: %s: %s";
+ private static final String fatal_create_arch = "Could not create archive: ";
+ private static final String fatal_req_arch = "Archive required but not found: ";
+ private static final String fatal_create_zfile = "Unable to open archive as ZipFile: ";
+ private static final String fatal_inv_args = "zip error: Invalid arguments (cannot repeat names in zip file)";
+ private static final String fatal_walking = "Exception while walking.";
+ private static final String fatal_read_stdin = "Exception while reading stdin.";
+ private static final String str_header_1 = " Size CSize Date Time M Name";
+ private static final String str_header_2 = " -------- -------- -------- ----- - ----";
+ private static final String str_footer = " -------- -------- -------";
+ private static final String str_archive = "Archive: ";
+ private static final String str_creating = "creating";
+ private static final String str_inflating = "inflating";
+ private static final String str_adding = "adding";
+ private static final String str_zip_warn = "zip warning";
+ private static final String str_fullname_1 = " first full name";
+ private static final String str_fullname_2 = "second full name";
+ private static final String str_name_repeat = "name in zip file repeated";
+
protected final StringArgument Patterns;
protected final FileArgument Archive;
protected final FlagArgument Delete;
@@ -82,9 +116,11 @@
private static final int ZIP_INSERT = ZIP_ADD | ZIP_MOVE;
private static final int ZIP_REQ_ARCH = ZIP_ALL & ~ZIP_INSERT;
- private List<Pattern> patterns;
- private List<Pattern> includes;
- private List<Pattern> excludes;
+ /* Populated in ZipCommand and UnzipCommand */
+ protected List<String> includes;
+ protected List<String> excludes;
+ protected List<String> excludeDirs;
+
private List<File> files;
private List<ZipEntry> fileEntries;
private List<ZipEntry> dirEntries;
@@ -94,13 +130,14 @@
private File archive;
private ZipFile zarchive;
protected File tmpDir;
- protected String noCompress;
+ protected String[] noCompress;
protected int mode;
protected boolean ignore_case;
protected boolean keep;
protected boolean overwrite;
protected boolean backup;
protected boolean noDirEntry;
+ protected boolean noPath;
protected boolean recurse;
protected boolean filesStdin;
protected boolean useStdout;
@@ -123,8 +160,13 @@
parseOptions(command);
try {
- if (mode == ZIP_ADD) {
+ if ((mode & ZIP_ADD) != 0) {
insert();
+ if ((mode & ZIP_MOVE) != 0) {
+ for (File file : files) {
+ file.delete();
+ }
+ }
return;
}
@@ -140,13 +182,7 @@
} catch (Exception e) {
e.printStackTrace();
} finally {
- if (zarchive != null) {
- try {
- zarchive.close();
- } catch (IOException _) {
- // ignore
- }
- }
+ close(zarchive);
exit(0);
}
}
@@ -157,11 +193,12 @@
InputStream in;
try {
- zout = new ZipOutputStream(new FileOutputStream(archive));
+ zout = new ZipOutputStream(archive);
for (File file : files) {
in = null;
+ entry = createEntry(file);
+ out(String.format(fmt_extract, str_adding, entry.getName()));
try {
- entry = createEntry(file);
if (!file.isDirectory()) {
if ((in = openFileRead(file)) == null) {
continue;
@@ -189,27 +226,29 @@
try {
zout.finish();
} catch (IOException e) {
- //
+ // ignore
}
}
}
}
+ @SuppressWarnings("unchecked")
private void list() throws IOException {
Enumeration<ZipEntry> entries;
- ZipEntry entry;
int size = 0;
int csize = 0;
int count = 0;
printListHeader();
- entries = zarchive.getEntries();
- while (entries.hasMoreElements()) {
- entry = entries.nextElement();
- //debug(entry);
+ for (ZipEntry entry : dirEntries) {
printListEntry(entry);
count++;
- size += entry.getSize();
+ }
+
+ for (ZipEntry entry : fileEntries) {
+ printListEntry(entry);
+ count++;
+ size += entry.getSize();
csize += entry.getCompressedSize();
}
printListFooter(size, csize, count);
@@ -220,44 +259,47 @@
OutputStream out = null;
File file;
- out("Archive: " + archive.getName());
+ out(str_archive + archive.getName());
+
for (ZipEntry entry : dirEntries) {
- out(String.format("%11s: %s", "creating", entry.getName()));
+ out(String.format(fmt_extract, str_creating, entry.getName()));
file = new File(entry.getName());
file.mkdirs();
}
for (ZipEntry entry : fileEntries) {
- out(String.format("%11s: %s", "inflating", entry.getName()));
+ out(String.format(fmt_extract, str_inflating, entry.getName()));
file = new File(entry.getName());
try {
+ File parent = file.getParentFile();
+ if (parent != null && !parent.exists()) {
+ parent.mkdirs();
+ }
file.createNewFile();
in = zarchive.getInputStream(entry);
- out = new FileOutputStream(file);
+ if ((out = openFileWrite(file, false, false)) == null) {
+ continue;
+ }
processStream(in, out);
} catch (IOException e) {
debug(e.getMessage());
} finally {
- if (in != null) {
- try {
- in.close();
- in = null;
- } catch (IOException _) {
- // ignore;
- }
- }
- if (out != null) {
- try {
- out.close();
- out = null;
- } catch (IOException _) {
- // ignore;
- }
- }
+ close(in);
+ close(out);
}
}
}
+ /**
+ * Creates a ZipEntry for the specified file.
+ *
+ * If the file is a directory it will have a trailing slash
+ * appended to its name. This is used to distinguish files
+ * from directories in the archive.
+ *
+ * If the -j option is given, then only the file name is stored,
+ * not its full pathname. Conflicts are dealt with in parseFiles()
+ */
private ZipEntry createEntry(File file) {
String name = file.getPath();
ZipEntry entry;
@@ -267,37 +309,34 @@
}
entry = new ZipEntry(name);
entry.setMethod(ZipEntry.STORED);
- entry.setCrc(0);
- entry.setSize(0);
} else {
+ if (noPath) {
+ name = file.getName();
+ }
entry = new ZipEntry(name);
entry.setMethod(ZipEntry.DEFLATED);
+ if (noCompress != null && noCompress.length > 0) {
+ for (String suf : noCompress) {
+ if (name.endsWith(suf)) {
+ entry.setMethod(ZipEntry.STORED);
+ break;
+ }
+ }
+ }
}
return entry;
}
- private void printListHeader() {
- out(" Size CSize Date Time Name");
- out(" -------- -------- -------- ----- ----");
- }
-
- private void printListEntry(ZipEntry entry) {
- out(String.format(" %8d %8d %s", entry.getSize(), entry.getCompressedSize(), entry.getName()));
- }
-
- private void printListFooter(int size, int csize, int numFiles) {
- out(" -------- -------- -------");
- out(String.format(" %8d %8d %d files", size, csize, numFiles));
- }
-
- private void printName(String s) {
- if (outMode != 0) {
- out(s);
+ private void parseOptions(String command) {
+ if (DEBUG || Debug.isSet()) {
+ outMode |= OUT_DEBUG;
}
- }
-
- private void parseOptions(String command) {
- outMode |= OUT_DEBUG;
+ if (Verbose.isSet()) {
+ outMode |= OUT_NOTICE;
+ }
+ if (Quiet.isSet()) {
+ outMode = 0;
+ }
if (command.equals("zip")) {
if (Delete.isSet()) {
mode = ZIP_DELETE;
@@ -306,7 +345,7 @@
} else if (Update.isSet()) {
mode = ZIP_UPDATE | ZIP_ADD;
} else if (Move.isSet()) {
- mode = ZIP_MOVE;
+ mode = ZIP_MOVE | ZIP_ADD;
} else {
mode = ZIP_ADD;
}
@@ -323,9 +362,10 @@
mode = ZIP_EXTRACT;
}
}
- assert mode != 0 : "Invalid mode";
- switch (mode) {
+ noPath = NoPath.isSet();
+
+ switch (mode & (ZIP_ADD | ZIP_EXTRACT | ZIP_LIST)) {
case ZIP_ADD :
parseFiles();
getArchive(true, false);
@@ -334,14 +374,26 @@
getArchive(false, true);
parseEntries();
break;
- case ZIP_LIST :
+ case ZIP_LIST :
getArchive(false, true);
+ parseEntries();
break;
default :
throw new UnsupportedOperationException("This mode is not implemented.");
}
}
+ /**
+ * Instantiates the archive.
+ *
+ * If zipfile is true, than a ZipFile object for the archive is also created.
+ *
+ * This will exit with an error if:
+ * - The archive does not exist, create is true, but an exception was thrown on creation.
+ * - The archive does not exist, and create is false.
+ * - The archive exists and create is true. (FIXME)
+ * - A ZipFile was requested and there was an exception during instantiation.
+ */
private void getArchive(boolean create, boolean zipfile) {
archive = Archive.getValue();
@@ -354,10 +406,10 @@
try {
archive.createNewFile();
} catch (IOException e) {
- fatal("Could not create archive: " + archive, 1);
+ fatal(fatal_create_arch + archive, 1);
}
} else {
- fatal("Archive required but not found: " + archive, 1);
+ fatal(fatal_req_arch + archive, 1);
}
} else {
if (create) {
@@ -370,18 +422,41 @@
zarchive = new ZipFile(archive);
} catch (IOException e) {
debug(e.getMessage());
- fatal("Unable to open archive as ZipFile: " + archive, 1);
+ fatal(fatal_create_zfile + archive, 1);
}
- assert zarchive != null : "null zarchive";
}
-
- assert archive != null : "null archive after getArchive()";
- assert archive.exists() : "archive does not exist, or was not created";
}
+ private class Walker extends AbstractDirectoryWalker {
+ @Override
+ public void handleFile(final File file) throws IOException {
+ addFile(file);
+ }
+ @Override
+ public void handleDir(final File file) throws IOException {
+ assert !(noDirEntry || noPath) : "handleDir called when noDirEntry || noPath";
+ addFile(file);
+ }
+ }
+
+ /**
+ * Creates a list of files based on the files and filename patterns given
+ * on the command line. If we're using recursion, then a directory walker
+ * is used with the given include/exclude filters if any are in use.
+ *
+ * The -D/-j options prevent directories from being listed.
+ * The -x/-i options are used to add exclude/include patterns.
+ * The -r option turns on recursion
+ *
+ * This will exit with an error if there was an exception while walking.
+ */
private void parseFiles() {
files = new ArrayList<File>();
+ List<File> dirs = new ArrayList<File>();
+ if (filesStdin) {
+ parseFilesStdin();
+ }
if (Patterns.isSet()) {
for (String pattern : Patterns.getValues()) {
if (!PathnamePattern.isPattern(pattern)) {
@@ -391,7 +466,7 @@
continue;
}
if (file.isDirectory()) {
- addDirectory(file);
+ dirs.add(file);
} else {
addFile(file);
}
@@ -401,7 +476,7 @@
for (String name : list) {
File file = new File(name);
if (file.isDirectory()) {
- addDirectory(file);
+ dirs.add(file);
} else {
addFile(file);
}
@@ -409,10 +484,90 @@
}
}
}
+
+ if (recurse && dirs.size() > 0) {
+ Walker walker = new Walker();
+ if (noDirEntry || noPath) {
+ walker.addFilter(new FileFilter() {
+ @Override
+ public boolean accept(File file) {
+ return !file.isDirectory();
+ }
+ });
+ }
+ if (excludes != null && excludes.size() > 0) {
+ for (String pattern : excludes) {
+ walker.addFilter(new PathnamePatternFilter(pattern, true));
+ }
+ }
+ if (includes != null && includes.size() > 0) {
+ for (String pattern : includes) {
+ walker.addFilter(new PathnamePatternFilter(pattern, false));
+ }
+ }
+ if (newer > 0) {
+ walker.addFilter(new ModTimeFilter(newer, true));
+ }
+ if (older > 0) {
+ walker.addFilter(new ModTimeFilter(older, false));
+ }
+ try {
+ walker.walk(dirs);
+ } catch (IOException e) {
+ debug(e.getMessage());
+ fatal(fatal_walking, 1);
+ }
+ }
}
+ /**
+ * Parses files from stdin, one file per line.
+ *
+ * If the file does not exist, it is ignored and omitted.
+ *
+ * This will exit with an error if there is an exception while reading stdin.
+ */
+ private void parseFilesStdin() {
+ LineNumberReader reader = new LineNumberReader(stdinReader);
+ String line;
+ File file;
+
+ try {
+ while ((line = reader.readLine()) != null) {
+ file = new File(line);
+ if (file.exists()) {
+ addFile(file);
+ }
+ }
+ } catch (IOException e) {
+ fatal(fatal_read_stdin, 1);
+ }
+ }
+
+ /**
+ * Adds a file to the list of files.
+ *
+ * If the -j option is used, then the list is scanned for the file name.
+ * This is done because -j strips the path from the pathname, which can cause
+ * collisions if two files from separate directories with the same name are added.
+ */
+ private void addFile(File file) {
+ if (noPath) {
+ // this isn't effecient by any means, but this is not an often-used
+ // case, and when it is, its not likely that files.size() is going
+ // to grow very large.
+ for (File f : files) {
+ if (f.getName().equals(file.getName())) {
+ printDuplicateError(file, f);
+ fatal(fatal_inv_args, 1);
+ }
+ }
+ }
+ files.add(file);
+ }
+
+ @SuppressWarnings("unchecked")
private void parseEntries() {
- assert zarchive != null : "null archive in parseEntries";
int count = 0;
ZipEntry entry;
@@ -429,30 +584,34 @@
fileEntries.add(entry);
}
}
-
- assert count == (fileEntries.size() + dirEntries.size());
}
-
- private void addDirectory(File dir) {
- if (!recurse) {
- return;
- }
- files.add(dir);
-
- for (File file : dir.listFiles()) {
- if (file.isDirectory()) {
- addDirectory(file);
- } else {
-
- addFile(file);
- }
- }
+
+ private void printListHeader() {
+ out(str_header_1);
+ out(str_header_2);
}
- private void addFile(File file) {
- files.add(file);
+ private void printListEntry(ZipEntry entry) {
+ out(String.format(fmt_entry, entry.getSize(), entry.getCompressedSize(), entry.getMethod(), entry.getName()));
}
+ private void printListFooter(int size, int csize, int numFiles) {
+ out(str_footer);
+ out(String.format(fmt_footer, size, csize, numFiles));
+ }
+
+ private void printDuplicateError(File A, File B) {
+ error(String.format(fmt_warn_dup, str_zip_warn, str_fullname_1, A.getPath()));
+ error(String.format(fmt_warn_dup, str_zip_warn, str_fullname_2, B.getPath()));
+ error(String.format(fmt_warn_dup, str_zip_warn, str_name_repeat, A.getName()));
+ }
+
+ private void printName(String s) {
+ if (outMode != 0) {
+ out(s);
+ }
+ }
+
private void debug(ZipEntry entry) {
debug("Name: " + entry.getName());
debug("Directory: " + entry.isDirectory());
Modified: trunk/fs/src/fs/org/jnode/fs/command/archive/ZipCommand.java
===================================================================
--- trunk/fs/src/fs/org/jnode/fs/command/archive/ZipCommand.java 2009-04-16 20:37:00 UTC (rev 5294)
+++ trunk/fs/src/fs/org/jnode/fs/command/archive/ZipCommand.java 2009-04-16 21:26:19 UTC (rev 5295)
@@ -20,6 +20,9 @@
package org.jnode.fs.command.archive;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.ArrayList;
import org.jnode.shell.syntax.Argument;
import org.jnode.shell.syntax.FlagArgument;
import org.jnode.shell.syntax.FileArgument;
@@ -37,7 +40,12 @@
private static final String help_recurse = "recurse into directories";
private static final String help_newer_than = "only include files newer than the specified time";
private static final String help_older_than = "only include files older than the specified time";
+ private static final String help_exclude = "do not includes files matching a pattern";
+ private static final String help_include = "only includes files matching a pattern";
+ private static final String fatal_bad_newer = "Invalid newer-than date: ";
+ private static final String fatal_bad_older = "Invalid older-than date: ";
+
private final FlagArgument FilesStdin;
private final FlagArgument NoDirEntry;
private final FlagArgument Recurse;
@@ -45,6 +53,8 @@
private final StringArgument NoCompress;
private final StringArgument NewerThan;
private final StringArgument OlderThan;
+ private final StringArgument Exclude;
+ private final StringArgument Include;
public ZipCommand() {
super("compress files into a zip archive");
@@ -56,11 +66,13 @@
FilesStdin = new FlagArgument("files-stdin", Argument.OPTIONAL, help_files_stdin);
NoDirEntry = new FlagArgument("no-dirs", Argument.OPTIONAL, help_no_dir);
Recurse = new FlagArgument("recurse", Argument.OPTIONAL, help_recurse);
- TmpDir = new FileArgument("tmp-dir", Argument.OPTIONAL, help_tmpdir);
+ TmpDir = new FileArgument("tmp-dir", Argument.OPTIONAL | Argument.EXISTING, help_tmpdir);
NoCompress = new StringArgument("no-compress", Argument.OPTIONAL, help_no_compress);
NewerThan = new StringArgument("newer", Argument.OPTIONAL, help_newer_than);
OlderThan = new StringArgument("older", Argument.OPTIONAL, help_older_than);
- registerArguments(FilesStdin, TmpDir, NoDirEntry, NoCompress, Recurse, NewerThan, OlderThan);
+ Exclude = new StringArgument("exclude", Argument.OPTIONAL | Argument.MULTIPLE, help_exclude);
+ Include = new StringArgument("include", Argument.OPTIONAL | Argument.MULTIPLE, help_include);
+ registerArguments(FilesStdin, TmpDir, NoDirEntry, NoCompress, Recurse, NewerThan, OlderThan, Exclude, Include);
}
@Override
@@ -68,9 +80,40 @@
recurse = Recurse.isSet();
noDirEntry = NoDirEntry.isSet();
filesStdin = FilesStdin.isSet();
- if (NoCompress.isSet()) noCompress = NoCompress.getValue();
if (TmpDir.isSet()) tmpDir = TmpDir.getValue();
-
+ /* FIXME
+ if (NewerThan.isSet()) {
+ try {
+ newer = DateFormat.getInstance().parse(NewerThan.getValue()).getTime();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ exit(1);
+ }
+ }
+ if (OlderThan.isSet()) {
+ try {
+ older = DateFormat.getInstance().parse(OlderThan.getValue()).getTime();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ exit(1);
+ }
+ }
+ */
+ if (NoCompress.isSet()) {
+ noCompress = NoCompress.getValue().split(":");
+ }
+ if (Exclude.isSet()) {
+ excludes = new ArrayList<String>(Exclude.getValues().length);
+ for (String pattern : Exclude.getValues()) {
+ excludes.add(pattern);
+ }
+ }
+ if (Include.isSet()) {
+ includes = new ArrayList<String>(Include.getValues().length);
+ for (String pattern : Include.getValues()) {
+ includes.add(pattern);
+ }
+ }
super.execute("zip");
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|