clean up scripting

This commit is contained in:
Jörg Prante 2022-01-27 10:35:00 +01:00
parent 78925aaf12
commit 366adee432
25 changed files with 72 additions and 62 deletions

View file

@ -4,11 +4,10 @@ import java.util.logging.Level;
import org.xbib.graphics.pdfbox.layout.element.scripting.command.Command; import org.xbib.graphics.pdfbox.layout.element.scripting.command.Command;
import org.xbib.settings.Settings; import org.xbib.settings.Settings;
import java.io.Closeable;
import java.io.IOException; import java.io.IOException;
import java.util.logging.Logger; import java.util.logging.Logger;
public class Engine implements Closeable { public class Engine {
private static final Logger logger = Logger.getLogger(Engine.class.getName()); private static final Logger logger = Logger.getLogger(Engine.class.getName());
@ -19,8 +18,8 @@ public class Engine implements Closeable {
private final State state; private final State state;
public Engine() { public Engine() {
packageName = getClass().getPackageName(); this.packageName = getClass().getPackageName();
classLoader = getClass().getClassLoader(); this.classLoader = getClass().getClassLoader();
this.state = new State(); this.state = new State();
} }
@ -30,12 +29,20 @@ public class Engine implements Closeable {
public void executeElements(Settings settings) throws IOException { public void executeElements(Settings settings) throws IOException {
execute(settings.getAsSettings("elements")); execute(settings.getAsSettings("elements"));
// limit to 1000 elements, abort if no element is present // limit to 1000 elements and abort if no element is present
for (int i = 0; i < 1000; i++) { int i = 0;
for (i = 0; i < 1000; i++) {
if (!executeElement(i, settings)) { if (!executeElement(i, settings)) {
break; break;
} }
} }
if (i == 1000) {
throw new IllegalStateException("limit of 1000 elements reached");
}
}
public State getState() {
return state;
} }
private boolean executeElement(int i, Settings settings) throws IOException { private boolean executeElement(int i, Settings settings) throws IOException {
@ -48,11 +55,11 @@ public class Engine implements Closeable {
} }
private void executeSettings(Settings settings) throws IOException { private void executeSettings(Settings settings) throws IOException {
try {
String type = settings.get("type"); String type = settings.get("type");
if (type == null) { if (type == null) {
return; throw new IllegalArgumentException("missing type in " + settings.getAsMap());
} }
try {
String className = packageName + ".command." + type.substring(0, 1).toUpperCase() + type.substring(1) + "Command"; String className = packageName + ".command." + type.substring(0, 1).toUpperCase() + type.substring(1) + "Command";
Class<?> cl = classLoader.loadClass(className); Class<?> cl = classLoader.loadClass(className);
Command command = (Command) cl.getConstructor().newInstance(); Command command = (Command) cl.getConstructor().newInstance();
@ -65,11 +72,4 @@ public class Engine implements Closeable {
} }
} }
@Override
public void close() throws IOException {
}
public State getState() {
return state;
}
} }

View file

@ -9,18 +9,25 @@ import java.util.stream.Collectors;
public class State { public class State {
public Stack<Element> elements = new Stack<>(); private final Stack<Element> elements = new Stack<>();
public Document getDocument() { public Stack<Element> getElements() {
List<Document> list = getDocuments(); return elements;
int size = list.size();
return size > 0 ? list.get(size - 1) : null;
} }
public List<Document> getDocuments() { /**
return elements.stream() * Get last document.
*
* @return the last document or null if there is no document.
*/
public Document getDocument() {
// there is no stream function to find last element, so we build the stream of documents into a list
// and get the last element from the list
List<Document> list = elements.stream()
.filter(e -> e instanceof Document) .filter(e -> e instanceof Document)
.map(e -> (Document) e) .map(e -> (Document) e)
.collect(Collectors.toList()); .collect(Collectors.toList());
int size = list.size();
return size == 0 ? null : list.get(size - 1);
} }
} }

View file

@ -53,6 +53,6 @@ public class BarcodeCommand implements Command {
float margintop = Float.parseFloat(margins[2]); float margintop = Float.parseFloat(margins[2]);
float marginbottom = Float.parseFloat(margins[3]); float marginbottom = Float.parseFloat(margins[3]);
VerticalLayoutHint verticalLayoutHint = new VerticalLayoutHint(alignment, marginleft, marginright, margintop, marginbottom, true); VerticalLayoutHint verticalLayoutHint = new VerticalLayoutHint(alignment, marginleft, marginright, margintop, marginbottom, true);
state.elements.peek().add(element, verticalLayoutHint); state.getElements().peek().add(element, verticalLayoutHint);
} }
} }

View file

@ -65,7 +65,7 @@ public class CellCommand implements Command {
} }
cell.colSpan(settings.getAsInt("colspan", 1)); cell.colSpan(settings.getAsInt("colspan", 1));
cell.rowSpan(settings.getAsInt("rowspan", 1)); cell.rowSpan(settings.getAsInt("rowspan", 1));
state.elements.peek().add(cell.build()); state.getElements().peek().add(cell.build());
} else if (settings.containsSetting("markup")) { } else if (settings.containsSetting("markup")) {
ParagraphCell.Builder cell = ParagraphCell.builder(); ParagraphCell.Builder cell = ParagraphCell.builder();
cell.colSpan(settings.getAsInt("colspan", 1)); cell.colSpan(settings.getAsInt("colspan", 1));
@ -90,7 +90,7 @@ public class CellCommand implements Command {
if (lineSpacing != null && lineSpacing >= 0f) { if (lineSpacing != null && lineSpacing >= 0f) {
cell.lineSpacing(lineSpacing); cell.lineSpacing(lineSpacing);
} }
state.elements.peek().add(cell.build()); state.getElements().peek().add(cell.build());
} }
} }
} }

View file

@ -50,6 +50,6 @@ public class ChartCommand implements Command {
float margintop = Float.parseFloat(margins[2]); float margintop = Float.parseFloat(margins[2]);
float marginbottom = Float.parseFloat(margins[3]); float marginbottom = Float.parseFloat(margins[3]);
VerticalLayoutHint verticalLayoutHint = new VerticalLayoutHint(alignment, marginleft, marginright, margintop, marginbottom, true); VerticalLayoutHint verticalLayoutHint = new VerticalLayoutHint(alignment, marginleft, marginright, margintop, marginbottom, true);
state.elements.peek().add(element, verticalLayoutHint); state.getElements().peek().add(element, verticalLayoutHint);
} }
} }

View file

@ -14,6 +14,6 @@ public class ColumnlayoutCommand implements Command {
ColumnLayout columnLayout = new ColumnLayout(); ColumnLayout columnLayout = new ColumnLayout();
columnLayout.setColumnCount(settings.getAsInt("columns", 2)); columnLayout.setColumnCount(settings.getAsInt("columns", 2));
columnLayout.setColumnSpacing(settings.getAsFloat("spacing", 10f)); columnLayout.setColumnSpacing(settings.getAsFloat("spacing", 10f));
state.elements.peek().add(columnLayout); state.getElements().peek().add(columnLayout);
} }
} }

View file

@ -7,5 +7,6 @@ import org.xbib.settings.Settings;
import java.io.IOException; import java.io.IOException;
public interface Command { public interface Command {
void execute(Engine engine, State state, Settings settings) throws IOException; void execute(Engine engine, State state, Settings settings) throws IOException;
} }

View file

@ -67,7 +67,7 @@ public class DocumentCommand implements Command {
} else { } else {
document.setModificationDate(instant); document.setModificationDate(instant);
} }
state.elements.push(document); state.getElements().push(document);
engine.executeElements(settings); engine.executeElements(settings);
} }
} }

View file

@ -23,6 +23,6 @@ public class FrameCommand implements Command {
Color borderColor = ColorFactory.web(settings.get("bordercolor", "black")); Color borderColor = ColorFactory.web(settings.get("bordercolor", "black"));
frame.setBorderColor(borderColor); frame.setBorderColor(borderColor);
} }
state.elements.peek().add(frame); state.getElements().peek().add(frame);
} }
} }

View file

@ -32,6 +32,6 @@ public class HorizontalrulerCommand implements Command {
if (settings.containsSetting("width")) { if (settings.containsSetting("width")) {
horizontalRuler.setMaxWidth(mmToPt(settings.getAsFloat("width", -1f))); horizontalRuler.setMaxWidth(mmToPt(settings.getAsFloat("width", -1f)));
} }
state.elements.peek().add(horizontalRuler); state.getElements().peek().add(horizontalRuler);
} }
} }

View file

@ -15,6 +15,7 @@ import java.util.Locale;
import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt; import static org.xbib.graphics.pdfbox.layout.util.PdfUtil.mmToPt;
public class ImageCommand implements Command { public class ImageCommand implements Command {
@Override @Override
public void execute(Engine engine, State state, Settings settings) throws IOException { public void execute(Engine engine, State state, Settings settings) throws IOException {
ImageElement imageElement = new ImageElement(); ImageElement imageElement = new ImageElement();
@ -48,6 +49,6 @@ public class ImageCommand implements Command {
float margintop = Float.parseFloat(margins[2]); float margintop = Float.parseFloat(margins[2]);
float marginbottom = Float.parseFloat(margins[3]); float marginbottom = Float.parseFloat(margins[3]);
VerticalLayoutHint verticalLayoutHint = new VerticalLayoutHint(alignment, marginleft, marginright, margintop, marginbottom, true); VerticalLayoutHint verticalLayoutHint = new VerticalLayoutHint(alignment, marginleft, marginright, margintop, marginbottom, true);
state.elements.peek().add(imageElement, verticalLayoutHint); state.getElements().peek().add(imageElement, verticalLayoutHint);
} }
} }

View file

@ -12,6 +12,6 @@ public class MarkpositionCommand implements Command {
@Override @Override
public void execute(Engine engine, State state, Settings settings) throws IOException { public void execute(Engine engine, State state, Settings settings) throws IOException {
PositionElement.MarkPosition markPosition = PositionElement.createMarkPosition(); PositionElement.MarkPosition markPosition = PositionElement.createMarkPosition();
state.elements.peek().add(markPosition); state.getElements().peek().add(markPosition);
} }
} }

View file

@ -15,6 +15,6 @@ public class MovepositionCommand implements Command {
public void execute(Engine engine, State state, Settings settings) throws IOException { public void execute(Engine engine, State state, Settings settings) throws IOException {
PositionElement.MovePosition movePosition = PositionElement.createMovePosition(mmToPt(settings.getAsFloat("x", 0f)), PositionElement.MovePosition movePosition = PositionElement.createMovePosition(mmToPt(settings.getAsFloat("x", 0f)),
mmToPt(settings.getAsFloat("y", null))); mmToPt(settings.getAsFloat("y", null)));
state.elements.peek().add(movePosition); state.getElements().peek().add(movePosition);
} }
} }

View file

@ -8,9 +8,10 @@ import org.xbib.settings.Settings;
import java.io.IOException; import java.io.IOException;
public class NewcolumnCommand implements Command { public class NewcolumnCommand implements Command {
@Override @Override
public void execute(Engine engine, State state, Settings settings) throws IOException { public void execute(Engine engine, State state, Settings settings) throws IOException {
ControlElement controlElement = ControlElement.NEWCOLUMN; ControlElement controlElement = ControlElement.NEWCOLUMN;
state.elements.peek().add(controlElement); state.getElements().peek().add(controlElement);
} }
} }

View file

@ -8,9 +8,10 @@ import org.xbib.settings.Settings;
import java.io.IOException; import java.io.IOException;
public class NewpageCommand implements Command { public class NewpageCommand implements Command {
@Override @Override
public void execute(Engine engine, State state, Settings settings) throws IOException { public void execute(Engine engine, State state, Settings settings) throws IOException {
ControlElement controlElement = ControlElement.NEWPAGE; ControlElement controlElement = ControlElement.NEWPAGE;
state.elements.peek().add(controlElement); state.getElements().peek().add(controlElement);
} }
} }

View file

@ -33,9 +33,9 @@ public class ParagraphCommand implements Command {
if (settings.containsSetting("rotation")) { if (settings.containsSetting("rotation")) {
paragraph.setRotation(settings.getAsFloat("rotation", 0f)); paragraph.setRotation(settings.getAsFloat("rotation", 0f));
} }
state.elements.push(paragraph); state.getElements().push(paragraph);
engine.executeElements(settings); engine.executeElements(settings);
state.elements.pop(); state.getElements().pop();
Alignment alignment = Alignment.valueOf(settings.get("layout.alignment", "left").toUpperCase(Locale.ROOT)); Alignment alignment = Alignment.valueOf(settings.get("layout.alignment", "left").toUpperCase(Locale.ROOT));
String margin = settings.get("layout.margin", "0 0 0 0"); String margin = settings.get("layout.margin", "0 0 0 0");
String[] margins = margin.split("\\s+"); String[] margins = margin.split("\\s+");
@ -45,6 +45,6 @@ public class ParagraphCommand implements Command {
float marginbottom = Float.parseFloat(margins[3]); float marginbottom = Float.parseFloat(margins[3]);
boolean resetY = settings.getAsBoolean("layout.resety", false); boolean resetY = settings.getAsBoolean("layout.resety", false);
VerticalLayoutHint verticalLayoutHint = new VerticalLayoutHint(alignment, marginleft, marginright, margintop, marginbottom, resetY); VerticalLayoutHint verticalLayoutHint = new VerticalLayoutHint(alignment, marginleft, marginright, margintop, marginbottom, resetY);
state.elements.peek().add(paragraph, verticalLayoutHint); state.getElements().peek().add(paragraph, verticalLayoutHint);
} }
} }

View file

@ -61,6 +61,6 @@ public class PathCommand implements Command {
strokeBuilder.dashPattern(new Stroke.DashPattern(settings.getAsFloat("dash", 1f))); strokeBuilder.dashPattern(new Stroke.DashPattern(settings.getAsFloat("dash", 1f)));
} }
Color color = ColorFactory.web(settings.get("color", "black")); Color color = ColorFactory.web(settings.get("color", "black"));
state.elements.peek().add(new PathElement(path, strokeBuilder.build(), color, position), LayoutHint.NOP); state.getElements().peek().add(new PathElement(path, strokeBuilder.build(), color, position), LayoutHint.NOP);
} }
} }

View file

@ -12,6 +12,6 @@ public class ResetpositionCommand implements Command {
@Override @Override
public void execute(Engine engine, State state, Settings settings) throws IOException { public void execute(Engine engine, State state, Settings settings) throws IOException {
PositionElement.ResetPosition resetPosition = PositionElement.createResetPosition(); PositionElement.ResetPosition resetPosition = PositionElement.createResetPosition();
state.elements.peek().add(resetPosition); state.getElements().peek().add(resetPosition);
} }
} }

View file

@ -52,9 +52,9 @@ public class RowCommand implements Command {
if (settings.containsSetting("verticalalignment")) { if (settings.containsSetting("verticalalignment")) {
row.verticalAlignment(VerticalAlignment.valueOf(settings.get("verticalalignment", "left").toUpperCase(Locale.ROOT))); row.verticalAlignment(VerticalAlignment.valueOf(settings.get("verticalalignment", "left").toUpperCase(Locale.ROOT)));
} }
state.elements.push(row); state.getElements().push(row);
engine.executeElements(settings); engine.executeElements(settings);
state.elements.pop(); state.getElements().pop();
state.elements.peek().add(row); state.getElements().peek().add(row);
} }
} }

View file

@ -13,9 +13,8 @@ public class SetpositionCommand implements Command {
@Override @Override
public void execute(Engine engine, State state, Settings settings) throws IOException { public void execute(Engine engine, State state, Settings settings) throws IOException {
PositionElement.SetPosition setPosition = PositionElement.SetPosition setPosition = PositionElement.createSetPosition(mmToPt(settings.getAsFloat("x", 0f)),
PositionElement.createSetPosition(mmToPt(settings.getAsFloat("x", 0f)),
mmToPt(settings.getAsFloat("y", 0f))); mmToPt(settings.getAsFloat("y", 0f)));
state.elements.peek().add(setPosition); state.getElements().peek().add(setPosition);
} }
} }

View file

@ -34,9 +34,9 @@ public class TableCommand implements Command {
float paddingBottom = Float.parseFloat(paddings[3]); float paddingBottom = Float.parseFloat(paddings[3]);
tableElement.padding(paddingLeft, paddingRight, paddingTop, paddingBottom); tableElement.padding(paddingLeft, paddingRight, paddingTop, paddingBottom);
} }
state.elements.push(tableElement); state.getElements().push(tableElement);
engine.executeElements(settings); engine.executeElements(settings);
state.elements.pop(); state.getElements().pop();
state.elements.peek().add(tableElement); state.getElements().peek().add(tableElement);
} }
} }

View file

@ -25,11 +25,11 @@ public class TextCommand implements Command {
float fontsize = settings.getAsFloat("fontsize", 11.0f); float fontsize = settings.getAsFloat("fontsize", 11.0f);
Document document = state.getDocument(); Document document = state.getDocument();
Font font = Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(document); Font font = Fonts.valueOf(settings.get("font", "helvetica").toUpperCase(Locale.ROOT)).getFont(document);
Element element = state.elements.peek(); Element element = state.getElements().peek();
if (element instanceof Paragraph) { if (element instanceof Paragraph) {
element.add(new TextElement(value, font, fontsize)); element.add(new TextElement(value, font, fontsize));
} else if (element instanceof Document) { } else if (element instanceof Document) {
// wrap text into a paragraph // wrap text into a standard paragraph
Paragraph paragraph = new Paragraph(); Paragraph paragraph = new Paragraph();
if (settings.containsSetting("x") && settings.containsSetting("y")) { if (settings.containsSetting("x") && settings.containsSetting("y")) {
paragraph.setAbsolutePosition(new Position(mmToPt(settings.getAsFloat("x", 0f)), mmToPt(settings.getAsFloat("y", 0f)))); paragraph.setAbsolutePosition(new Position(mmToPt(settings.getAsFloat("x", 0f)), mmToPt(settings.getAsFloat("y", 0f))));

View file

@ -17,11 +17,13 @@ public class TransformCommand implements Command {
element.setScale(settings.getAsFloat("scalex", null), settings.getAsFloat("scaley", null)); element.setScale(settings.getAsFloat("scalex", null), settings.getAsFloat("scaley", null));
} }
if (settings.containsSetting("translatex") && settings.containsSetting("translatey")) { if (settings.containsSetting("translatex") && settings.containsSetting("translatey")) {
element.setTranslate(mmToPt(settings.getAsFloat("translatex", null)), mmToPt(settings.getAsFloat("translatey", null))); element.setTranslate(mmToPt(settings.getAsFloat("translatex", null)),
mmToPt(settings.getAsFloat("translatey", null)));
} }
if (settings.containsSetting("angle") && settings.containsSetting("rotatex") && settings.containsSetting("rotatey")) { if (settings.containsSetting("angle") && settings.containsSetting("rotatex") && settings.containsSetting("rotatey")) {
element.setRotate(settings.getAsFloat("angle", null), mmToPt(settings.getAsFloat("rotatex", null)), mmToPt(settings.getAsFloat("rotatey", null))); element.setRotate(settings.getAsFloat("angle", null), mmToPt(settings.getAsFloat("rotatex", null)),
mmToPt(settings.getAsFloat("rotatey", null)));
} }
state.elements.peek().add(element); state.getElements().peek().add(element);
} }
} }

View file

@ -8,9 +8,10 @@ import org.xbib.settings.Settings;
import java.io.IOException; import java.io.IOException;
public class VerticalspacerCommand implements Command { public class VerticalspacerCommand implements Command {
@Override @Override
public void execute(Engine engine, State state, Settings settings) throws IOException { public void execute(Engine engine, State state, Settings settings) throws IOException {
VerticalSpacer verticalSpacer = new VerticalSpacer(settings.getAsFloat("height", 0f)); VerticalSpacer verticalSpacer = new VerticalSpacer(settings.getAsFloat("height", 0f));
state.elements.peek().add(verticalSpacer); state.getElements().peek().add(verticalSpacer);
} }
} }

View file

@ -16,10 +16,7 @@ public class ScriptingTest {
.build(); .build();
Engine engine = new Engine(); Engine engine = new Engine();
engine.execute(settings); engine.execute(settings);
int i = 0; Document document = engine.getState().getDocument();
for (Document document : engine.getState().getDocuments()) { document.render().save(new FileOutputStream("build/scripting.pdf")).close();
document.render().save(new FileOutputStream("build/scripting" + (i++) + ".pdf")).close();
}
engine.close();
} }
} }