001: /*
002: * $Header: /cvsroot/mvnforum/mvnforum/src/com/mvnforum/admin/importexport/XMLWriter.java,v 1.7 2007/01/15 10:27:01 dungbtm Exp $
003: * $Author: dungbtm $
004: * $Revision: 1.7 $
005: * $Date: 2007/01/15 10:27:01 $
006: *
007: * ====================================================================
008: *
009: * Copyright (C) 2002-2007 by MyVietnam.net
010: *
011: * All copyright notices regarding mvnForum MUST remain
012: * intact in the scripts and in the outputted HTML.
013: * The "powered by" text/logo with a link back to
014: * http://www.mvnForum.com and http://www.MyVietnam.net in
015: * the footer of the pages MUST remain visible when the pages
016: * are viewed on the internet or intranet.
017: *
018: * This program is free software; you can redistribute it and/or modify
019: * it under the terms of the GNU General Public License as published by
020: * the Free Software Foundation; either version 2 of the License, or
021: * any later version.
022: *
023: * This program is distributed in the hope that it will be useful,
024: * but WITHOUT ANY WARRANTY; without even the implied warranty of
025: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
026: * GNU General Public License for more details.
027: *
028: * You should have received a copy of the GNU General Public License
029: * along with this program; if not, write to the Free Software
030: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
031: *
032: * Support can be obtained from support forums at:
033: * http://www.mvnForum.com/mvnforum/index
034: *
035: * Correspondence and Marketing Questions can be sent to:
036: * info at MyVietnam net
037: *
038: * @author: Igor Manic
039: */
040: package com.mvnforum.admin.importexport;
041:
042: import java.io.*;
043:
044: import org.apache.commons.logging.Log;
045: import org.apache.commons.logging.LogFactory;
046: import net.myvietnam.mvncore.exception.ExportException;
047:
048: /**
049: * @author Igor Manic
050: * @version $Revision: 1.7 $, $Date: 2007/01/15 10:27:01 $
051: * <br/>
052: * <code>XMLWriter</code> class encapsulates methods for creating and writing
053: * data to XML files with automatic indentation and special characters encoding.
054: */
055: public class XMLWriter {
056:
057: /** Message log. */
058: private static Log log = LogFactory.getLog(XMLWriter.class);
059:
060: private static String lineSeparator = System.getProperty(
061: "line.separator", "\n");
062: private StringBuffer textBuffer;
063: private int indentLevel = 0; //current XML element level
064: private String indentString = ""; //indent string for each next level of XML output
065: private OutputStreamWriter outWriter = null;
066: private boolean startedNewElement = false;
067:
068: private XMLWriter() {
069: super ();
070: textBuffer = null;
071: indentLevel = 0;
072: indentString = "";
073: outWriter = null;
074: startedNewElement = false;
075: }
076:
077: public XMLWriter(String indentString, OutputStreamWriter outWriter) {
078: this ();
079: this .indentString = indentString;
080: this .outWriter = outWriter;
081: }
082:
083: public XMLWriter(String indentString, File outputFile)
084: throws ExportException {
085: this ();
086: this .indentString = indentString;
087: log.debug("Setting output to file \""
088: + outputFile.getAbsolutePath() + "\"");
089: if (!outputFile.exists())
090: try {
091: outputFile.createNewFile();
092: } catch (IOException e) {
093: log.error("XML output could not be created.");
094: throw new ExportException("Error on server: "
095: + "Can't make XML output file.", e);
096: }
097: else if (!outputFile.isFile()) {
098: log
099: .error("XML output is not a file (it's probably directory).");
100: throw new ExportException(
101: "Error on server: "
102: + "XML output is not a file (it's probably directory).");
103: }
104: if (!outputFile.canWrite()) {
105: log.error("XML output file can't be written to.");
106: throw new ExportException("Error on server: "
107: + "XML output file can't be written to.");
108: } else {
109: try {
110: java.io.OutputStream outStream = new FileOutputStream(
111: outputFile);
112: this .outWriter = new OutputStreamWriter(outStream,
113: "UTF8");
114: } catch (FileNotFoundException e) {
115: log.error("XML output file can't be found.");
116: throw new ExportException("Error on server: "
117: + "XML output file can't be found.", e);
118: } catch (UnsupportedEncodingException e) {
119: log
120: .error("UTF8 is unsupported encoding for XML output.");
121: throw new ExportException("Error on server: "
122: + "Can't make XML output file.", e);
123: }
124: }
125: }
126:
127: public XMLWriter(String indentString, String fileName)
128: throws ExportException {
129: this (indentString, new File(fileName));
130: }
131:
132: public void close() throws IOException {
133: outputFlush();
134: if (outWriter != null)
135: outWriter.close();
136: }
137:
138: public void startDocument(String dtdschemaDecl) throws IOException {
139: String xmlDecl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
140: startedNewElement = false;
141: outputText(xmlDecl);
142: outputNewLine();
143: outputText(dtdschemaDecl);
144: outputNewLine();
145: }
146:
147: public void endDocument() throws IOException {
148: processBufferedData();
149: outputNewLine();
150: outputFlush();
151: }
152:
153: public void startElement(String elementName) throws IOException {
154: startElement(elementName, null);
155: }
156:
157: public void startElement(String elementName, String[] attrNameValue)
158: throws IOException {
159: processBufferedData();
160: outputNewLine();
161: outputText("<" + elementName);
162: if (attrNameValue != null)
163: for (int i = 0; i < attrNameValue.length - 1; i += 2) {
164: String attrName = attrNameValue[i];
165: String attrValue = attrNameValue[i + 1];
166: outputText(" ");
167: outputText(attrName + "=\"" + attrValue + "\"");
168: }
169: outputText(">");
170: indentLevel++;
171: //outputNewLine();
172: startedNewElement = true;
173: }
174:
175: public void endElement(String elementName) throws IOException {
176: processBufferedData();
177: indentLevel--;
178: if (!startedNewElement)
179: outputNewLine();
180: outputText("</" + elementName + ">");
181: //outputNewLine();
182: startedNewElement = false;
183: }
184:
185: public void writeNewLine() throws IOException {
186: outputNewLine();
187: }
188:
189: public void writeComment(String comment) throws IOException {
190: processBufferedData();
191: /*if (startedNewElement)*/outputNewLine();
192: outputText("<!-- " + comment + " -->");
193: //startedNewElement=false; I should leave this variable, otherwise, if
194: //I have more comments one behind another, they'll all be output in
195: //one row, one to another, which is bad
196: }
197:
198: public void writeData(String data) throws IOException {
199: if (textBuffer == null) {
200: textBuffer = new StringBuffer(data);
201: } else {
202: textBuffer.append(data);
203: }
204: }
205:
206: public void encodeAndWriteData(String data) throws IOException {
207: //we should encode all '<' and '&'
208: int amp = data.indexOf('&');
209: int lt = data.indexOf('<');
210: int i = -1;
211: if ((amp >= 0) && (lt >= 0))
212: i = (amp < lt) ? amp : lt;
213: else if (amp >= 0)
214: i = amp;
215: else
216: i = lt;
217: while ((i < data.length()) && (i >= 0)) {
218: if (i == amp) {
219: data = data.substring(0, i) + "&"
220: + data.substring(i + 1);
221: amp = data.indexOf('&', i + 4);
222: lt = data.indexOf('<', i + 4);
223: i += 4; //it should be 5, but nevermind
224: } else if (i == lt) {
225: data = data.substring(0, i) + "<"
226: + data.substring(i + 1);
227: amp = data.indexOf('&', i + 3);
228: lt = data.indexOf('<', i + 3);
229: i += 3; //it should be 5, but nevermind
230: } else {
231: log.error("processBufferedRawText(): i==" + i
232: + " is different than both amp==" + amp
233: + " and lt==" + lt + "?!");
234: i++;
235: amp = data.indexOf('&', i);
236: lt = data.indexOf('<', i);
237: }
238: if ((amp >= 0) && (lt >= 0))
239: i = (amp < lt) ? amp : lt;
240: else if (amp >= 0)
241: i = amp;
242: else
243: i = lt;
244: }
245:
246: writeData(data);
247: }
248:
249: // ========================================================
250: // =================== RAW TEXT OUTPUT ====================
251: // ========================================================
252:
253: private void processBufferedData() throws IOException {
254: if (textBuffer == null)
255: return;
256: String s = "" + textBuffer;
257: if (!s.trim().equals(""))
258: textBuffer = null;
259: if (s.equals(""))
260: return;
261:
262: if (startedNewElement)
263: outputNewLine();
264: startedNewElement = false;
265: String padding = "";
266: for (int i = 0; i < indentLevel; i++)
267: padding = padding + indentString;
268: int pos = s.indexOf(lineSeparator);
269: while ((pos < s.length()) && (pos >= 0)) {
270: s = s.substring(0, pos) + lineSeparator + padding
271: + s.substring(pos + lineSeparator.length());
272: pos = s
273: .indexOf(lineSeparator, pos
274: + lineSeparator.length());
275: }
276: outputText(s);
277: }
278:
279: private void outputText(String s) throws IOException {
280: if (outWriter == null) {
281: log.error("outputText(): outWriter==null.");
282: } else {
283: outWriter.write(s);
284: }
285: }
286:
287: private void outputFlush() throws IOException {
288: if (outWriter == null) {
289: log.error("outputFlush(): outWriter==null.");
290: } else {
291: outWriter.flush();
292: }
293: }
294:
295: private void outputNewLine() throws IOException {
296: if (outWriter == null) {
297: log.error("outputNewLine(): outWriter==null.");
298: } else {
299: outWriter.write(lineSeparator);
300: for (int i = 0; i < indentLevel; i++)
301: outWriter.write(indentString);
302: }
303: }
304:
305: }
|