no message
This commit is contained in:
@@ -5,6 +5,9 @@
|
|||||||
Support BuyerReference (r+w), as well as SpecifiedLegalOrganization (w) and DefinedTradeContact (w)
|
Support BuyerReference (r+w), as well as SpecifiedLegalOrganization (w) and DefinedTradeContact (w)
|
||||||
use dom4j to format output xml document
|
use dom4j to format output xml document
|
||||||
corrected some exception logging glitches
|
corrected some exception logging glitches
|
||||||
|
upgrade PDFBox to 2.0.15+
|
||||||
|
extraction to use proper filename instead of alias #98
|
||||||
|
NullPointerException in ZUGFeRDImporter.extractLowLevel #96
|
||||||
|
|
||||||
|
|
||||||
1.7.1
|
1.7.1
|
||||||
|
|||||||
4
pom.xml
4
pom.xml
@@ -69,12 +69,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.pdfbox</groupId>
|
<groupId>org.apache.pdfbox</groupId>
|
||||||
<artifactId>preflight</artifactId>
|
<artifactId>preflight</artifactId>
|
||||||
<version>2.0.12</version>
|
<version>[2.0.15,)</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.pdfbox</groupId>
|
<groupId>org.apache.pdfbox</groupId>
|
||||||
<artifactId>pdfbox</artifactId>
|
<artifactId>pdfbox</artifactId>
|
||||||
<version>2.0.12</version>
|
<version>[2.0.15,)</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dom4j</groupId>
|
<groupId>org.dom4j</groupId>
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ import javax.xml.xpath.XPath;
|
|||||||
import javax.xml.xpath.XPathExpressionException;
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
import javax.xml.xpath.XPathFactory;
|
import javax.xml.xpath.XPathFactory;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@@ -67,14 +70,13 @@ public class ZUGFeRDImporter {
|
|||||||
private String xmpString = null; // XMP metadata
|
private String xmpString = null; // XMP metadata
|
||||||
|
|
||||||
public ZUGFeRDImporter(String pdfFilename) {
|
public ZUGFeRDImporter(String pdfFilename) {
|
||||||
try {
|
|
||||||
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(pdfFilename));
|
try (InputStream bis = Files.newInputStream(Paths.get(pdfFilename), StandardOpenOption.READ)) {
|
||||||
extractLowLevel(bis);
|
extractLowLevel(bis);
|
||||||
bis.close();
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
|
Logger.getLogger(ZUGFeRDImporter.class.getName()).log(Level.SEVERE, null, e);
|
||||||
throw new ZUGFeRDExportException(e);
|
throw new ZUGFeRDExportException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ZUGFeRDImporter(InputStream pdfStream) {
|
public ZUGFeRDImporter(InputStream pdfStream) {
|
||||||
@@ -125,7 +127,9 @@ public class ZUGFeRDImporter {
|
|||||||
|
|
||||||
|
|
||||||
private void extractFiles(Map<String, PDComplexFileSpecification> names) throws IOException {
|
private void extractFiles(Map<String, PDComplexFileSpecification> names) throws IOException {
|
||||||
for (String filename : names.keySet()) {
|
for (String alias : names.keySet()) {
|
||||||
|
String filename=names.get(alias).getFilename();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* currently (in the release candidate of version 1) only one attached file with
|
* currently (in the release candidate of version 1) only one attached file with
|
||||||
* the name ZUGFeRD-invoice.xml is allowed
|
* the name ZUGFeRD-invoice.xml is allowed
|
||||||
|
|||||||
134
src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java
Normal file
134
src/main/java/org/mustangproject/ZUGFeRD/ZUGFeRDVisualizer.java
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
/** **********************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2018 Jochen Staerk
|
||||||
|
*
|
||||||
|
* Use is subject to license terms.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy
|
||||||
|
* of the License at http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*********************************************************************** */
|
||||||
|
package org.mustangproject.ZUGFeRD;
|
||||||
|
|
||||||
|
import javax.xml.transform.*;
|
||||||
|
import javax.xml.transform.stream.StreamResult;
|
||||||
|
import javax.xml.transform.stream.StreamSource;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class ZUGFeRDVisualizer {
|
||||||
|
|
||||||
|
static final ClassLoader CLASS_LOADER = ZUGFeRDVisualizer.class.getClassLoader();
|
||||||
|
private static final String RESOURCE_PATH = ""; //$NON-NLS-1$
|
||||||
|
private static final Logger LOG = Logger.getLogger(ZUGFeRDVisualizer.class.getName());
|
||||||
|
// private static File createTempFileResult(final Transformer transformer, final StreamSource toTransform,
|
||||||
|
// final String suffix) throws TransformerException, IOException {
|
||||||
|
// File result = File.createTempFile("ZUV_", suffix); //$NON-NLS-1$
|
||||||
|
// result.deleteOnExit();
|
||||||
|
//
|
||||||
|
// try (FileOutputStream fos = new FileOutputStream(result)) {
|
||||||
|
// transformer.transform(toTransform, new StreamResult(fos));
|
||||||
|
// }
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
private TransformerFactory mFactory = null;
|
||||||
|
private Templates mXsltXRTemplate = null;
|
||||||
|
private Templates mXsltHTMLTemplate = null;
|
||||||
|
|
||||||
|
public ZUGFeRDVisualizer() {
|
||||||
|
mFactory = new net.sf.saxon.TransformerFactoryImpl();
|
||||||
|
//fact = TransformerFactory.newInstance();
|
||||||
|
mFactory.setURIResolver(new ClasspathResourceURIResolver());
|
||||||
|
try {
|
||||||
|
mXsltXRTemplate = mFactory.newTemplates(new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/cii-xr.xsl")));
|
||||||
|
mXsltHTMLTemplate = mFactory.newTemplates(new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + "stylesheets/xrechnung-html.xsl")));
|
||||||
|
} catch (TransformerConfigurationException ex) {
|
||||||
|
LOG.log(Level.SEVERE, null, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String visualize(String xmlFilename) throws FileNotFoundException, TransformerException, UnsupportedEncodingException {
|
||||||
|
/**
|
||||||
|
* *
|
||||||
|
* http://www.unece.org/fileadmin/DAM/cefact/xml/XML-Naming-And-Design-Rules-V2_1.pdf
|
||||||
|
* http://www.ferd-net.de/upload/Dokumente/FACTUR-X_ZUGFeRD_2p0_Teil1_Profil_EN16931_1p03.pdf
|
||||||
|
* http://countwordsfree.com/xmlviewer
|
||||||
|
*/
|
||||||
|
ByteArrayOutputStream iaos = new ByteArrayOutputStream();
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
applySchematronXsl(new FileInputStream(xmlFilename), iaos);
|
||||||
|
// take the copy of the stream and re-write it to an InputStream
|
||||||
|
PipedInputStream in = new PipedInputStream();
|
||||||
|
PipedOutputStream out;
|
||||||
|
try {
|
||||||
|
out = new PipedOutputStream(in);
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
public void run () {
|
||||||
|
try {
|
||||||
|
// write the original OutputStream to the PipedOutputStream
|
||||||
|
// note that in order for the below method to work, you need
|
||||||
|
// to ensure that the data has finished writing to the
|
||||||
|
// ByteArrayOutputStream
|
||||||
|
iaos.writeTo(out);
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// logging and exception handling should go here
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
// close the PipedOutputStream here because we're done writing data
|
||||||
|
// once this thread has completed its run
|
||||||
|
if (out != null) {
|
||||||
|
// close the PipedOutputStream cleanly
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
applySchematronXsl2(in, baos);
|
||||||
|
} catch (IOException e1) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return baos.toString("UTF-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applySchematronXsl(final InputStream xmlFile,
|
||||||
|
final OutputStream HTMLOutstream) throws TransformerException {
|
||||||
|
Transformer transformer = mXsltXRTemplate.newTransformer();
|
||||||
|
|
||||||
|
transformer.transform(new StreamSource(xmlFile), new StreamResult(HTMLOutstream));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applySchematronXsl2(final InputStream xmlFile,
|
||||||
|
final OutputStream HTMLOutstream) throws TransformerException {
|
||||||
|
Transformer transformer = mXsltHTMLTemplate.newTransformer();
|
||||||
|
|
||||||
|
transformer.transform(new StreamSource(xmlFile), new StreamResult(HTMLOutstream));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ClasspathResourceURIResolver implements URIResolver {
|
||||||
|
ClasspathResourceURIResolver() {
|
||||||
|
// Do nothing, just prevents synthetic access warning.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Source resolve(String href, String base) throws TransformerException {
|
||||||
|
return new StreamSource(CLASS_LOADER.getResourceAsStream(RESOURCE_PATH + href));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,8 +30,10 @@ import org.mustangproject.ZUGFeRD.*;
|
|||||||
import javax.xml.transform.TransformerException;
|
import javax.xml.transform.TransformerException;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
@@ -235,6 +237,8 @@ public class Toecount {
|
|||||||
|
|
||||||
// Option: Help
|
// Option: Help
|
||||||
Option<Boolean> helpOption = parser.addBooleanOption('h', "help");
|
Option<Boolean> helpOption = parser.addBooleanOption('h', "help");
|
||||||
|
// Option: Action
|
||||||
|
Option<String> actionOption = parser.addStringOption('a', "action");
|
||||||
|
|
||||||
// Generic options available for multiple command
|
// Generic options available for multiple command
|
||||||
// --source: input file
|
// --source: input file
|
||||||
@@ -304,6 +308,7 @@ public class Toecount {
|
|||||||
String sourceXMLName = parser.getOptionValue(sourceXmlOption);
|
String sourceXMLName = parser.getOptionValue(sourceXmlOption);
|
||||||
String outName = parser.getOptionValue(outOption);
|
String outName = parser.getOptionValue(outOption);
|
||||||
String format = parser.getOptionValue(formatOption);
|
String format = parser.getOptionValue(formatOption);
|
||||||
|
String action = parser.getOptionValue(actionOption);
|
||||||
String zugferdVersion = parser.getOptionValue(zugferdVersionOption);
|
String zugferdVersion = parser.getOptionValue(zugferdVersionOption);
|
||||||
String zugferdProfile = parser.getOptionValue(zugferdProfileOption);
|
String zugferdProfile = parser.getOptionValue(zugferdProfileOption);
|
||||||
|
|
||||||
@@ -319,6 +324,8 @@ public class Toecount {
|
|||||||
performConvert(sourceName, outName);
|
performConvert(sourceName, outName);
|
||||||
} else if (upgradeRequested) {
|
} else if (upgradeRequested) {
|
||||||
performUpgrade(sourceName, outName);
|
performUpgrade(sourceName, outName);
|
||||||
|
} else if (action.equals("convertToHTML")) {
|
||||||
|
performVisualization(sourceName, outName);
|
||||||
} else {
|
} else {
|
||||||
// no argument or argument unknown
|
// no argument or argument unknown
|
||||||
printUsage();
|
printUsage();
|
||||||
@@ -332,6 +339,48 @@ public class Toecount {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void performVisualization(String sourceName, String outName) {
|
||||||
|
// Get params from user if not already defined
|
||||||
|
if (sourceName == null) {
|
||||||
|
sourceName = getFilenameFromUser("ZUGFeRD XML source", "zugferd-invoice.xml", "xml", true, false);
|
||||||
|
} else {
|
||||||
|
System.out.println("ZUGFeRD XML source set to " + sourceName);
|
||||||
|
}
|
||||||
|
if (outName == null) {
|
||||||
|
outName = getFilenameFromUser("ZUGFeRD 2.0 XML target", "factur-x.html", "html", false, true);
|
||||||
|
} else {
|
||||||
|
System.out.println("ZUGFeRD 1.0 XML source set to " + outName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify params
|
||||||
|
try {
|
||||||
|
ensureFileExists(sourceName);
|
||||||
|
ensureFileNotExists(outName);
|
||||||
|
|
||||||
|
//stylesheets/ZUGFeRD_1p0_c1p0_s1p0.xslt
|
||||||
|
} catch (IOException e) {
|
||||||
|
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZUGFeRDVisualizer zvi = new ZUGFeRDVisualizer();
|
||||||
|
String xml = null;
|
||||||
|
try {
|
||||||
|
xml = zvi.visualize(sourceName);
|
||||||
|
Files.write(Paths.get(outName), xml.getBytes());
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
|
||||||
|
} catch (TransformerException e) {
|
||||||
|
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Logger.getLogger(Toecount.class.getName()).log(Level.SEVERE, null, e);
|
||||||
|
}
|
||||||
|
System.out.println("Written to " + outName);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private static void performUpgrade(String xmlName, String outName) throws IOException, TransformerException {
|
private static void performUpgrade(String xmlName, String outName) throws IOException, TransformerException {
|
||||||
|
|
||||||
// Get params from user if not already defined
|
// Get params from user if not already defined
|
||||||
@@ -341,7 +390,7 @@ public class Toecount {
|
|||||||
System.out.println("ZUGFeRD 1.0 XML source set to " + xmlName);
|
System.out.println("ZUGFeRD 1.0 XML source set to " + xmlName);
|
||||||
}
|
}
|
||||||
if (outName == null) {
|
if (outName == null) {
|
||||||
outName = getFilenameFromUser("ZUGFeRD 2.0 XML target", "factur-x.xml", "xml", false, true);
|
outName = getFilenameFromUser("ZUGFeRD 2.0 XML target", "zugferd-invoice.xml", "xml", false, true);
|
||||||
} else {
|
} else {
|
||||||
System.out.println("ZUGFeRD 1.0 XML source set to " + outName);
|
System.out.println("ZUGFeRD 1.0 XML source set to " + outName);
|
||||||
}
|
}
|
||||||
|
|||||||
3008
src/main/resources/stylesheets/ZUGFeRD_1p0_c1p0_s1p0.xslt
Normal file
3008
src/main/resources/stylesheets/ZUGFeRD_1p0_c1p0_s1p0.xslt
Normal file
File diff suppressed because it is too large
Load Diff
2202
src/main/resources/stylesheets/cii-xr.xsl
Normal file
2202
src/main/resources/stylesheets/cii-xr.xsl
Normal file
File diff suppressed because it is too large
Load Diff
1188
src/main/resources/stylesheets/xrechnung-html.xsl
Normal file
1188
src/main/resources/stylesheets/xrechnung-html.xsl
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Reference in New Issue
Block a user