package xvrengine.builders;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.core.internal.resources.ResourceStatus;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.ide.IDE;
import org.osgi.framework.Bundle;
import org.xvr.console.CompilerConsoleHandler;
import org.xvr.xvrengine.preferences.PreferenceConstants;
import org.xvr.xvrengine.util.XVRConstants;
import org.xvr.xvrengine.util.XVRUtils;
import xvrengine.XVRPlugin;
import xvrengine.ui.XVRProjectSupport;
@SuppressWarnings("restriction")
public class XVRBuilder extends IncrementalProjectBuilder {
public static final String BUILDER_ID = "xvrengine.builders.XVRBuilder";
public static final QualifiedName KEY_MAIN_FILE = new QualifiedName("xvrengine.builder", "MAIN_FILE");
public static final QualifiedName KEY_MAIN_HTML = new QualifiedName("xvrengine.builder", "MAIN_HTML");
public static final QualifiedName KEY_GLUT = new QualifiedName("xvrengine.builder", "GLUT");
public static final QualifiedName KEY_GLUT_64 = new QualifiedName("xvrengine.builder", "GLUT64");
public static final QualifiedName KEY_FS = new QualifiedName("xvrengine.builder", "XVRFullScreen");
public static final QualifiedName KEY_GLUT_PARAMS = new QualifiedName("xvrengine.glut_params", "GLUT");
public static final QualifiedName KEY_FS_PARAMS = new QualifiedName("xvrengine.fs_params", "FS");
public static final QualifiedName KEY_INCLUDE_DIRS_PARAMS = new QualifiedName("xvrengine.include_dirs", "INCLUDE_DIRS");
private boolean initialized;
//private File compiler;
private String compiler_path;
private String include_path;
private String main_file;
private String main_html;
private String vm_glut;
private String vm_glut_64;
private String vm_fs;
private String glut_params;
private String fs_params;
private String include_dirs;
public XVRBuilder() {
this.initialized = false;
}
private String getGlutPath(Map<String, String> args, String glutType, String glutDefault) throws CoreException{
String glut = args.get(glutType);
if(glut == null)
//throw new CoreException(new Status(Status.ERROR, XVRPlugin.PLUGIN_ID, "XVRGLUT not found.\nCheck the xvr runtime properties of the project"));
glut = glutDefault;
File temp = XVRUtils.getFile(glut);
if(temp == null)
throw new CoreException(new Status(Status.ERROR, XVRPlugin.getPluginID(), "Virtual machine(glut) not found: " + this.vm_glut));
return temp.getAbsolutePath();
}
protected boolean initBuilder(Map<String, String> args) throws CoreException{
File temp;
this.compiler_path = args.get(XVRProjectSupport.ARG_COMPILER_KEY);
if(this.compiler_path == null)
throw new CoreException(new Status(Status.ERROR, XVRPlugin.PLUGIN_ID, "Compiler not found.\nCheck the xvr runtime properties of the project"));
temp = XVRUtils.getFile(this.compiler_path);
this.compiler_path = temp.getAbsolutePath();
this.include_path = args.get(XVRProjectSupport.ARG_INCLUDE_KEY);
if(this.include_path == null)
throw new CoreException(new Status(Status.ERROR, XVRPlugin.PLUGIN_ID, "Include directory not found.\nCheck the xvr runtime properties of the project"));
temp = XVRUtils.getFile(this.include_path);
this.include_path = temp.getAbsolutePath();
// this.vm_glut = args.get(XVRProjectSupport.ARG_GLUT);
// if(this.vm_glut == null)
// //throw new CoreException(new Status(Status.ERROR, XVRPlugin.PLUGIN_ID, "XVRGLUT not found.\nCheck the xvr runtime properties of the project"));
// this.vm_glut = XVRProjectSupport.ARG_GLUT_VAL;
//
// temp = XVRUtils.getFile(this.vm_glut);
// if(temp == null)
// throw new CoreException(new Status(Status.ERROR, XVRPlugin.getPluginID(), "Virtual machine(glut) not found: " + this.vm_glut));
// this.vm_glut = temp.getAbsolutePath();
this.vm_glut = this.getGlutPath(args, XVRProjectSupport.ARG_GLUT, XVRProjectSupport.ARG_GLUT_VAL);
this.vm_glut_64 = this.getGlutPath(args, XVRProjectSupport.ARG_GLUT_64, XVRProjectSupport.ARG_GLUT_64_VAL);
System.out.println(this.vm_glut_64);
this.vm_fs = args.get(XVRProjectSupport.ARG_FS);
if(this.vm_fs == null)
//throw new CoreException(new Status(Status.ERROR, XVRPlugin.PLUGIN_ID, "XVRFullScreen not found.\nCheck the xvr runtime properties of the project"));
this.vm_fs = XVRProjectSupport.ARG_FS_VAL;
temp = XVRUtils.getFile(this.vm_fs);
this.vm_fs = temp.getAbsolutePath();
this.main_file = args.get(XVRProjectSupport.ARG_MAIN_KEY);
if(this.main_file == null)
throw new CoreException(new Status(Status.ERROR, XVRPlugin.PLUGIN_ID, "No active S3D file found.\nCheck the xvr runtime properties of the project"));
this.main_html = args.get(XVRProjectSupport.ARG_MAIN_HTML_KEY);
this.glut_params= args.get(XVRProjectSupport.ARG_GLUT_PARAM_KEY);
this.fs_params= args.get(XVRProjectSupport.ARG_FS_PARAM_KEY);
this.include_dirs = args.get(XVRProjectSupport.ARG_INCLUDE_DIRS_PARAM_KEY);
return true;
}
@SuppressWarnings("unchecked")
@Override
protected IProject[] build(int kind, @SuppressWarnings("rawtypes") Map args, IProgressMonitor monitor) throws CoreException {
try {
this.initialized = this.initBuilder(args);
} catch (CoreException e) {
XVRUtils.displayError(e.getMessage());
}
setProjectLaunchProperties(getProject());
fullBuild((String) args.get(XVRConstants.BUILD_MODE), monitor);
return null;
}
private void setProjectLaunchProperties(IProject prj) throws CoreException {
prj.setSessionProperty(XVRBuilder.KEY_MAIN_FILE, this.main_file);
prj.setSessionProperty(XVRBuilder.KEY_MAIN_HTML, this.main_html);
prj.setSessionProperty(XVRBuilder.KEY_GLUT, this.vm_glut);
prj.setSessionProperty(XVRBuilder.KEY_GLUT_64, this.vm_glut_64);
prj.setSessionProperty(XVRBuilder.KEY_FS, this.vm_fs);
prj.setSessionProperty(XVRBuilder.KEY_GLUT_PARAMS, this.glut_params);
prj.setSessionProperty(XVRBuilder.KEY_FS_PARAMS, this.fs_params);
}
protected boolean fullBuild(String mode, IProgressMonitor monitor) throws CoreException{
return compile(mode, monitor);
}
private boolean compile(String mode, IProgressMonitor monitor) throws CoreException{
if(!this.initialized)
throw new CoreException(new Status(Status.ERROR, XVRPlugin.PLUGIN_ID, "The builder has not been properly initialized"));
final IProject prj = getProject();
SubMonitor buildMonitor = SubMonitor.convert(monitor, "Building project " + prj.getName(), 50);
//Save all changes
buildMonitor.subTask("Saving editors");
Display.getDefault().syncExec(new Runnable() { // save all editors needs to be called by the ui thread!
@Override
public void run() {
IDE.saveAllEditors(new IResource[]{prj}, !XVRUtils.getBooleanPreference(PreferenceConstants.GEN_AUTO_SAVE_ON_BUILD));
}
});
buildMonitor.worked(30);
buildMonitor.subTask("compiling");
List<String> compilerArgs = new ArrayList<String>();
compilerArgs.add(this.compiler_path);
//Add main source file
compilerArgs.add(this.main_file.replace("\\", "/"));
if(mode != null && mode.equals(ILaunchManager.DEBUG_MODE))
compilerArgs.add("-G");
//adds first the include directories specified by the user
if(this.include_dirs != null && !this.include_dirs.isEmpty()){
compilerArgs.add("-I");
compilerArgs.add(this.include_dirs);
}
//then the default one.
compilerArgs.add("-I");
compilerArgs.add(this.include_path);
compilerArgs.add("-A");
//aggiunto parametro -p nel compilatore per definire dove volgiamo che sia salvato il risultato della compilazione
//adesso devo dare la possibilita di definire una directory in cui mettere i file compilati e poi fare in modo che i template generino sia src che bin(che eventualmente nascondo oppure mostro anche bin, asm e dbg)
/*compilerArgs.add("-p");
compilerArgs.add("bin/prova.bin");*/
String[] commandLine = (String[]) compilerArgs.toArray(new String[compilerArgs.size()]);
ProcessBuilder builder = new ProcessBuilder(commandLine);
builder.directory( new File(prj.getLocation().toString()));
builder.redirectErrorStream(true);
final Process compilerProcess;
//ILaunch l = XVRUtils.getXVRLaunh();
buildMonitor.worked(10);
try {
compilerProcess = builder.start();
} catch (IOException e1) {
e1.printStackTrace();
buildMonitor.done();
throw new CoreException(new ResourceStatus(ResourceStatus.BUILD_FAILED, "Compilation of " + prj.getName() + " failed due to the following exception: " + e1.getMessage()));
}
CompilerConsoleHandler.dumpBuildMessages(compilerProcess.getInputStream());
try {
compilerProcess.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
finally{
buildMonitor.worked(60);
buildMonitor.done();
}
if(compilerProcess.exitValue() != 0)
//throw new CoreException(new Status(Status.ERROR, XVRPlugin.PLUGIN_ID, "Compilation of " + prj.getName() + "failed and returns with code : " + compilerProcess.exitValue()));
throw new CoreException(new ResourceStatus(ResourceStatus.BUILD_FAILED, "Compilation of " + prj.getName() + " failed and returns with code : " + compilerProcess.exitValue()));
prj.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
return true;
}
protected static File openFile(String path){
Bundle bundle = XVRPlugin.getDefault().getBundle();
URL url = FileLocator.find(bundle, new Path(path), null);
if(url == null)
return null;
try {
url = FileLocator.resolve(url);
} catch (IOException e) {
e.printStackTrace();
return null;
}
return new Path(url.getFile()).toFile();
}
}