package org.geoserver.rest.javascript;
import java.io.File;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.restlet.Restlet;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.data.Status;
import org.restlet.resource.StringRepresentation;
import org.geoserver.catalog.Catalog;
import org.geoserver.platform.GeoServerResourceLoader;
import org.geoserver.rest.RestletException;
public class JavaScriptRestlet extends Restlet {
private String scriptPath;
private GeoServerResourceLoader resourceLoader;
private Catalog catalog;
public void setResourceLoader(GeoServerResourceLoader loader) {
resourceLoader = loader;
}
public void setRootPath(String s) { scriptPath = s; }
public void setCatalog(Catalog c) { catalog = c; }
public void handle(Request request, Response response) {
String scriptName = (String) request.getAttributes().get("script");
if (scriptName == null) {
File scriptDirectory = null;
try {
scriptDirectory = resourceLoader.find(scriptPath);
} catch (IOException ioe) {
// no, it's cool. we might have to handle a null return anyway.
}
if (scriptDirectory == null) throw new RestletException(
"No script directory", Status.CLIENT_ERROR_NOT_FOUND
);
StringBuilder out = new StringBuilder();
for (String script : scriptDirectory.list(new FilenameFilter() {
public boolean accept(File f, String name) {
return name.endsWith(".js");
}
})) {
out.append(script.substring(0, script.length() - 3))
.append(", ");
}
response.setEntity(new StringRepresentation(out.toString()));
} else {
File script;
try {
script = resourceLoader.find(scriptPath, scriptName + ".js");
} catch (IOException ioe) {
throw new RestletException(
"Requested script [" + scriptName + "] does not exist",
Status.CLIENT_ERROR_NOT_FOUND
);
}
Context cx = Context.enter();
try {
Scriptable scope = cx.initStandardObjects();
FileReader reader = new FileReader(script);
Object wrappedRequest = Context.javaToJS(request, scope);
Object wrappedResponse = Context.javaToJS(response, scope);
Object wrappedCatalog = Context.javaToJS(catalog, scope);
ScriptableObject.putProperty(scope, "request", wrappedRequest);
ScriptableObject
.putProperty(scope, "response", wrappedResponse);
ScriptableObject.putProperty(scope, "catalog", wrappedCatalog);
cx.evaluateReader(scope, reader, script.getName(), 1, null);
} catch (IOException e) {
throw new RestletException(
"I/O error while loading script...",
Status.SERVER_ERROR_INTERNAL
);
} finally {
Context.exit();
}
}
}
}