KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > optional > metamata > MAuditStreamHandler


1 /*
2  * Copyright 2001-2002,2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17 package org.apache.tools.ant.taskdefs.optional.metamata;
18
19 import java.io.BufferedReader JavaDoc;
20 import java.io.IOException JavaDoc;
21 import java.io.InputStream JavaDoc;
22 import java.io.InputStreamReader JavaDoc;
23 import java.io.OutputStream JavaDoc;
24 import java.util.Date JavaDoc;
25 import java.util.Enumeration JavaDoc;
26 import java.util.Hashtable JavaDoc;
27 import java.util.Vector JavaDoc;
28 import javax.xml.parsers.DocumentBuilder JavaDoc;
29 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
30 import org.apache.tools.ant.BuildException;
31 import org.apache.tools.ant.Project;
32 import org.apache.tools.ant.taskdefs.ExecuteStreamHandler;
33 import org.apache.tools.ant.taskdefs.LogOutputStream;
34 import org.apache.tools.ant.taskdefs.StreamPumper;
35 import org.apache.tools.ant.util.DOMElementWriter;
36 import org.apache.tools.ant.util.DateUtils;
37 import org.w3c.dom.Document JavaDoc;
38 import org.w3c.dom.Element JavaDoc;
39
40 /**
41  * This is a very bad stream handler for the MAudit task.
42  * All report to stdout that does not match a specific report pattern is dumped
43  * to the Ant output as warn level. The report that match the pattern is stored
44  * in a map with the key being the filepath that caused the error report.
45  * <p>
46  * The limitation with the choosen implementation is clear:
47  * <ul>
48  * <li>it does not handle multiline report( message that has \n ). the part until
49  * the \n will be stored and the other part (which will not match the pattern)
50  * will go to Ant output in Warn level.
51  * <li>it does not report error that goes to stderr.
52  * </ul>
53  *
54  */

55 class MAuditStreamHandler implements ExecuteStreamHandler {
56
57     /** parent task */
58     private MAudit task;
59
60     /** reader for stdout */
61     private BufferedReader JavaDoc br;
62
63     /**
64      * this is where the XML output will go, should mostly be a file
65      * the caller is responsible for flushing and closing this stream
66      */

67     private OutputStream JavaDoc xmlOut = null;
68
69     /** error stream, might be useful to spit out error messages */
70     private OutputStream JavaDoc errStream;
71
72     /** thread pumping out error stream */
73     private Thread JavaDoc errThread;
74
75     /**
76      * the multimap. The key in the map is the filepath that caused the audit
77      * error and the value is a vector of MAudit.Violation entries.
78      */

79     private Hashtable JavaDoc auditedFiles = new Hashtable JavaDoc();
80
81     /** program start timestamp for reporting purpose */
82     private Date JavaDoc program_start;
83
84     MAuditStreamHandler(MAudit task, OutputStream JavaDoc xmlOut) {
85         this.task = task;
86         this.xmlOut = xmlOut;
87     }
88
89     /** Ignore. */
90     public void setProcessInputStream(OutputStream JavaDoc os) {
91     }
92
93     /** Ignore. */
94     public void setProcessErrorStream(InputStream JavaDoc is) {
95         errStream = new LogOutputStream(task, Project.MSG_ERR);
96         errThread = createPump(is, errStream);
97     }
98
99     /** Set the inputstream */
100     public void setProcessOutputStream(InputStream JavaDoc is) throws IOException JavaDoc {
101         br = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(is));
102     }
103
104     /** Invokes parseOutput. This will block until the end :-(*/
105     public void start() throws IOException JavaDoc {
106         program_start = new Date JavaDoc();
107         errThread.start();
108         parseOutput(br);
109     }
110
111     /**
112      * Pretty dangerous business here. It serializes what was extracted from
113      * the MAudit output and write it to the output.
114      */

115     public void stop() {
116         // make sure to flush err stream
117
try {
118             errThread.join();
119         } catch (InterruptedException JavaDoc e) {
120         }
121         try {
122             errStream.flush();
123         } catch (IOException JavaDoc e) {
124         }
125         // serialize the content as XML, move this to another method
126
// this is the only code that could be needed to be overriden
127
Document JavaDoc doc = getDocumentBuilder().newDocument();
128         Element JavaDoc rootElement = doc.createElement("classes");
129         Enumeration JavaDoc keys = auditedFiles.keys();
130         Hashtable JavaDoc filemapping = task.getFileMapping();
131         final Date JavaDoc now = new Date JavaDoc();
132         rootElement.setAttribute("snapshot_created",
133             DateUtils.format(now, DateUtils.ISO8601_DATETIME_PATTERN));
134         rootElement.setAttribute("elapsed_time",
135             String.valueOf(now.getTime() - program_start.getTime()));
136         rootElement.setAttribute("program_start",
137             DateUtils.format(now, DateUtils.ISO8601_DATETIME_PATTERN));
138         rootElement.setAttribute("audited",
139             String.valueOf(filemapping.size()));
140         rootElement.setAttribute("reported",
141             String.valueOf(auditedFiles.size()));
142         int errors = 0;
143         while (keys.hasMoreElements()) {
144             String JavaDoc filepath = (String JavaDoc) keys.nextElement();
145             Vector JavaDoc v = (Vector JavaDoc) auditedFiles.get(filepath);
146             String JavaDoc fullclassname = (String JavaDoc) filemapping.get(filepath);
147             if (fullclassname == null) {
148                 task.getProject().log("Could not find class mapping for "
149                     + filepath, Project.MSG_WARN);
150                 continue;
151             }
152             int pos = fullclassname.lastIndexOf('.');
153             String JavaDoc pkg = (pos == -1) ? "" : fullclassname.substring(0, pos);
154             String JavaDoc clazzname = (pos == -1) ? fullclassname : fullclassname.substring(pos + 1);
155             Element JavaDoc clazz = doc.createElement("class");
156             clazz.setAttribute("package", pkg);
157             clazz.setAttribute("name", clazzname);
158             final int violationCount = v.size();
159             clazz.setAttribute("violations", String.valueOf(violationCount));
160             errors += violationCount;
161             for (int i = 0; i < violationCount; i++) {
162                 MAuditParser.Violation violation = (MAuditParser.Violation) v.elementAt(i);
163                 Element JavaDoc error = doc.createElement("violation");
164                 error.setAttribute("line", violation.line);
165                 error.setAttribute("message", violation.error);
166                 clazz.appendChild(error);
167             }
168             rootElement.appendChild(clazz);
169         }
170         rootElement.setAttribute("violations", String.valueOf(errors));
171
172         // now write it to the outputstream, not very nice code
173
DOMElementWriter domWriter = new DOMElementWriter();
174         try {
175             domWriter.write(rootElement, xmlOut);
176         } catch (IOException JavaDoc e) {
177             throw new BuildException(e);
178         }
179     }
180
181     protected static DocumentBuilder JavaDoc getDocumentBuilder() {
182         try {
183             return DocumentBuilderFactory.newInstance().newDocumentBuilder();
184         } catch (Exception JavaDoc exc) {
185             throw new ExceptionInInitializerError JavaDoc(exc);
186         }
187     }
188
189     /**
190      * Creates a stream pumper to copy the given input stream to the given output stream.
191      */

192     protected Thread JavaDoc createPump(InputStream JavaDoc is, OutputStream JavaDoc os) {
193         final Thread JavaDoc result = new Thread JavaDoc(new StreamPumper(is, os));
194         result.setDaemon(true);
195         return result;
196     }
197
198
199     /** read each line and process it */
200     protected void parseOutput(BufferedReader JavaDoc br) throws IOException JavaDoc {
201         String JavaDoc line = null;
202         final MAuditParser parser = new MAuditParser();
203         while ((line = br.readLine()) != null) {
204             final MAuditParser.Violation violation = parser.parseLine(line);
205             if (violation != null) {
206                 addViolation(violation.file, violation);
207             } else {
208                 // this doesn't match..report it as info, it could be
209
// either the copyright, summary or a multiline message (damn !)
210
task.log(line, Project.MSG_INFO);
211             }
212         }
213     }
214
215     /** add a violation entry for the file */
216     private void addViolation(String JavaDoc file, MAuditParser.Violation entry) {
217         Vector JavaDoc violations = (Vector JavaDoc) auditedFiles.get(file);
218         // if there is no decl for this file yet, create it.
219
if (violations == null) {
220             violations = new Vector JavaDoc();
221             auditedFiles.put(file, violations);
222         }
223         violations.addElement(entry);
224     }
225
226 }
227
Popular Tags