1e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov/******************************************************************************* 2b9d1b54e300318b470d9fedccc69d75187016444Evgeny Mandrikov * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors 3e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * All rights reserved. This program and the accompanying materials 4e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * are made available under the terms of the Eclipse Public License v1.0 5e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * which accompanies this distribution, and is available at 6e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * http://www.eclipse.org/legal/epl-v10.html 7e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 8e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Contributors: 9e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Marc R. Hoffmann - initial API and implementation 10e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 11e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov *******************************************************************************/ 12e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovpackage org.jacoco.report.internal.xml; 13e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 14e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovimport static java.lang.String.format; 15e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 16e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovimport java.io.IOException; 17e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovimport java.io.Writer; 18e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 19e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov/** 20e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Simple API to create well formed XML streams. A {@link XMLElement} instance 21e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * represents a single element in a XML document. 22e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 23e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @see XMLDocument 24e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 25e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovpublic class XMLElement { 26e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 27e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private static final char SPACE = ' '; 28e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 29e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private static final char EQ = '='; 30e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 31e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private static final char LT = '<'; 32e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 33e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private static final char GT = '>'; 34e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 35e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private static final char QUOT = '"'; 36e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 37e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private static final char AMP = '&'; 38e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 39e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private static final char SLASH = '/'; 40e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 41e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** Writer for content output */ 42e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov protected final Writer writer; 43e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 44e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private final String name; 45e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 46e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private boolean openTagDone; 47e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 48e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private boolean closed; 49e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 50e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private XMLElement lastchild; 51e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 52e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 53e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Creates a new element for a XML document. 54e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 55e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param writer 56e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * all output will be written directly to this 57e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param name 58e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * element name 59e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 60e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov protected XMLElement(final Writer writer, final String name) { 61e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov this.writer = writer; 62e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov this.name = name; 63e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov this.openTagDone = false; 64e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov this.closed = false; 65e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov this.lastchild = null; 66e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 67e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 68e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 69e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Emits the beginning of the open tag. This method has to be called before 70e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * other other methods are called on this element. 71e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 72e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @throws IOException 73e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * in case of problems with the writer 74e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 75e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov protected void beginOpenTag() throws IOException { 76e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write(LT); 77e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write(name); 78e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 79e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 80e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private void finishOpenTag() throws IOException { 81e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov if (!openTagDone) { 82e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.append(GT); 83e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov openTagDone = true; 84e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 85e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 86e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 87e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 88e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Adds the given child to this element. This will close all previous child 89e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * elements. 90e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 91e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param child 92e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * child element to add 93e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @throws IOException 94e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * in case of invalid nesting or problems with the writer 95e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 96e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov protected void addChildElement(final XMLElement child) throws IOException { 97e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov if (closed) { 98e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov throw new IOException(format("Element %s already closed.", name)); 99e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 100e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov finishOpenTag(); 101e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov if (lastchild != null) { 102e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov lastchild.close(); 103e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 104e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov child.beginOpenTag(); 105e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov lastchild = child; 106e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 107e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 108e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private void quote(final String text) throws IOException { 109e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov final int len = text.length(); 110e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov for (int i = 0; i < len; i++) { 111e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov final char c = text.charAt(i); 112e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov switch (c) { 113e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov case LT: 114e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write("<"); 115e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov break; 116e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov case GT: 117e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write(">"); 118e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov break; 119e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov case QUOT: 120e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write("""); 121e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov break; 122e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov case AMP: 123e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write("&"); 124e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov break; 125e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov default: 126e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write(c); 127e35a34adcc3a47eac6723533e811e52c288d4dd5Mirko Friedenhagen break; 128e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 129e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 130e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 131e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 132e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 133e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Adds an attribute to this element. May only be called before an child 134e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * element is added or this element has been closed. The attribute value 135e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * will be quoted. If the value is <code>null</code> the attribute will not 136e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * be added. 137e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 138e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param name 139e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * attribute name 140e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param value 141e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * attribute value or <code>null</code> 142e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 143e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @return this element 144e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @throws IOException 145e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * in case of problems with the writer 146e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 147e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public XMLElement attr(final String name, final String value) 148e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov throws IOException { 149e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov if (value == null) { 150e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov return this; 151e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 152e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov if (closed || openTagDone) { 153e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov throw new IOException(format("Element %s already closed.", 154e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov this.name)); 155e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 156e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write(SPACE); 157e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write(name); 158e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write(EQ); 159e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write(QUOT); 160e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov quote(value); 161e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write(QUOT); 162e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov return this; 163e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 164e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 165e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 166e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Adds an attribute to this element. May only be called before an child 167e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * element is added or this element has been closed. The attribute value is 168e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * the decimal representation of the given int value. 169e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 170e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param name 171e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * attribute name 172e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param value 173e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * attribute value 174e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 175e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @return this element 176e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @throws IOException 177e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * in case of problems with the writer 178e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 179e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public XMLElement attr(final String name, final int value) 180e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov throws IOException { 181e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov return attr(name, String.valueOf(value)); 182e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 183e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 184e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 185e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Adds an attribute to this element. May only be called before an child 186e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * element is added or this element has been closed. The attribute value is 187e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * the decimal representation of the given long value. 188e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 189e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param name 190e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * attribute name 191e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param value 192e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * attribute value 193e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 194e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @return this element 195e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @throws IOException 196e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * in case of problems with the writer 197e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 198e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public XMLElement attr(final String name, final long value) 199e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov throws IOException { 200e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov return attr(name, String.valueOf(value)); 201e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 202e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 203e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 204e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Adds the given text as a child to this node. The text will be quoted. 205e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 206e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param text 207e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * text to add 208e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @return this element 209e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @throws IOException 210e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * in case of problems with the writer 211e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 212e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public XMLElement text(final String text) throws IOException { 213e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov if (closed) { 214e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov throw new IOException(format("Element %s already closed.", name)); 215e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 216e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov finishOpenTag(); 217e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov if (lastchild != null) { 218e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov lastchild.close(); 219e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 220e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov quote(text); 221e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov return this; 222e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 223e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 224e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 225e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Creates a new child element for this element, 226e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 227e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param name 228e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * name of the child element 229e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @return child element instance 230e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @throws IOException 231e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * in case of problems with the writer 232e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 233e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public XMLElement element(final String name) throws IOException { 234e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov final XMLElement element = new XMLElement(writer, name); 235e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov addChildElement(element); 236e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov return element; 237e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 238e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 239e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 240e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Closes this element if it has not been closed before. 241e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 242e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @throws IOException 243e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * in case of problems with the writer 244e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 245e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public void close() throws IOException { 246e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov if (!closed) { 247e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov if (lastchild != null) { 248e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov lastchild.close(); 249e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 250e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov if (openTagDone) { 251e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write(LT); 252e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write(SLASH); 253e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write(name); 254e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } else { 255e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write(SLASH); 256e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 257e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov writer.write(GT); 258e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov closed = true; 259e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov openTagDone = true; 260e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 261e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 262e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 263e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov} 264