Add support for adding custom metadata (#8)

* add lombok dependency

* Add methods addMetadata and addMetadataProperty

* Version set to 1.1.0

* Introduce MetadataItem to replace multiple addMetadata methods
This commit is contained in:
Paul Campbell 2020-11-22 09:37:02 +00:00 committed by GitHub
parent 767d24fec3
commit ab551e4500
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 226 additions and 4 deletions

11
pom.xml
View file

@ -11,7 +11,7 @@
<groupId>net.kemitix</groupId>
<artifactId>epub-creator</artifactId>
<version>1.0.2</version>
<version>1.1.0</version>
<scm>
<connection>scm:git:git@github.com:kemitix/epub-creator.git</connection>
@ -51,7 +51,14 @@
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<optional>true</optional>
</dependency>
</dependencies>
<build>

View file

@ -0,0 +1,168 @@
package coza.opencollab.epub.creator.api;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class MetadataItem {
private final String name; //e.g. dc:description
private final String id;// optional
private final String property;// optional
private final String refines;// optional
private final String value;// optional
public String getName() {
return name;
}
public boolean hasId() {
return id != null;
}
public String getId() {
return id;
}
public boolean hasProperty() {
return property != null;
}
public String getProperty() {
return property;
}
public boolean hasRefines() {
return refines != null;
}
public String getRefines() {
return refines;
}
public boolean hasValue() {
return value != null;
}
public String getValue() {
return value;
}
public static Builder builder() {
return new Builder() {
@Override
public Stage1 name(String name) {
return new Stage1() {
@Override
public Stage2 id(String id) {
return new Stage2() {
@Override
public Stage3 property(String property) {
return new Stage3() {
@Override
public Stage4 refines(String refines) {
return new Stage4() {
@Override
public MetadataItem value(String value) {
return new MetadataItem(name, id, property, refines, value);
}
@Override
public MetadataItem build() {
return new MetadataItem(name, id, property, refines, null);
}
};
}
@Override
public MetadataItem value(String value) {
return new MetadataItem(name, id, property, null, value);
}
@Override
public MetadataItem build() {
return new MetadataItem(name, id, property, null, null);
}
};
}
@Override
public MetadataItem value(String value) {
return new MetadataItem(name, id, null, null, value);
}
@Override
public MetadataItem build() {
return new MetadataItem(name, id, null, null, null);
}
};
}
@Override
public Stage3 property(String property) {
return new Stage3() {
@Override
public Stage4 refines(String refines) {
return new Stage4() {
@Override
public MetadataItem value(String value) {
return new MetadataItem(name, null, property, refines, value);
}
@Override
public MetadataItem build() {
return new MetadataItem(name, null, property, refines, null);
}
};
}
@Override
public MetadataItem value(String value) {
return new MetadataItem(name, null, property, null, value);
}
@Override
public MetadataItem build() {
return new MetadataItem(name, null, property, null, null);
}
};
}
@Override
public MetadataItem value(String value) {
return new MetadataItem(name, null, null, null, value);
}
@Override
public MetadataItem build() {
return new MetadataItem(name, null, null, null, null);
}
};
}
};
}
public interface Builder {
Stage1 name(String name);
interface Stage1 {
Stage2 id(String id);
Stage3 property(String property);
MetadataItem value(String value);
MetadataItem build();
}
interface Stage2 {
Stage3 property(String property);
MetadataItem value(String value);
MetadataItem build();
}
interface Stage3 {
Stage4 refines(String refines);
MetadataItem value(String value);
MetadataItem build();
}
interface Stage4 {
MetadataItem value(String value);
MetadataItem build();
}
}
}

View file

@ -30,6 +30,8 @@ import coza.opencollab.epub.creator.model.EpubBook;
*/
public interface OpfCreator {
void addMetadata(MetadataItem metadataItem);
/**
* Creates the OPF file text from the EpubBook data
*

View file

@ -21,11 +21,10 @@
package coza.opencollab.epub.creator.impl;
import coza.opencollab.epub.creator.EpubConstants;
import coza.opencollab.epub.creator.api.MetadataItem;
import coza.opencollab.epub.creator.api.OpfCreator;
import coza.opencollab.epub.creator.model.Content;
import coza.opencollab.epub.creator.model.EpubBook;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.ContentNode;
import org.htmlcleaner.HtmlCleaner;
@ -33,6 +32,11 @@ import org.htmlcleaner.PrettyXmlSerializer;
import org.htmlcleaner.Serializer;
import org.htmlcleaner.TagNode;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Default implementation of the OpfCreator. This follows EPUB3 standards to
* create the OPF file content.
@ -57,6 +61,8 @@ public class OpfCreatorDefault implements OpfCreator {
*/
private final Serializer htmlSetdown;
private final List<MetadataItem> metadataItems = new ArrayList<>();
public OpfCreatorDefault() {
cleaner = new HtmlCleaner();
CleanerProperties htmlProperties = cleaner.getProperties();
@ -66,6 +72,11 @@ public class OpfCreatorDefault implements OpfCreator {
htmlSetdown = new PrettyXmlSerializer(htmlProperties);
}
@Override
public void addMetadata(MetadataItem metadataItem) {
this.metadataItems.add(metadataItem);
}
/**
* {@inheritDoc}
*/
@ -75,9 +86,30 @@ public class OpfCreatorDefault implements OpfCreator {
addMetaDataTags(tagNode, book);
addManifestTags(tagNode, book);
addSpineTags(tagNode, book);
addCustomMetadata(tagNode, book);
return htmlSetdown.getAsString(tagNode);
}
private void addCustomMetadata(TagNode tagNode, EpubBook book) {
TagNode metaNode = tagNode.findElementByName("metadata", true);
metadataItems.forEach(item -> {
TagNode node = new TagNode(item.getName());
if (item.hasId()) {
node.addAttribute("id", item.getId());
}
if (item.hasProperty()) {
node.addAttribute("property", item.getProperty());
}
if (item.hasRefines()) {
node.addAttribute("refines", item.getRefines());
}
if (item.hasValue()) {
node.addChild(new ContentNode(item.getValue()));
}
metaNode.addChild(node);
});
}
/**
* Add the required meta data
*

View file

@ -21,6 +21,7 @@
package coza.opencollab.epub.creator.model;
import coza.opencollab.epub.creator.EpubConstants;
import coza.opencollab.epub.creator.api.MetadataItem;
import coza.opencollab.epub.creator.util.EpubWriter;
import java.io.IOException;
import java.io.InputStream;
@ -426,4 +427,9 @@ public class EpubBook {
return uniqueHrefs;
}
public void addMetadata(MetadataItem metadataItem) {
getEpubCreator().getOpfCreator()
.addMetadata(metadataItem);
}
}

View file

@ -1,5 +1,6 @@
package coza.opencollab.epub.creator;
import coza.opencollab.epub.creator.api.MetadataItem;
import coza.opencollab.epub.creator.model.EpubBook;
import java.io.File;
import java.io.FileOutputStream;
@ -18,6 +19,12 @@ public class EpubCreatorTest {
try (FileOutputStream file = new FileOutputStream(new File("test.epub"))) {
EpubBook book = new EpubBook("en", "Samuel .-__Id1", "Samuel Test Book", "Samuel Holtzkampf");
MetadataItem.Builder builder = MetadataItem.builder();
book.addMetadata(builder.name("dc:creator").value("Bob Smith"));
book.addMetadata(builder.name("meta")
.property("role").refines("#editor-id")
.value("Editor"));
book.addContent(this.getClass().getResourceAsStream("/epub30-overview.xhtml"),
"application/xhtml+xml", "xhtml/epub30-overview.xhtml", true, true).setId("Overview");
book.addContent(this.getClass().getResourceAsStream("/idpflogo_web_125.jpg"),