diff --git a/fotolib2/src/main/java/de/k3b/io/FileCommandLogger.java b/fotolib2/src/main/java/de/k3b/io/FileCommandLogger.java index 10407c7e..b95c31e4 100644 --- a/fotolib2/src/main/java/de/k3b/io/FileCommandLogger.java +++ b/fotolib2/src/main/java/de/k3b/io/FileCommandLogger.java @@ -20,7 +20,6 @@ package de.k3b.io; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; @@ -44,11 +43,11 @@ public void openLogfile() { if (mLogFilePath != null) { OutputStream stream = null; try { - File logFile = new File(mLogFilePath); + IFile logFile = FileFacade.convert(new File(mLogFilePath)); if (logFile.exists()) { // open existing in append mode long ageInHours = (new Date().getTime() - logFile.lastModified()) / (1000 * 60 * 60); - stream = new FileOutputStream(logFile, true); + stream = logFile.openOutputStream(); mLogFile = new PrintWriter(stream, true); if (ageInHours > 15) { @@ -57,7 +56,7 @@ public void openLogfile() { } } else { // create new - mLogFile = new PrintWriter(logFile, "UTF-8"); + mLogFile = new PrintWriter(logFile.openOutputStream()); log("rem " , new Date()); } } catch (Throwable e) { diff --git a/fotolib2/src/main/java/de/k3b/io/FileCommands.java b/fotolib2/src/main/java/de/k3b/io/FileCommands.java index d6a8e7b1..eb74fb52 100644 --- a/fotolib2/src/main/java/de/k3b/io/FileCommands.java +++ b/fotolib2/src/main/java/de/k3b/io/FileCommands.java @@ -172,7 +172,7 @@ public int applyExifChanges(boolean move, PhotoPropertiesDiffCopy exifChanges, S * @param selectedFiles * @param destDirFolder where files are moved/copied to * @param progessListener */ - public int moveOrCopyFilesTo(boolean move, SelectedFiles selectedFiles, File destDirFolder, IProgessListener progessListener) { + public int moveOrCopyFilesTo(boolean move, SelectedFiles selectedFiles, IFile destDirFolder, IProgessListener progessListener) { PhotoAutoprocessingDto autoProccessData = (!LibGlobal.apmEnabled) ? null : getPhotoAutoprocessingDto(destDirFolder); return moveOrCopyFilesTo(move, selectedFiles, destDirFolder, autoProccessData, progessListener); @@ -187,7 +187,7 @@ public int moveOrCopyFilesTo(boolean move, SelectedFiles selectedFiles, File des * @param destDirFolder where files are moved/copied to * @param autoProccessData null or data for auto rename/exif data * @param progessListener */ - public int moveOrCopyFilesTo(boolean move, SelectedFiles selectedFiles, File destDirFolder, + public int moveOrCopyFilesTo(boolean move, SelectedFiles selectedFiles, IFile destDirFolder, PhotoAutoprocessingDto autoProccessData, IProgessListener progessListener) { boolean doNotRenameIfSourceInDestFolder = false; IFileNameProcessor renameProcessor = null; @@ -218,11 +218,11 @@ public int moveOrCopyFilesTo(boolean move, SelectedFiles selectedFiles, File des */ int moveOrCopyFilesTo(boolean move, PhotoPropertiesDiffCopy exifChanges, SelectedFiles selectedFiles, IFileNameProcessor renameProcessor, - File destDirFolder, IProgessListener progessListener) { + IFile destDirFolder, IProgessListener progessListener) { int result = 0; if (canProcessFile(move ? OP_MOVE : OP_COPY)) { if (osCreateDirIfNeccessary(destDirFolder)) { - File[] destFiles = createDestFiles(renameProcessor, destDirFolder, selectedFiles.getDatesPhotoTaken() , selectedFiles.getFiles()); + IFile[] destFiles = createDestFiles(renameProcessor, destDirFolder, selectedFiles.getDatesPhotoTaken(), selectedFiles.getIFiles()); result = moveOrCopyFiles(move, (move ? "mov" : "copy"), exifChanges, selectedFiles, destFiles, progessListener); @@ -275,7 +275,7 @@ protected TransactionLoggerBase createTransactionLogger(long now) { return new TransactionLoggerBase(this, now); } - private PhotoAutoprocessingDto getPhotoAutoprocessingDto(File destDirFolder) { + private PhotoAutoprocessingDto getPhotoAutoprocessingDto(IFile destDirFolder) { PhotoAutoprocessingDto autoProccessData = null; try { autoProccessData = new PhotoAutoprocessingDto().load(destDirFolder); @@ -290,16 +290,16 @@ public PhotoPropertiesBulkUpdateService createWorkflow(TransactionLoggerBase log return new PhotoPropertiesBulkUpdateService(logger); } - private File[] createDestFiles(IFileNameProcessor renameProcessor, File destDirFolder, Date[] datesLastModified, File... sourceFiles) { - File[] result = new File[sourceFiles.length]; + private IFile[] createDestFiles(IFileNameProcessor renameProcessor, IFile destDirFolder, Date[] datesLastModified, IFile... sourceFiles) { + IFile[] result = new IFile[sourceFiles.length]; int pos = 0; - File destFile; - for (File srcFile : sourceFiles) { + IFile destFile; + for (IFile srcFile : sourceFiles) { if (renameProcessor != null) { destFile = renameProcessor.getNextFile(srcFile, getRenameSourceFileDate(srcFile, datesLastModified, pos), -1); } else { - destFile = new File(destDirFolder, srcFile.getName()); + destFile = destDirFolder.create(srcFile.getName(), srcFile.getMime()); } result[pos++] = destFile; } @@ -307,7 +307,7 @@ private File[] createDestFiles(IFileNameProcessor renameProcessor, File destDirF return result; } - private Date getRenameSourceFileDate(File srcFile, Date[] datesLastModified, int pos) { + private Date getRenameSourceFileDate(IFile srcFile, Date[] datesLastModified, int pos) { if ((datesLastModified != null) && (pos >= 0) && (pos < datesLastModified.length)) { return datesLastModified[pos]; } diff --git a/fotolib2/src/main/java/de/k3b/io/FileProcessor.java b/fotolib2/src/main/java/de/k3b/io/FileProcessor.java index 155faa2a..a30a99de 100644 --- a/fotolib2/src/main/java/de/k3b/io/FileProcessor.java +++ b/fotolib2/src/main/java/de/k3b/io/FileProcessor.java @@ -26,6 +26,7 @@ */ public class FileProcessor extends FileCommandLogger implements IFileCommandLogger { + protected static final String UNKNOWN_MIME = null; private static final String EXT_SIDECAR = ".xmp"; /// TODO what is mime for XMP @@ -111,11 +112,6 @@ protected boolean fileOrSidecarExists(IFile file) { || FileCommands.getSidecar(parent, name, true).exists(); } - @Deprecated - public File renameDuplicate(File file) { - return FileFacade.convert(file).getFile(); - } - public static XmpFile getExistingSidecarOrNull(String absolutePath) { XmpFile result = null; if (absolutePath != null) { @@ -138,8 +134,13 @@ public static XmpFile getExistingSidecarOrNull(String absolutePath, boolean long return result; } + @Deprecated + public File renameDuplicate(File file) { + return FileFacade.convert(file).getFile(); + } + /** - * @return file if rename is not neccessary else File with new name + * @return file if rename is not neccessary else IFile with new name */ public IFile renameDuplicate(IFile file) { if (!fileOrSidecarExists(file)) { diff --git a/fotolib2/src/main/java/de/k3b/io/IFileNameProcessor.java b/fotolib2/src/main/java/de/k3b/io/IFileNameProcessor.java index da4a12a5..79452e2c 100644 --- a/fotolib2/src/main/java/de/k3b/io/IFileNameProcessor.java +++ b/fotolib2/src/main/java/de/k3b/io/IFileNameProcessor.java @@ -18,7 +18,6 @@ */ package de.k3b.io; -import java.io.File; import java.util.Date; /** @@ -33,5 +32,5 @@ public interface IFileNameProcessor { * @param firstFileInstanceNumber number where numbering starts with. -1 : auto * @return next absoulte renamed file. */ - File getNextFile(File sourceFile, Date sourceFileDate, int firstFileInstanceNumber); + IFile getNextFile(IFile sourceFile, Date sourceFileDate, int firstFileInstanceNumber); } diff --git a/fotolib2/src/main/java/de/k3b/io/PhotoAutoprocessingDto.java b/fotolib2/src/main/java/de/k3b/io/PhotoAutoprocessingDto.java index a3c26377..368cf57a 100644 --- a/fotolib2/src/main/java/de/k3b/io/PhotoAutoprocessingDto.java +++ b/fotolib2/src/main/java/de/k3b/io/PhotoAutoprocessingDto.java @@ -23,8 +23,8 @@ import org.slf4j.LoggerFactory; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.io.Serializable; import de.k3b.LibGlobal; @@ -53,29 +53,19 @@ public class PhotoAutoprocessingDto implements Serializable { private static final String KEY_OUT_DIR = "outDir"; private final Properties properties; - private File outDir; + private IFile outDir; public PhotoAutoprocessingDto() { this(null, new Properties()); } - public PhotoAutoprocessingDto(File outDir, Properties properties) { + public PhotoAutoprocessingDto(IFile outDir, Properties properties) { this.outDir = outDir; this.properties = properties; } - public PhotoAutoprocessingDto load(File outDir) throws IOException { - this.outDir = outDir; - File apm = getApmFile(); - properties.clear(); - if (apm.exists() && apm.isFile() && apm.canRead()) { - properties.load(apm); - if (LibGlobal.debugEnabled) { - logger.debug(this.getClass().getSimpleName() + ": loaded from " + apm + ":" + this); - } - return this; - } - return null; + public static IFile getApmFile(IFile outDir) { + return outDir.create(RuleFileNameProcessor.APM_FILE_NAME, null); } public void paste(PhotoAutoprocessingDto newData) { @@ -105,18 +95,44 @@ public String getTranslateName(PhotoAutoprocessingDto newData) { return null; } - private File getApmFile() { - return getApmFile(this.outDir); + /** + * Android support: to persist state and to transfer activites via intent. + */ + public static PhotoAutoprocessingDto load(Serializable content) { + PhotoAutoprocessingDto photoAutoprocessingDto = null; + if (content instanceof Properties) { + Properties properties = (Properties) content; + String outDir = properties.getProperty(KEY_OUT_DIR); + photoAutoprocessingDto = new PhotoAutoprocessingDto((outDir != null) ? FileFacade.convert(new File(outDir)) : null, properties); + } + if (LibGlobal.debugEnabled) { + logger.debug(PhotoAutoprocessingDto.class.getSimpleName() + ": load De-Serialize:" + photoAutoprocessingDto); + } + return photoAutoprocessingDto; } - public static File getApmFile(File outDir) { - return new File(outDir, RuleFileNameProcessor.APM_FILE_NAME); + public PhotoAutoprocessingDto load(IFile outDir) throws IOException { + this.outDir = outDir; + IFile apm = getApmFile(); + properties.clear(); + if (apm.exists() && apm.isFile() && apm.canRead()) { + properties.load(apm.openInputStream()); + if (LibGlobal.debugEnabled) { + logger.debug(this.getClass().getSimpleName() + ": loaded from " + apm + ":" + this); + } + return this; + } + return null; + } + + private IFile getApmFile() { + return getApmFile(this.outDir); } /** if has no data the file is deleted */ public void save() throws IOException { - File apm = getApmFile(); - FileOutputStream stream = null; + IFile apm = getApmFile(); + OutputStream stream = null; if (isEmpty()) { if (LibGlobal.debugEnabled) { logger.debug(this.getClass().getSimpleName() + ": save delete empty " + apm + ":" + this); @@ -127,7 +143,7 @@ public void save() throws IOException { if (LibGlobal.debugEnabled) { logger.debug(this.getClass().getSimpleName() + ": save to " + apm + ":" + this); } - stream = new FileOutputStream(apm); + stream = apm.openOutputStream(); properties.store(stream, PhotoAutoprocessingDto.sFileComment); } finally { FileUtils.close(stream, "PhotoAutoprocessingDto.load(" + apm + ")"); @@ -135,20 +151,6 @@ public void save() throws IOException { } } - /** Android support: to persist state and to transfer activites via intent. */ - public static PhotoAutoprocessingDto load(Serializable content) { - PhotoAutoprocessingDto photoAutoprocessingDto = null; - if (content instanceof Properties ) { - Properties properties = (Properties) content; - String outDir = properties.getProperty(KEY_OUT_DIR); - photoAutoprocessingDto = new PhotoAutoprocessingDto((outDir != null) ? new File(outDir) : null, properties); - } - if (LibGlobal.debugEnabled) { - logger.debug(PhotoAutoprocessingDto.class.getSimpleName() + ": load De-Serialize:" + photoAutoprocessingDto); - } - return photoAutoprocessingDto; - } - /** DateFormat part for {@link RuleFileNameProcessor} */ public String getDateFormat() { return getProperty(KEY_DATE_FORMAT); @@ -182,10 +184,11 @@ public PhotoAutoprocessingDto setNumberFormat(String NumberFormat) { return this; } - public File getOutDir() { + public IFile getOutDir() { return outDir; } - public PhotoAutoprocessingDto setOutDir(File outDir) { + + public PhotoAutoprocessingDto setOutDir(IFile outDir) { this.outDir = outDir; return this; } diff --git a/fotolib2/src/main/java/de/k3b/io/RuleFileNameProcessor.java b/fotolib2/src/main/java/de/k3b/io/RuleFileNameProcessor.java index 3e0d7300..13c7731e 100644 --- a/fotolib2/src/main/java/de/k3b/io/RuleFileNameProcessor.java +++ b/fotolib2/src/main/java/de/k3b/io/RuleFileNameProcessor.java @@ -46,18 +46,18 @@ public class RuleFileNameProcessor extends FileProcessor implements IFileNamePro private String mName; private String mNumberFormat; private final DecimalFormat mNumberFormatter = new DecimalFormat(); - private final File mOutDir; + private static final IFile sSomeExampleSourceFile = FileFacade.convert(new File("/a/Xxxxxxxx.jpg")); // optimisationn as long as lastDateFormatted does not changed nextFileInstanceNumber is recycled private String mLastDateFormatted = null; private int mNextFileInstanceNumber = 0; - private static final File sSomeExampleSourceFile = new File("/a/Xxxxxxxx.jpg"); + private final IFile mOutDir; /** * filename = outDir+dateFormat+name+numberFormat+fileExtension. * @param outDir . If null use directory where source file lives in. */ - public RuleFileNameProcessor(File outDir) { + public RuleFileNameProcessor(IFile outDir) { this.mOutDir = outDir; } /** @@ -70,7 +70,7 @@ public RuleFileNameProcessor(File outDir) { * Example "000" always at least 3 digits * @param outDir If null use directory where source file lives in. */ - public RuleFileNameProcessor(String dateFormat, String name, String numberFormat, File outDir) { + public RuleFileNameProcessor(String dateFormat, String name, String numberFormat, IFile outDir) { this(outDir); set(dateFormat, name, numberFormat); } @@ -78,11 +78,11 @@ public RuleFileNameProcessor(String dateFormat, String name, String numberFormat /** * Fix Autoprocessing/PhotoAutoprocessingDto renaming rules that contain source file direcory names. */ - public RuleFileNameProcessor(RuleFileNameProcessor ancestor, File newDir) { + public RuleFileNameProcessor(RuleFileNameProcessor ancestor, IFile newDir) { this(newDir); if (ancestor != null) { String name = ancestor.mName; - final File oldDir = ancestor.mOutDir; + final IFile oldDir = ancestor.mOutDir; if ((newDir != null) && (!StringUtils.isNullOrEmpty(name) & (oldDir != null) && (newDir != oldDir))) { name = replace(name,ancestor.getDirBaseName(),this.getDirBaseName()); @@ -175,6 +175,28 @@ protected boolean mustRename(String filenameWithoutPath) { return (!filenameWithoutPath.contains(this.mName)); } + public static IFile getFile(IFile _file) { + return (_file != null) ? _file : sSomeExampleSourceFile; + } + + /** + * Fix Autoprocessing/PhotoAutoprocessingDto renaming rules that contain source file direcory names. + */ + public static String translateName(RuleFileNameProcessor srcData, IFile outDir) { + RuleFileNameProcessor translated = new RuleFileNameProcessor(srcData, outDir); + return translated.mName; + } + + @Override + public String toString() { + return ListUtils.toString(" ", this.getClass().getSimpleName(), mDateFormat, mName, mNumberFormat, ": +", mNextFileInstanceNumber); + } + + public String getDirBaseName() { + if (mOutDir != null) return getBaseName(mOutDir.getName()); + return null; + } + /** * Calculate next free file name for sourceFile. Sourcefiles should be ordered asc by sourceFileDate * @@ -182,13 +204,13 @@ protected boolean mustRename(String filenameWithoutPath) { * @return next absoulte renamed file. */ @Override - public File getNextFile(File sourceFile, Date sourceFileDate, int firstFileInstanceNumber) { + public IFile getNextFile(IFile sourceFile, Date sourceFileDate, int firstFileInstanceNumber) { String name = getFile(sourceFile).getName(); - File outDir = (this.mOutDir != null) ? this.mOutDir : sourceFile.getParentFile(); + IFile outDir = (this.mOutDir != null) ? this.mOutDir : sourceFile.getParentFile(); if (!mustRename(name)) { // no rename rule or file already matches rules - File result = new File(outDir, name); + IFile result = outDir.create(name, UNKNOWN_MIME); // usecase: apply auto where inFile is already in outdir: no modification if ((sourceFile != null) && sourceFile.equals(result)) return result; @@ -208,10 +230,10 @@ public File getNextFile(File sourceFile, Date sourceFileDate, int firstFileInsta } // else reuse mNextFileInstanceNumber for the same date mLastDateFormatted = dateFormatted; - File result = null; + IFile result = null; int tryCount = 0; do { - result = new File(outDir, generateFileName(dateFormatted, mNextFileInstanceNumber, fileExtension)); + result = outDir.create(generateFileName(dateFormatted, mNextFileInstanceNumber, fileExtension), UNKNOWN_MIME); mNextFileInstanceNumber++; if (!fileOrSidecarExists(result)) return result; // filename not in use yet tryCount++; @@ -225,26 +247,6 @@ public File getNextFile(File sourceFile, Date sourceFileDate, int firstFileInsta throw new IllegalArgumentException(msg); } - public static File getFile(File _file) { - return (_file != null) ? _file : sSomeExampleSourceFile; - } - - @Override - public String toString() { - return ListUtils.toString(" ", this.getClass().getSimpleName(), mDateFormat, mName, mNumberFormat, ": +", mNextFileInstanceNumber); - } - - public String getDirBaseName() { - if (mOutDir != null) return getBaseName(mOutDir.getName()); - return null; - } - - public String getParentDirBaseName() { - File parent = (mOutDir != null) ? mOutDir.getParentFile() : null; - if (parent != null) return getBaseName(parent.getName()); - return null; - } - /** Get name without leading numbers. i.e. getBaseName("01701Test001") ==> "Test". package to allow unittesting */ static String getBaseName(String name) { if (name != null) { @@ -265,11 +267,9 @@ private static boolean isLetter(String name, int offset) { return result; } - /** - * Fix Autoprocessing/PhotoAutoprocessingDto renaming rules that contain source file direcory names. - */ - public static String translateName(RuleFileNameProcessor srcData, File outDir) { - RuleFileNameProcessor translated = new RuleFileNameProcessor(srcData, outDir); - return translated.mName; + public String getParentDirBaseName() { + IFile parent = (mOutDir != null) ? mOutDir.getParentFile() : null; + if (parent != null) return getBaseName(parent.getName()); + return null; } } diff --git a/fotolib2/src/main/java/de/k3b/io/collections/DestDirFileNameProcessor.java b/fotolib2/src/main/java/de/k3b/io/collections/DestDirFileNameProcessor.java index d7be9ad5..b1424930 100644 --- a/fotolib2/src/main/java/de/k3b/io/collections/DestDirFileNameProcessor.java +++ b/fotolib2/src/main/java/de/k3b/io/collections/DestDirFileNameProcessor.java @@ -22,7 +22,9 @@ import java.io.File; import java.util.Date; +import de.k3b.io.FileFacade; import de.k3b.io.FileProcessor; +import de.k3b.io.IFile; import de.k3b.io.IFileNameProcessor; /** @@ -30,10 +32,14 @@ */ public class DestDirFileNameProcessor extends FileProcessor implements IFileNameProcessor { - private final File destDirFolder; + private final IFile destDirFolder; private final boolean doNotRenameIfSourceInDestFolder; public DestDirFileNameProcessor(File destDirFolder, boolean doNotRenameIfSourceInDestFolder) { + this(FileFacade.convert(destDirFolder), doNotRenameIfSourceInDestFolder); + } + + public DestDirFileNameProcessor(IFile destDirFolder, boolean doNotRenameIfSourceInDestFolder) { this.destDirFolder = destDirFolder; this.doNotRenameIfSourceInDestFolder = doNotRenameIfSourceInDestFolder; } @@ -46,11 +52,11 @@ public DestDirFileNameProcessor(File destDirFolder, boolean doNotRenameIfSourceI * @param firstFileInstanceNumber number where numbering starts with. -1 : auto @return next absoulte renamed file. */ @Override - public File getNextFile(File sourceFile, Date sourceFileDate, int firstFileInstanceNumber) { + public IFile getNextFile(IFile sourceFile, Date sourceFileDate, int firstFileInstanceNumber) { // usecase: apply auto where inFile is already in outdir. if (doNotRenameIfSourceInDestFolder && this.destDirFolder.equals(sourceFile.getParentFile())) return sourceFile; - File dest = renameDuplicate(new File(this.destDirFolder, sourceFile.getName())); + IFile dest = renameDuplicate(this.destDirFolder.create(sourceFile.getName(), UNKNOWN_MIME)); return dest; } } diff --git a/fotolib2/src/test/java/de/k3b/io/FileCommandTests.java b/fotolib2/src/test/java/de/k3b/io/FileCommandTests.java index ab43d6dc..354a629e 100644 --- a/fotolib2/src/test/java/de/k3b/io/FileCommandTests.java +++ b/fotolib2/src/test/java/de/k3b/io/FileCommandTests.java @@ -38,8 +38,8 @@ * Created by k3b on 06.08.2015. */ public class FileCommandTests { - private static final File X_FAKE_OUTPUT_DIR = new File("/fakeOutputDir").getAbsoluteFile(); - private static final File X_FAKE_INPUT_DIR = new File("/fakeInputDir").getAbsoluteFile(); + private static final IFile X_FAKE_OUTPUT_DIR = FileFacade.convert(new File("/fakeOutputDir").getAbsoluteFile()); + private static final IFile X_FAKE_INPUT_DIR = FileFacade.convert(new File("/fakeInputDir").getAbsoluteFile()); private FileCommands sut; MediaTransactionLogEntryType lastMediaTransactionLogEntryType; @@ -63,6 +63,26 @@ public void setUp() { lastMediaTransactionLogEntryType = null; } + /** + * these files exist in source-dir and in dest-dir + */ + private static void registerFakeFiles(FileProcessor sut, String... filenames) { + if (filenames.length == 0) { + doReturn(false).when(sut).osFileExists(any(File.class)); + } else { + for (String filename : filenames) { + //doReturn(true).when(sut).osFileExists(new File(X_FAKE_OUTPUT_DIR, filename)); + doReturn(true).when(sut).osFileExists(createTestFile(X_FAKE_OUTPUT_DIR, filename)); + //doReturn(true).when(sut).osFileExists(new File(X_FAKE_INPUT_DIR, filename)); + doReturn(true).when(sut).osFileExists(createTestFile(X_FAKE_INPUT_DIR, filename)); + } + } + } + + private static IFile createTestFile(IFile destDir, String name) { + return destDir.create(name, null); + } + @Test public void shouldCopy() { registerFakeFiles(sut); @@ -71,7 +91,20 @@ public void shouldCopy() { sut.moveOrCopyFilesTo(false, selectedFiles, X_FAKE_OUTPUT_DIR, null); Assert.assertEquals("MediaTransactionLogEntryType", MediaTransactionLogEntryType.COPY, lastMediaTransactionLogEntryType); - verify(sut).osFileMoveOrCopy(false, new File(X_FAKE_OUTPUT_DIR, "a.jpg"), createTestFile(X_FAKE_OUTPUT_DIR, "a.jpg")); + verify(sut).osFileMoveOrCopy(false, createTestFile(X_FAKE_OUTPUT_DIR, "a.jpg"), createTestFile(X_FAKE_OUTPUT_DIR, "a.jpg")); + } + + @Test + public void shouldDeleteExistingWithXmp() { + registerFakeFiles(sut, "a.jpg", "a.xmp", "a.jpg.xmp"); + SelectedFiles selectedFiles = createTestSelectedFiles(X_FAKE_OUTPUT_DIR, "a.jpg"); + + sut.deleteFiles(selectedFiles, null); + + Assert.assertEquals("MediaTransactionLogEntryType", MediaTransactionLogEntryType.DELETE, lastMediaTransactionLogEntryType); + verify(sut).osDeleteFile(createTestFile(X_FAKE_OUTPUT_DIR, "a.jpg")); + verify(sut).osDeleteFile(createTestFile(X_FAKE_OUTPUT_DIR, "a.xmp")); + verify(sut).osDeleteFile(createTestFile(X_FAKE_OUTPUT_DIR, "a.jpg.xmp")); } @Test @@ -82,15 +115,15 @@ public void shouldCopyWitRenameExistingMultiple() { sut.moveOrCopyFilesTo(false, selectedFiles, X_FAKE_OUTPUT_DIR, null); Assert.assertEquals("MediaTransactionLogEntryType", MediaTransactionLogEntryType.COPY, lastMediaTransactionLogEntryType); - verify(sut).osFileMoveOrCopy(false, new File(X_FAKE_OUTPUT_DIR, "a(1).jpg"), createTestFile(X_FAKE_INPUT_DIR, "a.jpg")); - verify(sut).osFileMoveOrCopy(false, new File(X_FAKE_OUTPUT_DIR, "b(2).png"), createTestFile(X_FAKE_INPUT_DIR, "b.png")); + verify(sut).osFileMoveOrCopy(false, createTestFile(X_FAKE_OUTPUT_DIR, "a(1).jpg"), createTestFile(X_FAKE_INPUT_DIR, "a.jpg")); + verify(sut).osFileMoveOrCopy(false, createTestFile(X_FAKE_OUTPUT_DIR, "b(2).png"), createTestFile(X_FAKE_INPUT_DIR, "b.png")); } @Test public void shouldMoveExistingWithXmp() { registerFakeFiles(sut, "a.jpg", "a.xmp", "a.jpg.xmp"); // a(3) is next possible - File destFile = new File(X_FAKE_OUTPUT_DIR, "a.jpg"); + IFile destFile = createTestFile(X_FAKE_OUTPUT_DIR, "a.jpg"); // do not rename duplicate Mockito.doReturn(destFile).when(sut).renameDuplicate(destFile); @@ -100,43 +133,12 @@ public void shouldMoveExistingWithXmp() { sut.moveOrCopyFilesTo(true, selectedFiles, X_FAKE_OUTPUT_DIR, null); Assert.assertEquals("MediaTransactionLogEntryType", MediaTransactionLogEntryType.MOVE, lastMediaTransactionLogEntryType); - verify(sut).osFileMoveOrCopy(true, new File(X_FAKE_OUTPUT_DIR, "a.jpg"), createTestFile(X_FAKE_INPUT_DIR, "a.jpg")); - verify(sut).osFileMoveOrCopy(true, new File(X_FAKE_OUTPUT_DIR, "a.xmp"), createTestFile(X_FAKE_INPUT_DIR, "a.xmp")); - verify(sut).osFileMoveOrCopy(true, new File(X_FAKE_OUTPUT_DIR, "a.jpg.xmp"), createTestFile(X_FAKE_INPUT_DIR, "a.jpg.xmp")); - } - - @Test - public void shouldDeleteExistingWithXmp() { - registerFakeFiles(sut, "a.jpg", "a.xmp", "a.jpg.xmp"); - SelectedFiles selectedFiles = createTestSelectedFiles(X_FAKE_OUTPUT_DIR, "a.jpg"); - - sut.deleteFiles(selectedFiles, null); - - Assert.assertEquals("MediaTransactionLogEntryType", MediaTransactionLogEntryType.DELETE, lastMediaTransactionLogEntryType); - verify(sut).osDeleteFile(createTestFile(X_FAKE_OUTPUT_DIR, "a.jpg")); - verify(sut).osDeleteFile(createTestFile(X_FAKE_OUTPUT_DIR, "a.xmp")); - verify(sut).osDeleteFile(createTestFile(X_FAKE_OUTPUT_DIR, "a.jpg.xmp")); - } - - /** these files exist in source-dir and in dest-dir */ - private static void registerFakeFiles(FileProcessor sut, String... filenames) { - if (filenames.length == 0) { - doReturn(false).when(sut).osFileExists(any(File.class)); - } else { - for (String filename : filenames) { - doReturn(true).when(sut).osFileExists(new File(X_FAKE_OUTPUT_DIR, filename)); - doReturn(true).when(sut).osFileExists(createTestFile(X_FAKE_OUTPUT_DIR, filename)); - doReturn(true).when(sut).osFileExists(new File(X_FAKE_INPUT_DIR, filename)); - doReturn(true).when(sut).osFileExists(createTestFile(X_FAKE_INPUT_DIR, filename)); - } - } - } - - private static File createTestFile(File destDir, String name) { - return new File(destDir, name); + verify(sut).osFileMoveOrCopy(true, createTestFile(X_FAKE_OUTPUT_DIR, "a.jpg"), createTestFile(X_FAKE_INPUT_DIR, "a.jpg")); + verify(sut).osFileMoveOrCopy(true, createTestFile(X_FAKE_OUTPUT_DIR, "a.xmp"), createTestFile(X_FAKE_INPUT_DIR, "a.xmp")); + verify(sut).osFileMoveOrCopy(true, createTestFile(X_FAKE_OUTPUT_DIR, "a.jpg.xmp"), createTestFile(X_FAKE_INPUT_DIR, "a.jpg.xmp")); } - private SelectedFiles createTestSelectedFiles(File destDir, String... fileNames) { + private SelectedFiles createTestSelectedFiles(IFile destDir, String... fileNames) { String[] paths = new String[fileNames.length]; Long[] ids = new Long[fileNames.length]; int pos = 0; diff --git a/fotolib2/src/test/java/de/k3b/io/FileNameProcessorTests.java b/fotolib2/src/test/java/de/k3b/io/FileNameProcessorTests.java index 8ec50c58..f3fdc3bf 100644 --- a/fotolib2/src/test/java/de/k3b/io/FileNameProcessorTests.java +++ b/fotolib2/src/test/java/de/k3b/io/FileNameProcessorTests.java @@ -34,8 +34,8 @@ */ public class FileNameProcessorTests { - private static final File X_FAKE_OUTPUT_DIR = new File("/fakeOutputDir").getAbsoluteFile(); - private static final File X_FAKE_INPUT_DIR = new File("/fakeInputDir").getAbsoluteFile(); + private static final IFile X_FAKE_OUTPUT_DIR = FileFacade.convert(new File("/fakeOutputDir").getAbsoluteFile()); + private static final IFile X_FAKE_INPUT_DIR = FileFacade.convert(new File("/fakeInputDir").getAbsoluteFile()); @Test public void shouldExpandDateTimeInfo() { @@ -65,11 +65,29 @@ public void shouldHandleMustRename() { Assert.assertEquals(true, sut.mustRename("171224Something123.jpg")); } + /** + * these files exist in source-dir and in dest-dir + */ + private static void registerFakeFiles(RuleFileNameProcessor sut, String... filenames) { + if (filenames.length == 0) { + doReturn(false).when(sut).osFileExists(any(File.class)); + doReturn(false).when(sut).osFileExists(any(IFile.class)); + } else { + for (String filename : filenames) { + doReturn(true).when(sut).osFileExists(createTestFile(X_FAKE_OUTPUT_DIR, filename)); + doReturn(true).when(sut).osFileExists(createTestFile(X_FAKE_OUTPUT_DIR, filename)); + } + } + } + + private static IFile createTestFile(IFile dir, String filename) { + return dir.create(filename, null); + } @Test public void shouldGetNextFreeFileWithoutRename() { IFileNameProcessor sut = spy(new RuleFileNameProcessor(null, "Hello", null, X_FAKE_OUTPUT_DIR)); - File outFile = sut.getNextFile(new File(X_FAKE_INPUT_DIR, "171224Hello1234.jpg"),null,0); + IFile outFile = sut.getNextFile(X_FAKE_INPUT_DIR.create("171224Hello1234.jpg", null),null,0); Assert.assertEquals("171224Hello1234.jpg", outFile.getName()); } @@ -77,7 +95,7 @@ public void shouldGetNextFreeFileWithoutRename() { public void shouldGetNextFreeFile() { RuleFileNameProcessor sut = spy(new RuleFileNameProcessor(null, "Hello", null, X_FAKE_OUTPUT_DIR)); registerFakeFiles(sut, "Hello.jpg", "Hello1.jpg", "Hello2.jpg.xmp", "Hello3.xmp"); - File outFile = sut.getNextFile(new File(X_FAKE_INPUT_DIR, "1234.jpg"),null,0); + IFile outFile = sut.getNextFile(createTestFile(X_FAKE_INPUT_DIR, "1234.jpg"),null,0); Assert.assertEquals("Hello4.jpg", outFile.getName()); } @@ -85,7 +103,7 @@ public void shouldGetNextFreeFile() { public void shouldGetNextFreeFileNoOutDir() { RuleFileNameProcessor sut = spy(new RuleFileNameProcessor(null, "Hello", null, null)); registerFakeFiles(sut, "Hello.jpg", "Hello1.jpg", "Hello2.jpg.xmp", "Hello3.xmp"); - File outFile = sut.getNextFile(new File(X_FAKE_OUTPUT_DIR, "1234.jpg"), null, 0); + IFile outFile = sut.getNextFile(createTestFile(X_FAKE_OUTPUT_DIR, "1234.jpg"), null, 0); Assert.assertEquals("Hello4.jpg", outFile.getName()); } @@ -93,15 +111,32 @@ public void shouldGetNextFreeFileNoOutDir() { public void shouldGetNextFreeFileEmpty() { RuleFileNameProcessor sut = spy(new RuleFileNameProcessor(null, null, null, X_FAKE_OUTPUT_DIR)); registerFakeFiles(sut, "Hello.jpg"); - File outFile = sut.getNextFile(new File(X_FAKE_INPUT_DIR, "originalName.jpg"),null,0); + IFile outFile = sut.getNextFile(createTestFile(X_FAKE_INPUT_DIR, "originalName.jpg"),null,0); Assert.assertEquals("originalName.jpg", outFile.getName()); } + @Test + public void shouldGetFileExtension() { + Assert.assertEquals(".jpg", FileUtils.getExtension("hello.jpg")); + } + + @Test + public void shouldGetBaseName() { + CharSequence baseName = RuleFileNameProcessor.getBaseName("01701Test001"); + Assert.assertEquals("Test", baseName); + + baseName = RuleFileNameProcessor.getBaseName("Test"); + Assert.assertEquals("Test", baseName); + + baseName = RuleFileNameProcessor.getBaseName("001"); + Assert.assertEquals(null, baseName); + } + @Test public void shouldGetNextFreeFileEmptyExisting() { RuleFileNameProcessor sut = spy(new RuleFileNameProcessor(null, null, null, X_FAKE_OUTPUT_DIR)); registerFakeFiles(sut, "originalName.jpg"); - File outFile = sut.getNextFile(new File(X_FAKE_INPUT_DIR, "originalName.jpg"),null,0); + IFile outFile = sut.getNextFile(createTestFile(X_FAKE_INPUT_DIR, "originalName.jpg"),null,0); Assert.assertEquals("originalName(1).jpg", outFile.getName()); } @@ -110,7 +145,7 @@ public void shouldGetNextFreeFileSequenceWithDifferentDates() { RuleFileNameProcessor sut = spy(new RuleFileNameProcessor("yy", "Hello", null, X_FAKE_OUTPUT_DIR)); registerFakeFiles(sut, "16Hello.jpg", "16Hello1.jpg", "17Hello.jpg"); - File someInputFile = new File(X_FAKE_INPUT_DIR, "1234.jpg"); + IFile someInputFile = createTestFile(X_FAKE_INPUT_DIR, "1234.jpg"); int firstFileInstanceNumber = 0; Date date = DateUtil.parseIsoDate("20151224"); @@ -127,45 +162,15 @@ public void shouldGetNextFreeFileSequenceWithDifferentDates() { Assert.assertEquals("18Hello.jpg", sut.getNextFile(someInputFile,date, firstFileInstanceNumber).getName()); } - @Test - public void shouldGetFileExtension() { - Assert.assertEquals(".jpg", FileUtils.getExtension("hello.jpg")); - } - - @Test - public void shouldGetBaseName() { - CharSequence baseName = RuleFileNameProcessor.getBaseName("01701Test001"); - Assert.assertEquals("Test", baseName); - - baseName = RuleFileNameProcessor.getBaseName("Test"); - Assert.assertEquals("Test", baseName); - - baseName = RuleFileNameProcessor.getBaseName("001"); - Assert.assertEquals(null, baseName); - } - @Test public void shouldFixRuleOnFileChange() { RuleFileNameProcessor ancestor = new RuleFileNameProcessor( - null,"Crete-habour",null, - new File ("/DCIM/2007Crete/habour/") + null,"Crete-habour", null, + FileFacade.convert(new File("/DCIM/2007Crete/habour/")) ); - String newName = RuleFileNameProcessor.translateName(ancestor, new File ("/DCIM/2008Teneriffe/beach/")); + String newName = RuleFileNameProcessor.translateName(ancestor, FileFacade.convert(new File("/DCIM/2008Teneriffe/beach/"))); Assert.assertEquals("Teneriffe-beach", newName); } - - /** these files exist in source-dir and in dest-dir */ - private static void registerFakeFiles(RuleFileNameProcessor sut, String... filenames) { - if (filenames.length == 0) { - doReturn(false).when(sut).osFileExists(any(File.class)); - doReturn(false).when(sut).osFileExists(any(IFile.class)); - } else { - for (String filename : filenames) { - doReturn(true).when(sut).osFileExists(new File(X_FAKE_OUTPUT_DIR, filename)); - doReturn(true).when(sut).osFileExists(new FileFacade(new File(X_FAKE_OUTPUT_DIR, filename))); - } - } - } }