* extracted format specific stuff from VerificationFileScanner and VerificationFilePrinter into VerificationFormat

This commit is contained in:
Reinhard Pointner 2009-05-16 20:16:13 +00:00
parent a8b3e13339
commit 905cb49d31
13 changed files with 208 additions and 245 deletions

View File

@ -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<File, String> 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<File, String> entry = scanner.next();
if (file.getName().equals(entry.getKey().getPath())) {
return entry.getValue();
}
}
} finally {

View File

@ -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() {

View File

@ -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);
}
}

View File

@ -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));
}
}

View File

@ -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.
*
* <pre>
* Sample:
* folder/file.txt 970E4EF1
* | Group 1 | | Gr.2 |
* </pre>
*/
private final Pattern pattern = Pattern.compile("(.+)\\s+(\\p{XDigit}{8})");
@Override
protected Entry<File, String> 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));
}
}

View File

@ -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.
*
* <pre>
* Sample:
* folder/file.txt 970E4EF1
* | Group 1 | | Gr.2 |
* </pre>
*/
private final Pattern pattern = Pattern.compile("(.+)\\s+(\\p{XDigit}{8})");
@Override
public Entry<File, String> 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));
}
}

View File

@ -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();
}
}

View File

@ -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<Entry<File, String>>, Closeable {
private final Scanner scanner;
private String cache;
private final VerificationFormat format;
private Entry<File, String> 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<File, String> next() throws IllegalSyntaxException {
// cache next line
public Entry<File, String> 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<File, String> nextEntry() {
Entry<File, String> 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.
*
* <pre>
* Sample MD5:
* 50e85fe18e17e3616774637a82968f4c *folder/file.txt
* | Group 1 | Group 2 |
*
* Sample SHA-1:
* 1a02a7c1e9ac91346d08829d5037b240f42ded07 ?SHA1*folder/file.txt
* | Group 1 | | Group 2 |
* </pre>
*/
private final Pattern pattern = Pattern.compile("(\\p{XDigit}+)\\s+(?:\\?\\w+)?\\*?(.+)");
protected Entry<File, String> 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<Entry<File, String>>, C
}
protected Entry<File, String> entry(File file, String hash) {
return new SimpleEntry<File, String>(file, hash);
}
@Override
public void close() throws IOException {
scanner.close();

View File

@ -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<File, String> entry = (Entry<File, String>) 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.
*
* <pre>
* Sample MD5:
* 50e85fe18e17e3616774637a82968f4c *folder/file.txt
* | Group 1 | Group 2 |
*
* Sample SHA-1:
* 1a02a7c1e9ac91346d08829d5037b240f42ded07 ?SHA1*folder/file.txt
* | Group 1 | | Group 2 |
* </pre>
*/
private final Pattern pattern = Pattern.compile("(\\p{XDigit}+)\\s+(?:\\?\\w+)?\\*?(.+)");
@Override
public Entry<File, String> 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<File, String> parseObject(String line, ParsePosition pos) {
throw new UnsupportedOperationException();
}
protected Entry<File, String> entry(String path, String hash) {
return new SimpleImmutableEntry<File, String>(new File(path), hash);
}
}

View File

@ -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);
}
}

View File

@ -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));
}
}
}

View File

@ -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<C
protected void loadVerificationFile(File file, HashType type) throws IOException {
// don't use new Scanner(File) because of BUG 6368019 (http://bugs.sun.com/view_bug.do?bug_id=6368019)
VerificationFileScanner scanner = type.newScanner(new Scanner(new FileInputStream(file), "UTF-8"));
VerificationFileScanner scanner = new VerificationFileScanner(file, type.getFormat());
try {
// root for relative file paths in verification file
File root = file.getParentFile();
while (scanner.hasNext()) {
try {
Entry<File, String> 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<File, String> 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 {

View File

@ -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());
}