/**
* Copyright (c) 2013 IMS GLobal Learning Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* Author: Charles Severance <csev@umich.edu>
*/
package org.imsglobal.lti2;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;
import org.imsglobal.basiclti.BasicLTIConstants;
import org.imsglobal.basiclti.BasicLTIUtil;
import org.imsglobal.json.IMSJSONRequest;
import org.imsglobal.lti2.objects.Service_offered;
import org.imsglobal.lti2.objects.StandardServices;
import org.imsglobal.lti2.objects.ToolConsumer;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
/**
* Notes:
*
* This is a sample "Hello World" servlet for LTI2. It is a simple UI - mostly
* intended to exercise the APIs and show the way for servlet-based LTI2 code.
*
* Here are the web.xml entries:
*
* <servlet>
* <servlet-name>SampleServlet</servlet-name>
* <servlet-class>org.imsglobal.lti2.LTI2Servlet</servlet-class>
* </servlet>
* <servlet-mapping>
* <servlet-name>SampleServlet</servlet-name>
* <url-pattern>/sample/*</url-pattern>
* </servlet-mapping>
*
* The navigate to:
* http://localhost/testservlet/sample/register
*
* A PHP endpoint is available at:
*
* https://source.sakaiproject.org/svn/basiclti/trunk/basiclti-docs/resources/docs/sakai-api-test
*
* The tp.php script is the Tool Provider registration endpoint in the PHP code
*
*/
@SuppressWarnings("deprecation")
public class LTI2Servlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static Log M_log = LogFactory.getLog(LTI2Servlet.class);
protected Service_offered LTI2ResultItem = null;
protected Service_offered LTI2LtiLinkSettings = null;
protected Service_offered LTI2ToolProxyBindingSettings = null;
protected Service_offered LTI2ToolProxySettings = null;
private static final String SVC_tc_profile = "tc_profile";
private static final String SVC_tc_registration = "tc_registration";
private static final String SVC_Settings = "Settings";
private static final String SVC_Result = "Result";
@SuppressWarnings("unused")
private static final String EMPTY_JSON_OBJECT = "{\n}\n";
private static final String APPLICATION_JSON = "application/json";
// Normally these would be in a database
private static String TEST_KEY = "42";
private static String TEST_SECRET = "zaphod";
// Pretending to be a database row :)
private static Map<String, String> PERSIST = new TreeMap<String, String> ();
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
try {
doRequest(request, response);
} catch (Exception e) {
String ipAddress = request.getRemoteAddr();
String uri = request.getRequestURI();
M_log.warn("General LTI2 Failure URI="+uri+" IP=" + ipAddress);
e.printStackTrace();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
doErrorJSON(request, response, null, "General failure", e);
}
}
@SuppressWarnings("unused")
protected void doRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
System.out.println("getServiceURL="+getServiceURL(request));
String ipAddress = request.getRemoteAddr();
System.out.println("LTI Service request from IP=" + ipAddress);
String rpi = request.getPathInfo();
String uri = request.getRequestURI();
String [] parts = uri.split("/");
if ( parts.length < 4 ) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
doErrorJSON(request, response, null, "Incorrect url format", null);
return;
}
String controller = parts[3];
if ( "register".equals(controller) ) {
doRegister(request,response);
return;
} else if ( "launch".equals(controller) ) {
doLaunch(request,response);
return;
} else if ( SVC_tc_profile.equals(controller) && parts.length == 5 ) {
String profile_id = parts[4];
getToolConsumerProfile(request,response,profile_id);
return;
} else if ( SVC_tc_registration.equals(controller) && parts.length == 5 ) {
String profile_id = parts[4];
registerToolProviderProfile(request, response, profile_id);
return;
} else if ( SVC_Result.equals(controller) && parts.length == 5 ) {
String sourcedid = parts[4];
handleResultRequest(request, response, sourcedid);
return;
} else if ( SVC_Settings.equals(controller) && parts.length >= 6 ) {
handleSettingsRequest(request, response, parts);
return;
}
IMSJSONRequest jsonRequest = new IMSJSONRequest(request);
if ( jsonRequest.valid ) {
System.out.println(jsonRequest.getPostBody());
}
response.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
M_log.warn("Unknown request="+uri);
doErrorJSON(request, response, null, "Unknown request="+uri, null);
}
protected void doRegister(HttpServletRequest request, HttpServletResponse response)
{
// Reset our database
PERSIST.clear();
String launch_url = request.getParameter("launch_url");
response.setContentType("text/html");
String output = null;
if ( launch_url != null ) {
Properties ltiProps = new Properties();
ltiProps.setProperty(BasicLTIConstants.LTI_VERSION, LTI2Constants.LTI2_VERSION_STRING);
ltiProps.setProperty(LTI2Constants.REG_KEY,TEST_KEY);
ltiProps.setProperty(LTI2Constants.REG_PASSWORD,TEST_SECRET);
ltiProps.setProperty(BasicLTIUtil.BASICLTI_SUBMIT, "Press to Launch External Tool");
ltiProps.setProperty(BasicLTIConstants.LTI_MESSAGE_TYPE, BasicLTIConstants.LTI_MESSAGE_TYPE_TOOLPROXYREGISTRATIONREQUEST);
String serverUrl = getServiceURL(request);
ltiProps.setProperty(LTI2Constants.TC_PROFILE_URL,serverUrl + SVC_tc_profile + "/" + TEST_KEY);
ltiProps.setProperty(BasicLTIConstants.LAUNCH_PRESENTATION_RETURN_URL, serverUrl + "launch");
System.out.println("ltiProps="+ltiProps);
boolean dodebug = true;
output = BasicLTIUtil.postLaunchHTML(ltiProps, launch_url, dodebug);
} else {
output = "<form>Register URL:<br/><input type=\"text\" name=\"launch_url\" size=\"80\"\n" +
"value=\"http://localhost:8888/sakai-api-test/tp.php\"><input type=\"submit\">\n";
}
try {
PrintWriter out = response.getWriter();
out.println(output);
}
catch (Exception e) {
e.printStackTrace();
}
}
// We are actually bypassing the activation step. Usually activation will parse
// the profile, and install a tool if the admin is happy. For us we just parse
// the profile and do a launch.
@SuppressWarnings("unused")
protected void doLaunch(HttpServletRequest request, HttpServletResponse response)
{
String profile = PERSIST.get("profile");
response.setContentType("text/html");
String output = null;
if ( profile == null ) {
output = "Missing profile";
} else {
JSONObject providerProfile = (JSONObject) JSONValue.parse(profile);
List<Properties> profileTools = new ArrayList<Properties> ();
Properties info = new Properties();
String retval = LTI2Util.parseToolProfile(profileTools, info, providerProfile);
String launch = null;
String parameter = null;
for ( Properties profileTool : profileTools ) {
launch = (String) profileTool.get("launch");
parameter = (String) profileTool.get("parameter");
}
JSONObject security_contract = (JSONObject) providerProfile.get(LTI2Constants.SECURITY_CONTRACT);
String shared_secret = (String) security_contract.get(LTI2Constants.SHARED_SECRET);
System.out.println("launch="+launch);
System.out.println("shared_secret="+shared_secret);
Properties ltiProps = LTI2SampleData.getLaunch();
ltiProps.setProperty(BasicLTIConstants.LTI_VERSION,BasicLTIConstants.LTI_VERSION_2);
Properties lti2subst = LTI2SampleData.getSubstitution();
String settings_url = getServiceURL(request) + SVC_Settings + "/";
lti2subst.setProperty("LtiLink.custom.url", settings_url + LTI2Util.SCOPE_LtiLink + "/"
+ ltiProps.getProperty(BasicLTIConstants.RESOURCE_LINK_ID));
lti2subst.setProperty("ToolProxyBinding.custom.url", settings_url + LTI2Util.SCOPE_ToolProxyBinding + "/"
+ ltiProps.getProperty(BasicLTIConstants.CONTEXT_ID));
lti2subst.setProperty("ToolProxy.custom.url", settings_url + LTI2Util.SCOPE_ToolProxy + "/"
+ TEST_KEY);
lti2subst.setProperty("Result.url", getServiceURL(request) + SVC_Result + "/"
+ ltiProps.getProperty(BasicLTIConstants.RESOURCE_LINK_ID));
// Do the substitutions
Properties custom = new Properties();
LTI2Util.mergeLTI2Parameters(custom, parameter);
LTI2Util.substituteCustom(custom, lti2subst);
// Place the custom values into the launch
LTI2Util.addCustomToLaunch(ltiProps, custom);
ltiProps = BasicLTIUtil.signProperties(ltiProps, launch, "POST",
TEST_KEY, shared_secret, null, null, null);
boolean dodebug = true;
output = BasicLTIUtil.postLaunchHTML(ltiProps, launch, dodebug);
}
try {
PrintWriter out = response.getWriter();
out.println(output);
}
catch (Exception e) {
e.printStackTrace();
}
}
protected void getToolConsumerProfile(HttpServletRequest request,
HttpServletResponse response,String profile_id)
{
// Map<String,Object> deploy = ltiService.getDeployForConsumerKeyDao(profile_id);
Map<String,Object> deploy = null;
ToolConsumer consumer = buildToolConsumerProfile(request, deploy, profile_id);
ObjectMapper mapper = new ObjectMapper();
try {
// http://stackoverflow.com/questions/6176881/how-do-i-make-jackson-pretty-print-the-json-content-it-generates
ObjectWriter writer = mapper.defaultPrettyPrintingWriter();
// ***IMPORTANT!!!*** for Jackson 2.x use the line below instead of the one above:
// ObjectWriter writer = mapper.writer().withDefaultPrettyPrinter();
// System.out.println(mapper.writeValueAsString(consumer));
response.setContentType(APPLICATION_JSON);
PrintWriter out = response.getWriter();
out.println(writer.writeValueAsString(consumer));
// System.out.println(writer.writeValueAsString(consumer));
}
catch (Exception e) {
e.printStackTrace();
}
}
// Normally deploy would have the data about the deployment - for this test
// it is always null and we allow everything
protected ToolConsumer buildToolConsumerProfile(HttpServletRequest request, Map<String, Object> deploy, String profile_id)
{
// Load the configuration data
LTI2Config cnf = new org.imsglobal.lti2.LTI2ConfigSample();
ToolConsumer consumer = new ToolConsumer(profile_id+"", getServiceURL(request), cnf);
// Normally we would check permissions before we offer capabilities
List<String> capabilities = consumer.getCapability_offered();
LTI2Util.allowEmail(capabilities);
LTI2Util.allowName(capabilities);
LTI2Util.allowSettings(capabilities);
LTI2Util.allowResult(capabilities);
// Normally we would check permissions before we offer services
List<Service_offered> services = consumer.getService_offered();
services.add(StandardServices.LTI2Registration(getServiceURL(request) +
SVC_tc_registration + "/" + profile_id));
services.add(StandardServices.LTI2ResultItem(getServiceURL(request) +
SVC_Result + "/{" + BasicLTIConstants.LIS_RESULT_SOURCEDID + "}"));
services.add(StandardServices.LTI2LtiLinkSettings(getServiceURL(request) +
SVC_Settings + "/" + LTI2Util.SCOPE_LtiLink + "/{" + BasicLTIConstants.RESOURCE_LINK_ID + "}"));
services.add(StandardServices.LTI2ToolProxySettings(getServiceURL(request) +
SVC_Settings + "/" + LTI2Util.SCOPE_ToolProxyBinding + "/{" + BasicLTIConstants.CONTEXT_ID + "}"));
services.add(StandardServices.LTI2ToolProxySettings(getServiceURL(request) +
SVC_Settings + "/" + LTI2Util.SCOPE_ToolProxy + "/{" + LTI2Constants.TOOL_PROXY_GUID + "}"));
return consumer;
}
@SuppressWarnings({ "unchecked", "unused", "rawtypes" })
public void registerToolProviderProfile(HttpServletRequest request,HttpServletResponse response,
String profile_id) throws java.io.IOException
{
// Normally we would look up the deployment descriptor
if ( ! TEST_KEY.equals(profile_id) ) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
String key = TEST_KEY;
String secret = TEST_SECRET;
IMSJSONRequest jsonRequest = new IMSJSONRequest(request);
if ( ! jsonRequest.valid ) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
doErrorJSON(request, response, jsonRequest, "Request is not in a valid format", null);
return;
}
System.out.println(jsonRequest.getPostBody());
// Lets check the signature
if ( key == null || secret == null ) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
doErrorJSON(request, response, jsonRequest, "Deployment is missing credentials", null);
return;
}
jsonRequest.validateRequest(key, secret, request);
if ( !jsonRequest.valid ) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
doErrorJSON(request, response, jsonRequest, "OAuth signature failure", null);
return;
}
JSONObject providerProfile = (JSONObject) JSONValue.parse(jsonRequest.getPostBody());
// System.out.println("OBJ:"+providerProfile);
if ( providerProfile == null ) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
doErrorJSON(request, response, jsonRequest, "JSON parse failed", null);
return;
}
JSONObject default_custom = (JSONObject) providerProfile.get(LTI2Constants.CUSTOM);
JSONObject security_contract = (JSONObject) providerProfile.get(LTI2Constants.SECURITY_CONTRACT);
if ( security_contract == null ) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
doErrorJSON(request, response, jsonRequest, "JSON missing security_contract", null);
return;
}
String shared_secret = (String) security_contract.get(LTI2Constants.SHARED_SECRET);
System.out.println("shared_secret="+shared_secret);
if ( shared_secret == null ) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
doErrorJSON(request, response, jsonRequest, "JSON missing shared_secret", null);
return;
}
// Make sure that the requested services are a subset of the offered services
ToolConsumer consumer = buildToolConsumerProfile(request, null, profile_id);
JSONArray tool_services = (JSONArray) security_contract.get(LTI2Constants.TOOL_SERVICE);
String retval = LTI2Util.validateServices(consumer, providerProfile);
if ( retval != null ) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
doErrorJSON(request, response, jsonRequest, retval, null);
return;
}
// Parse the tool profile bit and extract the tools with error checking
retval = LTI2Util.validateCapabilities(consumer, providerProfile);
if ( retval != null ) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
doErrorJSON(request, response, jsonRequest, retval, null);
return;
}
// Pass the profile to the launch process
PERSIST.put("profile", providerProfile.toString());
// Share our happiness with the Tool Provider
Map jsonResponse = new TreeMap();
jsonResponse.put(LTI2Constants.CONTEXT,StandardServices.TOOLPROXY_ID_CONTEXT);
jsonResponse.put(LTI2Constants.TYPE, StandardServices.TOOLPROXY_ID_TYPE);
jsonResponse.put(LTI2Constants.JSONLD_ID, getServiceURL(request) + SVC_tc_registration + "/" +profile_id);
jsonResponse.put(LTI2Constants.TOOL_PROXY_GUID, profile_id);
jsonResponse.put(LTI2Constants.CUSTOM_URL, getServiceURL(request) + SVC_Settings + "/" + LTI2Util.SCOPE_ToolProxy + "/" +profile_id);
response.setContentType(StandardServices.TOOLPROXY_ID_FORMAT);
response.setStatus(HttpServletResponse.SC_CREATED);
String jsonText = JSONValue.toJSONString(jsonResponse);
M_log.debug(jsonText);
PrintWriter out = response.getWriter();
out.println(jsonText);
}
public String getServiceURL(HttpServletRequest request) {
String scheme = request.getScheme(); // http
String serverName = request.getServerName(); // localhost
int serverPort = request.getServerPort(); // 80
String contextPath = request.getContextPath(); // /imsblis
String servletPath = request.getServletPath(); // /ltitest
String url = scheme+"://"+serverName+":"+serverPort+contextPath+servletPath+"/";
return url;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public void handleResultRequest(HttpServletRequest request,HttpServletResponse response,
String sourcedid) throws java.io.IOException
{
IMSJSONRequest jsonRequest = null;
String retval = null;
if ( "GET".equals(request.getMethod()) ) {
String grade = PERSIST.get("grade");
String comment = PERSIST.get("comment");
Map jsonResponse = new TreeMap();
Map resultScore = new TreeMap();
jsonResponse.put(LTI2Constants.CONTEXT,StandardServices.RESULT_CONTEXT);
jsonResponse.put(LTI2Constants.TYPE, StandardServices.RESULT_TYPE);
resultScore.put(LTI2Constants.TYPE, LTI2Constants.GRADE_TYPE_DECIMAL);
jsonResponse.put(LTI2Constants.COMMENT, grade);
resultScore.put(LTI2Constants.VALUE, comment);
jsonResponse.put(LTI2Constants.RESULTSCORE,resultScore);
response.setContentType(StandardServices.RESULT_FORMAT);
response.setStatus(HttpServletResponse.SC_OK);
String jsonText = JSONValue.toJSONString(jsonResponse);
M_log.debug(jsonText);
PrintWriter out = response.getWriter();
out.println(jsonText);
return;
} else if ( "PUT".equals(request.getMethod()) ) {
retval = "Error parsing input data";
try {
jsonRequest = new IMSJSONRequest(request);
// System.out.println(jsonRequest.getPostBody());
JSONObject requestData = (JSONObject) JSONValue.parse(jsonRequest.getPostBody());
String comment = (String) requestData.get(LTI2Constants.COMMENT);
JSONObject resultScore = (JSONObject) requestData.get(LTI2Constants.RESULTSCORE);
String sGrade = (String) resultScore.get(LTI2Constants.VALUE);
Double dGrade = new Double(sGrade);
PERSIST.put("comment", comment);
PERSIST.put("grade", dGrade+"");
response.setStatus(HttpServletResponse.SC_OK);
return;
} catch (Exception e) {
retval = "Error: "+ e.getMessage();
}
} else {
retval = "Unsupported operation:" + request.getMethod();
}
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
doErrorJSON(request,response, jsonRequest, (String) retval, null);
}
// If this code looks like a hack - it is because the spec is a hack.
// There are five possible scenarios for GET and two possible scenarios
// for PUT. I begged to simplify the business logic but was overrulled.
// So we write obtuse code.
@SuppressWarnings("unused")
public void handleSettingsRequest(HttpServletRequest request,HttpServletResponse response,
String[] parts) throws java.io.IOException
{
String URL = request.getRequestURL().toString();
System.out.println("URL="+URL);
String scope = parts[4];
System.out.println("scope="+scope);
String acceptHdr = request.getHeader("Accept");
String contentHdr = request.getContentType();
boolean acceptComplex = acceptHdr == null || acceptHdr.indexOf(StandardServices.TOOLSETTINGS_FORMAT) >= 0 ;
System.out.println("accept="+acceptHdr+" ac="+acceptComplex);
// Check the JSON on PUT and check the oauth_body_hash
IMSJSONRequest jsonRequest = null;
JSONObject requestData = null;
if ( "PUT".equals(request.getMethod()) ) {
try {
jsonRequest = new IMSJSONRequest(request);
requestData = (JSONObject) JSONValue.parse(jsonRequest.getPostBody());
} catch (Exception e) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
doErrorJSON(request,response, jsonRequest, "Could not parse JSON", e);
return;
}
}
String consumer_key = TEST_KEY;
String profile = PERSIST.get("profile");
JSONObject providerProfile = (JSONObject) JSONValue.parse(profile);
JSONObject security_contract = (JSONObject) providerProfile.get(LTI2Constants.SECURITY_CONTRACT);
String oauth_secret = (String) security_contract.get(LTI2Constants.SHARED_SECRET);
// Validate the incoming message
Object retval = BasicLTIUtil.validateMessage(request, URL, oauth_secret, consumer_key);
if ( retval instanceof String ) {
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
doErrorJSON(request,response, jsonRequest, (String) retval, null);
return;
}
// The URLs for the various settings resources
String settingsUrl = getServiceURL(request) + SVC_Settings;
String proxy_url = settingsUrl + "/" + LTI2Util.SCOPE_ToolProxy + "/" + consumer_key;
String binding_url = settingsUrl + "/" + LTI2Util.SCOPE_ToolProxyBinding + "/" + "TBD";
String link_url = settingsUrl + "/" + LTI2Util.SCOPE_LtiLink + "/" + "TBD";
// Load and parse the old settings...
JSONObject link_settings = LTI2Util.parseSettings(PERSIST.get(LTI2Util.SCOPE_LtiLink));
JSONObject binding_settings = LTI2Util.parseSettings(PERSIST.get(LTI2Util.SCOPE_ToolProxyBinding));
JSONObject proxy_settings = LTI2Util.parseSettings(PERSIST.get(LTI2Util.SCOPE_ToolProxy));
// For a GET request we depend on LTI2Util to do the GET logic
if ( "GET".equals(request.getMethod()) ) {
Object obj = LTI2Util.getSettings(request, scope,
link_settings, binding_settings, proxy_settings,
link_url, binding_url, proxy_url);
if ( obj instanceof String ) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
doErrorJSON(request,response, jsonRequest, (String) obj, null);
return;
}
if ( acceptComplex ) {
response.setContentType(StandardServices.TOOLSETTINGS_FORMAT);
} else {
response.setContentType(StandardServices.TOOLSETTINGS_SIMPLE_FORMAT);
}
JSONObject jsonResponse = (JSONObject) obj;
response.setStatus(HttpServletResponse.SC_OK);
PrintWriter out = response.getWriter();
System.out.println("jsonResponse="+jsonResponse);
out.println(jsonResponse.toString());
return;
} else if ( "PUT".equals(request.getMethod()) ) {
// This is assuming the rule that a PUT of the complex settings
// format that there is only one entry in the graph and it is
// the same as our current URL. We parse without much checking.
String settings = null;
try {
JSONArray graph = (JSONArray) requestData.get(LTI2Constants.GRAPH);
if ( graph.size() != 1 ) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
doErrorJSON(request,response, jsonRequest, "Only one graph entry allowed", null);
return;
}
JSONObject firstChild = (JSONObject) graph.get(0);
JSONObject custom = (JSONObject) firstChild.get(LTI2Constants.CUSTOM);
settings = custom.toString();
} catch (Exception e) {
settings = jsonRequest.getPostBody();
}
PERSIST.put(scope,settings);
System.out.println("Stored settings scope="+scope);
System.out.println("settings="+settings);
response.setStatus(HttpServletResponse.SC_OK);
} else {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
doErrorJSON(request,response, jsonRequest, "Method not handled="+request.getMethod(), null);
}
}
/* IMS JSON version of Errors */
public void doErrorJSON(HttpServletRequest request,HttpServletResponse response,
IMSJSONRequest json, String message, Exception e)
throws java.io.IOException
{
if (e != null) {
M_log.error(e.getLocalizedMessage(), e);
}
M_log.info(message);
String output = IMSJSONRequest.doErrorJSON(request, response, json, message, e);
System.out.println(output);
}
public void destroy() {
}
}