Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 package de.mfuchs.xmlstorage.stream;
00040
00041 import java.io.BufferedWriter;
00042 import java.io.FileWriter;
00043 import java.io.IOException;
00044 import java.io.Writer;
00045 import java.util.Map;
00046 import java.util.Stack;
00047
00048 import de.mfuchs.xmlstorage.XMLHeader;
00049 import de.mfuchs.xmlstorage.XMLHelper;
00050 import de.mfuchs.xmlstorage.XMLNode;
00051
00052
00053
00054
00055
00056 public class XMLStreamWriter
00057 {
00058
00059 public static final int PRETTY_PLAIN = 0;
00060 public static final int PRETTY_LINEFEED = 1;
00061 public static final int PRETTY_INDENT = 2;
00062
00063
00064 public XMLStreamWriter(Writer out) throws IOException
00065 {
00066 this(out, PRETTY_INDENT, new XMLHeader());
00067 }
00068
00069 public XMLStreamWriter(final String path) throws IOException
00070 {
00071 this(path, PRETTY_INDENT, new XMLHeader());
00072 }
00073
00074 public XMLStreamWriter(Writer out, int pretty, final XMLHeader header) throws IOException
00075 {
00076 _out = out;
00077 _pretty = pretty;
00078
00079 header.print(_out, false);
00080 }
00081
00082 public XMLStreamWriter(final String path, int pretty, final XMLHeader header) throws IOException
00083 {
00084 _out = new BufferedWriter(new FileWriter(path));
00085 _pretty = pretty;
00086
00087 header.print(_out, false);
00088 }
00089
00090 public void close() throws IOException
00091 {
00092 _out.write('\n');
00093 _out.close();
00094 }
00095
00096
00097 public void create(final String name) throws IOException
00098 {
00099 if (!_stack.empty()) {
00100 StackEntry last = (StackEntry) _stack.peek();
00101
00102 if (last._state < PRE_CLOSED) {
00103 writeAttributes(last);
00104 closePre(last);
00105 }
00106
00107 last._children = true;
00108 }
00109
00110 StackEntry entry = new StackEntry(name);
00111 _stack.push(entry);
00112
00113 writePre(entry);
00114 }
00115
00116
00117 public boolean back() throws IOException
00118 {
00119 if (!_stack.empty()) {
00120 writePost((StackEntry)_stack.peek());
00121
00122 _stack.pop();
00123
00124 return true;
00125 } else
00126 return false;
00127 }
00128
00129
00130 public void put(String attrName, Object value)
00131 {
00132 if (!_stack.empty()) {
00133 XMLNode.AttributeMap attributes = ((StackEntry)_stack.peek())._attributes;
00134
00135 if (value != null)
00136 attributes.put(attrName, value.toString());
00137 else
00138 attributes.remove(attrName);
00139 }
00140 }
00141
00142
00143 public void put(String attrName, String value)
00144 {
00145 if (!_stack.empty()) {
00146 XMLNode.AttributeMap attributes = ((StackEntry)_stack.peek())._attributes;
00147
00148 if (value != null)
00149 attributes.put(attrName, value);
00150 else
00151 attributes.remove(attrName);
00152 }
00153 }
00154
00155 public void setContent(final String s)
00156 {
00157 setContent(s, false);
00158 }
00159
00160 public void setContent(final String s, boolean cdata)
00161 {
00162 if (!_stack.empty())
00163 ((StackEntry)_stack.peek())._content = s!=null? XMLHelper.encodeXMLString(s, cdata): "";
00164 }
00165
00166
00167 protected static final int NOTHING = 0;
00168
00169 protected static final int ATTRIBUTES = 2;
00170 protected static final int PRE_CLOSED = 3;
00171
00172 protected static final int POST = 5;
00173
00174 protected Writer _out;
00175 protected int _pretty;
00176
00177
00178
00179
00180 protected static class StackEntry {
00181 final String _nodeName;
00182 XMLNode.AttributeMap _attributes = new XMLNode.AttributeMap();
00183 String _content = "";
00184 int _state;
00185 boolean _children;
00186
00187 StackEntry(String nodeName)
00188 {
00189 _nodeName = nodeName;
00190 _children = false;
00191 _state = NOTHING;
00192 }
00193 };
00194
00195 protected Stack<StackEntry> _stack = new Stack<StackEntry>();
00196
00197
00198
00199 protected void closePre(StackEntry entry) throws IOException
00200 {
00201 _out.write('>');
00202
00203 entry._state = PRE_CLOSED;
00204 }
00205
00206 protected void writePre(StackEntry entry) throws IOException
00207 {
00208 if (_pretty >= PRETTY_LINEFEED)
00209 _out.write('\n');
00210
00211 if (_pretty == PRETTY_INDENT)
00212 for(int i=_stack.size(); --i>0; )
00213 _out.write(XMLNode.XML_INDENT_SPACE);
00214
00215 _out.write("<" + XMLHelper.encodeXMLString(entry._nodeName));
00216
00217 }
00218
00219 protected void writeAttributes(StackEntry entry) throws IOException
00220 {
00221 for(Map.Entry<String,String> it: entry._attributes.entrySet())
00222 _out.write(" " + XMLHelper.encodeXMLString(it.getKey()) +
00223 "=\"" + XMLHelper.encodeXMLString(it.getValue()) + "\"");
00224
00225 entry._state = ATTRIBUTES;
00226 }
00227
00228 protected void writePost(StackEntry entry) throws IOException
00229 {
00230 if (entry._state < ATTRIBUTES)
00231 writeAttributes(entry);
00232
00233 if (entry._children || entry._content.length()>0) {
00234 if (entry._state < PRE_CLOSED)
00235 closePre(entry);
00236
00237 _out.write(entry._content);
00238
00239
00240 if (_pretty>=PRETTY_LINEFEED && entry._content.length()==0)
00241 _out.write('\n');
00242
00243 if (_pretty==PRETTY_INDENT && entry._content.length()==0)
00244 for(int i=_stack.size(); --i>0; )
00245 _out.write(XMLNode.XML_INDENT_SPACE);
00246
00247 _out.write("</" + XMLHelper.encodeXMLString(entry._nodeName) + ">");
00248 } else {
00249 _out.write("/>");
00250 }
00251
00252 entry._state = POST;
00253 }
00254 }