From 7b2a61045662e9b03eb2fa5292fd0c4397332f66 Mon Sep 17 00:00:00 2001
From: Alex Kuiper
Date: Wed, 27 Mar 2013 07:58:24 +0100
Subject: [PATCH 01/57] Added OGG audio to recognized file types.
---
.../java/nl/siegmann/epublib/service/MediatypeService.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/service/MediatypeService.java b/epublib-core/src/main/java/nl/siegmann/epublib/service/MediatypeService.java
index d9074082..835567d9 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/service/MediatypeService.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/service/MediatypeService.java
@@ -37,13 +37,14 @@ public class MediatypeService {
// audio
public static final MediaType MP3 = new MediaType("audio/mpeg", ".mp3");
public static final MediaType MP4 = new MediaType("audio/mp4", ".mp4");
+ public static final MediaType OGG = new MediaType("audio/ogg", ".ogg");
public static final MediaType SMIL = new MediaType("application/smil+xml", ".smil");
public static final MediaType XPGT = new MediaType("application/adobe-page-template+xml", ".xpgt");
public static final MediaType PLS = new MediaType("application/pls+xml", ".pls");
public static MediaType[] mediatypes = new MediaType[] {
- XHTML, EPUB, JPG, PNG, GIF, CSS, SVG, TTF, NCX, XPGT, OPENTYPE, WOFF, SMIL, PLS, JAVASCRIPT, MP3, MP4
+ XHTML, EPUB, JPG, PNG, GIF, CSS, SVG, TTF, NCX, XPGT, OPENTYPE, WOFF, SMIL, PLS, JAVASCRIPT, MP3, MP4, OGG
};
public static Map mediaTypesByName = new HashMap();
From 6ef20621ab63a3d15f90f4a1a4664b2d91ffeaf0 Mon Sep 17 00:00:00 2001
From: Mayleen Lacouture
Date: Thu, 4 Apr 2013 16:06:45 +0200
Subject: [PATCH 02/57] Added support for reading epub files directly from a
java.zip.ZipFile instead of a ZipInputStream: the ZipInputStream approach
stops reading from the input when a null entry is found, which in some cases
leads to a toc-not-found-error.
---
.../nl/siegmann/epublib/domain/Resource.java | 6 ++-
.../nl/siegmann/epublib/epub/EpubReader.java | 53 +++++++++++++++----
.../siegmann/epublib/util/ResourceUtil.java | 12 ++---
3 files changed, 52 insertions(+), 19 deletions(-)
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
index 7b46e8f1..598501d5 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
@@ -12,6 +12,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.apache.commons.io.IOUtils;
+
import nl.siegmann.epublib.Constants;
import nl.siegmann.epublib.service.MediatypeService;
import nl.siegmann.epublib.util.IOUtil;
@@ -111,7 +113,7 @@ public Resource(Reader in, String href) throws IOException {
* @param href The location of the resource within the epub. Example: "cover.jpg".
*/
public Resource(InputStream in, String href) throws IOException {
- this(null, IOUtil.toByteArray(in), href, MediatypeService.determineMediaType(href));
+ this(null, IOUtils.toByteArray(in), href, MediatypeService.determineMediaType(href));
}
/**
@@ -194,7 +196,7 @@ public byte[] getData() throws IOException {
}
if ( zipEntry.getName().endsWith(this.href)) {
- this.data = IOUtil.toByteArray(in);
+ this.data = IOUtils.toByteArray(in);
}
}
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
index 1fcb7cea..96aff62a 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
@@ -4,8 +4,10 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
+import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import nl.siegmann.epublib.Constants;
@@ -40,7 +42,11 @@ public Book readEpub(InputStream in) throws IOException {
public Book readEpub(ZipInputStream in) throws IOException {
return readEpub(in, Constants.CHARACTER_ENCODING);
}
-
+
+ public Book readEpub(ZipFile zipfile) throws IOException {
+ return readEpub(zipfile, Constants.CHARACTER_ENCODING);
+ }
+
/**
* Read epub from inputstream
*
@@ -90,18 +96,25 @@ public Book readEpubLazy( String fileName, String encoding ) throws IOException
}
public Book readEpub(ZipInputStream in, String encoding) throws IOException {
- Book result = new Book();
- Resources resources = readResources(in, encoding);
- handleMimeType(result, resources);
- String packageResourceHref = getPackageResourceHref(resources);
- Resource packageResource = processPackageResource(packageResourceHref, result, resources);
- result.setOpfResource(packageResource);
- Resource ncxResource = processNcxResource(packageResource, result);
- result.setNcxResource(ncxResource);
- result = postProcessBook(result);
- return result;
+ return readEpubResources(readResources(in, encoding));
}
+ public Book readEpub(ZipFile in, String encoding) throws IOException {
+ return readEpubResources(readResources(in, encoding));
+ }
+
+ public Book readEpubResources(Resources resources) throws IOException{
+ Book result = new Book();
+ handleMimeType(result, resources);
+ String packageResourceHref = getPackageResourceHref(resources);
+ Resource packageResource = processPackageResource(packageResourceHref, result, resources);
+ result.setOpfResource(packageResource);
+ Resource ncxResource = processNcxResource(packageResource, result);
+ result.setNcxResource(ncxResource);
+ result = postProcessBook(result);
+ return result;
+ }
+
private Book postProcessBook(Book book) {
if (bookProcessor != null) {
book = bookProcessor.processBook(book);
@@ -193,4 +206,22 @@ private Resources readResources(ZipInputStream in, String defaultHtmlEncoding) t
}
return result;
}
+
+ private Resources readResources(ZipFile zipFile, String defaultHtmlEncoding) throws IOException {
+ Resources result = new Resources();
+ Enumeration extends ZipEntry> entries = zipFile.entries();
+
+ while(entries.hasMoreElements()){
+ ZipEntry zipEntry = entries.nextElement();
+ if(zipEntry != null && !zipEntry.isDirectory()){
+ Resource resource = ResourceUtil.createResource(zipEntry, zipFile.getInputStream(zipEntry));
+ if(resource.getMediaType() == MediatypeService.XHTML) {
+ resource.setInputEncoding(defaultHtmlEncoding);
+ }
+ result.add(resource);
+ }
+ }
+
+ return result;
+ }
}
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/util/ResourceUtil.java b/epublib-core/src/main/java/nl/siegmann/epublib/util/ResourceUtil.java
index 36ea1a04..1db60226 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/util/ResourceUtil.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/util/ResourceUtil.java
@@ -1,10 +1,6 @@
package nl.siegmann.epublib.util;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.UnsupportedEncodingException;
+import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@@ -64,7 +60,11 @@ public static Resource createResource(ZipEntry zipEntry, ZipInputStream zipInput
return new Resource(zipInputStream, zipEntry.getName());
}
-
+
+ public static Resource createResource(ZipEntry zipEntry, InputStream zipInputStream) throws IOException {
+ return new Resource(zipInputStream, zipEntry.getName());
+
+ }
/**
* Converts a given string from given input character encoding to the requested output character encoding.
From ba2a9bd37f4839fe9b101dabe55cec16f15662c3 Mon Sep 17 00:00:00 2001
From: Alex Kuiper
Date: Wed, 1 May 2013 21:13:09 +0200
Subject: [PATCH 03/57] Small memory optimization.
---
.../nl/siegmann/epublib/domain/Resource.java | 37 ++++++++++-----
.../nl/siegmann/epublib/epub/EpubReader.java | 2 +-
.../java/nl/siegmann/epublib/util/IOUtil.java | 45 +++++++++++++++----
3 files changed, 64 insertions(+), 20 deletions(-)
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
index 7b46e8f1..7204ebe1 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
@@ -1,11 +1,6 @@
package nl.siegmann.epublib.domain;
-import java.io.ByteArrayInputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.io.Serializable;
+import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@@ -111,9 +106,30 @@ public Resource(Reader in, String href) throws IOException {
* @param href The location of the resource within the epub. Example: "cover.jpg".
*/
public Resource(InputStream in, String href) throws IOException {
- this(null, IOUtil.toByteArray(in), href, MediatypeService.determineMediaType(href));
+ this(null, IOUtil.toByteArray(in), href, MediatypeService.determineMediaType(href));
}
-
+
+ /**
+ * Creates a Resource that tries to load the data, but falls back to lazy loading.
+ *
+ * If the size of the resource is known ahead of time we can use that to allocate
+ * a matching byte[]. If this succeeds we can safely load the data.
+ *
+ * If it fails we leave the data null for now and it will be lazy-loaded when
+ * it is accessed.
+ *
+ * @param in
+ * @param fileName
+ * @param length
+ * @param href
+ * @throws IOException
+ */
+ public Resource(InputStream in, String fileName, int length, String href) throws IOException {
+ this( null, IOUtil.toByteArray(in, length), href, MediatypeService.determineMediaType(href));
+ this.fileName = fileName;
+ this.cachedSize = length;
+ }
+
/**
* Creates a Lazy resource, by not actually loading the data for this entry.
*
@@ -141,7 +157,8 @@ public Resource( String fileName, long size, String href) {
public Resource(String id, byte[] data, String href, MediaType mediaType) {
this(id, data, href, mediaType, Constants.CHARACTER_ENCODING);
}
-
+
+
/**
* Creates a resource with the given id, data, mediatype at the specified href.
* If the data is of a text type (html/css/etc) then it will use the given inputEncoding.
@@ -194,7 +211,7 @@ public byte[] getData() throws IOException {
}
if ( zipEntry.getName().endsWith(this.href)) {
- this.data = IOUtil.toByteArray(in);
+ this.data = IOUtil.toByteArray(in, (int) this.cachedSize);
}
}
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
index 1fcb7cea..6cf03616 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
@@ -167,7 +167,7 @@ private Resources readLazyResources( String fileName, String defaultHtmlEncoding
if ( lazyLoadedTypes.contains(mediaType) ) {
resource = new Resource(fileName, zipEntry.getSize(), href);
} else {
- resource = new Resource( in, href );
+ resource = new Resource( in, fileName, (int) zipEntry.getSize(), href );
}
if(resource.getMediaType() == MediatypeService.XHTML) {
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/util/IOUtil.java b/epublib-core/src/main/java/nl/siegmann/epublib/util/IOUtil.java
index 163b720c..89d669af 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/util/IOUtil.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/util/IOUtil.java
@@ -1,12 +1,6 @@
package nl.siegmann.epublib.util;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.io.Writer;
+import java.io.*;
/**
* Most of the functions herein are re-implementations of the ones in apache io IOUtils.
@@ -45,7 +39,40 @@ public static byte[] toByteArray(InputStream in) throws IOException {
return result.toByteArray();
}
- /**
+ /**
+ * Reads data from the InputStream, using the specified buffer size.
+ *
+ * This is meant for situations where memory is tight, since
+ * it prevents buffer expansion.
+ *
+ * @param stream the stream to read data from
+ * @param size the size of the array to create
+ * @return the array, or null
+ * @throws IOException
+ */
+ public static byte[] toByteArray( InputStream in, int size ) throws IOException {
+
+ try {
+ ByteArrayOutputStream result;
+
+ if ( size > 0 ) {
+ result = new ByteArrayOutputStream(size);
+ } else {
+ result = new ByteArrayOutputStream();
+ }
+
+ copy(in, result);
+ result.flush();
+ return result.toByteArray();
+ } catch ( OutOfMemoryError error ) {
+ //Return null so it gets loaded lazily.
+ return null;
+ }
+
+ }
+
+
+ /**
* if totalNrRead < 0 then totalNrRead is returned, if (nrRead + totalNrRead) < Integer.MAX_VALUE then nrRead + totalNrRead is returned, -1 otherwise.
* @param nrRead
* @param totalNrNread
@@ -62,7 +89,7 @@ protected static int calcNewNrReadSize(int nrRead, int totalNrNread) {
}
}
- /**
+ /**
* Copies the contents of the InputStream to the OutputStream.
*
* @param in
From 805ddea206f09c4805a10fb0ea34e7c5407daff3 Mon Sep 17 00:00:00 2001
From: Alex Kuiper
Date: Fri, 7 Jun 2013 18:06:09 +0200
Subject: [PATCH 04/57] Extra check
---
.../main/java/nl/siegmann/epublib/domain/Resource.java | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
index 7204ebe1..9b334694 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
@@ -211,13 +211,19 @@ public byte[] getData() throws IOException {
}
if ( zipEntry.getName().endsWith(this.href)) {
- this.data = IOUtil.toByteArray(in, (int) this.cachedSize);
+ byte[] readData = IOUtil.toByteArray(in, (int) this.cachedSize);
+
+ if ( readData == null ) {
+ throw new IOException("Could not lazy-load data.");
+ } else {
+ this.data = readData;
+ }
}
}
in.close();
}
-
+
return data;
}
From 47046806afaf657180e4ca7bd34a786b2ed746fe Mon Sep 17 00:00:00 2001
From: Veselin Nikolov
Date: Tue, 15 May 2012 14:47:29 +0300
Subject: [PATCH 05/57] Adds support for ePubs with large resources that don't
fit into memory.
Conflicts:
epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
---
.../nl/siegmann/epublib/domain/Resource.java | 67 +++++++++++++------
1 file changed, 46 insertions(+), 21 deletions(-)
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
index 9b334694..867be905 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
@@ -1,18 +1,24 @@
package nl.siegmann.epublib.domain;
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.Serializable;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import nl.siegmann.epublib.Constants;
import nl.siegmann.epublib.service.MediatypeService;
import nl.siegmann.epublib.util.IOUtil;
import nl.siegmann.epublib.util.StringUtil;
import nl.siegmann.epublib.util.commons.io.XmlStreamReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* Represents a resource that is part of the epub.
* A resource can be a html file, image, xml, etc.
@@ -185,7 +191,20 @@ public Resource(String id, byte[] data, String href, MediaType mediaType, String
* @throws IOException
*/
public InputStream getInputStream() throws IOException {
- return new ByteArrayInputStream(getData());
+ if (isInitialized()) {
+ return new ByteArrayInputStream(getData());
+ } else {
+ return getResourceStream();
+ }
+ }
+
+ /**
+ * Initializes the resource by loading its data into memory.
+ *
+ * @throws IOException
+ */
+ public void initialize() throws IOException {
+ getData();
}
/**
@@ -203,22 +222,12 @@ public byte[] getData() throws IOException {
LOG.info("Initializing lazy resource " + fileName + "#" + this.href );
- ZipInputStream in = new ZipInputStream(new FileInputStream(this.fileName));
-
- for(ZipEntry zipEntry = in.getNextEntry(); zipEntry != null; zipEntry = in.getNextEntry()) {
- if(zipEntry.isDirectory()) {
- continue;
- }
-
- if ( zipEntry.getName().endsWith(this.href)) {
- byte[] readData = IOUtil.toByteArray(in, (int) this.cachedSize);
-
- if ( readData == null ) {
- throw new IOException("Could not lazy-load data.");
- } else {
- this.data = readData;
- }
- }
+ ZipInputStream in = getResourceStream();
+ byte[] readData = IOUtil.toByteArray(in, (int) this.cachedSize);
+ if ( readData == null ) {
+ throw new IOException("Could not lazy-load data.");
+ } else {
+ this.data = readData;
}
in.close();
@@ -226,6 +235,22 @@ public byte[] getData() throws IOException {
return data;
}
+
+ private ZipInputStream getResourceStream() throws FileNotFoundException,
+ IOException {
+ ZipInputStream in = new ZipInputStream(new FileInputStream(this.fileName));
+ for(ZipEntry zipEntry = in.getNextEntry(); zipEntry != null; zipEntry = in.getNextEntry()) {
+ if(zipEntry.isDirectory()) {
+ continue;
+ }
+
+ if ( zipEntry.getName().endsWith(this.href)) {
+ return in;
+ }
+ }
+
+ throw new IllegalStateException("Cannot find resources href in the epub file");
+ }
/**
* Tells this resource to release its cached data.
From f681c401d39249160ec4ad452ca68ea5d83abd17 Mon Sep 17 00:00:00 2001
From: ttopalov
Date: Thu, 14 Mar 2013 14:49:45 +0200
Subject: [PATCH 06/57] Otpimized the way the zip entry of a lazy loaded
Resource is found in the epub file.
Conflicts:
epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
---
.../nl/siegmann/epublib/domain/Resource.java | 26 ++++++-------
.../epublib/domain/ResourceInputStream.java | 37 +++++++++++++++++++
2 files changed, 48 insertions(+), 15 deletions(-)
create mode 100644 epublib-core/src/main/java/nl/siegmann/epublib/domain/ResourceInputStream.java
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
index 867be905..b1baa323 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
@@ -1,14 +1,13 @@
package nl.siegmann.epublib.domain;
import java.io.ByteArrayInputStream;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.Serializable;
import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
+import java.util.zip.ZipFile;
import nl.siegmann.epublib.Constants;
import nl.siegmann.epublib.service.MediatypeService;
@@ -35,6 +34,7 @@ public class Resource implements Serializable {
private String id;
private String title;
private String href;
+ private String originalHref;
private MediaType mediaType;
private String inputEncoding = Constants.CHARACTER_ENCODING;
private byte[] data;
@@ -178,6 +178,7 @@ public Resource(String id, byte[] data, String href, MediaType mediaType) {
public Resource(String id, byte[] data, String href, MediaType mediaType, String inputEncoding) {
this.id = id;
this.href = href;
+ this.originalHref = href;
this.mediaType = mediaType;
this.inputEncoding = inputEncoding;
this.data = data;
@@ -222,7 +223,7 @@ public byte[] getData() throws IOException {
LOG.info("Initializing lazy resource " + fileName + "#" + this.href );
- ZipInputStream in = getResourceStream();
+ InputStream in = getResourceStream();
byte[] readData = IOUtil.toByteArray(in, (int) this.cachedSize);
if ( readData == null ) {
throw new IOException("Could not lazy-load data.");
@@ -236,20 +237,15 @@ public byte[] getData() throws IOException {
return data;
}
- private ZipInputStream getResourceStream() throws FileNotFoundException,
+ private InputStream getResourceStream() throws FileNotFoundException,
IOException {
- ZipInputStream in = new ZipInputStream(new FileInputStream(this.fileName));
- for(ZipEntry zipEntry = in.getNextEntry(); zipEntry != null; zipEntry = in.getNextEntry()) {
- if(zipEntry.isDirectory()) {
- continue;
- }
-
- if ( zipEntry.getName().endsWith(this.href)) {
- return in;
- }
+ ZipFile zipResource = new ZipFile(fileName);
+ ZipEntry zipEntry = zipResource.getEntry(originalHref);
+ if (zipEntry == null) {
+ zipResource.close();
+ throw new IllegalStateException("Cannot find resources href in the epub file");
}
-
- throw new IllegalStateException("Cannot find resources href in the epub file");
+ return new ResourceInputStream(zipResource.getInputStream(zipEntry), zipResource);
}
/**
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/ResourceInputStream.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/ResourceInputStream.java
new file mode 100644
index 00000000..1a636f81
--- /dev/null
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/ResourceInputStream.java
@@ -0,0 +1,37 @@
+package nl.siegmann.epublib.domain;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipFile;
+
+
+/**
+ * A wrapper class for closing a ZipFile object when the InputStream derived
+ * from it is closed.
+ *
+ * @author ttopalov
+ *
+ */
+public class ResourceInputStream extends FilterInputStream {
+
+ private ZipFile zipResource;
+
+ /**
+ * Constructor.
+ *
+ * @param in
+ * The InputStream object.
+ * @param f
+ * The ZipFile object.
+ */
+ public ResourceInputStream(InputStream in, ZipFile f) {
+ super(in);
+ zipResource = f;
+ }
+
+ @Override
+ public void close() throws IOException {
+ super.close();
+ zipResource.close();
+ }
+}
From 365554a632fa97d02358f8121502ad59fdf7ecae Mon Sep 17 00:00:00 2001
From: Mayleen Lacouture
Date: Thu, 4 Apr 2013 16:06:45 +0200
Subject: [PATCH 07/57] Added support for reading epub files directly from a
java.zip.ZipFile instead of a ZipInputStream: the ZipInputStream approach
stops reading from the input when a null entry is found, which in some cases
leads to a toc-not-found-error.
Conflicts:
epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
---
.../nl/siegmann/epublib/epub/EpubReader.java | 53 +++++++++++++++----
.../siegmann/epublib/util/ResourceUtil.java | 12 ++---
2 files changed, 48 insertions(+), 17 deletions(-)
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
index 6cf03616..18003810 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
@@ -4,8 +4,10 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
+import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import nl.siegmann.epublib.Constants;
@@ -40,7 +42,11 @@ public Book readEpub(InputStream in) throws IOException {
public Book readEpub(ZipInputStream in) throws IOException {
return readEpub(in, Constants.CHARACTER_ENCODING);
}
-
+
+ public Book readEpub(ZipFile zipfile) throws IOException {
+ return readEpub(zipfile, Constants.CHARACTER_ENCODING);
+ }
+
/**
* Read epub from inputstream
*
@@ -90,18 +96,25 @@ public Book readEpubLazy( String fileName, String encoding ) throws IOException
}
public Book readEpub(ZipInputStream in, String encoding) throws IOException {
- Book result = new Book();
- Resources resources = readResources(in, encoding);
- handleMimeType(result, resources);
- String packageResourceHref = getPackageResourceHref(resources);
- Resource packageResource = processPackageResource(packageResourceHref, result, resources);
- result.setOpfResource(packageResource);
- Resource ncxResource = processNcxResource(packageResource, result);
- result.setNcxResource(ncxResource);
- result = postProcessBook(result);
- return result;
+ return readEpubResources(readResources(in, encoding));
}
+ public Book readEpub(ZipFile in, String encoding) throws IOException {
+ return readEpubResources(readResources(in, encoding));
+ }
+
+ public Book readEpubResources(Resources resources) throws IOException{
+ Book result = new Book();
+ handleMimeType(result, resources);
+ String packageResourceHref = getPackageResourceHref(resources);
+ Resource packageResource = processPackageResource(packageResourceHref, result, resources);
+ result.setOpfResource(packageResource);
+ Resource ncxResource = processNcxResource(packageResource, result);
+ result.setNcxResource(ncxResource);
+ result = postProcessBook(result);
+ return result;
+ }
+
private Book postProcessBook(Book book) {
if (bookProcessor != null) {
book = bookProcessor.processBook(book);
@@ -193,4 +206,22 @@ private Resources readResources(ZipInputStream in, String defaultHtmlEncoding) t
}
return result;
}
+
+ private Resources readResources(ZipFile zipFile, String defaultHtmlEncoding) throws IOException {
+ Resources result = new Resources();
+ Enumeration extends ZipEntry> entries = zipFile.entries();
+
+ while(entries.hasMoreElements()){
+ ZipEntry zipEntry = entries.nextElement();
+ if(zipEntry != null && !zipEntry.isDirectory()){
+ Resource resource = ResourceUtil.createResource(zipEntry, zipFile.getInputStream(zipEntry));
+ if(resource.getMediaType() == MediatypeService.XHTML) {
+ resource.setInputEncoding(defaultHtmlEncoding);
+ }
+ result.add(resource);
+ }
+ }
+
+ return result;
+ }
}
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/util/ResourceUtil.java b/epublib-core/src/main/java/nl/siegmann/epublib/util/ResourceUtil.java
index 36ea1a04..1db60226 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/util/ResourceUtil.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/util/ResourceUtil.java
@@ -1,10 +1,6 @@
package nl.siegmann.epublib.util;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.UnsupportedEncodingException;
+import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@@ -64,7 +60,11 @@ public static Resource createResource(ZipEntry zipEntry, ZipInputStream zipInput
return new Resource(zipInputStream, zipEntry.getName());
}
-
+
+ public static Resource createResource(ZipEntry zipEntry, InputStream zipInputStream) throws IOException {
+ return new Resource(zipInputStream, zipEntry.getName());
+
+ }
/**
* Converts a given string from given input character encoding to the requested output character encoding.
From ae41c312e43050f91d3f3b2fae7c11cba9825287 Mon Sep 17 00:00:00 2001
From: Mayleen Lacouture
Date: Thu, 11 Jul 2013 16:24:32 +0200
Subject: [PATCH 08/57] Add sbt build file to project
---
epublib-core/build.sbt | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100644 epublib-core/build.sbt
diff --git a/epublib-core/build.sbt b/epublib-core/build.sbt
new file mode 100644
index 00000000..07c74f76
--- /dev/null
+++ b/epublib-core/build.sbt
@@ -0,0 +1,14 @@
+scalaVersion := "2.10.1"
+
+libraryDependencies += "net.sf.kxml" % "kxml2" % "2.3.0"
+
+libraryDependencies += "xmlpull" % "xmlpull" % "1.1.3.4d_b4_min"
+
+libraryDependencies += "org.slf4j" % "slf4j-api" % "1.6.1"
+
+libraryDependencies += "org.slf4j" % "slf4j-simple" % "1.6.1"
+
+libraryDependencies += "junit" % "junit" % "4.10"
+
+libraryDependencies += "commons-io" % "commons-io" % "2.1"
+
From 0d25a18153c4751a6a7e51055c740287d9c1186e Mon Sep 17 00:00:00 2001
From: Mayleen Lacouture
Date: Tue, 16 Jul 2013 16:22:44 +0200
Subject: [PATCH 09/57] Complete sbt project file
---
epublib-core/build.sbt | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/epublib-core/build.sbt b/epublib-core/build.sbt
index 07c74f76..c40a3905 100644
--- a/epublib-core/build.sbt
+++ b/epublib-core/build.sbt
@@ -1,5 +1,13 @@
scalaVersion := "2.10.1"
+name := "epublib-core"
+
+organization := "nl.siegmann.epublib"
+
+version := "3.1"
+
+publishMavenStyle := true
+
libraryDependencies += "net.sf.kxml" % "kxml2" % "2.3.0"
libraryDependencies += "xmlpull" % "xmlpull" % "1.1.3.4d_b4_min"
@@ -12,3 +20,4 @@ libraryDependencies += "junit" % "junit" % "4.10"
libraryDependencies += "commons-io" % "commons-io" % "2.1"
+
From e56a8fb808adae8148106229dd8fb2ed8d728f9c Mon Sep 17 00:00:00 2001
From: Dave Jarvis
Date: Sat, 7 Sep 2013 00:51:47 -0700
Subject: [PATCH 10/57] Metadata no longer has coverImage.
Note that the Metadata class still contains an unused reference to coverImage.
---
README.markdown | 111 ++++++++++++++++++++++++++++--------------------
1 file changed, 65 insertions(+), 46 deletions(-)
diff --git a/README.markdown b/README.markdown
index 4c226235..bcac2189 100644
--- a/README.markdown
+++ b/README.markdown
@@ -22,54 +22,73 @@ Set the cover image of an existing epub
package nl.siegmann.epublib.examples;
+ import java.io.InputStream;
import java.io.FileOutputStream;
-
+
import nl.siegmann.epublib.domain.Author;
import nl.siegmann.epublib.domain.Book;
- import nl.siegmann.epublib.domain.InputStreamResource;
- import nl.siegmann.epublib.domain.Section;
+ import nl.siegmann.epublib.domain.Metadata;
+ import nl.siegmann.epublib.domain.Resource;
+ import nl.siegmann.epublib.domain.TOCReference;
+
import nl.siegmann.epublib.epub.EpubWriter;
-
- public class Simple1 {
- public static void main(String[] args) {
- try {
- // Create new Book
- Book book = new Book();
-
- // Set the title
- book.getMetadata().addTitle("Epublib test book 1");
-
- // Add an Author
- book.getMetadata().addAuthor(new Author("Joe", "Tester"));
-
- // Set cover image
- book.getMetadata().setCoverImage(new InputStreamResource(Simple1.class.getResourceAsStream("/book1/test_cover.png"), "cover.png"));
-
- // Add Chapter 1
- book.addResourceAsSection("Introduction", new InputStreamResource(Simple1.class.getResourceAsStream("/book1/chapter1.html"), "chapter1.html"));
-
- // Add css file
- book.getResources().add(new InputStreamResource(Simple1.class.getResourceAsStream("/book1/book1.css"), "book1.css"));
-
- // Add Chapter 2
- Section chapter2 = book.addResourceAsSection("Second Chapter", new InputStreamResource(Simple1.class.getResourceAsStream("/book1/chapter2.html"), "chapter2.html"));
-
- // Add image used by Chapter 2
- book.getResources().add(new InputStreamResource(Simple1.class.getResourceAsStream("/book1/flowers_320x240.jpg"), "flowers.jpg"));
-
- // Add Chapter2, Section 1
- book.addResourceAsSubSection(chapter2, "Chapter 2, section 1", new InputStreamResource(Simple1.class.getResourceAsStream("/book1/chapter2_1.html"), "chapter2_1.html"));
-
- // Add Chapter 3
- book.addResourceAsSection("Conclusion", new InputStreamResource(Simple1.class.getResourceAsStream("/book1/chapter3.html"), "chapter3.html"));
-
- // Create EpubWriter
- EpubWriter epubWriter = new EpubWriter();
-
- // Write the Book as Epub
- epubWriter.write(book, new FileOutputStream("test1_book1.epub"));
- } catch(Exception e) {
- e.printStackTrace();
- }
- }
+
+ public class Translator {
+ private static InputStream getResource( String path ) {
+ return Translator.class.getResourceAsStream( path );
+ }
+
+ private static Resource getResource( String path, String href ) {
+ return new Resource( getResource( path ), href );
+ }
+
+ public static void main(String[] args) {
+ try {
+ // Create new Book
+ Book book = new Book();
+ Metadata metadata = book.getMetadata();
+
+ // Set the title
+ metadata.addTitle("Epublib test book 1");
+
+ // Add an Author
+ metadata.addAuthor(new Author("Joe", "Tester"));
+
+ // Set cover image
+ book.setCoverImage(
+ getResource("/book1/test_cover.png", "cover.png") );
+
+ // Add Chapter 1
+ book.addSection("Introduction",
+ getResource("/book1/chapter1.html", "chapter1.html") );
+
+ // Add css file
+ book.getResources().add(
+ getResource("/book1/book1.css", "book1.css") );
+
+ // Add Chapter 2
+ TOCReference chapter2 = book.addSection( "Second Chapter",
+ getResource("/book1/chapter2.html", "chapter2.html") );
+
+ // Add image used by Chapter 2
+ book.getResources().add(
+ getResource("/book1/flowers_320x240.jpg", "flowers.jpg"));
+
+ // Add Chapter2, Section 1
+ book.addSection(chapter2, "Chapter 2, section 1",
+ getResource("/book1/chapter2_1.html", "chapter2_1.html"));
+
+ // Add Chapter 3
+ book.addSection("Conclusion",
+ getResource("/book1/chapter3.html", "chapter3.html"));
+
+ // Create EpubWriter
+ EpubWriter epubWriter = new EpubWriter();
+
+ // Write the Book as Epub
+ epubWriter.write(book, new FileOutputStream("test1_book1.epub"));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
}
From 202e9c4177dd010971f6a69189856cdc59f936d0 Mon Sep 17 00:00:00 2001
From: psiegman
Date: Mon, 9 Sep 2013 20:27:54 +0200
Subject: [PATCH 11/57] remove unused class
---
.../src/main/java/nl/siegmann/epublib/util/DomUtil.java | 9 ---------
1 file changed, 9 deletions(-)
delete mode 100644 epublib-core/src/main/java/nl/siegmann/epublib/util/DomUtil.java
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/util/DomUtil.java b/epublib-core/src/main/java/nl/siegmann/epublib/util/DomUtil.java
deleted file mode 100644
index 4ca8dc37..00000000
--- a/epublib-core/src/main/java/nl/siegmann/epublib/util/DomUtil.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package nl.siegmann.epublib.util;
-
-import org.w3c.dom.Node;
-
-public class DomUtil {
-
- public static void getFirstChildWithTagname(String tagname, Node parentNode) {
- }
-}
From 69ff55d2ba62b4ac347ae0c4b035192fba736dd4 Mon Sep 17 00:00:00 2001
From: psiegman
Date: Mon, 9 Sep 2013 20:29:04 +0200
Subject: [PATCH 12/57] refactoring and more testing
---
.../nl/siegmann/epublib/domain/Metadata.java | 12 +++-
.../epub/PackageDocumentMetadataReader.java | 24 +++++++-
.../epublib/epub/PackageDocumentReader.java | 2 +-
.../PackageDocumentMetadataReaderTest.java | 55 +++++++++++++++++--
4 files changed, 82 insertions(+), 11 deletions(-)
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Metadata.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Metadata.java
index 680ca886..1be02862 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Metadata.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Metadata.java
@@ -41,8 +41,8 @@ public class Metadata implements Serializable {
private List types = new ArrayList();
private List descriptions = new ArrayList();
private List publishers = new ArrayList();
- private Resource coverImage;
-
+ private Map metaAttributes = new HashMap();
+
public Metadata() {
identifiers.add(new Identifier());
autoGeneratedId = true;
@@ -207,4 +207,12 @@ public List getTypes() {
public void setTypes(List types) {
this.types = types;
}
+
+ public String getMetaAttribute(String name) {
+ return metaAttributes.get(name);
+ }
+
+ public void setMetaAttributes(Map metaAttributes) {
+ this.metaAttributes = metaAttributes;
+ }
}
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReader.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReader.java
index 33dd8d7f..707de36c 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReader.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReader.java
@@ -11,7 +11,6 @@
import nl.siegmann.epublib.domain.Date;
import nl.siegmann.epublib.domain.Identifier;
import nl.siegmann.epublib.domain.Metadata;
-import nl.siegmann.epublib.domain.Resources;
import nl.siegmann.epublib.util.StringUtil;
import org.slf4j.Logger;
@@ -34,7 +33,7 @@ class PackageDocumentMetadataReader extends PackageDocumentBase {
private static final Logger log = LoggerFactory.getLogger(PackageDocumentMetadataReader.class);
- public static Metadata readMetadata(Document packageDocument, Resources resources) {
+ public static Metadata readMetadata(Document packageDocument) {
Metadata result = new Metadata();
Element metadataElement = DOMUtil.getFirstElementByTagNameNS(packageDocument.getDocumentElement(), NAMESPACE_OPF, OPFTags.metadata);
if(metadataElement == null) {
@@ -52,7 +51,7 @@ public static Metadata readMetadata(Document packageDocument, Resources resource
result.setContributors(readContributors(metadataElement));
result.setDates(readDates(metadataElement));
result.setOtherProperties(readOtherProperties(metadataElement));
-
+ result.setMetaAttributes(readMetaProperties(metadataElement));
Element languageTag = DOMUtil.getFirstElementByTagNameNS(metadataElement, NAMESPACE_DUBLIN_CORE, DCTags.language);
if (languageTag != null) {
result.setLanguage(DOMUtil.getTextChildrenContent(languageTag));
@@ -85,6 +84,25 @@ private static Map readOtherProperties(Element metadataElement) {
return result;
}
+ /**
+ * consumes meta tags that have a property attribute as defined in the standard. For example:
+ * <meta property="rendition:layout">pre-paginated</meta>
+ * @param metadataElement
+ * @return
+ */
+ private static Map readMetaProperties(Element metadataElement) {
+ Map result = new HashMap();
+
+ NodeList metaTags = metadataElement.getElementsByTagName(OPFTags.meta);
+ for (int i = 0; i < metaTags.getLength(); i++) {
+ Element metaElement = (Element) metaTags.item(i);
+ String name = metaElement.getAttribute(OPFAttributes.name);
+ String value = DOMUtil.getTextChildrenContent(metaElement);
+ result.put(name, value);
+ }
+
+ return result;
+ }
private static String getBookIdId(Document document) {
Element packageElement = DOMUtil.getFirstElementByTagNameNS(document.getDocumentElement(), NAMESPACE_OPF, OPFTags.packageTag);
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentReader.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentReader.java
index 9c3d64d3..a57ddb09 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentReader.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentReader.java
@@ -58,7 +58,7 @@ public static void read(Resource packageResource, EpubReader epubReader, Book bo
resources = readManifest(packageDocument, packageHref, epubReader, resources, idMapping);
book.setResources(resources);
readCover(packageDocument, book);
- book.setMetadata(PackageDocumentMetadataReader.readMetadata(packageDocument, book.getResources()));
+ book.setMetadata(PackageDocumentMetadataReader.readMetadata(packageDocument));
book.setSpine(readSpine(packageDocument, epubReader, book.getResources(), idMapping));
// if we did not find a cover page then we make the first page of the book the cover page
diff --git a/epublib-core/src/test/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReaderTest.java b/epublib-core/src/test/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReaderTest.java
index a2e7d872..b0851f28 100644
--- a/epublib-core/src/test/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReaderTest.java
+++ b/epublib-core/src/test/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReaderTest.java
@@ -1,18 +1,23 @@
package nl.siegmann.epublib.epub;
+import java.io.IOException;
+import java.io.StringReader;
+
import junit.framework.TestCase;
+import nl.siegmann.epublib.domain.Identifier;
import nl.siegmann.epublib.domain.Metadata;
-import nl.siegmann.epublib.domain.Resources;
+import org.junit.Assert;
import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
public class PackageDocumentMetadataReaderTest extends TestCase {
public void test1() {
try {
Document document = EpubProcessorSupport.createDocumentBuilder().parse(PackageDocumentMetadataReader.class.getResourceAsStream("/opf/test2.opf"));
- Resources resources = new Resources();
- Metadata metadata = PackageDocumentMetadataReader.readMetadata(document, resources);
+ Metadata metadata = PackageDocumentMetadataReader.readMetadata(document);
assertEquals(1, metadata.getAuthors().size());
} catch (Exception e) {
e.printStackTrace();
@@ -33,9 +38,8 @@ public void testDefaultsToEnglish() {
private Metadata getMetadata(String file) {
try {
Document document = EpubProcessorSupport.createDocumentBuilder().parse(PackageDocumentMetadataReader.class.getResourceAsStream(file));
- Resources resources = new Resources();
- return PackageDocumentMetadataReader.readMetadata(document, resources);
+ return PackageDocumentMetadataReader.readMetadata(document);
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
@@ -43,4 +47,45 @@ private Metadata getMetadata(String file) {
return null;
}
}
+
+ public void test2() throws SAXException, IOException {
+ // given
+ String input = ""
+ + ""
+ + "Three Men in a Boat"
+ + "Jerome K. Jerome"
+ + "A. Frederics"
+ + "en"
+ + "1889"
+ + "2009-05-17"
+ + "zelda@mobileread.com:2010040720"
+ + "zelda pinwheel"
+ + "zelda pinwheel"
+ + "Public Domain"
+ + "Text"
+ + "Image"
+ + "Travel"
+ + "Humour"
+ + "Three Men in a Boat (To Say Nothing of the Dog), published in 1889, is a humorous account by Jerome K. Jerome of a boating holiday on the Thames between Kingston and Oxford. The book was initially intended to be a serious travel guide, with accounts of local history along the route, but the humorous elements took over to the point where the serious and somewhat sentimental passages seem a distraction to the comic novel. One of the most praised things about Three Men in a Boat is how undated it appears to modern readers, the jokes seem fresh and witty even today."
+ + ""
+ + ""
+ + ""
+ + "";
+
+ // when
+ Document metadataDocument = EpubProcessorSupport.createDocumentBuilder().parse(new InputSource(new StringReader(input)));
+ Metadata metadata = PackageDocumentMetadataReader.readMetadata(metadataDocument);
+
+ // then
+ Assert.assertEquals("Three Men in a Boat", metadata.getFirstTitle());
+
+ // test identifier
+ Assert.assertNotNull(metadata.getIdentifiers());
+ Assert.assertEquals(1, metadata.getIdentifiers().size());
+ Identifier identifier = metadata.getIdentifiers().get(0);
+ Assert.assertEquals("URI", identifier.getScheme());
+ Assert.assertEquals("zelda@mobileread.com:2010040720", identifier.getValue());
+
+ Assert.assertEquals("8", metadata.getMetaAttribute("calibre:rating"));
+ }
}
From e5ccfcbbccc2167cb9dcf8a81f4805ff23375c92 Mon Sep 17 00:00:00 2001
From: psiegman
Date: Mon, 9 Sep 2013 20:29:35 +0200
Subject: [PATCH 13/57] attempt at making the github repo work again
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 886d3b2e..6e2000d5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,7 +50,7 @@
github.repo
- file:///D:/private/project/git-maven-repo/mvn-repo
+ file:///D:/private/project/git-maven-repo/mvn-repo/releases
From b938462c0049d8ba83913a403fef60b6bc2cdc30 Mon Sep 17 00:00:00 2001
From: psiegman
Date: Mon, 9 Sep 2013 20:58:40 +0200
Subject: [PATCH 14/57] fix getting of meta attribute values
---
.../nl/siegmann/epublib/epub/PackageDocumentMetadataReader.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReader.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReader.java
index 707de36c..5e6a3d6c 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReader.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReader.java
@@ -97,7 +97,7 @@ private static Map readMetaProperties(Element metadataElement) {
for (int i = 0; i < metaTags.getLength(); i++) {
Element metaElement = (Element) metaTags.item(i);
String name = metaElement.getAttribute(OPFAttributes.name);
- String value = DOMUtil.getTextChildrenContent(metaElement);
+ String value = metaElement.getAttribute(OPFAttributes.content);
result.put(name, value);
}
From 1d5f89a013b26b730422780927fe62fa724a4ca2 Mon Sep 17 00:00:00 2001
From: psiegman
Date: Mon, 9 Sep 2013 21:02:32 +0200
Subject: [PATCH 15/57] add another test
---
.../siegmann/epublib/epub/PackageDocumentMetadataReaderTest.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/epublib-core/src/test/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReaderTest.java b/epublib-core/src/test/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReaderTest.java
index b0851f28..c4623206 100644
--- a/epublib-core/src/test/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReaderTest.java
+++ b/epublib-core/src/test/java/nl/siegmann/epublib/epub/PackageDocumentMetadataReaderTest.java
@@ -87,5 +87,6 @@ public void test2() throws SAXException, IOException {
Assert.assertEquals("zelda@mobileread.com:2010040720", identifier.getValue());
Assert.assertEquals("8", metadata.getMetaAttribute("calibre:rating"));
+ Assert.assertEquals("cover_pic", metadata.getMetaAttribute("cover"));
}
}
From ecc3b528b90b77d761aa7b08bd9eb361e6897479 Mon Sep 17 00:00:00 2001
From: psiegman
Date: Mon, 9 Sep 2013 21:45:38 +0200
Subject: [PATCH 16/57] Make images work in the viewer on Windows
---
.../java/nl/siegmann/epublib/viewer/ImageLoaderCache.java | 3 +++
.../src/main/java/nl/siegmann/epublib/viewer/Viewer.java | 4 +---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ImageLoaderCache.java b/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ImageLoaderCache.java
index dc921466..2ca5a250 100644
--- a/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ImageLoaderCache.java
+++ b/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ImageLoaderCache.java
@@ -85,6 +85,9 @@ private String getResourceHref(String requestUrl) {
String resourceHref = requestUrl.toString().substring(IMAGE_URL_PREFIX.length());
resourceHref = currentFolder + resourceHref;
resourceHref = FilenameUtils.normalize(resourceHref);
+ // normalize uses the SYSTEM_SEPARATOR, which on windows is a '\'
+ // replace with '/' to make it href '/'
+ resourceHref = resourceHref.replaceAll("\\\\", "/");
return resourceHref;
}
diff --git a/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/Viewer.java b/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/Viewer.java
index 6506e933..eea823f8 100644
--- a/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/Viewer.java
+++ b/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/Viewer.java
@@ -40,8 +40,6 @@
public class Viewer {
- private static final long serialVersionUID = 1610691708767665447L;
-
static final Logger log = LoggerFactory.getLogger(Viewer.class);
private final JFrame mainWindow;
private BrowseBar browseBar;
@@ -49,7 +47,7 @@ public class Viewer {
private JSplitPane leftSplitPane;
private JSplitPane rightSplitPane;
private Navigator navigator = new Navigator();
- NavigationHistory browserHistory;
+ private NavigationHistory browserHistory;
private BookProcessorPipeline epubCleaner = new BookProcessorPipeline(Collections.emptyList());
public Viewer(InputStream bookStream) {
From 24736e45c9ef8704e31ea8cc43faa3e10a3347d3 Mon Sep 17 00:00:00 2001
From: psiegman
Date: Mon, 9 Sep 2013 22:41:11 +0200
Subject: [PATCH 17/57] removed commons-io dependency from epublib-core
---
epublib-core/build.sbt | 2 -
epublib-core/pom.xml | 6 -
.../nl/siegmann/epublib/domain/Resource.java | 5 +-
.../nl/siegmann/epublib/epub/NCXDocument.java | 3 +-
.../nl/siegmann/epublib/util/StringUtil.java | 82 +++++--
.../epublib/epub/NCXDocumentTest.java | 24 +-
.../siegmann/epublib/util/StringUtilTest.java | 223 ++++++++----------
7 files changed, 177 insertions(+), 168 deletions(-)
diff --git a/epublib-core/build.sbt b/epublib-core/build.sbt
index c40a3905..4ae23e47 100644
--- a/epublib-core/build.sbt
+++ b/epublib-core/build.sbt
@@ -18,6 +18,4 @@ libraryDependencies += "org.slf4j" % "slf4j-simple" % "1.6.1"
libraryDependencies += "junit" % "junit" % "4.10"
-libraryDependencies += "commons-io" % "commons-io" % "2.1"
-
diff --git a/epublib-core/pom.xml b/epublib-core/pom.xml
index ec676b6a..c8d0f0a8 100644
--- a/epublib-core/pom.xml
+++ b/epublib-core/pom.xml
@@ -46,12 +46,6 @@
4.10test
-
- commons-io
- commons-io
- 2.1
- jar
-
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
index 3f367c61..1f563ab1 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
@@ -9,7 +9,6 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
-import org.apache.commons.io.IOUtils;
import nl.siegmann.epublib.Constants;
import nl.siegmann.epublib.service.MediatypeService;
@@ -114,7 +113,7 @@ public Resource(Reader in, String href) throws IOException {
* @param href The location of the resource within the epub. Example: "cover.jpg".
*/
public Resource(InputStream in, String href) throws IOException {
- this(null, IOUtils.toByteArray(in), href, MediatypeService.determineMediaType(href));
+ this(null, IOUtil.toByteArray(in), href, MediatypeService.determineMediaType(href));
}
/**
@@ -233,7 +232,7 @@ public byte[] getData() throws IOException {
throw new IOException("Could not lazy-load data.");
} else {
this.data = readData;
- this.data = IOUtils.toByteArray(in);
+ this.data = IOUtil.toByteArray(in);
}
in.close();
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/NCXDocument.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/NCXDocument.java
index af089132..b7e6c579 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/epub/NCXDocument.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/NCXDocument.java
@@ -21,7 +21,6 @@
import nl.siegmann.epublib.service.MediatypeService;
import nl.siegmann.epublib.util.ResourceUtil;
import nl.siegmann.epublib.util.StringUtil;
-import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -119,7 +118,7 @@ private static List readTOCReferences(NodeList navpoints, Book boo
private static TOCReference readTOCReference(Element navpointElement, Book book) {
String label = readNavLabel(navpointElement);
- String reference = FilenameUtils.getPath(book.getSpine().getTocResource().getHref())+readNavReference(navpointElement);
+ String reference = StringUtil.substringBeforeLast(book.getSpine().getTocResource().getHref(), '/') + '/' + readNavReference(navpointElement);
String href = StringUtil.substringBefore(reference, Constants.FRAGMENT_SEPARATOR_CHAR);
String fragmentId = StringUtil.substringAfter(reference, Constants.FRAGMENT_SEPARATOR_CHAR);
Resource resource = book.getResources().getByHref(href);
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/util/StringUtil.java b/epublib-core/src/main/java/nl/siegmann/epublib/util/StringUtil.java
index eadae95a..3735c652 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/util/StringUtil.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/util/StringUtil.java
@@ -7,24 +7,62 @@
/**
* Various String utility functions.
*
- * Most of the functions herein are re-implementations of the ones in apache commons StringUtils.
- * The reason for re-implementing this is that the functions are fairly simple and using my own implementation saves the inclusion of a 200Kb jar file.
+ * Most of the functions herein are re-implementations of the ones in apache
+ * commons StringUtils. The reason for re-implementing this is that the
+ * functions are fairly simple and using my own implementation saves the
+ * inclusion of a 200Kb jar file.
*
* @author paul.siegmann
- *
+ *
*/
public class StringUtil {
/**
- * Whether the String is not null, not zero-length and does not contain of only whitespace.
+ * Changes a path containing '..', '.' and empty dirs into a path that
+ * doesn't. X/foo/../Y is changed into 'X/Y', etc. Does not handle invalid
+ * paths like "../".
+ *
+ * @param path
+ * @return
+ */
+ public static String collapsePathDots(String path) {
+ String[] stringParts = path.split("/");
+ List parts = new ArrayList(Arrays.asList(stringParts));
+ for (int i = 0; i < parts.size() - 1; i++) {
+ String currentDir = parts.get(i);
+ if (currentDir.length() == 0 || currentDir.equals(".")) {
+ parts.remove(i);
+ i--;
+ } else if (currentDir.equals("..")) {
+ parts.remove(i - 1);
+ parts.remove(i - 1);
+ i -= 2;
+ }
+ }
+ StringBuilder result = new StringBuilder();
+ if (path.startsWith("/")) {
+ result.append('/');
+ }
+ for (int i = 0; i < parts.size(); i++) {
+ result.append(parts.get(i));
+ if (i < (parts.size() - 1)) {
+ result.append('/');
+ }
+ }
+ return result.toString();
+ }
+
+ /**
+ * Whether the String is not null, not zero-length and does not contain of
+ * only whitespace.
*
* @param text
* @return
*/
public static boolean isNotBlank(String text) {
- return ! isBlank(text);
+ return !isBlank(text);
}
-
+
/**
* Whether the String is null, zero-length and does contain only whitespace.
*/
@@ -33,13 +71,13 @@ public static boolean isBlank(String text) {
return true;
}
for (int i = 0; i < text.length(); i++) {
- if (! Character.isWhitespace(text.charAt(i))) {
+ if (!Character.isWhitespace(text.charAt(i))) {
return false;
}
}
return true;
}
-
+
/**
* Whether the given string is null or zero-length.
*
@@ -49,9 +87,10 @@ public static boolean isBlank(String text) {
public static boolean isEmpty(String text) {
return (text == null) || (text.length() == 0);
}
-
+
/**
- * Whether the given source string ends with the given suffix, ignoring case.
+ * Whether the given source string ends with the given suffix, ignoring
+ * case.
*
* @param source
* @param suffix
@@ -67,10 +106,11 @@ public static boolean endsWithIgnoreCase(String source, String suffix) {
if (suffix.length() > source.length()) {
return false;
}
- return source.substring(source.length() - suffix.length()).toLowerCase().endsWith(suffix.toLowerCase());
+ return source.substring(source.length() - suffix.length())
+ .toLowerCase().endsWith(suffix.toLowerCase());
}
-
- /**
+
+ /**
* If the given text is null return "", the original text otherwise.
*
* @param text
@@ -114,7 +154,7 @@ public static boolean equals(String text1, String text2) {
* @param keyValues
* @return
*/
- public static String toString(Object ... keyValues) {
+ public static String toString(Object... keyValues) {
StringBuilder result = new StringBuilder();
result.append('[');
for (int i = 0; i < keyValues.length; i += 2) {
@@ -139,7 +179,7 @@ public static String toString(Object ... keyValues) {
return result.toString();
}
- public static int hashCode(String ... values) {
+ public static int hashCode(String... values) {
int result = 31;
for (int i = 0; i < values.length; i++) {
result ^= String.valueOf(values[i]).hashCode();
@@ -150,7 +190,8 @@ public static int hashCode(String ... values) {
/**
* Gives the substring of the given text before the given separator.
*
- * If the text does not contain the given separator then the given text is returned.
+ * If the text does not contain the given separator then the given text is
+ * returned.
*
* @param text
* @param separator
@@ -168,9 +209,11 @@ public static String substringBefore(String text, char separator) {
}
/**
- * Gives the substring of the given text before the last occurrence of the given separator.
+ * Gives the substring of the given text before the last occurrence of the
+ * given separator.
*
- * If the text does not contain the given separator then the given text is returned.
+ * If the text does not contain the given separator then the given text is
+ * returned.
*
* @param text
* @param separator
@@ -188,7 +231,8 @@ public static String substringBeforeLast(String text, char separator) {
}
/**
- * Gives the substring of the given text after the last occurrence of the given separator.
+ * Gives the substring of the given text after the last occurrence of the
+ * given separator.
*
* If the text does not contain the given separator then "" is returned.
*
diff --git a/epublib-core/src/test/java/nl/siegmann/epublib/epub/NCXDocumentTest.java b/epublib-core/src/test/java/nl/siegmann/epublib/epub/NCXDocumentTest.java
index e8905ff8..a64f9c2c 100644
--- a/epublib-core/src/test/java/nl/siegmann/epublib/epub/NCXDocumentTest.java
+++ b/epublib-core/src/test/java/nl/siegmann/epublib/epub/NCXDocumentTest.java
@@ -1,20 +1,21 @@
package nl.siegmann.epublib.epub;
+import static org.junit.Assert.assertEquals;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
+
import nl.siegmann.epublib.domain.Book;
-import nl.siegmann.epublib.domain.GuideReference;
import nl.siegmann.epublib.domain.Resource;
-import nl.siegmann.epublib.domain.TOCReference;
import nl.siegmann.epublib.service.MediatypeService;
-import org.apache.commons.io.FileUtils;
+import nl.siegmann.epublib.util.IOUtil;
+
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
-import static org.junit.Assert.*;
public class NCXDocumentTest {
@@ -33,13 +34,19 @@ public static void tearDownClass() {
@Before
public void setUp() throws IOException {
- ncxData = FileUtils.readFileToByteArray(new File("src/test/resources/toc.xml"));
+ ncxData = IOUtil.toByteArray(new FileInputStream(new File("src/test/resources/toc.xml")));
}
@After
public void tearDown() {
}
+ private void addResource(Book book, String filename) {
+ Resource chapterResource = new Resource("id1", "Hello, world !".getBytes(), filename, MediatypeService.XHTML);
+ book.addResource(chapterResource);
+ book.getSpine().addResource(chapterResource);
+ }
+
/**
* Test of read method, of class NCXDocument.
*/
@@ -49,9 +56,10 @@ public void testReadWithNonRootLevelTOC() {
// If the tox.ncx file is not in the root, the hrefs it refers to need to preserve its path.
Book book = new Book();
Resource ncxResource = new Resource(ncxData, "xhtml/toc.ncx");
- Resource chapterResource = new Resource("id1", "Hello, world !".getBytes(), "xhtml/chapter1.html", MediatypeService.XHTML);
- book.addResource(chapterResource);
- book.getSpine().addResource(chapterResource);
+ addResource(book, "xhtml/chapter1.html");
+ addResource(book, "xhtml/chapter2.html");
+ addResource(book, "xhtml/chapter2_1.html");
+ addResource(book, "xhtml/chapter3.html");
book.setNcxResource(ncxResource);
book.getSpine().setTocResource(ncxResource);
diff --git a/epublib-core/src/test/java/nl/siegmann/epublib/util/StringUtilTest.java b/epublib-core/src/test/java/nl/siegmann/epublib/util/StringUtilTest.java
index 062bd0f8..fb990421 100644
--- a/epublib-core/src/test/java/nl/siegmann/epublib/util/StringUtilTest.java
+++ b/epublib-core/src/test/java/nl/siegmann/epublib/util/StringUtilTest.java
@@ -1,65 +1,50 @@
package nl.siegmann.epublib.util;
import java.io.IOException;
+
import junit.framework.TestCase;
-import org.apache.commons.io.FilenameUtils;
public class StringUtilTest extends TestCase {
public void testDefaultIfNull() {
- Object[] testData = new Object[] {
- null, "",
- "", "",
- " ", " ",
- "foo", "foo"
- };
+ Object[] testData = new Object[] { null, "", "", "", " ", " ", "foo",
+ "foo" };
for (int i = 0; i < testData.length; i += 2) {
- String actualResult = StringUtil.defaultIfNull((String) testData[i]);
+ String actualResult = StringUtil
+ .defaultIfNull((String) testData[i]);
String expectedResult = (String) testData[i + 1];
- assertEquals((i / 2) + " : " + testData[i], expectedResult, actualResult);
+ assertEquals((i / 2) + " : " + testData[i], expectedResult,
+ actualResult);
}
}
public void testDefaultIfNull_with_default() {
- Object[] testData = new Object[] {
- null, null, null,
- "", null, "",
- null, "", "",
- "foo", "", "foo",
- "", "foo", "",
- " ", " ", " ",
- null, "foo", "foo",
- };
+ Object[] testData = new Object[] { null, null, null, "", null, "",
+ null, "", "", "foo", "", "foo", "", "foo", "", " ", " ", " ",
+ null, "foo", "foo", };
for (int i = 0; i < testData.length; i += 3) {
- String actualResult = StringUtil.defaultIfNull((String) testData[i], (String) testData[i + 1]);
+ String actualResult = StringUtil.defaultIfNull(
+ (String) testData[i], (String) testData[i + 1]);
String expectedResult = (String) testData[i + 2];
- assertEquals((i / 3) + " : " + testData[i] + ", " + testData[i + 1], expectedResult, actualResult);
+ assertEquals(
+ (i / 3) + " : " + testData[i] + ", " + testData[i + 1],
+ expectedResult, actualResult);
}
}
-
+
public void testIsEmpty() {
- Object[] testData = new Object[] {
- null, true,
- "", true,
- " ", false,
- "asdfasfd", false
- };
+ Object[] testData = new Object[] { null, true, "", true, " ", false,
+ "asdfasfd", false };
for (int i = 0; i < testData.length; i += 2) {
boolean actualResult = StringUtil.isEmpty((String) testData[i]);
boolean expectedResult = (Boolean) testData[i + 1];
assertEquals(expectedResult, actualResult);
}
}
-
public void testIsBlank() {
- Object[] testData = new Object[] {
- null, true,
- "", true,
- " ", true,
- "\t\t \n\n", true,
- "asdfasfd", false
- };
+ Object[] testData = new Object[] { null, true, "", true, " ", true,
+ "\t\t \n\n", true, "asdfasfd", false };
for (int i = 0; i < testData.length; i += 2) {
boolean actualResult = StringUtil.isBlank((String) testData[i]);
boolean expectedResult = (Boolean) testData[i + 1];
@@ -68,150 +53,132 @@ public void testIsBlank() {
}
public void testIsNotBlank() {
- Object[] testData = new Object[] {
- null, ! true,
- "", ! true,
- " ", ! true,
- "\t\t \n\n", ! true,
- "asdfasfd", ! false
- };
+ Object[] testData = new Object[] { null, !true, "", !true, " ", !true,
+ "\t\t \n\n", !true, "asdfasfd", !false };
for (int i = 0; i < testData.length; i += 2) {
boolean actualResult = StringUtil.isNotBlank((String) testData[i]);
boolean expectedResult = (Boolean) testData[i + 1];
- assertEquals((i / 2) + " : " + testData[i], expectedResult, actualResult);
+ assertEquals((i / 2) + " : " + testData[i], expectedResult,
+ actualResult);
}
}
-
public void testEquals() {
- Object[] testData = new Object[] {
- null, null, true,
- "", "", true,
- null, "", false,
- "", null, false,
- null, "foo", false,
- "foo", null, false,
- "", "foo", false,
- "foo", "", false,
- "foo", "bar", false,
- "foo", "foo", true
- };
+ Object[] testData = new Object[] { null, null, true, "", "", true,
+ null, "", false, "", null, false, null, "foo", false, "foo",
+ null, false, "", "foo", false, "foo", "", false, "foo", "bar",
+ false, "foo", "foo", true };
for (int i = 0; i < testData.length; i += 3) {
- boolean actualResult = StringUtil.equals( (String) testData[i], (String) testData[i + 1]);
+ boolean actualResult = StringUtil.equals((String) testData[i],
+ (String) testData[i + 1]);
boolean expectedResult = (Boolean) testData[i + 2];
- assertEquals((i / 3) + " : " + testData[i] + ", " + testData[i + 1], expectedResult, actualResult);
+ assertEquals(
+ (i / 3) + " : " + testData[i] + ", " + testData[i + 1],
+ expectedResult, actualResult);
}
}
-
+
public void testEndWithIgnoreCase() {
- Object[] testData = new Object[] {
- null, null, true,
- "", "", true,
- "", "foo", false,
- "foo", "foo", true,
- "foo.bar", "bar", true,
- "foo.bar", "barX", false,
- "foo.barX", "bar", false,
- "foo", "bar", false,
- "foo.BAR", "bar", true,
- "foo.bar", "BaR", true
- };
+ Object[] testData = new Object[] { null, null, true, "", "", true, "",
+ "foo", false, "foo", "foo", true, "foo.bar", "bar", true,
+ "foo.bar", "barX", false, "foo.barX", "bar", false, "foo",
+ "bar", false, "foo.BAR", "bar", true, "foo.bar", "BaR", true };
for (int i = 0; i < testData.length; i += 3) {
- boolean actualResult = StringUtil.endsWithIgnoreCase( (String) testData[i], (String) testData[i + 1]);
+ boolean actualResult = StringUtil.endsWithIgnoreCase(
+ (String) testData[i], (String) testData[i + 1]);
boolean expectedResult = (Boolean) testData[i + 2];
- assertEquals((i / 3) + " : " + testData[i] + ", " + testData[i + 1], expectedResult, actualResult);
+ assertEquals(
+ (i / 3) + " : " + testData[i] + ", " + testData[i + 1],
+ expectedResult, actualResult);
}
}
public void testSubstringBefore() {
- Object[] testData = new Object[] {
- "", ' ', "",
- "", 'X', "",
- "fox", 'x', "fo",
- "foo.bar", 'b', "foo.",
- "aXbXc", 'X', "a",
- };
+ Object[] testData = new Object[] { "", ' ', "", "", 'X', "", "fox",
+ 'x', "fo", "foo.bar", 'b', "foo.", "aXbXc", 'X', "a", };
for (int i = 0; i < testData.length; i += 3) {
- String actualResult = StringUtil.substringBefore((String) testData[i], (Character) testData[i + 1]);
+ String actualResult = StringUtil.substringBefore(
+ (String) testData[i], (Character) testData[i + 1]);
String expectedResult = (String) testData[i + 2];
- assertEquals((i / 3) + " : " + testData[i] + ", " + testData[i + 1], expectedResult, actualResult);
+ assertEquals(
+ (i / 3) + " : " + testData[i] + ", " + testData[i + 1],
+ expectedResult, actualResult);
}
}
public void testSubstringBeforeLast() {
- Object[] testData = new Object[] {
- "", ' ', "",
- "", 'X', "",
- "fox", 'x', "fo",
- "foo.bar", 'b', "foo.",
- "aXbXc", 'X', "aXb",
- };
+ Object[] testData = new Object[] { "", ' ', "", "", 'X', "", "fox",
+ 'x', "fo", "foo.bar", 'b', "foo.", "aXbXc", 'X', "aXb", };
for (int i = 0; i < testData.length; i += 3) {
- String actualResult = StringUtil.substringBeforeLast((String) testData[i], (Character) testData[i + 1]);
+ String actualResult = StringUtil.substringBeforeLast(
+ (String) testData[i], (Character) testData[i + 1]);
String expectedResult = (String) testData[i + 2];
- assertEquals((i / 3) + " : " + testData[i] + ", " + testData[i + 1], expectedResult, actualResult);
+ assertEquals(
+ (i / 3) + " : " + testData[i] + ", " + testData[i + 1],
+ expectedResult, actualResult);
}
}
public void testSubstringAfter() {
- Object[] testData = new Object[] {
- "", ' ', "",
- "", 'X', "",
- "fox", 'f', "ox",
- "foo.bar", 'b', "ar",
- "aXbXc", 'X', "bXc",
- };
+ Object[] testData = new Object[] { "", ' ', "", "", 'X', "", "fox",
+ 'f', "ox", "foo.bar", 'b', "ar", "aXbXc", 'X', "bXc", };
for (int i = 0; i < testData.length; i += 3) {
- String actualResult = StringUtil.substringAfter((String) testData[i], (Character) testData[i + 1]);
+ String actualResult = StringUtil.substringAfter(
+ (String) testData[i], (Character) testData[i + 1]);
String expectedResult = (String) testData[i + 2];
- assertEquals((i / 3) + " : " + testData[i] + ", " + testData[i + 1], expectedResult, actualResult);
+ assertEquals(
+ (i / 3) + " : " + testData[i] + ", " + testData[i + 1],
+ expectedResult, actualResult);
}
}
public void testSubstringAfterLast() {
- Object[] testData = new Object[] {
- "", ' ', "",
- "", 'X', "",
- "fox", 'f', "ox",
- "foo.bar", 'b', "ar",
- "aXbXc", 'X', "c",
- };
+ Object[] testData = new Object[] { "", ' ', "", "", 'X', "", "fox",
+ 'f', "ox", "foo.bar", 'b', "ar", "aXbXc", 'X', "c", };
for (int i = 0; i < testData.length; i += 3) {
- String actualResult = StringUtil.substringAfterLast((String) testData[i], (Character) testData[i + 1]);
+ String actualResult = StringUtil.substringAfterLast(
+ (String) testData[i], (Character) testData[i + 1]);
String expectedResult = (String) testData[i + 2];
- assertEquals((i / 3) + " : " + testData[i] + ", " + testData[i + 1], expectedResult, actualResult);
+ assertEquals(
+ (i / 3) + " : " + testData[i] + ", " + testData[i + 1],
+ expectedResult, actualResult);
}
}
public void testToString() {
assertEquals("[name: 'paul']", StringUtil.toString("name", "paul"));
- assertEquals("[name: 'paul', address: 'a street']", StringUtil.toString("name", "paul", "address", "a street"));
+ assertEquals("[name: 'paul', address: 'a street']",
+ StringUtil.toString("name", "paul", "address", "a street"));
assertEquals("[name: ]", StringUtil.toString("name", null));
- assertEquals("[name: 'paul', address: ]", StringUtil.toString("name", "paul", "address"));
+ assertEquals("[name: 'paul', address: ]",
+ StringUtil.toString("name", "paul", "address"));
}
-
+
public void testHashCode() {
assertEquals(2522795, StringUtil.hashCode("isbn", "1234"));
assertEquals(3499691, StringUtil.hashCode("ISBN", "1234"));
}
-
+
public void testReplacementForCollapsePathDots() throws IOException {
- // This used to test StringUtil.collapsePathDots(String path).
- // I have left it to confirm that the Apache commons FilenameUtils.normalize
- // is a suitable replacement, but works where for "/a/b/../../c", which
- // the old method did not.
- String[] testData = new String[] {
- "/foo/bar.html", "/foo/bar.html",
- "/foo/../bar.html", "/bar.html",
- "/foo/moo/../../bar.html", "/bar.html",
- "/foo//bar.html", "/foo/bar.html",
- "/foo/./bar.html", "/foo/bar.html",
- "/foo/../sub/bar.html", "/sub/bar.html"
+ // This used to test StringUtil.collapsePathDots(String path).
+ // I have left it to confirm that the Apache commons
+ // FilenameUtils.normalize
+ // is a suitable replacement, but works where for "/a/b/../../c", which
+ // the old method did not.
+ String[] testData = new String[] { //
+ "/foo/bar.html", "/foo/bar.html",
+ "/foo/../bar.html", "/bar.html", //
+ "/foo/moo/../../bar.html", //
+ "/bar.html", "/foo//bar.html", //
+ "/foo/bar.html", "/foo/./bar.html", //
+ "/foo/bar.html", //
+ "/a/b/../../c", "/c", //
+ "/foo/../sub/bar.html", "/sub/bar.html" //
};
- for (int i = 0; i < testData.length; i += 2) {
- String actualResult = FilenameUtils.normalize(testData[i], true);
- assertEquals(testData[i + 1], actualResult);
- }
+ for (int i = 0; i < testData.length; i += 2) {
+ String actualResult = StringUtil.collapsePathDots(testData[i]);
+ assertEquals(testData[i], testData[i + 1], actualResult);
+ }
}
}
From 912be6c00e420e055aec72fd02cbb7e2ca489412 Mon Sep 17 00:00:00 2001
From: psiegman
Date: Mon, 9 Sep 2013 23:18:42 +0200
Subject: [PATCH 18/57] fix the getting of TOC references
---
.../main/java/nl/siegmann/epublib/epub/NCXDocument.java | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/NCXDocument.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/NCXDocument.java
index b7e6c579..d9857b41 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/epub/NCXDocument.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/NCXDocument.java
@@ -118,7 +118,13 @@ private static List readTOCReferences(NodeList navpoints, Book boo
private static TOCReference readTOCReference(Element navpointElement, Book book) {
String label = readNavLabel(navpointElement);
- String reference = StringUtil.substringBeforeLast(book.getSpine().getTocResource().getHref(), '/') + '/' + readNavReference(navpointElement);
+ String tocResourceRoot = StringUtil.substringBeforeLast(book.getSpine().getTocResource().getHref(), '/');
+ if (tocResourceRoot.length() == book.getSpine().getTocResource().getHref().length()) {
+ tocResourceRoot = "";
+ } else {
+ tocResourceRoot = tocResourceRoot + "/";
+ }
+ String reference = tocResourceRoot + readNavReference(navpointElement);
String href = StringUtil.substringBefore(reference, Constants.FRAGMENT_SEPARATOR_CHAR);
String fragmentId = StringUtil.substringAfter(reference, Constants.FRAGMENT_SEPARATOR_CHAR);
Resource resource = book.getResources().getByHref(href);
@@ -130,7 +136,6 @@ private static TOCReference readTOCReference(Element navpointElement, Book book)
result.setChildren(readTOCReferences(navpointElement.getChildNodes(), book));
return result;
}
-
private static String readNavReference(Element navpointElement) {
Element contentElement = DOMUtil.getFirstElementByTagNameNS(navpointElement, NAMESPACE_NCX, NCXTags.content);
From d637e5e0565b146fe4fa3a6accf841ba3ef3ee77 Mon Sep 17 00:00:00 2001
From: psiegman
Date: Mon, 9 Sep 2013 23:20:52 +0200
Subject: [PATCH 19/57] remove unused import
---
.../src/main/java/nl/siegmann/epublib/chm/ChmParser.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/epublib-tools/src/main/java/nl/siegmann/epublib/chm/ChmParser.java b/epublib-tools/src/main/java/nl/siegmann/epublib/chm/ChmParser.java
index f9ca6d65..97001a7d 100644
--- a/epublib-tools/src/main/java/nl/siegmann/epublib/chm/ChmParser.java
+++ b/epublib-tools/src/main/java/nl/siegmann/epublib/chm/ChmParser.java
@@ -22,8 +22,6 @@
import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileType;
-import com.sun.org.apache.bcel.internal.Constants;
-
/**
* Reads the files that are extracted from a windows help ('.chm') file and creates a epublib Book out of it.
*
From 88d577bb6da9b794a14a88ff415a5708507aa4ff Mon Sep 17 00:00:00 2001
From: "P. Siegmann"
Date: Tue, 10 Sep 2013 20:04:40 +0200
Subject: [PATCH 20/57] maven pom.xml reorganisation/cleanup
---
epublib-core/pom.xml | 2 +-
pom.xml => epublib-parent/pom.xml | 5 +++--
epublib-tools/pom.xml | 2 +-
3 files changed, 5 insertions(+), 4 deletions(-)
rename pom.xml => epublib-parent/pom.xml (96%)
diff --git a/epublib-core/pom.xml b/epublib-core/pom.xml
index c8d0f0a8..afa15b0b 100644
--- a/epublib-core/pom.xml
+++ b/epublib-core/pom.xml
@@ -8,7 +8,6 @@
nl.siegmann.epublibepublib-coreepublib-core
- 3.1A java library for reading/writing/manipulating epub fileshttp://www.siegmann.nl/epublib2009
@@ -17,6 +16,7 @@
nl.siegmann.epublibepublib-parent3.1
+ ../epublib-parent/pom.xml
diff --git a/pom.xml b/epublib-parent/pom.xml
similarity index 96%
rename from pom.xml
rename to epublib-parent/pom.xml
index 6e2000d5..394047b6 100644
--- a/pom.xml
+++ b/epublib-parent/pom.xml
@@ -20,8 +20,8 @@
- epublib-core
- epublib-tools
+ ../epublib-core
+ ../epublib-tools
@@ -87,6 +87,7 @@
org.apache.maven.pluginsmaven-javadoc-plugin
+ 2.9.1attach-javadocs
diff --git a/epublib-tools/pom.xml b/epublib-tools/pom.xml
index 6b2e5c1f..8f96ae2f 100644
--- a/epublib-tools/pom.xml
+++ b/epublib-tools/pom.xml
@@ -8,7 +8,6 @@
nl.siegmann.epublibepublib-toolsepublib-tools
- 3.1A java library for reading/writing/manipulating epub fileshttp://www.siegmann.nl/epublib2009
@@ -17,6 +16,7 @@
nl.siegmann.epublibepublib-parent3.1
+ ../epublib-parent/pom.xml
From ff14999c509e6e3b0289dd4c0cd6561cf8e50dee Mon Sep 17 00:00:00 2001
From: "P. Siegmann"
Date: Tue, 10 Sep 2013 20:05:45 +0200
Subject: [PATCH 21/57] javadoc fixes
---
.../browsersupport/NavigationEvent.java | 4 +--
.../browsersupport/NavigationHistory.java | 3 +-
.../epublib/browsersupport/Navigator.java | 3 +-
.../java/nl/siegmann/epublib/domain/Book.java | 27 ++++++++--------
.../nl/siegmann/epublib/domain/Guide.java | 6 ++--
.../siegmann/epublib/domain/Identifier.java | 4 +--
.../nl/siegmann/epublib/domain/Metadata.java | 4 +--
.../nl/siegmann/epublib/domain/Relator.java | 2 +-
.../nl/siegmann/epublib/domain/Resource.java | 27 ++++++++--------
.../epublib/domain/ResourceReference.java | 2 +-
.../nl/siegmann/epublib/domain/Resources.java | 29 ++++++++++-------
.../nl/siegmann/epublib/domain/Spine.java | 17 ++++++----
.../epublib/domain/SpineReference.java | 4 +--
.../epublib/domain/TableOfContents.java | 15 ++++++---
.../domain/TitledResourceReference.java | 2 +-
.../epublib/epub/EpubProcessorSupport.java | 2 +-
.../nl/siegmann/epublib/epub/EpubReader.java | 6 ++--
.../nl/siegmann/epublib/epub/NCXDocument.java | 7 ++--
.../epub/PackageDocumentMetadataWriter.java | 1 -
.../epublib/epub/PackageDocumentReader.java | 13 ++++----
.../epublib/service/MediatypeService.java | 2 +-
.../siegmann/epublib/util/CollectionUtil.java | 4 +--
.../java/nl/siegmann/epublib/util/IOUtil.java | 12 +++----
.../siegmann/epublib/util/ResourceUtil.java | 10 +++---
.../nl/siegmann/epublib/util/StringUtil.java | 32 ++++++++++---------
.../nl/siegmann/epublib/chm/ChmParser.java | 4 +--
.../epublib/fileset/FilesetBookCreator.java | 2 +-
.../siegmann/epublib/search/SearchIndex.java | 4 +--
.../nl/siegmann/epublib/util/DesktopUtil.java | 2 +-
.../epublib/util/ToolsResourceUtil.java | 4 +--
.../nl/siegmann/epublib/util/VFSUtil.java | 4 +--
.../nl/siegmann/epublib/viewer/ButtonBar.java | 3 +-
.../siegmann/epublib/viewer/ContentPane.java | 7 ++--
.../epublib/viewer/HTMLDocumentFactory.java | 6 ++--
.../epublib/viewer/TableOfContentsPane.java | 1 -
.../siegmann/epublib/viewer/ViewerUtil.java | 2 +-
36 files changed, 142 insertions(+), 135 deletions(-)
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/browsersupport/NavigationEvent.java b/epublib-core/src/main/java/nl/siegmann/epublib/browsersupport/NavigationEvent.java
index 590433f1..e3a96b04 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/browsersupport/NavigationEvent.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/browsersupport/NavigationEvent.java
@@ -40,7 +40,7 @@ public NavigationEvent(Object source, Navigator navigator) {
/**
* The previous position within the section.
*
- * @return
+ * @return The previous position within the section.
*/
public int getOldSectionPos() {
return oldSectionPos;
@@ -151,4 +151,4 @@ public String toString() {
public boolean isSectionPosChanged() {
return oldSectionPos != getCurrentSectionPos();
}
-}
\ No newline at end of file
+}
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/browsersupport/NavigationHistory.java b/epublib-core/src/main/java/nl/siegmann/epublib/browsersupport/NavigationHistory.java
index 61849900..1d7aed5c 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/browsersupport/NavigationHistory.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/browsersupport/NavigationHistory.java
@@ -76,7 +76,7 @@ public void initBook(Book book) {
* If the time between a navigation event is less than the historyWaitTime then the new location is not added to the history.
* When a user is rapidly viewing many pages using the slider we do not want all of them to be added to the history.
*
- * @return
+ * @return the time we wait before adding the page to the history
*/
public long getHistoryWaitTime() {
return historyWaitTime;
@@ -101,7 +101,6 @@ public void addLocation(Resource resource) {
* If this nr of locations becomes larger then the historySize then the first item(s) will be removed.
*
* @param location
- * @return
*/
public void addLocation(Location location) {
// do nothing if the new location matches the current location
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/browsersupport/Navigator.java b/epublib-core/src/main/java/nl/siegmann/epublib/browsersupport/Navigator.java
index dfa352c5..7f1e6643 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/browsersupport/Navigator.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/browsersupport/Navigator.java
@@ -137,7 +137,7 @@ public int gotoSpineSection(int newSpinePos, Object source) {
*
* @param newSpinePos
* @param source
- * @return
+ * @return The current position within the spine
*/
public int gotoSpineSection(int newSpinePos, int newPagePos, Object source) {
if (newSpinePos == currentSpinePos) {
@@ -203,7 +203,6 @@ public Book getBook() {
*
* If you want the eventListeners called use gotoSection(index);
*
- * @param currentSpinePos
*/
public int setCurrentResource(Resource currentResource) {
this.currentSpinePos = book.getSpine().getResourceIndex(currentResource);
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Book.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Book.java
index 277f144b..152d5b69 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Book.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Book.java
@@ -312,7 +312,7 @@ public class Book implements Serializable {
* @param parentSection
* @param sectionTitle
* @param resource
- * @return
+ * @return The table of contents
*/
public TOCReference addSection(TOCReference parentSection, String sectionTitle,
Resource resource) {
@@ -337,7 +337,7 @@ public void generateSpineFromTableOfContents() {
*
* @param title
* @param resource
- * @return
+ * @return The table of contents
*/
public TOCReference addSection(String title, Resource resource) {
getResources().add(resource);
@@ -352,7 +352,7 @@ public TOCReference addSection(String title, Resource resource) {
/**
* The Book's metadata (titles, authors, etc)
*
- * @return
+ * @return The Book's metadata (titles, authors, etc)
*/
public Metadata getMetadata() {
return metadata;
@@ -374,7 +374,7 @@ public Resource addResource(Resource resource) {
/**
* The collection of all images, chapters, sections, xhtml files, stylesheets, etc that make up the book.
*
- * @return
+ * @return The collection of all images, chapters, sections, xhtml files, stylesheets, etc that make up the book.
*/
public Resources getResources() {
return resources;
@@ -384,7 +384,7 @@ public Resources getResources() {
/**
* The sections of the book that should be shown if a user reads the book from start to finish.
*
- * @return
+ * @return The Spine
*/
public Spine getSpine() {
return spine;
@@ -399,7 +399,7 @@ public void setSpine(Spine spine) {
/**
* The Table of Contents of the book.
*
- * @return
+ * @return The Table of Contents of the book.
*/
public TableOfContents getTableOfContents() {
return tableOfContents;
@@ -411,10 +411,10 @@ public void setTableOfContents(TableOfContents tableOfContents) {
}
/**
- * The book's cover page.
+ * The book's cover page as a Resource.
* An XHTML document containing a link to the cover image.
*
- * @return
+ * @return The book's cover page as a Resource
*/
public Resource getCoverPage() {
Resource coverPage = guide.getCoverPage();
@@ -438,7 +438,7 @@ public void setCoverPage(Resource coverPage) {
/**
* Gets the first non-blank title from the book's metadata.
*
- * @return
+ * @return the first non-blank title from the book's metadata.
*/
public String getTitle() {
return getMetadata().getFirstTitle();
@@ -448,7 +448,7 @@ public String getTitle() {
/**
* The book's cover image.
*
- * @return
+ * @return The book's cover image.
*/
public Resource getCoverImage() {
return coverImage;
@@ -467,7 +467,7 @@ public void setCoverImage(Resource coverImage) {
/**
* The guide; contains references to special sections of the book like colophon, glossary, etc.
*
- * @return
+ * @return The guide; contains references to special sections of the book like colophon, glossary, etc.
*/
public Guide getGuide() {
return guide;
@@ -483,9 +483,8 @@ public Guide getGuide() {
*
The resources of the Table of Contents that are not already in the result
*
The resources of the Guide that are not already in the result
*
- * To get all html files that make up the epub file use
- * @see getResources().getAll()
- * @return
+ * To get all html files that make up the epub file use {@link #getResources()}
+ * @return All Resources of the Book that can be reached via the Spine, the TableOfContents or the Guide.
*/
public List getContents() {
Map result = new LinkedHashMap();
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Guide.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Guide.java
index 58e1e018..e18d7167 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Guide.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Guide.java
@@ -83,7 +83,7 @@ private void initCoverPage() {
/**
* The coverpage of the book.
*
- * @return
+ * @return The coverpage of the book.
*/
public Resource getCoverPage() {
GuideReference guideReference = getCoverReference();
@@ -109,7 +109,7 @@ public ResourceReference addReference(GuideReference reference) {
* A list of all GuideReferences that have the given referenceTypeName (ignoring case).
*
* @param referenceTypeName
- * @return
+ * @return A list of all GuideReferences that have the given referenceTypeName (ignoring case).
*/
public List getGuideReferencesByType(String referenceTypeName) {
List result = new ArrayList();
@@ -120,4 +120,4 @@ public List getGuideReferencesByType(String referenceTypeName) {
}
return result;
}
-}
\ No newline at end of file
+}
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Identifier.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Identifier.java
index 90e7944f..a6e30acd 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Identifier.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Identifier.java
@@ -50,7 +50,7 @@ public Identifier(String scheme, String value) {
* If no identifier has bookId == true then the first bookId identifier is written as the primary.
*
* @param identifiers
- * @return
+ * @return The first identifier for which the bookId is true is made the bookId identifier.
*/
public static Identifier getBookIdIdentifier(List identifiers) {
if(identifiers == null || identifiers.isEmpty()) {
@@ -97,7 +97,7 @@ public void setBookId(boolean bookId) {
* The Dublin Core metadata spec allows multiple identifiers for a Book.
* The epub spec requires exactly one identifier to be marked as the book id.
*
- * @return
+ * @return whether this is the unique book id.
*/
public boolean isBookId() {
return bookId;
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Metadata.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Metadata.java
index 1be02862..4fbbc312 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Metadata.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Metadata.java
@@ -55,7 +55,7 @@ public boolean isAutoGeneratedId() {
/**
* Metadata properties not hard-coded like the author, title, etc.
*
- * @return
+ * @return Metadata properties not hard-coded like the author, title, etc.
*/
public Map getOtherProperties() {
return otherProperties;
@@ -124,7 +124,7 @@ public List getRights() {
* Gets the first non-blank title of the book.
* Will return "" if no title found.
*
- * @return
+ * @return the first non-blank title of the book.
*/
public String getFirstTitle() {
if (titles == null || titles.isEmpty()) {
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Relator.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Relator.java
index 3dc5bc88..4ce05796 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Relator.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Relator.java
@@ -8,7 +8,7 @@
*
* This is contains the complete Library of Concress relator list.
*
- * @see http://www.loc.gov/marc/relators/relaterm.html
+ * @see MARC Code List for Relators
*
* @author paul
*
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
index 1f563ab1..a5f66cc6 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
@@ -75,7 +75,7 @@ public Resource(byte[] data, MediaType mediaType) {
*
* Assumes that if the data is of a text type (html/css/etc) then the encoding will be UTF-8
*
- * @see nl.siegmann.epublib.service.MediatypeService.determineMediaType(String)
+ * @see nl.siegmann.epublib.service.MediatypeService#determineMediaType(String)
*
* @param data The Resource's contents
* @param href The location of the resource within the epub. Example: "chapter1.html".
@@ -87,7 +87,8 @@ public Resource(byte[] data, String href) {
/**
* Creates a resource with the data from the given Reader at the specified href.
* The MediaType will be determined based on the href extension.
- * @see nl.siegmann.epublib.service.MediatypeService.determineMediaType(String)
+ *
+ * @see nl.siegmann.epublib.service.MediatypeService#determineMediaType(String)
*
* @param in The Resource's contents
* @param href The location of the resource within the epub. Example: "cover.jpg".
@@ -99,13 +100,13 @@ public Resource(Reader in, String href) throws IOException {
/**
* Creates a resource with the data from the given InputStream at the specified href.
* The MediaType will be determined based on the href extension.
- * @see nl.siegmann.epublib.service.MediatypeService.determineMediaType(String)
+ *
+ * @see nl.siegmann.epublib.service.MediatypeService#determineMediaType(String)
*
* Assumes that if the data is of a text type (html/css/etc) then the encoding will be UTF-8
*
- * It is recommended to us the
- * @see nl.siegmann.epublib.domain.Resource.Resource(Reader, String)
- * method for creating textual (html/css/etc) resources to prevent encoding problems.
+ * It is recommended to us the {@link #Resource(Reader, String)} method for creating textual
+ * (html/css/etc) resources to prevent encoding problems.
* Use this method only for binary Resources like images, fonts, etc.
*
*
@@ -298,7 +299,7 @@ public long getSize() {
/**
* If the title is found by scanning the underlying html document then it is cached here.
*
- * @return
+ * @return the title
*/
public String getTitle() {
return title;
@@ -317,7 +318,7 @@ public void setId(String id) {
* The resources Id.
*
* Must be both unique within all the resources of this book and a valid identifier.
- * @return
+ * @return The resources Id.
*/
public String getId() {
return id;
@@ -330,7 +331,7 @@ public String getId() {
* images/cover.jpg
* content/chapter1.xhtml
*
- * @return
+ * @return The location of the resource within the contents folder of the epub file.
*/
public String getHref() {
return href;
@@ -349,7 +350,7 @@ public void setHref(String href) {
* The character encoding of the resource.
* Is allowed to be null for non-text resources like images.
*
- * @return
+ * @return The character encoding of the resource.
*/
public String getInputEncoding() {
return inputEncoding;
@@ -369,8 +370,7 @@ public void setInputEncoding(String encoding) {
*
* Does all sorts of smart things (courtesy of apache commons io XMLStreamREader) to handle encodings, byte order markers, etc.
*
- * @param resource
- * @return
+ * @return the contents of the Resource as Reader.
* @throws IOException
*/
public Reader getReader() throws IOException {
@@ -388,6 +388,7 @@ public int hashCode() {
/**
* Checks to see of the given resourceObject is a resource and whether its href is equal to this one.
*
+ * @return whether the given resourceObject is a resource and whether its href is equal to this one.
*/
public boolean equals(Object resourceObject) {
if (! (resourceObject instanceof Resource)) {
@@ -399,7 +400,7 @@ public boolean equals(Object resourceObject) {
/**
* This resource's mediaType.
*
- * @return
+ * @return This resource's mediaType.
*/
public MediaType getMediaType() {
return mediaType;
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/ResourceReference.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/ResourceReference.java
index 096aa466..9ba8cea0 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/ResourceReference.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/ResourceReference.java
@@ -34,7 +34,7 @@ public void setResource(Resource resource) {
*
* null of the reference is null or has a null id itself.
*
- * @return
+ * @return The id of the reference referred to.
*/
public String getResourceId() {
if (resource != null) {
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resources.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resources.java
index 85ed1233..2067afd5 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resources.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resources.java
@@ -37,7 +37,7 @@ public class Resources implements Serializable {
* Fixes the resources id and href if necessary.
*
* @param resource
- * @return
+ * @return the newly added resource
*/
public Resource add(Resource resource) {
fixResourceHref(resource);
@@ -73,7 +73,7 @@ public void fixResourceId(Resource resource) {
* Check if the id is a valid identifier. if not: prepend with valid identifier
*
* @param resource
- * @return
+ * @return a valid id
*/
private String makeValidId(String resourceId, Resource resource) {
if (StringUtil.isNotBlank(resourceId) && ! Character.isJavaIdentifierStart(resourceId.charAt(0))) {
@@ -96,7 +96,7 @@ private String getResourceItemPrefix(Resource resource) {
* Creates a new resource id that is guarenteed to be unique for this set of Resources
*
* @param resource
- * @return
+ * @return a new resource id that is guarenteed to be unique for this set of Resources
*/
private String createUniqueResourceId(Resource resource) {
int counter = lastId;
@@ -120,7 +120,7 @@ private String createUniqueResourceId(Resource resource) {
* Whether the map of resources already contains a resource with the given id.
*
* @param id
- * @return
+ * @return Whether the map of resources already contains a resource with the given id.
*/
public boolean containsId(String id) {
if (StringUtil.isBlank(id)) {
@@ -195,7 +195,7 @@ public boolean isEmpty() {
/**
* The number of resources
- * @return
+ * @return The number of resources
*/
public int size() {
return resources.size();
@@ -205,7 +205,7 @@ public int size() {
* The resources that make up this book.
* Resources can be xhtml pages, images, xml documents, etc.
*
- * @return
+ * @return The resources that make up this book.
*/
public Map getResourceMap() {
return resources;
@@ -219,7 +219,7 @@ public Collection getAll() {
/**
* Whether there exists a resource with the given href
* @param href
- * @return
+ * @return Whether there exists a resource with the given href
*/
public boolean containsByHref(String href) {
if (StringUtil.isBlank(href)) {
@@ -265,7 +265,7 @@ public void set(Map resources) {
* fails it tries to find one with the idOrHref as href.
*
* @param idOrHref
- * @return
+ * @return the found Resource
*/
public Resource getByIdOrHref(String idOrHref) {
Resource resource = getById(idOrHref);
@@ -298,7 +298,7 @@ public Resource getByHref(String href) {
* Useful for looking up the table of contents as it's supposed to be the only resource with NCX mediatype.
*
* @param mediaType
- * @return
+ * @return the first resource (random order) with the give mediatype.
*/
public Resource findFirstResourceByMediaType(MediaType mediaType) {
return findFirstResourceByMediaType(resources.values(), mediaType);
@@ -310,7 +310,7 @@ public Resource findFirstResourceByMediaType(MediaType mediaType) {
* Useful for looking up the table of contents as it's supposed to be the only resource with NCX mediatype.
*
* @param mediaType
- * @return
+ * @return the first resource (random order) with the give mediatype.
*/
public static Resource findFirstResourceByMediaType(Collection resources, MediaType mediaType) {
for (Resource resource: resources) {
@@ -325,7 +325,7 @@ public static Resource findFirstResourceByMediaType(Collection resourc
* All resources that have the given MediaType.
*
* @param mediaType
- * @return
+ * @return All resources that have the given MediaType.
*/
public List getResourcesByMediaType(MediaType mediaType) {
List result = new ArrayList();
@@ -344,7 +344,7 @@ public List getResourcesByMediaType(MediaType mediaType) {
* All Resources that match any of the given list of MediaTypes
*
* @param mediaTypes
- * @return
+ * @return All Resources that match any of the given list of MediaTypes
*/
public List getResourcesByMediaTypes(MediaType[] mediaTypes) {
List result = new ArrayList();
@@ -364,6 +364,11 @@ public List getResourcesByMediaTypes(MediaType[] mediaTypes) {
}
+ /**
+ * All resource hrefs
+ *
+ * @return all resource hrefs
+ */
public Collection getAllHrefs() {
return resources.keySet();
}
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Spine.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Spine.java
index d0cda7ea..069ac5f7 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Spine.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Spine.java
@@ -63,7 +63,7 @@ public void setSpineReferences(List spineReferences) {
* Null if not found.
*
* @param index
- * @return
+ * @return the resource at the given index.
*/
public Resource getResource(int index) {
if (index < 0 || index >= spineReferences.size()) {
@@ -78,7 +78,7 @@ public Resource getResource(int index) {
* Null if not found.
*
* @param resourceId
- * @return
+ * @return the first resource that has the given resourceId.
*/
public int findFirstResourceById(String resourceId) {
if (StringUtil.isBlank(resourceId)) {
@@ -98,7 +98,7 @@ public int findFirstResourceById(String resourceId) {
* Adds the given spineReference to the spine references and returns it.
*
* @param spineReference
- * @return
+ * @return the given spineReference
*/
public SpineReference addSpineReference(SpineReference spineReference) {
if (spineReferences == null) {
@@ -111,8 +111,7 @@ public SpineReference addSpineReference(SpineReference spineReference) {
/**
* Adds the given resource to the spine references and returns it.
*
- * @param spineReference
- * @return
+ * @return the given spineReference
*/
public SpineReference addResource(Resource resource) {
return addSpineReference(new SpineReference(resource));
@@ -121,7 +120,7 @@ public SpineReference addResource(Resource resource) {
/**
* The number of elements in the spine.
*
- * @return
+ * @return The number of elements in the spine.
*/
public int size() {
return spineReferences.size();
@@ -142,7 +141,7 @@ public void setTocResource(Resource tocResource) {
* The resource containing the XML for the tableOfContents.
* When saving an epub file this resource needs to be in this place.
*
- * @return
+ * @return The resource containing the XML for the tableOfContents.
*/
public Resource getTocResource() {
return tocResource;
@@ -182,6 +181,10 @@ public int getResourceIndex(String resourceHref) {
return result;
}
+ /**
+ * Whether the spine has any references
+ * @return Whether the spine has any references
+ */
public boolean isEmpty() {
return spineReferences.isEmpty();
}
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/SpineReference.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/SpineReference.java
index db2804b2..6b545f43 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/SpineReference.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/SpineReference.java
@@ -41,9 +41,9 @@ public SpineReference(Resource resource, boolean linear) {
* a popup window apart from the main window which presents the primary
* content. (For an example of the types of content that may be considered
* auxiliary, refer to the example below and the subsequent discussion.)
- * @see http://www.idpf.org/2007/opf/OPF_2.0_final_spec.html#TOC2.4
+ * @see OPF Spine specification
*
- * @return
+ * @return whether the section is Primary or Auxiliary.
*/
public boolean isLinear() {
return linear;
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/TableOfContents.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/TableOfContents.java
index 94d65d15..56cf6d0e 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/TableOfContents.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/TableOfContents.java
@@ -50,6 +50,7 @@ public void setTocReferences(List tocReferences) {
/**
* Calls addTOCReferenceAtLocation after splitting the path using the DEFAULT_PATH_SEPARATOR.
+ * @return the new TOCReference
*/
public TOCReference addSection(Resource resource, String path) {
return addSection(resource, path, DEFAULT_PATH_SEPARATOR);
@@ -61,7 +62,7 @@ public TOCReference addSection(Resource resource, String path) {
* @param resource
* @param path
* @param pathSeparator
- * @return
+ * @return the new TOCReference
*/
public TOCReference addSection(Resource resource, String path, String pathSeparator) {
String[] pathElements = path.split(pathSeparator);
@@ -98,7 +99,7 @@ private static TOCReference findTocReferenceByTitle(String title, List getAllUniqueResources() {
Set uniqueHrefs = new HashSet();
@@ -218,7 +219,7 @@ private static void getAllUniqueResources(Set uniqueHrefs, List tocReferences) {
return result;
}
+ /**
+ * The maximum depth of the reference tree
+ * @return The maximum depth of the reference tree
+ */
public int calculateDepth() {
return calculateDepth(tocReferences, 0);
}
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/TitledResourceReference.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/TitledResourceReference.java
index 173943e9..81cee4b3 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/TitledResourceReference.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/TitledResourceReference.java
@@ -48,7 +48,7 @@ public void setTitle(String title) {
/**
* If the fragmentId is blank it returns the resource href, otherwise it returns the resource href + '#' + the fragmentId.
*
- * @return
+ * @return If the fragmentId is blank it returns the resource href, otherwise it returns the resource href + '#' + the fragmentId.
*/
public String getCompleteHref() {
if (StringUtil.isBlank(fragmentId)) {
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubProcessorSupport.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubProcessorSupport.java
index 0a4cfc64..70faba6a 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubProcessorSupport.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubProcessorSupport.java
@@ -106,7 +106,7 @@ public DocumentBuilderFactory getDocumentBuilderFactory() {
/**
* Creates a DocumentBuilder that looks up dtd's and schema's from epublib's classpath.
*
- * @return
+ * @return a DocumentBuilder that looks up dtd's and schema's from epublib's classpath.
*/
public static DocumentBuilder createDocumentBuilder() {
DocumentBuilder result = null;
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
index 18003810..929bf22d 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
@@ -52,7 +52,7 @@ public Book readEpub(ZipFile zipfile) throws IOException {
*
* @param in the inputstream from which to read the epub
* @param encoding the encoding to use for the html files within the epub
- * @return
+ * @return the Book as read from the inputstream
* @throws IOException
*/
public Book readEpub(InputStream in, String encoding) throws IOException {
@@ -65,7 +65,7 @@ public Book readEpub(InputStream in, String encoding) throws IOException {
* @param fileName the file to load
* @param encoding the encoding for XHTML files
* @param lazyLoadedTypes a list of the MediaType to load lazily
- * @return
+ * @return this Book without loading all resources into memory.
* @throws IOException
*/
public Book readEpubLazy( String fileName, String encoding, List lazyLoadedTypes ) throws IOException {
@@ -88,7 +88,7 @@ public Book readEpubLazy( String fileName, String encoding, List lazy
* @param fileName the file to load
* @param encoding the encoding for XHTML files
*
- * @return
+ * @return this Book without loading all resources into memory.
* @throws IOException
*/
public Book readEpubLazy( String fileName, String encoding ) throws IOException {
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/NCXDocument.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/NCXDocument.java
index d9857b41..7e18e249 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/epub/NCXDocument.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/NCXDocument.java
@@ -165,10 +165,9 @@ public static void write(EpubWriter epubWriter, Book book, ZipOutputStream resul
/**
* Generates a resource containing an xml document containing the table of contents of the book in ncx format.
*
- * @param epubWriter
- * @param book
- * @return
- * @
+ * @param xmlSerializer the serializer used
+ * @param book the book to serialize
+ *
* @throws FactoryConfigurationError
* @throws IOException
* @throws IllegalStateException
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentMetadataWriter.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentMetadataWriter.java
index 858eff99..af667816 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentMetadataWriter.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentMetadataWriter.java
@@ -26,7 +26,6 @@ public class PackageDocumentMetadataWriter extends PackageDocumentBase {
* @throws IOException
* @throws IllegalStateException
* @throws IllegalArgumentException
- * @
*/
public static void writeMetaData(Book book, XmlSerializer serializer) throws IllegalArgumentException, IllegalStateException, IOException {
serializer.startTag(NAMESPACE_OPF, OPFTags.metadata);
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentReader.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentReader.java
index a57ddb09..cfd15e99 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentReader.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/PackageDocumentReader.java
@@ -177,7 +177,7 @@ private static void readGuide(Document packageDocument,
*
* @param packageHref
* @param resourcesByHref
- * @return
+ * @return The stipped package href
*/
private static Resources fixHrefs(String packageHref,
Resources resourcesByHref) {
@@ -203,7 +203,7 @@ private static Resources fixHrefs(String packageHref,
* @param epubReader
* @param book
* @param resourcesById
- * @return
+ * @return the document's spine, containing all sections in reading order.
*/
private static Spine readSpine(Document packageDocument, EpubReader epubReader, Resources resources, Map idMapping) {
@@ -248,7 +248,7 @@ private static Spine readSpine(Document packageDocument, EpubReader epubReader,
* The generated spine consists of all XHTML pages in order of their href.
*
* @param resources
- * @return
+ * @return a spine created out of all resources in the resources.
*/
private static Spine generateSpineFromResources(Resources resources) {
Spine result = new Spine();
@@ -275,7 +275,7 @@ private static Spine generateSpineFromResources(Resources resources) {
*
* @param spineElement
* @param resourcesById
- * @return
+ * @return the Resource containing the table of contents
*/
private static Resource findTableOfContentsResource(Element spineElement, Resources resources) {
String tocResourceId = DOMUtil.getAttribute(spineElement, NAMESPACE_OPF, OPFAttributes.toc);
@@ -314,7 +314,7 @@ private static Resource findTableOfContentsResource(Element spineElement, Resour
* Search the meta tags and the guide references
*
* @param packageDocument
- * @return
+ * @return all resources that have something to do with the coverpage and the cover image.
*/
// package
static Set findCoverHrefs(Document packageDocument) {
@@ -352,7 +352,6 @@ static Set findCoverHrefs(Document packageDocument) {
* @param packageDocument
* @param book
* @param resources
- * @return
*/
private static void readCover(Document packageDocument, Book book) {
@@ -372,4 +371,4 @@ private static void readCover(Document packageDocument, Book book) {
}
-}
\ No newline at end of file
+}
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/service/MediatypeService.java b/epublib-core/src/main/java/nl/siegmann/epublib/service/MediatypeService.java
index 835567d9..045962bf 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/service/MediatypeService.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/service/MediatypeService.java
@@ -63,7 +63,7 @@ public static boolean isBitmapImage(MediaType mediaType) {
* Null of no matching extension found.
*
* @param filename
- * @return
+ * @return the MediaType based on the file extension.
*/
public static MediaType determineMediaType(String filename) {
for(int i = 0; i < mediatypes.length; i++) {
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/util/CollectionUtil.java b/epublib-core/src/main/java/nl/siegmann/epublib/util/CollectionUtil.java
index 7c33206e..5b563f15 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/util/CollectionUtil.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/util/CollectionUtil.java
@@ -34,7 +34,7 @@ public T nextElement() {
* Creates an Enumeration out of the given Iterator.
* @param
* @param it
- * @return
+ * @return an Enumeration created out of the given Iterator.
*/
public static Enumeration createEnumerationFromIterator(Iterator it) {
return new IteratorEnumerationAdapter(it);
@@ -46,7 +46,7 @@ public static Enumeration createEnumerationFromIterator(Iterator it) {
*
* @param
* @param list
- * @return
+ * @return the first element of the list, null if the list is null or empty.
*/
public static T first(List list) {
if(list == null || list.isEmpty()) {
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/util/IOUtil.java b/epublib-core/src/main/java/nl/siegmann/epublib/util/IOUtil.java
index 89d669af..4d2dd804 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/util/IOUtil.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/util/IOUtil.java
@@ -15,7 +15,7 @@ public class IOUtil {
*
* @param in
* @param encoding
- * @return
+ * @return the contents of the Reader as a byte[], with the given character encoding.
* @throws IOException
*/
public static byte[] toByteArray(Reader in, String encoding) throws IOException {
@@ -29,7 +29,7 @@ public static byte[] toByteArray(Reader in, String encoding) throws IOException
* Returns the contents of the InputStream as a byte[]
*
* @param in
- * @return
+ * @return the contents of the InputStream as a byte[]
* @throws IOException
*/
public static byte[] toByteArray(InputStream in) throws IOException {
@@ -45,7 +45,7 @@ public static byte[] toByteArray(InputStream in) throws IOException {
* This is meant for situations where memory is tight, since
* it prevents buffer expansion.
*
- * @param stream the stream to read data from
+ * @param in the stream to read data from
* @param size the size of the array to create
* @return the array, or null
* @throws IOException
@@ -76,7 +76,7 @@ public static byte[] toByteArray( InputStream in, int size ) throws IOException
* if totalNrRead < 0 then totalNrRead is returned, if (nrRead + totalNrRead) < Integer.MAX_VALUE then nrRead + totalNrRead is returned, -1 otherwise.
* @param nrRead
* @param totalNrNread
- * @return
+ * @return if totalNrRead < 0 then totalNrRead is returned, if (nrRead + totalNrRead) < Integer.MAX_VALUE then nrRead + totalNrRead is returned, -1 otherwise.
*/
protected static int calcNewNrReadSize(int nrRead, int totalNrNread) {
if (totalNrNread < 0) {
@@ -94,7 +94,7 @@ protected static int calcNewNrReadSize(int nrRead, int totalNrNread) {
*
* @param in
* @param out
- * @return the nr of bytes read, or -1 if the amount > Integer.MAX_VALUE
+ * @return the nr of bytes read, or -1 if the amount > Integer.MAX_VALUE
* @throws IOException
*/
public static int copy(InputStream in, OutputStream out)
@@ -115,7 +115,7 @@ public static int copy(InputStream in, OutputStream out)
*
* @param in
* @param out
- * @return the nr of characters read, or -1 if the amount > Integer.MAX_VALUE
+ * @return the nr of characters read, or -1 if the amount > Integer.MAX_VALUE
* @throws IOException
*/
public static int copy(Reader in, Writer out) throws IOException {
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/util/ResourceUtil.java b/epublib-core/src/main/java/nl/siegmann/epublib/util/ResourceUtil.java
index 1db60226..a1e23f6e 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/util/ResourceUtil.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/util/ResourceUtil.java
@@ -41,7 +41,7 @@ public static Resource createResource(File file) throws IOException {
*
* @param title
* @param href
- * @return
+ * @return a resource with as contents a html page with the given title.
*/
public static Resource createResource(String title, String href) {
String content = "" + title + "
" + title + "
";
@@ -53,7 +53,7 @@ public static Resource createResource(String title, String href) {
*
* @param zipEntry
* @param zipInputStream
- * @return
+ * @return a resource created out of the given zipEntry and zipInputStream.
* @throws IOException
*/
public static Resource createResource(ZipEntry zipEntry, ZipInputStream zipInputStream) throws IOException {
@@ -72,7 +72,7 @@ public static Resource createResource(ZipEntry zipEntry, InputStream zipInputStr
* @param inputEncoding
* @param outputEncoding
* @param input
- * @return
+ * @return the string from given input character encoding converted to the requested output character encoding.
* @throws UnsupportedEncodingException
*/
public static byte[] recode(String inputEncoding, String outputEncoding, byte[] input) throws UnsupportedEncodingException {
@@ -108,8 +108,8 @@ public static Document getAsDocument(Resource resource) throws UnsupportedEncodi
* Reads the given resources inputstream, parses the xml therein and returns the result as a Document
*
* @param resource
- * @param documentBuilderFactory
- * @return
+ * @param documentBuilder
+ * @return the document created from the given resource
* @throws UnsupportedEncodingException
* @throws SAXException
* @throws IOException
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/util/StringUtil.java b/epublib-core/src/main/java/nl/siegmann/epublib/util/StringUtil.java
index 3735c652..0f60b923 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/util/StringUtil.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/util/StringUtil.java
@@ -23,7 +23,7 @@ public class StringUtil {
* paths like "../".
*
* @param path
- * @return
+ * @return the normalized path
*/
public static String collapsePathDots(String path) {
String[] stringParts = path.split("/");
@@ -57,7 +57,7 @@ public static String collapsePathDots(String path) {
* only whitespace.
*
* @param text
- * @return
+ * @return Whether the String is not null, not zero-length and does not contain of
*/
public static boolean isNotBlank(String text) {
return !isBlank(text);
@@ -65,6 +65,8 @@ public static boolean isNotBlank(String text) {
/**
* Whether the String is null, zero-length and does contain only whitespace.
+ *
+ * @return Whether the String is null, zero-length and does contain only whitespace.
*/
public static boolean isBlank(String text) {
if (isEmpty(text)) {
@@ -81,8 +83,8 @@ public static boolean isBlank(String text) {
/**
* Whether the given string is null or zero-length.
*
- * @param text
- * @return
+ * @param text the input for this method
+ * @return Whether the given string is null or zero-length.
*/
public static boolean isEmpty(String text) {
return (text == null) || (text.length() == 0);
@@ -94,7 +96,7 @@ public static boolean isEmpty(String text) {
*
* @param source
* @param suffix
- * @return
+ * @return Whether the given source string ends with the given suffix, ignoring case.
*/
public static boolean endsWithIgnoreCase(String source, String suffix) {
if (isEmpty(suffix)) {
@@ -114,7 +116,7 @@ public static boolean endsWithIgnoreCase(String source, String suffix) {
* If the given text is null return "", the original text otherwise.
*
* @param text
- * @return
+ * @return If the given text is null "", the original text otherwise.
*/
public static String defaultIfNull(String text) {
return defaultIfNull(text, "");
@@ -125,7 +127,7 @@ public static String defaultIfNull(String text) {
*
* @param text
* @param defaultValue
- * @return
+ * @return If the given text is null "", the given defaultValue otherwise.
*/
public static String defaultIfNull(String text, String defaultValue) {
if (text == null) {
@@ -139,7 +141,7 @@ public static String defaultIfNull(String text, String defaultValue) {
*
* @param text1
* @param text2
- * @return
+ * @return whether the two strings are equal
*/
public static boolean equals(String text1, String text2) {
if (text1 == null) {
@@ -152,7 +154,7 @@ public static boolean equals(String text1, String text2) {
* Pretty toString printer.
*
* @param keyValues
- * @return
+ * @return a string representation of the input values
*/
public static String toString(Object... keyValues) {
StringBuilder result = new StringBuilder();
@@ -195,7 +197,7 @@ public static int hashCode(String... values) {
*
* @param text
* @param separator
- * @return
+ * @return the substring of the given text before the given separator.
*/
public static String substringBefore(String text, char separator) {
if (isEmpty(text)) {
@@ -217,7 +219,7 @@ public static String substringBefore(String text, char separator) {
*
* @param text
* @param separator
- * @return
+ * @return the substring of the given text before the last occurrence of the given separator.
*/
public static String substringBeforeLast(String text, char separator) {
if (isEmpty(text)) {
@@ -238,7 +240,7 @@ public static String substringBeforeLast(String text, char separator) {
*
* @param text
* @param separator
- * @return
+ * @return the substring of the given text after the last occurrence of the given separator.
*/
public static String substringAfterLast(String text, char separator) {
if (isEmpty(text)) {
@@ -256,9 +258,9 @@ public static String substringAfterLast(String text, char separator) {
*
* If the text does not contain the given separator then "" is returned.
*
- * @param text
- * @param separator
- * @return
+ * @param text the input text
+ * @param c the separator char
+ * @return the substring of the given text after the given separator.
*/
public static String substringAfter(String text, char c) {
if (isEmpty(text)) {
diff --git a/epublib-tools/src/main/java/nl/siegmann/epublib/chm/ChmParser.java b/epublib-tools/src/main/java/nl/siegmann/epublib/chm/ChmParser.java
index 97001a7d..501a9f5b 100644
--- a/epublib-tools/src/main/java/nl/siegmann/epublib/chm/ChmParser.java
+++ b/epublib-tools/src/main/java/nl/siegmann/epublib/chm/ChmParser.java
@@ -59,11 +59,11 @@ public static Book parseChm(FileObject chmRootDir, String inputHtmlEncoding)
/**
- * Finds in the '#SYSTEM' file the 3rd set of characters that have ascii value >= 32 and <= 126 and is more than 3 characters long.
+ * Finds in the '#SYSTEM' file the 3rd set of characters that have ascii value >= 32 and >= 126 and is more than 3 characters long.
* Assumes that that is then the title of the book.
*
* @param chmRootDir
- * @return
+ * @return Finds in the '#SYSTEM' file the 3rd set of characters that have ascii value >= 32 and >= 126 and is more than 3 characters long.
* @throws IOException
*/
protected static String findTitle(FileObject chmRootDir) throws IOException {
diff --git a/epublib-tools/src/main/java/nl/siegmann/epublib/fileset/FilesetBookCreator.java b/epublib-tools/src/main/java/nl/siegmann/epublib/fileset/FilesetBookCreator.java
index c38f1cdd..66f41280 100644
--- a/epublib-tools/src/main/java/nl/siegmann/epublib/fileset/FilesetBookCreator.java
+++ b/epublib-tools/src/main/java/nl/siegmann/epublib/fileset/FilesetBookCreator.java
@@ -61,7 +61,7 @@ public static Book createBookFromDirectory(FileObject rootDirectory) throws IOEx
*
* @see nl.siegmann.epublib.domain.MediaTypeService
* @param rootDirectory
- * @return
+ * @return the newly created Book
* @throws IOException
*/
public static Book createBookFromDirectory(FileObject rootDirectory, String encoding) throws IOException {
diff --git a/epublib-tools/src/main/java/nl/siegmann/epublib/search/SearchIndex.java b/epublib-tools/src/main/java/nl/siegmann/epublib/search/SearchIndex.java
index e3ce2e84..1c1c5d11 100644
--- a/epublib-tools/src/main/java/nl/siegmann/epublib/search/SearchIndex.java
+++ b/epublib-tools/src/main/java/nl/siegmann/epublib/search/SearchIndex.java
@@ -142,7 +142,7 @@ public static String getSearchContent(Reader content) {
* Checks whether the given character is a java whitespace or a non-breaking-space ( ).
*
* @param c
- * @return
+ * @return whether the given character is a java whitespace or a non-breaking-space ( ).
*/
private static boolean isHtmlWhitespace(int c) {
return c == NBSP || Character.isWhitespace(c);
@@ -177,7 +177,7 @@ public static String unicodeTrim(String text) {
* Replaces multiple whitespaces with a single space.
*
* @param text
- * @return
+ * @return html encoded text turned into plain text.
*/
public static String cleanText(String text) {
text = unicodeTrim(text);
diff --git a/epublib-tools/src/main/java/nl/siegmann/epublib/util/DesktopUtil.java b/epublib-tools/src/main/java/nl/siegmann/epublib/util/DesktopUtil.java
index b052e386..aa18159f 100644
--- a/epublib-tools/src/main/java/nl/siegmann/epublib/util/DesktopUtil.java
+++ b/epublib-tools/src/main/java/nl/siegmann/epublib/util/DesktopUtil.java
@@ -13,7 +13,7 @@ public class DesktopUtil {
/**
* Open a URL in the default web browser.
*
- * @param a URL to open in a web browser.
+ * @param url a URL to open in a web browser.
* @return true if a browser has been launched.
*/
public static boolean launchBrowser(URL url) throws BrowserLaunchException {
diff --git a/epublib-tools/src/main/java/nl/siegmann/epublib/util/ToolsResourceUtil.java b/epublib-tools/src/main/java/nl/siegmann/epublib/util/ToolsResourceUtil.java
index 7e23646c..3f84e175 100644
--- a/epublib-tools/src/main/java/nl/siegmann/epublib/util/ToolsResourceUtil.java
+++ b/epublib-tools/src/main/java/nl/siegmann/epublib/util/ToolsResourceUtil.java
@@ -56,11 +56,11 @@ public static String getTitle(Resource resource) {
/**
- * Retrieves whatever it finds between ... or ....
+ * Retrieves whatever it finds between <title>...</title> or <h1-7>...</h1-7>.
* The first match is returned, even if it is a blank string.
* If it finds nothing null is returned.
* @param resource
- * @return
+ * @return whatever it finds in the resource between <title>...</title> or <h1-7>...</h1-7>.
*/
public static String findTitleFromXhtml(Resource resource) {
if (resource == null) {
diff --git a/epublib-tools/src/main/java/nl/siegmann/epublib/util/VFSUtil.java b/epublib-tools/src/main/java/nl/siegmann/epublib/util/VFSUtil.java
index 248e1059..4124ca42 100644
--- a/epublib-tools/src/main/java/nl/siegmann/epublib/util/VFSUtil.java
+++ b/epublib-tools/src/main/java/nl/siegmann/epublib/util/VFSUtil.java
@@ -46,7 +46,7 @@ public static String calculateHref(FileObject rootDir, FileObject currentFile) t
/**
* First tries to load the inputLocation via VFS; if that doesn't work it tries to load it as a local File
* @param inputLocation
- * @return
+ * @return the FileObject referred to by the inputLocation
* @throws FileSystemException
*/
public static FileObject resolveFileObject(String inputLocation) throws FileSystemException {
@@ -69,7 +69,7 @@ public static FileObject resolveFileObject(String inputLocation) throws FileSyst
* First tries to load the inputLocation via VFS; if that doesn't work it tries to load it as a local File
*
* @param inputLocation
- * @return
+ * @return the InputStream referred to by the inputLocation
* @throws FileSystemException
*/
public static InputStream resolveInputStream(String inputLocation) throws FileSystemException {
diff --git a/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ButtonBar.java b/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ButtonBar.java
index b1cda782..553f74b3 100644
--- a/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ButtonBar.java
+++ b/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ButtonBar.java
@@ -12,7 +12,6 @@
/**
* Creates a panel with the first,previous,next and last buttons.
*
- * @return
*/
class ButtonBar extends JPanel {
private static final long serialVersionUID = 6431437924245035812L;
@@ -95,4 +94,4 @@ public void actionPerformed(ActionEvent e) {
}
});
}
-}
\ No newline at end of file
+}
diff --git a/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ContentPane.java b/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ContentPane.java
index 6cb59583..ae76fac6 100644
--- a/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ContentPane.java
+++ b/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ContentPane.java
@@ -38,7 +38,6 @@
/**
* Displays a page
*
- * @return
*/
public class ContentPane extends JPanel implements NavigationEventListener,
HyperlinkListener {
@@ -140,7 +139,7 @@ private void initBook(Book book) {
*
* @param searchString
* @param possibleValues
- * @return
+ * @return Whether the given searchString matches any of the possibleValues.
*/
private static boolean matchesAny(String searchString, String... possibleValues) {
for (int i = 0; i < possibleValues.length; i++) {
@@ -337,7 +336,7 @@ public void gotoNextPage() {
* Property handles http encoded spaces and such.
*
* @param clickUrl
- * @return
+ * @return a link generated by a click on a link transformed into a document to a resource href.
*/
private String calculateTargetHref(URL clickUrl) {
String resourceHref = clickUrl.toString();
@@ -383,4 +382,4 @@ public void navigationPerformed(NavigationEvent navigationEvent) {
}
-}
\ No newline at end of file
+}
diff --git a/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/HTMLDocumentFactory.java b/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/HTMLDocumentFactory.java
index edd5edc6..3af997b0 100644
--- a/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/HTMLDocumentFactory.java
+++ b/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/HTMLDocumentFactory.java
@@ -84,7 +84,7 @@ private void putDocument(Resource resource, HTMLDocument document) {
* the resource and adds it to the cache.
*
* @param resource
- * @return
+ * @return the HTMLDocument representation of the resource.
*/
public HTMLDocument getDocument(Resource resource) {
HTMLDocument document = null;
@@ -122,7 +122,7 @@ private String stripHtml(String input) {
* these confuse the html viewer.
*
* @param input
- * @return
+ * @return the input stripped of control characters
*/
private static String removeControlTags(String input) {
StringBuilder result = new StringBuilder();
@@ -150,7 +150,7 @@ private static String removeControlTags(String input) {
* If the resources is not of type XHTML then null is returned.
*
* @param resource
- * @return
+ * @return a swing HTMLDocument created from the given resource.
*/
private HTMLDocument createDocument(Resource resource) {
HTMLDocument result = null;
diff --git a/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/TableOfContentsPane.java b/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/TableOfContentsPane.java
index 8c73a8f8..5bd6631a 100644
--- a/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/TableOfContentsPane.java
+++ b/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/TableOfContentsPane.java
@@ -46,7 +46,6 @@ public class TableOfContentsPane extends JPanel implements NavigationEventListen
* Also sets up a selectionListener that updates the SectionWalker when an item in the tree is selected.
*
* @param navigator
- * @return
*/
public TableOfContentsPane(Navigator navigator) {
super(new GridLayout(1, 0));
diff --git a/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ViewerUtil.java b/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ViewerUtil.java
index 57739988..7f9e3b0e 100644
--- a/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ViewerUtil.java
+++ b/epublib-tools/src/main/java/nl/siegmann/epublib/viewer/ViewerUtil.java
@@ -19,7 +19,7 @@ public class ViewerUtil {
*
* @param iconName
* @param backupLabel
- * @return
+ * @return a button with the given icon.
*/
// package
static JButton createButton(String iconName, String backupLabel) {
From fd1e80fb5c8b9e975ab1c7148f91d285e9a167c6 Mon Sep 17 00:00:00 2001
From: Alex Kuiper
Date: Thu, 25 Jul 2013 21:06:52 +0200
Subject: [PATCH 22/57] Also used ZipFile for lazy loading now.
---
.../java/nl/siegmann/epublib/epub/EpubReader.java | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
index 929bf22d..bfba08a8 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
@@ -164,10 +164,14 @@ private void handleMimeType(Book result, Resources resources) {
private Resources readLazyResources( String fileName, String defaultHtmlEncoding,
List lazyLoadedTypes) throws IOException {
- ZipInputStream in = new ZipInputStream(new FileInputStream(fileName));
-
+ ZipFile zipFile = new ZipFile(fileName);
+
Resources result = new Resources();
- for(ZipEntry zipEntry = in.getNextEntry(); zipEntry != null; zipEntry = in.getNextEntry()) {
+ Enumeration extends ZipEntry> entries = zipFile.entries();
+
+ while( entries.hasMoreElements() ) {
+ ZipEntry zipEntry = entries.nextElement();
+
if(zipEntry.isDirectory()) {
continue;
}
@@ -180,7 +184,7 @@ private Resources readLazyResources( String fileName, String defaultHtmlEncoding
if ( lazyLoadedTypes.contains(mediaType) ) {
resource = new Resource(fileName, zipEntry.getSize(), href);
} else {
- resource = new Resource( in, fileName, (int) zipEntry.getSize(), href );
+ resource = new Resource( zipFile.getInputStream(zipEntry), fileName, (int) zipEntry.getSize(), href );
}
if(resource.getMediaType() == MediatypeService.XHTML) {
From eb6bd3724f41641bf815b928b23e80359ddc55d6 Mon Sep 17 00:00:00 2001
From: "P. Siegmann"
Date: Mon, 17 Mar 2014 05:22:43 +0100
Subject: [PATCH 23/57] add function to CollectionUtil
---
.../java/nl/siegmann/epublib/util/CollectionUtil.java | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/util/CollectionUtil.java b/epublib-core/src/main/java/nl/siegmann/epublib/util/CollectionUtil.java
index 5b563f15..f780cb68 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/util/CollectionUtil.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/util/CollectionUtil.java
@@ -1,5 +1,6 @@
package nl.siegmann.epublib.util;
+import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
@@ -54,4 +55,14 @@ public static T first(List list) {
}
return list.get(0);
}
+
+ /**
+ * Whether the given collection is null or has no elements.
+ *
+ * @param collection
+ * @return Whether the given collection is null or has no elements.
+ */
+ public static boolean isEmpty(Collection> collection) {
+ return collection == null || collection.isEmpty();
+ }
}
From 8ea49df246efb5250c7c01358e9dc7f471d71e76 Mon Sep 17 00:00:00 2001
From: "P. Siegmann"
Date: Mon, 17 Mar 2014 05:27:01 +0100
Subject: [PATCH 24/57] modernize unit test style
---
.../siegmann/epublib/epub/EpubReaderTest.java | 118 +++++++++---------
.../siegmann/epublib/epub/EpubWriterTest.java | 95 +++++++-------
2 files changed, 103 insertions(+), 110 deletions(-)
diff --git a/epublib-core/src/test/java/nl/siegmann/epublib/epub/EpubReaderTest.java b/epublib-core/src/test/java/nl/siegmann/epublib/epub/EpubReaderTest.java
index 16df2fa9..54a8ff2f 100644
--- a/epublib-core/src/test/java/nl/siegmann/epublib/epub/EpubReaderTest.java
+++ b/epublib-core/src/test/java/nl/siegmann/epublib/epub/EpubReaderTest.java
@@ -2,77 +2,73 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
-import junit.framework.TestCase;
import nl.siegmann.epublib.domain.Book;
import nl.siegmann.epublib.domain.Resource;
import nl.siegmann.epublib.service.MediatypeService;
-public class EpubReaderTest extends TestCase {
-
- public void testCover_only_cover() {
- try {
- Book book = new Book();
-
- book.setCoverImage(new Resource(this.getClass().getResourceAsStream("/book1/cover.png"), "cover.png"));
+import org.junit.Assert;
+import org.junit.Test;
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- (new EpubWriter()).write(book, out);
- byte[] epubData = out.toByteArray();
- Book readBook = new EpubReader().readEpub(new ByteArrayInputStream(epubData));
- assertNotNull(readBook.getCoverImage());
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- assertTrue(false);
- }
+public class EpubReaderTest {
+ @Test
+ public void testCover_only_cover() throws IOException {
+ Book book = new Book();
+
+ book.setCoverImage(new Resource(this.getClass().getResourceAsStream(
+ "/book1/cover.png"), "cover.png"));
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ (new EpubWriter()).write(book, out);
+ byte[] epubData = out.toByteArray();
+ Book readBook = new EpubReader().readEpub(new ByteArrayInputStream(
+ epubData));
+ Assert.assertNotNull(readBook.getCoverImage());
}
- public void testCover_cover_one_section() {
- try {
- Book book = new Book();
-
- book.setCoverImage(new Resource(this.getClass().getResourceAsStream("/book1/cover.png"), "cover.png"));
- book.addSection("Introduction", new Resource(this.getClass().getResourceAsStream("/book1/chapter1.html"), "chapter1.html"));
- book.generateSpineFromTableOfContents();
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- (new EpubWriter()).write(book, out);
- byte[] epubData = out.toByteArray();
- Book readBook = new EpubReader().readEpub(new ByteArrayInputStream(epubData));
- assertNotNull(readBook.getCoverPage());
- assertEquals(1, readBook.getSpine().size());
- assertEquals(1, readBook.getTableOfContents().size());
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- assertTrue(false);
- }
+ @Test
+ public void testCover_cover_one_section() throws IOException {
+ Book book = new Book();
+
+ book.setCoverImage(new Resource(this.getClass().getResourceAsStream(
+ "/book1/cover.png"), "cover.png"));
+ book.addSection("Introduction", new Resource(this.getClass()
+ .getResourceAsStream("/book1/chapter1.html"), "chapter1.html"));
+ book.generateSpineFromTableOfContents();
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ (new EpubWriter()).write(book, out);
+ byte[] epubData = out.toByteArray();
+ Book readBook = new EpubReader().readEpub(new ByteArrayInputStream(
+ epubData));
+ Assert.assertNotNull(readBook.getCoverPage());
+ Assert.assertEquals(1, readBook.getSpine().size());
+ Assert.assertEquals(1, readBook.getTableOfContents().size());
}
- public void testReadEpub_opf_ncx_docs() {
- try {
- Book book = new Book();
-
- book.setCoverImage(new Resource(this.getClass().getResourceAsStream("/book1/cover.png"), "cover.png"));
- book.addSection("Introduction", new Resource(this.getClass().getResourceAsStream("/book1/chapter1.html"), "chapter1.html"));
- book.generateSpineFromTableOfContents();
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- (new EpubWriter()).write(book, out);
- byte[] epubData = out.toByteArray();
- Book readBook = new EpubReader().readEpub(new ByteArrayInputStream(epubData));
- assertNotNull(readBook.getCoverPage());
- assertEquals(1, readBook.getSpine().size());
- assertEquals(1, readBook.getTableOfContents().size());
- assertNotNull(readBook.getOpfResource());
- assertNotNull(readBook.getNcxResource());
- assertEquals(MediatypeService.NCX, readBook.getNcxResource().getMediaType());
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- assertTrue(false);
- }
+ @Test
+ public void testReadEpub_opf_ncx_docs() throws IOException {
+ Book book = new Book();
+
+ book.setCoverImage(new Resource(this.getClass().getResourceAsStream(
+ "/book1/cover.png"), "cover.png"));
+ book.addSection("Introduction", new Resource(this.getClass()
+ .getResourceAsStream("/book1/chapter1.html"), "chapter1.html"));
+ book.generateSpineFromTableOfContents();
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ (new EpubWriter()).write(book, out);
+ byte[] epubData = out.toByteArray();
+ Book readBook = new EpubReader().readEpub(new ByteArrayInputStream(
+ epubData));
+ Assert.assertNotNull(readBook.getCoverPage());
+ Assert.assertEquals(1, readBook.getSpine().size());
+ Assert.assertEquals(1, readBook.getTableOfContents().size());
+ Assert.assertNotNull(readBook.getOpfResource());
+ Assert.assertNotNull(readBook.getNcxResource());
+ Assert.assertEquals(MediatypeService.NCX, readBook.getNcxResource()
+ .getMediaType());
}
}
diff --git a/epublib-core/src/test/java/nl/siegmann/epublib/epub/EpubWriterTest.java b/epublib-core/src/test/java/nl/siegmann/epublib/epub/EpubWriterTest.java
index fb3c0289..644b1a82 100644
--- a/epublib-core/src/test/java/nl/siegmann/epublib/epub/EpubWriterTest.java
+++ b/epublib-core/src/test/java/nl/siegmann/epublib/epub/EpubWriterTest.java
@@ -2,11 +2,11 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import junit.framework.TestCase;
import nl.siegmann.epublib.domain.Author;
import nl.siegmann.epublib.domain.Book;
import nl.siegmann.epublib.domain.GuideReference;
@@ -15,62 +15,59 @@
import nl.siegmann.epublib.domain.TOCReference;
import nl.siegmann.epublib.util.CollectionUtil;
-public class EpubWriterTest extends TestCase {
+import org.junit.Assert;
+import org.junit.Test;
- public void testBook1() {
- try {
- // create test book
- Book book = createTestBook();
-
- // write book to byte[]
- byte[] bookData = writeBookToByteArray(book);
-// FileOutputStream fileOutputStream = new FileOutputStream("foo.zip");
-// fileOutputStream.write(bookData);
-// fileOutputStream.flush();
-// fileOutputStream.close();
- assertNotNull(bookData);
- assertTrue(bookData.length > 0);
-
- // read book from byte[]
- Book readBook = new EpubReader().readEpub(new ByteArrayInputStream(bookData));
-
- // assert book values are correct
- assertEquals(book.getMetadata().getTitles(), readBook.getMetadata().getTitles());
- assertEquals(Identifier.Scheme.ISBN, CollectionUtil.first(readBook.getMetadata().getIdentifiers()).getScheme());
- assertEquals(CollectionUtil.first(book.getMetadata().getIdentifiers()).getValue(), CollectionUtil.first(readBook.getMetadata().getIdentifiers()).getValue());
- assertEquals(CollectionUtil.first(book.getMetadata().getAuthors()), CollectionUtil.first(readBook.getMetadata().getAuthors()));
- assertEquals(1, readBook.getGuide().getGuideReferencesByType(GuideReference.COVER).size());
- assertEquals(5, readBook.getSpine().size());
- assertNotNull(book.getCoverPage());
- assertNotNull(book.getCoverImage());
- assertEquals(4, readBook.getTableOfContents().size());
+public class EpubWriterTest {
+
+ @Test
+ public void testBook1() throws IOException {
+ // create test book
+ Book book = createTestBook();
+
+ // write book to byte[]
+ byte[] bookData = writeBookToByteArray(book);
+ FileOutputStream fileOutputStream = new FileOutputStream("foo.zip");
+ fileOutputStream.write(bookData);
+ fileOutputStream.flush();
+ fileOutputStream.close();
+ Assert.assertNotNull(bookData);
+ Assert.assertTrue(bookData.length > 0);
+
+ // read book from byte[]
+ Book readBook = new EpubReader().readEpub(new ByteArrayInputStream(bookData));
+
+ // assert book values are correct
+ Assert.assertEquals(book.getMetadata().getTitles(), readBook.getMetadata().getTitles());
+ Assert.assertEquals(Identifier.Scheme.ISBN, CollectionUtil.first(readBook.getMetadata().getIdentifiers()).getScheme());
+ Assert.assertEquals(CollectionUtil.first(book.getMetadata().getIdentifiers()).getValue(), CollectionUtil.first(readBook.getMetadata().getIdentifiers()).getValue());
+ Assert.assertEquals(CollectionUtil.first(book.getMetadata().getAuthors()), CollectionUtil.first(readBook.getMetadata().getAuthors()));
+ Assert.assertEquals(1, readBook.getGuide().getGuideReferencesByType(GuideReference.COVER).size());
+ Assert.assertEquals(5, readBook.getSpine().size());
+ Assert.assertNotNull(book.getCoverPage());
+ Assert.assertNotNull(book.getCoverImage());
+ Assert.assertEquals(4, readBook.getTableOfContents().size());
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
}
/**
* Test for a very old bug where epublib would throw a NullPointerException when writing a book with a cover that has no id.
+ * @throws IOException
+ * @throws FileNotFoundException
*
*/
- public void testWritingBookWithCoverWithNullId() {
- try {
- Book book = new Book();
- book.getMetadata().addTitle("Epub test book 1");
- book.getMetadata().addAuthor(new Author("Joe", "Tester"));
- InputStream is = this.getClass().getResourceAsStream("/book1/cover.png");
- book.setCoverImage(new Resource(is, "cover.png"));
- // Add Chapter 1
- InputStream is1 = this.getClass().getResourceAsStream("/book1/chapter1.html");
- book.addSection("Introduction", new Resource(is1, "chapter1.html"));
-
- EpubWriter epubWriter = new EpubWriter();
- epubWriter.write(book, new FileOutputStream("test1_book1.epub"));
- } catch (IOException e) {
- fail(e.getMessage());
- }
+ public void testWritingBookWithCoverWithNullId() throws FileNotFoundException, IOException {
+ Book book = new Book();
+ book.getMetadata().addTitle("Epub test book 1");
+ book.getMetadata().addAuthor(new Author("Joe", "Tester"));
+ InputStream is = this.getClass().getResourceAsStream("/book1/cover.png");
+ book.setCoverImage(new Resource(is, "cover.png"));
+ // Add Chapter 1
+ InputStream is1 = this.getClass().getResourceAsStream("/book1/chapter1.html");
+ book.addSection("Introduction", new Resource(is1, "chapter1.html"));
+
+ EpubWriter epubWriter = new EpubWriter();
+ epubWriter.write(book, new FileOutputStream("test1_book1.epub"));
}
private Book createTestBook() throws IOException {
From 1b0aa98b7a9f67e1b795c0177dc9674b2cb064b8 Mon Sep 17 00:00:00 2001
From: "P. Siegmann"
Date: Mon, 17 Mar 2014 05:28:54 +0100
Subject: [PATCH 25/57] refactor the loading of resources
---
.../siegmann/epublib/domain/LazyResource.java | 166 ++++++++++++++++
.../nl/siegmann/epublib/domain/Resource.java | 119 +-----------
.../epublib/domain/ResourceInputStream.java | 10 +-
.../nl/siegmann/epublib/domain/Resources.java | 4 +-
.../nl/siegmann/epublib/epub/EpubReader.java | 118 +++---------
.../epublib/epub/ResourcesLoader.java | 135 +++++++++++++
.../epublib/epub/ResourcesLoaderTest.java | 178 ++++++++++++++++++
.../epublib/util/CollectionUtilTest.java | 25 +++
.../src/test/resources/testbook1.epub | Bin 0 -> 337350 bytes
9 files changed, 536 insertions(+), 219 deletions(-)
create mode 100644 epublib-core/src/main/java/nl/siegmann/epublib/domain/LazyResource.java
create mode 100644 epublib-core/src/main/java/nl/siegmann/epublib/epub/ResourcesLoader.java
create mode 100644 epublib-core/src/test/java/nl/siegmann/epublib/epub/ResourcesLoaderTest.java
create mode 100644 epublib-core/src/test/java/nl/siegmann/epublib/util/CollectionUtilTest.java
create mode 100644 epublib-core/src/test/resources/testbook1.epub
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/LazyResource.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/LazyResource.java
new file mode 100644
index 00000000..7f49dc62
--- /dev/null
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/LazyResource.java
@@ -0,0 +1,166 @@
+package nl.siegmann.epublib.domain;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import nl.siegmann.epublib.service.MediatypeService;
+import nl.siegmann.epublib.util.IOUtil;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A Resource that loads its data only on-demand.
+ * This way larger books can fit into memory and can be opened faster.
+ *
+ */
+public class LazyResource extends Resource {
+
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5089400472352002866L;
+ private String filename;
+ private long cachedSize;
+
+ private static final Logger LOG = LoggerFactory.getLogger(LazyResource.class);
+
+ /**
+ * Creates a Lazy resource, by not actually loading the data for this entry.
+ *
+ * The data will be loaded on the first call to getData()
+ *
+ * @param fileName the fileName for the epub we're created from.
+ * @param size the size of this resource.
+ * @param href The resource's href within the epub.
+ */
+ public LazyResource(String filename, long size, String href) {
+ super( null, null, href, MediatypeService.determineMediaType(href));
+ this.filename = filename;
+ this.cachedSize = size;
+ }
+
+ /**
+ * Creates a Resource that tries to load the data, but falls back to lazy loading.
+ *
+ * If the size of the resource is known ahead of time we can use that to allocate
+ * a matching byte[]. If this succeeds we can safely load the data.
+ *
+ * If it fails we leave the data null for now and it will be lazy-loaded when
+ * it is accessed.
+ *
+ * @param in
+ * @param fileName
+ * @param length
+ * @param href
+ * @throws IOException
+ */
+ public LazyResource(InputStream in, String filename, int length, String href) throws IOException {
+ super(null, IOUtil.toByteArray(in, length), href, MediatypeService.determineMediaType(href));
+ this.filename = filename;
+ this.cachedSize = length;
+ }
+
+ /**
+ * Gets the contents of the Resource as an InputStream.
+ *
+ * @return The contents of the Resource.
+ *
+ * @throws IOException
+ */
+ public InputStream getInputStream() throws IOException {
+ if (isInitialized()) {
+ return new ByteArrayInputStream(getData());
+ } else {
+ return getResourceStream();
+ }
+ }
+
+ /**
+ * Initializes the resource by loading its data into memory.
+ *
+ * @throws IOException
+ */
+ public void initialize() throws IOException {
+ getData();
+ }
+
+ /**
+ * The contents of the resource as a byte[]
+ *
+ * If this resource was lazy-loaded and the data was not yet loaded,
+ * it will be loaded into memory at this point.
+ * This included opening the zip file, so expect a first load to be slow.
+ *
+ * @return The contents of the resource
+ */
+ public byte[] getData() throws IOException {
+
+ if ( data == null ) {
+
+ LOG.debug("Initializing lazy resource " + filename + "#" + this.getHref() );
+
+ InputStream in = getResourceStream();
+ byte[] readData = IOUtil.toByteArray(in, (int) this.cachedSize);
+ if ( readData == null ) {
+ throw new IOException("Could not load the contents of entry " + this.getHref() + " from epub file " + filename);
+ } else {
+ this.data = readData;
+ }
+
+ in.close();
+ }
+
+ return data;
+ }
+
+
+ private InputStream getResourceStream() throws FileNotFoundException,
+ IOException {
+ ZipFile zipFile = new ZipFile(filename);
+ ZipEntry zipEntry = zipFile.getEntry(originalHref);
+ if (zipEntry == null) {
+ zipFile.close();
+ throw new IllegalStateException("Cannot find entry " + originalHref + " in epub file " + filename);
+ }
+ return new ResourceInputStream(zipFile.getInputStream(zipEntry), zipFile);
+ }
+
+ /**
+ * Tells this resource to release its cached data.
+ *
+ * If this resource was not lazy-loaded, this is a no-op.
+ */
+ public void close() {
+ if ( this.filename != null ) {
+ this.data = null;
+ }
+ }
+
+ /**
+ * Returns if the data for this resource has been loaded into memory.
+ *
+ * @return true if data was loaded.
+ */
+ public boolean isInitialized() {
+ return data != null;
+ }
+
+ /**
+ * Returns the size of this resource in bytes.
+ *
+ * @return the size.
+ */
+ public long getSize() {
+ if ( data != null ) {
+ return data.length;
+ }
+
+ return cachedSize;
+ }
+}
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
index a5f66cc6..e8fefc18 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resource.java
@@ -1,14 +1,10 @@
package nl.siegmann.epublib.domain;
import java.io.ByteArrayInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.Serializable;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
import nl.siegmann.epublib.Constants;
import nl.siegmann.epublib.service.MediatypeService;
@@ -16,9 +12,6 @@
import nl.siegmann.epublib.util.StringUtil;
import nl.siegmann.epublib.util.commons.io.XmlStreamReader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
/**
* Represents a resource that is part of the epub.
* A resource can be a html file, image, xml, etc.
@@ -35,15 +28,10 @@ public class Resource implements Serializable {
private String id;
private String title;
private String href;
- private String originalHref;
+ protected String originalHref;
private MediaType mediaType;
private String inputEncoding = Constants.CHARACTER_ENCODING;
- private byte[] data;
-
- private String fileName;
- private long cachedSize;
-
- private static final Logger LOG = LoggerFactory.getLogger(Resource.class);
+ protected byte[] data;
/**
* Creates an empty Resource with the given href.
@@ -116,44 +104,6 @@ public Resource(Reader in, String href) throws IOException {
public Resource(InputStream in, String href) throws IOException {
this(null, IOUtil.toByteArray(in), href, MediatypeService.determineMediaType(href));
}
-
- /**
- * Creates a Resource that tries to load the data, but falls back to lazy loading.
- *
- * If the size of the resource is known ahead of time we can use that to allocate
- * a matching byte[]. If this succeeds we can safely load the data.
- *
- * If it fails we leave the data null for now and it will be lazy-loaded when
- * it is accessed.
- *
- * @param in
- * @param fileName
- * @param length
- * @param href
- * @throws IOException
- */
- public Resource(InputStream in, String fileName, int length, String href) throws IOException {
- this( null, IOUtil.toByteArray(in, length), href, MediatypeService.determineMediaType(href));
- this.fileName = fileName;
- this.cachedSize = length;
- }
-
- /**
-
- /**
- * Creates a Lazy resource, by not actually loading the data for this entry.
- *
- * The data will be loaded on the first call to getData()
- *
- * @param fileName the fileName for the epub we're created from.
- * @param size the size of this resource.
- * @param href The resource's href within the epub.
- */
- public Resource( String fileName, long size, String href) {
- this( null, null, href, MediatypeService.determineMediaType(href));
- this.fileName = fileName;
- this.cachedSize = size;
- }
/**
* Creates a resource with the given id, data, mediatype at the specified href.
@@ -196,72 +146,24 @@ public Resource(String id, byte[] data, String href, MediaType mediaType, String
* @throws IOException
*/
public InputStream getInputStream() throws IOException {
- if (isInitialized()) {
- return new ByteArrayInputStream(getData());
- } else {
- return getResourceStream();
- }
+ return new ByteArrayInputStream(getData());
}
- /**
- * Initializes the resource by loading its data into memory.
- *
- * @throws IOException
- */
- public void initialize() throws IOException {
- getData();
- }
-
/**
* The contents of the resource as a byte[]
*
- * If this resource was lazy-loaded and the data was not yet loaded,
- * it will be loaded into memory at this point.
- * This included opening the zip file, so expect a first load to be slow.
- *
* @return The contents of the resource
*/
public byte[] getData() throws IOException {
-
- if ( data == null ) {
-
- LOG.info("Initializing lazy resource " + fileName + "#" + this.href );
-
- InputStream in = getResourceStream();
- byte[] readData = IOUtil.toByteArray(in, (int) this.cachedSize);
- if ( readData == null ) {
- throw new IOException("Could not lazy-load data.");
- } else {
- this.data = readData;
- this.data = IOUtil.toByteArray(in);
- }
-
- in.close();
- }
-
return data;
}
- private InputStream getResourceStream() throws FileNotFoundException,
- IOException {
- ZipFile zipResource = new ZipFile(fileName);
- ZipEntry zipEntry = zipResource.getEntry(originalHref);
- if (zipEntry == null) {
- zipResource.close();
- throw new IllegalStateException("Cannot find resources href in the epub file");
- }
- return new ResourceInputStream(zipResource.getInputStream(zipEntry), zipResource);
- }
-
/**
* Tells this resource to release its cached data.
*
* If this resource was not lazy-loaded, this is a no-op.
*/
public void close() {
- if ( this.fileName != null ) {
- this.data = null;
- }
}
/**
@@ -274,26 +176,13 @@ public void setData(byte[] data) {
this.data = data;
}
- /**
- * Returns if the data for this resource has been loaded into memory.
- *
- * @return true if data was loaded.
- */
- public boolean isInitialized() {
- return data != null;
- }
-
/**
* Returns the size of this resource in bytes.
*
* @return the size.
*/
public long getSize() {
- if ( data != null ) {
- return data.length;
- }
-
- return cachedSize;
+ return data.length;
}
/**
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/ResourceInputStream.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/ResourceInputStream.java
index 1a636f81..92b305ff 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/ResourceInputStream.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/ResourceInputStream.java
@@ -14,24 +14,24 @@
*/
public class ResourceInputStream extends FilterInputStream {
- private ZipFile zipResource;
+ private final ZipFile zipFile;
/**
* Constructor.
*
* @param in
* The InputStream object.
- * @param f
+ * @param zipFile
* The ZipFile object.
*/
- public ResourceInputStream(InputStream in, ZipFile f) {
+ public ResourceInputStream(InputStream in, ZipFile zipFile) {
super(in);
- zipResource = f;
+ this.zipFile = zipFile;
}
@Override
public void close() throws IOException {
super.close();
- zipResource.close();
+ zipFile.close();
}
}
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resources.java b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resources.java
index 2067afd5..d7b88a9c 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resources.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/domain/Resources.java
@@ -93,10 +93,10 @@ private String getResourceItemPrefix(Resource resource) {
}
/**
- * Creates a new resource id that is guarenteed to be unique for this set of Resources
+ * Creates a new resource id that is guaranteed to be unique for this set of Resources
*
* @param resource
- * @return a new resource id that is guarenteed to be unique for this set of Resources
+ * @return a new resource id that is guaranteed to be unique for this set of Resources
*/
private String createUniqueResourceId(Resource resource) {
int counter = lastId;
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
index bfba08a8..f239f559 100644
--- a/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/EpubReader.java
@@ -1,12 +1,9 @@
package nl.siegmann.epublib.epub;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
-import java.util.Enumeration;
import java.util.List;
-import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
@@ -59,27 +56,6 @@ public Book readEpub(InputStream in, String encoding) throws IOException {
return readEpub(new ZipInputStream(in), encoding);
}
- /**
- * Reads this EPUB without loading all resources into memory.
- *
- * @param fileName the file to load
- * @param encoding the encoding for XHTML files
- * @param lazyLoadedTypes a list of the MediaType to load lazily
- * @return this Book without loading all resources into memory.
- * @throws IOException
- */
- public Book readEpubLazy( String fileName, String encoding, List lazyLoadedTypes ) throws IOException {
- Book result = new Book();
- Resources resources = readLazyResources(fileName, encoding, lazyLoadedTypes);
- handleMimeType(result, resources);
- String packageResourceHref = getPackageResourceHref(resources);
- Resource packageResource = processPackageResource(packageResourceHref, result, resources);
- result.setOpfResource(packageResource);
- Resource ncxResource = processNcxResource(packageResource, result);
- result.setNcxResource(ncxResource);
- result = postProcessBook(result);
- return result;
- }
/**
@@ -91,19 +67,35 @@ public Book readEpubLazy( String fileName, String encoding, List lazy
* @return this Book without loading all resources into memory.
* @throws IOException
*/
- public Book readEpubLazy( String fileName, String encoding ) throws IOException {
- return readEpubLazy(fileName, encoding, Arrays.asList(MediatypeService.mediatypes) );
+ public Book readEpubLazy(ZipFile zipFile, String encoding ) throws IOException {
+ return readEpubLazy(zipFile, encoding, Arrays.asList(MediatypeService.mediatypes) );
}
public Book readEpub(ZipInputStream in, String encoding) throws IOException {
- return readEpubResources(readResources(in, encoding));
+ return readEpub(ResourcesLoader.loadResources(in, encoding));
}
public Book readEpub(ZipFile in, String encoding) throws IOException {
- return readEpubResources(readResources(in, encoding));
+ return readEpub(ResourcesLoader.loadResources(in, encoding));
}
- public Book readEpubResources(Resources resources) throws IOException{
+ /**
+ * Reads this EPUB without loading all resources into memory.
+ *
+ * @param fileName the file to load
+ * @param encoding the encoding for XHTML files
+ * @param lazyLoadedTypes a list of the MediaType to load lazily
+ * @return this Book without loading all resources into memory.
+ * @throws IOException
+ */
+ public Book readEpubLazy(ZipFile zipFile, String encoding, List lazyLoadedTypes ) throws IOException {
+ Book result = new Book();
+ Resources resources = ResourcesLoader.loadResources(zipFile, encoding, lazyLoadedTypes);
+ readEpub(resources);
+ return result;
+ }
+
+ public Book readEpub(Resources resources) throws IOException{
Book result = new Book();
handleMimeType(result, resources);
String packageResourceHref = getPackageResourceHref(resources);
@@ -160,72 +152,4 @@ private String getPackageResourceHref(Resources resources) {
private void handleMimeType(Book result, Resources resources) {
resources.remove("mimetype");
}
-
- private Resources readLazyResources( String fileName, String defaultHtmlEncoding,
- List lazyLoadedTypes) throws IOException {
-
- ZipFile zipFile = new ZipFile(fileName);
-
- Resources result = new Resources();
- Enumeration extends ZipEntry> entries = zipFile.entries();
-
- while( entries.hasMoreElements() ) {
- ZipEntry zipEntry = entries.nextElement();
-
- if(zipEntry.isDirectory()) {
- continue;
- }
-
- String href = zipEntry.getName();
- MediaType mediaType = MediatypeService.determineMediaType(href);
-
- Resource resource;
-
- if ( lazyLoadedTypes.contains(mediaType) ) {
- resource = new Resource(fileName, zipEntry.getSize(), href);
- } else {
- resource = new Resource( zipFile.getInputStream(zipEntry), fileName, (int) zipEntry.getSize(), href );
- }
-
- if(resource.getMediaType() == MediatypeService.XHTML) {
- resource.setInputEncoding(defaultHtmlEncoding);
- }
- result.add(resource);
- }
-
- return result;
- }
-
- private Resources readResources(ZipInputStream in, String defaultHtmlEncoding) throws IOException {
- Resources result = new Resources();
- for(ZipEntry zipEntry = in.getNextEntry(); zipEntry != null; zipEntry = in.getNextEntry()) {
- if(zipEntry.isDirectory()) {
- continue;
- }
- Resource resource = ResourceUtil.createResource(zipEntry, in);
- if(resource.getMediaType() == MediatypeService.XHTML) {
- resource.setInputEncoding(defaultHtmlEncoding);
- }
- result.add(resource);
- }
- return result;
- }
-
- private Resources readResources(ZipFile zipFile, String defaultHtmlEncoding) throws IOException {
- Resources result = new Resources();
- Enumeration extends ZipEntry> entries = zipFile.entries();
-
- while(entries.hasMoreElements()){
- ZipEntry zipEntry = entries.nextElement();
- if(zipEntry != null && !zipEntry.isDirectory()){
- Resource resource = ResourceUtil.createResource(zipEntry, zipFile.getInputStream(zipEntry));
- if(resource.getMediaType() == MediatypeService.XHTML) {
- resource.setInputEncoding(defaultHtmlEncoding);
- }
- result.add(resource);
- }
- }
-
- return result;
- }
}
diff --git a/epublib-core/src/main/java/nl/siegmann/epublib/epub/ResourcesLoader.java b/epublib-core/src/main/java/nl/siegmann/epublib/epub/ResourcesLoader.java
new file mode 100644
index 00000000..9284ff8d
--- /dev/null
+++ b/epublib-core/src/main/java/nl/siegmann/epublib/epub/ResourcesLoader.java
@@ -0,0 +1,135 @@
+package nl.siegmann.epublib.epub;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
+
+import nl.siegmann.epublib.domain.LazyResource;
+import nl.siegmann.epublib.domain.MediaType;
+import nl.siegmann.epublib.domain.Resource;
+import nl.siegmann.epublib.domain.Resources;
+import nl.siegmann.epublib.service.MediatypeService;
+import nl.siegmann.epublib.util.CollectionUtil;
+import nl.siegmann.epublib.util.ResourceUtil;
+
+/**
+ * Loads Resources from inputStreams, ZipFiles, etc
+ *
+ * @author paul
+ *
+ */
+public class ResourcesLoader {
+ /**
+ * Loads the entries of the zipFile as resources.
+ *
+ * The MediaTypes that are in the lazyLoadedTypes will not get their contents loaded, but are stored as references to
+ * entries into the ZipFile and are loaded on demand by the Resource system.
+ *
+ * @param zipFile
+ * @param defaultHtmlEncoding
+ * @param lazyLoadedTypes
+ * @return
+ * @throws IOException
+ */
+ static Resources loadResources(ZipFile zipFile, String defaultHtmlEncoding,
+ List lazyLoadedTypes) throws IOException {
+
+ Resources result = new Resources();
+ Enumeration extends ZipEntry> entries = zipFile.entries();
+
+ while( entries.hasMoreElements() ) {
+ ZipEntry zipEntry = entries.nextElement();
+
+ if(zipEntry == null || zipEntry.isDirectory()) {
+ continue;
+ }
+
+ String href = zipEntry.getName();
+
+ Resource resource;
+
+ if (shouldLoadLazy(href, lazyLoadedTypes)) {
+ resource = new LazyResource(zipFile.getName(), zipEntry.getSize(), href);
+ } else {
+ resource = ResourceUtil.createResource(zipEntry, zipFile.getInputStream(zipEntry));
+ }
+
+ if(resource.getMediaType() == MediatypeService.XHTML) {
+ resource.setInputEncoding(defaultHtmlEncoding);
+ }
+ result.add(resource);
+ }
+
+ return result;
+ }
+
+ /**
+ * Whether the given href will load a mediaType that is in the collection of lazilyLoadedMediaTypes.
+ *
+ * @param href
+ * @param lazilyLoadedMediaTypes
+ * @return Whether the given href will load a mediaType that is in the collection of lazilyLoadedMediaTypes.
+ */
+ private static boolean shouldLoadLazy(String href, Collection lazilyLoadedMediaTypes) {
+ if (CollectionUtil.isEmpty(lazilyLoadedMediaTypes)) {
+ return false;
+ }
+ MediaType mediaType = MediatypeService.determineMediaType(href);
+ return lazilyLoadedMediaTypes.contains(mediaType);
+ }
+
+
+ static Resources loadResources(InputStream in, String defaultHtmlEncoding) throws IOException {
+ return loadResources(new ZipInputStream(in), defaultHtmlEncoding);
+ }
+
+
+ /**
+ * Loads all entries from the ZipInputStream as Resources.
+ *
+ * Loads the contents of all ZipEntries into memory.
+ * Is fast, but may lead to memory problems when reading large books on devices with small amounts of memory.
+ *
+ * @param in
+ * @param defaultHtmlEncoding
+ * @return
+ * @throws IOException
+ */
+ static Resources loadResources(ZipInputStream in, String defaultHtmlEncoding) throws IOException {
+ Resources result = new Resources();
+ for(ZipEntry zipEntry = in.getNextEntry(); zipEntry != null; zipEntry = in.getNextEntry()) {
+ if(zipEntry == null || zipEntry.isDirectory()) {
+ continue;
+ }
+ Resource resource = ResourceUtil.createResource(zipEntry, in);
+ if(resource.getMediaType() == MediatypeService.XHTML) {
+ resource.setInputEncoding(defaultHtmlEncoding);
+ }
+ result.add(resource);
+ }
+ return result;
+ }
+
+
+ /**
+ * Loads all entries from the ZipInputStream as Resources.
+ *
+ * Loads the contents of all ZipEntries into memory.
+ * Is fast, but may lead to memory problems when reading large books on devices with small amounts of memory.
+ *
+ * @param in
+ * @param defaultHtmlEncoding
+ * @return
+ * @throws IOException
+ */
+ static Resources loadResources(ZipFile zipFile, String defaultHtmlEncoding) throws IOException {
+ return loadResources(zipFile, defaultHtmlEncoding, Collections.emptyList());
+ }
+
+}
diff --git a/epublib-core/src/test/java/nl/siegmann/epublib/epub/ResourcesLoaderTest.java b/epublib-core/src/test/java/nl/siegmann/epublib/epub/ResourcesLoaderTest.java
new file mode 100644
index 00000000..4d621b2a
--- /dev/null
+++ b/epublib-core/src/test/java/nl/siegmann/epublib/epub/ResourcesLoaderTest.java
@@ -0,0 +1,178 @@
+package nl.siegmann.epublib.epub;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
+
+import nl.siegmann.epublib.domain.LazyResource;
+import nl.siegmann.epublib.domain.Resource;
+import nl.siegmann.epublib.domain.Resources;
+import nl.siegmann.epublib.service.MediatypeService;
+import nl.siegmann.epublib.util.IOUtil;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class ResourcesLoaderTest {
+
+ private static final String encoding = "UTF-8";
+ private static String testBookFilename;
+
+ @BeforeClass
+ public static void setUpClass() throws IOException {
+ File testbook = File.createTempFile("testbook", ".epub");
+ OutputStream out = new FileOutputStream(testbook);
+ IOUtil.copy(ResourcesLoaderTest.class.getResourceAsStream("/testbook1.epub"), out);
+ out.close();
+
+ ResourcesLoaderTest.testBookFilename = testbook.getAbsolutePath();
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ new File(testBookFilename).delete();
+ }
+
+ /**
+ * Loads the Resource from an InputStream
+ *
+ * @throws FileNotFoundException
+ * @throws IOException
+ */
+ @Test
+ public void testLoadResources_InputStream() throws FileNotFoundException, IOException {
+ // given
+ InputStream inputStream = new FileInputStream(new File(testBookFilename));
+
+ // when
+ Resources resources = ResourcesLoader.loadResources(inputStream, encoding);
+
+ // then
+ verifyResources(resources);
+ }
+
+ /**
+ * Loads the Resources from a ZipInputStream
+ *
+ * @throws FileNotFoundException
+ * @throws IOException
+ */
+ @Test
+ public void testLoadResources_ZipInputStream() throws FileNotFoundException, IOException {
+ // given
+ ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(new File(testBookFilename)));
+
+ // when
+ Resources resources = ResourcesLoader.loadResources(zipInputStream, encoding);
+
+ // then
+ verifyResources(resources);
+ }
+
+ /**
+ * Loads the Resources from a ZipFile
+ *
+ * @throws FileNotFoundException
+ * @throws IOException
+ */
+ @Test
+ public void testLoadResources_ZipFile() throws FileNotFoundException, IOException {
+ // given
+ ZipFile zipFile = new ZipFile(testBookFilename);
+
+ // when
+ Resources resources = ResourcesLoader.loadResources(zipFile, encoding);
+
+ // then
+ verifyResources(resources);
+ }
+
+ /**
+ * Loads all Resources lazily from a ZipFile
+ *
+ * @throws FileNotFoundException
+ * @throws IOException
+ */
+ @Test
+ public void testLoadResources_ZipFile_lazy_all() throws FileNotFoundException, IOException {
+ // given
+ ZipFile zipFile = new ZipFile(testBookFilename);
+
+ // when
+ Resources resources = ResourcesLoader.loadResources(zipFile, encoding, Arrays.asList(MediatypeService.mediatypes));
+
+ // then
+ verifyResources(resources);
+ Assert.assertEquals(Resource.class, resources.getById("container").getClass());
+ Assert.assertEquals(LazyResource.class, resources.getById("book1").getClass());
+ }
+
+ /**
+ * Loads the Resources from a ZipFile, some of them lazily.
+ *
+ * @throws FileNotFoundException
+ * @throws IOException
+ */
+ @Test
+ public void testLoadResources_ZipFile_partial_lazy() throws FileNotFoundException, IOException {
+ // given
+ ZipFile zipFile = new ZipFile(testBookFilename);
+
+ // when
+ Resources resources = ResourcesLoader.loadResources(zipFile, encoding, Arrays.asList(MediatypeService.CSS));
+
+ // then
+ verifyResources(resources);
+ Assert.assertEquals(Resource.class, resources.getById("container").getClass());
+ Assert.assertEquals(LazyResource.class, resources.getById("book1").getClass());
+ Assert.assertEquals(Resource.class, resources.getById("chapter1").getClass());
+ }
+
+ private void verifyResources(Resources resources) throws IOException {
+ Assert.assertNotNull(resources);
+ Assert.assertEquals(12, resources.getAll().size());
+ List allHrefs = new ArrayList(resources.getAllHrefs());
+ Collections.sort(allHrefs);
+
+ Resource resource;
+ byte[] expectedData;
+
+ // container
+ resource = resources.getByHref(allHrefs.get(0));
+ Assert.assertEquals("container", resource.getId());
+ Assert.assertEquals("META-INF/container.xml", resource.getHref());
+ Assert.assertNull(resource.getMediaType());
+ Assert.assertEquals(230, resource.getData().length);
+
+ // book1.css
+ resource = resources.getByHref(allHrefs.get(1));
+ Assert.assertEquals("book1", resource.getId());
+ Assert.assertEquals("OEBPS/book1.css", resource.getHref());
+ Assert.assertEquals(MediatypeService.CSS, resource.getMediaType());
+ Assert.assertEquals(65, resource.getData().length);
+ expectedData = IOUtil.toByteArray(this.getClass().getResourceAsStream("/book1/book1.css"));
+ Assert.assertTrue(Arrays.equals(expectedData, resource.getData()));
+
+
+ // chapter1
+ resource = resources.getByHref(allHrefs.get(2));
+ Assert.assertEquals("chapter1", resource.getId());
+ Assert.assertEquals("OEBPS/chapter1.html", resource.getHref());
+ Assert.assertEquals(MediatypeService.XHTML, resource.getMediaType());
+ Assert.assertEquals(247, resource.getData().length);
+ expectedData = IOUtil.toByteArray(this.getClass().getResourceAsStream("/book1/chapter1.html"));
+ Assert.assertTrue(Arrays.equals(expectedData, resource.getData()));
+ }
+}
diff --git a/epublib-core/src/test/java/nl/siegmann/epublib/util/CollectionUtilTest.java b/epublib-core/src/test/java/nl/siegmann/epublib/util/CollectionUtilTest.java
new file mode 100644
index 00000000..ef9e7c26
--- /dev/null
+++ b/epublib-core/src/test/java/nl/siegmann/epublib/util/CollectionUtilTest.java
@@ -0,0 +1,25 @@
+package nl.siegmann.epublib.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class CollectionUtilTest {
+
+ @Test
+ public void testIsEmpty_null() {
+ Assert.assertTrue(CollectionUtil.isEmpty(null));
+ }
+
+ @Test
+ public void testIsEmpty_empty() {
+ Assert.assertTrue(CollectionUtil.isEmpty(new ArrayList