001: /*
002: * ============================================================================
003: * GNU Lesser General Public License
004: * ============================================================================
005: *
006: * JasperReports - Free Java report-generating library.
007: * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
022: *
023: * JasperSoft Corporation
024: * 303 Second Street, Suite 450 North
025: * San Francisco, CA 94107
026: * http://www.jaspersoft.com
027: */
028: package net.sf.jasperreports.engine.util;
029:
030: import java.awt.Color;
031: import java.io.IOException;
032: import java.io.Writer;
033: import java.util.ArrayList;
034: import java.util.Arrays;
035: import java.util.Iterator;
036: import java.util.List;
037: import java.util.Map;
038:
039: import net.sf.jasperreports.engine.JRExpression;
040:
041: /**
042: * @author Lucian Chirita (lucianc@users.sourceforge.net)
043: * @version $Id: JRXmlWriteHelper.java 1654 2007-03-23 13:01:52Z teodord $
044: */
045: public class JRXmlWriteHelper {
046: private final Writer writer;
047:
048: private final List indents;
049:
050: private int indent;
051: private final List elementStack;
052: private StringBuffer buffer;
053: private StackElement lastElement;
054:
055: protected static class Attribute {
056: String name;
057: String value;
058:
059: Attribute(String name, String value) {
060: this .name = name;
061: this .value = value;
062: }
063: }
064:
065: protected static class StackElement {
066: String name;
067: List atts;
068: boolean hasChildren;
069:
070: StackElement(String name) {
071: this .name = name;
072: this .atts = new ArrayList();
073: this .hasChildren = false;
074: }
075:
076: void addAttribute(String attName, String value) {
077: atts.add(new Attribute(attName, value));
078: }
079: }
080:
081: public JRXmlWriteHelper(Writer writer) {
082: this .writer = writer;
083:
084: indents = new ArrayList();
085:
086: indent = 0;
087: elementStack = new ArrayList();
088: lastElement = null;
089:
090: clearBuffer();
091: }
092:
093: public void writeProlog(String encoding) throws IOException {
094: writer.write("<?xml version=\"1.0\" encoding=\"" + encoding
095: + "\"?>\n");
096: }
097:
098: public void writePublicDoctype(String rootElement,
099: String description, String dtdLocation) throws IOException {
100: writer.write("<!DOCTYPE " + rootElement + " PUBLIC \""
101: + description + "\" \"" + dtdLocation + "\">\n\n");
102: }
103:
104: public void startElement(String name) {
105: ++indent;
106: lastElement = new StackElement(name);
107: elementStack.add(lastElement);
108: }
109:
110: protected void writeParents(boolean content) throws IOException {
111: int stackSize = elementStack.size();
112:
113: int startWrite = stackSize - 1;
114: while (startWrite >= 0) {
115: StackElement element = (StackElement) elementStack
116: .get(startWrite);
117:
118: if (element.hasChildren) {
119: break;
120: }
121:
122: if (startWrite < stackSize - 1) {
123: element.hasChildren = true;
124: } else {
125: element.hasChildren |= content;
126: }
127:
128: --startWrite;
129: }
130:
131: for (int i = startWrite + 1; i < stackSize; ++i) {
132: StackElement element = (StackElement) elementStack.get(i);
133: writeElementAttributes(element, i);
134: }
135: }
136:
137: public void writeCDATA(String data) throws IOException {
138: if (data != null) {
139: writeParents(true);
140:
141: buffer.append(getIndent(indent));
142: buffer.append("<![CDATA[");
143: buffer.append(data);
144: buffer.append("]]>\n");
145: flushBuffer();
146: }
147: }
148:
149: public void writeCDATAElement(String name, String data)
150: throws IOException {
151: if (data != null) {
152: writeParents(true);
153:
154: buffer.append(getIndent(indent));
155: buffer.append('<');
156: buffer.append(name);
157: buffer.append("><![CDATA[");
158: buffer.append(data);
159: buffer.append("]]></");
160: buffer.append(name);
161: buffer.append(">\n");
162: flushBuffer();
163: }
164: }
165:
166: public void writeCDATAElement(String name, String data,
167: String attName, String attValue) throws IOException {
168: if (data != null) {
169: writeParents(true);
170:
171: buffer.append(getIndent(indent));
172: buffer.append('<');
173: buffer.append(name);
174: buffer.append(' ');
175: buffer.append(attName);
176: buffer.append("=\"");
177: buffer.append(attValue);
178: buffer.append("\"><![CDATA[");
179: buffer.append(data);
180: buffer.append("]]></");
181: buffer.append(name);
182: buffer.append(">\n");
183: flushBuffer();
184: }
185: }
186:
187: protected void writeElementAttributes(StackElement element,
188: int level) throws IOException {
189: buffer.append(getIndent(level));
190: buffer.append('<');
191: buffer.append(element.name);
192: for (Iterator i = element.atts.iterator(); i.hasNext();) {
193: Attribute att = (Attribute) i.next();
194: buffer.append(' ');
195: buffer.append(att.name);
196: buffer.append("=\"");
197: buffer.append(att.value);
198: buffer.append('"');
199: }
200:
201: if (element.hasChildren) {
202: buffer.append(">\n");
203: } else {
204: buffer.append("/>\n");
205: }
206:
207: flushBuffer();
208: }
209:
210: public void closeElement() throws IOException {
211: closeElement(false);
212: }
213:
214: public void closeElement(boolean skipIfEmpty) throws IOException {
215: --indent;
216:
217: if (skipIfEmpty && lastElement.atts.size() == 0
218: && !lastElement.hasChildren) {
219: clearBuffer();
220: } else {
221: writeParents(false);
222:
223: if (lastElement.hasChildren) {
224: buffer.append(getIndent(indent));
225: buffer.append("</");
226: buffer.append(lastElement.name);
227: buffer.append(">\n");
228: flushBuffer();
229: }
230: }
231:
232: elementStack.remove(indent);
233: lastElement = indent > 0 ? (StackElement) elementStack
234: .get(indent - 1) : null;
235: }
236:
237: protected char[] getIndent(int level) {
238: if (level >= indents.size()) {
239: for (int i = indents.size(); i <= level; ++i) {
240: char[] str = new char[i];
241: Arrays.fill(str, '\t');
242: indents.add(str);
243: }
244: }
245:
246: return (char[]) indents.get(level);
247: }
248:
249: protected void flushBuffer() throws IOException {
250: writer.write(buffer.toString());
251: clearBuffer();
252: }
253:
254: protected void clearBuffer() {
255: buffer = new StringBuffer();
256: }
257:
258: public void writeExpression(String name, JRExpression expression,
259: boolean writeClass) throws IOException {
260: writeExpression(name, expression, writeClass, null);
261: }
262:
263: public void writeExpression(String name, JRExpression expression,
264: boolean writeClass, String defaultClassName)
265: throws IOException {
266: if (expression != null) {
267: if (writeClass
268: && (defaultClassName == null || !defaultClassName
269: .equals(expression.getValueClassName()))) {
270: writeCDATAElement(name, expression.getText(), "class",
271: expression.getValueClassName());
272: } else {
273: writeCDATAElement(name, expression.getText());
274: }
275: }
276: }
277:
278: protected void writeAttribute(String name, String value) {
279: lastElement.addAttribute(name, value);
280: }
281:
282: public void addAttribute(String name, String value) {
283: if (value != null) {
284: writeAttribute(name, value);
285: }
286: }
287:
288: public void addEncodedAttribute(String name, String value) {
289: if (value != null) {
290: writeAttribute(name, JRStringUtil.xmlEncode(value));
291: }
292: }
293:
294: public void addAttribute(String name, String value,
295: String defaultValue) {
296: if (value != null && !value.equals(defaultValue)) {
297: writeAttribute(name, value);
298: }
299: }
300:
301: public void addEncodedAttribute(String name, String value,
302: String defaultValue) {
303: if (value != null && !value.equals(defaultValue)) {
304: writeAttribute(name, JRStringUtil.xmlEncode(value));
305: }
306: }
307:
308: public void addAttribute(String name, Object value) {
309: if (value != null) {
310: writeAttribute(name, String.valueOf(value));
311: }
312: }
313:
314: public void addAttribute(String name, int value) {
315: writeAttribute(name, String.valueOf(value));
316: }
317:
318: public void addAttributePositive(String name, int value) {
319: if (value > 0) {
320: writeAttribute(name, String.valueOf(value));
321: }
322: }
323:
324: public void addAttribute(String name, float value) {
325: writeAttribute(name, String.valueOf(value));
326: }
327:
328: public void addAttribute(String name, float value,
329: float defaultValue) {
330: if (value != defaultValue) {
331: writeAttribute(name, String.valueOf(value));
332: }
333: }
334:
335: public void addAttribute(String name, double value) {
336: writeAttribute(name, String.valueOf(value));
337: }
338:
339: public void addAttribute(String name, double value,
340: double defaultValue) {
341: if (value != defaultValue) {
342: writeAttribute(name, String.valueOf(value));
343: }
344: }
345:
346: public void addAttribute(String name, int value, int defaultValue) {
347: if (value != defaultValue) {
348: addAttribute(name, value);
349: }
350: }
351:
352: public void addAttribute(String name, boolean value) {
353: writeAttribute(name, String.valueOf(value));
354: }
355:
356: public void addAttribute(String name, boolean value,
357: boolean defaultValue) {
358: if (value != defaultValue) {
359: addAttribute(name, value);
360: }
361: }
362:
363: public void addAttribute(String name, Color color) {
364: if (color != null) {
365: writeAttribute(name, "#" + JRColorUtil.getColorHexa(color));
366: }
367: }
368:
369: public void addAttribute(String name, Color value,
370: Color defaultValue) {
371: if (value != null && value.getRGB() != defaultValue.getRGB()) {
372: addAttribute(name, value);
373: }
374: }
375:
376: public void addAttribute(String name, byte value, Map xmlValues) {
377: String xmlValue = (String) xmlValues.get(new Byte(value));
378: writeAttribute(name, xmlValue);
379: }
380:
381: public void addAttribute(String name, int value, Map xmlValues) {
382: String xmlValue = (String) xmlValues.get(new Integer(value));
383: writeAttribute(name, xmlValue);
384: }
385:
386: public void addAttribute(String name, byte value, Map xmlValues,
387: byte defaultValue) {
388: if (value != defaultValue) {
389: addAttribute(name, value, xmlValues);
390: }
391: }
392:
393: public void addAttribute(String name, Object value, Map xmlValues) {
394: if (value != null) {
395: String xmlValue = (String) xmlValues.get(value);
396: writeAttribute(name, xmlValue);
397: }
398: }
399:
400: public void addAttribute(String name, Object value, Map xmlValues,
401: Object defaultValue) {
402: if (!value.equals(defaultValue)) {
403: addAttribute(name, value, xmlValues);
404: }
405: }
406: }
|