Created
December 2, 2010 17:14
-
-
Save oravecz/725691 to your computer and use it in GitHub Desktop.
Patch for RingoJS - Auto-discovery of Packages
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: src/org/ringojs/repository/ZipRepository.java | |
=================================================================== | |
--- src/org/ringojs/repository/ZipRepository.java (revision e0dce2be640fc6fb43a1239d252948d10687ba9c) | |
+++ src/org/ringojs/repository/ZipRepository.java (revision ) | |
@@ -187,7 +187,7 @@ | |
} | |
} | |
- public Repository[] getRepositories() throws IOException { | |
+ public Repository[] getDirectChildren() throws IOException { | |
List<Repository> list = new ArrayList<Repository>(); | |
Map<String,ZipEntry> entries = getChildEntries(); | |
Index: src/org/ringojs/repository/Repository.java | |
=================================================================== | |
--- src/org/ringojs/repository/Repository.java (revision e0dce2be640fc6fb43a1239d252948d10687ba9c) | |
+++ src/org/ringojs/repository/Repository.java (revision ) | |
@@ -66,9 +66,10 @@ | |
public Resource[] getResources(String resourcePath, boolean recursive) throws IOException; | |
/** | |
- * Returns this repository's direct child repositories | |
+ * Returns this repository's direct child repositories along with any manually added | |
+ * repositories (@see addChild) | |
* | |
- * @return direct repositories | |
+ * @return all child repositories | |
* @throws IOException an I/O error occurred | |
*/ | |
public Repository[] getRepositories() throws IOException; | |
@@ -92,4 +93,11 @@ | |
*/ | |
public String getRelativePath(); | |
+ /** | |
+ * Adds the repository parameter to the list of direct repository children. | |
+ * | |
+ * @param repository the repository to add as a child | |
+ */ | |
+ void addChild(Repository repository); | |
+ | |
} | |
\ No newline at end of file | |
Index: src/org/ringojs/repository/WebappRepository.java | |
=================================================================== | |
--- src/org/ringojs/repository/WebappRepository.java (revision e0dce2be640fc6fb43a1239d252948d10687ba9c) | |
+++ src/org/ringojs/repository/WebappRepository.java (revision ) | |
@@ -96,7 +96,7 @@ | |
} | |
} | |
- public Repository[] getRepositories() throws IOException { | |
+ public Repository[] getDirectChildren() throws IOException { | |
Set paths = context.getResourcePaths(path); | |
List<Repository> list = new ArrayList<Repository>(); | |
Index: src/org/ringojs/repository/FileRepository.java | |
=================================================================== | |
--- src/org/ringojs/repository/FileRepository.java (revision e0dce2be640fc6fb43a1239d252948d10687ba9c) | |
+++ src/org/ringojs/repository/FileRepository.java (revision ) | |
@@ -186,7 +186,7 @@ | |
} | |
} | |
- public Repository[] getRepositories() throws IOException { | |
+ public Repository[] getDirectChildren() throws IOException { | |
File[] dir = directory.listFiles(); | |
List<Repository> list = new ArrayList<Repository>(dir.length); | |
Index: src/org/ringojs/repository/AbstractRepository.java | |
=================================================================== | |
--- src/org/ringojs/repository/AbstractRepository.java (revision e0dce2be640fc6fb43a1239d252948d10687ba9c) | |
+++ src/org/ringojs/repository/AbstractRepository.java (revision ) | |
@@ -16,11 +16,12 @@ | |
package org.ringojs.repository; | |
-import org.ringojs.util.StringUtils; | |
- | |
import java.io.IOException; | |
import java.lang.ref.SoftReference; | |
-import java.util.*; | |
+import java.util.ArrayList; | |
+import java.util.Arrays; | |
+import java.util.List; | |
+import java.util.Map; | |
import java.util.concurrent.ConcurrentHashMap; | |
/** | |
@@ -30,256 +31,289 @@ | |
public abstract class AbstractRepository implements Repository { | |
- /** | |
- * Parent repository this repository is contained in. | |
- */ | |
- AbstractRepository parent; | |
+ /** | |
+ * Parent repository this repository is contained in. | |
+ */ | |
+ AbstractRepository parent; | |
- /** | |
- * Cache for direct child repositories | |
- */ | |
- Map<String, SoftReference<AbstractRepository>> repositories = | |
- new ConcurrentHashMap<String, SoftReference<AbstractRepository>>(); | |
+ /** | |
+ * Cache for direct child repositories | |
+ */ | |
+ Map<String, SoftReference<AbstractRepository>> repositories = | |
+ new ConcurrentHashMap<String, SoftReference<AbstractRepository>>(); | |
- /** | |
- * Cache for direct resources | |
- */ | |
- Map<String, AbstractResource> resources = new ConcurrentHashMap<String, AbstractResource>(); | |
+ /** | |
+ * Cache for direct resources | |
+ */ | |
+ Map<String, AbstractResource> resources = new ConcurrentHashMap<String, AbstractResource>(); | |
- /** | |
- * Cached name for faster access | |
- */ | |
- String path; | |
+ /** | |
+ * Cached name for faster access | |
+ */ | |
+ String path; | |
- /** | |
- * Cached short name for faster access | |
- */ | |
- String name; | |
+ /** | |
+ * Cached short name for faster access | |
+ */ | |
+ String name; | |
- /** | |
- * Whether this repository uses an absolute path | |
- */ | |
- private boolean isAbsolute = false; | |
+ /** | |
+ * Whether this repository uses an absolute path | |
+ */ | |
+ private boolean isAbsolute = false; | |
+ private List<Repository> children = new ArrayList<Repository>(); | |
+ | |
- /** | |
- * Called to create a child resource for this repository if it exists. | |
- * @param name the name of the child resource | |
- * @return the child resource, or null if no resource with the given name exists | |
- * @throws IOException an I/O error occurred | |
- */ | |
- protected abstract Resource lookupResource(String name) throws IOException; | |
+ /** | |
+ * Called to create a child resource for this repository if it exists. | |
+ * @param name the name of the child resource | |
+ * @return the child resource, or null if no resource with the given name exists | |
+ * @throws IOException an I/O error occurred | |
+ */ | |
+ protected abstract Resource lookupResource(String name) throws IOException; | |
- /** | |
- * Create a new child reposiotory with the given name. | |
- * @param name the name | |
- * @return the new child repository | |
- * @throws IOException an I/O error occurred | |
- */ | |
- protected abstract AbstractRepository createChildRepository(String name) throws IOException; | |
+ /** | |
+ * Create a new child reposiotory with the given name. | |
+ * @param name the name | |
+ * @return the new child repository | |
+ * @throws IOException an I/O error occurred | |
+ */ | |
+ protected abstract AbstractRepository createChildRepository(String name) throws IOException; | |
- /** | |
- * Add the repository's resources into the list, optionally descending into | |
- * nested repositories. | |
+ /** | |
+ * Add the repository's resources into the list, optionally descending into | |
+ * nested repositories. | |
- * @param list the list to add the resources to | |
+ * @param list the list to add the resources to | |
- * @param recursive whether to descend into nested repositories | |
- * @throws IOException an I/O related error occurred | |
- */ | |
- protected abstract void getResources(List<Resource> list, boolean recursive) | |
- throws IOException; | |
+ * @param recursive whether to descend into nested repositories | |
+ * @throws IOException an I/O related error occurred | |
+ */ | |
+ protected abstract void getResources(List<Resource> list, boolean recursive) | |
+ throws IOException; | |
- /** | |
+ /** | |
+ * Returns this repository's direct child repositories | |
+ * | |
+ * @return direct repositories | |
+ */ | |
+ protected abstract Repository[] getDirectChildren() throws IOException; | |
+ | |
+ | |
+ /** | |
- * Get the full name that identifies this repository globally | |
- */ | |
- public String getPath() { | |
- return path; | |
- } | |
+ * Get the full name that identifies this repository globally | |
+ */ | |
+ public String getPath() { | |
+ return path; | |
+ } | |
- /** | |
- * Get the local name that identifies this repository locally within its | |
- * parent repository | |
- */ | |
- public String getName() { | |
- return name; | |
- } | |
+ /** | |
+ * Get the local name that identifies this repository locally within its | |
+ * parent repository | |
+ */ | |
+ public String getName() { | |
+ return name; | |
+ } | |
- /** | |
- * Mark this repository as root repository. | |
- */ | |
- public void setRoot() { | |
- parent = null; | |
- } | |
+ /** | |
+ * Mark this repository as root repository. | |
+ */ | |
+ public void setRoot() { | |
+ parent = null; | |
+ } | |
- /** | |
- * Set this Repository to absolute mode. This will cause all its | |
- * relative path operations to use absolute paths instead. | |
- * @param absolute true to operate in absolute mode | |
- */ | |
- public void setAbsolute(boolean absolute) { | |
- isAbsolute = absolute; | |
- } | |
+ /** | |
+ * Set this Repository to absolute mode. This will cause all its | |
+ * relative path operations to use absolute paths instead. | |
+ * @param absolute true to operate in absolute mode | |
+ */ | |
+ public void setAbsolute(boolean absolute) { | |
+ isAbsolute = absolute; | |
+ } | |
- /** | |
- * Return true if this Repository is in absolute mode. | |
- * @return true if absolute mode is on | |
- */ | |
- public boolean isAbsolute() { | |
- return isAbsolute; | |
- } | |
+ /** | |
+ * Return true if this Repository is in absolute mode. | |
+ * @return true if absolute mode is on | |
+ */ | |
+ public boolean isAbsolute() { | |
+ return isAbsolute; | |
+ } | |
- /** | |
- * Get the path of this repository relative to its root repository. | |
- * | |
- * @return the repository path | |
- */ | |
- public String getRelativePath() { | |
- if (isAbsolute) { | |
- return path; | |
- } else if (parent == null) { | |
- return ""; | |
- } else { | |
- StringBuffer b = new StringBuffer(); | |
- getRelativePath(b); | |
- return b.toString(); | |
- } | |
- } | |
+ /** | |
+ * Get the path of this repository relative to its root repository. | |
+ * | |
+ * @return the repository path | |
+ */ | |
+ public String getRelativePath() { | |
+ if (isAbsolute) { | |
+ return path; | |
+ } else if (parent == null) { | |
+ return ""; | |
+ } else { | |
+ StringBuffer b = new StringBuffer(); | |
+ getRelativePath(b); | |
+ return b.toString(); | |
+ } | |
+ } | |
- private void getRelativePath(StringBuffer buffer) { | |
- if (isAbsolute) { | |
- buffer.append(path); | |
- } else if (parent != null) { | |
- parent.getRelativePath(buffer); | |
- buffer.append(name).append('/'); | |
- } | |
- } | |
+ private void getRelativePath(StringBuffer buffer) { | |
+ if (isAbsolute) { | |
+ buffer.append(path); | |
+ } else if (parent != null) { | |
+ parent.getRelativePath(buffer); | |
+ buffer.append(name).append('/'); | |
+ } | |
+ } | |
- /** | |
- * Utility method to get the name for the module defined by this resource. | |
- * | |
- * @return the module name according to the securable module spec | |
- */ | |
- public String getModuleName() { | |
- return getRelativePath(); | |
- } | |
+ /** | |
+ * Utility method to get the name for the module defined by this resource. | |
+ * | |
+ * @return the module name according to the securable module spec | |
+ */ | |
+ public String getModuleName() { | |
+ return getRelativePath(); | |
+ } | |
- /** | |
- * Get a resource contained in this repository identified by the given local name. | |
- * If the name can't be resolved to a resource, a resource object is returned | |
- * for which {@link Resource exists()} returns <code>false<code>. | |
- */ | |
- public synchronized Resource getResource(String subpath) throws IOException { | |
- int separator = findSeparator(subpath, 0); | |
- if (separator < 0) { | |
- return lookupResource(subpath); | |
- } | |
- // FIXME this part is virtually identical to the one in getChildRepository() | |
- AbstractRepository repo = this; | |
- int last = 0; | |
- while (separator > -1 && repo != null) { | |
- String id = subpath.substring(last, separator); | |
- repo = repo.lookupRepository(id); | |
- last = separator + 1; | |
- separator = findSeparator(subpath, last); | |
- } | |
- return repo == null ? null : repo.lookupResource(subpath.substring(last)); | |
- } | |
+ /** | |
+ * Get a resource contained in this repository identified by the given local name. | |
+ * If the name can't be resolved to a resource, a resource object is returned | |
+ * for which {@link Resource exists()} returns <code>false<code>. | |
+ */ | |
+ public synchronized Resource getResource(String subpath) throws IOException { | |
+ int separator = findSeparator(subpath, 0); | |
+ if (separator < 0) { | |
+ return lookupResource(subpath); | |
+ } | |
+ // FIXME this part is virtually identical to the one in getChildRepository() | |
+ AbstractRepository repo = this; | |
+ int last = 0; | |
+ while (separator > -1 && repo != null) { | |
+ String id = subpath.substring(last, separator); | |
+ repo = repo.lookupRepository(id); | |
+ last = separator + 1; | |
+ separator = findSeparator(subpath, last); | |
+ } | |
+ return repo == null ? null : repo.lookupResource(subpath.substring(last)); | |
+ } | |
- /** | |
- * Get a child repository with the given name | |
- * @param subpath the name of the repository | |
- * @return the child repository | |
- */ | |
- public AbstractRepository getChildRepository(String subpath) throws IOException { | |
- int separator = findSeparator(subpath, 0); | |
- if (separator < 0) { | |
- return lookupRepository(subpath); | |
- } | |
- // FIXME this part is virtually identical to the one in getResource() | |
- AbstractRepository repo = this; | |
- int last = 0; | |
- while (separator > -1 && repo != null) { | |
- String id = subpath.substring(last, separator); | |
- repo = repo.lookupRepository(id); | |
- last = separator + 1; | |
- separator = findSeparator(subpath, last); | |
- } | |
- return repo == null ? null : repo.lookupRepository(subpath.substring(last)); | |
- } | |
+ /** | |
+ * Get a child repository with the given name | |
+ * @param subpath the name of the repository | |
+ * @return the child repository | |
+ */ | |
+ public AbstractRepository getChildRepository(String subpath) throws IOException { | |
+ int separator = findSeparator(subpath, 0); | |
+ if (separator < 0) { | |
+ return lookupRepository(subpath); | |
+ } | |
+ // FIXME this part is virtually identical to the one in getResource() | |
+ AbstractRepository repo = this; | |
+ int last = 0; | |
+ while (separator > -1 && repo != null) { | |
+ String id = subpath.substring(last, separator); | |
+ repo = repo.lookupRepository(id); | |
+ last = separator + 1; | |
+ separator = findSeparator(subpath, last); | |
+ } | |
+ return repo == null ? null : repo.lookupRepository(subpath.substring(last)); | |
+ } | |
- protected AbstractRepository lookupRepository(String name) throws IOException { | |
- if (".".equals(name) || "".equals(name)) { | |
- return this; | |
- } else if ("..".equals(name)) { | |
- return getParentRepository(); | |
- } | |
- SoftReference<AbstractRepository> ref = repositories.get(name); | |
- AbstractRepository repo = ref == null ? null : ref.get(); | |
- if (repo == null) { | |
- repo = createChildRepository(name); | |
- repositories.put(name, new SoftReference<AbstractRepository>(repo)); | |
- } | |
- return repo; | |
- } | |
+ protected AbstractRepository lookupRepository(String name) throws IOException { | |
+ if (".".equals(name) || "".equals(name)) { | |
+ return this; | |
+ } else if ("..".equals(name)) { | |
+ return getParentRepository(); | |
+ } | |
+ SoftReference<AbstractRepository> ref = repositories.get(name); | |
+ AbstractRepository repo = ref == null ? null : ref.get(); | |
+ if (repo == null) { | |
+ repo = createChildRepository(name); | |
+ repositories.put(name, new SoftReference<AbstractRepository>(repo)); | |
+ } | |
+ return repo; | |
+ } | |
- /** | |
+ /** | |
+ * Returns this repository's direct child repositories | |
+ * | |
+ * @return direct repositories | |
+ * @throws java.io.IOException an I/O error occurred | |
+ */ | |
+ public Repository[] getRepositories() throws IOException { | |
+ final ArrayList<Repository> result = new ArrayList<Repository>(this.children); | |
+ | |
+ result.addAll(Arrays.asList(getDirectChildren())); | |
+ | |
+ return result.toArray(new Repository[result.size()]); | |
+ } | |
+ | |
+ /** | |
- * Get this repository's parent repository. | |
- */ | |
- public AbstractRepository getParentRepository() { | |
- return parent; | |
- } | |
+ * Get this repository's parent repository. | |
+ */ | |
+ public AbstractRepository getParentRepository() { | |
+ return parent; | |
+ } | |
- /** | |
- * Get the repository's root repository | |
- */ | |
- public Repository getRootRepository() { | |
- if (parent == null) { | |
- return this; | |
- } | |
- return parent.getRootRepository(); | |
- } | |
+ /** | |
+ * Get the repository's root repository | |
+ */ | |
+ public Repository getRootRepository() { | |
+ if (parent == null) { | |
+ return this; | |
+ } | |
+ return parent.getRootRepository(); | |
+ } | |
- public Resource[] getResources() throws IOException { | |
- return getResources(false); | |
- } | |
+ public Resource[] getResources() throws IOException { | |
+ return getResources(false); | |
+ } | |
- public Resource[] getResources(boolean recursive) throws IOException { | |
- List<Resource> list = new ArrayList<Resource>(); | |
- getResources(list, recursive); | |
- return list.toArray(new Resource[list.size()]); | |
- } | |
+ public Resource[] getResources(boolean recursive) throws IOException { | |
+ List<Resource> list = new ArrayList<Resource>(); | |
+ getResources(list, recursive); | |
+ return list.toArray(new Resource[list.size()]); | |
+ } | |
- public Resource[] getResources(String resourcePath, boolean recursive) | |
- throws IOException { | |
- Repository repository = getChildRepository(resourcePath); | |
- if (repository == null || !repository.exists()) { | |
- return new Resource[0]; | |
- } | |
- return repository.getResources(recursive); | |
- } | |
+ public Resource[] getResources(String resourcePath, boolean recursive) | |
+ throws IOException { | |
+ Repository repository = getChildRepository(resourcePath); | |
+ if (repository == null || !repository.exists()) { | |
+ return new Resource[0]; | |
+ } | |
+ return repository.getResources(recursive); | |
+ } | |
- /** | |
+ /** | |
+ * Adds the repository parameter to the list of direct repository children. | |
+ * | |
+ * @param repository the repository to add as a child | |
+ */ | |
+ public void addChild(Repository repository) { | |
+ this.children.add(repository); | |
+ } | |
+ | |
+ /** | |
- * Returns the repositories full path as string representation. | |
- * @see #getPath() | |
- */ | |
- public String toString() { | |
- return getPath(); | |
- } | |
+ * Returns the repositories full path as string representation. | |
+ * @see #getPath() | |
+ */ | |
+ public String toString() { | |
+ return getPath(); | |
+ } | |
- // Optimized separator lookup to avoid object creation overhead | |
- // of StringTokenizer and friends on critical code | |
- private int findSeparator(String path, int start) { | |
- int max = path.length(); | |
- int numberOfSeparators = SEPARATOR.length(); | |
- int found = -1; | |
- for (int i = 0; i < numberOfSeparators; i++) { | |
- char c = SEPARATOR.charAt(i); | |
- for (int j = start; j < max; j++) { | |
- if (path.charAt(j) == c) { | |
- found = max = j; | |
- break; | |
- } | |
- } | |
- } | |
- return found; | |
- } | |
+ // Optimized separator lookup to avoid object creation overhead | |
+ // of StringTokenizer and friends on critical code | |
+ private int findSeparator(String path, int start) { | |
+ int max = path.length(); | |
+ int numberOfSeparators = SEPARATOR.length(); | |
+ int found = -1; | |
+ for (int i = 0; i < numberOfSeparators; i++) { | |
+ char c = SEPARATOR.charAt(i); | |
+ for (int j = start; j < max; j++) { | |
+ if (path.charAt(j) == c) { | |
+ found = max = j; | |
+ break; | |
+ } | |
+ } | |
+ } | |
+ return found; | |
+ } | |
} | |
Index: src/org/ringojs/tools/RingoConfiguration.java | |
=================================================================== | |
--- src/org/ringojs/tools/RingoConfiguration.java (revision e0dce2be640fc6fb43a1239d252948d10687ba9c) | |
+++ src/org/ringojs/tools/RingoConfiguration.java (revision ) | |
@@ -28,6 +28,7 @@ | |
import java.io.UnsupportedEncodingException; | |
import java.net.URLDecoder; | |
import java.util.ArrayList; | |
+import java.util.Enumeration; | |
import java.util.List; | |
import java.util.Collections; | |
import java.net.MalformedURLException; | |
@@ -99,6 +100,8 @@ | |
addModuleRepository(resolveRootRepository(systemModules)); | |
} | |
+ addPackagesOnClasspath(); | |
+ | |
// now that repositories are set up try to set default log4j configuration file | |
if (System.getProperty("log4j.configuration") == null) { | |
Resource log4jConfig = getResource("config/log4j.properties"); | |
@@ -111,6 +114,35 @@ | |
getLogger().fine("Parsed repository list: " + repositories); | |
} | |
+ /** | |
+ * Scour the current classpath looking for Common-JS packages to be added to the repository | |
+ * list for package resolution. A Common-JS package is identified as an archive on the Java | |
+ * classpath containing a package.json resource in the root folder. | |
+ * (@see http://wiki.commonjs.org/wiki/Packages/1.0) | |
+ * | |
+ * @throws IOException | |
+ */ | |
+ public void addPackagesOnClasspath() throws IOException { | |
+ ClassLoader loader = Thread.currentThread().getContextClassLoader(); | |
+ Enumeration<URL> resources = loader.getResources("package.json"); | |
+ if (resources.hasMoreElements()) { | |
+ | |
+ final Repository packages = getPackageRepository(); | |
+ | |
+ while (resources.hasMoreElements()) { | |
+ URL url = resources.nextElement(); | |
+ String path = url.getPath(); | |
+ // If the package.json file is found in a jar/zip file, we need to strip the url | |
+ // down to resolve the root. | |
+ if (path.startsWith("file:")) path = path.substring(5); | |
+ String[] paths = path.split("!"); | |
+ getLogger().fine("Found package.json at " + paths[0]); | |
+// addModuleRepository(resolveRootRepository(paths[0])); | |
+ packages.addChild(resolveRootRepository(paths[0])); | |
+ } | |
+ } | |
+ } | |
+ | |
public void addModuleRepository(Repository repository) throws IOException { | |
if (repository != null && repository.exists()) { | |
repository.setRoot(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment