001    /* ============================================================
002     * JRobin : Pure java implementation of RRDTool's functionality
003     * ============================================================
004     *
005     * Project Info:  http://www.jrobin.org
006     * Project Lead:  Sasa Markovic (saxon@jrobin.org);
007     *
008     * (C) Copyright 2003-2005, by Sasa Markovic.
009     *
010     * Developers:    Sasa Markovic (saxon@jrobin.org)
011     *
012     *
013     * This library is free software; you can redistribute it and/or modify it under the terms
014     * of the GNU Lesser General Public License as published by the Free Software Foundation;
015     * either version 2.1 of the License, or (at your option) any later version.
016     *
017     * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
018     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
019     * See the GNU Lesser General Public License for more details.
020     *
021     * You should have received a copy of the GNU Lesser General Public License along with this
022     * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
023     * Boston, MA 02111-1307, USA.
024     */
025    
026    package org.jrobin.core;
027    
028    import java.awt.*;
029    import java.io.File;
030    import java.io.OutputStream;
031    import java.io.PrintWriter;
032    import java.util.Stack;
033    
034    /**
035     * Extremely simple utility class used to create XML documents.
036     */
037    public class XmlWriter {
038            static final String INDENT_STR = "   ";
039    
040            private PrintWriter writer;
041            private StringBuffer indent = new StringBuffer("");
042            private Stack<String> openTags = new Stack<String>();
043    
044            /**
045             * Creates XmlWriter with the specified output stream to send XML code to.
046             *
047             * @param stream Output stream which receives XML code
048             */
049            public XmlWriter(OutputStream stream) {
050                    writer = new PrintWriter(stream, true);
051            }
052    
053            /**
054             * Opens XML tag
055             *
056             * @param tag XML tag name
057             */
058            public void startTag(String tag) {
059                    writer.println(indent + "<" + tag + ">");
060                    openTags.push(tag);
061                    indent.append(INDENT_STR);
062            }
063    
064            /**
065             * Closes the corresponding XML tag
066             */
067            public void closeTag() {
068                    String tag = openTags.pop();
069                    indent.setLength(indent.length() - INDENT_STR.length());
070                    writer.println(indent + "</" + tag + ">");
071            }
072    
073            /**
074             * Writes &lt;tag&gt;value&lt;/tag&gt; to output stream
075             *
076             * @param tag   XML tag name
077             * @param value value to be placed between <code>&lt;tag&gt</code> and <code>&lt;/tag&gt;</code>
078             */
079            public void writeTag(String tag, Object value) {
080                    if (value != null) {
081                            writer.println(indent + "<" + tag + ">" +
082                                            escape(value.toString()) + "</" + tag + ">");
083                    }
084                    else {
085                            writer.println(indent + "<" + tag + "></" + tag + ">");
086                    }
087            }
088    
089            /**
090             * Writes &lt;tag&gt;value&lt;/tag&gt; to output stream
091             *
092             * @param tag   XML tag name
093             * @param value value to be placed between <code>&lt;tag&gt</code> and <code>&lt;/tag&gt;</code>
094             */
095            public void writeTag(String tag, int value) {
096                    writeTag(tag, "" + value);
097            }
098    
099            /**
100             * Writes &lt;tag&gt;value&lt;/tag&gt; to output stream
101             *
102             * @param tag   XML tag name
103             * @param value value to be placed between <code>&lt;tag&gt</code> and <code>&lt;/tag&gt;</code>
104             */
105            public void writeTag(String tag, long value) {
106                    writeTag(tag, "" + value);
107            }
108    
109            /**
110             * Writes &lt;tag&gt;value&lt;/tag&gt; to output stream
111             *
112             * @param tag   XML tag name
113             * @param value value to be placed between <code>&lt;tag&gt</code> and <code>&lt;/tag&gt;</code>
114             */
115            public void writeTag(String tag, double value, String nanString) {
116                    writeTag(tag, Util.formatDouble(value, nanString, true));
117            }
118    
119            /**
120             * Writes &lt;tag&gt;value&lt;/tag&gt; to output stream
121             *
122             * @param tag   XML tag name
123             * @param value value to be placed between <code>&lt;tag&gt</code> and <code>&lt;/tag&gt;</code>
124             */
125            public void writeTag(String tag, double value) {
126                    writeTag(tag, Util.formatDouble(value, true));
127            }
128    
129            /**
130             * Writes &lt;tag&gt;value&lt;/tag&gt; to output stream
131             *
132             * @param tag   XML tag name
133             * @param value value to be placed between <code>&lt;tag&gt</code> and <code>&lt;/tag&gt;</code>
134             */
135            public void writeTag(String tag, boolean value) {
136                    writeTag(tag, "" + value);
137            }
138    
139            /**
140             * Writes &lt;tag&gt;value&lt;/tag&gt; to output stream
141             *
142             * @param tag   XML tag name
143             * @param value value to be placed between <code>&lt;tag&gt</code> and <code>&lt;/tag&gt;</code>
144             */
145            public void writeTag(String tag, Color value) {
146                    int rgb = value.getRGB() & 0xFFFFFF;
147                    writeTag(tag, "#" + Integer.toHexString(rgb).toUpperCase());
148            }
149    
150            /**
151             * Writes &lt;tag&gt;value&lt;/tag&gt; to output stream
152             *
153             * @param tag   XML tag name
154             * @param value value to be placed between <code>&lt;tag&gt</code> and <code>&lt;/tag&gt;</code>
155             */
156            public void writeTag(String tag, Font value) {
157                    startTag(tag);
158                    writeTag("name", value.getName());
159                    int style = value.getStyle();
160                    if ((style & Font.BOLD) != 0 && (style & Font.ITALIC) != 0) {
161                            writeTag("style", "BOLDITALIC");
162                    }
163                    else if ((style & Font.BOLD) != 0) {
164                            writeTag("style", "BOLD");
165                    }
166                    else if ((style & Font.ITALIC) != 0) {
167                            writeTag("style", "ITALIC");
168                    }
169                    else {
170                            writeTag("style", "PLAIN");
171                    }
172                    writeTag("size", value.getSize());
173                    closeTag();
174            }
175    
176            /**
177             * Writes &lt;tag&gt;value&lt;/tag&gt; to output stream
178             *
179             * @param tag   XML tag name
180             * @param value value to be placed between <code>&lt;tag&gt</code> and <code>&lt;/tag&gt;</code>
181             */
182            public void writeTag(String tag, File value) {
183                    writeTag(tag, value.getPath());
184            }
185    
186            /**
187             * Flushes the output stream
188             */
189            public void flush() {
190                    writer.flush();
191            }
192    
193            protected void finalize() throws Throwable {
194                    super.finalize();
195                    writer.close();
196            }
197    
198            /**
199             * Writes XML comment to output stream
200             *
201             * @param comment comment string
202             */
203            public void writeComment(Object comment) {
204                    writer.println(indent + "<!-- " + escape(comment.toString()) + " -->");
205            }
206    
207            private static String escape(String s) {
208                    return s.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
209            }
210    }