Index: lams_bb_integration/src/org/lamsfoundation/ld/integration/blackboard/GradebookServlet.java =================================================================== diff -u -refced1f751a9f688a5f99a75cf6592120260428e -r780957f27df870898ade718ccdacd93d5dfadbd7 --- lams_bb_integration/src/org/lamsfoundation/ld/integration/blackboard/GradebookServlet.java (.../GradebookServlet.java) (revision efced1f751a9f688a5f99a75cf6592120260428e) +++ lams_bb_integration/src/org/lamsfoundation/ld/integration/blackboard/GradebookServlet.java (.../GradebookServlet.java) (revision 780957f27df870898ade718ccdacd93d5dfadbd7) @@ -68,6 +68,7 @@ import blackboard.persist.course.CourseDbLoader; import blackboard.persist.course.CourseMembershipDbLoader; import blackboard.persist.gradebook.LineitemDbLoader; +import blackboard.persist.gradebook.LineitemDbPersister; import blackboard.persist.gradebook.ScoreDbLoader; import blackboard.persist.gradebook.ScoreDbPersister; import blackboard.persist.user.UserDbLoader; @@ -103,10 +104,10 @@ String userName = request.getParameter(Constants.PARAM_USER_ID); String timeStamp = request.getParameter(Constants.PARAM_TIMESTAMP); String hash = request.getParameter(Constants.PARAM_HASH); - String lessonId = request.getParameter(Constants.PARAM_LESSON_ID); + String lamsLessonIdParam = request.getParameter(Constants.PARAM_LESSON_ID); // check parameters - if (userName == null || timeStamp == null || hash == null || lessonId == null) { + if (userName == null || timeStamp == null || hash == null || lamsLessonIdParam == null) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "missing expected parameters"); return; } @@ -121,32 +122,32 @@ } //check if isGradebookcenter - PortalExtraInfo pei = PortalUtil.loadPortalExtraInfo(null, null, "LamsStorage"); - ExtraInfo ei = pei.getExtraInfo(); - Set internalLessonIds = ei.getKeys(); - String internalLessonId = null; - for (String internalLessonIdIter : internalLessonIds) { - String externalLessonId = ei.getValue(internalLessonIdIter); - if (lessonId.equals(externalLessonId)) { - internalLessonId = internalLessonIdIter; + PortalExtraInfo portalExtraInfo = PortalUtil.loadPortalExtraInfo(null, null, "LamsStorage"); + ExtraInfo extraInfo = portalExtraInfo.getExtraInfo(); + Set bbContentIds = extraInfo.getKeys(); + String bbContentId = null; + for (String bbContentIdIter : bbContentIds) { + String lamsLessonId = extraInfo.getValue(bbContentIdIter); + if (lamsLessonIdParam.equals(lamsLessonId)) { + bbContentId = bbContentIdIter; break; } } // exit method as it was created in version prior to 1.2.1 and thus don't have lineitem - if (internalLessonId == null) { + if (bbContentId == null) { return; } - // check if we need to store mark in Gradebook + //check isGradecenter option is ON BbPersistenceManager bbPm = BbServiceManager.getPersistenceService().getDbPersistenceManager(); Container bbContainer = bbPm.getContainer(); - Id contentId = new PkId( bbContainer, CourseDocument.DATA_TYPE, internalLessonId ); - ContentDbLoader courseDocumentLoader = (ContentDbLoader) bbPm.getLoader( ContentDbLoader.TYPE ); - Content modifiedLesson = (Content)courseDocumentLoader.loadById( contentId ); - if (!modifiedLesson.getIsDescribed()) { - //isDescribed field is used for storing isGradecenter parameter and thus if it's false it means don't store mark to Gradecenter - return; + Id contentId = new PkId( bbContainer, CourseDocument.DATA_TYPE, bbContentId ); + ContentDbLoader contentDbLoader = (ContentDbLoader) bbPm.getLoader( ContentDbLoader.TYPE ); + Content bbContent = (Content)contentDbLoader.loadById( contentId ); + //check isGradecenter option is ON + if (!bbContent.getIsDescribed()) {//(isDescribed field is used for storing isGradecenter parameter) + return; } // get user list, but no role info since there are no course info @@ -162,7 +163,7 @@ Document document = null; String serviceURL = serverAddr + "/services/xml/LessonManager?" + LamsSecurityUtil.generateAuthenticateParameters(ctx) + "&courseId=" - + "&method=toolOutputsUser&lsId=" + lessonId + "&outputsUser=" + + "&method=toolOutputsUser&lsId=" + lamsLessonIdParam + "&outputsUser=" + URLEncoder.encode(userName, "UTF8"); URL url = new URL(serviceURL); @@ -214,27 +215,39 @@ } } - - - CourseDbLoader cLoader = CourseDbLoader.Default.getInstance(); - LineitemDbLoader lineitemLoader = LineitemDbLoader.Default.getInstance(); - - List userCourses = cLoader.loadByUserId(ctx.getUserId()); - - // search for appropriate lineitem + + //get lineitemid from the storage (bbContentId -> lineitemid) + PortalExtraInfo pei = PortalUtil.loadPortalExtraInfo(null, null, "LamsLineitemStorage"); + ExtraInfo ei = pei.getExtraInfo(); + String lineitemIdStr = ei.getValue(bbContentId); + + //TODO remove the following paragraph after a while. (It deals with lineitems created in versions after 1.2 and before 1.2.3) Lineitem lineitem = null; - for (Course userCourse : userCourses) { - List lineitems = lineitemLoader.loadByCourseId(userCourse.getId()); + if (lineitemIdStr == null) { + CourseDbLoader cLoader = CourseDbLoader.Default.getInstance(); + LineitemDbLoader lineitemLoader = LineitemDbLoader.Default.getInstance(); + + List userCourses = cLoader.loadByUserId(ctx.getUserId()); + + // search for appropriate lineitem + lineitem = null; + for (Course userCourse : userCourses) { + List lineitems = lineitemLoader.loadByCourseId(userCourse.getId()); + + for (Lineitem lineitemIter : lineitems) { + if (lineitemIter.getAssessmentId() != null && lineitemIter.getAssessmentId().equals(lamsLessonIdParam)) { + lineitem = lineitemIter; + break; + } + } + } + } else { + + Id lineitemId = bbPm.generateId(Lineitem.LINEITEM_DATA_TYPE, lineitemIdStr.trim()); + LineitemDbLoader lineitemLoader = (LineitemDbLoader) bbPm.getLoader(LineitemDbLoader.TYPE); + lineitem = lineitemLoader.loadById(lineitemId); + } - for (Lineitem lineitemIter : lineitems) { - if (lineitemIter.getAssessmentId() != null && lineitemIter.getAssessmentId().equals(lessonId)) { - lineitem = lineitemIter; - break; - } - } - - } - if (lineitem == null) { throw new ServletException("lineitem not found"); } @@ -262,7 +275,6 @@ current_score.setGrade(new DecimalFormat("##.##").format(gradebookMark)); current_score.validate(); scorePersister.persist(current_score); - } catch (MalformedURLException e) { errorMsg = "Unable to get LAMS learning designs, bad URL: " + ", please check lams.properties"; Index: lams_bb_integration/src/org/lamsfoundation/ld/integration/blackboard/LamsSecurityUtil.java =================================================================== diff -u -rd1bd46656c685991413555e26f4efe3a9c4db39f -r780957f27df870898ade718ccdacd93d5dfadbd7 --- lams_bb_integration/src/org/lamsfoundation/ld/integration/blackboard/LamsSecurityUtil.java (.../LamsSecurityUtil.java) (revision d1bd46656c685991413555e26f4efe3a9c4db39f) +++ lams_bb_integration/src/org/lamsfoundation/ld/integration/blackboard/LamsSecurityUtil.java (.../LamsSecurityUtil.java) (revision 780957f27df870898ade718ccdacd93d5dfadbd7) @@ -57,7 +57,7 @@ */ public class LamsSecurityUtil { - static Logger logger = Logger.getLogger(LamsSecurityUtil.class); + private static Logger logger = Logger.getLogger(LamsSecurityUtil.class); /** * Generates login requests to LAMS for author, monitor and learner @@ -70,14 +70,6 @@ * @throws Exception */ public static String generateRequestURL(Context ctx, String method) throws Exception { -// Course c = CourseDbLoader.Default.getInstance().loadByCourseId("aa"); -// Id cID = c.getId(); -// -// OutcomeDefinition def = new OutcomeDefinition(); -// Id sID = OutcomeDefinitionScaleDbLoader.Default.getInstance().loadByCourseIdAndTitle(cID, OutcomeDefinitionScale.COMPLETE_INCOMPLETE).getId(); -// def.setScaleId(sID); -// //def.setScorable(false); -// OutcomeDefinitionDbPersister.Default.getInstance().persist(def); String serverAddr = getServerAddress(); String serverId = getServerID(); @@ -163,44 +155,7 @@ return url; } - - /** - * Checks whether lesson has scorable outputs (i.e. MCQ or Assessment activity). - * - * @param ctx - * the blackboard contect, contains session data - * @return a url pointing to the LAMS lesson, monitor, author session - * @throws Exception - */ - public static boolean hasLessonScoreOutputs(Context ctx) throws Exception { - String ldId = ctx.getRequestParameter("sequence_id").trim(); - String learningDesignSvgUrl = generateRequestLearningDesignImage(ctx, true) + "&ldId=" + ldId; - URL url = new URL(learningDesignSvgUrl); - URLConnection conn = url.openConnection(); - if (!(conn instanceof HttpURLConnection)) { - logger.error("Unable to open connection to: " + learningDesignSvgUrl); - } - - HttpURLConnection httpConn = (HttpURLConnection) conn; - - if (httpConn.getResponseCode() != HttpURLConnection.HTTP_OK) { - String errorMsg = "HTTP Response Code: " + httpConn.getResponseCode() + ", HTTP Response Message: " - + httpConn.getResponseMessage(); - logger.error(errorMsg); - throw new RuntimeException(errorMsg); - } - - // InputStream is = url.openConnection().getInputStream(); - InputStream is = conn.getInputStream(); - - // parse xml response - String learningDesignSvg = IOUtils.toString(is, "UTF-8"); - boolean hasLessonScoreOutputs = (learningDesignSvg.indexOf("icon_mcq.png") != -1) || (learningDesignSvg.indexOf("icon_assessment.png") != -1); - - return hasLessonScoreOutputs; - } - /** * Gets a list of learning designs for the current user from LAMS * @@ -209,16 +164,15 @@ * @param mode * the mode to call upon learning designes * @return a string containing the LAMS workspace tree in tigra format - * @throws Exception */ - public static String getLearningDesigns(Context ctx, Integer mode) throws Exception { + public static String getLearningDesigns(Context ctx, Integer mode) { String serverAddr = getServerAddress(); String serverId = getServerID(); String serverKey = getServerKey(); // If lams.properties could not be read, throw exception if (serverAddr == null || serverId == null || serverKey == null) { - throw new Exception("Configuration Exception " + serverAddr + ", " + serverId); + throw new RuntimeException("lams.properties file could not be read. serverAddr:" + serverAddr + ", serverId:" + serverId); } String timestamp = new Long(System.currentTimeMillis()).toString(); @@ -273,41 +227,27 @@ //String replacement = "'javascript:selectSequence($1)'"; //learningDesigns = learningDesigns.replaceAll(pattern, replacement); - // TODO better error handling } catch (MalformedURLException e) { - logger.error("Unable to get LAMS learning designs, bad URL: '" + serverAddr + throw new RuntimeException("Unable to get LAMS learning designs, bad URL: '" + serverAddr + "', please check lams.properties", e); - e.printStackTrace(); - return "error"; } catch (IllegalStateException e) { - logger.error( + throw new RuntimeException( "LAMS Server timeout, did not get a response from the LAMS server. Please contact your systems administrator", e); - e.printStackTrace(); - return "error"; } catch (ConnectException e) { - logger.error( + throw new RuntimeException( "LAMS Server timeout, did not get a response from the LAMS server. Please contact your systems administrator", e); - e.printStackTrace(); - return "error"; } catch (UnsupportedEncodingException e) { - logger.error(e); - e.printStackTrace(); - return "error"; + throw new RuntimeException(e); } catch (IOException e) { - logger.error(e); - e.printStackTrace(); - return "error"; + throw new RuntimeException(e); } catch (ParserConfigurationException e) { - logger.error(e); - e.printStackTrace(); - return "error"; + throw new RuntimeException(e); } catch (SAXException e) { - logger.error(e); - e.printStackTrace(); - return "error"; + throw new RuntimeException(e); } + return learningDesigns; } @@ -338,8 +278,7 @@ String method = (isPreview) ? "preview" : "start"; if (serverId == null || serverAddr == null || serverKey == null) { - logger.error("Unable to retrieve learning designs from LAMS, one or more lams configuration properties is null"); - return null; + throw new RuntimeException("Unable to start lesson, one or more lams configuration properties is null"); } try { @@ -362,15 +301,14 @@ URL url = new URL(serviceURL); URLConnection conn = url.openConnection(); if (!(conn instanceof HttpURLConnection)) { - logger.error("Unable to open connection to: " + serviceURL); + throw new RuntimeException("Unable to open connection to: " + serviceURL); } HttpURLConnection httpConn = (HttpURLConnection) conn; if (httpConn.getResponseCode() != HttpURLConnection.HTTP_OK) { - logger.error("HTTP Response Code: " + httpConn.getResponseCode() + ", HTTP Response Message: " - + httpConn.getResponseMessage()); - return error; + throw new RuntimeException("HTTP Response Code: " + httpConn.getResponseCode() + + ", HTTP Response Message: " + httpConn.getResponseMessage()); } // InputStream is = url.openConnection().getInputStream(); @@ -387,38 +325,26 @@ * The getTextContext is not a java 1.4 method, so Blackboard 7.1 comes up with errors using getNodeValue() * instead */ - // return - // Long.parseLong(document.getElementsByTagName("Lesson").item(0).getAttributes().getNamedItem("lessonId").getTextContent()); + // return Long.parseLong(document.getElementsByTagName("Lesson").item(0).getAttributes().getNamedItem("lessonId").getTextContent()); return Long.parseLong(document.getElementsByTagName("Lesson").item(0).getAttributes() .getNamedItem("lessonId").getNodeValue()); } catch (MalformedURLException e) { - logger.error("Unable to start LAMS lesson, bad URL: '" + serverAddr + "', please check lams.properties", e); - e.printStackTrace(); - return error; + throw new RuntimeException("Unable to start LAMS lesson, bad URL: '" + serverAddr + + "', please check lams.properties", e); } catch (IllegalStateException e) { - logger.error( + throw new RuntimeException( "LAMS Server timeout, did not get a response from the LAMS server. Please contact your systems administrator", e); - e.printStackTrace(); - return error; } catch (RemoteException e) { - logger.error("Unable to start LAMS lesson, RMI Remote Exception", e); - e.printStackTrace(); - return error; + throw new RuntimeException("Unable to start LAMS lesson, RMI Remote Exception", e); } catch (UnsupportedEncodingException e) { - logger.error("Unable to start LAMS lesson, Unsupported Encoding Exception", e); - e.printStackTrace(); - return error; + throw new RuntimeException("Unable to start LAMS lesson, Unsupported Encoding Exception", e); } catch (ConnectException e) { - logger.error( + throw new RuntimeException( "LAMS Server timeout, did not get a response from the LAMS server. Please contact your systems administrator", e); - e.printStackTrace(); - return error; } catch (Exception e) { - logger.error("Unable to start LAMS lesson. Please contact your system administrator.", e); - e.printStackTrace(); - return error; + throw new RuntimeException("Unable to start LAMS lesson. Please contact your system administrator.", e); } } @@ -450,40 +376,7 @@ public static String getReqSrc() { return LamsPluginUtil.getProperties().getProperty(LamsPluginUtil.PROP_REQ_SRC); } - - -// -// if (empty($array['#']['LearningDesign']) && empty($array['#']['Folder'])) { -// $output .= ",expanded:0,children:[{type:'HTML',html:'-" . get_string('empty', 'lamslesson') . "-', id:0}]}"; -// return $output; -// } else { -// $output .= ",children:["; -// } -// -// if (!empty($array['#']['LearningDesign'])) { -// $lds = $array['#']['LearningDesign']; -// for($i=0; $i lineitemid) + PortalExtraInfo pei = PortalUtil.loadPortalExtraInfo(null, null, "LamsLineitemStorage"); + ExtraInfo ei = pei.getExtraInfo(); + ei.setValue(bbContentId, lineitemId); + PortalUtil.savePortalExtraInfo(pei); + } + + /** + * Checks whether lesson has scorable outputs (i.e. MCQ or Assessment activity). + * + * @param ctx + * the blackboard contect, contains session data + * @return a url pointing to the LAMS lesson, monitor, author session + * @throws Exception + */ + private static boolean hasLessonScoreOutputs(Context ctx, Content bbContent) throws Exception { + String ldId = ctx.getRequestParameter("sequence_id"); + //sequence_id parameter is null in case we come from modify_proc + if (ldId == null) { + //get sequence_id from bbcontent URL set in start_lesson_proc + String bbContentUrl = bbContent.getUrl(); + String[] params = bbContentUrl.split("&"); + for (String param : params) { + String paramName = param.split("=")[0]; + String paramValue = param.split("=")[1]; + + if ("ldid".equals(paramName)) { + ldId = paramValue; + break; + } + } + } + + String learningDesignSvgUrl = LamsSecurityUtil.generateRequestLearningDesignImage(ctx, true) + "&ldId=" + ldId.trim(); + + URL url = new URL(learningDesignSvgUrl); + URLConnection conn = url.openConnection(); + if (!(conn instanceof HttpURLConnection)) { + logger.error("Unable to open connection to: " + learningDesignSvgUrl); + } + + HttpURLConnection httpConn = (HttpURLConnection) conn; + + if (httpConn.getResponseCode() != HttpURLConnection.HTTP_OK) { + String errorMsg = "HTTP Response Code: " + httpConn.getResponseCode() + ", HTTP Response Message: " + + httpConn.getResponseMessage(); + logger.error(errorMsg); + throw new RuntimeException(errorMsg); + } + + // InputStream is = url.openConnection().getInputStream(); + InputStream is = conn.getInputStream(); + + // parse xml response + String learningDesignSvg = IOUtils.toString(is, "UTF-8"); + boolean hasLessonScoreOutputs = (learningDesignSvg.indexOf("icon_mcq.png") != -1) || (learningDesignSvg.indexOf("icon_assessment.png") != -1); + + return hasLessonScoreOutputs; + } + + public static void removeLineitem(String bbContentId, String courseIdStr) throws PersistenceException, ServletException { + BbPersistenceManager bbPm = BbServiceManager.getPersistenceService().getDbPersistenceManager(); + + Container bbContainer = bbPm.getContainer(); + Id contentId = new PkId( bbContainer, CourseDocument.DATA_TYPE, bbContentId ); + ContentDbLoader courseDocumentLoader = (ContentDbLoader) bbPm.getLoader( ContentDbLoader.TYPE ); + Content bbContent = (Content)courseDocumentLoader.loadById( contentId ); + //check isGradecenter option is ON + if (!bbContent.getIsDescribed()) {//(isDescribed field is used for storing isGradecenter parameter) + return; + } + + //get lineitemid from the storage (bbContentId -> lineitemid) + PortalExtraInfo pei = PortalUtil.loadPortalExtraInfo(null, null, "LamsLineitemStorage"); + ExtraInfo ei = pei.getExtraInfo(); + String lineitemIdStr = ei.getValue(bbContentId); + + //TODO remove the following paragraph after a while. (It removes lineitems created in versions after 1.2 and before 1.2.3) + if (lineitemIdStr == null) { + // get stored bbContentId -> lamsLessonId. + PortalExtraInfo portalExtraInfo = PortalUtil.loadPortalExtraInfo(null, null, "LamsStorage"); + ExtraInfo extraInfo = portalExtraInfo.getExtraInfo(); + String lamsLessonId = extraInfo.getValue(bbContentId); + + if (lamsLessonId == null || "".equals(lamsLessonId)) { + throw new ServletException( + "LamsLessonId not found in PortalExtraInfo LamsStorage which corresponds to bbContentId:" + + bbContentId); + } + + // search for appropriate lineitem + Id courseId = bbPm.generateId(Course.DATA_TYPE, courseIdStr); + LineitemDbLoader lineitemLoader = LineitemDbLoader.Default.getInstance(); + List lineitems = lineitemLoader.loadByCourseId(courseId); + + Lineitem lineitem = null; + for (Lineitem lineitemIter : lineitems) { + if (lineitemIter.getAssessmentId() != null && lineitemIter.getAssessmentId().equals(lamsLessonId)) { + lineitem = lineitemIter; + break; + } + } + + if (lineitem == null) { + throw new ServletException("Lineitem that corresponds to bbContentId: " + bbContentId + "was not found"); + } + + // delete lineitem (can't delete it simply doing linePersister.deleteById(lineitem.getId()) due to BB9 bug) + PkId lineitemPkId = (PkId) lineitem.getId(); + lineitemIdStr = "_" + lineitemPkId.getPk1() + "_" + lineitemPkId.getPk2(); + } + + if (lineitemIdStr == null) { + throw new ServletException("Lineitem was not found for contentId:" + bbContentId + + ". This is despite the fact that isGradecenter option is ON."); + } + + Id lineitemId = bbPm.generateId(Lineitem.LINEITEM_DATA_TYPE, lineitemIdStr.trim()); + LineitemDbPersister linePersister = (LineitemDbPersister) bbPm.getPersister(LineitemDbPersister.TYPE); + linePersister.deleteById(lineitemId); + + } +} Index: lams_bb_integration/web/modules/create.jsp =================================================================== diff -u -refced1f751a9f688a5f99a75cf6592120260428e -r780957f27df870898ade718ccdacd93d5dfadbd7 --- lams_bb_integration/web/modules/create.jsp (.../create.jsp) (revision efced1f751a9f688a5f99a75cf6592120260428e) +++ lams_bb_integration/web/modules/create.jsp (.../create.jsp) (revision 780957f27df870898ade718ccdacd93d5dfadbd7) @@ -40,11 +40,6 @@ // Get the list of Learning Designs String learningDesigns = LamsSecurityUtil.getLearningDesigns(ctx, 2); - // Error checking - if (learningDesigns.equals("error")) { - response.sendRedirect("lamsServerDown.jsp"); - return; - } String lamsServerUrl = LamsSecurityUtil.getServerAddress(); %> @@ -97,7 +92,6 @@ -