001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005: package org.vfny.geoserver.global.xml;
006:
007: import org.vfny.geoserver.global.ConfigurationException;
008: import java.io.IOException;
009: import java.io.Writer;
010: import java.util.Collections;
011: import java.util.Iterator;
012: import java.util.Map;
013: import java.util.logging.Logger;
014:
015: /**
016: * WriterUtils purpose.
017: *
018: * <p>
019: * Used to provide assitance writing xml to a Writer.
020: * </p>
021: *
022: * <p></p>
023: *
024: * @author dzwiers, Refractions Research, Inc.
025: * @version $Id: WriterHelper.java 8482 2008-02-29 04:59:42Z arneke $
026: */
027: public class WriterHelper {
028: /** Used internally to create log information to detect errors. */
029: private static final Logger LOGGER = org.geotools.util.logging.Logging
030: .getLogger("org.vfny.geoserver.global");
031:
032: /** The output writer. */
033: protected Writer writer;
034: protected int indent;
035: protected StringBuffer indentBuffer = new StringBuffer();
036:
037: /**
038: * WriterUtils constructor.
039: *
040: * <p>
041: * Should never be called.
042: * </p>
043: */
044: protected WriterHelper() {
045: }
046:
047: /**
048: * WriterUtils constructor.
049: *
050: * <p>
051: * Stores the specified writer to use for output.
052: * </p>
053: *
054: * @param writer the writer which will be used for outputing the xml.
055: */
056: public WriterHelper(Writer writer) {
057: this .writer = writer;
058: }
059:
060: /**
061: * writeln purpose.
062: *
063: * <p>
064: * Writes the String specified to the stored output writer.
065: * </p>
066: *
067: * @param s The String to write.
068: *
069: * @throws ConfigurationException When an IO exception occurs.
070: */
071: public void writeln(String s) throws ConfigurationException {
072: try {
073: writer
074: .write(indentBuffer.subSequence(0, indent) + s
075: + "\n");
076: writer.flush();
077: } catch (IOException e) {
078: throw new ConfigurationException("Writeln" + writer, e);
079: }
080: }
081:
082: private void increaseIndent() {
083: indent += 2;
084: indentBuffer.append(" ");
085: }
086:
087: private void decreaseIndent() {
088: if (indent > 0) {
089: indent -= 2;
090: indentBuffer.setLength(indentBuffer.length() - 2);
091: }
092: }
093:
094: /**
095: * openTag purpose.
096: *
097: * <p>
098: * Writes an open xml tag with the name specified to the stored output
099: * writer.
100: * </p>
101: *
102: * @param tagName The tag name to write.
103: *
104: * @throws ConfigurationException When an IO exception occurs.
105: */
106: public void openTag(String tagName) throws ConfigurationException {
107: openTag(tagName, Collections.EMPTY_MAP);
108: }
109:
110: /**
111: * openTag purpose.
112: *
113: * <p>
114: * Writes an open xml tag with the name and attributes specified to the
115: * stored output writer.
116: * </p>
117: *
118: * @param tagName The tag name to write.
119: * @param attributes The tag attributes to write.
120: *
121: * @throws ConfigurationException When an IO exception occurs.
122: */
123: public void openTag(String tagName, Map attributes)
124: throws ConfigurationException {
125: StringBuffer sb = new StringBuffer();
126: sb.append("<" + tagName + " ");
127:
128: Iterator i = attributes.keySet().iterator();
129:
130: while (i.hasNext()) {
131: String s = (String) i.next();
132:
133: if (attributes.get(s) != null) {
134: sb.append(s + " = " + "\""
135: + escape((attributes.get(s)).toString())
136: + "\" ");
137: }
138: }
139:
140: sb.append(">");
141: writeln(sb.toString());
142: increaseIndent();
143: }
144:
145: /**
146: * closeTag purpose.
147: *
148: * <p>
149: * Writes an close xml tag with the name specified to the stored output
150: * writer.
151: * </p>
152: *
153: * @param tagName The tag name to write.
154: *
155: * @throws ConfigurationException When an IO exception occurs.
156: */
157: public void closeTag(String tagName) throws ConfigurationException {
158: decreaseIndent();
159: writeln("</" + tagName + ">");
160: }
161:
162: /**
163: * valueTag purpose.
164: *
165: * <p>
166: * Writes an xml tag with the name and value specified to the stored output
167: * writer.
168: * </p>
169: *
170: * @param tagName The tag name to write.
171: * @param value The text data to write.
172: *
173: * @throws ConfigurationException When an IO exception occurs.
174: */
175: public void valueTag(String tagName, String value)
176: throws ConfigurationException {
177: writeln("<" + tagName + " value = \"" + escape(value) + "\" />");
178: }
179:
180: /**
181: * attrTag purpose.
182: *
183: * <p>
184: * Writes an xml tag with the name and attributes specified to the stored
185: * output writer.
186: * </p>
187: *
188: * @param tagName The tag name to write.
189: * @param attributes The tag attributes to write.
190: *
191: * @throws ConfigurationException When an IO exception occurs.
192: */
193: public void attrTag(String tagName, Map attributes)
194: throws ConfigurationException {
195: StringBuffer sb = new StringBuffer();
196: sb.append("<" + tagName + " ");
197:
198: Iterator i = attributes.keySet().iterator();
199:
200: while (i.hasNext()) {
201: String s = (String) i.next();
202:
203: if (attributes.get(s) != null) {
204: sb.append(s + " = " + "\""
205: + escape((attributes.get(s)).toString())
206: + "\" ");
207: }
208: }
209:
210: sb.append("/>");
211: writeln(sb.toString());
212: }
213:
214: /**
215: * textTag purpose.
216: *
217: * <p>
218: * Writes a text xml tag with the name and text specified to the stored
219: * output writer.
220: * </p>
221: *
222: * @param tagName The tag name to write.
223: * @param data The text data to write.
224: *
225: * @throws ConfigurationException When an IO exception occurs.
226: */
227: public void textTag(String tagName, String data)
228: throws ConfigurationException {
229: textTag(tagName, Collections.EMPTY_MAP, data);
230: }
231:
232: /**
233: * textTag purpose.
234: *
235: * <p>
236: * Writes an xml tag with the name, text and attributes specified to the
237: * stored output writer.
238: * </p>
239: *
240: * @param tagName The tag name to write.
241: * @param attributes The tag attributes to write.
242: * @param data The tag text to write.
243: *
244: * @throws ConfigurationException When an IO exception occurs.
245: */
246: public void textTag(String tagName, Map attributes, String data)
247: throws ConfigurationException {
248: StringBuffer sb = new StringBuffer();
249: sb.append("<" + tagName + ((attributes.size() > 0) ? " " : ""));
250:
251: Iterator i = attributes.keySet().iterator();
252:
253: while (i.hasNext()) {
254: String s = (String) i.next();
255:
256: if (attributes.get(s) != null) {
257: sb.append(s + " = " + "\""
258: + escape((attributes.get(s)).toString())
259: + "\" ");
260: }
261: }
262:
263: String escapedData = "";
264: if (data != null)
265: escapedData = escape(data);
266: sb.append(">" + escapedData + "</" + tagName + ">");
267: writeln(sb.toString());
268: }
269:
270: /**
271: * comment purpose.
272: *
273: * <p>
274: * Writes an xml comment with the text specified to the stored output
275: * writer.
276: * </p>
277: *
278: * @param comment The comment text to write.
279: *
280: * @throws ConfigurationException When an IO exception occurs.
281: */
282: public void comment(String comment) throws ConfigurationException {
283: writeln("<!--");
284: increaseIndent();
285:
286: String ib = indentBuffer.substring(0, indent);
287: comment = comment.trim();
288: comment = comment.replaceAll("\n", "\n" + ib);
289: writeln(comment);
290: decreaseIndent();
291: writeln("-->");
292: }
293:
294: /**
295: * Escapes the provided text with XML entities,
296: * see (http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Character_entities_in_XML)
297: * @param text
298: * @return
299: */
300: private String escape(String text) {
301: String s = new String(text);
302:
303: // All redundant carriage returns should already have been stripped.
304: s = s.replaceAll("\r\n", "\n");
305:
306: if (s.matches("(.*)[\"&'<>]*(.*)(\\n)*")) {
307: s = s.replaceAll("\"", """);
308: s = s.replaceAll("&", "&");
309: s = s.replaceAll("'", "'");
310: s = s.replaceAll("<", "<");
311: s = s.replaceAll(">", ">");
312: }
313: return s;
314: }
315: }
|