/** * Resolves a module id to a package resource. If module id consists of just one term and resolves * to a package directory, the main module of the package is returned. If the module id consists * of several terms and the first term resolves to a package directory, the remaining part of the * module id is resolved against the "lib" directory of the package. * * @link http://nodejs.org/docs/v0.4.4/api/modules.html#folders_as_Modules * @param moduleName the name of the package to load * @param localPath the path of the resource issuing this call * @return the location of the package's main module * @throws IOException an unrecoverable I/O exception occurred while reading the package */ protected Resource loadPackage(String moduleName, Repository localPath) throws IOException { int slash = 0; String packageName, remainingName; do { slash = moduleName.indexOf('/', slash + 1); if (slash == -1) { packageName = moduleName; remainingName = null; } else { packageName = moduleName.substring(0, slash); if (".".equals(packageName) || "..".equals(packageName)) continue; remainingName = moduleName.substring(slash + 1); } Resource json = findResource(packageName + "/package.json", null, localPath); if (json != null && json.exists()) { Scriptable obj = parseJsonResource(json); Repository parent = json.getParentRepository(); String moduleId; Resource res; if (remainingName == null) { // get the main module of this package moduleId = getStringProperty(obj, "main", null); if (moduleId != null) { // optimize for the common case where main module // property links to the exact file name res = parent.getResource(moduleId); if (res != null && res.exists()) return res; } } else { // map remaining name to libs directory String lib = "lib"; Object dirs = ScriptableObject.getProperty(obj, "directories"); if (dirs instanceof Scriptable) { lib = getStringProperty((Scriptable) dirs, "lib", "lib"); } moduleId = lib + "/" + remainingName; } if (moduleId != null) { for (ModuleLoader loader : loaders) { res = parent.getResource(moduleId + loader.getExtension()); if (res != null && res.exists()) return res; } if (remainingName != null) { res = parent.getResource(moduleId); if (res != null && res.exists()) return res; } } } } while (slash != -1); return findResource(moduleName + "/index", loaders, localPath); }
/** * Search for a repository in the local path, or the main repository path. * * @param path the repository name * @param localPath a repository to look first * @return the repository * @throws IOException if an I/O error occurred */ public Repository findRepository(String path, Repository localPath) throws IOException { // To be consistent, always return absolute repository if path is absolute // if we make this dependent on whether files exist we introduce a lot of // vague and undetermined behaviour. File file = new File(path); if (file.isAbsolute()) { return new FileRepository(file); } if (localPath != null) { Repository repository = localPath.getChildRepository(path); if (repository != null && repository.exists()) { return repository; } } return config.getRepository(normalizePath(path)); }
/** * Search for a resource in a local path, or the main repository path. * * @param path the resource name * @param loaders optional list of module loaders * @param localRoot a repository to look first * @return the resource * @throws IOException if an I/O error occurred */ public Resource findResource(String path, ModuleLoader[] loaders, Repository localRoot) throws IOException { // Note: as an extension to the CommonJS modules API // we allow absolute module paths for resources File file = new File(path); if (file.isAbsolute()) { Resource res; outer: if (loaders != null) { // loaders must contain at least one loader assert loaders.length > 0 && loaders[0] != null; for (ModuleLoader loader : loaders) { res = new FileResource(path + loader.getExtension()); if (res.exists()) { break outer; } } res = new FileResource(path + loaders[0].getExtension()); } else { res = new FileResource(file); } res.setAbsolute(true); return res; } else if (localRoot != null && (path.startsWith("./") || path.startsWith("../"))) { String newpath = localRoot.getRelativePath() + path; return findResource(newpath, loaders, null); } else { return config.getResource(normalizePath(path), loaders); } }
/** * Return a shell scope for interactive evaluation * * @return a shell scope * @throws IOException an I/O related exception occurred */ public Scriptable getShellScope(RingoWorker worker) throws IOException { Repository repository = new FileRepository(""); repository.setAbsolute(true); Scriptable protoScope = mainScope != null ? mainScope : globalScope; return new ModuleScope("<shell>", repository, protoScope, worker); }