Java tutorial
/********************************************************************************** * $URL: https://source.sakaiproject.org/svn/basiclti/branches/sakai-10.x/basiclti-tool/src/java/org/sakaiproject/blti/tool/LTIAdminTool.java $ * $Id: LTIAdminTool.java 311798 2014-08-11 14:00:13Z enietzel@anisakai.com $ *********************************************************************************** * * Copyright (c) 2011 The Sakai Foundation * * Licensed under the Educational Community 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.opensource.org/licenses/ECL-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. * **********************************************************************************/ package org.sakaiproject.blti.tool; import java.io.Writer; import java.io.PrintWriter; import java.io.StringWriter; import java.util.HashSet; import java.util.Properties; import java.util.List; import java.util.Map; import java.util.HashMap; import java.util.ArrayList; import java.util.Arrays; import java.util.Set; import java.util.UUID; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.lang.StringUtils; import org.json.simple.JSONValue; import org.json.simple.JSONObject; import org.json.simple.JSONArray; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.ObjectWriter; import org.sakaiproject.cheftool.Context; import org.sakaiproject.cheftool.JetspeedRunData; import org.sakaiproject.cheftool.RunData; import org.sakaiproject.cheftool.VelocityPortlet; import org.sakaiproject.cheftool.VelocityPortletPaneledAction; import org.sakaiproject.cheftool.api.Menu; import org.sakaiproject.cheftool.menu.MenuEntry; import org.sakaiproject.cheftool.menu.MenuImpl; import org.sakaiproject.event.api.SessionState; import org.sakaiproject.util.ResourceLoader; import org.sakaiproject.tool.api.Placement; import org.sakaiproject.tool.api.ToolManager; import org.sakaiproject.tool.api.Session; import org.sakaiproject.component.cover.ComponentManager; import org.sakaiproject.tool.cover.SessionManager; import org.sakaiproject.site.api.Site; import org.sakaiproject.site.api.SitePage; import org.sakaiproject.site.cover.SiteService; import org.sakaiproject.site.api.ToolConfiguration; import org.sakaiproject.component.api.ServerConfigurationService; import org.sakaiproject.util.FormattedText; // TODO: FIX THIS import org.sakaiproject.tool.cover.SessionManager; import org.sakaiproject.lti.api.LTIService; import org.sakaiproject.basiclti.util.SakaiBLTIUtil; import org.imsglobal.basiclti.BasicLTIUtil; import org.imsglobal.lti2.LTI2Config; import org.imsglobal.lti2.LTI2Util; import org.sakaiproject.lti2.SakaiLTI2Config; // import org.sakaiproject.lti.impl.DBLTIService; // HACK import org.sakaiproject.util.foorm.SakaiFoorm; /** * <p> * LTIAdminTool is a Simple Velocity-based Tool * </p> */ public class LTIAdminTool extends VelocityPortletPaneledAction { private static Log M_log = LogFactory.getLog(LTIAdminTool.class); /** Resource bundle using current language locale */ protected static ResourceLoader rb = new ResourceLoader("ltitool"); private boolean inHelper = false; private static String STATE_POST = "lti:state_post"; private static String STATE_SUCCESS = "lti:state_success"; private static String STATE_ID = "lti:state_id"; private static String STATE_TOOL_ID = "lti:state_tool_id"; private static String STATE_CONTENT_ID = "lti:state_content_id"; private static String STATE_REDIRECT_URL = "lti:state_redirect_url"; private static String STATE_LTI2_TOOL_ID = "lti2:state_tool_id"; private static String SECRET_HIDDEN = "***************"; private static String ALLOW_MAINTAINER_ADD_SYSTEM_TOOL = "lti:allow_maintainer_add_system_tool"; /** Service Implementations */ protected static ToolManager toolManager = null; protected static LTIService ltiService = null; protected static ServerConfigurationService serverConfigurationService = null; protected static SakaiFoorm foorm = new SakaiFoorm(); /** * Pull in any necessary services using factory pattern */ protected void getServices() { if (toolManager == null) toolManager = (ToolManager) ComponentManager.get("org.sakaiproject.tool.api.ToolManager"); /* HACK to save many restarts during development if ( ltiService == null ) { ltiService = (LTIService) new DBLTIService(); ((org.sakaiproject.lti.impl.DBLTIService) ltiService).setAutoDdl("true"); ((org.sakaiproject.lti.impl.DBLTIService) ltiService).init(); } End of HACK */ if (ltiService == null) ltiService = (LTIService) ComponentManager.get("org.sakaiproject.lti.api.LTIService"); if (serverConfigurationService == null) serverConfigurationService = (ServerConfigurationService) ComponentManager .get("org.sakaiproject.component.api.ServerConfigurationService"); } /** * Populate the state with configuration settings */ protected void initState(SessionState state, VelocityPortlet portlet, JetspeedRunData rundata) { super.initState(state, portlet, rundata); getServices(); Placement placement = toolManager.getCurrentPlacement(); String toolReg = placement.getToolId(); inHelper = !("sakai.basiclti.admin".equals(toolReg)); } /** * Setup the velocity context and choose the template for the response. */ public String buildErrorPanelContext(VelocityPortlet portlet, Context context, RunData rundata, SessionState state) { context.put("tlang", rb); state.removeAttribute(STATE_ID); state.removeAttribute(STATE_TOOL_ID); state.removeAttribute(STATE_POST); state.removeAttribute(STATE_SUCCESS); state.removeAttribute(STATE_REDIRECT_URL); return "lti_error"; } public String buildMainPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { // default to site view return buildToolSitePanelContext(portlet, context, data, state); } public String buildToolSitePanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.edit")); return "lti_error"; } String returnUrl = data.getParameters().getString("returnUrl"); // if ( returnUrl != null ) state.setAttribute(STATE_REDIRECT_URL, returnUrl); context.put("ltiService", ltiService); context.put("isAdmin", new Boolean(ltiService.isAdmin())); context.put("inHelper", new Boolean(inHelper)); context.put("getContext", toolManager.getCurrentPlacement().getContext()); context.put("doEndHelper", BUTTON + "doEndHelper"); state.removeAttribute(STATE_POST); state.removeAttribute(STATE_SUCCESS); // this is for the "site tools" panel List<Map<String, Object>> contents = ltiService.getContents(null, null, 0, 5000); for (Map<String, Object> content : contents) { Long tool_id_long = null; try { tool_id_long = new Long(content.get(LTIService.LTI_TOOL_ID).toString()); } catch (Exception e) { // log the error M_log.error("error parsing tool id " + content.get(LTIService.LTI_TOOL_ID)); } context.put("tool_id_long", tool_id_long); String plstr = (String) content.get(LTIService.LTI_PLACEMENT); ToolConfiguration tool = SiteService.findTool(plstr); if (tool == null) { content.put(LTIService.LTI_PLACEMENT, null); } } context.put("contents", contents); context.put("messageSuccess", state.getAttribute(STATE_SUCCESS)); context.put("isAdmin", new Boolean(ltiService.isAdmin())); context.put("getContext", toolManager.getCurrentPlacement().getContext()); // top navigation menu Menu menu = new MenuImpl(portlet, data, "LTIAdminTool"); menu.add(new MenuEntry(rb.getString("tool.in.site"), false, "doNav_tool_site")); menu.add(new MenuEntry(rb.getString("tool.in.system"), true, "doNav_tool_system")); context.put("menu", menu); return "lti_tool_site"; } public String buildToolSystemPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.edit")); return "lti_error"; } String contextString = toolManager.getCurrentPlacement().getContext(); String returnUrl = data.getParameters().getString("returnUrl"); // if ( returnUrl != null ) state.setAttribute(STATE_REDIRECT_URL, returnUrl); context.put("ltiService", ltiService); context.put("isAdmin", new Boolean(ltiService.isAdmin())); context.put("inHelper", new Boolean(inHelper)); context.put("doEndHelper", BUTTON + "doEndHelper"); state.removeAttribute(STATE_POST); state.removeAttribute(STATE_SUCCESS); context.put("messageSuccess", state.getAttribute(STATE_SUCCESS)); context.put("isAdmin", new Boolean(ltiService.isAdmin())); // by default, site maintainer can add system-wide LTI tool context.put("allowMaintainerAddSystemTool", new Boolean(serverConfigurationService.getBoolean(ALLOW_MAINTAINER_ADD_SYSTEM_TOOL, true))); context.put("getContext", contextString); // this is for the system tool panel List<Map<String, Object>> tools = ltiService.getTools(null, null, 0, 0); context.put("ltiTools", tools); // top navigation menu Menu menu = new MenuImpl(portlet, data, "LTIAdminTool"); menu.add(new MenuEntry(rb.getString("tool.in.site"), true, "doNav_tool_site")); menu.add(new MenuEntry(rb.getString("tool.in.system"), false, "doNav_tool_system")); context.put("menu", menu); return "lti_tool_system"; } public void doEndHelper(RunData data, Context context) { // Request a shortcut transfer back to the tool we are helping // This working depends on SAK-20898 SessionManager.getCurrentToolSession().setAttribute(HELPER_LINK_MODE, HELPER_MODE_DONE); // In case the above fails... String peid = ((JetspeedRunData) data).getJs_peid(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(peid); switchPanel(state, "Main"); } public String buildToolViewPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.view")); return "lti_error"; } context.put("messageSuccess", state.getAttribute(STATE_SUCCESS)); String[] mappingForm = ltiService.getToolModel(); String id = data.getParameters().getString(LTIService.LTI_ID); if (id == null) { addAlert(state, rb.getString("error.id.not.found")); return "lti_main"; } Long key = new Long(id); Map<String, Object> tool = ltiService.getTool(key); if (tool == null) return "lti_main"; // Deal with the differences between LTI 1 and LTI 2 Long version = foorm.getLongNull(tool.get(LTIService.LTI_VERSION)); boolean isLTI1 = version == null || version == LTIService.LTI_VERSION_1; if (isLTI1) { mappingForm = foorm.filterForm(mappingForm, null, ".*:only=lti2.*"); } else { mappingForm = foorm.filterForm(mappingForm, null, ".*:only=lti1.*"); } // Extract the version to make it view only String fieldInfo = foorm.getFormField(mappingForm, "version"); fieldInfo = fieldInfo.replace(":hidden=true", ""); String formStatus = ltiService.formOutput(tool, fieldInfo); context.put("formStatus", formStatus); tool.put(LTIService.LTI_SECRET, SECRET_HIDDEN); tool.put(LTIService.LTI_CONSUMERKEY, SECRET_HIDDEN); String formOutput = ltiService.formOutput(tool, mappingForm); context.put("formOutput", formOutput); state.removeAttribute(STATE_SUCCESS); return "lti_tool_view"; } public String buildToolEditPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); String stateId = (String) state.getAttribute(STATE_ID); state.removeAttribute(STATE_ID); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.edit")); return "lti_error"; } context.put("doToolAction", BUTTON + "doToolPut"); context.put("messageSuccess", state.getAttribute(STATE_SUCCESS)); String[] mappingForm = ltiService.getToolModel(); String id = data.getParameters().getString(LTIService.LTI_ID); if (id == null) id = stateId; if (id == null) { addAlert(state, rb.getString("error.id.not.found")); return "lti_main"; } Long key = new Long(id); Map<String, Object> tool = ltiService.getTool(key); if (tool == null) return "lti_main"; // Hide the old tool secret unless it is incomplete if (!LTIService.LTI_SECRET_INCOMPLETE.equals(tool.get(LTIService.LTI_SECRET))) { tool.put(LTIService.LTI_SECRET, SECRET_HIDDEN); } // Deal with the differences between LTI 1 and LTI 2 Long version = foorm.getLongNull(tool.get(LTIService.LTI_VERSION)); boolean isLTI1 = version == null || version == LTIService.LTI_VERSION_1; if (isLTI1) { mappingForm = foorm.filterForm(mappingForm, null, ".*:only=lti2.*"); } else { mappingForm = foorm.filterForm(mappingForm, null, ".*:only=lti1.*"); } // Extract the version to make it view only String fieldInfo = foorm.getFormField(mappingForm, "version"); fieldInfo = fieldInfo.replace(":hidden=true", ""); String formStatus = ltiService.formOutput(tool, fieldInfo); context.put("formStatus", formStatus); // If we are not admin, hide url, key, and secret if (!isLTI1 && !ltiService.isAdmin()) { mappingForm = foorm.filterForm(mappingForm, null, "^launch:.*|^consumerkey:.*|^secret:.*"); } String formInput = ltiService.formInput(tool, mappingForm); context.put("formInput", formInput); state.removeAttribute(STATE_SUCCESS); return "lti_tool_insert"; } public String buildToolDeletePanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.delete")); return "lti_error"; } context.put("doToolAction", BUTTON + "doToolDelete"); String[] mappingForm = foorm.filterForm(ltiService.getToolModel(), "^title:.*|^launch:.*|^id:.*", null); String id = data.getParameters().getString(LTIService.LTI_ID); if (id == null) { addAlert(state, rb.getString("error.id.not.found")); return "lti_main"; } Long key = new Long(id); // Retrieve the tool using a WHERE clause so the counts get computed List<Map<String, Object>> tools = ltiService.getTools("lti_tools.id = " + key, null, 0, 0); if (tools == null || tools.size() < 1) { addAlert(state, rb.getString("error.tool.not.found")); return "lti_main"; } Map<String, Object> tool = tools.get(0); String formOutput = ltiService.formOutput(tool, mappingForm); context.put("formOutput", formOutput); context.put("tool", tool); context.put("tool_count", tool.get("lti_content_count")); context.put("tool_unique_site_count", tool.get("lti_site_count")); state.removeAttribute(STATE_SUCCESS); return "lti_tool_delete"; } public void doToolDelete(RunData data, Context context) { String peid = ((JetspeedRunData) data).getJs_peid(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(peid); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.delete")); switchPanel(state, "Error"); return; } Properties reqProps = data.getParameters().getProperties(); String id = data.getParameters().getString(LTIService.LTI_ID); Object retval = null; if (id == null) { addAlert(state, rb.getString("error.id.not.found")); switchPanel(state, "ToolSystem"); return; } Long key = new Long(id); if (ltiService.deleteTool(key)) { state.setAttribute(STATE_SUCCESS, rb.getString("success.deleted")); // remove all content object and site links if any // this is for the "site tools" panel List<Map<String, Object>> contents = ltiService.getContents(null, null, 0, 5000); for (Map<String, Object> content : contents) { Long tool_id_long = null; try { tool_id_long = new Long(content.get(LTIService.LTI_TOOL_ID).toString()); if (tool_id_long.equals(key)) { // the content with same tool id // remove the content link first String content_id = content.get(LTIService.LTI_ID).toString(); Long content_key = content_id == null ? null : new Long(content_id); //TODO: how to handle the errors in content link and content deletion? // remove the external tool content site link ltiService.deleteContentLink(content_key); // remove the external tool content ltiService.deleteContent(content_key); } } catch (Exception e) { // log the error M_log.error("error parsing tool id " + content.get(LTIService.LTI_TOOL_ID)); } } switchPanel(state, "ToolSystem"); } else { addAlert(state, rb.getString("error.delete.fail")); switchPanel(state, "ToolSystem"); } } public String buildToolInsertPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.edit")); return "lti_error"; } context.put("doToolAction", BUTTON + "doToolPut"); context.put("messageSuccess", state.getAttribute(STATE_SUCCESS)); String[] mappingForm = ltiService.getToolModel(); mappingForm = foorm.filterForm(mappingForm, null, ".*:only=edit.*|.*:only=lti2.*"); Properties previousPost = (Properties) state.getAttribute(STATE_POST); String formInput = ltiService.formInput(previousPost, mappingForm); context.put("formInput", formInput); state.removeAttribute(STATE_POST); state.removeAttribute(STATE_SUCCESS); return "lti_tool_insert"; } // Insert or edit public void doToolPut(RunData data, Context context) { String peid = ((JetspeedRunData) data).getJs_peid(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(peid); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.delete")); switchPanel(state, "Error"); return; } Properties reqProps = data.getParameters().getProperties(); String newSecret = reqProps.getProperty(LTIService.LTI_SECRET); if (SECRET_HIDDEN.equals(newSecret)) { reqProps.remove(LTIService.LTI_SECRET); newSecret = null; } if (newSecret != null) { newSecret = SakaiBLTIUtil.encryptSecret(newSecret.trim()); reqProps.setProperty(LTIService.LTI_SECRET, newSecret); } String id = data.getParameters().getString(LTIService.LTI_ID); String success = null; Object retval = null; if (id == null) { retval = ltiService.insertTool(reqProps); success = rb.getString("success.created"); } else { Long key = new Long(id); retval = ltiService.updateTool(key, reqProps); success = rb.getString("success.updated"); } if (retval instanceof String) { state.setAttribute(STATE_POST, reqProps); addAlert(state, (String) retval); state.setAttribute(STATE_ID, id); return; } state.setAttribute(STATE_SUCCESS, success); switchPanel(state, "ToolSystem"); } /** Deployment related methods ------------------------------ */ public String buildDeployInsertPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); if (!ltiService.isAdmin()) { addAlert(state, rb.getString("error.admin.edit")); return "lti_error"; } context.put("doDeployAction", BUTTON + "doDeployPut"); context.put("messageSuccess", state.getAttribute(STATE_SUCCESS)); context.put("reg_state", new Integer(0)); String[] mappingForm = ltiService.getDeployModel(); mappingForm = foorm.filterForm(mappingForm, null, ".*:hide=insert.*"); Properties previousPost = (Properties) state.getAttribute(STATE_POST); String formInput = ltiService.formInput(previousPost, mappingForm); context.put("formInput", formInput); state.removeAttribute(STATE_POST); state.removeAttribute(STATE_SUCCESS); return "lti_deploy_insert"; } public String buildDeployViewPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); if (!ltiService.isAdmin()) { addAlert(state, rb.getString("error.admin.view")); return "lti_error"; } context.put("messageSuccess", state.getAttribute(STATE_SUCCESS)); String[] mappingForm = ltiService.getDeployModel(); String id = data.getParameters().getString(LTIService.LTI_ID); if (id == null) { addAlert(state, rb.getString("error.id.not.found")); return "lti_error"; } Long key = new Long(id); Map<String, Object> deploy = ltiService.getDeployDao(key); if (deploy == null) return "lti_error"; // Extract the reg_state to make it view only String fieldInfo = foorm.getFormField(mappingForm, "reg_state"); fieldInfo = fieldInfo.replace(":hidden=true", ""); String formStatus = ltiService.formOutput(deploy, fieldInfo); context.put("formStatus", formStatus); String formOutput = ltiService.formOutput(deploy, mappingForm); context.put("formOutput", formOutput); Long reg_state = foorm.getLongNull(deploy.get(LTIService.LTI_REG_STATE)); context.put("reg_state", reg_state); context.put("id", id); state.removeAttribute(STATE_SUCCESS); return "lti_deploy_view"; } public String buildDeployEditPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); String stateId = (String) state.getAttribute(STATE_ID); state.removeAttribute(STATE_ID); if (!ltiService.isAdmin()) { addAlert(state, rb.getString("error.admin.edit")); return "lti_error"; } context.put("doDeployAction", BUTTON + "doDeployPut"); context.put("messageSuccess", state.getAttribute(STATE_SUCCESS)); String[] mappingForm = ltiService.getDeployModel(); String id = data.getParameters().getString(LTIService.LTI_ID); if (id == null) id = stateId; if (id == null) { addAlert(state, rb.getString("error.id.not.found")); return "lti_error"; } Long key = new Long(id); Map<String, Object> deploy = ltiService.getDeployDao(key); if (deploy == null) return "lti_error"; // Extract the reg_state to make it view only String fieldInfo = foorm.getFormField(mappingForm, "reg_state"); fieldInfo = fieldInfo.replace(":hidden=true", ""); String formStatus = ltiService.formOutput(deploy, fieldInfo); context.put("formStatus", formStatus); Long reg_state = foorm.getLongNull(deploy.get(LTIService.LTI_REG_STATE)); context.put("reg_state", reg_state); // Remove reg_state from the editable part of the model mappingForm = foorm.filterForm(mappingForm, null, "^reg_state:.*"); String formInput = ltiService.formInput(deploy, mappingForm); context.put("formInput", formInput); state.removeAttribute(STATE_SUCCESS); return "lti_deploy_insert"; } // Insert or edit public void doDeployPut(RunData data, Context context) { String peid = ((JetspeedRunData) data).getJs_peid(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(peid); if (!ltiService.isAdmin()) { addAlert(state, rb.getString("error.admin.edit")); switchPanel(state, "Error"); return; } Properties reqProps = data.getParameters().getProperties(); String id = data.getParameters().getString(LTIService.LTI_ID); // If we are inserting, fill in the blanks if (id == null) { reqProps.setProperty(LTIService.LTI_REG_KEY, UUID.randomUUID().toString()); // TODO: We should show off and encrypt the REG_PASSWORD too.. reqProps.setProperty(LTIService.LTI_REG_PASSWORD, UUID.randomUUID().toString()); reqProps.setProperty(LTIService.LTI_CONSUMERKEY, UUID.randomUUID().toString()); } String success = null; Object retval = null; boolean lti2Insert = false; if (id == null) { retval = ltiService.insertDeployDao(reqProps); success = rb.getString("success.created"); lti2Insert = true; } else { Long key = new Long(id); retval = ltiService.updateDeployDao(key, reqProps); success = rb.getString("success.updated"); } if (retval instanceof String) { state.setAttribute(STATE_POST, reqProps); addAlert(state, (String) retval); state.setAttribute(STATE_ID, id); return; } state.setAttribute(STATE_SUCCESS, success); if (lti2Insert && retval instanceof Long) { Long insertedKey = (Long) retval; switchPanel(state, "DeployRegister&id=" + insertedKey); } else { switchPanel(state, "DeploySystem"); } } public String buildDeployRegisterPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.activate")); return "lti_error"; } context.put("messageSuccess", state.getAttribute(STATE_SUCCESS)); String[] mappingForm = foorm.filterForm(ltiService.getDeployModel(), "^title:.*|^reg_state:.*|^reg_launch:.*|^id:.*", null); String id = data.getParameters().getString(LTIService.LTI_ID); if (id == null) { addAlert(state, rb.getString("error.id.not.found")); return "lti_error"; } Long key = new Long(id); Map<String, Object> deploy = ltiService.getDeployDao(key); if (deploy == null) { addAlert(state, rb.getString("error.deploy.not.found")); return "lti_error"; } Long reg_state = foorm.getLongNull(deploy.get(LTIService.LTI_REG_STATE)); String reg_key = (String) deploy.get(LTIService.LTI_REG_KEY); String reg_password = (String) deploy.get(LTIService.LTI_REG_PASSWORD); String consumerkey = (String) deploy.get(LTIService.LTI_CONSUMERKEY); String secret = (String) deploy.get(LTIService.LTI_SECRET); if (reg_state == 0 && reg_key != null && reg_password != null && consumerkey != null) { // Good news ... } else if ((reg_state == 1 || reg_state == 2) && secret != null && consumerkey != null) { // Good news ... } else { addAlert(state, rb.getString("error.register.not.ready")); return "lti_error"; } // Extract the reg_state to make it view only String fieldInfo = foorm.getFormField(mappingForm, "reg_state"); fieldInfo = fieldInfo.replace(":hidden=true", ""); String formStatus = ltiService.formOutput(deploy, fieldInfo); context.put("formStatus", formStatus); String formOutput = ltiService.formOutput(deploy, mappingForm); context.put("formOutput", formOutput); Placement placement = toolManager.getCurrentPlacement(); String registerURL = "/access/basiclti/site/~admin/deploy:" + key + "?placement=" + placement.getId(); context.put("registerURL", registerURL); state.removeAttribute(STATE_SUCCESS); return "lti_deploy_register"; } public String buildActivatePanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); if (!ltiService.isAdmin()) { addAlert(state, rb.getString("error.admin.activate")); return "lti_error"; } context.put("messageSuccess", state.getAttribute(STATE_SUCCESS)); String[] mappingForm = ltiService.getDeployModel(); String id = data.getParameters().getString(LTIService.LTI_ID); if (id == null) { addAlert(state, rb.getString("error.id.not.found")); return "lti_error"; } Long key = null; try { key = new Long(id); } catch (Exception e) { return "Non-numeric id value " + id; } Map<String, Object> deploy = ltiService.getDeployDao(key); if (deploy == null) return "lti_error"; String profileText = (String) deploy.get(LTIService.LTI_REG_PROFILE); if (profileText == null || profileText.length() < 1) { addAlert(state, rb.getString("error.activate.not.ready")); return "lti_error"; } // Load and check the tools from the profile List<Map<String, Object>> theTools = new ArrayList<Map<String, Object>>(); Properties info = new Properties(); String retval = prepareValidate(deploy, theTools, info, state); if (retval != null) return retval; context.put("info", info); context.put("deploy", deploy); context.put("tools", theTools); context.put("profile", profileText); context.put("doAction", BUTTON + "doActivate"); return "lti_deploy_activate"; } public void doActivate(RunData data, Context context) { String peid = ((JetspeedRunData) data).getJs_peid(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(peid); if (!ltiService.isAdmin()) { addAlert(state, rb.getString("error.admin.activate")); switchPanel(state, "Error"); return; } Properties reqProps = data.getParameters().getProperties(); String id = data.getParameters().getString(LTIService.LTI_ID); if (id == null) { addAlert(state, rb.getString("error.id.not.found")); switchPanel(state, "DeploySystem"); return; } Long key = new Long(id); Map<String, Object> deploy = ltiService.getDeployDao(key); if (deploy == null) { addAlert(state, rb.getString("error.deploy.not.found")); switchPanel(state, "DeploySystem"); return; } List<Map<String, Object>> theTools = new ArrayList<Map<String, Object>>(); Properties info = new Properties(); String prepare = prepareValidate(deploy, theTools, info, state); M_log.info("Starting activation process for id=" + key + " title=" + info.get("title")); int inserts = 0; int updates = 0; String failures = ""; for (Map<String, Object> theTool : theTools) { Object retval = null; Long toolId = foorm.getLongNull(theTool.get(LTIService.LTI_ID)); theTool.put(LTIService.LTI_VERSION, LTIService.LTI_VERSION_2); if (toolId == null) { retval = ltiService.insertTool(theTool); if (retval instanceof String) { String oops = "Unable to insert " + theTool.get(LTIService.LTI_RESOURCE_HANDLER) + " " + retval; M_log.error(oops); failures += "\n" + oops; } else { M_log.info("Inserted tool=" + retval + " " + theTool.get(LTIService.LTI_RESOURCE_HANDLER)); inserts++; } } else { retval = ltiService.updateTool(toolId, theTool); if (retval instanceof String) { String oops = "Unable to update " + theTool.get(LTIService.LTI_RESOURCE_HANDLER) + " " + retval; M_log.error(oops); failures += "\n" + oops; } else { M_log.info("Updated tool=" + toolId + " " + theTool.get(LTIService.LTI_RESOURCE_HANDLER)); updates++; } } } // Update reg_state to indicate we are activated... Map<String, Object> deployUpdate = new HashMap<String, Object>(); deployUpdate.put(LTIService.LTI_REG_STATE, "2"); Object obj = ltiService.updateDeployDao(key, deployUpdate); boolean updated = (obj instanceof Boolean) && ((Boolean) obj == Boolean.TRUE); if (!updated) { String oops = "Unable to update deployment key=" + key; M_log.error(oops); failures += "\n" + oops; } // We can have a combination of successes and failures... String success = ""; if (inserts > 0) success = inserts + " tools inserted "; if (updates > 0) success = updates + " tools updated "; if (success.length() > 0) state.setAttribute(STATE_SUCCESS, success); if (failures.length() > 0) { state.setAttribute(STATE_POST, reqProps); addAlert(state, failures); } switchPanel(state, "DeploySystem"); } public String prepareValidate(Map<String, Object> deploy, List<Map<String, Object>> theTools, Properties info, SessionState state) { Long reg_state = foorm.getLongNull(deploy.get(LTIService.LTI_REG_STATE)); String profileText = (String) deploy.get(LTIService.LTI_REG_PROFILE); if (profileText == null || profileText.length() < 1) { addAlert(state, rb.getString("error.activate.not.ready")); return "lti_error"; } JSONObject providerProfile = (JSONObject) JSONValue.parse(profileText); List<Properties> profileTools = new ArrayList<Properties>(); try { String retval = LTI2Util.parseToolProfile(profileTools, info, providerProfile); if (retval != null) { addAlert(state, rb.getString("deploy.parse.error") + " " + retval); return "lti_error"; } } catch (Exception e) { addAlert(state, rb.getString("deploy.parse.exception") + " " + e.getLocalizedMessage()); e.printStackTrace(); return "lti_error"; } String instance_guid = (String) info.get("instance_guid"); if (profileTools.size() < 1) { addAlert(state, rb.getString("deploy.activate.notools")); return "lti_error"; } // Check them all first for (Properties profileTool : profileTools) { String launch = (String) profileTool.get(LTIService.LTI_LAUNCH); if (!FormattedText.validateURL(launch)) { addAlert(state, rb.getString("deploy.activate.badlaunch") + " " + launch); return "lti_error"; } } // Make a copy of the deploy object and clean it up Map<String, Object> localDeploy = new HashMap<String, Object>(); localDeploy.putAll(deploy); localDeploy.remove(LTIService.LTI_ID); localDeploy.remove(LTIService.LTI_CREATED_AT); localDeploy.remove(LTIService.LTI_UPDATED_AT); localDeploy.remove(LTIService.LTI_REG_PROFILE); // Loop through all of the tools for (Properties profileTool : profileTools) { String resource_type_code = (String) profileTool.get("resource_type_code"); String resource_handler = instance_guid; if (!resource_handler.endsWith("/") && !resource_handler.startsWith("/")) resource_handler = resource_handler + "/"; resource_handler = resource_handler + resource_type_code; Map<String, Object> tool = ltiService.getToolForResourceHandlerDao(resource_handler); // Construct a new tool object Map<String, Object> newTool = new HashMap<String, Object>(); if (tool != null) { newTool.putAll(tool); newTool.putAll(localDeploy); // New settings from the deployment } else { newTool.putAll(localDeploy); } newTool.put(LTIService.LTI_RESOURCE_HANDLER, resource_handler); newTool.put(LTIService.LTI_DEPLOYMENT_ID, deploy.get(LTIService.LTI_ID)); // Copy explicitly in case the parser changes slightly if (profileTool.get(LTIService.LTI_LAUNCH) != null) newTool.put(LTIService.LTI_LAUNCH, profileTool.get(LTIService.LTI_LAUNCH)); if (profileTool.get(LTIService.LTI_TITLE) != null) newTool.put(LTIService.LTI_TITLE, profileTool.get(LTIService.LTI_TITLE)); if (profileTool.get(LTIService.LTI_TITLE) != null) newTool.put(LTIService.LTI_PAGETITLE, profileTool.get(LTIService.LTI_TITLE)); // Duplicate by default if (profileTool.get("button") != null) newTool.put(LTIService.LTI_PAGETITLE, profileTool.get("button")); // Note different fields if (profileTool.get(LTIService.LTI_DESCRIPTION) != null) newTool.put(LTIService.LTI_DESCRIPTION, profileTool.get(LTIService.LTI_DESCRIPTION)); if (profileTool.get(LTIService.LTI_PARAMETER) != null) newTool.put(LTIService.LTI_PARAMETER, profileTool.get(LTIService.LTI_PARAMETER)); if (profileTool.get(LTIService.LTI_ENABLED_CAPABILITY) != null) newTool.put(LTIService.LTI_ENABLED_CAPABILITY, profileTool.get(LTIService.LTI_ENABLED_CAPABILITY)); System.out.println("newTool=" + newTool); theTools.add(newTool); } return null; // Success } public String buildDeploySystemPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); if (!ltiService.isAdmin()) { addAlert(state, rb.getString("error.admin.view")); return "lti_error"; } String contextString = toolManager.getCurrentPlacement().getContext(); context.put("ltiService", ltiService); state.removeAttribute(STATE_POST); context.put("messageSuccess", state.getAttribute(STATE_SUCCESS)); context.put("getContext", contextString); state.removeAttribute(STATE_SUCCESS); List<Map<String, Object>> deploys = ltiService.getDeploysDao(null, null, 0, 5000); context.put("deploys", deploys); // Check if we are configured LTI2Config cnf = new SakaiLTI2Config(); if (cnf.getGuid() == null) { context.put("alertMessage", rb.getString("error.deploy.not.config")); M_log.error("*********************************************"); M_log.error("* LTI2 NOT CONFIGURED - Using Sample Data *"); M_log.error("* Do not use this in production. Test only *"); M_log.error("*********************************************"); } return "lti_deploy_system"; } public String buildDeployDeletePanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); if (!ltiService.isAdmin()) { addAlert(state, rb.getString("error.maintain.delete")); return "lti_error"; } context.put("doAction", BUTTON + "doDeployDelete"); String id = data.getParameters().getString(LTIService.LTI_ID); if (id == null) { addAlert(state, rb.getString("error.id.not.found")); return "lti_deploy_system"; } Long key = new Long(id); // Retrieve the tool using a WHERE clause so the counts get computed List<Map<String, Object>> deploys = ltiService.getDeploysDao("lti_deploy.id = " + key, null, 0, 0); if (deploys == null || deploys.size() < 1) { addAlert(state, rb.getString("error.deploy.not.found")); return "lti_deploy_system"; } Map<String, Object> deploy = deploys.get(0); context.put("deploy", deploy); String[] mappingForm = foorm.filterForm(ltiService.getDeployModel(), "^title:.*|^reg_launch:.*|^id:.*", null); String formOutput = ltiService.formOutput(deploy, mappingForm); context.put("formOutput", formOutput); String deployData = rb.getString("deploy.data"); deployData = deployData.replace(":tools", "" + deploy.get("lti_tool_count")) .replace(":contents", "" + deploy.get("lti_content_count")) .replace(":sites", "" + deploy.get("lti_site_count")); context.put("deployData", deployData); state.removeAttribute(STATE_SUCCESS); return "lti_deploy_delete"; } public void doDeployDelete(RunData data, Context context) { String peid = ((JetspeedRunData) data).getJs_peid(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(peid); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.delete")); switchPanel(state, "Error"); return; } Properties reqProps = data.getParameters().getProperties(); String id = data.getParameters().getString(LTIService.LTI_ID); Object retval = null; if (id == null) { addAlert(state, rb.getString("error.id.not.found")); switchPanel(state, "Deploy"); return; } Long key = new Long(id); // also remove the link if (ltiService.deleteDeployDao(key)) { state.setAttribute(STATE_SUCCESS, rb.getString("success.deleted")); } else { addAlert(state, rb.getString("error.delete.fail")); } switchPanel(state, "DeploySystem"); } /** Content related methods ------------------------------ */ public String buildContentPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.view")); return "lti_error"; } List<Map<String, Object>> contents = ltiService.getContents(null, null, 0, 5000); for (Map<String, Object> content : contents) { String plstr = (String) content.get(LTIService.LTI_PLACEMENT); ToolConfiguration tool = SiteService.findTool(plstr); if (tool == null) { content.put(LTIService.LTI_PLACEMENT, null); } } context.put("contents", contents); context.put("messageSuccess", state.getAttribute(STATE_SUCCESS)); context.put("isAdmin", new Boolean(ltiService.isAdmin())); context.put("getContext", toolManager.getCurrentPlacement().getContext()); state.removeAttribute(STATE_SUCCESS); return "lti_content"; } public String buildContentPutPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { String contextString = toolManager.getCurrentPlacement().getContext(); context.put("tlang", rb); String stateToolId = (String) state.getAttribute(STATE_TOOL_ID); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.edit")); return "lti_error"; } context.put("isAdmin", new Boolean(ltiService.isAdmin())); context.put("doAction", BUTTON + "doContentPut"); state.removeAttribute(STATE_SUCCESS); List<Map<String, Object>> tools = ltiService.getTools(null, null, 0, 0); // only list the tools available in the system List<Map<String, Object>> systemTools = new ArrayList<Map<String, Object>>(); for (Map<String, Object> tool : tools) { String siteId = !tool.containsKey(ltiService.LTI_SITE_ID) ? null : StringUtils.trimToNull((String) tool.get(ltiService.LTI_SITE_ID)); if (siteId == null) { // add tool for whole system systemTools.add(tool); } else if (siteId.equals(contextString)) { // add the tool for current site only systemTools.add(tool); } else if (ltiService.isAdmin()) { // if in Admin's my workspace, show all tools systemTools.add(tool); } } context.put("tools", systemTools); Object previousData = null; String toolId = data.getParameters().getString(LTIService.LTI_TOOL_ID); if (toolId == null) toolId = stateToolId; // output the tool id value to context context.put("tool_id", toolId); Long key = null; if (toolId != null) { try { key = new Long(toolId); } catch (NumberFormatException e) { //Reset toolId and key key = null; toolId = null; } } Map<String, Object> tool = null; if (key != null) { tool = ltiService.getTool(key); if (tool == null) { addAlert(state, rb.getString("error.tool.not.found")); return "lti_content_insert"; } } String contentId = data.getParameters().getString(LTIService.LTI_ID); if (contentId == null) contentId = (String) state.getAttribute(STATE_CONTENT_ID); if (contentId == null) { // Insert if (toolId == null) { return "lti_content_insert"; } previousData = (Properties) state.getAttribute(STATE_POST); // Edit } else { Long contentKey = new Long(contentId); Map<String, Object> content = ltiService.getContent(contentKey); if (content == null) { addAlert(state, rb.getString("error.content.not.found")); state.removeAttribute(STATE_CONTENT_ID); return "lti_content"; } if (key == null) { key = foorm.getLongNull(content.get(LTIService.LTI_TOOL_ID)); if (key != null) tool = ltiService.getTool(key); } previousData = content; // whether the content has a site link created already? String plstr = (String) content.get(LTIService.LTI_PLACEMENT); ToolConfiguration siteLinkTool = SiteService.findTool(plstr); if (siteLinkTool != null) { context.put(LTIService.LTI_PLACEMENT, plstr); } } // We will handle the tool_id field ourselves in the Velocity code String[] contentForm = foorm.filterForm(null, ltiService.getContentModel(key), null, "^tool_id:.*"); if (contentForm == null || key == null) { addAlert(state, rb.getString("error.tool.not.found")); return "lti_error"; } if (previousData == null) { Properties defaultData = new Properties(); defaultData.put("title", tool.get(LTIService.LTI_TITLE)); defaultData.put("pagetitle", tool.get(LTIService.LTI_PAGETITLE)); previousData = defaultData; } String formInput = ltiService.formInput(previousData, contentForm); context.put("formInput", formInput); context.put(LTIService.LTI_TOOL_ID, key); if (tool != null) { context.put("tool_description", tool.get(LTIService.LTI_DESCRIPTION)); Long visible = foorm.getLong(tool.get(LTIService.LTI_VISIBLE)); context.put("tool_visible", visible); } return "lti_content_insert"; } // Insert or edit public void doContentPut(RunData data, Context context) { String peid = ((JetspeedRunData) data).getJs_peid(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(peid); state.removeAttribute(STATE_POST); Properties reqProps = data.getParameters().getProperties(); String id = data.getParameters().getString(LTIService.LTI_ID); String toolId = data.getParameters().getString(LTIService.LTI_TOOL_ID); Object retval = ltiService.insertToolContent(id, toolId, reqProps); Long contentKey = null; Map<String, Object> content = null; if (retval instanceof String) { addAlert(state, (String) retval); switchPanel(state, "Error"); state.setAttribute(STATE_POST, reqProps); state.setAttribute(STATE_CONTENT_ID, id); return; } else if (retval instanceof Boolean) { //If it's true retrieve the previous content? if ((Boolean) retval == true) { content = ltiService.getContent(Long.parseLong(id)); if (content == null) { addAlert(state, rb.getString("error.content.not.found")); switchPanel(state, "Error"); state.setAttribute(STATE_POST, reqProps); state.setAttribute(STATE_CONTENT_ID, id); return; } } else { // TODO: returns false, should it do anyhing else? M_log.error("insertToolContent returned false for" + id); } } else { // the return value is the content key Long value id = ((Long) retval).toString(); contentKey = new Long(id); content = ltiService.getContent(contentKey); if (content == null) { addAlert(state, rb.getString("error.content.not.found")); switchPanel(state, "Error"); state.setAttribute(STATE_POST, reqProps); state.setAttribute(STATE_CONTENT_ID, id); return; } } String returnUrl = reqProps.getProperty("returnUrl"); if (returnUrl != null) { if (id != null) { if (returnUrl.startsWith("about:blank")) { // Redirect to the item if (content != null) { String launch = (String) ltiService.getContentLaunch(content); if (launch != null) returnUrl = launch; } switchPanel(state, "Forward"); } else { if (returnUrl.indexOf("?") > 0) { returnUrl += "<iItemId=/blti/" + retval; } else { returnUrl += "?ltiItemId=/blti/" + retval; } switchPanel(state, "Redirect"); } } state.setAttribute(STATE_REDIRECT_URL, returnUrl); return; } String success = null; if (id == null) { success = rb.getString("success.created"); } else { success = rb.getString("success.updated"); } state.setAttribute(STATE_SUCCESS, success); String title = data.getParameters().getString(LTIService.LTI_PAGETITLE); // Take the title from the content (or tool) definition if (title == null || title.trim().length() < 1) { if (content != null) { title = (String) content.get(ltiService.LTI_PAGETITLE); } } if (reqProps.getProperty("add_site_link") != null) { // this is to add site link: retval = ltiService.insertToolSiteLink(id, title); if (retval instanceof String) { String prefix = ((String) retval).substring(0, 2); addAlert(state, ((String) retval).substring(2)); if ("0-".equals(prefix)) { switchPanel(state, "Refresh"); } else if ("1-".equals(prefix)) { switchPanel(state, "Error"); } return; } else if (retval instanceof Boolean) { if (((Boolean) retval).booleanValue()) { switchPanel(state, "Refresh"); } else { switchPanel(state, "Error"); } return; } state.setAttribute(STATE_SUCCESS, rb.getString("success.link.add")); } switchPanel(state, "ToolSite"); } public String buildRedirectPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); String returnUrl = (String) state.getAttribute(STATE_REDIRECT_URL); state.removeAttribute(STATE_REDIRECT_URL); if (returnUrl == null) return "lti_content_redirect"; // System.out.println("Redirecting parent frame back to="+returnUrl); if (!returnUrl.startsWith("about:blank")) context.put("returnUrl", returnUrl); return "lti_content_redirect"; } public String buildForwardPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); String returnUrl = (String) state.getAttribute(STATE_REDIRECT_URL); state.removeAttribute(STATE_REDIRECT_URL); if (returnUrl == null) return "lti_content_redirect"; // System.out.println("Forwarding frame to="+returnUrl); context.put("forwardUrl", returnUrl); return "lti_content_redirect"; } // Special panel for Lesson Builder // Add New: panel=Config&tool_id=14 // Edit existing: panel=Config&id=12 public String buildContentConfigPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); state.removeAttribute(STATE_SUCCESS); Properties previousPost = (Properties) state.getAttribute(STATE_POST); state.removeAttribute(STATE_POST); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.edit")); return "lti_error"; } String returnUrl = data.getParameters().getString("returnUrl"); if (returnUrl == null && previousPost != null) returnUrl = previousPost.getProperty("returnUrl"); if (returnUrl == null) { addAlert(state, rb.getString("error.missing.return")); return "lti_error"; } Map<String, Object> content = null; Map<String, Object> tool = null; Long toolKey = foorm.getLongNull(data.getParameters().getString(LTIService.LTI_TOOL_ID)); Long contentKey = foorm.getLongNull(data.getParameters().getString(LTIService.LTI_ID)); if (contentKey == null && previousPost != null) contentKey = foorm.getLongNull(previousPost.getProperty(LTIService.LTI_ID)); if (contentKey != null) { content = ltiService.getContent(contentKey); if (content == null) { addAlert(state, rb.getString("error.content.not.found")); state.removeAttribute(STATE_CONTENT_ID); return "lti_error"; } toolKey = foorm.getLongNull(content.get(LTIService.LTI_TOOL_ID)); } if (toolKey == null && previousPost != null) toolKey = foorm.getLongNull(previousPost.getProperty(LTIService.LTI_TOOL_ID)); if (toolKey != null) tool = ltiService.getTool(toolKey); // No matter what, we must have a tool if (tool == null) { addAlert(state, rb.getString("error.tool.not.found")); return "lti_error"; } Object previousData = null; if (content != null) { previousData = content; } else { previousData = (Properties) state.getAttribute(STATE_POST); } // We will handle the tool_id field ourselves in the Velocity code String[] contentForm = foorm.filterForm(null, ltiService.getContentModel(toolKey), null, "^tool_id:.*|^SITE_ID:.*"); if (contentForm == null) { addAlert(state, rb.getString("error.tool.not.found")); return "lti_error"; } context.put("isAdmin", new Boolean(ltiService.isAdmin())); context.put("doAction", BUTTON + "doContentPut"); if (!returnUrl.startsWith("about:blank")) context.put("cancelUrl", returnUrl); context.put("returnUrl", returnUrl); context.put(LTIService.LTI_TOOL_ID, toolKey); context.put("tool_description", tool.get(LTIService.LTI_DESCRIPTION)); context.put("tool_title", tool.get(LTIService.LTI_TITLE)); context.put("tool_launch", tool.get(LTIService.LTI_LAUNCH)); String key = (String) tool.get(LTIService.LTI_CONSUMERKEY); String secret = (String) tool.get(LTIService.LTI_SECRET); if (LTIService.LTI_SECRET_INCOMPLETE.equals(secret) && LTIService.LTI_SECRET_INCOMPLETE.equals(key)) { String keyField = foorm.formInput(null, "consumerkey:text:label=need.tool.key:required=true:maxlength=255", rb); context.put("keyField", keyField); String secretField = foorm.formInput(null, "secret:text:required=true:label=need.tool.secret:maxlength=255", rb); context.put("secretField", secretField); } String formInput = ltiService.formInput(previousData, contentForm); context.put("formInput", formInput); return "lti_content_config"; } public String buildContentDeletePanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.delete")); return "lti_error"; } context.put("doAction", BUTTON + "doContentDelete"); String id = data.getParameters().getString(LTIService.LTI_ID); if (id == null) { addAlert(state, rb.getString("error.id.not.found")); return "lti_deploy_system"; } Long key = new Long(id); Map<String, Object> content = ltiService.getContent(key); if (content == null) { addAlert(state, rb.getString("error.content.not.found")); return "lti_deploy_system"; } Long tool_id_long = null; try { tool_id_long = new Long(content.get(LTIService.LTI_TOOL_ID).toString()); } catch (Exception e) { // log the error M_log.error("error parsing tool id " + content.get(LTIService.LTI_TOOL_ID)); } context.put("tool_id_long", tool_id_long); context.put("content", content); context.put("ltiService", ltiService); state.removeAttribute(STATE_SUCCESS); return "lti_content_delete"; } // Insert or edit public void doContentDelete(RunData data, Context context) { String peid = ((JetspeedRunData) data).getJs_peid(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(peid); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.delete")); switchPanel(state, "Error"); return; } Properties reqProps = data.getParameters().getProperties(); String id = data.getParameters().getString(LTIService.LTI_ID); Object retval = null; if (id == null) { addAlert(state, rb.getString("error.id.not.found")); switchPanel(state, "DeploySystem"); return; } Long key = new Long(id); // also remove the link if (ltiService.deleteContent(key)) { state.setAttribute(STATE_SUCCESS, rb.getString("success.deleted")); } else { addAlert(state, rb.getString("error.delete.fail")); } switchPanel(state, "Refresh"); } public String buildLinkAddPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.link")); return "lti_error"; } context.put("doAction", BUTTON + "doSiteLink"); String id = data.getParameters().getString(LTIService.LTI_ID); if (id == null) { addAlert(state, rb.getString("error.id.not.found")); return "lti_deploy_system"; } Long key = new Long(id); Map<String, Object> content = ltiService.getContent(key); if (content == null) { addAlert(state, rb.getString("error.content.not.found")); return "lti_deploy_system"; } context.put("content", content); state.removeAttribute(STATE_SUCCESS); return "lti_link_add"; } // Insert or edit public void doSiteLink(RunData data, Context context) { String peid = ((JetspeedRunData) data).getJs_peid(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(peid); String id = data.getParameters().getString(LTIService.LTI_ID); String button_text = data.getParameters().getString("button_text"); Object retval = ltiService.insertToolSiteLink(id, button_text); if (retval instanceof String) { String prefix = ((String) retval).substring(0, 2); addAlert(state, ((String) retval).substring(2)); if ("0-".equals(prefix)) { switchPanel(state, "Content"); } else if ("1-".equals(prefix)) { switchPanel(state, "Error"); } return; } state.setAttribute(STATE_SUCCESS, rb.getString("success.link.add")); switchPanel(state, "Refresh"); } public String buildLinkRemovePanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); if (!ltiService.isMaintain()) { addAlert(state, rb.getString("error.maintain.link")); return "lti_error"; } context.put("doAction", BUTTON + "doLinkRemove"); String id = data.getParameters().getString(LTIService.LTI_ID); if (id == null) { addAlert(state, rb.getString("error.id.not.found")); return "lti_main"; } Long key = new Long(id); Map<String, Object> content = ltiService.getContent(key); if (content == null) { addAlert(state, rb.getString("error.content.not.found")); return "lti_main"; } context.put("content", content); state.removeAttribute(STATE_SUCCESS); return "lti_link_remove"; } public void doLinkRemove(RunData data, Context context) { String peid = ((JetspeedRunData) data).getJs_peid(); SessionState state = ((JetspeedRunData) data).getPortletSessionState(peid); String id = data.getParameters().getString(LTIService.LTI_ID); Long key = id == null ? null : new Long(id); String rv = ltiService.deleteContentLink(key); if (rv != null) { // there is error removing the external tool site link addAlert(state, rv); switchPanel(state, "Error"); return; } else { // external tool site link removed successfully state.setAttribute(STATE_SUCCESS, rb.getString("success.link.remove")); switchPanel(state, "Refresh"); } } public String buildRefreshPanelContext(VelocityPortlet portlet, Context context, RunData data, SessionState state) { context.put("tlang", rb); context.put("messageSuccess", state.getAttribute(STATE_SUCCESS)); state.removeAttribute(STATE_SUCCESS); return "lti_top_refresh"; } }