KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > XMLLogger


1 ////////////////////////////////////////////////////////////////////////////////
2
// checkstyle: Checks Java source code for adherence to a set of rules.
3
// Copyright (C) 2001-2005 Oliver Burn
4
//
5
// This library is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation; either
8
// version 2.1 of the License, or (at your option) any later version.
9
//
10
// This library is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
// Lesser General Public License for more details.
14
//
15
// You should have received a copy of the GNU Lesser General Public
16
// License along with this library; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
////////////////////////////////////////////////////////////////////////////////
19
package com.puppycrawl.tools.checkstyle;
20
21 import java.io.OutputStream JavaDoc;
22 import java.io.OutputStreamWriter JavaDoc;
23 import java.io.PrintWriter JavaDoc;
24 import java.io.StringWriter JavaDoc;
25 import java.io.UnsupportedEncodingException JavaDoc;
26 import java.util.ResourceBundle JavaDoc;
27
28 import com.puppycrawl.tools.checkstyle.api.AuditEvent;
29 import com.puppycrawl.tools.checkstyle.api.AuditListener;
30 import com.puppycrawl.tools.checkstyle.api.AutomaticBean;
31 import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
32
33 /**
34  * Simple XML logger.
35  * It outputs everything in UTF-8 (default XML encoding is UTF-8) in case
36  * we want to localize error messages or simply that filenames are
37  * localized and takes care about escaping as well.
38
39  * @author <a HREF="mailto:stephane.bailliez@wanadoo.fr">Stephane Bailliez</a>
40  */

41 public class XMLLogger
42     extends AutomaticBean
43     implements AuditListener
44 {
45     /** decimal radix */
46     private static final int BASE_10 = 10;
47
48     /** hex radix */
49     private static final int BASE_16 = 16;
50
51     /** close output stream in auditFinished */
52     private boolean mCloseStream;
53
54     /** helper writer that allows easy encoding and printing */
55     private PrintWriter JavaDoc mWriter;
56
57     /** some known entities to detect */
58     private static final String JavaDoc[] ENTITIES = {"gt", "amp", "lt", "apos",
59                                               "quot", };
60
61     /**
62      * Creates a new <code>XMLLogger</code> instance.
63      * Sets the output to a defined stream.
64      * @param aOS the stream to write logs to.
65      * @param aCloseStream close aOS in auditFinished
66      */

67     public XMLLogger(OutputStream JavaDoc aOS, boolean aCloseStream)
68     {
69         setOutputStream(aOS);
70         mCloseStream = aCloseStream;
71     }
72
73     /**
74      * sets the OutputStream
75      * @param aOS the OutputStream to use
76      **/

77     private void setOutputStream(OutputStream JavaDoc aOS)
78     {
79         try {
80             final OutputStreamWriter JavaDoc osw = new OutputStreamWriter JavaDoc(aOS, "UTF-8");
81             mWriter = new PrintWriter JavaDoc(osw);
82         }
83         catch (final UnsupportedEncodingException JavaDoc e) {
84             // unlikely to happen...
85
throw new ExceptionInInitializerError JavaDoc(e);
86         }
87     }
88
89     /** {@inheritDoc} */
90     public void auditStarted(AuditEvent aEvt)
91     {
92         mWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
93
94         final ResourceBundle JavaDoc compilationProperties =
95             ResourceBundle.getBundle("checkstylecompilation");
96         final String JavaDoc version =
97             compilationProperties.getString("checkstyle.compile.version");
98
99         mWriter.println("<checkstyle version=\"" + version + "\">");
100     }
101
102     /** {@inheritDoc} */
103     public void auditFinished(AuditEvent aEvt)
104     {
105         mWriter.println("</checkstyle>");
106         if (mCloseStream) {
107             mWriter.close();
108         }
109         else {
110             mWriter.flush();
111         }
112     }
113
114     /** {@inheritDoc} */
115     public void fileStarted(AuditEvent aEvt)
116     {
117         mWriter.println("<file name=\"" + aEvt.getFileName() + "\">");
118     }
119
120     /** {@inheritDoc} */
121     public void fileFinished(AuditEvent aEvt)
122     {
123         mWriter.println("</file>");
124     }
125
126     /** {@inheritDoc} */
127     public void addError(AuditEvent aEvt)
128     {
129         if (!SeverityLevel.IGNORE.equals(aEvt.getSeverityLevel())) {
130             mWriter.print("<error" + " line=\"" + aEvt.getLine() + "\"");
131             if (aEvt.getColumn() > 0) {
132                 mWriter.print(" column=\"" + aEvt.getColumn() + "\"");
133             }
134             mWriter.print(" severity=\""
135                 + aEvt.getSeverityLevel().getName()
136                 + "\"");
137             mWriter.print(" message=\""
138                 + encode(aEvt.getMessage())
139                 + "\"");
140             mWriter.println(" source=\""
141                 + encode(aEvt.getSourceName())
142                 + "\"/>");
143         }
144     }
145
146     /** {@inheritDoc} */
147     public void addException(AuditEvent aEvt, Throwable JavaDoc aThrowable)
148     {
149         final StringWriter JavaDoc sw = new StringWriter JavaDoc();
150         final PrintWriter JavaDoc pw = new PrintWriter JavaDoc(sw);
151         pw.println("<exception>");
152         pw.println("<![CDATA[");
153         aThrowable.printStackTrace(pw);
154         pw.println("]]>");
155         pw.println("</exception>");
156         pw.flush();
157         mWriter.println(encode(sw.toString()));
158     }
159
160     /**
161      * Escape &lt;, &gt; &amp; &apos; and &quot; as their entities.
162      * @param aValue the value to escape.
163      * @return the escaped value if necessary.
164      */

165     public String JavaDoc encode(String JavaDoc aValue)
166     {
167         final StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
168         for (int i = 0; i < aValue.length(); i++) {
169             final char c = aValue.charAt(i);
170             switch (c) {
171             case '<':
172                 sb.append("&lt;");
173                 break;
174             case '>':
175                 sb.append("&gt;");
176                 break;
177             case '\'':
178                 sb.append("&apos;");
179                 break;
180             case '\"':
181                 sb.append("&quot;");
182                 break;
183             case '&':
184                 final int nextSemi = aValue.indexOf(";", i);
185                 if ((nextSemi < 0)
186                     || !isReference(aValue.substring(i, nextSemi + 1)))
187                 {
188                     sb.append("&amp;");
189                 }
190                 else {
191                     sb.append('&');
192                 }
193                 break;
194             default:
195                 sb.append(c);
196                 break;
197             }
198         }
199         return sb.toString();
200     }
201
202     /**
203      * @return whether the given argument a character or entity reference
204      * @param aEnt the possible entity to look for.
205      */

206     public boolean isReference(String JavaDoc aEnt)
207     {
208         if (!(aEnt.charAt(0) == '&') || !aEnt.endsWith(";")) {
209             return false;
210         }
211
212         if (aEnt.charAt(1) == '#') {
213             int prefixLength = 2; // "&#"
214
int radix = BASE_10;
215             if (aEnt.charAt(2) == 'x') {
216                 prefixLength++;
217                 radix = BASE_16;
218             }
219             try {
220                 Integer.parseInt(
221                     aEnt.substring(prefixLength, aEnt.length() - 1), radix);
222                 return true;
223             }
224             catch (final NumberFormatException JavaDoc nfe) {
225                 return false;
226             }
227         }
228
229         final String JavaDoc name = aEnt.substring(1, aEnt.length() - 1);
230         for (int i = 0; i < ENTITIES.length; i++) {
231             if (name.equals(ENTITIES[i])) {
232                 return true;
233             }
234         }
235         return false;
236     }
237 }
238
Popular Tags