org.mozilla.javascript.commonjs.module.provider.ModuleSourceProviderBase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rhino Show documentation
Show all versions of rhino Show documentation
The Rhino JavaScript Engine for Java
The newest version!
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.javascript.commonjs.module.provider;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
/**
* A base implementation for all module script providers that actually load
* module scripts. Performs validation of identifiers, allows loading from
* preferred locations (attempted before require.paths), from require.paths
* itself, and from fallback locations (attempted after require.paths). Note
* that while this base class strives to be as generic as possible, it does
* have loading from an URI built into its design, for the simple reason that
* the require.paths is defined in terms of URIs.
* @author Attila Szegedi
* @version $Id: ModuleSourceProviderBase.java,v 1.3 2011/04/07 20:26:12 hannes%helma.at Exp $
*/
public abstract class ModuleSourceProviderBase implements
ModuleSourceProvider, Serializable
{
private static final long serialVersionUID = 1L;
public ModuleSource loadSource(String moduleId, Scriptable paths,
Object validator) throws IOException, URISyntaxException
{
if(!entityNeedsRevalidation(validator)) {
return NOT_MODIFIED;
}
ModuleSource moduleSource = loadFromPrivilegedLocations(
moduleId, validator);
if(moduleSource != null) {
return moduleSource;
}
if(paths != null) {
moduleSource = loadFromPathArray(moduleId, paths,
validator);
if(moduleSource != null) {
return moduleSource;
}
}
return loadFromFallbackLocations(moduleId, validator);
}
public ModuleSource loadSource(URI uri, URI base, Object validator)
throws IOException, URISyntaxException {
return loadFromUri(uri, base, validator);
}
private ModuleSource loadFromPathArray(String moduleId,
Scriptable paths, Object validator) throws IOException
{
final long llength = ScriptRuntime.toUint32(
ScriptableObject.getProperty(paths, "length"));
// Yeah, I'll ignore entries beyond Integer.MAX_VALUE; so sue me.
int ilength = llength > Integer.MAX_VALUE ? Integer.MAX_VALUE :
(int)llength;
for(int i = 0; i < ilength; ++i) {
final String path = ensureTrailingSlash(
ScriptableObject.getTypedProperty(paths, i, String.class));
try {
URI uri = new URI(path);
if (!uri.isAbsolute()) {
uri = new File(path).toURI().resolve("");
}
final ModuleSource moduleSource = loadFromUri(
uri.resolve(moduleId), uri, validator);
if(moduleSource != null) {
return moduleSource;
}
}
catch(URISyntaxException e) {
throw new MalformedURLException(e.getMessage());
}
}
return null;
}
private static String ensureTrailingSlash(String path) {
return path.endsWith("/") ? path : path.concat("/");
}
/**
* Override to determine whether according to the validator, the cached
* module script needs revalidation. A validator can carry expiry
* information. If the cached representation is not expired, it doesn'
* t need revalidation, otherwise it does. When no cache revalidation is
* required, the external resource will not be contacted at all, so some
* level of expiry (staleness tolerance) can greatly enhance performance.
* The default implementation always returns true so it will always require
* revalidation.
* @param validator the validator
* @return returns true if the cached module needs revalidation.
*/
protected boolean entityNeedsRevalidation(Object validator) {
return true;
}
/**
* Override in a subclass to load a module script from a logical URI. The
* URI is absolute but does not have a file name extension such as ".js".
* It is up to the ModuleSourceProvider implementation to add such an
* extension.
* @param uri the URI of the script, without file name extension.
* @param base the base URI the uri was resolved from.
* @param validator a validator that can be used to revalidate an existing
* cached source at the URI. Can be null if there is no cached source
* available.
* @return the loaded module script, or null if it can't be found, or
* {@link ModuleSourceProvider#NOT_MODIFIED} if it revalidated the existing
* cached source against the URI.
* @throws IOException if the module script was found, but an I/O exception
* prevented it from being loaded.
* @throws URISyntaxException if the final URI could not be constructed
*/
protected abstract ModuleSource loadFromUri(URI uri, URI base,
Object validator) throws IOException, URISyntaxException;
/**
* Override to obtain a module source from privileged locations. This will
* be called before source is attempted to be obtained from URIs specified
* in require.paths.
* @param moduleId the ID of the module
* @param validator a validator that can be used to validate an existing
* cached script. Can be null if there is no cached script available.
* @return the loaded module script, or null if it can't be found in the
* privileged locations, or {@link ModuleSourceProvider#NOT_MODIFIED} if
* the existing cached module script is still valid.
* @throws IOException if the module script was found, but an I/O exception
* prevented it from being loaded.
* @throws URISyntaxException if the final URI could not be constructed.
*/
protected ModuleSource loadFromPrivilegedLocations(
String moduleId, Object validator)
throws IOException, URISyntaxException
{
return null;
}
/**
* Override to obtain a module source from fallback locations. This will
* be called after source is attempted to be obtained from URIs specified
* in require.paths.
* @param moduleId the ID of the module
* @param validator a validator that can be used to validate an existing
* cached script. Can be null if there is no cached script available.
* @return the loaded module script, or null if it can't be found in the
* privileged locations, or {@link ModuleSourceProvider#NOT_MODIFIED} if
* the existing cached module script is still valid.
* @throws IOException if the module script was found, but an I/O exception
* prevented it from being loaded.
* @throws URISyntaxException if the final URI could not be constructed.
*/
protected ModuleSource loadFromFallbackLocations(
String moduleId, Object validator)
throws IOException, URISyntaxException
{
return null;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy