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;
00040
00041 import java.io.IOException;
00042 import java.io.Writer;
00043 import java.util.Iterator;
00044 import java.util.LinkedList;
00045 import java.util.Map;
00046 import java.util.TreeMap;
00047
00048
00049
00050
00051
00052
00053 public class XMLNode extends AbstractXMLNode
00054 {
00055 public XMLNode(final String name)
00056 {
00057 _name = name;
00058 }
00059
00060 public XMLNode(final String name, final String leading)
00061 {
00062 _name = name;
00063 _leading = leading;
00064 }
00065
00066 public XMLNode(final XMLNode other)
00067 {
00068 assign(other);
00069 }
00070
00071 protected String _name;
00072
00073 public String getName()
00074 {
00075 return _name;
00076 }
00077
00078 public String toString()
00079 {
00080 return _name;
00081 }
00082
00083
00084
00085
00086 public static class Children extends LinkedList<XMLNode>
00087 {
00088 private static final long serialVersionUID = 1L;
00089
00090 public void assign(final Children other)
00091 {
00092 this.clear();
00093
00094 for(XMLNode node : other)
00095 addLast(new XMLNode(node));
00096 }
00097
00098 public void clear()
00099 {
00100 while(!isEmpty()) {
00101 XMLNode node = getLast();
00102 removeLast();
00103
00104 node.clear();
00105 }
00106 }
00107 }
00108
00109
00110
00111
00112
00113 public static class AttributeMap extends TreeMap<String, String>
00114 {
00115 private static final long serialVersionUID = 1L;
00116 }
00117
00118 protected Children _children = new Children();
00119 protected AttributeMap _attributes = new AttributeMap();
00120
00121 protected String _leading = "";
00122 protected String _content = "";
00123 protected String _endLeading = "";
00124 protected String _trailing = "";
00125
00126 public void clear()
00127 {
00128 _leading = "";
00129 _content = "";
00130 _endLeading = "";
00131 _trailing = "";
00132
00133 _attributes.clear();
00134 _children.clear();
00135
00136 _name = "";
00137 }
00138
00139 public void assign(final XMLNode other)
00140 {
00141 _children.assign(other._children);
00142
00143 _attributes = (AttributeMap) other._attributes.clone();
00144
00145 _leading = other._leading;
00146 _content = other._content;
00147 _endLeading = other._endLeading;
00148 _trailing = other._trailing;
00149 }
00150
00151
00152 public void addChild(XMLNode child)
00153 {
00154 _children.addLast(child);
00155 }
00156
00157
00158 public String get(final String attrName)
00159 {
00160 String found = _attributes.get(attrName);
00161
00162 if (found != null)
00163 return found;
00164 else
00165 return "";
00166 }
00167
00168
00169 public String get(final String attrName, final String def)
00170 {
00171 String found = _attributes.get(attrName);
00172
00173 if (found != null)
00174 return found;
00175 else
00176 return def;
00177 }
00178
00179
00180 public void put(final String attrName, final String value)
00181 {
00182 _attributes.put(attrName, value);
00183 }
00184
00185
00186 public String getSubattrib(final String nodeName, final String attrName)
00187 {
00188 final AbstractXMLNode node = find(nodeName);
00189
00190 if (node != null)
00191 return node.get(attrName);
00192 else
00193 return "";
00194 }
00195
00196 public String getSubattrib(final String nodeName, final String attrName, int n)
00197 {
00198 final AbstractXMLNode node = find(nodeName, n);
00199
00200 if (node != null)
00201 return node.get(attrName);
00202 else
00203 return "";
00204 }
00205
00206
00207 public void putSubattrib(final String nodeName, final String attrName, final String value)
00208 {
00209 XMLNode node = find(nodeName);
00210
00211 if (node == null) {
00212 node = new XMLNode(nodeName);
00213 addChild(node);
00214 }
00215
00216 node.put(attrName, value);
00217 }
00218
00219 public void putSubattrib(final String nodeName, final String attrName, final String value, int n)
00220 {
00221 XMLNode node = find(nodeName, n);
00222
00223 if (node == null) {
00224 node = new XMLNode(nodeName);
00225 addChild(node);
00226 }
00227
00228 node.put(attrName, value);
00229 }
00230
00231 public Children getChildren()
00232 {
00233 return _children;
00234 }
00235
00236 public String getContent()
00237 {
00238 return XMLHelper.decodeXMLString(_content);
00239 }
00240
00241 public void setContent(final String s)
00242 {
00243 setContent(s, false);
00244 }
00245
00246 public void setContent(final String s, boolean cdata)
00247 {
00248 _content = XMLHelper.encodeXMLString(s, cdata);
00249 }
00250
00251
00252
00253 public static final int FORMAT_SMART = 0;
00254 public static final int FORMAT_ORIGINAL = 1;
00255 public static final int FORMAT_PRETTY = 2;
00256
00257 public void write(Writer out) throws Exception
00258 {
00259 write(out, FORMAT_SMART, 0);
00260 }
00261
00262 public void write(Writer out, int mode) throws Exception
00263 {
00264 write(out, mode, 0);
00265 }
00266
00267
00268 public void write(Writer out, int mode, int indent) throws IOException
00269 {
00270 switch(mode) {
00271 case FORMAT_PRETTY:
00272 prettyWriteWorker(out, indent);
00273 break;
00274
00275 case FORMAT_ORIGINAL:
00276 writeWorker(out, indent);
00277 break;
00278
00279 default:
00280 smartWriteWorker(out, indent);
00281 }
00282 }
00283
00284 protected XMLNode getFirstChild()
00285 {
00286 if (!_children.isEmpty())
00287 return _children.getFirst();
00288 else
00289 return null;
00290 }
00291
00292
00293
00294
00295
00296
00297 public XMLNode find(final String nodeName)
00298 {
00299 for(XMLNode child : _children)
00300 if (child._name.equals(nodeName))
00301 return child;
00302
00303 return null;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312 public XMLNode find(final String nodeName, int n)
00313 {
00314 for(XMLNode child : _children)
00315 if (child._name.equals(nodeName))
00316 if (n-- == 0)
00317 return child;
00318
00319 return null;
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329 public XMLNode find(final String nodeName, final String attrName, final String attrValue)
00330 {
00331 for(XMLNode child : _children)
00332 if (child._name.equals(nodeName) && child.get(attrName).equals(attrValue))
00333 return child;
00334
00335 return null;
00336 }
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 public XMLNode find(final String nodeName, final String attrName, final String attrValue, int n)
00347 {
00348 for(XMLNode node : _children)
00349 if (node._name.equals(nodeName) && node.get(attrName).equals(attrValue))
00350 if (n-- == 0)
00351 return node;
00352
00353 return null;
00354 }
00355
00356
00357 XMLNode findRelative(XPath xpath)
00358 {
00359 XMLNode node = this;
00360
00361 for(XPathElement xelem : xpath) {
00362 node = xelem.find(node);
00363
00364 if (node == null)
00365 break;
00366 }
00367
00368 return node;
00369 }
00370
00371
00372 AbstractXMLNode createRelative(XPath xpath)
00373 {
00374 XMLNode node = this;
00375
00376 for(XPathElement elem : xpath) {
00377 XMLNode child = elem.find(node);
00378
00379 if (child == null) {
00380 child = new XMLNode(elem._childName);
00381 node.addChild(child);
00382
00383 for(Map.Entry<String, String> it : elem._mAttrAndAttr.entrySet())
00384 put(it.getKey(), it.getValue());
00385 }
00386
00387 node = child;
00388 }
00389
00390 return node;
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400 protected void writeWorker(Writer out, int indent) throws IOException
00401 {
00402 out.write(_leading);
00403 out.write('<');
00404 out.write(XMLHelper.encodeXMLString(_name));
00405
00406 for(Map.Entry<String,String> it : _attributes.entrySet()) {
00407 String attrValue = it.getValue();
00408
00409 if (attrValue != null) {
00410 out.write(' ');
00411 out.write(XMLHelper.encodeXMLString(it.getKey()));
00412 out.write("=\"");
00413 out.write(XMLHelper.encodeXMLString(attrValue));
00414 out.write("\"");
00415 }
00416 }
00417
00418
00419 if (!_children.isEmpty() || _content.length()>0) {
00420 out.write('>');
00421 out.write(_content);
00422
00423 for(XMLNode child: _children)
00424 child.writeWorker(out, indent+1);
00425
00426 out.write(_endLeading);
00427 out.write("</");
00428 out.write(XMLHelper.encodeXMLString(_name));
00429 out.write('>');
00430 } else
00431 out.write("/>");
00432
00433 out.write(_trailing);
00434 }
00435
00436 public static final String XML_INDENT_SPACE = " ";
00437
00438 protected void prettyWriteWorker(Writer out, int indent) throws IOException
00439 {
00440 for(int i=indent; i-->0; )
00441 out.write(XML_INDENT_SPACE);
00442
00443 out.write('<');
00444 out.write(XMLHelper.encodeXMLString(_name));
00445
00446 for(Map.Entry<String,String> it : _attributes.entrySet()) {
00447 String attrValue = it.getValue();
00448
00449 if (attrValue != null) {
00450 out.write(' ');
00451 out.write(XMLHelper.encodeXMLString(it.getKey()));
00452 out.write("=\"");
00453 out.write(XMLHelper.encodeXMLString(attrValue));
00454 out.write("\"");
00455 }
00456 }
00457
00458 if (!_children.isEmpty() || _content.length()>0) {
00459 out.write(">\n");
00460
00461 for(XMLNode child : _children)
00462 child.prettyWriteWorker(out, indent+1);
00463
00464 for(int i=indent; i-->0; )
00465 out.write(XML_INDENT_SPACE);
00466
00467 out.write("</");
00468 out.write(XMLHelper.encodeXMLString(_name));
00469 out.write(">\n");
00470 } else
00471 out.write("/>\n");
00472 }
00473
00474 protected void smartWriteWorker(Writer out, int indent) throws IOException
00475 {
00476 if (_leading.length() == 0)
00477 for(int i=indent; i-->0; )
00478 out.write(XML_INDENT_SPACE);
00479 else
00480 out.write(_leading);
00481
00482 out.write('<');
00483 out.write(XMLHelper.encodeXMLString(_name));
00484
00485 for(Map.Entry<String,String> it : _attributes.entrySet()) {
00486 String attrValue = it.getValue();
00487
00488 if (attrValue != null) {
00489 out.write(' ');
00490 out.write(XMLHelper.encodeXMLString(it.getKey()));
00491 out.write("=\"");
00492 out.write(XMLHelper.encodeXMLString(attrValue));
00493 out.write("\"");
00494 }
00495 }
00496
00497 if (_children.isEmpty() && _content.length()==0)
00498 out.write("/>");
00499 else {
00500 out.write('>');
00501
00502 if (_content.length() == 0)
00503 out.write('\n');
00504 else
00505 out.write(_content);
00506
00507 Iterator<XMLNode> it = _children.iterator();
00508
00509 if (it.hasNext()) {
00510 while(it.hasNext())
00511 it.next().smartWriteWorker(out, indent+1);
00512
00513 if (_endLeading.length() == 0)
00514 for(int i=indent; i-->0; )
00515 out.write(XML_INDENT_SPACE);
00516 else
00517 out.write(_endLeading);
00518 } else
00519 out.write(_endLeading);
00520
00521 out.write("</");
00522 out.write(XMLHelper.encodeXMLString(_name));
00523 out.write('>');
00524 }
00525
00526 if (_trailing.length() == 0)
00527 out.write('\n');
00528 else
00529 out.write(_trailing);
00530 }
00531 }