View Javadoc

1   /*
2    * Copyright (C) 2005-2006 Christian Siefkes <christian@siefkes.net>.
3    * Development of this software is supported by the German Research Society,
4    * Berlin-Brandenburg Graduate School in Distributed Information Systems
5    * (DFG grant no. GRK 316).
6    *
7    * This program is free software; you can redistribute it and/or modify
8    * it under the terms of the GNU General Public License as published by
9    * the Free Software Foundation; either version 2 of the License, or
10   * (at your option) any later version.
11   *
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with this program; if not, visit
19   * http://www.gnu.org/licenses/gpl.html or write to the Free Software
20   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21   */
22  package de.fu_berlin.ties.xml.convert;
23  
24  import java.io.IOException;
25  import java.io.Reader;
26  
27  import org.apache.commons.lang.builder.ToStringBuilder;
28  import org.dom4j.Document;
29  import org.dom4j.Element;
30  import org.dom4j.QName;
31  import org.dom4j.tree.DefaultDocument;
32  
33  import de.fu_berlin.ties.ContextMap;
34  import de.fu_berlin.ties.DocumentWriter;
35  import de.fu_berlin.ties.ProcessingException;
36  import de.fu_berlin.ties.TiesConfiguration;
37  import de.fu_berlin.ties.io.DelimSepValues;
38  import de.fu_berlin.ties.io.FieldContainer;
39  import de.fu_berlin.ties.xml.dom.DOMUtils;
40  
41  /***
42   * Converts data in {@link de.fu_berlin.ties.io.DelimSepValues DSV format} (or
43   * any other {@link de.fu_berlin.ties.io.FieldContainer}s) into XML format.
44   * Optionally, all attributes can be omitted.
45   *
46   * <p>Instances of this class are not thread-safe and must be synchronized
47   * externally, if required (if setter methods are used -- otherwise this
48   * class is stateless and can be used to convert multiple documents in
49   * parallel).
50   *
51   * @author Christian Siefkes
52   * @version $Revision: 1.9 $, $Date: 2006/10/21 16:04:31 $, $Author: siefkes $
53   */
54  public class DSVtoXMLConverter extends DocumentWriter {
55  
56      /***
57       * Whether attributes are omitted.
58       */
59      private boolean omittingAttribs;
60  
61      /***
62       * The name of the root element.
63       */
64      private QName rootName;
65  
66      /***
67       * The name of elements inserted as second level; if <code>null</code>,
68       * no second level is used.
69       */
70      private QName level2Name;
71  
72  
73      /***
74       * Creates a new instance, using the {@linkplain TiesConfiguration#CONF
75       * standard configuration}.
76       *
77       * @param outExt the extension to use for output files
78       */
79      public DSVtoXMLConverter(final String outExt) {
80          this(outExt, TiesConfiguration.CONF);
81      }
82  
83      /***
84       * Creates a new instance.
85       *
86       * @param outExt the extension to use for output files
87       * @param conf used to configure this instance; must not be
88       * <code>null</code>
89       */
90      public DSVtoXMLConverter(final String outExt,
91              final TiesConfiguration conf) {
92          this(outExt, conf, DOMUtils.defaultName(conf.getString("dsv2xml.root")),
93                  conf.getBoolean("dsv2xml.attribs.omit"),
94                  DOMUtils.defaultName(conf.getString("dsv2xml.level2", null)),
95                  conf.getString("dsv2xml.level2.pattern"));
96      }
97  
98      /***
99       * Creates a new instance.
100      *
101      * @param outExt the extension to use for output files
102      * @param conf used to configure this instance; if <code>null</code>,
103      * the {@linkplain TiesConfiguration#CONF standard configuration} is used
104      * @param rootElement the name of the root element
105      * @param omitAttribs whether to omit all attributes
106      * @param secondLevelName the name of elements inserted as second level;
107      * if <code>null</code>, no second level is used
108      * @param secondLevelPattern pattern that must be matched for second-level
109      * elements to be created
110      */
111     public DSVtoXMLConverter(final String outExt, final TiesConfiguration conf,
112             final QName rootElement, final boolean omitAttribs,
113             final QName secondLevelName, final String secondLevelPattern) {
114         super(outExt, conf);
115         rootName = rootElement;
116         omittingAttribs = omitAttribs;
117         level2Name = secondLevelName;
118     }
119 
120 
121     /***
122      * Converts a field container into XML.
123      *
124      * @param data the container to convert
125      * @return the converted XML document
126      */
127     public Document convert(final FieldContainer data) {
128         // java class attribute is not used
129         final Element rootElement =
130             data.toElement(rootName, level2Name).unsetJavaClass();
131 
132         if (omittingAttribs) {
133             // recursively delete all attributes
134             DOMUtils.deleteAllAttributes(rootElement, true);
135         }
136 
137         return new DefaultDocument(rootElement);
138     }
139 
140     /***
141      * Returns the name of elements inserted as second level;
142      * if <code>null</code>, no second level is used.
143      *
144      * @return the value of the attribute
145      */
146     public QName getLevel2Name() {
147         return level2Name;
148     }
149 
150     /***
151      * Returns the name used for the root element.
152      * @return the value of the attribute
153      */
154     public QName getRootName() {
155         return rootName;
156     }
157 
158     /***
159      * Whether attributes are omitted.
160      * @return the value of the attribute
161      */
162     public boolean isOmittingAttribs() {
163         return omittingAttribs;
164     }
165 
166     /***
167      * {@inheritDoc} This implementation delegates to
168      * {@link #convert(FieldContainer)}, reading input in
169      * {@linkplain DelimSepValues DSV format}.
170      */
171     public Document process(final Reader reader, final ContextMap context)
172             throws IOException, ProcessingException {
173         // delegate to convert method, using DSV format for input
174         final FieldContainer container = new DelimSepValues(getConfig());
175         container.read(reader);
176         return convert(container);
177     }
178 
179     /***
180      * Modifies the name of elements to insert as second level;
181      * if <code>null</code>, no second level is used.
182      *
183      * @param newLevel2Name the new value of the attribute
184      */
185     public void setLevel2Name(final QName newLevel2Name) {
186         this.level2Name = newLevel2Name;
187     }
188 
189 
190     /***
191      * Specifies whether to omit attributes.
192      * @param newOmittingAttribs the new value of the attribute
193      */
194     public void setOmittingAttribs(final boolean newOmittingAttribs) {
195         this.omittingAttribs = newOmittingAttribs;
196     }
197 
198     /***
199      * Returns a string representation of this object.
200      *
201      * @return a textual representation
202      */
203     public String toString() {
204         final ToStringBuilder builder = new ToStringBuilder(this)
205             .appendSuper(super.toString())
206             .append("root name", rootName)
207             .append("omitting attributes", omittingAttribs);
208 
209         if (level2Name != null) {
210             builder.append("level 2 name", level2Name);
211         }
212 
213         return builder.toString();
214     }
215 
216 }