Skip to content

Instantly share code, notes, and snippets.

@oravecz
Created December 2, 2010 17:14
Show Gist options
  • Save oravecz/725691 to your computer and use it in GitHub Desktop.
Save oravecz/725691 to your computer and use it in GitHub Desktop.
Patch for RingoJS - Auto-discovery of Packages
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