Index: lams_build/lib/lams/lams-central.jar =================================================================== diff -u -rb128694883b5db515c3f98f6803b573e04d203d2 -rf3de7ac12162d8c33e8de55c3ca868b05600b7d4 Binary files differ Index: lams_central/conf/xdoclet/servlet-mappings.xml =================================================================== diff -u -rac293c56d01d08018c14f01dfa851a772dfde23a -rf3de7ac12162d8c33e8de55c3ca868b05600b7d4 --- lams_central/conf/xdoclet/servlet-mappings.xml (.../servlet-mappings.xml) (revision ac293c56d01d08018c14f01dfa851a772dfde23a) +++ lams_central/conf/xdoclet/servlet-mappings.xml (.../servlet-mappings.xml) (revision f3de7ac12162d8c33e8de55c3ca868b05600b7d4) @@ -53,4 +53,14 @@ CourseGroupManager /services/CourseGroupManager + + + + LearningDesignRestServlet + /rest/LearningDesign + + + + ToolContentRestServlet + /rest/ToolContent \ No newline at end of file Index: lams_central/conf/xdoclet/servlets.xml =================================================================== diff -u -rac293c56d01d08018c14f01dfa851a772dfde23a -rf3de7ac12162d8c33e8de55c3ca868b05600b7d4 --- lams_central/conf/xdoclet/servlets.xml (.../servlets.xml) (revision ac293c56d01d08018c14f01dfa851a772dfde23a) +++ lams_central/conf/xdoclet/servlets.xml (.../servlets.xml) (revision f3de7ac12162d8c33e8de55c3ca868b05600b7d4) @@ -99,4 +99,18 @@ org.lamsfoundation.lams.web.OrganisationGroupServlet + + + + LearningDesignRestServlet + + org.lamsfoundation.lams.rest.LearningDesignRestServlet + + + + + ToolContentRestServlet + + org.lamsfoundation.lams.rest.ToolContentRestServlet + \ No newline at end of file Index: lams_central/conf/xdoclet/web-security.xml =================================================================== diff -u -rea63f6db0d83cdc29f998531cfad896c5e650a71 -rf3de7ac12162d8c33e8de55c3ca868b05600b7d4 --- lams_central/conf/xdoclet/web-security.xml (.../web-security.xml) (revision ea63f6db0d83cdc29f998531cfad896c5e650a71) +++ lams_central/conf/xdoclet/web-security.xml (.../web-security.xml) (revision f3de7ac12162d8c33e8de55c3ca868b05600b7d4) @@ -31,7 +31,9 @@ /services/Register/* /ForgotPasswordRequest /signup/* - + + /rest/* + /css/* /errorpages/* Index: lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java =================================================================== diff -u -r668918e9507fd75ee906f01eed8a4ca5d43522b4 -rf3de7ac12162d8c33e8de55c3ca868b05600b7d4 --- lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java (.../ObjectExtractor.java) (revision 668918e9507fd75ee906f01eed8a4ca5d43522b4) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java (.../ObjectExtractor.java) (revision f3de7ac12162d8c33e8de55c3ca868b05600b7d4) @@ -1470,6 +1470,9 @@ } private void parseAnnotations(JSONArray annotationList) throws ObjectExtractorException, JSONException { + if (annotationList == null) { + return; + } Set existingAnnotations = learningDesign.getAnnotations(); if (existingAnnotations == null) { @@ -1811,7 +1814,7 @@ activity.setLibraryActivityUiImage((String) JsonUtil.opt(activityDetails, AuthoringJsonTags.LIBRARY_IMAGE)); activity.setGroupingSupportType((Integer) JsonUtil .opt(activityDetails, AuthoringJsonTags.GROUPING_SUPPORT_TYPE)); - activity.setStopAfterActivity((Boolean) JsonUtil.opt(activityDetails, AuthoringJsonTags.STOP_AFTER_ACTIVITY)); + activity.setStopAfterActivity((Boolean) JsonUtil.opt(activityDetails, AuthoringJsonTags.STOP_AFTER_ACTIVITY, false)); return activity; } @@ -2733,7 +2736,7 @@ } group.getBranchActivities().add(entry); } - + entry.setCondition(condition); if (branchingActivity.isConditionGate()) { @@ -2884,7 +2887,7 @@ } group.getBranchActivities().add(entry); } - + entry.setCondition(condition); if (branchingActivity.isConditionGate()) { Index: lams_central/src/java/org/lamsfoundation/lams/rest/LearningDesignRestServlet.java =================================================================== diff -u --- lams_central/src/java/org/lamsfoundation/lams/rest/LearningDesignRestServlet.java (revision 0) +++ lams_central/src/java/org/lamsfoundation/lams/rest/LearningDesignRestServlet.java (revision f3de7ac12162d8c33e8de55c3ca868b05600b7d4) @@ -0,0 +1,48 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.rest; + +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; +import org.apache.tomcat.util.json.JSONObject; +import org.lamsfoundation.lams.learningdesign.LearningDesign; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; + +public class LearningDesignRestServlet extends RestServlet { + private static final Logger log = Logger.getLogger(LearningDesignRestServlet.class); + + @Override + protected void doPostInternal(JSONObject requestJSON, UserDTO userDTO, HttpServletResponse response) + throws Exception { + JSONObject learningDesignJSON = requestJSON.getJSONObject("ld"); + LearningDesign learningDesign = getAuthoringService().saveLearningDesignDetails(learningDesignJSON); + + JSONObject JSONObject = new JSONObject(); + JSONObject.put("learningDesignID", learningDesign.getLearningDesignId()); + JSONObject.put("title", learningDesign.getTitle()); + response.setContentType("application/json;charset=utf-8"); + response.getWriter().print(JSONObject); + } +} \ No newline at end of file Index: lams_central/src/java/org/lamsfoundation/lams/rest/RestServlet.java =================================================================== diff -u --- lams_central/src/java/org/lamsfoundation/lams/rest/RestServlet.java (revision 0) +++ lams_central/src/java/org/lamsfoundation/lams/rest/RestServlet.java (revision f3de7ac12162d8c33e8de55c3ca868b05600b7d4) @@ -0,0 +1,203 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.rest; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.apache.tomcat.util.json.JSONException; +import org.apache.tomcat.util.json.JSONObject; +import org.lamsfoundation.lams.authoring.service.IAuthoringService; +import org.lamsfoundation.lams.integration.ExtServerOrgMap; +import org.lamsfoundation.lams.integration.ExtUserUseridMap; +import org.lamsfoundation.lams.integration.UserInfoFetchException; +import org.lamsfoundation.lams.integration.UserInfoValidationException; +import org.lamsfoundation.lams.integration.security.AuthenticationException; +import org.lamsfoundation.lams.integration.security.Authenticator; +import org.lamsfoundation.lams.integration.service.IIntegrationService; +import org.lamsfoundation.lams.integration.service.IntegrationService; +import org.lamsfoundation.lams.integration.util.LoginRequestDispatcher; +import org.lamsfoundation.lams.tool.dao.IToolDAO; +import org.lamsfoundation.lams.tool.service.ILamsCoreToolService; +import org.lamsfoundation.lams.usermanagement.User; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +/** + * Base class for LAMS REST servlets. + * + * @author Marcin Cieslak + */ +public abstract class RestServlet extends HttpServlet { + + private static final Logger log = Logger.getLogger(RestServlet.class); + + private static IToolDAO toolDAO; + private static ILamsCoreToolService lamsCoreToolService; + private static IIntegrationService integrationService; + private static IAuthoringService authoringService; + private static IUserManagementService userManagementService; + + /** + * Checks if the provided auth JSON is valid. + */ + private UserDTO authenticate(JSONObject authenticationJSON) { + User user = null; + try { + String serverName = authenticationJSON.getString(LoginRequestDispatcher.PARAM_SERVER_ID); + ExtServerOrgMap serverMap = getIntegrationService().getExtServerOrgMap(serverName); + String userName = authenticationJSON.getString(LoginRequestDispatcher.PARAM_USER_ID); + String method = authenticationJSON.getString(LoginRequestDispatcher.PARAM_METHOD).toLowerCase(); + String timestamp = authenticationJSON.getString(LoginRequestDispatcher.PARAM_TIMESTAMP); + String hash = authenticationJSON.getString(LoginRequestDispatcher.PARAM_HASH); + + // Throws AuthenticationException if it fails + Authenticator.authenticateLoginRequest(serverMap, timestamp, userName, method, null, hash); + + ExtUserUseridMap userMap = getIntegrationService().getExtUserUseridMap(serverMap, userName); + user = userMap.getUser(); + // get concrete user + user = (User) getUserManagementService().findById(User.class, user.getUserId()); + return user.getUserDTO(); + } catch (JSONException e) { + RestServlet.log.error("Error while reading authentication JSON", e); + } catch (AuthenticationException e) { + RestServlet.log.error("The user was not authenticated", e); + } catch (UserInfoFetchException e) { + RestServlet.log.error("Could not fetch new user information from integration server", e); + } catch (UserInfoValidationException e) { + RestServlet.log.error("User data is not valid", e); + } + + return null; + } + + private IIntegrationService getIntegrationService() { + if (RestServlet.integrationService == null) { + RestServlet.integrationService = (IntegrationService) WebApplicationContextUtils + .getRequiredWebApplicationContext(getServletContext()).getBean("integrationService"); + } + return RestServlet.integrationService; + } + + @Override + protected final void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, + IOException { + String requestBody = IOUtils.toString(request.getInputStream(), "UTF-8"); + JSONObject requestJSON = null; + JSONObject authenticationJSON = null; + try { + requestJSON = new JSONObject(requestBody); + authenticationJSON = requestJSON.getJSONObject("auth"); + } catch (JSONException e) { + throw new IOException("Error while parsing REST request JSON", e); + } + + UserDTO userDTO = authenticate(authenticationJSON); + if (userDTO == null) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, "The user is not authenticated"); + return; + } + // do not pass authentication info to concrete REST servlets + requestJSON.remove("auth"); + + // Some LAMS code, like creating a Learning Design object, requires UserDTO in the shared session. + // User may be not authenticated at all, so we need to create a new session. + // Or the authentication JSON specified a different user than the one that is currently authenticated in LAMS, + // so we need to swap it in the session. + UserDTO existingUserDTO = null; + HttpSession session = SessionManager.getSession(); + boolean createNewSession = session == null; + if (createNewSession) { + // if there is no session, start it manually + SessionManager.startSession(request, response); + } else { + existingUserDTO = (UserDTO) session.getAttribute(AttributeNames.USER); + } + session = SessionManager.getSession(); + session.setAttribute(AttributeNames.USER, userDTO); + + try { + doPostInternal(requestJSON, userDTO, response); + } catch (Exception e) { + throw new ServletException("Error while processing REST request", e); + } finally { + if (createNewSession) { + SessionManager.endSession(); + } else { + session.setAttribute(AttributeNames.USER, existingUserDTO); + } + } + } + + protected abstract void doPostInternal(JSONObject requestJSON, UserDTO userDTO, HttpServletResponse response) + throws Exception; + + protected final IAuthoringService getAuthoringService() { + if (RestServlet.authoringService == null) { + WebApplicationContext ctx = WebApplicationContextUtils + .getRequiredWebApplicationContext(getServletContext()); + RestServlet.authoringService = (IAuthoringService) ctx.getBean("authoringService"); + } + return RestServlet.authoringService; + } + + protected ILamsCoreToolService getLamsCoreToolService() { + if (RestServlet.lamsCoreToolService == null) { + WebApplicationContext ctx = WebApplicationContextUtils + .getRequiredWebApplicationContext(getServletContext()); + RestServlet.lamsCoreToolService = (ILamsCoreToolService) ctx.getBean("lamsCoreToolService"); + } + return RestServlet.lamsCoreToolService; + } + + protected IToolDAO getToolDAO() { + if (RestServlet.toolDAO == null) { + WebApplicationContext ctx = WebApplicationContextUtils + .getRequiredWebApplicationContext(getServletContext()); + RestServlet.toolDAO = (IToolDAO) ctx.getBean("toolDAO"); + } + return RestServlet.toolDAO; + } + + protected final IUserManagementService getUserManagementService() { + if (RestServlet.userManagementService == null) { + WebApplicationContext ctx = WebApplicationContextUtils + .getRequiredWebApplicationContext(getServletContext()); + RestServlet.userManagementService = (IUserManagementService) ctx.getBean("userManagementService"); + } + return RestServlet.userManagementService; + } +} \ No newline at end of file Index: lams_central/src/java/org/lamsfoundation/lams/rest/ToolContentRestServlet.java =================================================================== diff -u --- lams_central/src/java/org/lamsfoundation/lams/rest/ToolContentRestServlet.java (revision 0) +++ lams_central/src/java/org/lamsfoundation/lams/rest/ToolContentRestServlet.java (revision f3de7ac12162d8c33e8de55c3ca868b05600b7d4) @@ -0,0 +1,52 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.rest; + +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; +import org.apache.tomcat.util.json.JSONObject; +import org.lamsfoundation.lams.tool.Tool; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; + +public class ToolContentRestServlet extends RestServlet { + private static final Logger log = Logger.getLogger(ToolContentRestServlet.class); + + @Override + protected void doPostInternal(JSONObject requestJSON, UserDTO userDTO, HttpServletResponse response) + throws Exception { + // find out which Tool to create + String toolSignature = requestJSON.getString("toolSignature"); + Tool tool = getToolDAO().getToolBySignature(toolSignature); + Long toolContentID = getAuthoringService().insertToolContentID(tool.getToolId()); + + JSONObject toolContentJSON = requestJSON.getJSONObject("toolContent"); + // Tools' services implement an interface for processing REST requests + ToolRestManager toolRestService = (ToolRestManager) getLamsCoreToolService().findToolService(tool); + toolRestService.createRestToolContent(userDTO.getUserID(), toolContentID, toolContentJSON); + + response.setContentType("application/json;charset=utf-8"); + response.getWriter().print("{\"toolContentID\":" + toolContentID + "}"); + } +} \ No newline at end of file Index: lams_central/src/java/org/lamsfoundation/lams/rest/ToolRestManager.java =================================================================== diff -u --- lams_central/src/java/org/lamsfoundation/lams/rest/ToolRestManager.java (revision 0) +++ lams_central/src/java/org/lamsfoundation/lams/rest/ToolRestManager.java (revision f3de7ac12162d8c33e8de55c3ca868b05600b7d4) @@ -0,0 +1,31 @@ +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2.0 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +/* $Id$ */ +package org.lamsfoundation.lams.rest; + +import org.apache.tomcat.util.json.JSONException; +import org.apache.tomcat.util.json.JSONObject; + +public interface ToolRestManager { + void createRestToolContent(Integer userID, Long toolContentID, JSONObject toolContentJSON) throws JSONException; +} \ No newline at end of file Index: lams_central/web/css/defaultHTML.css =================================================================== diff -u -re0e39f7cf5291dd75dde343c82eb9ff07a049aec -rf3de7ac12162d8c33e8de55c3ca868b05600b7d4 --- lams_central/web/css/defaultHTML.css (.../defaultHTML.css) (revision e0e39f7cf5291dd75dde343c82eb9ff07a049aec) +++ lams_central/web/css/defaultHTML.css (.../defaultHTML.css) (revision f3de7ac12162d8c33e8de55c3ca868b05600b7d4) @@ -843,6 +843,10 @@ border: 1px solid #E82A28; } +input.error{ + color: #cc0000; + border: 1px solid #E82A28; +} b.error { color: #cc0000; } Index: lams_central/web/css/defaultHTML_rtl.css =================================================================== diff -u -r0b85d3d42a2ec95d010ecdf98807043a3522f654 -rf3de7ac12162d8c33e8de55c3ca868b05600b7d4 --- lams_central/web/css/defaultHTML_rtl.css (.../defaultHTML_rtl.css) (revision 0b85d3d42a2ec95d010ecdf98807043a3522f654) +++ lams_central/web/css/defaultHTML_rtl.css (.../defaultHTML_rtl.css) (revision f3de7ac12162d8c33e8de55c3ca868b05600b7d4) @@ -861,6 +861,11 @@ border: 1px solid #E82A28; } +input.error{ + color: #cc0000; + border: 1px solid #E82A28; +} + b.error {color:#cc0000;} /* ***********************************************