blob: 6a158d706d59ce377257516efb30e4ba8ae4d2ad [file] [log] [blame]
package org.eclipse.wtp.releng.wtpbuilder;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Properties;
/**
* This abstract class is a base class for adding builders which run ant scripts on given builds and
* caches the list of already scanned builds to the filename given.
*/
public abstract class AbstractBuilder implements IBuildConstants {
/**
* The URL to the public declared build site
*/
private static final String URL_BUILD_PUBLIC = "http://download.eclipse.org/webtools/downloads/"; //$NON-NLS-1$
/**
* The URL to the committers build page for continuous builds
*/
private static final String URL_BUILD_COMMITTER = "http://download.eclipse.org/webtools/committers/"; //$NON-NLS-1$
/**
* The default filename for the file cache of completed build scans
*/
protected static final String DEFAULT_COMPLETED_BUILDS_FILE = "completed_builds.properties"; //$NON-NLS-1$
private Properties completedBuilds;
private String completedBuildsFilename;
private Build latestBuild;
protected String baseos;
protected String basews;
protected String basearch;
protected String login;
private long minTS;
/**
* Default constructor uses default file name for completed builds cache
*/
public AbstractBuilder() {
this(DEFAULT_COMPLETED_BUILDS_FILE);
}
/**
* Constructor taking the filename for the completed builds cache as an argument
* @param completedBuildsFile
*/
public AbstractBuilder(String completedBuildsFile) {
completedBuildsFilename = completedBuildsFile;
try {
File file = new File(completedBuildsFilename);
file.createNewFile();
completedBuilds = new Properties();
completedBuilds.load(new FileInputStream(file));
} catch (IOException ioe) {
throw new RuntimeException(ioe.getMessage());
}
}
/**
* Clients must override the abstract build method to do whatever scan they want on the given build
* @param build
* @return boolean success
*/
public abstract boolean build(Build build);
/**
* set the minimum timestamp to start scanning from
* @param minTS
*/
public void setMinTS(long minTS) {
this.minTS = minTS;
}
/**
* set the base architecture param
* @param basearch
*/
public void setBasearch(String basearch) {
this.basearch = basearch;
}
/**
* Set the base operating system
* @param baseos
*/
public void setBaseos(String baseos) {
this.baseos = baseos;
}
/**
* Set the base ws, same as os usually
* @param basews
*/
public void setBasews(String basews) {
this.basews = basews;
}
/**
* Set the ssh login to upload results
* @param login
*/
public void setLogin(String login) {
this.login = login;
}
/**
* The default build method wraps the actually building and updating of the cache
* @return String
*/
public String build() {
latestBuild = null;
build2(URL_BUILD_PUBLIC, true);
if (latestBuild == null && acceptCommitterBuilds())
build2(URL_BUILD_COMMITTER, false);
if (latestBuild != null) {
if (build(latestBuild)) {
update(latestBuild);
return latestBuild.toString();
}
}
return null;
}
/**
* Should the scan accept committer builds or only public declared ones?
* @return boolean
*/
protected boolean acceptCommitterBuilds() {
return true;
}
/**
* This is a helper method which will grab the latest build from the appropriate build site
* @param buildURL
* @param publicBuild
*/
private void build2(String buildURL, boolean publicBuild) {
InputStream is = null;
BufferedReader br = null;
try {
URL url = new URL(buildURL);
is = url.openConnection().getInputStream();
br = new BufferedReader(new InputStreamReader(is));
String s = br.readLine();
while (s != null) {
String start = "href=\"drops/"; //$NON-NLS-1$
String end = "/"; //$NON-NLS-1$
int startIndex = s.indexOf(start);
int streamIndex = s.indexOf(end, startIndex + start.length());
int endIndex = s.indexOf(end, streamIndex + end.length());
while (startIndex != -1 && streamIndex != -1 && endIndex != -1) {
String stream = s.substring(startIndex + start.length(), streamIndex);
String buildLabel = s.substring(streamIndex + end.length(), endIndex);
if (buildLabel.length() > 0 && !completedBuilds.containsKey(buildLabel)) {
String[] buildFragments = buildLabel.split("-"); //$NON-NLS-1$
if (buildFragments.length > 2 && buildFragments[0].length() == 1 && buildFragments[2].length() > 11) {
if (Long.parseLong(buildFragments[2]) >= minTS) {
Build build = new Build(publicBuild, buildFragments[0], buildFragments[1], buildFragments[2].substring(0, 8), buildFragments[2].substring(8), stream);
if (latestBuild == null || !latestBuild.isNewer(build)) {
latestBuild = build;
}
}
}
}
startIndex = s.indexOf(start, endIndex + end.length());
streamIndex = s.indexOf(end, startIndex + start.length());
endIndex = s.indexOf(end, streamIndex + end.length());
}
s = br.readLine();
}
} catch (IOException ioe) {
throw new RuntimeException(ioe.getMessage());
} catch (NumberFormatException nfe) {
throw new RuntimeException(nfe.getMessage());
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ioe) {
}
}
if (br != null) {
try {
br.close();
} catch (IOException ioe) {
}
}
}
}
/**
* Updates the cache of completed builds with the given build argument
* @param build
*/
public void update(Build build) {
if (build.isPublicBuild())
completedBuilds.put(build.toString(), PUBLIC);
else
completedBuilds.put(build.toString(), COMMITTER);
try {
completedBuilds.store(new FileOutputStream(completedBuildsFilename), ""); //$NON-NLS-1$
} catch (IOException ioe) {
throw new RuntimeException(ioe.getMessage());
}
}
/**
* The main driver method for the builder which controls the build method invocation
*/
protected void main() {
if (baseos != null)
System.setProperty(BASE_OS, baseos);
if (basews != null)
System.setProperty(BASE_WS, basews);
if (basearch != null)
System.setProperty(BASE_ARCH, basearch);
if (login != null)
System.setProperty(LOGIN, login);
System.setProperty(CLEAN, Boolean.TRUE.toString());
try {
build();
} catch (Throwable t) {
t.printStackTrace();
}
}
}