package xvrengine.ui;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.ResourcesPlugin;
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.xvr.xvrengine.parser.XVRPrj;
import org.xvr.xvrengine.util.Assert;
import org.xvr.xvrengine.util.XVRUtils;
import xvrengine.XVRPlugin;
import xvrengine.builders.XVRBuilder;
import xvrengine.natures.XVRNature;
public class XVRProjectSupport {
public static final String S3D_EXTENSION = ".s3d";
//public static final String FOLDER_SRC = "src";
public static final String FOLDER_MEDIA = "VRMedia";
public static final String FOLDER_TEMPLATE = "/template";
public static final String ARG_COMPILER_KEY = "COMPILER";
public static final String ARG_COMPILER_VAL = FOLDER_MEDIA + "/s3dc.exe";
public static final String ARG_INCLUDE_KEY = "INCLUDE";
public static final String ARG_INCLUDE_VAL = FOLDER_MEDIA + "/Include";
public static final String ARG_MAIN_KEY = "MAIN";
public static final String ARG_MAIN_HTML_KEY = "MAIN_HTML";
//public static final String ARG_MAIN_VAL = FOLDER_SRC + "\\main.s3d";
public static final String ARG_GLUT = "GLUT";
public static final String ARG_GLUT_VAL = FOLDER_MEDIA + "/XVRGlut.exe";
public static final String ARG_GLUT_64 = "GLUT_64";
public static final String ARG_GLUT_64_VAL = FOLDER_MEDIA + "/XVRGlut_64.exe";
public static final String ARG_FS = "XVRFULLSCREEN";
public static final String ARG_FS_VAL = FOLDER_MEDIA + "/XVRFullScreen.exe";
public static final String ARG_PARAM_FILE_KEY = "COMMAND_LINE_PARAMS_FILE";
public static final String ARG_PARAM_FILE_VAL = ".xvruntime";
public static final String ARG_INCLUDE_DIRS_PARAM_KEY = "INCLUDE_DIRS_PARAMS";
public static final String ARG_INCLUDE_DIRS_PARAM_VAL = "";
public static final String ARG_GLUT_PARAM_KEY = "GLUT_COMMAND_LINE_PARAMS";
public static final String ARG_GLUT_PARAM_VAL = "";
public static final String ARG_GLUT_PARAM_ACTIVE_KEY = "GLUT_COMMAND_LINE_PARAMS_ACTIVE";
public static final String ARG_GLUT_PARAM_ACTIVE_VAL = "-1";
public static final String ARG_FS_PARAM_KEY = "FS_COMMAND_LINE_PARAMS";
public static final String ARG_FS_PARAM_VAL = "";
public static final String ARG_FS_PARAM_ACTIVE_KEY = "FS_COMMAND_LINE_PARAMS_ACTIVE";
public static final String ARG_FS_PARAM_ACTIVE_VAL = "-1";
//private static final String BIN_EXTENSION = ".bin";
public static void importProject(XVRPrj parse, String prj_name, boolean active) {
//String prj_name = parse.getProjectName();
String prj_dir = parse.getProjectDir();
IProject newProject = ResourcesPlugin.getWorkspace().getRoot().getProject(prj_name);
if (newProject.exists()) {
XVRUtils.displayError(prj_name + " already exist.\n");
return;
}
URI projectLocation = XVRUtils.getFile(prj_dir).toURI();
IProjectDescription desc = newProject.getWorkspace().newProjectDescription(newProject.getName());
desc.setLocationURI(projectLocation);
desc.setNatureIds(new String[]{XVRNature.NATURE_ID});
String main_html = parse.getActiveHTML();
String main_s3d = parse.getActiveS3D();
Assert.assertNotNull(main_html);
Assert.assertNotNull(main_s3d);
//add builder to project
ICommand command = desc.newCommand();
command.setBuilderName(XVRBuilder.BUILDER_ID);
//Here we have to create builder command arguments(compiler and include locations)
Map<String, String> args = new HashMap<String, String>();
args.put(ARG_COMPILER_KEY, ARG_COMPILER_VAL);
args.put(ARG_INCLUDE_KEY, ARG_INCLUDE_VAL);
args.put(ARG_MAIN_KEY, main_s3d);
args.put(ARG_MAIN_HTML_KEY, main_html);
args.put(ARG_GLUT, ARG_GLUT_VAL);
args.put(ARG_FS, ARG_FS_VAL);
args.put(ARG_PARAM_FILE_KEY, ARG_PARAM_FILE_VAL);
args.put(ARG_GLUT_PARAM_KEY, ARG_GLUT_PARAM_VAL);
args.put(ARG_GLUT_PARAM_ACTIVE_KEY, ARG_GLUT_PARAM_ACTIVE_VAL);
args.put(ARG_INCLUDE_DIRS_PARAM_KEY, ARG_INCLUDE_DIRS_PARAM_VAL);
command.setArguments(args);
desc.setBuildSpec(new ICommand[]{command});
try {
newProject.create(desc, new NullProgressMonitor());
if (!newProject.isOpen())
newProject.open(new NullProgressMonitor());
} catch (CoreException e){
e.printStackTrace();
XVRUtils.displayError("Error while creating the new project.\n" + e.getMessage());
return;
}
if(active)
XVRUtils.setActiveProject(newProject);
}
public static void importProject(XVRPrj resources, String prj_name, URI location, boolean active){
Assert.assertNotNull(resources);
IProject project = createBaseProject(prj_name, location);
try {
Iterator<String> it;
//adds s3d files
it = resources.getS3DIterator();
while(it.hasNext()){
addFile(project, resources.getProjectDir(), it.next());
}
//adds htmls
it = resources.getHTMLIterator();
while(it.hasNext()){
addFile(project, resources.getProjectDir(), it.next());
}
//adds resources
it = resources.getResourceIterator();
while(it.hasNext()){
addFile(project, resources.getProjectDir(), it.next());
}
addNature(project);
addBuilder(project, resources.getActiveS3D(), resources.getActiveHTML());
} catch (CoreException e) {
XVRUtils.displayError("Error while creating the new project.\n"+e.getMessage());
e.printStackTrace();
project = null;
}
if(active)
XVRUtils.setActiveProject(project);
}
private static void addFile(IProject project, String prj_root, String relative) {
IFile main = null;
String s = relative.replaceAll("\\\\", "/");
if(s.charAt(0)!= '/')
s = "/"+relative;
int last = s.lastIndexOf("/") + 1;
String path = s.substring(0, last);
String name = s.substring(last);
try {
if(path.lastIndexOf('/') == path.indexOf('/')){
main = project.getFile(name);
}else{
IFolder folder = project.getFolder(path);
if(!folder.exists())
folder.create(false, false, null);
main = folder.getFile(name);
}
String fpath = prj_root + System.getProperty("file.separator") + relative;
File fin = new File(fpath);
if(!fin.exists()){
XVRUtils.displayError("The file " + fpath + " can not be found.");
return;
}
main.create(new FileInputStream(fin), true, null);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (CoreException e){
e.printStackTrace();
}
}
/**
* Creates an new empty project with the specified name or <code>null</code> if something wrong happens.
* The new project will contain an empty s3d file and an html page with the embedded script.
* @param name The name of the new project.
* @param location The location where the project should be created.
* @param active Whether the project has to be set as active or not
* @param htmlType Which kind of html page, static or dynamic, should be created.
* @return The newly created project or <code>null</code> if something wrong happens.
*/
public static IProject createEmptyProject(String name, URI location, boolean active) {
Assert.assertNotNull(name);
Assert.assertTrue(name.trim().length() != 0);
IProject project = createBaseProject(name, location);
try {
// String[] paths = { FOLDER_SRC };
// addToProjectStructure(project, paths);
String main_file_name = name.concat(S3D_EXTENSION);
String main_location = addEmptyFile(project, "/", main_file_name);
//addTemplateFile(project, "/", FOLDER_TEMPLATE + "/index.html", "index.html");
//addHTML(project, main_location, "/", "index.html", htmlType);
addNature(project);
addBuilder(project, main_location, "index.html");
if(active)
XVRUtils.setActiveProject(project);
} catch (CoreException e) {
XVRUtils.displayError("Error while creating the new project.\n"+e.getMessage());
e.printStackTrace();
project = null;
}
return project;
}
/**
* Adds an empty file in the <code>project</code>.
* The file <code>file_name</code> will be created in the specified folder <code>location</code>
* @param project The project to which add the file
* @param location The file location in the project
* @param file_name The name of the new file.
* @return The relative path of the created file inside the project or <code>null</code> if something goes wrong.
*/
private static String addEmptyFile(IProject project, String location, String file_name) {
IFile main = null;
if(location.compareTo("/") == 0){
main = project.getFile(file_name);
}else{
IFolder folder = project.getFolder(location);
if(!folder.exists()){
XVRUtils.displayError("The file " + file_name + " could not be created cause the folder " + location + " does not exists.");
return null;
}
main = folder.getFile(file_name);
}
try {
main.create(new ByteArrayInputStream(new byte[0]), false, null);
}
catch (CoreException e){
XVRUtils.displayError("The file " + file_name + " could not be created cause in the folder " + location + "\n" + e.getMessage());
e.printStackTrace();
return null;
}
return main.getProjectRelativePath().toOSString();
}
// /**
// * For this marvelous project we need to:
// * - create the default Eclipse project
// * - add the custom project nature
// * - create the folder structure
// *
// * @param projectName
// * @param location
// * @param natureId
// * @return
// */
// public static IProject createProject(String projectName, URI location, boolean active, HTMLType htmlType) {
// Assert.assertNotNull(projectName);
// Assert.assertTrue(projectName.trim().length() != 0);
//
// IProject project = createBaseProject(projectName, location);
// try {
// String[] paths = { FOLDER_SRC };
// addToProjectStructure(project, paths);
// String main_file_name = projectName.concat(S3D_EXTENSION);
// String main_location = addTemplateFile(project, FOLDER_SRC, FOLDER_TEMPLATE + "/main.s3d", main_file_name);
// //addTemplateFile(project, "/", FOLDER_TEMPLATE + "/index.html", "index.html");
// addHTML(project, main_location, "/", "index.html", htmlType);
//
// addNature(project);
// addBuilder(project, main_location, "index.html");
//
// } catch (CoreException e) {
// e.printStackTrace();
// project = null;
// }
//
// if(active)
// XVRUtils.setActiveProject(project);
//
// return project;
// }
public static IProject createProject(String projectName, URI location, String template_path, boolean active) {
Assert.assertNotNull(projectName);
Assert.assertTrue(projectName.trim().length() != 0);
IProject project = createBaseProject(projectName, location);
try {
// String[] paths = { FOLDER_SRC };
// addToProjectStructure(project, paths);
String main_file_name = projectName.concat(S3D_EXTENSION);
String main_location = addTemplateFile(project, "/", template_path , main_file_name);
//addTemplateFile(project, "/", FOLDER_TEMPLATE + "/index.html", "index.html");
//addHTML(project, main_location, "/", "index.html", htmlType);
addNature(project);
addBuilder(project, main_location, "index.html");
} catch (CoreException e) {
e.printStackTrace();
project = null;
}
if(active)
XVRUtils.setActiveProject(project);
return project;
}
private static void addBuilder(IProject project, String main_location, String main_html) throws CoreException {
Assert.assertNotNull(main_html);
Assert.assertNotNull(main_location);
Assert.assertNotNull(project);
IProjectDescription desc = project.getDescription();
ICommand[] commands = desc.getBuildSpec();
boolean found = false;
for (int i = 0; i < commands.length; ++i) {
if (commands[i].getBuilderName().equals(XVRBuilder.BUILDER_ID)) {
found = true;
break;
}
}
if (!found) {
//add builder to project
ICommand command = desc.newCommand();
command.setBuilderName(XVRBuilder.BUILDER_ID);
//Here we have to create builder command arguments(compiler and include locations)
Map<String, String> args = new HashMap<String, String>();
args.put(ARG_COMPILER_KEY, ARG_COMPILER_VAL);
args.put(ARG_INCLUDE_KEY, ARG_INCLUDE_VAL);
args.put(ARG_MAIN_KEY, main_location);
args.put(ARG_MAIN_HTML_KEY, main_html);
args.put(ARG_GLUT, ARG_GLUT_VAL);
args.put(ARG_FS, ARG_FS_VAL);
args.put(ARG_PARAM_FILE_KEY, ARG_PARAM_FILE_VAL);
args.put(ARG_GLUT_PARAM_KEY, ARG_GLUT_PARAM_VAL);
args.put(ARG_GLUT_PARAM_ACTIVE_KEY, ARG_GLUT_PARAM_ACTIVE_VAL);
args.put(ARG_INCLUDE_DIRS_PARAM_KEY, ARG_INCLUDE_DIRS_PARAM_VAL);
command.setArguments(args);
ICommand[] newCommands = new ICommand[commands.length + 1];
// Add it before other builders.
System.arraycopy(commands, 0, newCommands, 1, commands.length);
newCommands[0] = command;
desc.setBuildSpec(newCommands);
project.setDescription(desc, null);
}
}
/**
* Just do the basics: create a basic project.
*
* @param location
* @param projectName
*/
private static IProject createBaseProject(String projectName, URI location) {
// it is acceptable to use the ResourcesPlugin class
IProject newProject = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
if (!newProject.exists()) {
URI projectLocation = null;
if(location != null){
try {
projectLocation = new URI(location.toString() + "/" + projectName);
} catch (URISyntaxException e){
XVRUtils.displayError("Error while creating the project location. The project will be created in the default folder.\n" + e.getMessage());
e.printStackTrace();
}
}
else
projectLocation = location;
IProjectDescription desc = newProject.getWorkspace().newProjectDescription(newProject.getName());
if (location != null && ResourcesPlugin.getWorkspace().getRoot().getLocationURI().equals(location)) {
projectLocation = null;
}
desc.setLocationURI(projectLocation);
try {
newProject.create(desc, null);
if (!newProject.isOpen()) {
newProject.open(null);
}
} catch (CoreException e) {
e.printStackTrace();
}
}
return newProject;
}
private static void createFolder(IFolder folder) throws CoreException {
IContainer parent = folder.getParent();
if (parent instanceof IFolder) {
createFolder((IFolder) parent);
}
if (!folder.exists()) {
folder.create(false, true, null);
}
}
// /**
// * Adds a new file from template to the project.
// * @param project The project to which adds the new file.
// * @param path The relative path where add the new file.
// * @param template The name of the template to be used.
// */
// private static void addTemplateFile(IProject project, String path, String template){
// IFile main = null;
//
// if(path.compareTo("/") == 0){
// main = project.getFile(template);
// }else{
// IFolder folder = project.getFolder(path);
// if(!folder.exists()) return;
// main = folder.getFile(template);
// }
//
// try {
// File f = XVRUtils.getFile(template);
// main.create(new FileInputStream(f), false, null);
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// } catch (CoreException e){
// e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
/**
* Adds a new file from template to the project.
* @param project The project to which adds the new file.
* @param path The relative path where add the new file.
* @param template The name of the template to be used.
* @param name the name for the new file.
*
* @return The relative path of the newly created file or null if something goes wrong.
*/
private static String addTemplateFile(IProject project, String path, String template, String name){
IFile main = null;
if(path.compareTo("/") == 0){
main = project.getFile(name);
}else{
IFolder folder = project.getFolder(path);
if(!folder.exists()) return null;
main = folder.getFile(name);
}
try {
main.create(FileLocator.openStream(XVRPlugin.getDefault().getBundle(), new Path(template), true), true, null);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (CoreException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return main.getProjectRelativePath().toOSString();
}
// private static String addHTML(IProject prj, String active_s3d, String path, String f_name, HTMLType htmlType){
// String doc_content = null;
// if(htmlType == HTMLType.STATIC)
// doc_content = HTMLWizardUtils.getDefaultStaitcHTMLDocument(prj.getName(), active_s3d + BIN_EXTENSION);
// else
// doc_content = HTMLWizardUtils.getDefaultDynamicHTMLDocument(prj.getName(), active_s3d + BIN_EXTENSION);
//
// IFile file = null;
//
// if(path.compareTo("/") == 0){
// file = prj.getFile(f_name);
// }else{
// IFolder folder = prj.getFolder(path);
// if(!folder.exists()) return null;
// file = folder.getFile(f_name);
// }
//
// InputStream is = new ByteArrayInputStream(doc_content.getBytes());
// try {
// file.create(is, true, new NullProgressMonitor());
// } catch (CoreException e) {
// e.printStackTrace();
// }
//
// return file.getProjectRelativePath().toOSString();
// }
/**
* Create a folder structure with a parent root, overlay, and a few child
* folders.
*
* @param newProject
* @param paths
* @throws CoreException
*/
private static void addToProjectStructure(IProject newProject, String[] paths) throws CoreException {
for (String path : paths) {
IFolder etcFolders = newProject.getFolder(path);
createFolder(etcFolders);
}
}
private static void addNature(IProject project) throws CoreException {
if (!project.hasNature(XVRNature.NATURE_ID)) {
IProjectDescription description = project.getDescription();
String[] prevNatures = description.getNatureIds();
String[] newNatures = new String[prevNatures.length + 1];
System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
newNatures[prevNatures.length] = XVRNature.NATURE_ID;
description.setNatureIds(newNatures);
IProgressMonitor monitor = null;
project.setDescription(description, monitor);
}
}
}