Skip to content

Commit

Permalink
#13: Added api for source relative paths in zip file
Browse files Browse the repository at this point in the history
  • Loading branch information
k3b committed Nov 2, 2018
1 parent 8a52166 commit b890b87
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 64 deletions.
4 changes: 0 additions & 4 deletions libK3b/libK3b.iml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,5 @@
<orderEntry type="library" exported="" scope="TEST" name="powermock-reflect-1.5.2" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="javassist-3.18.0-GA" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="objenesis-1.2" level="project" />
<orderEntry type="library" exported="" name="libK3b.libK3b-L2.0.15" level="project" />
<orderEntry type="library" exported="" name="libK3b.libK3b-L2.0.15" level="project" />
<orderEntry type="library" exported="" name="libK3b.libK3b-L2.0.15" level="project" />
<orderEntry type="library" exported="" name="libK3b.libK3b-L2.0.15" level="project" />
</component>
</module>
50 changes: 50 additions & 0 deletions libK3b/src/main/java/de/k3b/io/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
import org.slf4j.LoggerFactory;

/**
* Helper functions for java.io.File.
* Changes here should also be added to https://github.com/k3b/APhotoManager/
*
* Created by k3b on 06.10.2015.
*/
public class FileUtils {
Expand Down Expand Up @@ -56,4 +59,51 @@ public boolean accept(File owner, String fileName) {
});
}

// #118 app specific content uri convert
// from {content://approvider}//storage/emulated/0/DCIM/... to /storage/emulated/0/DCIM/
public static String fixPath(String path) {
if (path != null) {
while (path.startsWith("//")) {
path = path.substring(1);
}
}
return path;
}

/** tryGetCanonicalFile without exception */
public static File tryGetCanonicalFile(String path) {
if (path == null) return null;

final File file = new File(path);
return tryGetCanonicalFile(file, file);
}

/** tryGetCanonicalFile without exception */
public static File tryGetCanonicalFile(File file, File errorValue) {
if (file == null) return null;

try {
return file.getCanonicalFile();
} catch (IOException ex) {
logger.warn(DBG_CONTEXT + "Error tryGetCanonicalFile('" + file.getAbsolutePath() + "') => '" + errorValue + "' exception " + ex.getMessage(), ex);
return errorValue;
}
}

/** tryGetCanonicalFile without exception */
public static File tryGetCanonicalFile(File file) {
return tryGetCanonicalFile(file, file);
}

/** tryGetCanonicalFile without exception */
public static String tryGetCanonicalPath(File file, String errorValue) {
if (file == null) return null;

try {
return file.getCanonicalPath();
} catch (IOException ex) {
logger.warn(DBG_CONTEXT + "Error tryGetCanonicalPath('" + file.getAbsolutePath() + "') => '" + errorValue + "' exception " + ex.getMessage(), ex);
return errorValue;
}
}
}
61 changes: 6 additions & 55 deletions libK3bZip/src/main/java/de/k3b/zip/CompressJob.java
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ List<CompressItem> handleDuplicates(Map<String, Long> existingZipEntries) {

// remove the ithems that are marked with null filename
for (int i = this.compressQue.size() - 1; i >= 0; i--) {
if (this.compressQue.get(i).getZipEntryFileName() == null) {
if (getCompressItemAt(i).getZipEntryFileName() == null) {
this.compressQue.remove(i);
}
}
Expand All @@ -264,6 +264,11 @@ List<CompressItem> handleDuplicates(Map<String, Long> existingZipEntries) {
return null;
}

/** scope package to allow unittests */
CompressItem getCompressItemAt(int i) {
return this.compressQue.get(i);
}

/**
* package to allow unittesting: <br/>
* gets a fixed (renamed) name for the zip entry or null if file
Expand Down Expand Up @@ -308,60 +313,6 @@ String getRenamedZipEntryFileName(Map<String, Long> existingZipEntries, Compress
id++;
}
}
/**
* package to allow unittesting: <br/>
* gets a fixed (renamed) name for the zip entry or null if file
* should not be added to zip.
*/
String getRenamedZipEntryFileName_Deprecated(ZipFile zipFile, ZipEntry zipEntry,
long lastModified) {
String zipEntryFileName = zipEntry.getName();
if (!optRenameExistingOldEntry) {
logger.debug("do not include: optRenameExistingOldEntry disabled {}", zipEntryFileName);
return null;
}

if (sameDate_Deprecated(zipEntry, lastModified)) {
logger.debug("do not include: duplicate with same datetime found {}", zipEntryFileName);
return null;
}

String extension = ")";
int extensionPosition = zipEntryFileName.lastIndexOf(".");
if (extensionPosition >= 0) {
extension = ")" + zipEntryFileName.substring(extensionPosition);
zipEntryFileName = zipEntryFileName.substring(0, extensionPosition) + "(";
}
int id = 1;
while (true) {
String newZifFileName = zipEntryFileName + id + extension;
ZipEntry newZipEntry = zipFile.getEntry(newZifFileName);
if (newZipEntry == null) {
logger.debug("renamed zipentry from '{}' to '{}'", zipEntry.getName(), newZifFileName);
return newZifFileName;
}

if (sameDate_Deprecated(newZipEntry, lastModified)) {
if (logger.isDebugEnabled()) {
logger.debug("do not include: duplicate with same datetime found '{}' for '{}'",
newZifFileName, zipEntryFileName);
}
return null;
}

id++;
}
}

/**
* return true, if zipEntry has same date as fileLastModified
*/
private boolean sameDate_Deprecated(ZipEntry zipEntry, long fileLastModified) {
// may varay in millisec
long zipLastModified = zipEntry.getTime();
final String zipEntryFileName = zipEntry.getName();
return sameDate(zipEntryFileName, fileLastModified, zipLastModified);
}

private boolean sameDate(String zipEntryFileName, long fileLastModified, long zipLastModified) {
long timeDiff = Math.abs(fileLastModified - zipLastModified);
Expand Down
67 changes: 65 additions & 2 deletions libK3bZip/src/main/java/de/k3b/zip/FileCompressItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,51 +20,114 @@

import java.io.*;

import de.k3b.io.FileUtils;
import de.k3b.io.StringUtils;

/**
* One android independant, java.io.File based dto-item that should be compressed.<br/>
* <p/>
* Author k3b
*/
public class FileCompressItem extends CompressItem {
/** source file to be compressed */
private File file;

/** if not null file adds will be relative to this path if file is below this path */
private static String zipRelPath = null;

/**
*
* @param destZipPathWithoutFileName directory with trailing "/" (without filename) where the entry goes to. null==root dir.
* @param srcFile full path to source file
* @param zipEntryComment
*/
public FileCompressItem(String destZipPathWithoutFileName, File srcFile, String zipEntryComment) {
if (destZipPathWithoutFileName == null) destZipPathWithoutFileName = "";
String zipEntryName = calculateZipEntryName(destZipPathWithoutFileName, srcFile, FileCompressItem.zipRelPath);
setFile(srcFile);
setZipEntryFileName(destZipPathWithoutFileName + srcFile.getName());
setZipEntryFileName(zipEntryName);
setZipEntryComment(zipEntryComment);
}

/**
* Calculates the path within the zip file.
*
* Scope: package to allow unittesting.
*
* @param destZipPathWithoutFileName
* @param srcFile
* @param zipRelPath
* @return
*/
static String calculateZipEntryName(String destZipPathWithoutFileName, File srcFile, String zipRelPath) {
if (!StringUtils.isNullOrEmpty(zipRelPath)) {
String srcPath = getCanonicalPath(srcFile);
if (srcPath.startsWith(zipRelPath)) {
String result = srcPath.substring(zipRelPath.length()+1);
return result;
}
}

StringBuilder result = new StringBuilder();

if (destZipPathWithoutFileName != null) result.append(destZipPathWithoutFileName);
result.append(srcFile.getName());
return result.toString();
}

/** if not null file adds will be relative to this path if file is below this path */
public static void setZipRelPath(File zipRelPath) {
FileCompressItem.zipRelPath = getCanonicalPath(zipRelPath);
}

/** so that files are comparable */
static String getCanonicalPath(File zipRelPath) {
File canonicalFile = FileUtils.tryGetCanonicalFile(zipRelPath);
if (canonicalFile != null) {
return FileUtils.fixPath(canonicalFile.getAbsolutePath());
}
return null;
}


/** source file to be compressed */
public FileCompressItem setFile(File file) {
this.file = file;
this.processed = false;
return this;
}

/** source file to be compressed */
public File getFile() {
return file;
}

/**
* {@inheritDoc}
*/
@Override
public InputStream getFileInputStream() throws IOException {
return new FileInputStream(file);
}

/**
* {@inheritDoc}
*/
@Override
public long getLastModified() {
return this.getFile().lastModified();
}

/**
* {@inheritDoc}
*/
@Override
public boolean isSame(CompressItem other) {
return super.isSame(other) && (this.file.equals(((FileCompressItem) other).file));
}

/**
* {@inheritDoc}
*/
@Override
public StringBuilder getLogEntry(StringBuilder _result) {
StringBuilder result = super.getLogEntry(_result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import junit.framework.Assert;

import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

Expand All @@ -34,6 +33,8 @@
import java.text.SimpleDateFormat;
import java.util.Date;

import de.k3b.io.FileUtils;

/**
* Integration-Tests using real zip files in the temp-folder<br/>
* <br/>
Expand All @@ -43,8 +44,8 @@ public class CompressJobIntegrationTests {
private static final int NUMBER_OF_LOG_ENTRIES = 1;
static private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd_HHmmss-S");
// static private File root = new File(System.getProperty("java.io.tmpdir")
static private String root = System.getProperty("java.io.tmpdir")
+ "/k3bZipTests/CompressJobIntegrationTests/";
static private String root = FileUtils.fixPath(System.getProperty("java.io.tmpdir")
+ "/k3bZipTests/CompressJobIntegrationTests/");
static private String rootInput = root + "inputFiles/";
static private File testContent = new File(rootInput + "testFile.txt");
static private File testContent2 = new File(rootInput + "testFile2.txt");
Expand Down Expand Up @@ -144,4 +145,36 @@ public void shouldAppendTextAsFileToExisting() {
int itemCount = sut.compress(false) - NUMBER_OF_LOG_ENTRIES;
Assert.assertEquals(1, itemCount);
}

@Test
public void shouldCalculateRelPath() {
File srcFile = new File("/path/to/my/source/file.txt");

Assert.assertEquals("source/file.txt",
getCalRelPath("root/", srcFile, "/path/to/my/"));
Assert.assertEquals("root/file.txt",
getCalRelPath("root/", srcFile, "/path/to/other/"));
}

private static String getCalRelPath(String notFoundRelPath, File srcFile, String refPath) {
String result = FileCompressItem.calculateZipEntryName(notFoundRelPath, srcFile,
FileCompressItem.getCanonicalPath(new File(refPath)));

// fix windows path seperator
return result.replaceAll("\\\\","/");
}

@Test
public void shouldAddWithRelPath() {
CompressJob sut = createCompressJob("shouldAddWithRelPath");

FileCompressItem.setZipRelPath(new File(root));
sut.addToCompressQue("ignoredPath/", testContent2, testContent4);
FileCompressItem.setZipRelPath(null);

int itemCount = sut.compress(false) - NUMBER_OF_LOG_ENTRIES;
Assert.assertEquals(2, itemCount);
Assert.assertEquals(false, sut.getCompressItemAt(1).getZipEntryFileName().contains("ignore"));
}

}

0 comments on commit b890b87

Please sign in to comment.