001: /*
002: * JavuX - Java Component Set
003: * Copyright (c) 2005-2007 Krzysztof A. Sadlocha
004: * e-mail: ksadlocha@programics.com
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or (at your option) any later version.
010: *
011: * This 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 GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020:
021: package com.javujavu.javux.proptree;
022:
023: import java.io.FileOutputStream;
024: import java.io.IOException;
025: import java.io.OutputStream;
026: import java.io.OutputStreamWriter;
027: import java.io.PrintWriter;
028: import java.io.UnsupportedEncodingException;
029: import java.util.Vector;
030:
031: /**
032: * This class saves <code>PropTree</code> trees as property tree documents<br>
033: * <br>
034: * <b>This class is NOT thread safe.</b>
035: **/
036: public class PropTreeDocWriter {
037: private int dots;
038: private int line;
039: private String indent;
040: private String assign;
041:
042: protected PrintWriter pw;
043: private String lastKey;
044: private String separator;
045:
046: public PropTreeDocWriter() {
047: dots = 0;
048: line = 1000;
049: indent = "\t";
050: assign = "= ";
051: separator = "\r\n";
052: }
053:
054: public void setRelativeDots(int relativeDotCount) {
055: this .dots = relativeDotCount;
056: }
057:
058: public void setAssignment(String assignmentOperator) {
059: this .assign = assignmentOperator;
060: }
061:
062: public void setIndent(String indent) {
063: this .indent = indent;
064: }
065:
066: public void setSeparator(String lineSeparator) {
067: this .separator = lineSeparator;
068: }
069:
070: public void setLine(int lineWidth) {
071: this .line = lineWidth;
072: }
073:
074: public void save(String fileName, PropTree tree) {
075: try {
076: FileOutputStream fos = new FileOutputStream(fileName);
077: save(fos, tree);
078: fos.close();
079: } catch (IOException e) {
080: }
081: }
082:
083: public void save(OutputStream os, PropTree tree) {
084: open(os);
085: saveNode(tree, "", false);
086:
087: flush();
088: }
089:
090: private void saveNode(PropTree node, String prefix,
091: boolean separatePrev) {
092: if (node.key != null
093: && (node.value != null || separatePrev || node
094: .childCount() == 0)) {
095: dataNode(prefix + node.key, node.value);
096: }
097: Vector v = node.all;
098: if (v == null)
099: v = node.data;
100: if (v == null)
101: return;
102: String prevKey = null;
103: String nprefix = (node.key != null) ? prefix + node.key + "."
104: : prefix;
105: PropTree n;
106: Object o;
107: for (int i = 0; i < v.size(); i++) {
108: o = v.elementAt(i);
109: if (o instanceof String) {
110: comment((String) o);
111: } else {
112: n = (PropTree) o;
113: saveNode(n, nprefix, n.key.equals(prevKey));
114: prevKey = n.key;
115: }
116: }
117: }
118:
119: private void open(OutputStream os) {
120: OutputStreamWriter osw = null;
121:
122: try {
123: osw = new OutputStreamWriter(os, "ISO8859_1");
124: } catch (UnsupportedEncodingException e) {
125: try {
126: osw = new OutputStreamWriter(os, "ISO-8859-1");
127: } catch (UnsupportedEncodingException e1) {
128: osw = new OutputStreamWriter(os);
129: }
130: }
131:
132: pw = new PrintWriter(osw);
133:
134: lastKey = "";
135: }
136:
137: public void flush() {
138: if (pw != null)
139: pw.flush();
140: }
141:
142: public void comment(String line) {
143: if (line == null || line.length() == 0)
144: println("");
145: else {
146: if (line.charAt(0) != '#')
147: pw.print('#');
148: println(line);
149: }
150: }
151:
152: public void dataNode(String fullKey, String value) {
153: int i, lx;
154: String key = fullKey;
155: if (dots > 0) {
156: int start = 0, dot, ind;
157: char c;
158: lx = Math.min(fullKey.length(), lastKey.length());
159: ind = 0;
160: for (i = 0; i < lx; i++) {
161: if ((c = fullKey.charAt(i)) != lastKey.charAt(i))
162: break;
163: if (c == '.') {
164: start = i + 1;
165: ind++;
166: }
167: }
168: if (i == lx && fullKey.length() > lx
169: && fullKey.charAt(i) == '.') {
170: start = i + 1;
171: ind++;
172: dot = 1;
173: } else {
174: dot = 2;
175: }
176:
177: if (start > 0) {
178: for (i = start, lx = lastKey.length(); i < lx; i++)
179: if (lastKey.charAt(i) == '.')
180: dot++;
181: if (dot <= this .dots) {
182: int indentLen = indent.length();
183: StringBuffer b = new StringBuffer();
184: if (indentLen > 0)
185: ind -= (dot + indentLen - 1) / indentLen;
186: else
187: ind = 0;
188: for (i = 0; i < ind; i++)
189: b.append(indent);
190: for (i = 0; i < dot; i++)
191: b.append('.');
192: if (b.length() < start) {
193: b.append(fullKey.substring(start));
194: key = b.toString();
195: }
196: }
197: }
198: }
199: pw.print(key);
200: pw.print(assign);
201: int keyLen = key.length() + assign.length();
202:
203: lastKey = fullKey;
204: int valueLen;
205: if (value == null)
206: println("");
207: else if ((valueLen = value.length()) == 0)
208: println("\"\"");
209: else {
210: value = PropTreeDocCoder.encode(value, false);
211: if (valueLen + keyLen > line) {
212: int j = 0, k, indentLen = indent.length();
213: if (keyLen + 4 < line) {
214: j = line - keyLen - 2;
215: pw.print("\"");
216: pw.print(value.substring(0, j));
217: println("\"");
218: }
219: while (valueLen - j + 2 + indentLen > line) {
220: k = j + line - 2 - indentLen;
221: pw.print(indent);
222: pw.print("\"");
223: pw.print(value.substring(j, k));
224: println("\"");
225: j = k;
226: }
227: if (j < valueLen) {
228: pw.print(indent);
229: pw.print("\"");
230: pw.print(value.substring(j));
231: println("\"");
232: }
233: } else if (value.charAt(0) == ' '
234: || value.charAt(0) == '\t'
235: || value.charAt(valueLen - 1) == ' '
236: || value.charAt(valueLen - 1) == '\t') {
237: pw.print("\"");
238: pw.print(value);
239: println("\"");
240: } else
241: println(value);
242: }
243:
244: }
245:
246: private void println(String text) {
247: pw.print(text);
248: pw.print(separator);
249: }
250: }
|