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. |