diff --git a/editor/processing.plugin.core/src/processing/plugin/core/ProcessingCore.java b/editor/processing.plugin.core/src/processing/plugin/core/ProcessingCore.java index 11e22ee25..48c3a889e 100644 --- a/editor/processing.plugin.core/src/processing/plugin/core/ProcessingCore.java +++ b/editor/processing.plugin.core/src/processing/plugin/core/ProcessingCore.java @@ -13,6 +13,8 @@ import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; import java.util.MissingResourceException; import java.util.ResourceBundle; @@ -21,6 +23,9 @@ import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Plugin; import processing.plugin.core.builder.Utilities; @@ -87,11 +92,34 @@ public final class ProcessingCore extends Plugin { } } + /** + * Resolves the plug-in resources folder to a File and returns it. This will include the + * Processing libraries and the core libraries folder. + * + * @return File reference to the core resources + */ + public File getPluginResourceFolder(){ + URL fileLocation = ProcessingCore.getProcessingCore().getPluginResource(""); + try { + File folder = new File(FileLocator.toFileURL(fileLocation).getPath()); + if (folder.exists()) + return folder; + } catch (Exception e) { + ProcessingLog.logError(e); + } + return null; + } + /** Returns a file handle to the plug-in's local cache folder. */ public File getBuiltInCacheFolder(){ return new File(this.getStateLocation().toString()); } + /** Returns a file handle to the temp folder in the plug-in's local cache*/ + public File getPluginTempFolder(){ + return new File(getBuiltInCacheFolder(), "temp"); + } + /** Returns the plug-in's resource bundle */ public ResourceBundle getResourceBundle(){ return resourceBundle; @@ -114,19 +142,19 @@ public final class ProcessingCore extends Plugin { } /** Returns true if the resource is a Processing file */ - public static boolean isPDEFile(IResource resource){ + public static boolean isProcessingFile(IResource resource){ if (resource.getType() == IResource.FILE) - return isPDEFilename(resource.getName()); + return isProcessingFile(resource.getName()); return false; } /** Returns true if the file is a Processing file */ - public static boolean isPDEFile(IFile resource) { - return isPDEFilename(resource.getName()); + public static boolean isProcessingFile(IFile resource) { + return isProcessingFile(resource.getName()); } /** Returns true if the file has a Processing extension */ - public static boolean isPDEFilename(String filename){ + public static boolean isProcessingFile(String filename){ return filename.endsWith(".pde"); } @@ -142,7 +170,7 @@ public final class ProcessingCore extends Plugin { public static boolean isLibrary(File rootFolder){ return isLibrary(rootFolder, false); } - + /** * Returns true if the folder is a Processing library root folder. * When complain is false only errors are logged and reported. When @@ -150,31 +178,51 @@ public final class ProcessingCore extends Plugin { * libraries will also be reported. */ public static boolean isLibrary(File rootFolder, boolean complain){ - if (rootFolder != null){ - String name = rootFolder.getName(); - try { - File libraryJar = new File(rootFolder.getCanonicalPath() + - File.separatorChar + "library" + File.separatorChar + - name + ".jar"); - if (libraryJar.exists()) - if (Utilities.sanitizeName(name).equals(name)){ - return true; - } else { - if(complain){ + if (rootFolder == null) return false; + if(!rootFolder.isDirectory()) return false; + + String name = rootFolder.getName(); + try { + File libraryJar = new File(rootFolder.getCanonicalPath() + + File.separatorChar + "library" + File.separatorChar + + name + ".jar"); + if (libraryJar.exists()) + if (Utilities.sanitizeName(name).equals(name)){ + return true; + } else { + if(complain){ String mess = "The library \"" + name + "\" cannot be used.\n" + "Library names must contain only basic letters and numbers.\n" + "(ASCII only and no spaces, and it cannot start with a number)"; ProcessingLog.logInfo("Ignoring bad library " + name + "\n" + mess); - } } - } catch (IOException e) { - ProcessingLog.logError("Problem checking librarary " + - name + ", could not resolve canonical path.", e); - } + } + } catch (IOException e) { + ProcessingLog.logError("Problem checking library " + + name + ", could not resolve canonical path.", e); } + return false; } + /** + * Finds the folder containing the Processing core libraries, which are bundled with the + * plugin. This folder doesn't exist in the workspace, so we return it as a File, not IFile. + * If something goes wrong, logs an error and returns null. + * + * @return File containing the core libraries folder or null + */ + public File getCoreLibsFolder() { + URL fileLocation = getPluginResource("libraries"); + try { + File folder = new File(FileLocator.toFileURL(fileLocation).getPath()); + if (folder.exists()) + return folder; + } catch (Exception e) { + ProcessingLog.logError(e); + } + return null; + } } diff --git a/editor/processing.plugin.core/src/processing/plugin/core/builder/SketchBuilder.java b/editor/processing.plugin.core/src/processing/plugin/core/builder/SketchBuilder.java index e73ccc745..e8947e751 100644 --- a/editor/processing.plugin.core/src/processing/plugin/core/builder/SketchBuilder.java +++ b/editor/processing.plugin.core/src/processing/plugin/core/builder/SketchBuilder.java @@ -1,11 +1,8 @@ package processing.plugin.core.builder; -import java.io.ByteArrayInputStream; import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.StringWriter; -import java.net.URL; +import java.io.FileWriter; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -17,17 +14,12 @@ 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.IPath; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.jdt.core.IClasspathEntry; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.launching.IVMInstall; -import org.eclipse.jdt.launching.JavaRuntime; import processing.app.Preferences; import processing.app.debug.RunnerException; @@ -35,7 +27,6 @@ import processing.app.preproc.PdePreprocessor; import processing.app.preproc.PreprocessResult; import processing.plugin.core.ProcessingCore; -import processing.plugin.core.ProcessingCorePreferences; import processing.plugin.core.ProcessingLog; /** @@ -107,47 +98,33 @@ public class SketchBuilder extends IncrementalProjectBuilder{ // truly separated from the UI. Possible create it in the PDE, and extend it // here for marker management and such. -// /** Data folder, located in the sketch folder, may not exist */ -// private IFolder dataFolder; + // /** Data folder, located in the sketch folder, may not exist */ + // private IFolder dataFolder; + + /** Full paths to source folders for the JDT */ + private ArrayListsrcFolderPathList; + + /** Full paths to jars required to compile the sketch */ + private ArrayListlibraryJarPathList; /** Code folder, located in the sketch folder, may not exist */ private IFolder codeFolder; /** A temporary build folder, will be created if it doesn't exist */ - private IFolder buildFolder; - - /** The output applet folder for after the compile */ - private IFolder appletFolder; - - /** The core libraries folder in the plug-in resources. */ - private File coreLibs; - - /** The SketchBook libraries folder, may not exist */ - private File sketchBookLibs; - - /** the library path for the compiler */ - private String libraryPath; - - /** the class path for the compiler */ - private String classPath; - - /** a list of library folders */ - private ArrayList importedLibraries; // list of library folders - - /** a table resolving a package to the folder containing its .jar */ - private HashMap importToLibraryTable; - - /** Supplied as a build argument, usually empty */ - private String packageName = ""; + private File buildFolder; /** Clean any leftover state from previous builds. */ protected void clean(SketchProject sketch, IProgressMonitor monitor) throws CoreException{ deleteP5ProblemMarkers(sketch); - if (buildFolder != null && buildFolder.exists()){ - for( IResource r : buildFolder.members()){ - r.delete(IResource.FORCE, monitor); - } - } + srcFolderPathList = new ArrayList(); + libraryJarPathList = new ArrayList(); + // if this is the first run of the builder the build folder will not be stored yet, + // but if there is an old build folder from a trial run it should still be nuked. + // get the handle to it from the project's configuration + Utilities.deleteFolderContents(sketch.getBuildFolder()); + + + // any other cleaning stuff goes here // Eventually, a model should control the markers, and once a model is // written it should be controlled by the SketchProject. Cleaning the model @@ -202,48 +179,45 @@ public class SketchBuilder extends IncrementalProjectBuilder{ return null; } - // Setup the folders - codeFolder = sketch.getFolder("code"); - buildFolder = sketch.getFolder("bin"); // TODO relocate to MyPlugin.getPlugin().getStateLocation().getFolder("bin") - appletFolder = sketch.getFolder("applet"); + // Get handles to the folders + codeFolder = sketchProject.getCodeFolder(); + buildFolder = sketchProject.getBuildFolder(); // null if it couldn't be created + + if (buildFolder == null){ + ProcessingLog.logError("Build folder could not be accessed.", null); + return null; + } monitor.beginTask("Sketch Build", 400); // not sure how much work to do here if(!sketch.isOpen()) { return null; } // has to be open to access it if(checkCancel(monitor)) { return null; } - // 1 . PREPARE - - if (!buildFolder.exists()) - buildFolder.create(IResource.NONE, true, null); - - monitor.worked(100); // 100 for every step of the process? - if(checkCancel(monitor)){ return null; } - - // 2 . PREPROCESS PdePreprocessor preproc = new PdePreprocessor(sketch.getName(), 4); - String[] codeFolderPackages = null; - classPath = buildFolder.getLocation().toOSString(); - // check the contents of the code folder to see if there are files that need to be added to the imports + // If the code folder exists: + // Find any .jar files in it and its subfolders + // Add their paths to the library jar list for addition to the class path later on + // Get the packages of those jars so they can be added to the imports + // Add it to the class path source folders if (codeFolder.exists()){ - libraryPath = codeFolder.getLocation().toOSString(); - // get a list of .jar files in the code folder and its subfolders String codeFolderClassPath = Utilities.contentsToClassPath(codeFolder.getLocation().toFile()); - // append the jar files to the class path - classPath += File.pathSeparator + codeFolderClassPath; - // get the list of packages in those jars + for( String s : codeFolderClassPath.split(File.separator)){ + libraryJarPathList.add(new Path(s)); + } codeFolderPackages = Utilities.packageListFromClassPath(codeFolderClassPath); - } else { libraryPath = ""; } + srcFolderPathList.add(codeFolder.getFullPath()); // not sure about this one + } - // concat all .pde files to the 'main' pde - // store line number for the starting and ending points of each bit + // concatenate the individual .pde files into one large file using temporary + // 'session properties' attached to the IResource files, mark the start and end lines that they + // contribute to the bigCode file. This information will be used later for mapping errors backwards StringBuffer bigCode = new StringBuffer(); int bigCount = 0; // line count for( IResource file : sketch.members()){ - if(file.getFileExtension() != null && file.getFileExtension().equalsIgnoreCase("pde")){ + if("pde".equalsIgnoreCase(file.getFileExtension())){ file.setSessionProperty(new QualifiedName(BUILDER_ID, "preproc start"), bigCount); String content = Utilities.readFile((IFile) file); bigCode.append(content); @@ -257,31 +231,22 @@ public class SketchBuilder extends IncrementalProjectBuilder{ if(checkCancel(monitor)) { return null; } PreprocessResult result = null; - try{ - IFile outputFile = buildFolder.getFile(sketch.getName() + ".java"); - StringWriter stream = new StringWriter(); - result = preproc.write(stream, bigCode.toString(), codeFolderPackages); - - // Eclipse idiom for generating the java file and marking it as a generated file - ByteArrayInputStream inStream = new ByteArrayInputStream(stream.toString().getBytes()); + try{ + final File java = new File(buildFolder, sketch.getName() + ".java"); + final PrintWriter stream = new PrintWriter(new FileWriter(java)); try{ - if (outputFile.exists()) { - outputFile.setContents(inStream, true, false, monitor); - } else { - outputFile.create(inStream, true, monitor); - } - outputFile.setDerived(true, monitor); + result = preproc.write(stream, bigCode.toString(), codeFolderPackages); + srcFolderPathList.add(new Path(buildFolder.getCanonicalPath())); } finally { stream.close(); - inStream.close(); } } catch(antlr.RecognitionException re){ - IResource errorFile = null; // if this remains null, the error is reported back on the sketch itself with no line + IResource errorFile = null; // if this remains null, the error is reported back on the sketch itself with no line number int errorLine = re.getLine() - 1; for( IResource file : sketch.members()){ - if(file.getFileExtension() != null && file.getFileExtension().equalsIgnoreCase("pde")){ + if("pde".equalsIgnoreCase(file.getFileExtension())){ int low = (Integer) file.getSessionProperty(new QualifiedName(BUILDER_ID, "preproc start")); int high = (Integer) file.getSessionProperty(new QualifiedName(BUILDER_ID, "preproc end")); if( low <= errorLine && high > errorLine){ @@ -298,13 +263,11 @@ public class SketchBuilder extends IncrementalProjectBuilder{ errorLine = -1; } - //DEBUG - //System.out.println("error line - error file - offset"); - //System.out.println(errorLine + " - " + errorFile + " - " + getPreprocOffset((IFile) folderContents[errorFile])); - String msg = re.getMessage(); - //TODO better remapping of errors, matching errors often get put after the document end. see highlightLine() inside editor. + //TODO better errors handling, matching errors often get put after the document end. see highlightLine() inside editor. + // try to find a way to put all this error handling code in one spot. All of the message parsing and resource blaming, + // so it doesn't appear multiple times in the source. if (msg.equals("expecting RCURLY, found 'null'")) msg = "Found one too many { characters without a } to match it."; if (msg.indexOf("expecting RBRACK") != -1) @@ -331,7 +294,7 @@ public class SketchBuilder extends IncrementalProjectBuilder{ // int errorColumn = Integer.parseInt(matches[2]); // unused in the builder for( IResource file : sketch.members()){ - if(file.getFileExtension() != null && file.getFileExtension().equalsIgnoreCase("pde")){ + if("pde".equalsIgnoreCase(file.getFileExtension())){ int low = (Integer) file.getSessionProperty(new QualifiedName(BUILDER_ID, "preproc start")); int high = (Integer) file.getSessionProperty(new QualifiedName(BUILDER_ID, "preproc end")); if( low <= errorLine && high > errorLine){ @@ -363,7 +326,7 @@ public class SketchBuilder extends IncrementalProjectBuilder{ int errorLine = re.getCodeLine() + 1; for( IResource file : sketch.members()){ - if(file.getFileExtension() != null && file.getFileExtension().equalsIgnoreCase("pde")){ + if("pde".equalsIgnoreCase(file.getFileExtension())){ int low = (Integer) file.getSessionProperty(new QualifiedName(BUILDER_ID, "preproc start")); int high = (Integer) file.getSessionProperty(new QualifiedName(BUILDER_ID, "preproc end")); if( low <= errorLine && high > errorLine){ @@ -386,7 +349,7 @@ public class SketchBuilder extends IncrementalProjectBuilder{ String msg = re.getMessage(); - //TODO better remapping of errors, matching errors often get put after the document end. see highlightLine() inside editor. + //TODO see better error mapping todo above if (msg.equals("expecting RCURLY, found 'null'")) msg = "Found one too many { characters without a } to match it."; if (msg.indexOf("expecting RBRACK") != -1) @@ -400,137 +363,118 @@ public class SketchBuilder extends IncrementalProjectBuilder{ reportProblem(msg, errorFile, errorLine, true); return null; // exit the build - } catch (CoreException e){ - ProcessingLog.logError(e); // logging the error is a better - return null; } catch (Exception e){ ProcessingLog.logError(e); return null; } monitor.worked(10); - if(checkCancel(monitor)) { return null; } + if(checkCancel(monitor)) { return null; } -////////// LIBRARY STUFF MOVED TO SKETCH PROJECT - - // Get the imports from the code that was preproc'd -// importedLibraries = new ArrayList(); + ArrayList libs = new ArrayList(); // a list of all the libraries that can be found -// coreLibs = getCoreLibsFolder().getAbsoluteFile(); -// sketchBookLibs = getSketchBookLibsFolder(sketch).getAbsoluteFile(); + libs.addAll( Utilities.getLibraryJars(ProcessingCore.getProcessingCore().getCoreLibsFolder()) ); + libs.addAll( Utilities.getLibraryJars(Utilities.getSketchBookLibsFolder(sketch)) ); - // Clean the library table and rebuild it -// importToLibraryTable = new HashMap(); + // setup the library table + HashMap importToLibraryTable = new HashMap(); - // addLibraries internally checks for null folders -// try{ -// addLibraries(coreLibs); -// addLibraries(sketchBookLibs); -// } catch (IOException e){ -// ProcessingLog.logError("Libraries could not be loaded.", e); -// } -// -// for (String item : result.extraImports){ -// // remove things up to the last dot -// int dot = item.lastIndexOf('.'); -// String entry = (dot == -1) ? item : item.substring(0, dot); -// File libFolder = importToLibraryTable.get(entry); -// if (libFolder != null ){ -// importedLibraries.add(libFolder); -// classPath += Utilities.contentsToClassPath(libFolder); -// libraryPath += File.pathSeparator + libFolder.getAbsolutePath(); -// } -// } - - // Finally add the regular Java CLASSPATH - String javaClassPath = System.getProperty("java.class.path"); - // Remove quotes if any ... an annoying ( and frequent ) Windows problem - if (javaClassPath.startsWith("\"") && javaClassPath.endsWith("\"")) - javaClassPath = javaClassPath.substring(1,javaClassPath.length()-1); - classPath += File.pathSeparator + javaClassPath; - - monitor.worked(10); - if(checkCancel(monitor)) { return null; } - - // 3. loop over the code[] and save each .java file - - for( IResource file : sketch.members()){ - if(file.getFileExtension() != null && file.getFileExtension().equalsIgnoreCase("java")){ - String filename = file.getName() + ".java"; - try{ - String program = Utilities.readFile((IFile) file); - String[] pkg = Utilities.match(program, Utilities.PACKAGE_REGEX); - // if no package, add one - if(pkg == null){ - pkg = new String[] { packageName }; - // add the package name to the source - program = "package " + packageName + ";" + program; - } - IFolder packageFolder = buildFolder.getFolder(pkg[0].replace('.', '/')); - if (!packageFolder.exists()) - packageFolder.create(IResource.NONE, true, null); - - IFile modFile = packageFolder.getFile(file.getName() + ".java"); - - ByteArrayInputStream inStream = new ByteArrayInputStream(program.getBytes()); - try{ - if (modFile.exists()) { - modFile.setContents(inStream, true, false, monitor); - } else { - modFile.create(inStream, true, monitor); - } - modFile.setDerived(true, monitor); - } finally { - inStream.close(); - } - } catch (Exception e){ - ProcessingLog.logError("Problem moving " + filename + " to the build folder.", e); - } - } else if (file.getFileExtension() != null && file.getFileExtension().equalsIgnoreCase("pde")){ - // The compiler will need this to have a proper offset - // not sure why every file gets the same offset, but ok I'll go with it... [lonnen] aug 20 2011 - file.setSessionProperty(new QualifiedName(BUILDER_ID, "preproc start"), result.headerOffset); +// System.out.println("Libraries found (path sep: " + File.separator + " ) :"); + for (String s : libs ){ +// System.out.println(s); + String[] packages = Utilities.packageListFromClassPath(s); + for (String pkg : packages){ + importToLibraryTable.put(pkg, new Path(s)); +// System.out.println(pkg); } } +// System.out.println("There were a few extra imports: " + result.extraImports.size()); + for (int i=0; i < result.extraImports.size(); i++){ + String item = result.extraImports.get(i); + // remove things up to the last dot + int dot = item.lastIndexOf('.'); + String entry = (dot == -1) ? item : item.substring(0, dot); +// System.out.println(entry); + IPath libPath = importToLibraryTable.get(entry); + if (libPath != null ){ + libraryJarPathList.add(libPath); // huzzah! we've found it, make sure its fed to the compiler + } else { + // The user is trying to import something we won't be able to find. + reportProblem( + "Library import " + entry +" could not be found. Check the library folder in your sketchbook.", + sketch.getFile( sketch.getName() + ".pde"), i+1, true + ); + } + } + + // Adding the ol' Java classpath is handled by Eclipse. We don't worry about it. + monitor.worked(10); if(checkCancel(monitor)) { return null; } - //COMPILE -// -// // setup the VM -// IPath containerPath = new Path(JavaRuntime.JRE_CONTAINER); -// IVMInstall vm = JavaRuntime.getDefaultVMInstall(); -// IPath vmPath = containerPath.append(vm.getVMInstallType().getId()).append(vm.getName()); -// -// // Collect all the paths in one place -// ArrayList paths = new ArrayList(); -// -// // Split up the classPath, convert each member to a path -// // and store them individually -// System.out.println("classPath entries:"); -// for( String s : classPath.split(File.pathSeparator)){ -// if (!s.isEmpty()){ -// System.out.println(s); -// paths.add(new Path(s)); -// } -// } -// -// IClasspathEntry[] classpathEntries = new IClasspathEntry[paths.size()+1]; -// -// System.out.println("IClasspathEntry[] items:"); -// for (int i = 0; i"processing.plugin.core.processingnature" */ public static final String NATURE_ID = ProcessingCore.PLUGIN_ID + ".sketchNature"; - + /** The basic project entry being managed */ protected IProject project; - + /** * Return the SketchProject associated with the given IProject, or null * if the project is not associated with a SketchProject. @@ -76,7 +78,7 @@ public class SketchProject implements IProjectNature { description.setNatureIds(newIds.toArray(new String[newIds.size()])); return; } - + IProjectDescription description = project.getDescription(); List newIds = new ArrayList(); @@ -126,113 +128,41 @@ public class SketchProject implements IProjectNature { public IJavaProject getJavaProject(){ return JavaCore.create(project); } - + /** Associate the sketch builder with this nature's project */ public void configure() throws CoreException { if (!project.isOpen()) return; - // Setup the folders - IFolder codeFolder = project.getFolder("code"); - IFolder dataFolder = project.getFolder("data"); - IFolder buildFolder = project.getFolder("bin"); // TODO relocate to MyPlugin.getPlugin().getStateLocation().getFolder("bin") - IFolder appletFolder = project.getFolder("applet"); - IFolder javaBuildFolder = project.getFolder("compile"); - - File coreResources = getCoreResourcesFolder(); - File sketchbookLibs = getSketchBookLibsFolder(project); - - if(!codeFolder.exists()) - buildFolder.create(IResource.NONE, true, null); - if(!dataFolder.exists()) - dataFolder.create(IResource.NONE, true, null); - if(!buildFolder.exists()) - buildFolder.create(IResource.NONE, true, null); - if(!appletFolder.exists()) - appletFolder.create(IResource.NONE, true, null); - if(!javaBuildFolder.exists()) - javaBuildFolder.create(IResource.NONE, true, null); - - // Setup the Java project underlying the Sketch - IJavaProject jproject = JavaCore.create(project); - - // Get a default VM to toss in the mix - IPath containerPath = new Path(JavaRuntime.JRE_CONTAINER); - IVMInstall vm = JavaRuntime.getDefaultVMInstall(); - IPath vmPath = containerPath.append(vm.getVMInstallType().getId()).append(vm.getName()); - - // Setup dynamic classpath containers so we don't have to recalculate them and set them every time - List entries = new ArrayList(); - - entries.add(JavaCore.newContainerEntry(vmPath.makeAbsolute())); // JVM - entries.add(JavaCore.newSourceEntry(buildFolder.getFullPath().makeAbsolute())); // java source - entries.add(JavaCore.newContainerEntry(codeFolder.getFullPath().makeAbsolute())); // data source - if(coreResources != null){ - entries.add( - JavaCore.newLibraryEntry( new Path(coreResources.getAbsolutePath()).append("lib/core.jar"), - null, //no source - null, //no source - false //not exported - ) - ); - } - if(sketchbookLibs != null) - entries.add(JavaCore.newContainerEntry(new Path(sketchbookLibs.getAbsolutePath()))); // sketchbook libs container - - // casting doesn't work so we have to explicitly unpack the list. - IClasspathEntry[] classpathEntries = new IClasspathEntry[entries.size()]; - for(int i=0; i< entries.size(); i++ ){ - classpathEntries[i] = entries.get(i); - } - - // Combine all of these entries and set the raw classpath of the project. - // None of these should require further modification because they are dynamic - // Also provide an explicit output folder and a null progress monitor - jproject.setRawClasspath( classpathEntries, javaBuildFolder.getFullPath(), null); + getCodeFolder(); + getDataFolder(); // Check the description to see if it already has the builder IProjectDescription description = this.project.getDescription(); List newCmds = new ArrayList(); newCmds.addAll(Arrays.asList(description.getBuildSpec())); - + int ploc = -1; // builder ID location for (int i = 0; i < newCmds.size(); i++){ if (newCmds.get(i).getBuilderName().equals(SketchBuilder.BUILDER_ID)) ploc = i; } - + if (ploc == 0) // its there and where we want it return; - + if (ploc > 0) newCmds.remove(ploc); // its not where we want it, remove it and add to the beginning - + ICommand command = description.newCommand(); command.setBuilderName(SketchBuilder.BUILDER_ID); newCmds.add(0, command); description.setBuildSpec( (ICommand[]) newCmds.toArray(new ICommand[newCmds.size()])); project.setDescription(description,null); - - // refresh the local space, folders were created - project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); - - // schedule and run a build once its added. - /*new Job("Build Sketch"){ - protected IStatus run(IProgressMonitor monitor){ - try{ - project.build( - IncrementalProjectBuilder.FULL_BUILD, - SketchBuilder.BUILDER_ID, - null, - monitor); - } catch (CoreException e){ - ProcessingLog.logError(e); - } - return Status.OK_STATUS; - } - }.schedule();*/ + // refresh the local space, folders may have been created + project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); } /** @@ -253,7 +183,7 @@ public class SketchProject implements IProjectNature { description.setBuildSpec(newCmds.toArray(new ICommand[newCmds.size()])); } } - + // clean up your tokens SketchBuilder.deleteP5ProblemMarkers(project); } @@ -262,9 +192,9 @@ public class SketchProject implements IProjectNature { public QualifiedName getPropertyName(String localName){ return new QualifiedName(ProcessingCore.PLUGIN_ID, localName); } - + /** - * Sets a persistent property in the pojects property store + * Sets a persistent property in the poject's property store * If there is an exception it will be reported and the project * will not persist. **/ @@ -275,88 +205,141 @@ public class SketchProject implements IProjectNature { ProcessingLog.logError(e); } } - + /** Trigger a full build of the project being managed */ public void fullBuild(IProgressMonitor monitor) throws CoreException{ project.build(IncrementalProjectBuilder.FULL_BUILD, monitor); } - - /** - * Finds the folder containing the Processing core libraries, which are bundled with the - * plugin. This folder doesn't exist in the workspace, so we return it as a File, not IFile. - * If something goes wrong, logs an error and returns null. - * - * @return File containing the core libraries folder or null - */ - public File getCoreLibsFolder() { - URL fileLocation = ProcessingCore.getProcessingCore().getPluginResource("libraries"); - try { - File folder = new File(FileLocator.toFileURL(fileLocation).getPath()); - if (folder.exists()) - return folder; - } catch (Exception e) { - ProcessingLog.logError(e); - } - return null; - } - - /** - * Resolves the plug-in resources folder to a File and returns it. This will include the - * Processing libraries and the core libraries folder. - * - * @return File reference to the core resources - */ - public File getCoreResourcesFolder(){ - URL fileLocation = ProcessingCore.getProcessingCore().getPluginResource(""); - try { - File folder = new File(FileLocator.toFileURL(fileLocation).getPath()); - if (folder.exists()) - return folder; - } catch (Exception e) { - ProcessingLog.logError(e); - } - return null; - } - - /** - * Find the folder containing the users libraries, which should be in the sketchbook. - * Looks in the user's preferences first, then look relative to the sketch location. - * - * @return File containing the Sketch book library folder, or null if it can't be located - */ - public File getSketchBookLibsFolder(IProject proj) { - IPath sketchbook = ProcessingCorePreferences.current().getSketchbookPath(); - if (sketchbook == null) - sketchbook = findSketchBookLibsFolder(proj); - if (sketchbook == null) - return null; - return new File(sketchbook.toOSString()); - } - - /** - * Tries to locate the sketchbook library folder relative to the project path - * based on the default sketch / sketchbook setup. If such a folder exists, loop - * through its contents until a valid library is found and then return the path - * to the sketchbook. If no valid libraries are found (empty folder, improper - * sketchbook setup), or if no valid folder is found, return null. - * - * @return IPath containing the location of the new library folder, or null - */ - public IPath findSketchBookLibsFolder(IProject proj) { + /** Return the sketch's code folder or null if it cannot be retrieved */ + public IFolder getCodeFolder(){ try{ - IPath guess = proj.getLocation().removeLastSegments(1).append("libraries"); - File folder = new File(guess.toOSString()); - if(folder.isDirectory()) - for( File file : folder.listFiles()){ - if(file.isDirectory()) - if (ProcessingCore.isLibrary(file)) - return guess; - } + IFolder code = project.getFolder("code"); + if(!code.exists()) + code.create(IResource.NONE, true, null); + return code; } catch (Exception e){ - ProcessingLog.logError(e); + ProcessingLog.logError("Code folder could not be created.", e); + return null; } + } + + /** Return the sketch's code folder or null if it cannot be retrieved */ + public IFolder getDataFolder(){ + try{ + IFolder data = project.getFolder("data"); + if(!data.exists()) + data.create(IResource.NONE, true, null); + return data; + } catch (Exception e){ + ProcessingLog.logError("Data folder could not be created.", e); + return null; + } + } + + /** Return the sketch's code folder or null if it cannot be retrieved. */ + public IFolder getAppletFolder(){ + try{ + IFolder applet = project.getFolder("applet"); + if(!applet.exists()) + applet.create(IResource.NONE, true, null); + return project.getFolder("applet"); + } catch (Exception e){ + ProcessingLog.logError("Applet folder could not be created.", e); + return null; + } + } + + /** + * Return a vanilla File handle to the output folder for the Java compiler + * inside the cached build folder, or null if it cannot be created. + */ + public File getJavaBuildFolder(){ + File build = getBuildFolder(); + if(build != null){ + File compile = new File(build, "compile"); + compile.mkdirs(); + if(compile.exists()) + return compile; + } + ProcessingLog.logError("Could not create the temporary build (compile) folder.", null); return null; } -} + /** + * Returns a vanilla File handle to the project specific build folder, which is located inside + * the temp directory of the plug-in's local cache, or null if it doesn't exist + */ + public File getBuildFolder(){ + //File tempBuildFolder = File.createTempFile("") + File tempBuildFolder = new File(ProcessingCore.getProcessingCore().getPluginTempFolder(), project.getName()); + tempBuildFolder.mkdirs(); + if(tempBuildFolder.exists()) + return tempBuildFolder; + ProcessingLog.logError("Could not create the temporary build (preprocess) folder.", null); + return null; + //return project.getFolder("bin").getFullPath().toFile(); + } + + /** + * Register a new set of class path entries from the provided source folder list and library jars. + * This method completely replaces the old class path. + * + * @param srcFolderPathList A list of absolute paths to source folders + * @param libraryJarPathList A list of absolute paths to source folders + */ + public void updateClasspathEntries( IPath[] srcFolderPathList, IPath[] libraryJarPathList) { + IJavaProject jproject = this.getJavaProject(); + + // Get a default VM to toss in the mix + IPath containerPath = new Path(JavaRuntime.JRE_CONTAINER); + IVMInstall vm = JavaRuntime.getDefaultVMInstall(); + IPath vmPath = containerPath.append(vm.getVMInstallType().getId()).append(vm.getName()); + + // Duplicate entries cause errors, so prep them with a set + HashSet entries = new HashSet(); + + // VM + entries.add(JavaCore.newContainerEntry(vmPath.makeAbsolute())); // JVM + + // if we were given a list of source folders, add them to the list + // this should include the build folder and the code folder, if it was necessary + if(srcFolderPathList != null){ + for( IPath p : srcFolderPathList){ + entries.add(JavaCore.newSourceEntry(p.makeAbsolute())); + } + } + + if(libraryJarPathList != null){ + for(IPath p : libraryJarPathList){ + //System.out.println(p.toString()); + entries.add( + JavaCore.newLibraryEntry(p.makeAbsolute(), + null, // no source + null, // no source + false // not exported + ) + ); + } + } + + // things are added in no particular order + + + IClasspathEntry[] classpathEntries = new IClasspathEntry[entries.size()]; + + int i = 0; + for (IClasspathEntry cpe : entries) classpathEntries[i++] = cpe; + + // Combine all of these entries and set the raw classpath of the project. + // None of these should require further modification because they are dynamic + // Also provide an explicit output folder and a null progress monitor + try { + jproject.setRawClasspath( classpathEntries, new Path(this.getJavaBuildFolder().getCanonicalPath()), null); + } catch (Exception e) { + ProcessingLog.logError("There was a problem setting the compiler class path.", e); + } + + } + +} \ No newline at end of file diff --git a/editor/processing.plugin.core/src/processing/plugin/core/builder/Utilities.java b/editor/processing.plugin.core/src/processing/plugin/core/builder/Utilities.java index d23c03f0f..4136c96eb 100644 --- a/editor/processing.plugin.core/src/processing/plugin/core/builder/Utilities.java +++ b/editor/processing.plugin.core/src/processing/plugin/core/builder/Utilities.java @@ -2,6 +2,7 @@ package processing.plugin.core.builder; import java.io.BufferedReader; import java.io.File; +import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -16,7 +17,12 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import processing.plugin.core.ProcessingCore; +import processing.plugin.core.ProcessingCorePreferences; import processing.plugin.core.ProcessingLog; /** @@ -174,7 +180,7 @@ public class Utilities { /** * Get a list of packages contained in a .zip file */ - static private void packageListFromZip(String filename, Hashtable table) { + static public void packageListFromZip(String filename, Hashtable table) { try { ZipFile file = new ZipFile(filename); Enumeration entries = file.entries(); @@ -206,7 +212,7 @@ public class Utilities { * class is found in a folder, add its containing set of folders to the package * list. If another folder is found, walk down into that folder and continue. */ - static private void packageListFromFolder(File dir, String sofar, Hashtable table) { + static public void packageListFromFolder(File dir, String sofar, Hashtable table) { boolean foundClass = false; String files[] = dir.list(); @@ -227,169 +233,269 @@ public class Utilities { } } } - - /** - * Produce a sanitized name that fits our standards for likely to work. - *

- * Java classes have a wider range of names that are technically allowed - * (supposedly any Unicode name) than what we support. The reason for - * going more narrow is to avoid situations with text encodings and - * converting during the process of moving files between operating - * systems, i.e. uploading from a Windows machine to a Linux server, - * or reading a FAT32 partition in OS X and using a thumb drive. - *

- * This helper function replaces everything but A-Z, a-z, and 0-9 with - * underscores. Also disallows starting the sketch name with a digit. - */ - static public String sanitizeName(String origName) { - char c[] = origName.toCharArray(); - StringBuffer buffer = new StringBuffer(); - - // can't lead with a digit, so start with an underscore - if ((c[0] >= '0') && (c[0] <= '9')) { - buffer.append('_'); - } - for (int i = 0; i < c.length; i++) { - if (((c[i] >= '0') && (c[i] <= '9')) || - ((c[i] >= 'a') && (c[i] <= 'z')) || - ((c[i] >= 'A') && (c[i] <= 'Z'))) { - buffer.append(c[i]); - - } else { - buffer.append('_'); - } - } - // let's not be ridiculous about the length of filenames. - // in fact, Mac OS 9 can handle 255 chars, though it can't really - // deal with filenames longer than 31 chars in the Finder. - // but limiting to that for sketches would mean setting the - // upper-bound on the character limit here to 25 characters - // (to handle the base name + ".class") - if (buffer.length() > 63) { - buffer.setLength(63); - } - return buffer.toString(); - } - /** - * Match a string with a regular expression, and returns the match as an - * array. The first index is the matching expression, and array elements - * [1] and higher represent each of the groups (sequences found in parens). - * - * This uses multiline matching (Pattern.MULTILINE) and dotall mode - * (Pattern.DOTALL) by default, so that ^ and $ match the beginning and - * end of any lines found in the source, and the . operator will also - * pick up newline characters. - */ - static public String[] match(String what, String regexp) { - Pattern p = matchPattern(regexp); - Matcher m = p.matcher(what); - if (m.find()) { - int count = m.groupCount() + 1; - String[] groups = new String[count]; - for (int i = 0; i < count; i++) { - groups[i] = m.group(i); - } - return groups; - } - return null; - } - - static protected HashMap matchPatterns; - - static Pattern matchPattern(String regexp) { - Pattern p = null; - if (matchPatterns == null) { - matchPatterns = new HashMap(); - } else { - p = matchPatterns.get(regexp); - } - if (p == null) { - if (matchPatterns.size() == 10) { - // Just clear out the match patterns here if more than 10 are being - // used. It's not terribly efficient, but changes that you have >10 - // different match patterns are very slim, unless you're doing - // something really tricky (like custom match() methods), in which - // case match() won't be efficient anyway. (And you should just be - // using your own Java code.) The alternative is using a queue here, - // but that's a silly amount of work for negligible benefit. - matchPatterns.clear(); - } - p = Pattern.compile(regexp, Pattern.MULTILINE | Pattern.DOTALL); - matchPatterns.put(regexp, p); - } - return p; - } + /** + * Find the folder containing the users libraries, which should be in the sketchbook. + * Looks in the user's preferences first, then look relative to the sketch location. + * + * @return File containing the Sketch book library folder, or null if it can't be located + */ + public static File getSketchBookLibsFolder(IProject proj) { + IPath sketchbook = ProcessingCorePreferences.current().getSketchbookPath(); + if (sketchbook == null) + sketchbook = findSketchBookLibsFolder(proj); + if (sketchbook == null) + return null; + return new File(sketchbook.toOSString()); + } - /** - * Split a String on a specific delimiter. Unlike Java's String.split() - * method, this does not parse the delimiter as a regexp because it's more - * confusing than necessary, and String.split() is always available for - * those who want regexp. - */ - static public String[] split(String what, String delim) { - ArrayList items = new ArrayList(); - int index; - int offset = 0; - while ((index = what.indexOf(delim, offset)) != -1) { - items.add(what.substring(offset, index)); - offset = index + delim.length(); - } - items.add(what.substring(offset)); - String[] outgoing = new String[items.size()]; - items.toArray(outgoing); - return outgoing; - } - - /** - * Split a string into pieces along a specific character. - * Most commonly used to break up a String along a space or a tab - * character. - *

- * This operates differently than the others, where the - * single delimeter is the only breaking point, and consecutive - * delimeters will produce an empty string (""). This way, - * one can split on tab characters, but maintain the column - * alignments (of say an excel file) where there are empty columns. - */ - static public String[] split(String what, char delim) { - // do this so that the exception occurs inside the user's - // program, rather than appearing to be a bug inside split() - if (what == null) return null; - //return split(what, String.valueOf(delim)); // huh + /** + * Tries to locate the sketchbook library folder relative to the project path + * based on the default sketch / sketchbook setup. If such a folder exists, loop + * through its contents until a valid library is found and then return the path + * to the sketchbook. If no valid libraries are found (empty folder, improper + * sketchbook setup), or if no valid folder is found, return null. + * + * @return IPath containing the location of the new library folder, or null + */ + public static IPath findSketchBookLibsFolder(IProject proj) { + try{ + IPath guess = proj.getLocation().removeLastSegments(1).append("libraries"); + File folder = new File(guess.toOSString()); + if(folder.isDirectory()) + for( File file : folder.listFiles()){ + if(file.isDirectory()) + if (ProcessingCore.isLibrary(file)) + return guess; + } + } catch (Exception e){ + ProcessingLog.logError(e); + } + return null; + } - char chars[] = what.toCharArray(); - int splitCount = 0; //1; - for (int i = 0; i < chars.length; i++) { - if (chars[i] == delim) splitCount++; - } - // make sure that there is something in the input string - //if (chars.length > 0) { - // if the last char is a delimeter, get rid of it.. - //if (chars[chars.length-1] == delim) splitCount--; - // on second thought, i don't agree with this, will disable - //} - if (splitCount == 0) { - String splits[] = new String[1]; - splits[0] = new String(what); - return splits; - } - //int pieceCount = splitCount + 1; - String splits[] = new String[splitCount + 1]; - int splitIndex = 0; - int startIndex = 0; - for (int i = 0; i < chars.length; i++) { - if (chars[i] == delim) { - splits[splitIndex++] = - new String(chars, startIndex, i-startIndex); - startIndex = i + 1; - } - } - //if (startIndex != chars.length) { - splits[splitIndex] = - new String(chars, startIndex, chars.length-startIndex); - //} - return splits; - } + /** + * If the folder is the root of a Processing library, return a String containing + * the canonical path to the library's Jar. If it is not, return null. + */ + public static String getLibraryJarPath(File folder){ + if( ProcessingCore.isLibrary(folder) ){ + try { + return folder.getCanonicalPath().concat( File.separatorChar + "library" + File.separatorChar + folder.getName() + ".jar" ); + } catch (IOException e) { + ProcessingLog.logError("Could not get the library jar for library " + folder.getName(), e); + } + } + return null; + } + + /** + * Looks in the provided folder for valid libraries and returns a list of paths to them. + * Returns an empty list if there are no valid libraries. + * + * @param folder + * @return + */ + public static ArrayList getLibraryJars(File folder){ + ArrayList libPaths = new ArrayList(); + if(folder == null) return libPaths; + if(!folder.exists()) return libPaths; + + for (File f : folder.listFiles()){ + if ( ProcessingCore.isLibrary(f) ){ + // if it is a library, add the jar + String path = getLibraryJarPath(f); + if (path!= null) + libPaths.add(path); + } else if (f.isDirectory()){ + // if it is not a library, but is a directory, recurse + // and add all libraries in it to our list + libPaths.addAll(getLibraryJars(f)); + } + // we don't care about anything else. + } + return libPaths; + } + + /** + * Produce a sanitized name that fits our standards for likely to work. + *

+ * Java classes have a wider range of names that are technically allowed + * (supposedly any Unicode name) than what we support. The reason for + * going more narrow is to avoid situations with text encodings and + * converting during the process of moving files between operating + * systems, i.e. uploading from a Windows machine to a Linux server, + * or reading a FAT32 partition in OS X and using a thumb drive. + *

+ * This helper function replaces everything but A-Z, a-z, and 0-9 with + * underscores. Also disallows starting the sketch name with a digit. + */ + static public String sanitizeName(String origName) { + char c[] = origName.toCharArray(); + StringBuffer buffer = new StringBuffer(); + + // can't lead with a digit, so start with an underscore + if ((c[0] >= '0') && (c[0] <= '9')) { + buffer.append('_'); + } + for (int i = 0; i < c.length; i++) { + if (((c[i] >= '0') && (c[i] <= '9')) || + ((c[i] >= 'a') && (c[i] <= 'z')) || + ((c[i] >= 'A') && (c[i] <= 'Z'))) { + buffer.append(c[i]); + + } else { + buffer.append('_'); + } + } + // let's not be ridiculous about the length of filenames. + // in fact, Mac OS 9 can handle 255 chars, though it can't really + // deal with filenames longer than 31 chars in the Finder. + // but limiting to that for sketches would mean setting the + // upper-bound on the character limit here to 25 characters + // (to handle the base name + ".class") + if (buffer.length() > 63) { + buffer.setLength(63); + } + return buffer.toString(); + } + + /** + * Match a string with a regular expression, and returns the match as an + * array. The first index is the matching expression, and array elements + * [1] and higher represent each of the groups (sequences found in parens). + * + * This uses multiline matching (Pattern.MULTILINE) and dotall mode + * (Pattern.DOTALL) by default, so that ^ and $ match the beginning and + * end of any lines found in the source, and the . operator will also + * pick up newline characters. + */ + static public String[] match(String what, String regexp) { + Pattern p = matchPattern(regexp); + Matcher m = p.matcher(what); + if (m.find()) { + int count = m.groupCount() + 1; + String[] groups = new String[count]; + for (int i = 0; i < count; i++) { + groups[i] = m.group(i); + } + return groups; + } + return null; + } + + static protected HashMap matchPatterns; + + static public Pattern matchPattern(String regexp) { + Pattern p = null; + if (matchPatterns == null) { + matchPatterns = new HashMap(); + } else { + p = matchPatterns.get(regexp); + } + if (p == null) { + if (matchPatterns.size() == 10) { + // Just clear out the match patterns here if more than 10 are being + // used. It's not terribly efficient, but changes that you have >10 + // different match patterns are very slim, unless you're doing + // something really tricky (like custom match() methods), in which + // case match() won't be efficient anyway. (And you should just be + // using your own Java code.) The alternative is using a queue here, + // but that's a silly amount of work for negligible benefit. + matchPatterns.clear(); + } + p = Pattern.compile(regexp, Pattern.MULTILINE | Pattern.DOTALL); + matchPatterns.put(regexp, p); + } + return p; + } + + /** + * Split a String on a specific delimiter. Unlike Java's String.split() + * method, this does not parse the delimiter as a regexp because it's more + * confusing than necessary, and String.split() is always available for + * those who want regexp. + */ + static public String[] split(String what, String delim) { + ArrayList items = new ArrayList(); + int index; + int offset = 0; + while ((index = what.indexOf(delim, offset)) != -1) { + items.add(what.substring(offset, index)); + offset = index + delim.length(); + } + items.add(what.substring(offset)); + String[] outgoing = new String[items.size()]; + items.toArray(outgoing); + return outgoing; + } + + /** + * Split a string into pieces along a specific character. + * Most commonly used to break up a String along a space or a tab + * character. + *

+ * This operates differently than the others, where the + * single delimeter is the only breaking point, and consecutive + * delimeters will produce an empty string (""). This way, + * one can split on tab characters, but maintain the column + * alignments (of say an excel file) where there are empty columns. + */ + static public String[] split(String what, char delim) { + // do this so that the exception occurs inside the user's + // program, rather than appearing to be a bug inside split() + if (what == null) return null; + //return split(what, String.valueOf(delim)); // huh + + char chars[] = what.toCharArray(); + int splitCount = 0; //1; + for (int i = 0; i < chars.length; i++) { + if (chars[i] == delim) splitCount++; + } + // make sure that there is something in the input string + //if (chars.length > 0) { + // if the last char is a delimeter, get rid of it.. + //if (chars[chars.length-1] == delim) splitCount--; + // on second thought, i don't agree with this, will disable + //} + if (splitCount == 0) { + String splits[] = new String[1]; + splits[0] = new String(what); + return splits; + } + //int pieceCount = splitCount + 1; + String splits[] = new String[splitCount + 1]; + int splitIndex = 0; + int startIndex = 0; + for (int i = 0; i < chars.length; i++) { + if (chars[i] == delim) { + splits[splitIndex++] = + new String(chars, startIndex, i-startIndex); + startIndex = i + 1; + } + } + //if (startIndex != chars.length) { + splits[splitIndex] = + new String(chars, startIndex, chars.length-startIndex); + //} + return splits; + } + + public static void deleteFolderContents(File folder) { + if (folder == null) return; + if (!folder.isDirectory()) return; + for (File f : folder.listFiles()){ + if(!f.delete()){ + if(f.isDirectory()) { + deleteFolderContents(f); + } else { + // that's odd. could not be deleted and isn't a directory. it might be locked or have permissions issues + ProcessingLog.logError( "Could not delete " + f.getName() + + ". If it causes problems, you may have to manually delete it. You can find it here: " + + f.getAbsolutePath(), null); + } + } + } + } } diff --git a/editor/processing.plugin.ui/src/processing/plugin/ui/wizards/NewSketchWizard.java b/editor/processing.plugin.ui/src/processing/plugin/ui/wizards/NewSketchWizard.java index f3d60bc5f..6ccc210ea 100644 --- a/editor/processing.plugin.ui/src/processing/plugin/ui/wizards/NewSketchWizard.java +++ b/editor/processing.plugin.ui/src/processing/plugin/ui/wizards/NewSketchWizard.java @@ -114,17 +114,20 @@ public class NewSketchWizard extends Wizard implements INewWizard { // create the folders IContainer container = (IContainer) proj; + + // Configuring the project will set up the folder structure + //data - IFolder dataFolder = container.getFolder(new Path("data")); - dataFolder.create(true, true, monitor); - monitor.worked(33); - //code - IFolder codeFolder = container.getFolder(new Path("code")); - codeFolder.create(true, true, monitor); - monitor.worked(33); - //bin - IFolder binFolder = container.getFolder(new Path("bin")); - binFolder.create(true, true, monitor); +// IFolder dataFolder = container.getFolder(new Path("data")); +// dataFolder.create(true, true, monitor); +// monitor.worked(33); +// //code +// IFolder codeFolder = container.getFolder(new Path("code")); +// codeFolder.create(true, true, monitor); +// monitor.worked(33); +// //bin +// IFolder binFolder = container.getFolder(new Path("bin")); +// binFolder.create(true, true, monitor); monitor.worked(34); if (monitor.isCanceled()){throw new OperationCanceledException();}