new zf 2.2 xslts, schema, schematron, switch to apache commons cli
This commit is contained in:
@@ -11,19 +11,6 @@
|
||||
<name>e-invoices commandline tool, allowing to create(embed), split and validate Factur-X/ZUGFeRD files. Validation should also work for XRechnung/CII. </name>
|
||||
<packaging>jar</packaging>
|
||||
<version>2.4.1-SNAPSHOT</version>
|
||||
<repositories>
|
||||
<repository>
|
||||
<!-- for jargs -->
|
||||
<id>sonatype-oss-public</id>
|
||||
<url>https://oss.sonatype.org/content/groups/public/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
@@ -36,12 +23,13 @@
|
||||
mvn install:install-file -Dfile=mustang-1.5.4-SNAPSHOT.jar -DgroupId=org.mustangproject.ZUGFeRD -DartifactId=mustang -Dversion=1.5.4 -Dpackaging=jar -DgeneratePom=true
|
||||
-->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- for commandline options -->
|
||||
<groupId>com.sanityinc</groupId>
|
||||
<artifactId>jargs</artifactId>
|
||||
<version>2.0-SNAPSHOT</version>
|
||||
<!-- https://mvnrepository.com/artifact/commons-cli/commons-cli -->
|
||||
<dependency><!-- apache commons cli to parse command line -->
|
||||
<groupId>commons-cli</groupId>
|
||||
<artifactId>commons-cli</artifactId>
|
||||
<version>1.5.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.riversun</groupId>
|
||||
<artifactId>bigdoc</artifactId>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/** **********************************************************************
|
||||
/************************************************************************
|
||||
*
|
||||
* Copyright 2018 Jochen Staerk
|
||||
*
|
||||
@@ -18,21 +18,22 @@
|
||||
*********************************************************************** */
|
||||
package org.mustangproject.commandline;
|
||||
|
||||
import com.sanityinc.jargs.CmdLineParser;
|
||||
import com.sanityinc.jargs.CmdLineParser.Option;
|
||||
import org.apache.commons.cli.*;
|
||||
import org.mustangproject.CII.CIIToUBL;
|
||||
import org.mustangproject.EStandard;
|
||||
import org.mustangproject.ZUGFeRD.*;
|
||||
import org.mustangproject.validator.Validator;
|
||||
import org.mustangproject.validator.ZUGFeRDValidator;
|
||||
import org.mustangproject.FileAttachment;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/***
|
||||
/*
|
||||
* This is the command line interface to mustangproject
|
||||
*
|
||||
*/
|
||||
@@ -49,7 +50,7 @@ public class Main {
|
||||
}
|
||||
|
||||
private static String getUsage() {
|
||||
return "Usage: --action metrics|combine|extract|a3only|ubl|validate|visualize [-d,--directory] [-l,--listfromstdin] [-i,--ignore fileextension, PDF/A errors] | [-h,--help] \r\n"
|
||||
return "Usage: --action metrics|combine|extract|a3only|ubl|validate|validateExpectInvalid|validateExpectValid|visualize [-d,--directory] [-l,--listfromstdin] [-i,--ignore fileextension, PDF/A errors] | [-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"
|
||||
@@ -76,6 +77,9 @@ public class Main {
|
||||
+ " [--profile <...>]: set ZUGFeRD profile\n"
|
||||
+ " For ZUGFeRD v1: <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"
|
||||
+ " --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"
|
||||
@@ -85,17 +89,14 @@ public class Main {
|
||||
+ " [--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=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=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=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"
|
||||
+ " [--source <filename>]: set input XML file\n"
|
||||
+ " [--out <filename>]: set output HTML file\n"
|
||||
@@ -132,7 +133,7 @@ public class Main {
|
||||
// for a more sophisticated dialogue maybe https://github.com/mabe02/lanterna/
|
||||
// could be taken into account
|
||||
System.out.print(prompt + " (default: " + defaultValue + ")");
|
||||
if (!firstInput) {
|
||||
if ((!firstInput)&&(pattern.length()>0)) {
|
||||
System.out.print("\n(allowed pattern: " + pattern + ")");
|
||||
|
||||
}
|
||||
@@ -190,8 +191,9 @@ public class Main {
|
||||
boolean hasCorrectExtension=false;
|
||||
String[] expectedExtensions=expectedExtension.split("\\|");
|
||||
for (String currentExtension: expectedExtensions) {
|
||||
if (selectedName.toLowerCase().endsWith(expectedExtension.toLowerCase())) {
|
||||
if (selectedName.toLowerCase().endsWith(currentExtension.toLowerCase())) {
|
||||
hasCorrectExtension=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// error cases
|
||||
@@ -263,8 +265,8 @@ public class Main {
|
||||
|
||||
/***
|
||||
* converts from CII to UBL
|
||||
* @param xmlName
|
||||
* @param outName
|
||||
* @param xmlName the name of the xml file
|
||||
* @param outName the name of the output file
|
||||
* @throws IOException
|
||||
* @throws TransformerException
|
||||
*/
|
||||
@@ -325,70 +327,55 @@ public class Main {
|
||||
}
|
||||
/***
|
||||
* the main function of the commandline tool...
|
||||
* @param args
|
||||
* @param args the commandline args, see also https://www.mustangproject.org/commandline/#verbose
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
CmdLineParser parser = new CmdLineParser();
|
||||
CommandLine cmd;
|
||||
CommandLineParser parser = new BasicParser();
|
||||
// create Options object
|
||||
Options options = new Options();
|
||||
|
||||
|
||||
// Option: Help
|
||||
Option<Boolean> helpOption = parser.addBooleanOption('h', "help");
|
||||
// Option: Action
|
||||
Option<String> actionOption = parser.addStringOption('a', "action");
|
||||
options.addOption(new Option("h", "help",false, "display usage"));
|
||||
options.addOption(new Option("a", "action",true, "which action to perform"));
|
||||
options.addOption(new Option("f", "format",true, "which format to output"));
|
||||
options.addOption(new Option("", "version",true, "which version of the standard to use"));
|
||||
options.addOption(new Option("", "profile",true, "which profile of the standard to use"));
|
||||
Option attachmentOpt=new Option("", "attachment", true, "File attachments");
|
||||
attachmentOpt.setValueSeparator(',');
|
||||
attachmentOpt.setArgs(Option.UNLIMITED_VALUES);
|
||||
options.addOption(new Option("", "source",true, "which source file to use"));
|
||||
options.addOption(new Option("", "source-xml",true, "which source file to use"));
|
||||
options.addOption(new Option("", "out",true, "which output file to write to"));
|
||||
options.addOption(new Option("", "no-notices",false, "suppress non-fatal errors"));
|
||||
options.addOption(new Option("", "logAppend",true, "freeform text to be appended to log messages"));
|
||||
options.addOption(new Option("", "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"));
|
||||
|
||||
// Generic options available for multiple command
|
||||
// --source: input file
|
||||
Option<String> sourceOption = parser.addStringOption("source");
|
||||
// --out: output file
|
||||
Option<String> outOption = parser.addStringOption("out");
|
||||
Option<Boolean> noNoticesOption = parser.addBooleanOption("no-notices");
|
||||
Option<String> logAppendOption = parser.addStringOption("logAppend");
|
||||
|
||||
// Command: Combining PDF and XML
|
||||
// --combine
|
||||
// (--source: input PDF file)
|
||||
// (--source-xml: input XML file)
|
||||
// (--out: output PDF file)
|
||||
// (--version: ZUGFeRD version)
|
||||
// (--profile: ZUGFeRD profile)
|
||||
Option<String> sourceXmlOption = parser.addStringOption("source-xml");
|
||||
Option<String> formatOption = parser.addStringOption('f', "format");
|
||||
Option<String> zugferdVersionOption = parser.addStringOption("version");
|
||||
Option<String> zugferdProfileOption = parser.addStringOption("profile");
|
||||
cmd = parser.parse(options, args);
|
||||
|
||||
// Command: Show metrics in dir
|
||||
// --directory
|
||||
// (--ignorefileextension)
|
||||
Option<String> dirnameOption = parser.addStringOption('d', "directory");
|
||||
Option<Boolean> ignoreFileExtOption = parser.addBooleanOption('i', "ignorefileextension");
|
||||
|
||||
// Command: Show metrics from list from stdin
|
||||
// --listfromstdin
|
||||
Option<Boolean> filesFromStdInOption = parser.addBooleanOption('l', "listfromstdin");
|
||||
try {
|
||||
parser.parse(args);
|
||||
} catch (CmdLineParser.OptionException e) {
|
||||
System.err.println(e.getMessage());
|
||||
printUsage();
|
||||
System.exit(2);
|
||||
}
|
||||
|
||||
// Retrieve all options
|
||||
String action = parser.getOptionValue(actionOption);
|
||||
String directoryName = parser.getOptionValue(dirnameOption);
|
||||
Boolean filesFromStdIn = parser.getOptionValue(filesFromStdInOption, Boolean.FALSE);
|
||||
Boolean ignoreFileExt = parser.getOptionValue(ignoreFileExtOption, Boolean.FALSE);
|
||||
Boolean helpRequested = parser.getOptionValue(helpOption, Boolean.FALSE) || ((action!=null)&&(action.equals("help")));
|
||||
String action = cmd.getOptionValue("action");
|
||||
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")));
|
||||
|
||||
String sourceName = parser.getOptionValue(sourceOption);
|
||||
String sourceXMLName = parser.getOptionValue(sourceXmlOption);
|
||||
String outName = parser.getOptionValue(outOption);
|
||||
String format = parser.getOptionValue(formatOption);
|
||||
Boolean noNotices = parser.getOptionValue(noNoticesOption);
|
||||
String sourceName = cmd.getOptionValue("source");
|
||||
String sourceXMLName = cmd.getOptionValue("source-xml");
|
||||
String outName = cmd.getOptionValue("out");
|
||||
String format = cmd.getOptionValue("format");
|
||||
Boolean noNotices = cmd.hasOption("no-notices");
|
||||
|
||||
String zugferdVersion = cmd.getOptionValue("version");
|
||||
String zugferdProfile = cmd.getOptionValue("profile");
|
||||
|
||||
ArrayList<FileAttachment> attachments=new ArrayList <>();
|
||||
|
||||
String zugferdVersion = parser.getOptionValue(zugferdVersionOption);
|
||||
String zugferdProfile = parser.getOptionValue(zugferdProfileOption);
|
||||
boolean optionsRecognized=false;
|
||||
if (helpRequested) {
|
||||
printHelp();
|
||||
@@ -400,7 +387,7 @@ public class Main {
|
||||
performMetrics(directoryName, filesFromStdIn, ignoreFileExt);
|
||||
optionsRecognized=true;
|
||||
} else if ((action!=null)&&(action.equals("combine"))) {
|
||||
performCombine(sourceName, sourceXMLName, outName, format, zugferdVersion, zugferdProfile, ignoreFileExt);
|
||||
performCombine(sourceName, sourceXMLName, outName, format, zugferdVersion, zugferdProfile, ignoreFileExt, attachments);
|
||||
optionsRecognized=true;
|
||||
} else if ((action!=null)&&(action.equals("extract"))) {
|
||||
performExtract(sourceName, outName);
|
||||
@@ -418,12 +405,13 @@ public class Main {
|
||||
performUBL(sourceName, outName);
|
||||
optionsRecognized=true;
|
||||
} else if ((action!=null)&&(action.equals("validate"))) {
|
||||
optionsRecognized=performValidate(sourceName, noNotices!=null&&noNotices, parser.getOptionValue(logAppendOption));
|
||||
optionsRecognized=performValidate(sourceName, noNotices!=null&&noNotices, cmd.getOptionValue("logAppend"));
|
||||
} else if ((action!=null)&&(action.equals("validateExpectValid"))) {
|
||||
optionsRecognized=performValidateExpect(true, directoryName);
|
||||
} else if ((action!=null)&&(action.equals("validateExpectInvalid"))) {
|
||||
optionsRecognized=performValidateExpect(false, directoryName);
|
||||
} else {
|
||||
}
|
||||
if (!optionsRecognized){
|
||||
// no argument or argument unknown
|
||||
printUsage();
|
||||
System.exit(2);
|
||||
@@ -534,7 +522,7 @@ public class Main {
|
||||
}
|
||||
|
||||
private static void performCombine(String pdfName, String xmlName, String outName, String format, String zfVersion,
|
||||
String zfProfile, Boolean ignoreInputErrors) throws Exception {
|
||||
String zfProfile, Boolean ignoreInputErrors, ArrayList <FileAttachment> attachments) throws Exception {
|
||||
/*
|
||||
* ZUGFeRDExporter ze= new ZUGFeRDExporterFromA1Factory()
|
||||
* .setProducer("toecount") .setCreator(System.getProperty("user.name"))
|
||||
@@ -557,11 +545,23 @@ public class Main {
|
||||
}
|
||||
|
||||
if (outName == null) {
|
||||
outName = getFilenameFromUser("Ouput PDF", "invoice.ZUGFeRD.pdf", "pdf", false, true);
|
||||
outName = getFilenameFromUser("Output PDF", "invoice.ZUGFeRD.pdf", "pdf", false, true);
|
||||
} else {
|
||||
System.out.println("Output PDF set to " + outName);
|
||||
}
|
||||
|
||||
byte attachmentContents[]=null;
|
||||
String attachmentFilename, attachmentMime, attachmentDescription;
|
||||
attachmentFilename = getFilenameFromUser("Attachment filename (empty for none)", "", "pdf", true, false);
|
||||
if (attachmentFilename.length()!=0) {
|
||||
attachmentContents=Files.readAllBytes(Paths.get(attachmentFilename));
|
||||
attachmentMime= Files.probeContentType(Paths.get(attachmentFilename));
|
||||
attachments.add(new FileAttachment(attachmentFilename, attachmentMime, "Data", attachmentContents));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (format == null) {
|
||||
try {
|
||||
format = getStringFromUser("Format (fx=Factur-X, zf=ZUGFeRD, ox=Order-X)", "zf", "fx|zf|ox");
|
||||
@@ -600,6 +600,8 @@ public class Main {
|
||||
}
|
||||
zfProfile = zfProfile.toLowerCase();
|
||||
|
||||
|
||||
|
||||
// Verify params
|
||||
ensureFileExists(pdfName);
|
||||
ensureFileExists(xmlName);
|
||||
@@ -664,6 +666,9 @@ public class Main {
|
||||
((ZUGFeRDExporterFromA1)ze).ignorePDFAErrors();
|
||||
}
|
||||
}
|
||||
for (FileAttachment attachment: attachments) {
|
||||
((ZUGFeRDExporterFromA3) ze).attachFile(attachment.getFilename(), attachment.getData(), attachment.getMimetype(), attachment.getRelation());
|
||||
}
|
||||
|
||||
ze = ze.load(pdfName);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user