/** * 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); } }
/** * Invoke a script from the command line. * * @param scriptResource the script resource of path * @param scriptArgs an array of command line arguments * @return the return value * @throws IOException an I/O related error occurred * @throws JavaScriptException the script threw an error during compilation or execution */ public Object runScript(Object scriptResource, String... scriptArgs) throws IOException, JavaScriptException { Resource resource; if (scriptResource instanceof Resource) { resource = (Resource) scriptResource; } else if (scriptResource instanceof String) { resource = findResource((String) scriptResource, null, null); } else { throw new IOException("Unsupported script resource: " + scriptResource); } if (!resource.exists()) { throw new FileNotFoundException(scriptResource.toString()); } Context cx = contextFactory.enterContext(); try { Object retval; Map<Trackable, ReloadableScript> scripts = getScriptCache(cx); commandLineArgs = Arrays.asList(scriptArgs); ReloadableScript script = new ReloadableScript(resource, this); scripts.put(resource, script); mainScope = new ModuleScope(resource.getModuleName(), resource, globalScope, mainWorker); retval = mainWorker.evaluateScript(cx, script, mainScope); mainScope.updateExports(); return retval instanceof Wrapper ? ((Wrapper) retval).unwrap() : retval; } finally { Context.exit(); } }
private void evaluateBootstrapScripts(Context cx) throws IOException { List<String> bootstrapScripts = config.getBootstrapScripts(); if (bootstrapScripts != null) { for (String script : bootstrapScripts) { Resource resource = new FileResource(script); // not found, attempt to resolve the file relative to ringo home if (!resource.exists()) { resource = getRingoHome().getResource(script); } if (resource == null || !resource.exists()) { throw new FileNotFoundException("Bootstrap script " + script + " not found"); } mainWorker.evaluateScript(cx, new ReloadableScript(resource, this), globalScope); } } }
/** * 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); }
public ModuleLoader getModuleLoader(Resource resource) { String name = resource.getName(); for (ModuleLoader loader : loaders) { if (name.endsWith(loader.getExtension())) { return loader; } } return loaders[0]; }
private Scriptable parseJsonResource(Resource resource) throws IOException { JsonParser parser = new JsonParser(Context.getCurrentContext(), globalScope); try { Object result = parser.parseValue(resource.getContent()); if (!(result instanceof Scriptable)) { throw new RuntimeException("Expected Object from package.json, got " + result); } return (Scriptable) result; } catch (JsonParser.ParseException px) { throw new RuntimeException(px); } }
/** * Resolves a type name to a script file within our script directory and returns a Scriptable * evaluated to the file. * * @param moduleName the name of the module to load * @param localPath the path of the resource issuing this call * @return The raw compiled script for the module * @throws JavaScriptException if an error occurred evaluating the script file * @throws IOException if an error occurred reading the script file */ public ReloadableScript getScript(String moduleName, Repository localPath) throws JavaScriptException, IOException { ReloadableScript script; Resource source = findResource(moduleName, loaders, localPath); if (!source.exists()) { source = loadPackage(moduleName, localPath); if (!source.exists()) { source = findResource(moduleName, null, localPath); } } Context cx = Context.getCurrentContext(); Map<Trackable, ReloadableScript> scripts = getScriptCache(cx); if (scripts.containsKey(source)) { script = scripts.get(source); } else { script = new ReloadableScript(source, this); if (source.exists()) { scripts.put(source, script); } } return script; }