View Javadoc
1   /*
2    * (c) Copyright 2006-2020 by rapiddweller GmbH & Volker Bergmann. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, is permitted under the terms of the
6    * GNU General Public License.
7    *
8    * For redistributing this software or a derivative work under a license other
9    * than the GPL-compatible Free Software License as defined by the Free
10   * Software Foundation or approved by OSI, you must first obtain a commercial
11   * license to this software product from rapiddweller GmbH & Volker Bergmann.
12   *
13   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14   * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
15   * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
16   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
17   * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24   * POSSIBILITY OF SUCH DAMAGE.
25   */
26  
27  package com.rapiddweller.platform.dbunit;
28  
29  import com.rapiddweller.benerator.consumer.AbstractConsumer;
30  import com.rapiddweller.common.ConfigurationError;
31  import com.rapiddweller.common.Encodings;
32  import com.rapiddweller.common.IOUtil;
33  import com.rapiddweller.common.SystemInfo;
34  import com.rapiddweller.common.converter.ToStringConverter;
35  import com.rapiddweller.model.data.Entity;
36  import org.apache.logging.log4j.LogManager;
37  import org.apache.logging.log4j.Logger;
38  import org.xml.sax.SAXException;
39  import org.xml.sax.helpers.AttributesImpl;
40  
41  import javax.xml.transform.OutputKeys;
42  import javax.xml.transform.Transformer;
43  import javax.xml.transform.TransformerConfigurationException;
44  import javax.xml.transform.sax.SAXTransformerFactory;
45  import javax.xml.transform.sax.TransformerHandler;
46  import javax.xml.transform.stream.StreamResult;
47  import java.io.FileOutputStream;
48  import java.io.IOException;
49  import java.io.OutputStream;
50  import java.util.Map;
51  
52  /**
53   * Exports entities in DbUnit XML file format.
54   *
55   * @author Volker Bergmann
56   * @since 0.3.04
57   */
58  public class DbUnitEntityExporter extends AbstractConsumer {
59  
60    // attributes ------------------------------------------------------------------------------------------------------
61  
62    private static final Logger logger = LogManager.getLogger(DbUnitEntityExporter.class);
63  
64    private static final String DEFAULT_FILE_ENCODING = Encodings.UTF_8;
65    private static final String DEFAULT_URI = "data.dbunit.xml";
66  
67    private static final String DATE_PATTERN = "yyyy-MM-dd";
68    private static final String TIMESTAMP_PATTERN = "yyyy-MM-dd HH:mm:ss.SSSSSS";
69  
70    private final ToStringConverter toStringConverter;
71  
72    private String uri;
73    private String encoding;
74  
75    private OutputStream out;
76    private TransformerHandler handler;
77  
78  
79    // constructors ----------------------------------------------------------------------------------------------------
80  
81    /**
82     * Instantiates a new Db unit entity exporter.
83     */
84    public DbUnitEntityExporter() {
85      this(DEFAULT_URI);
86    }
87  
88    /**
89     * Instantiates a new Db unit entity exporter.
90     *
91     * @param uri the uri
92     */
93    public DbUnitEntityExporter(String uri) {
94      this(uri, DEFAULT_FILE_ENCODING);
95    }
96  
97    /**
98     * Instantiates a new Db unit entity exporter.
99     *
100    * @param uri      the uri
101    * @param encoding the encoding
102    */
103   public DbUnitEntityExporter(String uri, String encoding) {
104     setUri(uri);
105     setEncoding(encoding);
106     this.toStringConverter = new ToStringConverter(null, DATE_PATTERN, TIMESTAMP_PATTERN);
107   }
108 
109   // properties ------------------------------------------------------------------------------------------------------
110 
111   /**
112    * Gets uri.
113    *
114    * @return the uri
115    */
116   public String getUri() {
117     return uri;
118   }
119 
120   /**
121    * Sets uri.
122    *
123    * @param uri the uri
124    */
125   public void setUri(String uri) {
126     this.uri = uri;
127   }
128 
129   /**
130    * Gets encoding.
131    *
132    * @return the encoding
133    */
134   public String getEncoding() {
135     return encoding;
136   }
137 
138   /**
139    * Sets encoding.
140    *
141    * @param encoding the encoding
142    */
143   public void setEncoding(String encoding) {
144     this.encoding = (encoding != null ? encoding : SystemInfo.getFileEncoding());
145     if (this.encoding == null) {
146       this.encoding = DEFAULT_FILE_ENCODING;
147     }
148   }
149 
150   // Consumer interface ----------------------------------------------------------------------------------------------
151 
152   @Override
153   public void startProductConsumption(Object object) {
154     if (!(object instanceof Entity)) {
155       throw new IllegalArgumentException("Expected entity");
156     }
157     Entity../../../../com/rapiddweller/model/data/Entity.html#Entity">Entity entity = (Entity) object;
158     try {
159       if (logger.isDebugEnabled()) {
160         logger.debug("exporting " + entity);
161       }
162       if (out == null) {
163         initPrinter();
164       }
165       AttributesImpl atts = new AttributesImpl();
166       for (Map.Entry<String, Object> entry : entity.getComponents().entrySet()) {
167         Object value = entry.getValue();
168         if (value == null) {
169           continue;
170         }
171         String s = toStringConverter.convert(value);
172         if (s != null) {
173           atts.addAttribute("", "", entry.getKey(), "CDATA", s);
174         }
175       }
176       handler.startElement("", "", entity.type(), atts);
177       handler.endElement("", "", entity.type());
178     } catch (IOException e) {
179       throw new RuntimeException(e);
180     } catch (SAXException e) {
181       throw new ConfigurationError("Error in processing element: " + entity, e);
182     }
183   }
184 
185   @Override
186   public void flush() {
187     if (out != null) {
188       IOUtil.flush(out);
189     }
190   }
191 
192   @Override
193   public void close() {
194     if (handler != null) {
195       try {
196         handler.endElement("", "", "dataset");
197         handler.endDocument();
198         handler = null;
199       } catch (SAXException e) {
200         throw new ConfigurationError("Error closing XML file.", e);
201       } finally {
202         IOUtil.close(out);
203         out = null;
204       }
205     }
206   }
207 
208   //  java.lang.String overrides --------------------------------------------------------------------------------------
209 
210   private void initPrinter() throws IOException {
211     try {
212       // create file and write header
213       SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
214       handler = tf.newTransformerHandler();
215 
216       Transformer serializer = handler.getTransformer();
217       serializer.setOutputProperty(OutputKeys.ENCODING, encoding);
218       serializer.setOutputProperty(OutputKeys.INDENT, "yes");
219 
220       out = new FileOutputStream(uri);
221       handler.setResult(new StreamResult(out));
222       handler.startDocument();
223       handler.startElement("", "", "dataset", null);
224 
225     } catch (TransformerConfigurationException e) {
226       throw new ConfigurationError(e);
227     } catch (SAXException e) {
228       throw new ConfigurationError("Error in initializing XML file", e);
229     }
230   }
231 
232   @Override
233   public String toString() {
234     return getClass().getSimpleName() + '[' + uri + ", " + encoding + "]";
235   }
236 }