001: /*
002: * TagWriter.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.db.report;
013:
014: import java.util.ArrayList;
015: import java.util.Collection;
016: import java.util.List;
017: import workbench.util.StrBuffer;
018: import workbench.util.StringUtil;
019:
020: /**
021: * Utility class to add XML tags to a StrBuffer.
022: * Handles namespaces for the tags as well.
023: * @author support@sql-workbench.net
024: */
025: public class TagWriter {
026: public static final String CDATA_START = "<![CDATA[";
027: public static final String CDATA_END = "]]>";
028:
029: private String xmlNamespace = null;
030:
031: public TagWriter() {
032: }
033:
034: public TagWriter(String ns) {
035: this .xmlNamespace = ns;
036: }
037:
038: /**
039: * Appends an integer value for a tag in one line. There will be a new line
040: * after the closing tag.
041: */
042: public void appendTag(StrBuffer target, StrBuffer indent,
043: String tag, int value) {
044: appendTag(target, indent, tag, String.valueOf(value), false);
045: }
046:
047: /**
048: * Appends a boolean value for a tag in one line. There will be a new line
049: * after the closing tag.
050: */
051: public void appendTag(StrBuffer target, StrBuffer indent,
052: String tag, boolean value) {
053: if (value)
054: appendTag(target, indent, tag, "true", false);
055: else
056: appendTag(target, indent, tag, "false", false);
057: }
058:
059: /**
060: * Appends the tag and the value in one line. There will be a new line
061: * after the closing tag.
062: */
063: public void appendTag(StrBuffer target, StrBuffer indent,
064: String tag, CharSequence value) {
065: appendTag(target, indent, tag, value, false);
066: }
067:
068: public void appendTagConditionally(StrBuffer target,
069: StrBuffer indent, String tag, String value) {
070: if (!StringUtil.isEmptyString(value))
071: appendTag(target, indent, tag, value, false);
072: }
073:
074: public void appendTag(StrBuffer target, StrBuffer indent,
075: String tag, CharSequence value, String attr, String attValue) {
076: appendOpenTag(target, indent, tag, attr, attValue);
077: target.append(value);
078: appendCloseTag(target, null, tag);
079: }
080:
081: /**
082: * Appends the tag and the value in one line. There will be a new line
083: * after the closing tag. If checkCData is true, then the value
084: * is checked for characters which require a <![CDATA[ "quoting"
085: */
086: public void appendTag(StrBuffer target, StrBuffer indent,
087: String tag, CharSequence value, boolean checkCData) {
088: appendOpenTag(target, indent, tag);
089: boolean useCData = checkCData && needsCData(value);
090: if (useCData) {
091: target.append(CDATA_START);
092: target.append('\n');
093: }
094: target.append(value);
095: if (useCData) {
096: target.append(CDATA_END);
097: target.append('\n');
098: target.append(indent);
099: }
100: appendCloseTag(target, null, tag);
101: }
102:
103: /**
104: * Appends the tag and the value in one line. There will be a new line
105: * after the closing tag.
106: */
107: public void appendEmptyTag(StrBuffer target, StrBuffer indent,
108: String tag, String attribute, String attValue) {
109: appendOpenTag(target, indent, tag, false, new TagAttribute(
110: attribute, attValue));
111: target.append("/>");
112: }
113:
114: public void appendOpenTag(StrBuffer target, StrBuffer indent,
115: String tag) {
116: this .appendOpenTag(target, indent, tag, null, true);
117: }
118:
119: public void appendOpenTag(StrBuffer target, StrBuffer indent,
120: String tag, String attribute, String attValue) {
121: appendOpenTag(target, indent, tag, true, new TagAttribute(
122: attribute, attValue));
123: }
124:
125: public void appendOpenTag(StrBuffer target, StrBuffer indent,
126: String tag, String[] attributes, String[] values) {
127: appendOpenTag(target, indent, tag, attributes, values, true);
128: }
129:
130: /**
131: * Appends a opening tag to the target buffer including attributes.
132: * No new line will be written
133: */
134: public void appendOpenTag(StrBuffer target, StrBuffer indent,
135: String tag, String[] attributes, String[] values,
136: boolean closeTag) {
137: List<TagAttribute> att = null;
138: if (attributes != null) {
139: att = new ArrayList<TagAttribute>(attributes.length);
140: for (int i = 0; i < attributes.length; i++) {
141: att.add(new TagAttribute(attributes[i], values[i]));
142: }
143: }
144: appendOpenTag(target, indent, tag, att, closeTag);
145: }
146:
147: public void appendOpenTag(StrBuffer target, StrBuffer indent,
148: String tag, Collection<TagAttribute> attributes,
149: boolean closeTag) {
150: if (indent != null)
151: target.append(indent);
152: target.append('<');
153: if (this .xmlNamespace != null) {
154: target.append(xmlNamespace);
155: target.append(':');
156: }
157: target.append(tag);
158: if (attributes != null && attributes.size() > 0) {
159: for (TagAttribute att : attributes) {
160: target.append(' ');
161: target.append(att.getTagText());
162: }
163: }
164: if (closeTag)
165: target.append('>');
166: }
167:
168: public void appendOpenTag(StrBuffer target, StrBuffer indent,
169: String tag, boolean closeTag, TagAttribute... attributes) {
170: if (indent != null)
171: target.append(indent);
172: target.append('<');
173: if (this .xmlNamespace != null) {
174: target.append(xmlNamespace);
175: target.append(':');
176: }
177: target.append(tag);
178: for (TagAttribute att : attributes) {
179: target.append(' ');
180: target.append(att.getTagText());
181: }
182: if (closeTag)
183: target.append('>');
184: }
185:
186: public void appendCloseTag(StrBuffer target, StrBuffer indent,
187: String tag) {
188: if (indent != null)
189: target.append(indent);
190: target.append("</");
191: if (this .xmlNamespace != null) {
192: target.append(xmlNamespace);
193: target.append(':');
194: }
195: target.append(tag);
196: target.append(">\n");
197: }
198:
199: /**
200: * Getter for property namespace.
201: * @return Value of property namespace.
202: */
203: public String getNamespace() {
204: return xmlNamespace;
205: }
206:
207: /**
208: * Setter for property namespace.
209: * @param namespace New value of property namespace.
210: */
211: public void setNamespace(String namespace) {
212: this .xmlNamespace = namespace;
213: }
214:
215: private static final char[] SPECIAL_CHARS = new char[] { '<', '>',
216: '&', '\'', '\n', '\r' };
217:
218: public static boolean needsCData(CharSequence value) {
219: if (value == null)
220: return false;
221: for (int i = 0; i < SPECIAL_CHARS.length; i++) {
222: if (StringUtil.indexOf(value, SPECIAL_CHARS[i]) > -1)
223: return true;
224: }
225: return false;
226: }
227:
228: }
|