moved json serialisation for freemarker template to individual class
improved GSON handling updated GSON to 2.7
This commit is contained in:
@ -9,7 +9,7 @@ import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
|||||||
*
|
*
|
||||||
* @author jomu
|
* @author jomu
|
||||||
*/
|
*/
|
||||||
abstract class Content {
|
abstract class Content implements TemplateSerializeable {
|
||||||
|
|
||||||
protected PDFDocument document;
|
protected PDFDocument document;
|
||||||
protected PDRectangle rect;
|
protected PDRectangle rect;
|
||||||
@ -47,6 +47,8 @@ abstract class Content {
|
|||||||
|
|
||||||
protected abstract Coordinate addContentToPdf(PDPageContentStream cos) throws IOException, ConfigurationException;
|
protected abstract Coordinate addContentToPdf(PDPageContentStream cos) throws IOException, ConfigurationException;
|
||||||
|
|
||||||
|
public abstract String getTemplateJsonString();
|
||||||
|
|
||||||
/* *** getter / setter *** */
|
/* *** getter / setter *** */
|
||||||
public float getX() {
|
public float getX() {
|
||||||
return x;
|
return x;
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import java.util.List;
|
|||||||
*
|
*
|
||||||
* @author joern.muehlencord
|
* @author joern.muehlencord
|
||||||
*/
|
*/
|
||||||
class DefaultTableRow extends TableRow {
|
class DefaultTableRow extends TableRow implements TemplateSerializeable {
|
||||||
|
|
||||||
@Expose
|
@Expose
|
||||||
private final List<TextElement> row;
|
private final List<TextElement> row;
|
||||||
@ -33,6 +33,33 @@ class DefaultTableRow extends TableRow {
|
|||||||
this.varName = null;
|
this.varName = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTemplateJsonString() {
|
||||||
|
// copy object, null values for listName and isList so they are no longer printed in the template
|
||||||
|
DefaultTableRow newRow = new DefaultTableRow ();
|
||||||
|
newRow.row.addAll(this.row);
|
||||||
|
newRow.padding.addAll(this.padding);
|
||||||
|
newRow.isList = null;
|
||||||
|
newRow.listName = null;
|
||||||
|
newRow.varName = null;
|
||||||
|
|
||||||
|
String returnValue = GsonUtil.getInstance().toJson(newRow);
|
||||||
|
if (isList()) {
|
||||||
|
String listStartString = "<#list ";
|
||||||
|
listStartString += getListName();
|
||||||
|
listStartString += " as ";
|
||||||
|
listStartString += getVarName();
|
||||||
|
listStartString += ">\n";
|
||||||
|
|
||||||
|
String listEndString = "<#if (" + getVarName() + "?has_next)>,</#if>";
|
||||||
|
listEndString += "</#list>\n";
|
||||||
|
|
||||||
|
returnValue = listStartString + returnValue + listEndString;
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addColumn(TextElement element) {
|
protected void addColumn(TextElement element) {
|
||||||
row.add(element);
|
row.add(element);
|
||||||
@ -67,10 +94,11 @@ class DefaultTableRow extends TableRow {
|
|||||||
if (currentPadding == null) {
|
if (currentPadding == null) {
|
||||||
return 0F;
|
return 0F;
|
||||||
} else {
|
} else {
|
||||||
return currentPadding ;
|
return currentPadding;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected String getFontAlias(int columnPos) {
|
protected String getFontAlias(int columnPos) {
|
||||||
return row.get(columnPos).getFontAlias();
|
return row.get(columnPos).getFontAlias();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,25 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
class DefaultTableRowTypeAdapterFactory extends GsonCustomizedTypeAdapterFactory<DefaultTableRow> {
|
||||||
|
|
||||||
|
protected DefaultTableRowTypeAdapterFactory() {
|
||||||
|
super(DefaultTableRow.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JsonElement updateElement(JsonElement toSerialize) {
|
||||||
|
|
||||||
|
JsonObject elem = toSerialize.getAsJsonObject();
|
||||||
|
final JsonObject member = new JsonObject();
|
||||||
|
member.addProperty("type", DefaultTableRow.class.getName());
|
||||||
|
member.add("data", toSerialize.getAsJsonObject());
|
||||||
|
return member;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.TypeAdapter;
|
||||||
|
import com.google.gson.TypeAdapterFactory;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
|
import com.google.gson.stream.JsonWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
abstract class GsonCustomizedTypeAdapterFactory<C> implements TypeAdapterFactory {
|
||||||
|
|
||||||
|
protected final Class<C> customizedClass;
|
||||||
|
|
||||||
|
public GsonCustomizedTypeAdapterFactory(Class<C> customizedClass) {
|
||||||
|
this.customizedClass = customizedClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this to muck with {@code toSerialize} before it is written to
|
||||||
|
* the outgoing JSON stream.
|
||||||
|
*/
|
||||||
|
protected void beforeWrite(C source, JsonElement toSerialize) {
|
||||||
|
// do nothing in default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this to muck with {@code deserialized} before it parsed into the
|
||||||
|
* application type.
|
||||||
|
*/
|
||||||
|
protected void afterRead(JsonElement deserialized) {
|
||||||
|
// do nothing in default implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
protected JsonElement updateElement(JsonElement toSerialize) {
|
||||||
|
// do nothing in default implementation
|
||||||
|
return toSerialize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
|
||||||
|
TypeAdapter<T> returnValue = null;
|
||||||
|
if (customizedClass.isAssignableFrom(type.getRawType())) {
|
||||||
|
returnValue = (TypeAdapter<T>) customizeMyClassAdapter(gson, (TypeToken<C>) type);
|
||||||
|
}
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TypeAdapter<C> customizeMyClassAdapter(Gson gson, TypeToken<C> type) {
|
||||||
|
final TypeAdapter<C> delegate = gson.getDelegateAdapter(this, type);
|
||||||
|
final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
|
||||||
|
return new TypeAdapter<C>() {
|
||||||
|
@Override
|
||||||
|
public void write(JsonWriter out, C value) throws IOException {
|
||||||
|
JsonElement tree = delegate.toJsonTree(value);
|
||||||
|
tree = updateElement(tree);
|
||||||
|
beforeWrite(value, tree);
|
||||||
|
elementAdapter.write(out, tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public C read(JsonReader in) throws IOException {
|
||||||
|
JsonElement tree = elementAdapter.read(in);
|
||||||
|
afterRead(tree);
|
||||||
|
return delegate.fromJsonTree(tree);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,14 +9,22 @@ import com.google.gson.GsonBuilder;
|
|||||||
*/
|
*/
|
||||||
class GsonUtil {
|
class GsonUtil {
|
||||||
|
|
||||||
protected final static Gson getGsonInstance() {
|
private final static Gson INSTANCE = new GsonBuilder()
|
||||||
return new GsonBuilder()
|
|
||||||
.setPrettyPrinting()
|
.setPrettyPrinting()
|
||||||
.excludeFieldsWithoutExposeAnnotation()
|
.excludeFieldsWithoutExposeAnnotation()
|
||||||
.registerTypeAdapter(Content.class, new InterfaceAdapter<>())
|
.registerTypeAdapter(Content.class, new InterfaceAdapter<>())
|
||||||
.registerTypeAdapter(TableRow.class, new InterfaceAdapter<>())
|
.registerTypeAdapter(TableRow.class, new InterfaceAdapter<>())
|
||||||
.registerTypeAdapter(CellValue.class, new InterfaceAdapter<>())
|
.registerTypeAdapter(CellValue.class, new InterfaceAdapter<>())
|
||||||
|
.registerTypeAdapterFactory(new PDFImageContentTypeAdapterFactory())
|
||||||
|
.registerTypeAdapterFactory(new PDFTableContentTypeAdapterFactory())
|
||||||
|
.registerTypeAdapterFactory(new PDFTextContentTypeAdapterFactory())
|
||||||
|
.registerTypeAdapterFactory(new DefaultTableRowTypeAdapterFactory())
|
||||||
|
.registerTypeAdapterFactory(new TextCellValueTypeAdapterFactory())
|
||||||
.create();
|
.create();
|
||||||
|
|
||||||
|
protected final static Gson getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
package de.muehlencord.shared.pdf;
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
import com.google.gson.JsonDeserializationContext;
|
||||||
import java.lang.reflect.Type;
|
|
||||||
import com.google.gson.JsonDeserializer;
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParseException;
|
import com.google.gson.JsonParseException;
|
||||||
@ -19,7 +19,7 @@ class InterfaceAdapter<T> implements JsonSerializer<T>, JsonDeserializer<T> {
|
|||||||
public final JsonElement serialize(final T object, final Type interfaceType, final JsonSerializationContext context) {
|
public final JsonElement serialize(final T object, final Type interfaceType, final JsonSerializationContext context) {
|
||||||
final JsonObject member = new JsonObject();
|
final JsonObject member = new JsonObject();
|
||||||
member.addProperty("type", object.getClass().getName());
|
member.addProperty("type", object.getClass().getName());
|
||||||
member.add("data", context.serialize(object));
|
member.add("data", context.serialize(object, object.getClass()));
|
||||||
return member;
|
return member;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,8 +2,10 @@ package de.muehlencord.shared.pdf;
|
|||||||
|
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||||
@ -37,81 +39,49 @@ public class PDFDocument {
|
|||||||
this.fontMap = null;
|
this.fontMap = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toJson() {
|
public String getTemplateString() {
|
||||||
return GsonUtil.getGsonInstance().toJson(this);
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int indent = 0; // TODO add indent support
|
||||||
|
sb.append("{\n");
|
||||||
|
|
||||||
|
// paper size
|
||||||
|
sb.append("\"paperSize\": ");
|
||||||
|
sb.append(paperSize.getTemplateJsonString());
|
||||||
|
sb.append(",\n");
|
||||||
|
|
||||||
|
// standardFOnt
|
||||||
|
sb.append ("\"standardFont\": ");
|
||||||
|
sb.append (standardFont.getTemplateJsonString());
|
||||||
|
sb.append (",\n");
|
||||||
|
|
||||||
|
|
||||||
|
sb.append("\"fontMap\": {\n");
|
||||||
|
Iterator<Map.Entry<String, PDFFont>> it = fontMap.entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Entry<String, PDFFont> entry = it.next();
|
||||||
|
sb.append("\"").append(entry.getKey()).append("\": ");
|
||||||
|
sb.append (entry.getValue().getTemplateJsonString());
|
||||||
|
if (it.hasNext()) {
|
||||||
|
sb.append(",");
|
||||||
}
|
}
|
||||||
|
sb.append("\n");
|
||||||
public String fromJson() {
|
|
||||||
return GsonUtil.getGsonInstance().toJson(this);
|
|
||||||
}
|
}
|
||||||
|
sb.append ("},\n"); // fontMap
|
||||||
|
|
||||||
public String getTemplateString() throws TemplateException {
|
sb.append ("\"contentList\": [\n");
|
||||||
|
Iterator<Content> contentIterator = contentList.iterator();
|
||||||
ConcurrentLinkedDeque<Integer> bracketStack = new ConcurrentLinkedDeque<>();
|
while (contentIterator.hasNext()) {
|
||||||
int currentPosInTemplate = 0;
|
Content content = contentIterator.next();
|
||||||
int currentStartOfSubelement = 0;
|
String contentString = content.getTemplateJsonString();
|
||||||
String templateString = GsonUtil.getGsonInstance().toJson(this);
|
sb.append (contentString);
|
||||||
String typeSearchString = " \"type\": \"de.muehlencord.shared.pdf.DefaultTableRow\"";
|
if (contentIterator.hasNext())
|
||||||
while (templateString.indexOf(typeSearchString, currentPosInTemplate) > 0) {
|
sb.append (",");
|
||||||
// get next element
|
sb.append ("\n");
|
||||||
currentPosInTemplate = templateString.indexOf(typeSearchString, currentPosInTemplate);
|
|
||||||
int posOpenBracket = templateString.substring(currentStartOfSubelement, currentPosInTemplate).lastIndexOf("{") + currentStartOfSubelement;
|
|
||||||
int posCloseBracket;
|
|
||||||
// store position of 1st open bracket
|
|
||||||
bracketStack.push(posOpenBracket);
|
|
||||||
|
|
||||||
// work until closing bracket for this element
|
|
||||||
while ((!bracketStack.isEmpty()) && (currentPosInTemplate < templateString.length())) {
|
|
||||||
currentPosInTemplate += 1;
|
|
||||||
char currentChar = templateString.charAt(currentPosInTemplate);
|
|
||||||
if (currentChar == '{') {
|
|
||||||
// new open bracket found
|
|
||||||
posOpenBracket = currentPosInTemplate;
|
|
||||||
bracketStack.push(posOpenBracket);
|
|
||||||
} else if (currentChar == '}') {
|
|
||||||
if (bracketStack.isEmpty()) {
|
|
||||||
throw new TemplateException("Found closing bracket, but missing open bracket");
|
|
||||||
}
|
}
|
||||||
// new open bracket found
|
sb.append ("]\n");
|
||||||
posCloseBracket = currentPosInTemplate;
|
|
||||||
posOpenBracket = bracketStack.pop();
|
|
||||||
if (bracketStack.isEmpty()) {
|
|
||||||
// next element starts behing the closing bracket earliests
|
|
||||||
currentStartOfSubelement = posCloseBracket + 1;
|
|
||||||
|
|
||||||
String jsonSubString = templateString.substring(posOpenBracket, posCloseBracket + 1);
|
sb.append("}"); // closing pdfDocument
|
||||||
|
return sb.toString();
|
||||||
// insert the list values into the gson string
|
|
||||||
TableRow element = GsonUtil.getGsonInstance().fromJson(jsonSubString, TableRow.class);
|
|
||||||
if (element.isList()) {
|
|
||||||
String listStartString = "<#list ";
|
|
||||||
listStartString += element.getListName();
|
|
||||||
listStartString += " as ";
|
|
||||||
listStartString += element.getVarName();
|
|
||||||
listStartString += ">\n";
|
|
||||||
|
|
||||||
String listEndString = "<#if ("+element.getVarName()+"?has_next)>,</#if>";
|
|
||||||
listEndString += "</#list>\n";
|
|
||||||
|
|
||||||
String newString = templateString.substring(0, posOpenBracket);
|
|
||||||
newString += listStartString;
|
|
||||||
newString += templateString.substring(posOpenBracket, posCloseBracket+1);
|
|
||||||
newString += listEndString;
|
|
||||||
newString += templateString.substring(posCloseBracket+1, templateString.length());
|
|
||||||
|
|
||||||
templateString = newString;
|
|
||||||
currentPosInTemplate += listStartString.length();
|
|
||||||
currentPosInTemplate += listEndString.length();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!bracketStack.isEmpty()) {
|
|
||||||
throw new TemplateException("Exception - stack not empty but end of string reached");
|
|
||||||
}
|
|
||||||
} // for all types
|
|
||||||
|
|
||||||
return templateString;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addFont(String name, PDFFont font) {
|
public void addFont(String name, PDFFont font) {
|
||||||
@ -169,5 +139,4 @@ public class PDFDocument {
|
|||||||
this.pdDocument = pdDocument;
|
this.pdDocument = pdDocument;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import com.google.gson.annotations.Expose;
|
|||||||
*
|
*
|
||||||
* @author jomu
|
* @author jomu
|
||||||
*/
|
*/
|
||||||
public class PDFFont {
|
public class PDFFont implements TemplateSerializeable {
|
||||||
|
|
||||||
@Expose
|
@Expose
|
||||||
private String fontName;
|
private String fontName;
|
||||||
@ -27,6 +27,13 @@ public class PDFFont {
|
|||||||
this.padding = padding;
|
this.padding = padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTemplateJsonString() {
|
||||||
|
return GsonUtil.getInstance().toJson (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* *** getter / setter *** */
|
/* *** getter / setter *** */
|
||||||
|
|
||||||
public String getFontName() {
|
public String getFontName() {
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
|
|||||||
*
|
*
|
||||||
* @author joern.muehlencord
|
* @author joern.muehlencord
|
||||||
*/
|
*/
|
||||||
public class PDFImageContent extends Content {
|
public class PDFImageContent extends Content implements TemplateSerializeable {
|
||||||
|
|
||||||
@Expose
|
@Expose
|
||||||
private Float scale = null;
|
private Float scale = null;
|
||||||
@ -70,6 +70,17 @@ public class PDFImageContent extends Content {
|
|||||||
this.base64CodedImage = ImageUtil.getEncodedString(img);
|
this.base64CodedImage = ImageUtil.getEncodedString(img);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* defaut toJson implementation uses standard JSON string
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getTemplateJsonString() {
|
||||||
|
String returnValue = GsonUtil.getInstance().toJson(this);
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Coordinate addContentToPdf(PDPageContentStream cos) throws IOException, ConfigurationException {
|
protected Coordinate addContentToPdf(PDPageContentStream cos) throws IOException, ConfigurationException {
|
||||||
BufferedImage image = ImageUtil.getImageFromEncodedString(base64CodedImage);
|
BufferedImage image = ImageUtil.getImageFromEncodedString(base64CodedImage);
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
class PDFImageContentTypeAdapterFactory extends GsonCustomizedTypeAdapterFactory<PDFImageContent> {
|
||||||
|
|
||||||
|
protected PDFImageContentTypeAdapterFactory() {
|
||||||
|
super(PDFImageContent.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JsonElement updateElement(JsonElement toSerialize) {
|
||||||
|
final JsonObject member = new JsonObject();
|
||||||
|
member.addProperty("type", PDFImageContent.class.getName());
|
||||||
|
member.add("data", toSerialize.getAsJsonObject());
|
||||||
|
return member;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,15 +1,10 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package de.muehlencord.shared.pdf;
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author jomu
|
* @author jomu
|
||||||
*/
|
*/
|
||||||
public enum PDFPaperSize {
|
public enum PDFPaperSize implements TemplateSerializeable {
|
||||||
|
|
||||||
A4("A4");
|
A4("A4");
|
||||||
|
|
||||||
@ -23,4 +18,11 @@ public enum PDFPaperSize {
|
|||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTemplateJsonString() {
|
||||||
|
return GsonUtil.getInstance().toJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
package de.muehlencord.shared.pdf;
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||||
@ -37,6 +39,38 @@ public class PDFTableContent extends Content {
|
|||||||
this.data = new ArrayList<>();
|
this.data = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* defaut toJson implementation uses standard JSON string
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getTemplateJsonString() {
|
||||||
|
Gson gson = GsonUtil.getInstance();
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append ("{\n");
|
||||||
|
sb.append ("\"type\": ");
|
||||||
|
sb.append ("\"").append(this.getClass().getName()).append ("\",\n");
|
||||||
|
sb.append ("\"data\": {");
|
||||||
|
sb.append ("\"columSizes\": ");
|
||||||
|
sb.append (gson.toJson(columSizes));
|
||||||
|
sb.append (",\"data\": [");
|
||||||
|
Iterator<TableRow> it = data.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
TableRow row = it.next();
|
||||||
|
sb.append (row.getTemplateJsonString());
|
||||||
|
if (it.hasNext()) {
|
||||||
|
sb.append (",\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append ("]\n"); // data array
|
||||||
|
sb.append ("}\n"); // data list
|
||||||
|
sb.append ("}\n"); // pdf table object
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
// return GsonUtil.getInstance().toJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
public PDFTableContent addColumn(float size) {
|
public PDFTableContent addColumn(float size) {
|
||||||
// TODO check if enough columns are defined
|
// TODO check if enough columns are defined
|
||||||
this.columSizes.add(new ColumnDefinition(size));
|
this.columSizes.add(new ColumnDefinition(size));
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
class PDFTableContentTypeAdapterFactory extends GsonCustomizedTypeAdapterFactory<PDFTableContent> {
|
||||||
|
|
||||||
|
protected PDFTableContentTypeAdapterFactory() {
|
||||||
|
super(PDFTableContent.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JsonElement updateElement(JsonElement toSerialize) {
|
||||||
|
final JsonObject member = new JsonObject();
|
||||||
|
member.addProperty("type", PDFTableContent.class.getName());
|
||||||
|
member.add("data", toSerialize.getAsJsonObject());
|
||||||
|
return member;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -47,7 +47,7 @@ public class PDFTemplate {
|
|||||||
String json = out.toString();
|
String json = out.toString();
|
||||||
LOGGER.debug(json);
|
LOGGER.debug(json);
|
||||||
|
|
||||||
Gson gson = GsonUtil.getGsonInstance();
|
Gson gson = GsonUtil.getInstance();
|
||||||
PDFDocument pdfDoc = gson.fromJson(json, PDFDocument.class);
|
PDFDocument pdfDoc = gson.fromJson(json, PDFDocument.class);
|
||||||
pdfDoc.setPdDocument(new PDDocument());
|
pdfDoc.setPdDocument(new PDDocument());
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ public class PDFTemplate {
|
|||||||
}
|
}
|
||||||
pdfDoc.getPdDocument().addPage(page);
|
pdfDoc.getPdDocument().addPage(page);
|
||||||
|
|
||||||
PDPageContentStream cos = new PDPageContentStream(pdfDoc.getPdDocument(), page, AppendMode.APPEND, false);
|
try (PDPageContentStream cos = new PDPageContentStream(pdfDoc.getPdDocument(), page, AppendMode.APPEND, false)) {
|
||||||
Coordinate coord = new Coordinate(page.getMediaBox().getLowerLeftX(), page.getMediaBox().getUpperRightY());
|
Coordinate coord = new Coordinate(page.getMediaBox().getLowerLeftX(), page.getMediaBox().getUpperRightY());
|
||||||
for (Content content : pdfDoc.getContentList()) {
|
for (Content content : pdfDoc.getContentList()) {
|
||||||
content.setDocument(pdfDoc); // FIXME move to serialization
|
content.setDocument(pdfDoc); // FIXME move to serialization
|
||||||
@ -69,12 +69,7 @@ public class PDFTemplate {
|
|||||||
content.setCoordinate(coord);
|
content.setCoordinate(coord);
|
||||||
coord = content.addContentToPdf(cos);
|
coord = content.addContentToPdf(cos);
|
||||||
}
|
}
|
||||||
cos.close();
|
}
|
||||||
pdfDoc.getPdDocument().save(filenName);
|
pdfDoc.getPdDocument().save(filenName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void applyTemplate(Template template) {
|
|
||||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,6 +32,17 @@ public class PDFTextContent extends Content {
|
|||||||
this.textLines.add(new TextElement(text));
|
this.textLines.add(new TextElement(text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* defaut toJson implementation uses standard JSON string
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getTemplateJsonString() {
|
||||||
|
String returnValue = GsonUtil.getInstance().toJson(this);
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
public PDFTextContent addLine() {
|
public PDFTextContent addLine() {
|
||||||
this.textLines.add(new TextElement());
|
this.textLines.add(new TextElement());
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
class PDFTextContentTypeAdapterFactory extends GsonCustomizedTypeAdapterFactory<PDFTextContent> {
|
||||||
|
|
||||||
|
protected PDFTextContentTypeAdapterFactory() {
|
||||||
|
super(PDFTextContent.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JsonElement updateElement(JsonElement toSerialize) {
|
||||||
|
final JsonObject member = new JsonObject();
|
||||||
|
member.addProperty("type", PDFTextContent.class.getName());
|
||||||
|
member.add("data", toSerialize.getAsJsonObject());
|
||||||
|
return member;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,7 +4,7 @@ package de.muehlencord.shared.pdf;
|
|||||||
*
|
*
|
||||||
* @author joern.muehlencord
|
* @author joern.muehlencord
|
||||||
*/
|
*/
|
||||||
abstract class TableRow {
|
abstract class TableRow implements TemplateSerializeable {
|
||||||
|
|
||||||
protected abstract TableRow createList(String listName, String varName);
|
protected abstract TableRow createList(String listName, String varName);
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,11 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
interface TemplateSerializeable {
|
||||||
|
|
||||||
|
String getTemplateJsonString();
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
class TextCellValueTypeAdapterFactory extends GsonCustomizedTypeAdapterFactory<TextCellValue> {
|
||||||
|
|
||||||
|
protected TextCellValueTypeAdapterFactory() {
|
||||||
|
super(TextCellValue.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JsonElement updateElement(JsonElement toSerialize) {
|
||||||
|
final JsonObject member = new JsonObject();
|
||||||
|
member.addProperty("type", TextCellValue.class.getName());
|
||||||
|
member.add("data", toSerialize.getAsJsonObject());
|
||||||
|
return member;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -27,7 +27,7 @@ public class DefaultTableRowTest {
|
|||||||
" }";
|
" }";
|
||||||
|
|
||||||
|
|
||||||
TableRow tableRow = GsonUtil.getGsonInstance().fromJson(jsonString, TableRow.class);
|
TableRow tableRow = GsonUtil.getInstance().fromJson(jsonString, TableRow.class);
|
||||||
assertNotNull ("tableRowObject", tableRow);
|
assertNotNull ("tableRowObject", tableRow);
|
||||||
assertEquals ("column count", 2, tableRow.getColumnCount());
|
assertEquals ("column count", 2, tableRow.getColumnCount());
|
||||||
assertFalse ("isList", tableRow.isList());
|
assertFalse ("isList", tableRow.isList());
|
||||||
|
|||||||
24
pdf/src/test/java/de/muehlencord/shared/pdf/PDFFontTest.java
Normal file
24
pdf/src/test/java/de/muehlencord/shared/pdf/PDFFontTest.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
public class PDFFontTest {
|
||||||
|
|
||||||
|
public PDFFontTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTemplateSerialisation() {
|
||||||
|
PDFFont font = new PDFFont("Test", 12, 0);
|
||||||
|
String gsonString = GsonUtil.getInstance().toJson(font);
|
||||||
|
String templateString = font.getTemplateJsonString();
|
||||||
|
System.out.println(templateString);
|
||||||
|
assertEquals(gsonString, templateString);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
public class PDFImageContentTest {
|
||||||
|
|
||||||
|
public PDFImageContentTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testImage() throws IOException {
|
||||||
|
|
||||||
|
PDFDocument doc = new PDFDocument(PDFPaperSize.A4);
|
||||||
|
PDFImageContent logoContent = new PDFImageContent(doc, 400F, 700F, 0.6F, new File("c:/temp/logo-verkehrsverein-hoevelh.jpg"));
|
||||||
|
|
||||||
|
System.out.println(GsonUtil.getInstance().toJson(logoContent));
|
||||||
|
System.out.println(GsonUtil.getInstance().toJson(logoContent));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
public class PDFTextContentTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSomeMethod() {
|
||||||
|
PDFDocument doc = new PDFDocument(PDFPaperSize.A4);
|
||||||
|
PDFTextContent informationContent = new PDFTextContent(doc, 400F, 662F);
|
||||||
|
informationContent.addLine("Anzeigenabrechnung", "bold");
|
||||||
|
informationContent.addLine("Veronika Mühlencord", "helv12");
|
||||||
|
informationContent.addLine("Telefon: 05257/940154", "helv12");
|
||||||
|
informationContent.addLine("Telefax: 05257/940156", "helv12");
|
||||||
|
informationContent.addLine();
|
||||||
|
informationContent.addLine("Hövelhof, den ${invoice.invoiceDate?date}", "bold");
|
||||||
|
doc.addContent(informationContent);
|
||||||
|
|
||||||
|
// System.out.println (informationContent.getTemplateJsonString());
|
||||||
|
// System.out.println ("*****");
|
||||||
|
// System.out.println (GsonUtil.getGsonInstance().toJson(informationContent));
|
||||||
|
System.out.println("*****");
|
||||||
|
|
||||||
|
Gson gson = new GsonBuilder()
|
||||||
|
.registerTypeAdapterFactory(new PDFImageContentTypeAdapterFactory())
|
||||||
|
.setPrettyPrinting()
|
||||||
|
.excludeFieldsWithoutExposeAnnotation()
|
||||||
|
.create();
|
||||||
|
|
||||||
|
System.out.println(gson.toJson(informationContent, PDFTextContent.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -18,7 +18,7 @@ public class TextTest {
|
|||||||
+ "\"text\": \"Rechnungs-Nr.:\"\n"
|
+ "\"text\": \"Rechnungs-Nr.:\"\n"
|
||||||
+ "}";
|
+ "}";
|
||||||
|
|
||||||
TextElement text = GsonUtil.getGsonInstance().fromJson(jsonString, TextElement.class);
|
TextElement text = GsonUtil.getInstance().fromJson(jsonString, TextElement.class);
|
||||||
assertNotNull ("text object", text);
|
assertNotNull ("text object", text);
|
||||||
assertEquals ("text value", "Rechnungs-Nr.:", text.getText());
|
assertEquals ("text value", "Rechnungs-Nr.:", text.getText());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user