001    /*
002     *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003     *
004     *  This file is licensed to You under the Eclipse Public License (EPL);
005     *  You may not use this file except in compliance with the License. You
006     *  may obtain a copy of the License at
007     *
008     *      http://www.opensource.org/licenses/eclipse-1.0.php
009     *
010     *  See the COPYRIGHT.txt file distributed with this work for information
011     *  regarding copyright ownership.
012     */
013    package org.mmtk.utility.statistics;
014    
015    import org.mmtk.utility.Log;
016    import org.vmmagic.pragma.Uninterruptible;
017    import org.vmmagic.unboxed.Word;
018    
019    /**
020     * Utility class for writing statistics out in XML format.
021     */
022    @Uninterruptible
023    public class Xml {
024      /**
025       * Mark the start of XML output
026       */
027      public static void begin() {
028        Log.writeln("<xml-begin/> <!-- Everything until xml-end is now valid xml -->");
029      }
030    
031      /**
032       * Mark the end of XML output
033       */
034      public static void end() {
035        Log.writeln("<xml-end/> <!-- Non-xml data follows ... -->");
036      }
037    
038      /**
039       * Close the innermost XML tag and pop it from the stack.
040       */
041      public static void closeTag(String name) {
042        Log.write("</"); Log.write(name); Log.writeln(">");
043      }
044    
045      /**
046       * Open an XML tag.
047       *
048       * @param name Tag name
049       * @param endTag Should the tag be closed, or left open for
050       *               adding additional attributes
051       */
052      static void openTag(String name, boolean endTag) {
053        openMinorTag(name);
054        if (endTag)
055          closeTag(false);
056      }
057    
058      /**
059       * Open a simple XML entity.
060       *
061       * @param name Name of the entity
062       */
063      static void openTag(String name) { openTag(name,true); }
064    
065      /**
066       * Output a "stat" entity, with a given name, <code>double</code>value and optionally, units.
067       *
068       * @param name Name of the entity
069       * @param value The value of the entity
070       * @param units The units, or null for no units.
071       */
072      public static void singleValue(String name, double value, String units) {
073        openMinorTag("stat");
074        attribute("name",name);
075        attribute("value",value);
076        if (units != null) attribute("units",units);
077        closeMinorTag();
078      }
079    
080      /**
081       * Convenience version of singleValue where units are not specified.
082       *
083       * @param name Name of the entity
084       * @param value The value of the entity
085       */
086      public static void singleValue(String name, double value) {
087        singleValue(name,value,null);
088      }
089    
090      /**
091       * Output a "config" entity, with a given name and <code>boolean</code>value.
092       *
093       * @param name Name of the entity
094       * @param value The value of the entity
095       */
096      public static void configItem(String name, boolean value) {
097        openMinorTag("conf");
098        attribute("name",name);
099        attribute("value",value);
100        closeMinorTag();
101      }
102    
103      /**
104       * Output a "config" entity, with a given name and <code>String</code>value.
105       *
106       * @param name Name of the entity
107       * @param value The value of the entity
108       */
109      public static void configItem(String name, String value) {
110        openMinorTag("conf");
111        attribute("name",name);
112        attribute("value",value);
113        closeMinorTag();
114      }
115    
116      /**
117       * Output a "stat" entity, with a given name, <code>long</code> value and
118       * optionally, units.
119       *
120       * @param name Name of the entity
121       * @param value The value of the entity
122       * @param units The units, or null for no units.
123       */
124      public static void singleValue(String name, long value, String units) {
125        openMinorTag("stat");
126        attribute("name",name);
127        attribute("value",value);
128        if (units != null) attribute("units",units);
129        closeMinorTag();
130      }
131    
132      /**
133       * Convenience version of singleValue where units are not specified.
134       *
135       * @param name Name of the entity
136       * @param value The value of the entity
137       */
138      public static void singleValue(String name, long value) {
139        singleValue(name,value,null);
140      }
141    
142      /**
143       * Add a word-valued attribute to an open XML tag.
144       *
145       * @param name Name of the entity
146       * @param value The value of the entity
147       */
148      public static void attribute(String name, Word value) {
149        openAttribute(name); Log.write(value); closeAttribute();
150      }
151    
152      /**
153       * Add a byte[]-valued attribute to an open XML tag.
154       *
155       * @param name Name of the entity
156       * @param value The value of the entity
157       */
158      public static void attribute(String name, byte[] value) {
159        openAttribute(name); Log.write(value); closeAttribute();
160      }
161    
162      /**
163       * Add a String-valued attribute to an open XML tag.
164       *
165       * @param name Name of the entity
166       * @param value The value of the entity
167       */
168      public static void attribute(String name, String value) {
169        openAttribute(name); Log.write(value); closeAttribute();
170      }
171    
172      /**
173       * Add a boolean-valued attribute to an open XML tag.
174       *
175       * @param name Name of the entity
176       * @param value The value of the entity
177       */
178      public static void attribute(String name, boolean value) {
179        openAttribute(name); Log.write(value); closeAttribute();
180      }
181    
182      /**
183       * Add a double-valued attribute to an open XML tag.
184       *
185       * @param name Name of the entity
186       * @param value The value of the entity
187       */
188      public static void attribute(String name, double value) {
189        openAttribute(name); Log.write(value); closeAttribute();
190      }
191    
192      /**
193       * Add a long-valued attribute to an open XML tag.
194       *
195       * @param name Name of the entity
196       * @param value The value of the entity
197       */
198      public static void attribute(String name, long value) {
199        openAttribute(name); Log.write(value); closeAttribute();
200      }
201    
202      /**
203       * Add an int-valued attribute to an open XML tag.
204       *
205       * @param name Name of the entity
206       * @param value The value of the entity
207       */
208      public static void attribute(String name, int value) {
209        openAttribute(name); Log.write(value); closeAttribute();
210      }
211    
212      /**
213       * Close an attribute (actually a simple close-quote)
214       */
215      public static void closeAttribute() {
216        Log.write("\"");
217      }
218    
219      /**
220       * Open an attribute (write "{name}=\")
221       *
222       * @param name Name of the entity
223       */
224      public static void openAttribute(String name) {
225        Log.write(" "); Log.write(name); Log.write("=\"");
226      }
227    
228      /**
229       * Start a tag
230       */
231      public static void startTag() {
232        Log.write("<");
233      }
234    
235      /**
236       * End a tag, optionally closing it (if it is a simple entity)
237       *
238       * @param close If true, close the tag with "/>" rather than ">"
239       */
240      public static void closeTag(boolean close) {
241        closeTag(close,true);
242      }
243    
244      /**
245       * End a tag, optionally closing it (if it is a simple entity),
246       * and optionally printing end-of-line
247       *
248       * @param close If true, close the tag with "/>" rather than ">"
249       * @param endLine If true end the current line.
250       */
251      public static void closeTag(boolean close, boolean endLine) {
252        if (close) Log.write("/");
253        Log.write(">");
254        if (endLine) Log.writeln();
255      }
256    
257      /**
258       * Close a tag with a "/>"
259       */
260      public static void closeMinorTag() {
261        closeTag(true,true);
262      }
263    
264      /**
265       * Open a tag without pushing it on the tag stack - must end this
266       * with a call to closeMinorTag()
267       *
268       * @param name Name of the entity
269       */
270      public static void openMinorTag(String name) {
271        Log.write("<"); Log.write(name);
272      }
273    
274      /**
275       * Open an XML comment
276       */
277      public static void openComment() {
278        Log.write("<!-- ");
279      }
280    
281      /**
282       * Close an XML comment
283       */
284      public static void closeComment() {
285        Log.write(" -->");
286      }
287    
288      /**
289       * Add a comment, bracketing it with open- and close-comment tags.
290       *
291       * @param comment The comment.
292       */
293      public static void comment(String comment) {
294        openComment();
295        Log.write(comment);
296        closeComment();
297        Log.writeln();
298      }
299    
300    }