From 905cb49d3145c531c2bb7db480a54eb1e1d78878 Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Sat, 16 May 2009 20:16:13 +0000 Subject: [PATCH] * extracted format specific stuff from VerificationFileScanner and VerificationFilePrinter into VerificationFormat --- .../format/EpisodeFormatBindingBean.java | 20 ++--- .../sourceforge/filebot/hash/HashType.java | 40 +++------ .../filebot/hash/IllegalSyntaxException.java | 16 ---- .../filebot/hash/SfvFilePrinter.java | 20 ----- .../filebot/hash/SfvFileScanner.java | 46 ---------- .../sourceforge/filebot/hash/SfvFormat.java | 43 ++++++++++ .../filebot/hash/VerificationFilePrinter.java | 33 ------- .../filebot/hash/VerificationFileScanner.java | 86 ++++++++----------- .../filebot/hash/VerificationFormat.java | 86 +++++++++++++++++++ .../filebot/ui/FileBotListExportHandler.java | 6 +- .../panel/sfv/ChecksumTableExportHandler.java | 13 ++- .../sfv/ChecksumTableTransferablePolicy.java | 34 +++----- .../ui/transfer/TextFileExportHandler.java | 10 +-- 13 files changed, 208 insertions(+), 245 deletions(-) delete mode 100644 source/net/sourceforge/filebot/hash/IllegalSyntaxException.java delete mode 100644 source/net/sourceforge/filebot/hash/SfvFilePrinter.java delete mode 100644 source/net/sourceforge/filebot/hash/SfvFileScanner.java create mode 100644 source/net/sourceforge/filebot/hash/SfvFormat.java delete mode 100644 source/net/sourceforge/filebot/hash/VerificationFilePrinter.java create mode 100644 source/net/sourceforge/filebot/hash/VerificationFormat.java diff --git a/source/net/sourceforge/filebot/format/EpisodeFormatBindingBean.java b/source/net/sourceforge/filebot/format/EpisodeFormatBindingBean.java index e700b14a..112edf45 100644 --- a/source/net/sourceforge/filebot/format/EpisodeFormatBindingBean.java +++ b/source/net/sourceforge/filebot/format/EpisodeFormatBindingBean.java @@ -13,16 +13,14 @@ import java.io.IOException; import java.io.InputStream; import java.util.Scanner; import java.util.Map.Entry; -import java.util.logging.Level; -import java.util.logging.Logger; import java.util.zip.CRC32; import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Element; import net.sourceforge.filebot.FileBotUtilities; -import net.sourceforge.filebot.hash.IllegalSyntaxException; -import net.sourceforge.filebot.hash.SfvFileScanner; +import net.sourceforge.filebot.hash.SfvFormat; +import net.sourceforge.filebot.hash.VerificationFileScanner; import net.sourceforge.filebot.mediainfo.MediaInfo; import net.sourceforge.filebot.mediainfo.MediaInfo.StreamKind; import net.sourceforge.filebot.web.Episode; @@ -261,18 +259,14 @@ public class EpisodeFormatBindingBean { File folder = file.getParentFile(); for (File sfvFile : folder.listFiles(SFV_FILES)) { - SfvFileScanner scanner = new SfvFileScanner(sfvFile); + VerificationFileScanner scanner = new VerificationFileScanner(sfvFile, new SfvFormat()); try { while (scanner.hasNext()) { - try { - Entry entry = scanner.next(); - - if (file.getName().equals(entry.getKey().getPath())) { - return entry.getValue(); - } - } catch (IllegalSyntaxException e) { - Logger.getLogger("global").log(Level.WARNING, e.getMessage()); + Entry entry = scanner.next(); + + if (file.getName().equals(entry.getKey().getPath())) { + return entry.getValue(); } } } finally { diff --git a/source/net/sourceforge/filebot/hash/HashType.java b/source/net/sourceforge/filebot/hash/HashType.java index 2a94f54f..0050d195 100644 --- a/source/net/sourceforge/filebot/hash/HashType.java +++ b/source/net/sourceforge/filebot/hash/HashType.java @@ -2,8 +2,6 @@ package net.sourceforge.filebot.hash; -import java.util.Formatter; -import java.util.Scanner; import java.util.zip.CRC32; @@ -18,14 +16,9 @@ public enum HashType { @Override - public VerificationFileScanner newScanner(Scanner scanner) { - return new SfvFileScanner(scanner); - } - - - @Override - public VerificationFilePrinter newPrinter(Formatter out) { - return new SfvFilePrinter(out); + public VerificationFormat getFormat() { + // e.g folder/file.txt 970E4EF1 + return new SfvFormat(); } }, @@ -39,16 +32,11 @@ public enum HashType { @Override - public VerificationFileScanner newScanner(Scanner scanner) { - return new VerificationFileScanner(scanner); + public VerificationFormat getFormat() { + // e.g. 50e85fe18e17e3616774637a82968f4c *folder/file.txt + return new VerificationFormat(); } - - @Override - public VerificationFilePrinter newPrinter(Formatter out) { - // e.g. 50e85fe18e17e3616774637a82968f4c *folder/file.txt - return new VerificationFilePrinter(out, null); - } }, SHA1 { @@ -60,15 +48,9 @@ public enum HashType { @Override - public VerificationFileScanner newScanner(Scanner scanner) { - return new VerificationFileScanner(scanner); - } - - - @Override - public VerificationFilePrinter newPrinter(Formatter out) { + public VerificationFormat getFormat() { // e.g 1a02a7c1e9ac91346d08829d5037b240f42ded07 ?SHA1*folder/file.txt - return new VerificationFilePrinter(out, "SHA1"); + return new VerificationFormat("SHA1"); } @@ -76,15 +58,13 @@ public enum HashType { public String toString() { return "SHA-1"; } + }; public abstract Hash newHash(); - public abstract VerificationFileScanner newScanner(Scanner scanner); - - - public abstract VerificationFilePrinter newPrinter(Formatter out); + public abstract VerificationFormat getFormat(); public String getExtension() { diff --git a/source/net/sourceforge/filebot/hash/IllegalSyntaxException.java b/source/net/sourceforge/filebot/hash/IllegalSyntaxException.java deleted file mode 100644 index 30dc83c3..00000000 --- a/source/net/sourceforge/filebot/hash/IllegalSyntaxException.java +++ /dev/null @@ -1,16 +0,0 @@ - -package net.sourceforge.filebot.hash; - - -public class IllegalSyntaxException extends RuntimeException { - - public IllegalSyntaxException(int lineNumber, String line) { - this(String.format("Illegal syntax in line %d: %s", lineNumber, line)); - } - - - public IllegalSyntaxException(String message) { - super(message); - } - -} diff --git a/source/net/sourceforge/filebot/hash/SfvFilePrinter.java b/source/net/sourceforge/filebot/hash/SfvFilePrinter.java deleted file mode 100644 index 2a7913b1..00000000 --- a/source/net/sourceforge/filebot/hash/SfvFilePrinter.java +++ /dev/null @@ -1,20 +0,0 @@ - -package net.sourceforge.filebot.hash; - - -import java.util.Formatter; - - -public class SfvFilePrinter extends VerificationFilePrinter { - - public SfvFilePrinter(Formatter out) { - super(out, "CRC32"); - } - - - @Override - public void println(String path, String hash) { - // e.g folder/file.txt 970E4EF1 - out.format(String.format("%s %s%n", path, hash)); - } -} diff --git a/source/net/sourceforge/filebot/hash/SfvFileScanner.java b/source/net/sourceforge/filebot/hash/SfvFileScanner.java deleted file mode 100644 index 034eb407..00000000 --- a/source/net/sourceforge/filebot/hash/SfvFileScanner.java +++ /dev/null @@ -1,46 +0,0 @@ - -package net.sourceforge.filebot.hash; - - -import java.io.File; -import java.io.FileNotFoundException; -import java.util.Scanner; -import java.util.Map.Entry; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - - -public class SfvFileScanner extends VerificationFileScanner { - - public SfvFileScanner(File file) throws FileNotFoundException { - super(file); - } - - - public SfvFileScanner(Scanner scanner) { - super(scanner); - } - - /** - * Pattern used to parse the lines of a sfv file. - * - *
-	 * Sample:
-	 * folder/file.txt 970E4EF1
-	 * |  Group 1    | | Gr.2 |
-	 * 
- */ - private final Pattern pattern = Pattern.compile("(.+)\\s+(\\p{XDigit}{8})"); - - - @Override - protected Entry parseLine(String line) throws IllegalSyntaxException { - Matcher matcher = pattern.matcher(line); - - if (!matcher.matches()) - throw new IllegalSyntaxException(getLineNumber(), line); - - return entry(new File(matcher.group(1)), matcher.group(2)); - } - -} diff --git a/source/net/sourceforge/filebot/hash/SfvFormat.java b/source/net/sourceforge/filebot/hash/SfvFormat.java new file mode 100644 index 00000000..9aa27560 --- /dev/null +++ b/source/net/sourceforge/filebot/hash/SfvFormat.java @@ -0,0 +1,43 @@ + +package net.sourceforge.filebot.hash; + + +import java.io.File; +import java.text.ParseException; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class SfvFormat extends VerificationFormat { + + @Override + public String format(String path, String hash) { + // e.g folder/file.txt 970E4EF1 + return String.format("%s %s", path, hash); + } + + /** + * Pattern used to parse the lines of a sfv file. + * + *
+	 * Sample:
+	 * folder/file.txt 970E4EF1
+	 * |  Group 1    | | Gr.2 |
+	 * 
+ */ + private final Pattern pattern = Pattern.compile("(.+)\\s+(\\p{XDigit}{8})"); + + + @Override + public Entry parseObject(String line) throws ParseException { + Matcher matcher = pattern.matcher(line); + + if (!matcher.matches()) { + throw new ParseException("Illegal input pattern", 0); + } + + return entry(matcher.group(1), matcher.group(2)); + } + +} diff --git a/source/net/sourceforge/filebot/hash/VerificationFilePrinter.java b/source/net/sourceforge/filebot/hash/VerificationFilePrinter.java deleted file mode 100644 index 4f696456..00000000 --- a/source/net/sourceforge/filebot/hash/VerificationFilePrinter.java +++ /dev/null @@ -1,33 +0,0 @@ - -package net.sourceforge.filebot.hash; - - -import java.io.Closeable; -import java.io.IOException; -import java.util.Formatter; - - -public class VerificationFilePrinter implements Closeable { - - protected final Formatter out; - protected final String algorithm; - - - public VerificationFilePrinter(Formatter out, String algorithm) { - this.out = out; - this.algorithm = algorithm; - } - - - public void println(String path, String hash) { - // e.g. 1a02a7c1e9ac91346d08829d5037b240f42ded07 ?SHA1*folder/file.txt - out.format("%s %s*%s%n", hash, algorithm == null ? "" : '?' + algorithm.toUpperCase(), path); - } - - - @Override - public void close() throws IOException { - out.close(); - } - -} diff --git a/source/net/sourceforge/filebot/hash/VerificationFileScanner.java b/source/net/sourceforge/filebot/hash/VerificationFileScanner.java index fcd8750b..aaa67c56 100644 --- a/source/net/sourceforge/filebot/hash/VerificationFileScanner.java +++ b/source/net/sourceforge/filebot/hash/VerificationFileScanner.java @@ -7,97 +7,86 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.text.ParseException; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Scanner; -import java.util.AbstractMap.SimpleEntry; import java.util.Map.Entry; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.logging.Level; +import java.util.logging.Logger; public class VerificationFileScanner implements Iterator>, Closeable { private final Scanner scanner; - private String cache; + private final VerificationFormat format; + + private Entry buffer; private int lineNumber = 0; - public VerificationFileScanner(File file) throws FileNotFoundException { + public VerificationFileScanner(File file, VerificationFormat format) throws FileNotFoundException { // don't use new Scanner(File) because of BUG 6368019 (http://bugs.sun.com/view_bug.do?bug_id=6368019) - this(new Scanner(new FileInputStream(file), "UTF-8")); + this(new Scanner(new FileInputStream(file), "UTF-8"), format); } - public VerificationFileScanner(Scanner scanner) { + public VerificationFileScanner(Scanner scanner, VerificationFormat format) { this.scanner = scanner; + this.format = format; } @Override public boolean hasNext() { - if (cache == null) { - // cache next line - cache = nextLine(); + if (buffer == null) { + // cache next entry + buffer = nextEntry(); } - return cache != null; + return buffer != null; } @Override - public Entry next() throws IllegalSyntaxException { - // cache next line + public Entry next() { + // cache next entry if (!hasNext()) { throw new NoSuchElementException(); } try { - return parseLine(cache); + return buffer; } finally { // invalidate cache - cache = null; + buffer = null; } } - protected String nextLine() { - String line = null; + protected Entry nextEntry() { + Entry entry = null; - // get next non-comment line - while (scanner.hasNext() && (line == null || isComment(line))) { - line = scanner.nextLine().trim(); + // get next valid entry + while (entry == null && scanner.hasNextLine()) { + String line = scanner.nextLine().trim(); + + // ignore comments + if (!isComment(line)) { + try { + entry = format.parseObject(line); + } catch (ParseException e) { + // log and ignore + Logger.getLogger(getClass().getName()).log(Level.WARNING, String.format("Illegal format on line %d: %s", lineNumber, line)); + } + } + lineNumber++; } - return line; - } - - /** - * Pattern used to parse the lines of a md5 or sha1 file. - * - *
-	 * Sample MD5:
-	 * 50e85fe18e17e3616774637a82968f4c *folder/file.txt
-	 * |           Group 1               |   Group 2   |
-	 * 
-	 * Sample SHA-1:
-	 * 1a02a7c1e9ac91346d08829d5037b240f42ded07 ?SHA1*folder/file.txt
-	 * |               Group 1                |       |   Group 2   |
-	 * 
- */ - private final Pattern pattern = Pattern.compile("(\\p{XDigit}+)\\s+(?:\\?\\w+)?\\*?(.+)"); - - - protected Entry parseLine(String line) throws IllegalSyntaxException { - Matcher matcher = pattern.matcher(line); - - if (!matcher.matches()) - throw new IllegalSyntaxException(getLineNumber(), line); - - return entry(new File(matcher.group(2)), matcher.group(1)); + return entry; } @@ -111,11 +100,6 @@ public class VerificationFileScanner implements Iterator>, C } - protected Entry entry(File file, String hash) { - return new SimpleEntry(file, hash); - } - - @Override public void close() throws IOException { scanner.close(); diff --git a/source/net/sourceforge/filebot/hash/VerificationFormat.java b/source/net/sourceforge/filebot/hash/VerificationFormat.java new file mode 100644 index 00000000..9ac1ab28 --- /dev/null +++ b/source/net/sourceforge/filebot/hash/VerificationFormat.java @@ -0,0 +1,86 @@ + +package net.sourceforge.filebot.hash; + + +import java.io.File; +import java.text.FieldPosition; +import java.text.Format; +import java.text.ParseException; +import java.text.ParsePosition; +import java.util.AbstractMap.SimpleImmutableEntry; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class VerificationFormat extends Format { + + private final String hashTypeHint; + + + public VerificationFormat() { + this.hashTypeHint = ""; + } + + + public VerificationFormat(String hashTypeHint) { + this.hashTypeHint = hashTypeHint.isEmpty() ? "" : '?' + hashTypeHint.toUpperCase(); + } + + + @Override + public StringBuffer format(Object obj, StringBuffer sb, FieldPosition pos) { + @SuppressWarnings("unchecked") + Entry entry = (Entry) obj; + + String path = entry.getKey().getPath(); + String hash = entry.getValue(); + + return sb.append(format(path, hash)); + } + + + public String format(String path, String hash) { + // e.g. 1a02a7c1e9ac91346d08829d5037b240f42ded07 ?SHA1*folder/file.txt + return String.format("%s %s*%s", hash, hashTypeHint, path); + } + + /** + * Pattern used to parse the lines of a md5 or sha1 file. + * + *
+	 * Sample MD5:
+	 * 50e85fe18e17e3616774637a82968f4c *folder/file.txt
+	 * |           Group 1               |   Group 2   |
+	 * 
+	 * Sample SHA-1:
+	 * 1a02a7c1e9ac91346d08829d5037b240f42ded07 ?SHA1*folder/file.txt
+	 * |               Group 1                |       |   Group 2   |
+	 * 
+ */ + private final Pattern pattern = Pattern.compile("(\\p{XDigit}+)\\s+(?:\\?\\w+)?\\*?(.+)"); + + + @Override + public Entry parseObject(String line) throws ParseException { + Matcher matcher = pattern.matcher(line); + + if (!matcher.find()) { + throw new ParseException("Illegal input pattern", 0); + } + + return entry(matcher.group(2), matcher.group(1)); + } + + + @Override + public Entry parseObject(String line, ParsePosition pos) { + throw new UnsupportedOperationException(); + } + + + protected Entry entry(String path, String hash) { + return new SimpleImmutableEntry(new File(path), hash); + } + +} diff --git a/source/net/sourceforge/filebot/ui/FileBotListExportHandler.java b/source/net/sourceforge/filebot/ui/FileBotListExportHandler.java index 16176cdd..3c3cbdc7 100644 --- a/source/net/sourceforge/filebot/ui/FileBotListExportHandler.java +++ b/source/net/sourceforge/filebot/ui/FileBotListExportHandler.java @@ -2,7 +2,7 @@ package net.sourceforge.filebot.ui; -import java.util.Formatter; +import java.io.PrintWriter; import net.sourceforge.filebot.ui.transfer.TextFileExportHandler; @@ -24,9 +24,9 @@ public class FileBotListExportHandler extends TextFileExportHandler { @Override - public void export(Formatter out) { + public void export(PrintWriter out) { for (Object entry : list.getModel()) { - out.format("%s%n", entry); + out.println(entry); } } diff --git a/source/net/sourceforge/filebot/ui/panel/sfv/ChecksumTableExportHandler.java b/source/net/sourceforge/filebot/ui/panel/sfv/ChecksumTableExportHandler.java index e56dd423..072cdea5 100644 --- a/source/net/sourceforge/filebot/ui/panel/sfv/ChecksumTableExportHandler.java +++ b/source/net/sourceforge/filebot/ui/panel/sfv/ChecksumTableExportHandler.java @@ -6,11 +6,10 @@ import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.Date; -import java.util.Formatter; import net.sourceforge.filebot.Settings; import net.sourceforge.filebot.hash.HashType; -import net.sourceforge.filebot.hash.VerificationFilePrinter; +import net.sourceforge.filebot.hash.VerificationFormat; import net.sourceforge.filebot.ui.transfer.TextFileExportHandler; import net.sourceforge.tuned.FileUtilities; @@ -32,7 +31,7 @@ class ChecksumTableExportHandler extends TextFileExportHandler { @Override - public void export(Formatter out) { + public void export(PrintWriter out) { export(out, defaultColumn()); } @@ -58,14 +57,14 @@ class ChecksumTableExportHandler extends TextFileExportHandler { PrintWriter out = new PrintWriter(file, "UTF-8"); try { - export(new Formatter(out), column); + export(out, column); } finally { out.close(); } } - public void export(Formatter out, File column) { + public void export(PrintWriter out, File column) { HashType hashType = model.getHashType(); // print header @@ -74,7 +73,7 @@ class ChecksumTableExportHandler extends TextFileExportHandler { out.format(";%n"); // print data - VerificationFilePrinter printer = hashType.newPrinter(out); + VerificationFormat format = hashType.getFormat(); for (ChecksumRow row : model.rows()) { ChecksumCell cell = row.getChecksum(column); @@ -83,7 +82,7 @@ class ChecksumTableExportHandler extends TextFileExportHandler { String hash = cell.getChecksum(hashType); if (hash != null) { - printer.println(cell.getName(), hash); + out.println(format.format(cell.getName(), hash)); } } } diff --git a/source/net/sourceforge/filebot/ui/panel/sfv/ChecksumTableTransferablePolicy.java b/source/net/sourceforge/filebot/ui/panel/sfv/ChecksumTableTransferablePolicy.java index b2bafd12..62a9a004 100644 --- a/source/net/sourceforge/filebot/ui/panel/sfv/ChecksumTableTransferablePolicy.java +++ b/source/net/sourceforge/filebot/ui/panel/sfv/ChecksumTableTransferablePolicy.java @@ -5,18 +5,15 @@ package net.sourceforge.filebot.ui.panel.sfv; import static net.sourceforge.tuned.FileUtilities.containsOnly; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.util.Collections; import java.util.List; -import java.util.Scanner; import java.util.Map.Entry; import java.util.concurrent.ExecutorService; import java.util.logging.Level; import java.util.logging.Logger; import net.sourceforge.filebot.hash.HashType; -import net.sourceforge.filebot.hash.IllegalSyntaxException; import net.sourceforge.filebot.hash.VerificationFileScanner; import net.sourceforge.filebot.ui.transfer.BackgroundFileTransferablePolicy; import net.sourceforge.tuned.ExceptionUtilities; @@ -85,30 +82,25 @@ class ChecksumTableTransferablePolicy extends BackgroundFileTransferablePolicy entry = scanner.next(); - - String name = normalizeRelativePath(entry.getKey()); - String hash = entry.getValue(); - - ChecksumCell correct = new ChecksumCell(name, file, Collections.singletonMap(type, hash)); - ChecksumCell current = createComputationCell(name, root, type); - - publish(correct, current); - - if (Thread.interrupted()) { - break; - } - } catch (IllegalSyntaxException e) { - // tell user about illegal lines in verification file - publish(e); + Entry entry = scanner.next(); + + String name = normalizeRelativePath(entry.getKey()); + String hash = entry.getValue(); + + ChecksumCell correct = new ChecksumCell(name, file, Collections.singletonMap(type, hash)); + ChecksumCell current = createComputationCell(name, root, type); + + publish(correct, current); + + if (Thread.interrupted()) { + break; } } } finally { diff --git a/source/net/sourceforge/filebot/ui/transfer/TextFileExportHandler.java b/source/net/sourceforge/filebot/ui/transfer/TextFileExportHandler.java index b356d7de..7a21a2b9 100644 --- a/source/net/sourceforge/filebot/ui/transfer/TextFileExportHandler.java +++ b/source/net/sourceforge/filebot/ui/transfer/TextFileExportHandler.java @@ -6,7 +6,7 @@ import java.awt.datatransfer.Transferable; import java.io.File; import java.io.IOException; import java.io.PrintWriter; -import java.util.Formatter; +import java.io.StringWriter; import javax.swing.JComponent; import javax.swing.TransferHandler; @@ -17,7 +17,7 @@ public abstract class TextFileExportHandler implements TransferableExportHandler public abstract boolean canExport(); - public abstract void export(Formatter out); + public abstract void export(PrintWriter out); public abstract String getDefaultFileName(); @@ -28,7 +28,7 @@ public abstract class TextFileExportHandler implements TransferableExportHandler PrintWriter out = new PrintWriter(file, "UTF-8"); try { - export(new Formatter(out)); + export(out); } finally { out.close(); } @@ -47,8 +47,8 @@ public abstract class TextFileExportHandler implements TransferableExportHandler @Override public Transferable createTransferable(JComponent c) { // get transfer data - StringBuilder buffer = new StringBuilder(); - export(new Formatter(buffer)); + StringWriter buffer = new StringWriter(); + export(new PrintWriter(buffer)); return new LazyTextFileTransferable(buffer.toString(), getDefaultFileName()); }