Skip to content

Commit

Permalink
closes #392
Browse files Browse the repository at this point in the history
  • Loading branch information
jstaerk committed Jun 27, 2024
1 parent cbd8f71 commit 53391ea
Show file tree
Hide file tree
Showing 8 changed files with 262 additions and 217 deletions.
2 changes: 2 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
- jakarta support #372
- Upgrade to PDFBox 3 #373
- #397
- #392 CLI: action combine: --ignorefileextension to ignore PDF/A input file errors dosen't work
- for CLI combine, fx is now default

2.11.0
=======
Expand Down
163 changes: 77 additions & 86 deletions Mustang-CLI/src/main/java/org/mustangproject/commandline/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,64 +36,65 @@

public class Main {
private static org.slf4j.Logger LOGGER; // log output

private static void printUsage() {
System.err.println(getUsage());
}

private static String getUsage() {
return "Usage: --action metrics|combine|extract|a3only|ubl|validate|validateExpectInvalid|validateExpectValid|visualize [-d,--directory] [-l,--listfromstdin] [-i,--ignore fileextension, PDF/A errors] [--disable-file-logging] | [-h,--help] \r\n"
+ " --action license display open source license and notice\n"
+ " --action metrics\n"
+ " -d, --directory count ZUGFeRD files in directory to be scanned\n"
+ " If it is a directory, it will recurse.\n"
+ " -l, --listfromstdin count ZUGFeRD files from a list of linefeed separated files on runtime.\n"
+ " It will start once a blank line has been entered.\n" + "\n"
+ " Additional parameter for both count operations\n"
+ " [-i, --ignorefileextension] Check for all files (*.*) instead of PDF files only (*.pdf) in metrics, ignore PDF/A input file errors in combine\n"
+ " [--disable-file-logging] disable logging to file.\n"
+ " --action extract extract Factur-X PDF to XML file\n"
+ " Additional parameters (optional - user will be prompted if not defined)\n"
+ " [--source <filename>]: set input PDF file\n"
+ " [--out <filename>]: set output XML file\n"
+ " --action a3only upgrade from PDF/A1 to A3 only (no ZUGFeRD data attached)\n"
+ " Additional parameters (optional - user will be prompted if not defined)\n"
+ " [--source <filename>]: set input PDF file\n"
+ " [--out <filename>]: set output PDF file\n"
+ " --action combine combine XML and PDF file to Factur-X PDF file\n"
+ " Additional parameters (optional - user will be prompted if not defined)\n"
+ " [--source <filename>]: set input PDF file\n"
+ " [--source-xml <filename>]: set input XML file\n"
+ " [--out <filename>]: set output PDF file\n"
+ " [--format <fx|zf|ox|da>]: set Factur-X, ZUGFeRD, Order-X or Cross Industry Despatch Advice\n"
+ " [--version <1|2>]: set ZUGFeRD version\n"
+ " [--profile <...>]: set ZUGFeRD profile\n"
+ " For ZUGFeRD v1 or Order-X: <B>ASIC, <C>OMFORT or EX<T>ENDED\n"
+ " For ZUGFeRD v2: <M>INIMUM, BASIC <W>L, <B>ASIC, <C>IUS, <E>N16931, <X>Rechnung, EX<T>ENDED\n"
+ " [--attachments <filenames>]: list of file attachments (passing a single empty file name prevents prompting)\n"
+ " --action ubl convert UN/CEFACT 2016b CII XML to UBL XML\n"
+ " [--source <filename>]: set input XML file\n"
+ " [--out <filename>]: set output XML file\n"
+ " --action upgrade upgrade ZUGFeRD XML to ZUGFeRD 2 XML\n"
+ " Additional parameters (optional - user will be prompted if not defined)\n"
+ " [--source <filename>]: set input XML ZUGFeRD 1 file\n"
+ " [--out <filename>]: set output XML ZUGFeRD 2 file\n"
+ " --action validate validate XML or PDF file \n"
+ " [--no-notices]: refrain from reporting notices\n"
+ " [--logAppend <text>]: text to be added to log line\n"
+ " Additional parameters (optional - user will be prompted if not defined)\n"
+ " [--source <filename>]: input PDF or XML file\n"
+ " --action validateExpectInvalid validate directory expecting negative results \n"
+ " [--no-notices]: refrain from reporting notices\n"
+ " Additional parameters (optional - user will be prompted if not defined)\n"
+ " -d, --directory to check recursively\n"
+ " --action validateExpectValid validate directory expecting positive results \n"
+ " [--no-notices]: refrain from reporting notices\n"
+ " Additional parameters (optional - user will be prompted if not defined)\n"
+ " -d, --directory to check recursively \n"
+ " --action visualize convert XML to HTML \n"
+ " [--language <lang>]: set output lang (en, fr or de)\n"
+ " [--source <filename>]: set input XML file\n"
+ " [--out <filename>]: set output HTML file\n"
+ " --action license display open source license and notice\n"
+ " --action metrics\n"
+ " -d, --directory count ZUGFeRD files in directory to be scanned\n"
+ " If it is a directory, it will recurse.\n"
+ " -l, --listfromstdin count ZUGFeRD files from a list of linefeed separated files on runtime.\n"
+ " It will start once a blank line has been entered.\n" + "\n"
+ " Additional parameter for both count operations\n"
+ " [-i, --ignorefileextension] Check for all files (*.*) instead of PDF files only (*.pdf) in metrics, ignore PDF/A input file errors in combine\n"
+ " [--disable-file-logging] disable logging to file.\n"
+ " --action extract extract Factur-X PDF to XML file\n"
+ " Additional parameters (optional - user will be prompted if not defined)\n"
+ " [--source <filename>]: set input PDF file\n"
+ " [--out <filename>]: set output XML file\n"
+ " --action a3only upgrade from PDF/A1 to A3 only (no ZUGFeRD data attached)\n"
+ " Additional parameters (optional - user will be prompted if not defined)\n"
+ " [--source <filename>]: set input PDF file\n"
+ " [--out <filename>]: set output PDF file\n"
+ " --action combine combine XML and PDF file to Factur-X PDF file\n"
+ " Additional parameters (optional - user will be prompted if not defined)\n"
+ " [--source <filename>]: set input PDF file\n"
+ " [--source-xml <filename>]: set input XML file\n"
+ " [--out <filename>]: set output PDF file\n"
+ " [--format <fx|zf|ox|da>]: set Factur-X, ZUGFeRD, Order-X or Cross Industry Despatch Advice\n"
+ " [--version <1|2>]: set ZUGFeRD version\n"
+ " [--profile <...>]: set ZUGFeRD profile\n"
+ " For ZUGFeRD v1 or Order-X: <B>ASIC, <C>OMFORT or EX<T>ENDED\n"
+ " For ZUGFeRD v2: <M>INIMUM, BASIC <W>L, <B>ASIC, <C>IUS, <E>N16931, <X>Rechnung, EX<T>ENDED\n"
+ " [--attachments <filenames>]: list of file attachments (passing a single empty file name prevents prompting)\n"
+ " --action ubl convert UN/CEFACT 2016b CII XML to UBL XML\n"
+ " [--source <filename>]: set input XML file\n"
+ " [--out <filename>]: set output XML file\n"
+ " --action upgrade upgrade ZUGFeRD XML to ZUGFeRD 2 XML\n"
+ " Additional parameters (optional - user will be prompted if not defined)\n"
+ " [--source <filename>]: set input XML ZUGFeRD 1 file\n"
+ " [--out <filename>]: set output XML ZUGFeRD 2 file\n"
+ " --action validate validate XML or PDF file \n"
+ " [--no-notices]: refrain from reporting notices\n"
+ " [--logAppend <text>]: text to be added to log line\n"
+ " Additional parameters (optional - user will be prompted if not defined)\n"
+ " [--source <filename>]: input PDF or XML file\n"
+ " --action validateExpectInvalid validate directory expecting negative results \n"
+ " [--no-notices]: refrain from reporting notices\n"
+ " Additional parameters (optional - user will be prompted if not defined)\n"
+ " -d, --directory to check recursively\n"
+ " --action validateExpectValid validate directory expecting positive results \n"
+ " [--no-notices]: refrain from reporting notices\n"
+ " Additional parameters (optional - user will be prompted if not defined)\n"
+ " -d, --directory to check recursively \n"
+ " --action visualize convert XML to HTML \n"
+ " [--language <lang>]: set output lang (en, fr or de)\n"
+ " [--source <filename>]: set input XML file\n"
+ " [--out <filename>]: set output HTML file\n"
+ " --action pdf convert XML to PDF \n"
+ " [--source <filename>]: set input XML file\n"
+ " [--out <filename>]: set output PDF file\n"
Expand Down Expand Up @@ -344,18 +345,18 @@ public static void main(String[] args) {
attachmentOpt.setArgs(Option.UNLIMITED_VALUES);

options.addOption(attachmentOpt);
options.addOption(new Option("source", "source",true, "which source file to use"));
options.addOption(new Option("source-xml", "source-xml",true, "which source file to use"));
options.addOption(new Option("language", "language",true, "output language (en, de or fr)"));
options.addOption(new Option("out", "out",true, "which output file to write to"));
options.addOption(new Option("no-notices", "no-notices",false, "suppress non-fatal errors"));
options.addOption(new Option("logAppend", "logAppend",true, "freeform text to be appended to log messages"));
options.addOption(new Option("source", "source", true, "which source file to use"));
options.addOption(new Option("source-xml", "source-xml", true, "which source file to use"));
options.addOption(new Option("language", "language", true, "output language (en, de or fr)"));
options.addOption(new Option("out", "out", true, "which output file to write to"));
options.addOption(new Option("no-notices", "no-notices", false, "suppress non-fatal errors"));
options.addOption(new Option("logAppend", "logAppend", true, "freeform text to be appended to log messages"));
options.addOption(new Option("disable-file-logging", "disable-file-logging", false, "suppress logging to file"));
options.addOption(new Option("d", "directory",true, "which directory to operate on"));
options.addOption(new Option("i", "ignorefileextension",false, "ignore non-matching file extensions"));
options.addOption(new Option("l", "listfromstdin",false, "take list of files from commandline"));
options.addOption(new Option("d", "directory", true, "which directory to operate on"));
options.addOption(new Option("i", "ignorefileextension", false, "ignore non-matching file extensions"));
options.addOption(new Option("l", "listfromstdin", false, "take list of files from commandline"));

boolean optionsRecognized=false;
boolean optionsRecognized = false;
String action = "";

Boolean disableFileLogging = false;
Expand All @@ -367,7 +368,7 @@ public static void main(String[] args) {
String directoryName = cmd.getOptionValue("directory");
Boolean filesFromStdIn = cmd.hasOption("listfromstdin");//((Number)cmdLine.getParsedOptionValue("integer-option")).intValue();
Boolean ignoreFileExt = cmd.hasOption("ignorefileextension");
Boolean helpRequested = cmd.hasOption("help") || ((action!=null)&&(action.equals("help")));
Boolean helpRequested = cmd.hasOption("help") || ((action != null) && (action.equals("help")));
disableFileLogging = cmd.hasOption("disable-file-logging");

String sourceName = cmd.getOptionValue("source");
Expand All @@ -383,14 +384,12 @@ public static void main(String[] args) {
String[] attachmentFilenames = cmd.hasOption("attachments") ? cmd.getOptionValues("attachments") : null;




ArrayList<FileAttachment> attachments=new ArrayList <>();
ArrayList<FileAttachment> attachments = new ArrayList<>();
/*
setting system property to disable FILE appender and
suppress creation of files and folders.
*/
System.setProperty("FILE_APPENDER_ENABLED", ((Boolean)(disableFileLogging==false)).toString());
System.setProperty("FILE_APPENDER_ENABLED", ((Boolean) (disableFileLogging == false)).toString());

LOGGER = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);

Expand Down Expand Up @@ -600,7 +599,7 @@ private static void performCombine(String pdfName, String xmlName, String outNam

if (format == null) {
try {
format = getStringFromUser("Format (fx=Factur-X, zf=ZUGFeRD, ox=Order-X, da=Cross Industry Despatch Advice)", "zf", "fx|zf|ox|da");
format = getStringFromUser("Format (fx=Factur-X, zf=ZUGFeRD, ox=Order-X, da=Cross Industry Despatch Advice)", "fx", "fx|zf|ox|da");
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
Expand All @@ -610,7 +609,7 @@ private static void performCombine(String pdfName, String xmlName, String outNam

if (zfVersion == null) {
try {
zfVersion = getStringFromUser("Version (1 or 2)", Integer.toString(ZUGFeRDExporterFromA3.DefaultZUGFeRDVersion), "1|2");
zfVersion = getStringFromUser("Version (1 or 2)", "1", "1|2");//fx default version is 1
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
Expand Down Expand Up @@ -694,41 +693,33 @@ private static void performCombine(String pdfName, String xmlName, String outNam
IZUGFeRDExporter ze = null;
// All params are good! continue...
if (format.equals("ox")) {
ze = new OXExporterFromA1().setProducer("Mustang-cli")
.setZUGFeRDVersion(zfIntVersion)
.setCreator(System.getProperty("user.name")).setProfile(zfConformanceLevelProfile);
ze = new OXExporterFromA1();
if (ignoreInputErrors) {
((OXExporterFromA1) ze).ignorePDFAErrors();
}

} else if (format.equals("da")) {
ze = new DXExporterFromA1().setProducer("Mustang-cli")
.setZUGFeRDVersion(zfIntVersion)
.setCreator(System.getProperty("user.name")).setProfile(zfConformanceLevelProfile);

ze = new DXExporterFromA1();
if (ignoreInputErrors) {
((DXExporterFromA1) ze).ignorePDFAErrors();
}

} else {
if (format.equals("fx")) {
zfIntVersion=2;// actually we are talking of generation, not version
zfIntVersion = 2;// actually we are talking of generation, not version
// so even if someone correctly requested factur-x 1 internally we call it zugferd 2 :-(
}
ze = new ZUGFeRDExporterFromPDFA().load(pdfName);

ze.setProducer("Mustang-cli")
.setZUGFeRDVersion(zfIntVersion)
.setCreator(System.getProperty("user.name")).setProfile(zfConformanceLevelProfile);
ze = new ZUGFeRDExporterFromPDFA();
if (ignoreInputErrors) {
((ZUGFeRDExporterFromA1) ze).ignorePDFAErrors();
((ZUGFeRDExporterFromPDFA)ze).ignorePDFAErrors();
}
}
for (FileAttachment attachment : attachments) {
((ZUGFeRDExporterFromA3) ze).attachFile(attachment.getFilename(), attachment.getData(), attachment.getMimetype(), attachment.getRelation());
}

// ze = ze.load(pdfName);
ze.load(pdfName);
ze.setProducer("Mustang-cli")
.setZUGFeRDVersion(zfIntVersion)
.setCreator(System.getProperty("user.name")).setProfile(zfConformanceLevelProfile);

if (format.equals("zf")) {
ze.disableFacturX();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,6 @@
import jakarta.activation.DataSource;

public class ZUGFeRDExporterFromA1 extends ZUGFeRDExporterFromA3 implements IZUGFeRDExporter {
protected boolean ignorePDFAErrors = false;

public ZUGFeRDExporterFromA1 ignorePDFAErrors() {
this.ignorePDFAErrors = true;
return this;
}

private static boolean isValidA1(DataSource dataSource) throws IOException {
return getPDFAParserValidationResult(PreflightParserHelper.createPreflightParser(dataSource));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,12 @@ public class ZUGFeRDExporterFromA3 extends XRExporter implements IZUGFeRDExporte
private boolean isFacturX = true;

public static final int DefaultZUGFeRDVersion = 2;
protected boolean ignorePDFAErrors = false;

public ZUGFeRDExporterFromA3 ignorePDFAErrors() {
this.ignorePDFAErrors = true;
return this;
}
protected PDFAConformanceLevel conformanceLevel = PDFAConformanceLevel.UNICODE;
protected ArrayList<FileAttachment> fileAttachments = new ArrayList<FileAttachment>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,28 @@ public class ZUGFeRDExporterFromPDFA implements IZUGFeRDExporter {

protected IZUGFeRDExporter theExporter;

protected boolean ignorePDFAErrors = false;

public ZUGFeRDExporterFromPDFA ignorePDFAErrors() {
this.ignorePDFAErrors = true;
return this;
}
protected void determineAndSetExporter(int PDFAVersion) {
if (PDFAVersion == 3) {
theExporter = new ZUGFeRDExporterFromA3();
if (ignorePDFAErrors) {
((ZUGFeRDExporterFromA3)theExporter).ignorePDFAErrors();
}
} else if (PDFAVersion == 1) {
theExporter = new ZUGFeRDExporterFromA1();
if (ignorePDFAErrors) {
((ZUGFeRDExporterFromA1)theExporter).ignorePDFAErrors();
}
} else {
throw new IllegalArgumentException("PDF-A version not supported");
}


}
protected IZUGFeRDExporter getExporter() {
if (theExporter==null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,11 @@ public void testFailIgnore() {
hasEx = false;
try (InputStream source = this.getClass()
.getResourceAsStream(SOURCE_PDF)) {
ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1().setProducer("My Application").ignorePDFAErrors()
.setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2)
.load(source);
ze.setTransaction(createInvoice());
ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1();
ze.ignorePDFAErrors().load(source);

ze.setProducer("My Application").setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).
setTransaction(createInvoice());
ze.export(TARGET_PDF);
} catch (IOException e) {
hasEx = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,12 +293,15 @@ public void testEdgeExport() {

// the writing part

try (InputStream SOURCE_PDF = this.getClass()
try {
InputStream SOURCE_PDF = this.getClass()
.getResourceAsStream("/MustangGnuaccountingBeispielRE-20170509_505blanko.pdf");

ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1().setProducer("My Application")
.setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile(Profiles.getByName("Extended")).ignorePDFAErrors()
.load(SOURCE_PDF)) {
ZUGFeRDExporterFromA1 ze = new ZUGFeRDExporterFromA1();ze.ignorePDFAErrors();
ze.load(SOURCE_PDF);
ze.setProducer("My Application")
.setCreator(System.getProperty("user.name")).setZUGFeRDVersion(2).setProfile(Profiles.getByName("Extended"));

ze.setTransaction(this);
String theXML = new String(ze.getProvider().getXML(), StandardCharsets.UTF_8);
assertTrue(theXML.contains("<rsm:CrossIndustryInvoice"));
Expand Down
Loading

0 comments on commit 53391ea

Please sign in to comment.