1/*******************************************************************************
2 * Copyright (c) 2000, 2006 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 *     IBM Corporation - initial API and implementation
10 *******************************************************************************/
11package org.eclipse.releng;
12
13/**
14 * A custom Ant task that finds compile logs containing compile
15 * errors.  The compile logs with errors are sent as email attachments using
16 * information in monitor.properties.
17 */
18
19import java.io.BufferedReader;
20import java.io.File;
21import java.io.FileNotFoundException;
22import java.io.FileReader;
23import java.io.IOException;
24import java.util.Enumeration;
25import java.util.Vector;
26
27import javax.xml.parsers.ParserConfigurationException;
28import javax.xml.parsers.SAXParser;
29import javax.xml.parsers.SAXParserFactory;
30
31import org.apache.tools.ant.BuildException;
32import org.apache.tools.ant.Task;
33import org.xml.sax.Attributes;
34import org.xml.sax.InputSource;
35import org.xml.sax.SAXException;
36import org.xml.sax.helpers.DefaultHandler;
37
38public class CompileErrorCheck extends Task {
39
40	private static final class CompilerErrorCheckerHandler extends DefaultHandler {
41		boolean hasErrors = false;
42
43		public void startElement(String uri, String localName,
44				String name, Attributes attributes) throws SAXException {
45			if (this.hasErrors) return;
46			if ("problem_summary".equals(name)) {
47				// problem_summary name
48				String value = attributes.getValue("errors");
49				this.hasErrors = value != null && !value.equals("0");
50			}
51		}
52		public boolean hasErrors() {
53			return this.hasErrors;
54		}
55	}
56
57	//directory containing of build source, parent of features and plugins
58	private String install = "";
59
60	//keep track of compile logs containing errors
61	private Vector logsWithErrors;
62
63	// keep track of the factory to use
64	private SAXParser parser;
65
66	public CompileErrorCheck() {
67		this.logsWithErrors = new Vector();
68		SAXParserFactory factory = SAXParserFactory.newInstance();
69		this.parser = null;
70
71		try {
72			this.parser = factory.newSAXParser();
73		} catch (ParserConfigurationException e) {
74			e.printStackTrace();
75		} catch (SAXException e) {
76			e.printStackTrace();
77		}
78	}
79
80	public void execute() throws BuildException {
81		if (parser == null) return;
82		findLogs(new File(install));
83		sendNotice();
84	}
85
86	// test
87	public static void main(String[] args) {
88		CompileErrorCheck checker = new CompileErrorCheck();
89		checker.install="d:/compilelogs";
90		checker.execute();
91	}
92
93	private void findLogs(File aFile) {
94		if (!aFile.exists()) return;
95		// basis case
96		if (aFile.isFile()) {
97			String absolutePath = aFile.getAbsolutePath();
98			if (absolutePath.endsWith(".xml")) {
99				parse(aFile);
100			} else if (absolutePath.endsWith(".jar.bin.log")||absolutePath.endsWith("dot.bin.log")){
101				read(aFile);
102			}
103		} else {
104			//recurse into directories looking for and reading compile logs
105			File files[] = aFile.listFiles();
106
107			if (files != null) {
108				for (int i = 0, max = files.length; i < max; i++) {
109					findLogs(files[i]);
110				}
111			}
112		}
113	}
114
115	private void read(File file) {
116		//read the contents of the log file, and return contents as a String
117		if (file.length()==0)
118			return;
119
120		BufferedReader in = null;
121		String aLine;
122
123		try {
124			in = new BufferedReader(new FileReader(file));
125		} catch (FileNotFoundException e) {
126			e.printStackTrace();
127		}
128
129		try {
130			while ((aLine = in.readLine()) != null) {
131				int statusSummaryIndex=aLine.indexOf("problem (");
132				if (statusSummaryIndex==-1)
133					statusSummaryIndex=aLine.indexOf("problems (");
134
135				if (statusSummaryIndex!=-1&&(aLine.indexOf("error", statusSummaryIndex) != -1)){
136					logsWithErrors.add(file);
137					System.out.println(file.getName()+" has compile errors.");
138					return;
139				}
140			}
141		} catch (IOException e) {
142			e.printStackTrace();
143		} finally {
144			// make sure we don't leave any file handle open
145			if (in != null) {
146				try {
147					in.close();
148				} catch (IOException e) {
149					// ignore
150				}
151			}
152		}
153	}
154
155	private void parse(File file) {
156		BufferedReader reader = null;
157		try {
158			reader = new BufferedReader(new FileReader(file));
159		} catch (FileNotFoundException e) {
160			e.printStackTrace();
161		}
162
163		InputSource inputSource = new InputSource(reader);
164
165		CompilerErrorCheckerHandler compilerErrorCheckerHandler = new CompilerErrorCheckerHandler();
166		try {
167			parser.parse(inputSource, compilerErrorCheckerHandler);
168		} catch (SAXException e) {
169			e.printStackTrace();
170		} catch (IOException e) {
171			e.printStackTrace();
172		} finally {
173			// make sure we don't leave any file handle open
174			if (reader != null) {
175				try {
176					reader.close();
177				} catch (IOException e) {
178					// ignore
179				}
180			}
181		}
182
183		if (compilerErrorCheckerHandler.hasErrors()) {
184			logsWithErrors.add(new File(file.getParentFile(),file.getName().replaceAll(".xml", ".html")));
185			System.out.println(file.getName()+" has compile errors.");
186		}
187	}
188
189	private void sendNotice() {
190		//send email notification that there are compile errors in the build
191		//send the logs as attachments
192		Enumeration enumeration = logsWithErrors.elements();
193
194		if (logsWithErrors.size() > 0) {
195			try{
196
197				Mailer mailer = new Mailer();
198				String [] logFiles = new String [logsWithErrors.size()];
199
200				int i=0;
201
202				while (enumeration.hasMoreElements()) {
203					logFiles[i++]=((File) enumeration.nextElement()).getAbsolutePath();
204				}
205
206				mailer.sendMultiPartMessage("Compile errors in build", "Compile errors in build.  See attached compile logs.", logFiles);
207			} catch (NoClassDefFoundError e){
208				while (enumeration.hasMoreElements()) {
209					String path=((File) enumeration.nextElement()).getAbsolutePath();
210					String nameWithPlugin=path.substring(path.indexOf("plugins"),path.length());
211					System.out.println("Compile errors detected in "+nameWithPlugin);
212				}
213
214				System.out.println("Unable to send email notice of compile errors.");
215				System.out.println("The j2ee.jar may not be on the Ant classpath.");
216
217			}
218
219		}
220
221	}
222
223	/**
224	 * Gets the install.
225	 * @return Returns a String
226	 */
227	public String getInstall() {
228		return install;
229	}
230
231	/**
232	 * Sets the install.
233	 * @param install The install to set
234	 */
235	public void setInstall(String install) {
236		this.install = install;
237	}
238
239}
240