From f8deaa5cfbf25d9e3687f54753dafcea1847e269 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 8 Feb 2013 18:12:53 +0100 Subject: [PATCH] Factoring Library class --- app/src/processing/app/Base.java | 130 ++++++++---------- app/src/processing/app/Sketch.java | 18 +-- app/src/processing/app/debug/Compiler.java | 14 +- app/src/processing/app/packages/Library.java | 79 +++++++++++ .../processing/app/packages/LibraryList.java | 30 ++++ .../processing/app/syntax/PdeKeywords.java | 5 +- 6 files changed, 184 insertions(+), 92 deletions(-) create mode 100644 app/src/processing/app/packages/Library.java create mode 100644 app/src/processing/app/packages/LibraryList.java diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index afa62e18b..057c80344 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -37,7 +37,9 @@ import processing.app.helpers.Maps; import processing.app.helpers.PreferencesMap; import processing.app.helpers.filefilters.OnlyDirs; import processing.app.helpers.filefilters.OnlyFilesWithExtension; -import processing.app.javax.swing.filechooser.FileNameExtensionFilter;import processing.app.tools.MapWithSubkeys; +import processing.app.javax.swing.filechooser.FileNameExtensionFilter;import processing.app.packages.Library; +import processing.app.packages.LibraryList; +import processing.app.tools.MapWithSubkeys; import processing.app.tools.ZipDeflater; import processing.core.*; import static processing.app.I18n._; @@ -89,10 +91,10 @@ public class Base { static private List librariesFolders; // maps library name to their library folder - static private Map libraries; + static private LibraryList libraries; // maps #included files to their library folder - static Map importToLibraryTable; + static Map importToLibraryTable; // classpath for all known libraries for p5 // (both those in the p5/libs folder and those with lib subfolders @@ -1038,26 +1040,26 @@ public class Base { } } - public Map getIDELibs() { + public LibraryList getIDELibs() { + LibraryList libs = new LibraryList(); if (libraries == null) - return new HashMap(); - Map ideLibs = new HashMap(libraries); - for (String lib : libraries.keySet()) { - if (FileUtils.isSubDirectory(getSketchbookFolder(), libraries.get(lib))) - ideLibs.remove(lib); + return libs; + for (Library lib : libraries) { + if (!FileUtils.isSubDirectory(getSketchbookFolder(), lib.getRootFolder())) + libs.add(lib); } - return ideLibs; + return libs; } - public Map getUserLibs() { + public LibraryList getUserLibs() { + LibraryList libs = new LibraryList(); if (libraries == null) - return new HashMap(); - Map userLibs = new HashMap(libraries); - for (String lib : libraries.keySet()) { - if (!FileUtils.isSubDirectory(getSketchbookFolder(), libraries.get(lib))) - userLibs.remove(lib); + return libs; + for (Library lib : libraries) { + if (FileUtils.isSubDirectory(getSketchbookFolder(), lib.getRootFolder())) + libs.add(lib); } - return userLibs; + return libs; } public void rebuildImportMenu(JMenu importMenu, final Editor editor) { @@ -1077,8 +1079,8 @@ public class Base { // Split between user supplied libraries and IDE libraries TargetPlatform targetPlatform = getTargetPlatform(); if (targetPlatform != null) { - Map ideLibs = getIDELibs(); - Map userLibs = getUserLibs(); + LibraryList ideLibs = getIDELibs(); + LibraryList userLibs = getUserLibs(); try { // Find the current target. Get the platform, and then select the // correct name and core path. @@ -1118,24 +1120,24 @@ public class Base { if (found) menu.addSeparator(); // Add examples from libraries - Map ideLibs = getIDELibs(); - List names = new ArrayList(ideLibs.keySet()); - Collections.sort(names, String.CASE_INSENSITIVE_ORDER); - for (String name : names) { - File folder = ideLibs.get(name); + LibraryList ideLibs = getIDELibs(); + Collections.sort(ideLibs, Library.CASE_INSENSITIVE_ORDER); + for (Library lib : ideLibs) { + File folder = lib.getRootFolder(); + String name = lib.getName(); addSketchesSubmenu(menu, name, folder, false); // Allows "fat" libraries to have examples in the root folder if (folder.getName().equals(Base.getTargetPlatform().getName())) addSketchesSubmenu(menu, name, folder.getParentFile(), false); } - Map userLibs = getUserLibs(); + LibraryList userLibs = getUserLibs(); if (userLibs.size()>0) { menu.addSeparator(); - names = new ArrayList(userLibs.keySet()); - Collections.sort(names, String.CASE_INSENSITIVE_ORDER); - for (String name : names) { - File folder = userLibs.get(name); + Collections.sort(userLibs, Library.CASE_INSENSITIVE_ORDER); + for (Library lib : userLibs) { + File folder = lib.getRootFolder(); + String name = lib.getName(); addSketchesSubmenu(menu, name, folder, false); // Allows "fat" libraries to have examples in the root folder if (folder.getName().equals(Base.getTargetPlatform().getName())) @@ -1147,15 +1149,16 @@ public class Base { } } - public Map scanLibraries(List folders) { - Map res = new HashMap(); + public LibraryList scanLibraries(List folders) { + LibraryList res = new LibraryList(); for (File folder : folders) - res.putAll(scanLibraries(folder)); + res.addAll(scanLibraries(folder)); return res; } - public Map scanLibraries(File folder) { - Map res = new HashMap(); + public LibraryList scanLibraries(File folder) { + LibraryList res = new LibraryList(); + String list[] = folder.list(new OnlyDirs()); // if a bad folder or something like that, this might come back null if (list == null) @@ -1172,41 +1175,15 @@ public class Base { continue; } - subfolder = scanFatLibrary(subfolder); + Library lib = Library.fromFolder(subfolder, Base.getTargetPlatform().getName()); // (also replace previously found libs with the same name) - if (subfolder != null) - res.put(libName, subfolder); + if (lib != null) + res.addOrReplace(lib); } return res; } - /** - * Scans inside a "FAT" (multi-platform) library folder to see if it contains - * a version suitable for the actual selected architecture. If a suitable - * version is found the folder containing that version is returned, otherwise - * null is returned.
- *
- * If a non-"FAT" library is detected, we assume that the library is suitable - * for the current architecture and the libFolder parameter is returned.
- * - * @param libFolder - * @return - */ - public File scanFatLibrary(File libFolder) { - // A library is considered "fat" if it contains a file called - // "library.properties" - File libraryPropFile = new File(libFolder, "library.properties"); - if (!libraryPropFile.exists() || !libraryPropFile.isFile()) - return libFolder; - - // Search for a subfolder for actual architecture, return null if not found - File archSubfolder = new File(libFolder, Base.getTargetPlatform().getName()); - if (!archSubfolder.exists() || !archSubfolder.isDirectory()) - return null; - return archSubfolder; - } - public void onBoardOrPortChange() { TargetPlatform targetPlatform = getTargetPlatform(); if (targetPlatform == null) @@ -1228,15 +1205,16 @@ public class Base { libraries = scanLibraries(librariesFolders); // Populate importToLibraryTable - importToLibraryTable = new HashMap(); - for (File subfolder : libraries.values()) { + importToLibraryTable = new HashMap(); + for (Library lib : libraries) { try { - String packages[] = headerListFromIncludePath(subfolder); - for (String pkg : packages) { - importToLibraryTable.put(pkg, subfolder); + String headers[] = headerListFromIncludePath(lib.getRootFolder()); + for (String header : headers) { + importToLibraryTable.put(header, lib); } } catch (IOException e) { - showWarning(_("Error"), I18n.format("Unable to list header files in {0}", subfolder), e); + showWarning(_("Error"), I18n + .format("Unable to list header files in {0}", lib.getRootFolder()), e); } } @@ -1580,10 +1558,10 @@ public class Base { return found; } - protected void addLibraries(JMenu menu, Map libs) throws IOException { + protected void addLibraries(JMenu menu, LibraryList libs) throws IOException { - List list = new ArrayList(libs.keySet()); - Collections.sort(list, String.CASE_INSENSITIVE_ORDER); + LibraryList list = new LibraryList(libs); + Collections.sort(list, Library.CASE_INSENSITIVE_ORDER); ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent event) { @@ -1596,11 +1574,11 @@ public class Base { } }; - for (String name : list) { - File folder = libs.get(name); + for (Library lib : list) { + File folder = lib.getRootFolder(); // Add new element at the bottom - JMenuItem item = new JMenuItem(name); + JMenuItem item = new JMenuItem(lib.getName()); item.addActionListener(listener); item.setActionCommand(folder.getAbsolutePath()); menu.add(item); @@ -1874,7 +1852,7 @@ public class Base { } - static public Map getLibraries() { + static public LibraryList getLibraries() { return libraries; } diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 6d84c70b9..df09bab1a 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -29,6 +29,8 @@ import processing.app.debug.RunnerException; import processing.app.debug.Sizer; import processing.app.debug.Uploader; import processing.app.helpers.PreferencesMap; +import processing.app.packages.Library; +import processing.app.packages.LibraryList; import processing.app.preproc.*; import processing.core.*; import static processing.app.I18n._; @@ -96,7 +98,7 @@ public class Sketch { /** * List of library folders. */ - private ArrayList importedLibraries; + private LibraryList importedLibraries; /** * path is location of the main .pde file, because this is also @@ -1421,18 +1423,18 @@ public class Sketch { // grab the imports from the code just preproc'd - importedLibraries = new ArrayList(); + importedLibraries = new LibraryList(); //Remember to clear library path before building it. libraryPath = ""; for (String item : preprocessor.getExtraImports()) { - File libFolder = (File) Base.importToLibraryTable.get(item); - //If needed can Debug libraryPath here + Library lib = Base.importToLibraryTable.get(item); + //If needed can Debug libraryPath here - if (libFolder != null && !importedLibraries.contains(libFolder)) { - importedLibraries.add(libFolder); + if (lib != null && !importedLibraries.contains(lib)) { + importedLibraries.add(lib); //classPath += Compiler.contentsToClassPath(libFolder); - libraryPath += File.pathSeparator + libFolder.getAbsolutePath(); + libraryPath += File.pathSeparator + lib.getRootFolder().getAbsolutePath(); } } @@ -1462,7 +1464,7 @@ public class Sketch { } - public ArrayList getImportedLibraries() { + public LibraryList getImportedLibraries() { return importedLibraries; } diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index ad3093842..ebb997116 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -41,6 +41,7 @@ import processing.app.SketchCode; import processing.app.helpers.PreferencesMap; import processing.app.helpers.StringReplacer; import processing.app.helpers.filefilters.OnlyDirs; +import processing.app.packages.Library; import processing.core.PApplet; public class Compiler implements MessageConsumer { @@ -84,8 +85,8 @@ public class Compiler implements MessageConsumer { includePaths.add(prefs.get("build.core.path")); if (prefs.get("build.variant.path").length() != 0) includePaths.add(prefs.get("build.variant.path")); - for (File file : sketch.getImportedLibraries()) - includePaths.add(file.getPath()); + for (Library lib : sketch.getImportedLibraries()) + includePaths.add(lib.getRootFolder().getPath()); // 1. compile the sketch (already in the buildPath) sketch.setCompilingProgress(30); @@ -580,11 +581,12 @@ public class Compiler implements MessageConsumer { // // void compileLibraries(List includePaths) throws RunnerException { File outputPath = new File(prefs.get("build.path")); - for (File libraryFolder : sketch.getImportedLibraries()) { - if (new File(libraryFolder.getParentFile(), "library.properties").exists()) { - recursiveCompileLibrary(outputPath, libraryFolder, includePaths); + for (Library lib : sketch.getImportedLibraries()) { + File libFolder = lib.getRootFolder(); + if (lib.isNewLib()) { + recursiveCompileLibrary(outputPath, libFolder, includePaths); } else { - compileLibrary(outputPath, libraryFolder, includePaths); + compileLibrary(outputPath, libFolder, includePaths); } } } diff --git a/app/src/processing/app/packages/Library.java b/app/src/processing/app/packages/Library.java new file mode 100644 index 000000000..27f72254b --- /dev/null +++ b/app/src/processing/app/packages/Library.java @@ -0,0 +1,79 @@ +package processing.app.packages; + +import java.io.File; +import java.util.Comparator; +import java.util.List; + +public class Library { + + private String name; + private File folder; + private List architectures; + private boolean oldLib = true; + + /** + * Scans inside a library folder to see if it contains a version suitable for + * the actual selected architecture. If a suitable version is found the folder + * containing that version is selected, otherwise null is selected.
+ *
+ * If an old-style library is detected, we assume that the library is suitable + * for the current architecture and the libFolder parameter is used.
+ * + * @param libFolder + * @param arch + * Currently selected architecture + * @return + */ + static public Library fromFolder(File libFolder, String arch) { + // A library is considered "new" if it contains a file called + // "library.properties" + File libraryPropFile = new File(libFolder, "library.properties"); + if (!libraryPropFile.exists() || !libraryPropFile.isFile()) { + // construct an old style library + Library res = new Library(); + res.folder = libFolder; + res.name = libFolder.getName(); + res.oldLib = true; + return res; + } + + // Search for a subfolder for actual architecture, return null if not found + File archSubfolder = new File(libFolder, arch); + if (!archSubfolder.exists() || !archSubfolder.isDirectory()) + return null; + + Library res = new Library(); + res.folder = archSubfolder; + res.name = libFolder.getName(); + res.oldLib = false; + return res; + } + + public File getRootFolder() { + return folder; + } + + public String getName() { + return name; + } + + public void setName(String _name) { + name = _name; + } + + public static final Comparator CASE_INSENSITIVE_ORDER = new Comparator() { + @Override + public int compare(Library o1, Library o2) { + return o1.getName().compareToIgnoreCase(o2.getName()); + } + }; + + public boolean isOldLib() { + return oldLib; + } + + public boolean isNewLib() { + return !oldLib; + } + +} diff --git a/app/src/processing/app/packages/LibraryList.java b/app/src/processing/app/packages/LibraryList.java new file mode 100644 index 000000000..94fe5089e --- /dev/null +++ b/app/src/processing/app/packages/LibraryList.java @@ -0,0 +1,30 @@ +package processing.app.packages; + +import java.util.ArrayList; + +@SuppressWarnings("serial") +public class LibraryList extends ArrayList { + + public LibraryList(LibraryList libs) { + super(libs); + } + + public LibraryList() { + super(); + } + + public Library getByName(String name) { + for (Library l : this) + if (l.getName().equals(name)) + return l; + return null; + } + + public void addOrReplace(Library lib) { + Library l = getByName(lib.getName()); + if (l != null) + remove(l); + add(lib); + } + +} diff --git a/app/src/processing/app/syntax/PdeKeywords.java b/app/src/processing/app/syntax/PdeKeywords.java index 3f3016dde..4b8d8dfbe 100644 --- a/app/src/processing/app/syntax/PdeKeywords.java +++ b/app/src/processing/app/syntax/PdeKeywords.java @@ -25,6 +25,7 @@ package processing.app.syntax; import processing.app.*; +import processing.app.packages.Library; import java.io.*; import java.util.*; @@ -59,8 +60,8 @@ public class PdeKeywords extends CTokenMarker { keywordColoring = new KeywordMap(false); keywordToReference = new Hashtable(); getKeywords(Base.getLibStream("keywords.txt")); - for (File lib : Base.getLibraries().values()) { - File keywords = new File(lib, "keywords.txt"); + for (Library lib : Base.getLibraries()) { + File keywords = new File(lib.getRootFolder(), "keywords.txt"); if (keywords.exists()) getKeywords(new FileInputStream(keywords)); } } catch (Exception e) {