/*******************************************************************************
* Copyright (c) 2006-2015
* Software Technology Group, Dresden University of Technology
* DevBoost GmbH, Dresden, Amtsgericht Dresden, HRB 34001
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Software Technology Group - TU Dresden, Germany;
* DevBoost GmbH - Dresden, Germany
* - initial API and implementation
******************************************************************************/
package de.devboost.buildboost;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import de.devboost.buildboost.model.IBuildConfiguration;
import de.devboost.buildboost.model.IBuildStage;
import de.devboost.buildboost.util.ScriptSaver;
import de.devboost.buildboost.util.StreamUtil;
public class BuildScriptGeneratorRunner {
public static void main(String[] args) throws BuildException {
if (args.length < 2) {
System.out.println("Wrong call to BuildScriptGeneratorRunner.main().");
System.out.println("Usage: BuildScriptGeneratorRunner.main(pathToWorkspace, classToRun).");
System.exit(1);
return;
}
new BuildScriptGeneratorRunner().run(args);
}
private void run(String[] args) throws BuildException {
String workspace = args[0];
String classToRun = args[1];
File stageFile = getStageFile(workspace);
String stage = readLastStage(stageFile);
int stageNumber = Integer.parseInt(stage);
writeNextStage(stageFile, stageNumber);
Class<?> clazzToRun = loadClassToRun(classToRun);
System.out.println("INFO: BuildScriptGeneratorRunner: Generating script for stage " + stageNumber);
System.out.println("INFO: BuildScriptGeneratorRunner: Generator class " + clazzToRun.getName());
boolean isBuildConfiguration = IBuildConfiguration.class.isAssignableFrom(clazzToRun);
System.out.println("INFO: BuildScriptGeneratorRunner: Generator class implements "
+ IBuildConfiguration.class.getName());
if (isBuildConfiguration) {
// instantiate and call via interface
callViaInterface(clazzToRun, workspace, stageNumber);
} else {
// call main method (for backward compatibility)
callMainMethod(clazzToRun, args);
}
}
private File getStageFile(String workspace) {
return new File(new File(workspace, "build"), "current_stage");
}
private Class<?> loadClassToRun(String classToRun) throws BuildException {
Class<?> clazzToRun;
try {
clazzToRun = Class.forName(classToRun);
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new BuildException("Can't find class " + classToRun);
}
return clazzToRun;
}
private void callViaInterface(Class<?> clazzToRun, String workspace, int stageNumber) throws BuildException {
try {
Object newInstance = clazzToRun.newInstance();
IBuildConfiguration configuration = (IBuildConfiguration) newInstance;
List<IBuildStage> buildStages = configuration.getBuildStages(workspace);
IBuildStage currentStage = buildStages.get(stageNumber - 1);
String buildDir = workspace + File.separator + "build";
ScriptSaver scriptSaver = new ScriptSaver();
File targetDir = new File(buildDir);
scriptSaver.saveStage(targetDir, currentStage, scriptSaver.getStageFileName(stageNumber));
scriptSaver.saveMasterScript(targetDir, buildStages);
// if this is the last stage, we must remove the 'current_stage' stage file, because
// otherwise subsequent builds will not start at the first stage. this particularly
// applies to the bootstrapping build.
if (stageNumber == buildStages.size()) {
File stageFile = getStageFile(workspace);
stageFile.delete();
}
} catch (InstantiationException e) {
e.printStackTrace();
throw new BuildException("Can't instantiate class " + clazzToRun.getName());
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new BuildException("Can't access class " + clazzToRun.getName());
}
}
private void callMainMethod(Class<?> clazzToRun, String[] args) throws BuildException {
Method mainMethod;
try {
mainMethod = clazzToRun.getMethod("main", String[].class);
} catch (SecurityException e) {
e.printStackTrace();
throw new BuildException("Can't access method main() in class " + clazzToRun.getName());
} catch (NoSuchMethodException e) {
e.printStackTrace();
throw new BuildException("Can't find method main() in class " + clazzToRun.getName());
}
try {
mainMethod.invoke(null, (Object) args);
} catch (IllegalArgumentException e) {
e.printStackTrace();
throw new BuildException("Can't invoke main method in class " + clazzToRun.getName());
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new BuildException("Can't invoke main method in class " + clazzToRun.getName());
} catch (InvocationTargetException e) {
e.printStackTrace();
throw new BuildException("Can't invoke main method in class " + clazzToRun.getName());
}
}
private void writeNextStage(File stageFile, int stageNumber) throws BuildException {
try {
FileWriter writer = new FileWriter(stageFile);
writer.write(Integer.toString(stageNumber + 1));
writer.close();
} catch (IOException ioe) {
throw new BuildException("Can't write stage file (" + ioe.getMessage() + ").");
}
}
private String readLastStage(File stageFile) throws BuildException {
if (stageFile.exists()) {
try {
FileInputStream fis = new FileInputStream(stageFile);
String stage = new StreamUtil().getContentAsString(fis);
fis.close();
return stage;
} catch (IOException ioe) {
throw new BuildException("Can't read stage file (" + ioe.getMessage() + ").");
}
}
return "1";
}
}