/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.script.rest; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.io.Writer; import java.util.logging.Level; import java.util.logging.Logger; import javax.script.ScriptEngine; import javax.script.ScriptException; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.geoserver.rest.PageInfo; import org.geoserver.rest.RestletException; import org.geoserver.script.ScriptManager; import org.geoserver.script.ScriptSession; import org.restlet.data.MediaType; import org.restlet.data.Request; import org.restlet.data.Response; import org.restlet.data.Status; import org.restlet.resource.OutputRepresentation; import org.restlet.resource.Resource; import org.restlet.resource.StringRepresentation; /** * Resource for a script session. * <p> * This resource provides access to {@link ScriptSession} instances. It allows for the following * operations: * <ul> * <li>POST /sessions : create a new session, returning its identifier * <li>GET /sessions/[id] : return info about session [id] * <li>PUT /sessions/[id] : execute a statement in session [id] * <ul> * </p> * @author Justin Deoliveira, OpenGeo */ public class SessionResource extends Resource { static Logger LOGGER = Logger.getLogger("org.geoserver.script.rest"); ScriptManager scriptMgr; public SessionResource(ScriptManager scriptMgr, Request request, Response response) { super(null, request, response); this.scriptMgr = scriptMgr; } @Override public void handleGet() { String s = (String) getRequest().getAttributes().get("session"); String ext = (String) getRequest().getAttributes().get("ext"); JSONObject obj = null; if (s != null) { //return individual obj = toJSON(scriptMgr.findSession(Long.valueOf(s))); } else { //return all JSONArray array = new JSONArray(); for (ScriptSession session : scriptMgr.findSessions(ext)) { array.add(toJSON(session)); } obj = new JSONObject(); obj.put("sessions", array); } getResponse().setEntity(new StringRepresentation(obj.toString(2), MediaType.APPLICATION_JSON)); getResponse().setStatus(Status.SUCCESS_OK); } JSONObject toJSON(ScriptSession session) { PageInfo pageInfo = (PageInfo) getRequest().getAttributes().get(PageInfo.KEY); JSONObject obj = new JSONObject(); obj.put("id", session.getId()); obj.put("engine", session.getEngineName()); obj.put("self", pageInfo.baseURI( String.format("sessions/%s/%d", session.getExtension(), session.getId()))); return obj; } @Override public boolean allowPost() { return !getRequest().getAttributes().containsKey("session"); } @Override public void handlePost() { String ext = (String) getRequest().getAttributes().get("ext"); ScriptSession session = scriptMgr.createNewSession(ext); if (session == null) { throw new RestletException("Unable to create session", Status.SERVER_ERROR_INTERNAL); } PageInfo page = (PageInfo) getRequest().getAttributes().get(PageInfo.KEY); getResponse().redirectSeeOther(page.pageURI(String.valueOf(session.getId()))); getResponse().setEntity(new StringRepresentation(String.valueOf(session.getId()))); getResponse().setStatus(Status.SUCCESS_CREATED); } @Override public boolean allowPut() { return getRequest().getAttributes().containsKey("session"); } @Override public void handlePut() { long sid = Long.valueOf((String)getRequest().getAttributes().get("session")); ScriptSession session = scriptMgr.findSession(sid); ScriptEngine engine = session.getEngine(); final ByteArrayOutputStream output = new ByteArrayOutputStream(); Writer w = new PrintWriter(output); engine.getContext().setWriter(w); engine.getContext().setErrorWriter(w); try { try { Object result = engine.eval(new InputStreamReader(getRequest().getEntity().getStream())); if (result != null) { w.write(result.toString()); } } catch (ScriptException e) { Throwable t = e; if (t.getCause() != null) { t = t.getCause(); } t.printStackTrace(new PrintWriter(w)); if (LOGGER.isLoggable(Level.FINE)) { LOGGER.log(Level.FINE, "Script error", e); } } w.flush(); } catch(IOException e) { throw new RestletException("i/o error", Status.SERVER_ERROR_INTERNAL, e); } getResponse().setEntity(new OutputRepresentation(MediaType.TEXT_PLAIN) { @Override public void write(OutputStream outputStream) throws IOException { outputStream.write(output.toByteArray()); } }); getResponse().setStatus(Status.SUCCESS_OK); } }