001/* 002 * Copyright (C) 2014 konik.io 003 * 004 * This file is part of Konik library. 005 * 006 * Konik library is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU Affero General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Konik library is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU Affero General Public License for more details. 015 * 016 * You should have received a copy of the GNU Affero General Public License 017 * along with Konik library. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package io.konik; 020 021import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; 022import static javax.xml.bind.JAXBContext.newInstance; 023import io.konik.exception.TransformationException; 024import io.konik.zugferd.Invoice; 025 026import java.io.ByteArrayOutputStream; 027import java.io.File; 028import java.io.InputStream; 029import java.net.URL; 030 031import javax.inject.Inject; 032import javax.inject.Named; 033import javax.inject.Singleton; 034import javax.xml.bind.JAXBContext; 035import javax.xml.bind.JAXBElement; 036import javax.xml.bind.JAXBException; 037import javax.xml.bind.Marshaller; 038import javax.xml.bind.Unmarshaller; 039import javax.xml.transform.stream.StreamSource; 040import javax.xml.validation.Schema; 041import javax.xml.validation.SchemaFactory; 042import javax.xml.validation.Validator; 043 044import org.xml.sax.SAXException; 045 046/** 047 * Transforms invoices from one representation to another. In other words marshaling and unmarshalling. 048 * 049 */ 050@Named 051@Singleton 052public class InvoiceTransformer { 053 054 private static final String KONIK_CONTEXT = "io.konik.zugferd"; 055 056 private final JAXBContext jaxbContext; 057 058 /** 059 * Instantiates a new invoice transformer. 060 */ 061 public InvoiceTransformer() { 062 try { 063 this.jaxbContext = newInstance(KONIK_CONTEXT); 064 } catch (JAXBException e) { 065 throw new TransformationException("Could not instantiate JaxB Context", e); 066 } 067 } 068 069 /** 070 * Instantiates a new invoice transformer. 071 * 072 * @param jaxbContext the jaxb context 073 */ 074 @Inject 075 public InvoiceTransformer(JAXBContext jaxbContext) { 076 this.jaxbContext = jaxbContext; 077 } 078 079 /** 080 * Transform from XML input stream to the invoice model. 081 * 082 * @param xmlIs the xml input stream 083 * @return the invoice model 084 */ 085 public Invoice from(InputStream xmlIs) { 086 try { 087 Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 088 return unmarshaller.unmarshal(new StreamSource(xmlIs), Invoice.class).getValue(); 089 } catch (JAXBException e) { 090 throw new TransformationException("Marshalling error", e); 091 } 092 } 093 094 /** 095 * Transform from XML content from File to the invoice model. 096 * 097 * @param file the file 098 * @return the invoice 099 */ 100 @SuppressWarnings("unchecked") 101 public Invoice from(File file) { 102 try { 103 Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 104 return ((JAXBElement<Invoice>) unmarshaller.unmarshal(file)).getValue(); 105 } catch (JAXBException e) { 106 throw new TransformationException("Marshalling error", e); 107 } 108 } 109 /** 110 * Transform from Invoice model to xml byte array. 111 * 112 * @param invoice the invoice 113 * @return the byte[] 114 */ 115 public byte[] from(Invoice invoice) { 116 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(16000); 117 try { 118 Marshaller marshaller = jaxbContext.createMarshaller(); 119 marshaller.marshal(invoice, outputStream); 120 } catch (JAXBException e) { 121 throw new TransformationException("Marshalling error", e); 122 } 123 return outputStream.toByteArray(); 124 } 125 126 /** 127 * Transform from Invoice model to output stream. 128 * 129 * @param invoice the invoice 130 * @param outputStream the output stream 131 */ 132 public void from(Invoice invoice, ByteArrayOutputStream outputStream) { 133 try { 134 Marshaller marshaller = jaxbContext.createMarshaller(); 135 marshaller.marshal(invoice, outputStream); 136 } catch (JAXBException e) { 137 throw new TransformationException("Marshalling error", e); 138 } 139 } 140 141 142 /** 143 * Gets the ZUGFeRD schema Validator. 144 * 145 * @return the Schema Validator 146 * @throws SAXException the SAX exception 147 */ 148 public Validator getZfSchemaValidator() throws SAXException { 149 SchemaFactory sf = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI); 150 URL schemaInvoice = InvoiceTransformer.class.getResource("/zfSchema/Invoice.xsd"); 151 Schema invoiceSchema = sf.newSchema(schemaInvoice); 152 return invoiceSchema.newValidator(); 153 } 154}