Index: lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java =================================================================== diff -u -rc4bbe0b084234edffd2c0c43dce7d7b1fbf14863 -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java (.../ObjectExtractor.java) (revision c4bbe0b084234edffd2c0c43dce7d7b1fbf14863) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java (.../ObjectExtractor.java) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -35,6 +35,7 @@ import org.apache.log4j.Logger; import org.lamsfoundation.lams.dao.IBaseDAO; +import org.lamsfoundation.lams.learningdesign.ActivityEvaluation; import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.learningdesign.ActivityOrderComparator; import org.lamsfoundation.lams.learningdesign.BranchActivityEntry; @@ -832,6 +833,12 @@ Hashtable activityDetails = (Hashtable) iterator.next(); Activity activity = extractActivityObject(activityDetails); activityDAO.insertOrUpdate(activity); + + // if its a tool activity, extract evaluation details + if (activity.isToolActivity()) { + extractEvaluationObject(activityDetails, (ToolActivity) activity); + } + newActivityMap.put(activity.getActivityUIID(), activity); } } @@ -853,9 +860,60 @@ } /** - * Parses the list of activities sent from the WDDX packet for competence mappings. Each activity's new set of - * competenceMapping is compared against the old set and the db is updated accordingly + * This method extracts and saves the evaluation object for each activity. * + * Here we would normally go through the tool activity evaluation list and + * check if there have been any added/removed. But since our current + * implementation only allows 1 tool output per activity to go to Gradebook, + * we only need to fetch the first. + * + * This implementation will need to be changed if we ever choose to allow + * more than one output per activity to go to Gradebook + * + * @param activityDetails + * @param toolActivity + */ + private void extractEvaluationObject(Hashtable activityDetails, ToolActivity toolActivity) + throws WDDXProcessorConversionException, ObjectExtractorException { + + Set activityEvaluations = toolActivity.getActivityEvaluations(); + ActivityEvaluation activityEvaluation; + + // Get the first (only) ActivityEvaluation if it exists + if (activityEvaluations != null && activityEvaluations.size() >= 1) { + activityEvaluation = (ActivityEvaluation) activityEvaluations.iterator().next(); + } else { + activityEvaluation = new ActivityEvaluation(); + } + + if (keyExists(activityDetails, WDDXTAGS.TOOL_OUTPUT_DEFINITION) + && WDDXProcessor.convertToString(activityDetails, WDDXTAGS.TOOL_OUTPUT_DEFINITION) != null + && !WDDXProcessor.convertToString(activityDetails, WDDXTAGS.TOOL_OUTPUT_DEFINITION).equals("")) { + activityEvaluations = new HashSet(); + activityEvaluation.setActivity(toolActivity); + activityEvaluation.setToolOutputDefinition(WDDXProcessor.convertToString(activityDetails, + WDDXTAGS.TOOL_OUTPUT_DEFINITION)); + activityEvaluations.add(activityEvaluation); + toolActivity.setActivityEvaluations(activityEvaluations); + baseDAO.insertOrUpdate(activityEvaluation); + + // update the parent toolActivity + toolActivity.setActivityEvaluations(activityEvaluations); + activityDAO.insertOrUpdate(toolActivity); + + } else if (activityEvaluation.getUid() != null) { + // update the parent toolActivity + toolActivity.setActivityEvaluations(new HashSet()); + activityDAO.insertOrUpdate(toolActivity); + baseDAO.delete(activityEvaluation); + } + } + + /** + * Parses the list of activities sent from the WDDX packet for competence + * mappings. Each activity's new set of competenceMapping is compared + * against the old set and the db is updated accordingly + * * @param activitiesList * The list of activities from the WDDX packet. * @throws WDDXProcessorConversionException Index: lams_central/src/java/org/lamsfoundation/lams/authoring/service/AuthoringService.java =================================================================== diff -u -r9a772f5ba1954a3a719a19e7ae237b6b09dc76ef -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_central/src/java/org/lamsfoundation/lams/authoring/service/AuthoringService.java (.../AuthoringService.java) (revision 9a772f5ba1954a3a719a19e7ae237b6b09dc76ef) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/service/AuthoringService.java (.../AuthoringService.java) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -43,6 +43,7 @@ import org.apache.log4j.Logger; import org.lamsfoundation.lams.authoring.IObjectExtractor; import org.lamsfoundation.lams.dao.hibernate.BaseDAO; +import org.lamsfoundation.lams.learningdesign.ActivityEvaluation; import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.learningdesign.BranchActivityEntry; import org.lamsfoundation.lams.learningdesign.BranchingActivity; @@ -168,9 +169,9 @@ this.pedagogicalPlannerDAO = pedagogicalPlannerDAO; } - /******************************************************************************************************************* + /*************************************************************************** * Setter Methods - ******************************************************************************************************************/ + **************************************************************************/ /** * Set i18n MessageService */ @@ -370,12 +371,13 @@ this.beanFactory = beanFactory; } - /******************************************************************************************************************* + /*************************************************************************** * Utility/Service Methods - ******************************************************************************************************************/ + **************************************************************************/ /** - * Helper method to retrieve the user data. Gets the id from the user details in the shared session + * Helper method to retrieve the user data. Gets the id from the user + * details in the shared session * * @return the user id */ @@ -597,10 +599,12 @@ } /** - * Remove a temp. System Gate from the design. Requires removing the gate from any learner progress entries - should - * only be a current activity but remove it from previous and next, just in case. + * Remove a temp. System Gate from the design. Requires removing the gate + * from any learner progress entries - should only be a current activity but + * remove it from previous and next, just in case. * - * This will leave a "hole" in the learner progress, but the progress engine can take care of that. + * This will leave a "hole" in the learner progress, but the progress engine + * can take care of that. * * @param gate * @param design @@ -915,7 +919,8 @@ /** * @see org.lamsfoundation.lams.authoring.service.IAuthoringService#copyLearningDesign(org.lamsfoundation.lams.learningdesign.LearningDesign, * java.lang.Integer, org.lamsfoundation.lams.usermanagement.User, - * org.lamsfoundation.lams.usermanagement.WorkspaceFolder, java.lang.Boolean, java.lang.String) + * org.lamsfoundation.lams.usermanagement.WorkspaceFolder, + * java.lang.Boolean, java.lang.String) */ public LearningDesign copyLearningDesign(LearningDesign originalLearningDesign, Integer copyType, User user, WorkspaceFolder workspaceFolder, boolean setOriginalDesign, String newDesignName, String customCSV) @@ -949,6 +954,8 @@ updateCompetenceMappings(newLearningDesign.getCompetences(), newActivities); + updateEvaluations(newActivities); + return newLearningDesign; } @@ -957,7 +964,8 @@ * @throws WorkspaceFolderException * @throws IOException * @see org.lamsfoundation.lams.authoring.service.IAuthoringService#insertLearningDesign(java.lang.Long, - * java.lang.Long, java.lang.Integer, java.lang.Boolean, java.lang.String, java.lang.Integer) + * java.lang.Long, java.lang.Integer, java.lang.Boolean, + * java.lang.String, java.lang.Integer) */ public LearningDesign insertLearningDesign(Long originalDesignID, Long designToImportID, Integer userID, boolean createNewLearningDesign, String newDesignName, Integer workspaceFolderID, String customCSV) @@ -1026,13 +1034,26 @@ insertCompetenceMappings(mainDesign.getCompetences(), designToImport.getCompetences(), newActivities); - return mainDesign; + // For some reason, the evaluations will not save on insert when the + // learning design is saved, so doing it manually here + + this.updateEvaluations(newActivities); + +// for (Integer activityKey : newActivities.keySet()) { +// Activity activity = newActivities.get(activityKey); +// if (activity.isToolActivity()) { +// ToolActivity toolAct = (ToolActivity) activity; +// baseDAO.insertOrUpdateAll(toolAct.getActivityEvaluations()); +// } +// } + return mainDesign; } /** * @see org.lamsfoundation.lams.authoring.service.IAuthoringService#copyLearningDesignToolContent(org.lamsfoundation.lams.learningdesign.LearningDesign, - * org.lamsfoundation.lams.learningdesign.LearningDesign, java.lang.Integer) + * org.lamsfoundation.lams.learningdesign.LearningDesign, + * java.lang.Integer) */ private LearningDesign copyLearningDesignToolContent(LearningDesign design, LearningDesign originalLearningDesign, Integer copyType) throws LearningDesignException { @@ -1084,20 +1105,21 @@ } /** - * Updates the Activity information in the newLearningDesign based on the originalLearningDesign. This any grouping - * details. + * Updates the Activity information in the newLearningDesign based on the + * originalLearningDesign. This any grouping details. * - * As new activities are created, the UIID is incremented by the uiidOffset. If we are just copying a sequence this - * will be set to 0. But if we are importing a sequence into another sequence, this will be an offset value so we - * new ids guaranteed to be outside of the range of the main sequence (this may mean gaps in the uiids but that - * doesn't matter). + * As new activities are created, the UIID is incremented by the uiidOffset. + * If we are just copying a sequence this will be set to 0. But if we are + * importing a sequence into another sequence, this will be an offset value + * so we new ids guaranteed to be outside of the range of the main sequence + * (this may mean gaps in the uiids but that doesn't matter). * * @param originalLearningDesign * The LearningDesign to be copied * @param newLearningDesign * The copy of the originalLearningDesign - * @return Map of all the new activities, where the key is the UIID value. This is used as an input to - * updateDesignTransitions + * @return Map of all the new activities, where the key is the UIID value. + * This is used as an input to updateDesignTransitions */ private HashMap updateDesignActivities(LearningDesign originalLearningDesign, LearningDesign newLearningDesign, int uiidOffset, String customCSV) { @@ -1233,21 +1255,25 @@ } /** - * As part of updateDesignActivities(), process an activity and, via recursive calls, the activity's child - * activities. Need to keep track of any new groupings created so we can go back and update the grouped activities - * with their new groupings at the end. Also copies the tool content. + * As part of updateDesignActivities(), process an activity and, via + * recursive calls, the activity's child activities. Need to keep track of + * any new groupings created so we can go back and update the grouped + * activities with their new groupings at the end. Also copies the tool + * content. * * @param activity * Activity to process. May not be null. * @param newLearningDesign * The new learning design. May not be null. * @param newActivities - * Temporary set of new activities - as activities are processed they are added to the set. May not - * be null. + * Temporary set of new activities - as activities are + * processed they are added to the set. May not be null. * @param newGroupings - * Temporary set of new groupings. Key is the grouping UUID. May not be null. + * Temporary set of new groupings. Key is the grouping UUID. + * May not be null. * @param parentActivity - * This activity's parent activity (if one exists). May be null. + * This activity's parent activity (if one exists). May be + * null. */ private void processActivity(Activity activity, LearningDesign newLearningDesign, Map newActivities, Map newGroupings, Activity parentActivity, @@ -1301,7 +1327,8 @@ } /** - * Updates the Transition information in the newLearningDesign based on the originalLearningDesign + * Updates the Transition information in the newLearningDesign based on the + * originalLearningDesign * * @param originalLearningDesign * The LearningDesign to be copied @@ -1351,7 +1378,8 @@ } /** - * Updates the competence information in the newLearningDesign based on the originalLearningDesign + * Updates the competence information in the newLearningDesign based on the + * originalLearningDesign * * @param originalLearningDesign * The LearningDesign to be copied @@ -1454,7 +1482,8 @@ } /** - * Updates the competence information in the newLearningDesign based on the originalLearningDesign + * Updates the competence information in the newLearningDesign based on the + * originalLearningDesign * * @param originalLearningDesign * The LearningDesign to be copied @@ -1488,13 +1517,29 @@ } } + private void updateEvaluations(HashMap newActivities) { + + for (Integer key : newActivities.keySet()) + { + Activity activity = newActivities.get(key); + if (activity.isToolActivity()) { + Set newActivityEvaluations = ((ToolActivity)activity).getActivityEvaluations(); + + if (newActivityEvaluations != null) { + baseDAO.insertOrUpdateAll(newActivityEvaluations); + } + } + } + } + /** * Determines the type of activity and returns a deep-copy of the same * * @param activity * The object to be deep-copied * @param newGroupings - * Temporary set of new groupings. Key is the grouping UUID. May not be null. + * Temporary set of new groupings. Key is the grouping UUID. + * May not be null. * @return Activity The new deep-copied Activity object */ private Activity getActivityCopy(final Activity activity, Map newGroupings, int uiidOffset) { @@ -1532,11 +1577,13 @@ } /** - * This method saves a new Learning Design to the database. It received a WDDX packet from flash, deserializes it - * and then finally persists it to the database. + * This method saves a new Learning Design to the database. It received a + * WDDX packet from flash, deserializes it and then finally persists it to + * the database. * - * A user may update an existing learning design if they have user/owner rights to the folder or they are doing live - * edit. A user may create a new learning design only if they have user/owner rights to the folder. + * A user may update an existing learning design if they have user/owner + * rights to the folder or they are doing live edit. A user may create a new + * learning design only if they have user/owner rights to the folder. * * Note: it does not validate the design - that must be done separately. * @@ -1593,8 +1640,9 @@ /** * Validate the learning design, updating the valid flag appropriately. * - * This needs to be run in a separate transaction to storeLearningDesignDetails to ensure the database is fully - * updated before the validation occurs (due to some quirks we are finding using Hibernate) + * This needs to be run in a separate transaction to + * storeLearningDesignDetails to ensure the database is fully updated before + * the validation occurs (due to some quirks we are finding using Hibernate) * * @param learningDesignId * @throws Exception @@ -1650,7 +1698,8 @@ } /** - * This is a utility method used by the method getAllLearningDesignDetails to pack the required + * This is a utility method used by the method + * getAllLearningDesignDetails to pack the required * information in a data transfer object. * * @param iterator @@ -1744,8 +1793,8 @@ } /** - * Delete a learning design from the database. Does not remove any content stored in tools - that is done by the - * LamsCoreToolService + * Delete a learning design from the database. Does not remove any content + * stored in tools - that is done by the LamsCoreToolService */ public void deleteLearningDesign(LearningDesign design) { if (design == null) { @@ -1800,10 +1849,12 @@ } /** - * Get a unique name for a learning design, based on the names of the learning designs in the folder. If the - * learning design has duplicated name in same folder, then the new name will have a timestamp. The new name format - * will be oldname_ddMMYYYY_idx. The idx will be auto incremental index number, start from 1. Warning - this may be - * quite intensive as it gets all the learning designs in a folder. + * Get a unique name for a learning design, based on the names of the + * learning designs in the folder. If the learning design has duplicated + * name in same folder, then the new name will have a timestamp. The new + * name format will be oldname_ddMMYYYY_idx. The idx will be auto + * incremental index number, start from 1. Warning - this may be quite + * intensive as it gets all the learning designs in a folder. * * @param originalLearningDesign * @param workspaceFolder Index: lams_central/src/java/org/lamsfoundation/lams/authoring/web/ExportToolContentAction.java =================================================================== diff -u -r9a123141df4cdf18fefb239b7d4c50e9d488d42d -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_central/src/java/org/lamsfoundation/lams/authoring/web/ExportToolContentAction.java (.../ExportToolContentAction.java) (revision 9a123141df4cdf18fefb239b7d4c50e9d488d42d) +++ lams_central/src/java/org/lamsfoundation/lams/authoring/web/ExportToolContentAction.java (.../ExportToolContentAction.java) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -25,11 +25,14 @@ package org.lamsfoundation.lams.authoring.web; import java.io.BufferedInputStream; +import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import javax.servlet.http.HttpServletRequest; @@ -45,127 +48,190 @@ import org.lamsfoundation.lams.util.FileUtil; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.action.LamsAction; +import org.lamsfoundation.lams.web.lamscommunity.LamsCommunityUtil; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; + /** * - * @struts.action path = "/authoring/exportToolContent" - * validate = "false" + * @struts.action path = "/authoring/exportToolContent" validate = "false" * @struts.action-forward name = "choice" path = "/toolcontent/exportchoice.jsp" - * @struts.action-forward name = "loading" path = "/toolcontent/exportloading.jsp" + * @struts.action-forward name = "loading" path = + * "/toolcontent/exportloading.jsp" * @struts.action-forward name = "result" path = "/toolcontent/exportresult.jsp" - * + * * Export tool content action. It needs learingDesignID as input parameter. * @author Steve.Ni * @version $Revision$ */ public class ExportToolContentAction extends LamsAction { - private static final long serialVersionUID = 1L; - public static final String EXPORT_TOOLCONTENT_SERVICE_BEAN_NAME = "exportToolContentService"; - public static final String PARAM_LEARING_DESIGN_ID = "learningDesignID"; - public static final String ATTR_TOOLS_ERROR_MESSAGE = "toolsErrorMessages"; - public static final String ATTR_LD_ERROR_MESSAGE = "ldErrorMessages"; - private static final String PARAM_EXPORT_FORMAT = "format"; - private static final String IMS_XSLT_NAME = "learning-design-ims.xslt"; - private static final String IMS_XSLT_PATH = "/toolcontent"; + private static final long serialVersionUID = 1L; + public static final String EXPORT_TOOLCONTENT_SERVICE_BEAN_NAME = "exportToolContentService"; + public static final String PARAM_LEARING_DESIGN_ID = "learningDesignID"; + public static final String ATTR_TOOLS_ERROR_MESSAGE = "toolsErrorMessages"; + public static final String ATTR_LD_ERROR_MESSAGE = "ldErrorMessages"; + private static final String PARAM_EXPORT_FORMAT = "format"; + private static final String IMS_XSLT_NAME = "learning-design-ims.xslt"; + private static final String IMS_XSLT_PATH = "/toolcontent"; + private Logger log = Logger.getLogger(ExportToolContentAction.class); - private Logger log = Logger.getLogger(ExportToolContentAction.class); - - @Override - public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { - String param = request.getParameter("method"); - //-----------------------Resource Author function --------------------------- - if(StringUtils.equals(param,"loading")){ - Long learningDesignId = WebUtil.readLongParam(request,PARAM_LEARING_DESIGN_ID); - request.setAttribute(PARAM_LEARING_DESIGN_ID,learningDesignId); - int format = WebUtil.readIntParam(request,PARAM_EXPORT_FORMAT); - request.setAttribute(PARAM_EXPORT_FORMAT,format); - //display initial page for automatically loading download pgm - return mapping.findForward("loading"); - }else if(StringUtils.equals(param,"export")){ - //the export LD pgm - return exportLD(mapping,request,response); - }else{ //choice format - Long learningDesignId = WebUtil.readLongParam(request,PARAM_LEARING_DESIGN_ID); - request.setAttribute(PARAM_LEARING_DESIGN_ID,learningDesignId); - //display choose IMS or LAMS format page - return mapping.findForward("choice"); - } + @Override + public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws Exception { + String param = request.getParameter("method"); + //-----------------------Resource Author function --------------------------- + if (StringUtils.equals(param, "loading")) { + Long learningDesignId = WebUtil.readLongParam(request, PARAM_LEARING_DESIGN_ID); + request.setAttribute(PARAM_LEARING_DESIGN_ID, learningDesignId); + int format = WebUtil.readIntParam(request, PARAM_EXPORT_FORMAT); + request.setAttribute(PARAM_EXPORT_FORMAT, format); + //display initial page for automatically loading download pgm + return mapping.findForward("loading"); + } else if (StringUtils.equals(param, "export")) { + //the export LD pgm + return exportLD(mapping, request, response); + } else { //choice format + Long learningDesignId = WebUtil.readLongParam(request, PARAM_LEARING_DESIGN_ID); + request.setAttribute(PARAM_LEARING_DESIGN_ID, learningDesignId); + //display choose IMS or LAMS format page + return mapping.findForward("choice"); } - private ActionForward exportLD(ActionMapping mapping, HttpServletRequest request,HttpServletResponse response){ - Long learningDesignId = WebUtil.readLongParam(request,PARAM_LEARING_DESIGN_ID); - int format = WebUtil.readIntParam(request,PARAM_EXPORT_FORMAT); - IExportToolContentService service = getExportService(); - List ldErrorMsgs = new ArrayList(); - List toolsErrorMsgs = new ArrayList(); - + } + + private ActionForward exportLD(ActionMapping mapping, HttpServletRequest request, HttpServletResponse response) { + Long learningDesignId = WebUtil.readLongParam(request, PARAM_LEARING_DESIGN_ID); + int format = WebUtil.readIntParam(request, PARAM_EXPORT_FORMAT); + IExportToolContentService service = getExportService(); + List ldErrorMsgs = new ArrayList(); + List toolsErrorMsgs = new ArrayList(); + + try { + File xslt = new File(this.getServlet().getServletContext().getRealPath(IMS_XSLT_PATH) + File.separator + + IMS_XSLT_NAME); + String zipFilename = service.exportLearningDesign(learningDesignId, toolsErrorMsgs, format, xslt); + + // get only filename + String zipfile = FileUtil.getFileName(zipFilename); + + // replace spaces (" ") with underscores ("_") + + zipfile = zipfile.replaceAll(" ", "_"); + + //write zip file as response stream. + + // Different browsers handle stream downloads differently LDEV-1243 + String filename = FileUtil.encodeFilenameForDownload(request, zipfile); + log.debug("Final filename to export: " + filename); + + response.setContentType("application/x-download"); + // response.setContentType("application/zip"); + response.setHeader("Content-Disposition", "attachment;filename=" + filename); + InputStream in = null; + OutputStream out = null; + try { + in = new BufferedInputStream(new FileInputStream(zipFilename)); + out = response.getOutputStream(); + int count = 0; + + int ch; + while ((ch = in.read()) != -1) { + out.write((char) ch); + count++; + } + log.debug("Wrote out " + count + " bytes"); + response.setContentLength(count); + out.flush(); + } catch (Exception e) { + log.error("Exception occured writing out file:" + e.getMessage()); + throw new ExportToolContentException(e); + } finally { try { - File xslt = new File(this.getServlet().getServletContext().getRealPath(IMS_XSLT_PATH)+File.separator+IMS_XSLT_NAME); - String zipFilename = service.exportLearningDesign(learningDesignId,toolsErrorMsgs,format,xslt); - - // get only filename - String zipfile = FileUtil.getFileName(zipFilename); - - // replace spaces (" ") with underscores ("_") - - zipfile = zipfile.replaceAll(" ", "_"); - - //write zip file as response stream. + if (in != null) + in.close(); // very important + if (out != null) + out.close(); + } catch (Exception e) { + log.error("Error Closing file. File already written out - no exception being thrown.", e); + } + } - // Different browsers handle stream downloads differently LDEV-1243 - String filename = FileUtil.encodeFilenameForDownload(request, zipfile); - log.debug("Final filename to export: " + filename); - - response.setContentType("application/x-download"); -// response.setContentType("application/zip"); - response.setHeader("Content-Disposition","attachment;filename="+filename); - InputStream in = null; - OutputStream out = null; - try { - in = new BufferedInputStream(new FileInputStream(zipFilename)); - out = response.getOutputStream(); - int count = 0; - - int ch; - while ((ch = in.read()) != -1) - { - out.write((char) ch); - count++; - } - log.debug("Wrote out " + count + " bytes"); - response.setContentLength(count); - out.flush(); - } catch (Exception e) { - log.error( "Exception occured writing out file:" + e.getMessage()); - throw new ExportToolContentException(e); - } finally { - try { - if (in != null) in.close(); // very important - if (out != null) out.close(); - } - catch (Exception e) { - log.error("Error Closing file. File already written out - no exception being thrown.",e); - } - } - - return null; - } catch (Exception e1) { - log.error("Unable to export tool content: " + e1.toString()); - ldErrorMsgs.add(0,e1.getClass().getName()); - request.setAttribute(ATTR_LD_ERROR_MESSAGE,ldErrorMsgs); - request.setAttribute(ATTR_TOOLS_ERROR_MESSAGE,toolsErrorMsgs); + return null; + } catch (Exception e1) { + log.error("Unable to export tool content: " + e1.toString()); + ldErrorMsgs.add(0, e1.getClass().getName()); + request.setAttribute(ATTR_LD_ERROR_MESSAGE, ldErrorMsgs); + request.setAttribute(ATTR_TOOLS_ERROR_MESSAGE, toolsErrorMsgs); + } + //display initial page for upload + return mapping.findForward("result"); + } + + /** + * Exports the learning design to lamscommunity + * + * @param mapping + * @param request + * @param response + * @return + */ + private ActionForward exportLDToLC(ActionMapping mapping, HttpServletRequest request, HttpServletResponse response) { + Long learningDesignId = WebUtil.readLongParam(request, PARAM_LEARING_DESIGN_ID); + int format = WebUtil.readIntParam(request, PARAM_EXPORT_FORMAT); + IExportToolContentService service = getExportService(); + List ldErrorMsgs = new ArrayList(); + List toolsErrorMsgs = new ArrayList(); + + try { + File xslt = new File(this.getServlet().getServletContext().getRealPath(IMS_XSLT_PATH) + File.separator + + IMS_XSLT_NAME); + String zipFilename = service.exportLearningDesign(learningDesignId, toolsErrorMsgs, format, xslt); + + // get only filename + String zipfile = FileUtil.getFileName(zipFilename); + + // replace spaces (" ") with underscores ("_") + + zipfile = zipfile.replaceAll(" ", "_"); + + File uploadFile = new File(zipfile); + if (uploadFile != null && uploadFile.exists()) { + HashMap authParams = LamsCommunityUtil.getAuthParams(); + InputStream is = WebUtil.performMultipartFilePost(uploadFile, + LamsCommunityUtil.LAMS_COMMUNITY_EXPORT_URL, zipFilename, authParams); + + BufferedReader isReader = new BufferedReader(new InputStreamReader(is)); + String responseStr = isReader.readLine(); + + if (responseStr != null && responseStr.trim().equals("success")){ + // successful export to lams community + // Get the ldID and forward user to the lamscommunity form } - //display initial page for upload - return mapping.findForward("result"); + else if(responseStr!=null){ + // get the failure type and add it to the errors + }else { + // general failure + } + } + + return null; + } catch (Exception e1) { + log.error("Unable to export tool content: " + e1.toString()); + ldErrorMsgs.add(0, e1.getClass().getName()); + request.setAttribute(ATTR_LD_ERROR_MESSAGE, ldErrorMsgs); + request.setAttribute(ATTR_TOOLS_ERROR_MESSAGE, toolsErrorMsgs); } - - //*************************************************************************************** - // Private method - //*************************************************************************************** - private IExportToolContentService getExportService(){ - WebApplicationContext webContext = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServlet().getServletContext()); - return (IExportToolContentService) webContext.getBean(EXPORT_TOOLCONTENT_SERVICE_BEAN_NAME); - } + //display initial page for upload + return mapping.findForward("result"); + } + + //*************************************************************************************** + // Private method + //*************************************************************************************** + private IExportToolContentService getExportService() { + WebApplicationContext webContext = WebApplicationContextUtils.getRequiredWebApplicationContext(this + .getServlet().getServletContext()); + return (IExportToolContentService) webContext.getBean(EXPORT_TOOLCONTENT_SERVICE_BEAN_NAME); + } } Index: lams_central/src/java/org/lamsfoundation/lams/web/LoginRequestServlet.java =================================================================== diff -u -rc2a96caab480d04c02dc7a90e719fc0bb9af6a50 -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_central/src/java/org/lamsfoundation/lams/web/LoginRequestServlet.java (.../LoginRequestServlet.java) (revision c2a96caab480d04c02dc7a90e719fc0bb9af6a50) +++ lams_central/src/java/org/lamsfoundation/lams/web/LoginRequestServlet.java (.../LoginRequestServlet.java) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -69,172 +69,165 @@ @SuppressWarnings("serial") public class LoginRequestServlet extends HttpServlet { - private static Logger log = Logger.getLogger(LoginRequestServlet.class); - - private static IntegrationService integrationService = null; + private static Logger log = Logger.getLogger(LoginRequestServlet.class); - private static final String JNDI_DATASOURCE = "java:/jdbc/lams-ds"; + private static IntegrationService integrationService = null; - private static final String PASSWORD_QUERY = "select password from lams_user where login=?"; + private static final String JNDI_DATASOURCE = "java:/jdbc/lams-ds"; - /** - * The doGet method of the servlet.
- * - * This method is called when a form has its tag value method equals to get. - * - * @param request - * the request send by the client to the server - * @param response - * the response send by the server to the client - * @throws ServletException - * if an error occurred - * @throws IOException - * if an error occurred - */ - public void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - // create http session required by the valve - // since valve can't create session - /*HttpSession hses = request.getSession(); - if(hses!=null) hses.invalidate(); - HttpSession sharedsession = SessionManager.getSession(); - if(sharedsession!=null) sharedsession.invalidate();*/ - HttpSession hses = request.getSession(true); + private static final String PASSWORD_QUERY = "select password from lams_user where login=?"; - String extUsername = request.getParameter(LoginRequestDispatcher.PARAM_USER_ID); - String serverId = request.getParameter(LoginRequestDispatcher.PARAM_SERVER_ID); - String extCourseId = request.getParameter(LoginRequestDispatcher.PARAM_COURSE_ID); - String timestamp = request.getParameter(LoginRequestDispatcher.PARAM_TIMESTAMP); - String hash = request.getParameter(LoginRequestDispatcher.PARAM_HASH); - String method = request.getParameter(LoginRequestDispatcher.PARAM_METHOD); - String countryIsoCode = request.getParameter(LoginRequestDispatcher.PARAM_COUNTRY); - String langIsoCode = request.getParameter(LoginRequestDispatcher.PARAM_LANGUAGE); - String courseName = request.getParameter(CentralConstants.PARAM_COURSE_NAME); - - // implicit login params - String firstName = request.getParameter(LoginRequestDispatcher.PARAM_FIRST_NAME); - String lastName = request.getParameter(LoginRequestDispatcher.PARAM_LAST_NAME); - String email = request.getParameter(LoginRequestDispatcher.PARAM_EMAIL); - - if (extUsername == null || method == null || serverId == null || timestamp == null - || hash == null || extCourseId == null) { - response.sendError(HttpServletResponse.SC_BAD_REQUEST, - "Login Failed - login parameters missing"); - return; - } - ExtServerOrgMap serverMap = getService().getExtServerOrgMap(serverId); + /** + * The doGet method of the servlet.
+ * + * This method is called when a form has its tag value method equals to get. + * + * @param request + * the request send by the client to the server + * @param response + * the response send by the server to the client + * @throws ServletException + * if an error occurred + * @throws IOException + * if an error occurred + */ + public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // create http session required by the valve + // since valve can't create session + /*HttpSession hses = request.getSession(); + if(hses!=null) hses.invalidate(); + HttpSession sharedsession = SessionManager.getSession(); + if(sharedsession!=null) sharedsession.invalidate();*/ + HttpSession hses = request.getSession(true); - try { - ExtUserUseridMap userMap = null; - - if (firstName==null && lastName==null) - { - userMap = getService().getExtUserUseridMap(serverMap, extUsername); - } - else - { - userMap = getService().getImplicitExtUserUseridMap(serverMap, extUsername, firstName, lastName, langIsoCode, countryIsoCode, email); - } - - - Authenticator.authenticate(serverMap, timestamp, extUsername, method, hash); - ExtCourseClassMap orgMap = getService().getExtCourseClassMap(serverMap, userMap, extCourseId, countryIsoCode, langIsoCode, courseName); - User user = userMap.getUser(); - String login = user.getLogin(); - //was using hses.inNew() API to check if the external user has logged in yet, - // but it seems not working. The "extUser" attribute works as a flag to indicate - // if the user has logged in - String loginRequestUsername = (String)hses.getAttribute("extUser"); - if(loginRequestUsername != null && loginRequestUsername.equals(login)){ - String url = LoginRequestDispatcher.getRequestURL(request); - response.sendRedirect(response.encodeRedirectURL(url)); - return; - } else if(loginRequestUsername != null && !loginRequestUsername.equals(login)){ - hses.invalidate(); - hses = request.getSession(true); - } else if(request.getRemoteUser() != null && loginRequestUsername == null){ - hses.invalidate(); - hses = request.getSession(true); - } - Organisation org = orgMap.getOrganisation(); - IUserManagementService userManagementService = integrationService.getService(); - UserOrganisation uo = userManagementService.getUserOrganisation(user.getUserId(), org.getOrganisationId()); - // make sure external user has minimal set of roles, i.e. learner - Integer[] roleIds = new Integer[]{Role.ROLE_LEARNER}; - //we have to assign all the roles to the external user here, because once the user logged in, the roles - //are cached in JBoss, all the calls of request.isUserInRole() will be based on the cached roles - Map properties = new HashMap(); - properties.put("userOrganisation.userOrganisationId", uo.getUserOrganisationId()); - for(Integer roleId : roleIds){ - properties.put("role.roleId", roleId); - List list = userManagementService.findByProperties(UserOrganisationRole.class, properties); - if(list==null || list.size()==0){ - UserOrganisationRole uor = new UserOrganisationRole(uo, (Role)userManagementService.findById(Role.class, roleId)); - userManagementService.save(uor); - } - } - log.debug("Session Id - "+hses.getId()); - // connect to DB and get password here - String pass = getUserPassword(userMap.getUser().getLogin()); - // should post the parameters back so it's little more secure, - // but forward doesn't work, use this until a better method is found - hses.setAttribute("extUser", login); - hses.setAttribute(AttributeNames.USER, user.getUserDTO()); - response.sendRedirect("j_security_check?j_username=" + login + "&j_password=" + pass); - } catch (AuthenticationException e) { - log.error("Authentication error: ", e); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, - "Login Failed - authentication error"); - } catch (UserInfoFetchException e) { - log.error("User fetch info error: ", e); - response.sendError(HttpServletResponse.SC_BAD_GATEWAY, - "Login Failed - failed to fetch user info from the third party server"); - } catch (FailedLoginException e) { - log.error("Login error: ", e); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, - "Login Failed - user was not found"); - } catch (NamingException e) { - log.error("Naming error: ", e); - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); - } catch (SQLException e) { - log.error("Database error: ", e); - response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + String extUsername = request.getParameter(LoginRequestDispatcher.PARAM_USER_ID); + String serverId = request.getParameter(LoginRequestDispatcher.PARAM_SERVER_ID); + String extCourseId = request.getParameter(LoginRequestDispatcher.PARAM_COURSE_ID); + String timestamp = request.getParameter(LoginRequestDispatcher.PARAM_TIMESTAMP); + String hash = request.getParameter(LoginRequestDispatcher.PARAM_HASH); + String method = request.getParameter(LoginRequestDispatcher.PARAM_METHOD); + String countryIsoCode = request.getParameter(LoginRequestDispatcher.PARAM_COUNTRY); + String langIsoCode = request.getParameter(LoginRequestDispatcher.PARAM_LANGUAGE); + String courseName = request.getParameter(CentralConstants.PARAM_COURSE_NAME); + + // implicit login params + String firstName = request.getParameter(LoginRequestDispatcher.PARAM_FIRST_NAME); + String lastName = request.getParameter(LoginRequestDispatcher.PARAM_LAST_NAME); + String email = request.getParameter(LoginRequestDispatcher.PARAM_EMAIL); + + if (extUsername == null || method == null || serverId == null || timestamp == null || hash == null + || extCourseId == null) { + response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Login Failed - login parameters missing"); + return; + } + ExtServerOrgMap serverMap = getService().getExtServerOrgMap(serverId); + + try { + ExtUserUseridMap userMap = null; + + if (firstName == null && lastName == null) { + userMap = getService().getExtUserUseridMap(serverMap, extUsername); + } else { + userMap = getService().getImplicitExtUserUseridMap(serverMap, extUsername, firstName, lastName, + langIsoCode, countryIsoCode, email); + } + + Authenticator.authenticate(serverMap, timestamp, extUsername, method, hash); + ExtCourseClassMap orgMap = getService().getExtCourseClassMap(serverMap, userMap, extCourseId, + countryIsoCode, langIsoCode, courseName); + User user = userMap.getUser(); + String login = user.getLogin(); + //was using hses.inNew() API to check if the external user has logged in yet, + // but it seems not working. The "extUser" attribute works as a flag to indicate + // if the user has logged in + String loginRequestUsername = (String) hses.getAttribute("extUser"); + if (loginRequestUsername != null && loginRequestUsername.equals(login)) { + String url = LoginRequestDispatcher.getRequestURL(request); + response.sendRedirect(response.encodeRedirectURL(url)); + return; + } else if (loginRequestUsername != null && !loginRequestUsername.equals(login)) { + hses.invalidate(); + hses = request.getSession(true); + } else if (request.getRemoteUser() != null && loginRequestUsername == null) { + hses.invalidate(); + hses = request.getSession(true); + } + Organisation org = orgMap.getOrganisation(); + IUserManagementService userManagementService = integrationService.getService(); + UserOrganisation uo = userManagementService.getUserOrganisation(user.getUserId(), org.getOrganisationId()); + // make sure external user has minimal set of roles, i.e. learner + Integer[] roleIds = new Integer[] { Role.ROLE_LEARNER }; + //we have to assign all the roles to the external user here, because once the user logged in, the roles + //are cached in JBoss, all the calls of request.isUserInRole() will be based on the cached roles + Map properties = new HashMap(); + properties.put("userOrganisation.userOrganisationId", uo.getUserOrganisationId()); + for (Integer roleId : roleIds) { + properties.put("role.roleId", roleId); + List list = userManagementService.findByProperties(UserOrganisationRole.class, properties); + if (list == null || list.size() == 0) { + UserOrganisationRole uor = new UserOrganisationRole(uo, (Role) userManagementService.findById( + Role.class, roleId)); + userManagementService.save(uor); } + } + log.debug("Session Id - " + hses.getId()); + // connect to DB and get password here + String pass = getUserPassword(userMap.getUser().getLogin()); + // should post the parameters back so it's little more secure, + // but forward doesn't work, use this until a better method is found + hses.setAttribute("extUser", login); + hses.setAttribute(AttributeNames.USER, user.getUserDTO()); + response.sendRedirect("j_security_check?j_username=" + login + "&j_password=" + pass); + } catch (AuthenticationException e) { + log.error("Authentication error: ", e); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Login Failed - authentication error"); + } catch (UserInfoFetchException e) { + log.error("User fetch info error: ", e); + response.sendError(HttpServletResponse.SC_BAD_GATEWAY, + "Login Failed - failed to fetch user info from the third party server"); + } catch (FailedLoginException e) { + log.error("Login error: ", e); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Login Failed - user was not found"); + } catch (NamingException e) { + log.error("Naming error: ", e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); + } catch (SQLException e) { + log.error("Database error: ", e); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()); } + } - // using JDBC connection to prevent the caching of passwords by hibernate - private String getUserPassword(String username) throws FailedLoginException, NamingException, - SQLException { - InitialContext ctx = new InitialContext(); + // using JDBC connection to prevent the caching of passwords by hibernate + private String getUserPassword(String username) throws FailedLoginException, NamingException, SQLException { + InitialContext ctx = new InitialContext(); - DataSource ds = (DataSource) ctx.lookup(JNDI_DATASOURCE); - Connection conn = null; - String password = null; - try { - conn = ds.getConnection(); - PreparedStatement ps = conn.prepareStatement(PASSWORD_QUERY); - ps.setString(1, username); - ResultSet rs = ps.executeQuery(); + DataSource ds = (DataSource) ctx.lookup(JNDI_DATASOURCE); + Connection conn = null; + String password = null; + try { + conn = ds.getConnection(); + PreparedStatement ps = conn.prepareStatement(PASSWORD_QUERY); + ps.setString(1, username); + ResultSet rs = ps.executeQuery(); - // check if there is any result - if (rs.next() == false) - throw new FailedLoginException("invalid username"); + // check if there is any result + if (rs.next() == false) + throw new FailedLoginException("invalid username"); - password = rs.getString(1); - rs.close(); - } finally { - if (conn != null && !conn.isClosed()) - conn.close(); - } - return password; + password = rs.getString(1); + rs.close(); + } finally { + if (conn != null && !conn.isClosed()) + conn.close(); } + return password; + } - private IntegrationService getService() { - if (integrationService == null) { - integrationService = (IntegrationService) WebApplicationContextUtils - .getRequiredWebApplicationContext(getServletContext()).getBean( - "integrationService"); - } - return integrationService; + private IntegrationService getService() { + if (integrationService == null) { + integrationService = (IntegrationService) WebApplicationContextUtils.getRequiredWebApplicationContext( + getServletContext()).getBean("integrationService"); } + return integrationService; + } } Index: lams_central/src/java/org/lamsfoundation/lams/webservice/xml/LessonManagerServlet.java =================================================================== diff -u -rbdd916337e3a48589da367f4c8b7705fe3197af2 -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_central/src/java/org/lamsfoundation/lams/webservice/xml/LessonManagerServlet.java (.../LessonManagerServlet.java) (revision bdd916337e3a48589da367f4c8b7705fe3197af2) +++ lams_central/src/java/org/lamsfoundation/lams/webservice/xml/LessonManagerServlet.java (.../LessonManagerServlet.java) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -10,6 +10,8 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Set; +import java.util.SortedMap; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -36,12 +38,20 @@ import org.lamsfoundation.lams.integration.security.Authenticator; import org.lamsfoundation.lams.integration.service.IntegrationService; import org.lamsfoundation.lams.integration.util.LoginRequestDispatcher; +import org.lamsfoundation.lams.learningdesign.Activity; +import org.lamsfoundation.lams.learningdesign.ActivityEvaluation; +import org.lamsfoundation.lams.learningdesign.ToolActivity; import org.lamsfoundation.lams.learningdesign.service.IExportToolContentService; import org.lamsfoundation.lams.lesson.LearnerProgress; import org.lamsfoundation.lams.lesson.Lesson; import org.lamsfoundation.lams.lesson.dto.LearnerProgressDTO; import org.lamsfoundation.lams.lesson.service.ILessonService; import org.lamsfoundation.lams.monitoring.service.IMonitoringService; +import org.lamsfoundation.lams.tool.OutputType; +import org.lamsfoundation.lams.tool.ToolOutput; +import org.lamsfoundation.lams.tool.ToolOutputDefinition; +import org.lamsfoundation.lams.tool.ToolSession; +import org.lamsfoundation.lams.tool.service.ILamsCoreToolService; import org.lamsfoundation.lams.usermanagement.Organisation; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.util.CentralConstants; @@ -68,6 +78,8 @@ private static IExportToolContentService exportService = null; + private static ILamsCoreToolService toolService = null; + /** * Constructor of the object. */ @@ -118,6 +130,7 @@ String method = request.getParameter(CentralConstants.PARAM_METHOD); String filePath = request.getParameter(CentralConstants.PARAM_FILEPATH); String progressUser = request.getParameter(CentralConstants.PARAM_PROGRESS_USER); + String outputsUser = request.getParameter("outputsUser"); String learnerIds = request.getParameter(CentralConstants.PARAM_LEARNER_IDS); String monitorIds = request.getParameter(CentralConstants.PARAM_MONITOR_IDS); @@ -196,6 +209,18 @@ element = document.createElement(CentralConstants.ELEM_LESSON); element.setAttribute(CentralConstants.ATTR_LESSON_ID, lsIdStr); + } else if (method.equals("toolOutputsAllUsers")) { + lsId = new Long(lsIdStr); + element = getToolOutputs(document, serverId, datetime, hashValue, username, lsId, courseId, false); + } else if (method.equals("authoredToolOutputsAllUsers")) { + lsId = new Long(lsIdStr); + element = getToolOutputs(document, serverId, datetime, hashValue, username, lsId, courseId, true); + } else if (method.equals("toolOutputsUser")) { + lsId = new Long(lsIdStr); + element = getToolOutputsForUser(document, serverId, datetime, hashValue, username, lsId, courseId, false, outputsUser); + } else if (method.equals("authoredToolOutputsUser")) { + lsId = new Long(lsIdStr); + element = getToolOutputsForUser(document, serverId, datetime, hashValue, username, lsId, courseId, true, outputsUser); } else { String msg = "Method :" + method + " is not recognised"; log.error(msg); @@ -330,20 +355,6 @@ LearnerProgress learnProg = (LearnerProgress) iterator.next(); LearnerProgressDTO learnerProgress = learnProg.getLearnerProgressData(); - //Iterator activities = learnProg.getLesson().getLearningDesign().getActivities().iterator(); - - //String currActivity = ""; - //while (activities.hasNext()) - //{ - // Activity act = (Activity)iterator.next(); - // - // if (learnerProgress.getCurrentActivityId() == ((Activity)iterator.next()).getActivityId()) - // { - // currActivity = act.getTitle(); - // break; - // } - //} - // get the username with the integration prefix removed String userNoPrefixName = learnerProgress.getUserName().substring(prefix.length() + 1); ExtUserUseridMap learnerMap = integrationService.getExtUserUseridMap(serverMap, userNoPrefixName); @@ -550,7 +561,7 @@ * Initialization of the servlet.
* * @throws ServletException - * if an error occure + * if an error occured */ public void init() throws ServletException { service = (IWorkspaceManagementService) WebApplicationContextUtils.getRequiredWebApplicationContext( @@ -568,6 +579,9 @@ exportService = (IExportToolContentService) WebApplicationContextUtils.getRequiredWebApplicationContext( getServletContext()).getBean("exportToolContentService"); + toolService = (ILamsCoreToolService) WebApplicationContextUtils.getRequiredWebApplicationContext( + getServletContext()).getBean("lamsCoreToolService"); + } private class AddUsersToLessonThread implements Runnable { @@ -690,4 +704,296 @@ } } + /** + * + * This method gets the tool outputs for an entire lesson and returns + * them in an XML format. + * + * @param document + * @param serverId + * @param hashValue + * @param username + * @param lsId + * @param courseID + * @param isAuthoredToolOutputs + * @throws Exception + * @return + */ + @SuppressWarnings("unchecked") + public Element getToolOutputs(Document document, String serverId, String datetime, String hashValue, + String username, Long lsId, String courseID, boolean isAuthoredToolOutputs) throws Exception { + try { + ExtServerOrgMap serverMap = integrationService.getExtServerOrgMap(serverId); + + // TODO: Un-comment once finished testing as well as the prefix stuff + //Authenticator.authenticate(serverMap, datetime, username, hashValue); + + // Get the lesson and activitied given an lsId + Lesson lesson = lessonService.getLesson(lsId); + Set activities = (Set) lesson.getLearningDesign().getActivities(); + + // Create the root node of the xml document + Element toolOutputsElement = document.createElement("ToolOutputs"); + + if (lesson != null) { + log.debug("Getting tool ouputs report for: " + lsId + ". With learning design: " + + lesson.getLearningDesign().getLearningDesignId()); + + toolOutputsElement.setAttribute(CentralConstants.ATTR_LESSON_ID, "" + lsId); + toolOutputsElement.setAttribute("name", lesson.getLessonName()); + + Iterator learnerIterator = lesson.getAllLearners().iterator(); + while (learnerIterator.hasNext()) { + User learner = (User) learnerIterator.next(); + toolOutputsElement.appendChild(getLearnerOutputsElement(document, learner, lesson, activities, isAuthoredToolOutputs)); + } + } else { + // TODO: handle this error instead of throwing an exception + log.debug("No lesson exists for: " + lsId + ". Cannot get tool outputs report."); + throw new Exception("Lesson with lessonID: " + lsId + " could not be found for learner progresses"); + } + + return toolOutputsElement; + + } catch (Exception e) { + log.error("Problem creating tool output report for lesson: " + lsId.toString(), e); + throw new Exception(e); + } + + } + + /** + * + * This method gets the tool outputs for a specific user in a lesson and + * returns them in XML format. + * + * @param document + * @param serverId + * @param hashValue + * @param username + * @param lsId + * @param courseID + * @param isAuthoredToolOutputs + * @param userId + * @throws Exception + * @return + */ + @SuppressWarnings("unchecked") + public Element getToolOutputsForUser(Document document, String serverId, String datetime, String hashValue, + String username, Long lsId, String courseID, boolean isAuthoredToolOutputs, String userStr) throws Exception { + try { + // Create the root node of the xml document + Element toolOutputsElement = document.createElement("ToolOutputs"); + + ExtServerOrgMap serverMap = integrationService.getExtServerOrgMap(serverId); + + // TODO: Un-comment once finished testing as well as the prefix stuff + //Authenticator.authenticate(serverMap, datetime, username, hashValue); + + ExtUserUseridMap userMap = integrationService.getExistingExtUserUseridMap(serverMap, userStr); + if (userMap != null) { + User learner = (User) userMap.getUser(); + + // Get the lesson and activitied given an lsId + Lesson lesson = lessonService.getLesson(lsId); + Set activities = (Set) lesson.getLearningDesign().getActivities(); + + if (lesson != null) { + log.debug("Getting tool ouputs report for: " + lsId + ". With learning design: " + + lesson.getLearningDesign().getLearningDesignId()); + + toolOutputsElement.setAttribute(CentralConstants.ATTR_LESSON_ID, "" + lsId); + toolOutputsElement.setAttribute("name", lesson.getLessonName()); + + toolOutputsElement.appendChild(getLearnerOutputsElement(document, learner, lesson, activities, isAuthoredToolOutputs)); + } + } else { + // TODO: handle this error instead of throwing an exception + log.debug("No user exists for: " + userStr + ". Cannot get tool outputs report."); + throw new Exception("No user exists for: " + userStr + ". Cannot get tool outputs report."); + } + + return toolOutputsElement; + + } catch (Exception e) { + log.error("Problem creating tool output report for lesson: " + lsId.toString(), e); + throw new Exception(e); + } + + } + + /** + * Gets the outputs for an activity for a specific learner and returns them + * in XML format + * + * @param document + * @param learner + * @param lesson + * @param activities + * @param isAuthoredToolOutputs + * @return + */ + private Element getLearnerOutputsElement(Document document, User learner, Lesson lesson, Set activities, + boolean isAuthoredToolOutputs) { + Element learnerElement = document.createElement("LearnerOutput"); + //String userNoPrefixName = learner.getLogin().substring(serverMap.getPrefix().length() + 1); + learnerElement.setAttribute("userName", learner.getLogin()); + learnerElement.setAttribute("lamsUserName", learner.getLogin()); + learnerElement.setAttribute("lamsUserId", learner.getUserId().toString()); + learnerElement.setAttribute("firstName", learner.getFirstName()); + learnerElement.setAttribute("lastName", learner.getLastName()); + + LearnerProgress learnerProgress = monitoringService.getLearnerProgress(learner.getUserId(), lesson + .getLessonId()); + + if (learnerProgress != null) + { + learnerElement.setAttribute("completedLesson", "" + learnerProgress.isComplete()); + } + + /* + * Hibernate CGLIB is failing to load the first activity in + * the sequence as a ToolActivity for some mysterious reason + * Causes a ClassCastException when you try to cast it, even + * if it is a ToolActivity. + * + * THIS IS A HACK to retrieve the first tool activity + * manually so it can be cast as a ToolActivity + */ + Activity firstActivity = monitoringService.getActivityById(lesson.getLearningDesign().getFirstActivity() + .getActivityId()); + log.debug("Getting tool ouputs for first activity: " + firstActivity.getActivityId() + ". For user: " + + learner.getUserId()); + if (firstActivity.isToolActivity() && firstActivity instanceof ToolActivity) { + learnerElement.appendChild(getActivityOutputsElement(document, (ToolActivity) firstActivity, learner, + learnerProgress, isAuthoredToolOutputs)); + } + + for (Activity activity : activities) { + + if (activity.getActivityId().longValue() != firstActivity.getActivityId().longValue()) { + + log.debug("Getting tool ouputs for activity: " + activity.getActivityId() + ". For user: " + + learner.getUserId()); + + if (activity.isToolActivity() && activity instanceof ToolActivity) { + + learnerElement.appendChild(getActivityOutputsElement(document, (ToolActivity) activity, learner, + learnerProgress, isAuthoredToolOutputs)); + } + } + } + return learnerElement; + } + + /** + * Gets the tool output for a specified activity and learner and returns an + * XML representation of the data + * + * @param document + * @param toolAct + * @param learner + * @param progress + * @param isAuthoredToolOutputs + * @return + */ + private Element getActivityOutputsElement(Document document, ToolActivity toolAct, User learner, + LearnerProgress progress, boolean isAuthoredToolOutputs) { + Element activityElement = document.createElement("Activity"); + activityElement.setAttribute("title", toolAct.getTitle()); + activityElement.setAttribute("activityId", toolAct.getActivityId().toString()); + if (toolAct.getOrderId() != null) { + activityElement.setAttribute("orderId", toolAct.getOrderId().toString()); + } + + boolean activityAttempted = false; + if (progress != null) { + boolean completed = (progress.getProgressState(toolAct) == LearnerProgress.ACTIVITY_COMPLETED); + activityElement.setAttribute("completed", "" + completed); + + activityAttempted = completed || (progress.getProgressState(toolAct) == LearnerProgress.ACTIVITY_ATTEMPTED); + activityElement.setAttribute("attempted", "" + activityAttempted); + + } else { + activityElement.setAttribute("attempted", "" + false); + activityElement.setAttribute("completed", "" + false); + } + + if (activityAttempted) { + ToolSession toolSession = toolService.getToolSessionByLearner(learner, toolAct); + SortedMap map = toolService.getOutputDefinitionsFromTool(toolAct + .getToolContentId()); + + if (toolSession != null) { + + for (String outputName : map.keySet()) { + + try { + + if (isAuthoredToolOutputs) { + Set activityEvaluations = toolAct.getActivityEvaluations(); + if (activityEvaluations != null) { + for (ActivityEvaluation evaluation : activityEvaluations) { + if (outputName.equals(evaluation.getToolOutputDefinition())) { + ToolOutput toolOutput = toolService.getOutputFromTool(outputName, toolSession, + learner.getUserId()); + activityElement.appendChild(getOutputElement(document, toolOutput)); + } + } + } + } else { + ToolOutput toolOutput = toolService.getOutputFromTool(outputName, toolSession, learner + .getUserId()); + + if (toolOutput != null) { + activityElement.appendChild(getOutputElement(document, toolOutput)); + + } + + } + + } catch (RuntimeException e) { + log.debug("Runtime exception when attempted to get outputs for activity: " + + toolAct.getActivityId() + ", continuing for other activities", e); + } + } + + } + } + return activityElement; + } + + /** + * Returns an XML element containing the tool output data for one instance + * + * @param document + * @param toolOutput + * @return + */ + private Element getOutputElement(Document document, ToolOutput toolOutput) { + Element toolOutputElement = document.createElement("ToolOutput"); + toolOutputElement.setAttribute("name", toolOutput.getName()); + toolOutputElement.setAttribute("description", toolOutput.getDescription()); + toolOutputElement.setAttribute("output", toolOutput.getValue().getString()); + + String type; + OutputType outputType = toolOutput.getValue().getType(); + + if (outputType == OutputType.OUTPUT_BOOLEAN) { + type = "boolean"; + } else if (outputType == OutputType.OUTPUT_COMPLEX){ + type = "complex"; + } else if (outputType == OutputType.OUTPUT_DOUBLE){ + type = "double"; + } else if (outputType == OutputType.OUTPUT_LONG){ + type = "long"; + } else if (outputType == OutputType.OUTPUT_SET_BOOLEAN){ + type = "set_boolean"; + } else { + type = "string"; + } + + toolOutputElement.setAttribute("type", type); + return toolOutputElement; + } } Index: lams_common/build.xml =================================================================== diff -u -r00a6e145b37916eb1561ea5c68319b0fc691681b -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_common/build.xml (.../build.xml) (revision 00a6e145b37916eb1561ea5c68319b0fc691681b) +++ lams_common/build.xml (.../build.xml) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -400,6 +400,23 @@ + + + + + + + + + + + + + + + + + Index: lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/learningdesign/Activity.hbm.xml =================================================================== diff -u -rd3b9b5d94b98da06dcce673877406d8e580a114e -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/learningdesign/Activity.hbm.xml (.../Activity.hbm.xml) (revision d3b9b5d94b98da06dcce673877406d8e580a114e) +++ lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/learningdesign/Activity.hbm.xml (.../Activity.hbm.xml) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -161,6 +161,15 @@ + + + @hibernate.set lazy="false" inverse="true" cascade="none" + @hibernate.collection-key column="activity_evaluation_id" + @hibernate.collection-one-to-many class="org.lamsfoundation.lams.evaluation.model.ActivityEvaluation" + + + + @hibernate.set lazy="false" inverse="true" cascade="none" Index: lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/learningdesign/ActivityEvaluation.hbm.xml =================================================================== diff -u --- lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/learningdesign/ActivityEvaluation.hbm.xml (revision 0) +++ lams_common/conf/hibernate/mappings/org/lamsfoundation/lams/learningdesign/ActivityEvaluation.hbm.xml (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + Index: lams_common/db/sql/create_lams_11_tables.sql =================================================================== diff -u -rc4bbe0b084234edffd2c0c43dce7d7b1fbf14863 -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_common/db/sql/create_lams_11_tables.sql (.../create_lams_11_tables.sql) (revision c4bbe0b084234edffd2c0c43dce7d7b1fbf14863) +++ lams_common/db/sql/create_lams_11_tables.sql (.../create_lams_11_tables.sql) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -1090,4 +1090,14 @@ UNIQUE KEY (parent_uid, order_id), CONSTRAINT FK_lams_planner_node_parent FOREIGN KEY (parent_uid) REFERENCES lams_planner_nodes(uid) ON DELETE CASCADE ON UPDATE CASCADE -)TYPE=InnoDB; \ No newline at end of file +)TYPE=InnoDB; + +CREATE TABLE lams_activity_evaluation ( + activity_evaluation_id BIGINT(20) NOT NULL auto_increment + , activity_id BIGINT(20) NOT NULL + , tool_output_definition VARCHAR(255) NOT NULL + , INDEX (activity_id) + , CONSTRAINT FK_lams_activity_evaluation_1 FOREIGN KEY (activity_id) + REFERENCES lams_learning_activity (activity_id) ON DELETE CASCADE ON UPDATE CASCADE + , PRIMARY KEY (activity_evaluation_id) +)TYPE=InnoDB; \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/commonContext.xml =================================================================== diff -u -r00a6e145b37916eb1561ea5c68319b0fc691681b -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_common/src/java/org/lamsfoundation/lams/commonContext.xml (.../commonContext.xml) (revision 00a6e145b37916eb1561ea5c68319b0fc691681b) +++ lams_common/src/java/org/lamsfoundation/lams/commonContext.xml (.../commonContext.xml) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -48,8 +48,8 @@ classpath:org/lamsfoundation/lams/learningdesign/LearningLibrary.hbm.xml classpath:org/lamsfoundation/lams/learningdesign/Transition.hbm.xml classpath:org/lamsfoundation/lams/learningdesign/License.hbm.xml + classpath:org/lamsfoundation/lams/learningdesign/ActivityEvaluation.hbm.xml - classpath:org/lamsfoundation/lams/lesson/LearnerProgress.hbm.xml classpath:org/lamsfoundation/lams/lesson/Lesson.hbm.xml Index: lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch0015_updateFrom22.sql =================================================================== diff -u -rc697b5c30ab742ab453859355b35cd518856334f -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch0015_updateFrom22.sql (.../patch0015_updateFrom22.sql) (revision c697b5c30ab742ab453859355b35cd518856334f) +++ lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch0015_updateFrom22.sql (.../patch0015_updateFrom22.sql) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -60,6 +60,17 @@ -- LDEV-2115 -------------- ALTER TABLE lams_progress_completed ADD COLUMN completed_date_time DATETIME NOT NULL; +-- LDEV-2163 -------------- +CREATE TABLE lams_activity_evaluation ( + activity_evaluation_id BIGINT(20) NOT NULL auto_increment + , activity_id BIGINT(20) NOT NULL + , tool_output_definition VARCHAR(255) NOT NULL + , INDEX (activity_id) + , CONSTRAINT FK_lams_activity_evaluation_1 FOREIGN KEY (activity_id) + REFERENCES lams_learning_activity (activity_id) ON DELETE CASCADE ON UPDATE CASCADE + , PRIMARY KEY (activity_evaluation_id) +)TYPE=InnoDB; + ----------------------Put all sql statements above here------------------------- -- If there were no errors, commit and restore autocommit to on Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/ActivityEvaluation.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/ActivityEvaluation.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/ActivityEvaluation.java (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -0,0 +1,83 @@ +/**************************************************************** + * Copyright (C) 2008 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.learningdesign; + +/** + * This is a POJO bean object for an evaluation criteria for a given activity. + * This object exists at the learning design level. Ie it can be designed, + * copied and exported in author. + * + * @author lfoxton + * + * + * @hibernate.class table="lams_activity_evaluation" + */ +public class ActivityEvaluation { + + private Long uid; + private Activity activity; + private String toolOutputDefinition; + + public ActivityEvaluation() { + super(); + // TODO Auto-generated constructor stub + } + + /** + * @hibernate.id generator-class="native" type="java.lang.Long" column="activity_evaluation_id" + */ + public Long getUid() { + return uid; + } + + public void setUid(Long uid) { + this.uid = uid; + } + + /** + * @hibernate.many-to-one cascade="save-update" + * class="org.lamsfoundation.lams.learningdesign.ToolActivity" + * column="activity_id" not-null="true" + */ + public Activity getActivity() { + return activity; + } + + public void setActivity(Activity activity) { + this.activity = activity; + } + + /** + * @hibernate.property column="tool_output_definition" length="255" + */ + public String getToolOutputDefinition() { + return toolOutputDefinition; + } + + public void setToolOutputDefinition(String toolOutputDefinition) { + this.toolOutputDefinition = toolOutputDefinition; + } + + +} Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/Competence.java =================================================================== diff -u -rfdbf7a3cfb10831b1ac581efa42807d3207a71ff -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/Competence.java (.../Competence.java) (revision fdbf7a3cfb10831b1ac581efa42807d3207a71ff) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/Competence.java (.../Competence.java) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -1,70 +1,72 @@ package org.lamsfoundation.lams.learningdesign; -/** +import org.lamsfoundation.lams.learningdesign.dto.CompetenceDTO; + +/** * * @hibernate.class table="lams_competence" */ public class Competence { - - private Long competenceId; - private LearningDesign learningDesign; - private String title; - private String description; - - public Competence() {} - - - /** - * @hibernate.id generator-class="native" type="java.lang.Long" - * column="competence_id" + + private Long competenceId; + private LearningDesign learningDesign; + private String title; + private String description; + + public Competence() { + } + + /** + * @hibernate.id generator-class="native" type="java.lang.Long" + * column="competence_id" */ public Long getCompetenceId() { - return this.competenceId; + return this.competenceId; } + public void setCompetenceId(Long competenceId) { - this.competenceId = competenceId; + this.competenceId = competenceId; } - /** - * @hibernate.property column="title" length="255" - * not-null="true" + /** + * @hibernate.property column="title" length="255" not-null="true" */ - public String getTitle() { - return title; - } - public void setTitle(String title) { - this.title = title; - } - - /** - * @hibernate.property column="description" length="65535" - * not-null="false" + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + /** + * @hibernate.property column="description" length="65535" not-null="false" */ - public String getDescription() { - return description; - } - public void setDescription(String description) { - this.description = description; - } - - /** - * @hibernate.many-to-one not-null="true" - * @hibernate.column name="learning_design_id" - * - */ - public org.lamsfoundation.lams.learningdesign.LearningDesign getLearningDesign() { - return this.learningDesign; - } + public String getDescription() { + return description; + } - public void setLearningDesign( - org.lamsfoundation.lams.learningdesign.LearningDesign learningDesign) { - this.learningDesign = learningDesign; - } - - public Competence createCopy(Competence originalCompetence) { - Competence newCompetence = new Competence(); - newCompetence.setTitle(originalCompetence.getTitle()); - newCompetence.setDescription(originalCompetence.getDescription()); - return newCompetence; - } + public void setDescription(String description) { + this.description = description; + } + + /** + * @hibernate.many-to-one not-null="true" + * @hibernate.column name="learning_design_id" + * + */ + public org.lamsfoundation.lams.learningdesign.LearningDesign getLearningDesign() { + return this.learningDesign; + } + + public void setLearningDesign(org.lamsfoundation.lams.learningdesign.LearningDesign learningDesign) { + this.learningDesign = learningDesign; + } + + public Competence createCopy(Competence originalCompetence) { + Competence newCompetence = new Competence(); + newCompetence.setTitle(originalCompetence.getTitle()); + newCompetence.setDescription(originalCompetence.getDescription()); + return newCompetence; + } } Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/ToolActivity.java =================================================================== diff -u -r9a772f5ba1954a3a719a19e7ae237b6b09dc76ef -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/ToolActivity.java (.../ToolActivity.java) (revision 9a772f5ba1954a3a719a19e7ae237b6b09dc76ef) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/ToolActivity.java (.../ToolActivity.java) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -32,6 +32,7 @@ import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.log4j.Logger; +import org.lamsfoundation.lams.learningdesign.ActivityEvaluation; import org.lamsfoundation.lams.learningdesign.strategy.ToolActivityStrategy; import org.lamsfoundation.lams.lesson.Lesson; import org.lamsfoundation.lams.lesson.LessonClass; @@ -59,20 +60,23 @@ private Set toolSessions; private Set competenceMappings; + + private Set activityEvaluations; /** full constructor */ public ToolActivity(Long activityId, Integer id, String description, String title, Integer xcoord, Integer ycoord, Integer orderId, Boolean defineLater, java.util.Date createDateTime, LearningLibrary learningLibrary, Activity parentActivity, Activity libraryActivity, Integer parentUIID, LearningDesign learningDesign, Grouping grouping, Integer activityTypeId, Transition transitionTo, Transition transitionFrom, String languageFile, Boolean stopAfterActivity, Set inputActivities, Tool tool, Long toolContentId, - Set branchActivityEntries, Set competenceMappings) { + Set branchActivityEntries, Set competenceMappings, Set activityEvaluations) { super(activityId, id, description, title, xcoord, ycoord, orderId, defineLater, createDateTime, learningLibrary, parentActivity, libraryActivity, parentUIID, learningDesign, grouping, activityTypeId, transitionTo, transitionFrom, languageFile, stopAfterActivity, inputActivities, branchActivityEntries); this.tool = tool; this.toolContentId = toolContentId; this.competenceMappings = competenceMappings; + this.activityEvaluations = activityEvaluations; super.simpleActivityStrategy = new ToolActivityStrategy(this); } @@ -96,7 +100,8 @@ } /** - * Makes a copy of the ToolActivity for authoring, preview and monitoring enviornment + * Makes a copy of the ToolActivity for authoring, preview and monitoring + * environment * * @return ToolActivity Returns a deep-copy of the originalActivity */ @@ -107,36 +112,49 @@ newToolActivity.setTool(this.getTool()); newToolActivity.setToolContentId(this.getToolContentId()); - Set newCompetenceMappings = new HashSet(); - if (competenceMappings != null) { - for (CompetenceMapping compMap : competenceMappings) { - CompetenceMapping newComp = new CompetenceMapping(); - newComp.setCompetence(compMap.getCompetence()); - newComp.setToolActivity(compMap.getToolActivity()); - newCompetenceMappings.add(compMap); - } + Set newCompetenceMappings = new HashSet(); + for (CompetenceMapping compMap : this.competenceMappings) { + CompetenceMapping newComp = new CompetenceMapping(); + newComp.setCompetence(compMap.getCompetence()); + newComp.setToolActivity(compMap.getToolActivity()); + newCompetenceMappings.add(compMap); } newToolActivity.setCompetenceMappings(newCompetenceMappings); + + Set newEvaluations = new HashSet(); + for (ActivityEvaluation evaluation : this.activityEvaluations) + { + ActivityEvaluation newEvaluation = new ActivityEvaluation(); + newEvaluation.setActivity(newToolActivity); + newEvaluation.setToolOutputDefinition(evaluation.getToolOutputDefinition()); + newEvaluations.add(newEvaluation); + } + newToolActivity.setActivityEvaluations(newEvaluations); return newToolActivity; } /** - * Factory method to create a new tool session for a single user when he is running current activity. Does not check - * to see if a tool session already exists. + * Factory method to create a new tool session for a single user when he is + * running current activity. Does not check to see if a tool session already + * exists. *

- * If the activity has groupingSupportType = GROUPING_SUPPORT_NONE then a new tool session is created for each - * learner. + * If the activity has groupingSupportType = GROUPING_SUPPORT_NONE then a + * new tool session is created for each learner. *

- * If the activity has groupingSupportType = GROUPING_SUPPORT_REQUIRED then a new tool session is created for each - * group of learners. It will fall back to a class group if no grouping is found - the user interface should not - * have allowed this! + * If the activity has groupingSupportType = GROUPING_SUPPORT_REQUIRED then + * a new tool session is created for each group of learners. It will fall + * back to a class group if no grouping is found - the user interface should + * not have allowed this! *

- * If the activity has groupingSupportType = GROUPING_SUPPORT_OPTIONAL then a new tool session is created for each - * group of learners. If no grouping is available then a whole of class group is created. + * If the activity has groupingSupportType = GROUPING_SUPPORT_OPTIONAL then + * a new tool session is created for each group of learners. If no grouping + * is available then a whole of class group is created. *

- * If groupingSupportType is not set then defaults to GROUPING_SUPPORT_NONE. If for some reason a grouped session if - * also does the equivalent of GROUPING_SUPPORT_NONE. This way the system will still function, if not as expected! + * If groupingSupportType is not set then defaults to GROUPING_SUPPORT_NONE. + * If for some reason a grouped session if also does the equivalent of + * GROUPING_SUPPORT_NONE. This way the system will still function, if not as + * expected! *

* * @param learner @@ -149,16 +167,16 @@ ToolSession session = null; if (supportType != null - && (supportType.intValue() == Activity.GROUPING_SUPPORT_REQUIRED || supportType.intValue() == Activity.GROUPING_SUPPORT_OPTIONAL)) { + && (supportType.intValue() == GROUPING_SUPPORT_REQUIRED || supportType.intValue() == GROUPING_SUPPORT_OPTIONAL)) { // Both cases create a small group if a grouping exists, otherwise creates a class group. Group learners = null; if (getApplyGrouping().booleanValue()) { learners = this.getGroupFor(learner); } - if (supportType.intValue() == Activity.GROUPING_SUPPORT_REQUIRED && learners == null) { - ToolActivity.log + if (supportType.intValue() == GROUPING_SUPPORT_REQUIRED && learners == null) { + log .error("Activity " + getActivityId() + " requires grouping (groupingSupportType=GROUPING_SUPPORT_REQUIRED) but no grouping was available. " @@ -174,16 +192,15 @@ if (learners != null && !learners.isNull()) { session = new GroupedToolSession(this, now, ToolSession.STARTED_STATE, learners, lesson); } else { - ToolActivity.log + log .error("Unable to get the group for a new tool session for Activity " + getActivityId() + " Falling back to one learner per session." + " Learner " + learner + ", lesson is " + lesson); } } if (session == null) { - // Either GROUPING_SUPPORT_NONE was selected, supportType == null or the grouped tool sessions could not be - // created. + // Either GROUPING_SUPPORT_NONE was selected, supportType == null or the grouped tool sessions could not be created. // So create one session per user. session = new NonGroupedToolSession(this, now, ToolSession.STARTED_STATE, learner, lesson); } @@ -203,7 +220,7 @@ */ public Long getToolContentId() { - return toolContentId; + return this.toolContentId; } /** @@ -224,7 +241,7 @@ */ public Tool getTool() { - return tool; + return this.tool; } /** @@ -280,12 +297,23 @@ } /** - * Get all the tool activities in this activity. Called by Activity.getAllToolActivities() As we are a tool - * activity, just add ourself. + * Get all the tool activities in this activity. Called by + * Activity.getAllToolActivities() As we are a tool activity, just add + * ourself. */ @Override protected void getToolActivitiesInActivity(SortedSet toolActivities) { toolActivities.add(this); } + public Set getActivityEvaluations() { + return activityEvaluations; + } + + public void setActivityEvaluations(Set activityEvaluations) { + this.activityEvaluations = activityEvaluations; + } + + + } Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/dto/AuthoringActivityDTO.java =================================================================== diff -u -rd3b9b5d94b98da06dcce673877406d8e580a114e -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/dto/AuthoringActivityDTO.java (.../AuthoringActivityDTO.java) (revision d3b9b5d94b98da06dcce673877406d8e580a114e) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/dto/AuthoringActivityDTO.java (.../AuthoringActivityDTO.java) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -28,6 +28,7 @@ import java.util.Iterator; import java.util.Set; +import org.lamsfoundation.lams.learningdesign.ActivityEvaluation; import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.learningdesign.BranchActivityEntry; import org.lamsfoundation.lams.learningdesign.BranchingActivity; @@ -246,6 +247,8 @@ /** List of the UIIDs of the activities that are input activities for this activity */ private Integer toolActivityUIID; + + private ArrayList activityEvaluations; /** * Used by a sequence activity to determine the start of the transition based sequence and used by tool based @@ -414,6 +417,14 @@ competenceMappingTitles.add(competenceMappingTitle); } } + + activityEvaluations = new ArrayList(); + if (toolActivity.getActivityEvaluations() != null){ + for(ActivityEvaluation eval : toolActivity.getActivityEvaluations()) + { + activityEvaluations.add(eval.getToolOutputDefinition()); + } + } } private void addGateActivityAttributes(Object activity, ArrayList branchMappings) { @@ -1329,4 +1340,12 @@ public void setCompetenceMappingTitles(ArrayList competenceMappingTitles) { this.competenceMappingTitles = competenceMappingTitles; } + + public ArrayList getActivityEvaluations() { + return activityEvaluations; + } + + public void setActivityEvaluations(ArrayList activityEvaluations) { + this.activityEvaluations = activityEvaluations; + } } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/dto/LearningDesignDTO.java =================================================================== diff -u -rcc236819430d4acdecf4f5f77416bcf0df71777a -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/dto/LearningDesignDTO.java (.../LearningDesignDTO.java) (revision cc236819430d4acdecf4f5f77416bcf0df71777a) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/dto/LearningDesignDTO.java (.../LearningDesignDTO.java) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -32,13 +32,9 @@ import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.learningdesign.ActivityDTOOrderComparator; -import org.lamsfoundation.lams.learningdesign.BranchActivityEntry; import org.lamsfoundation.lams.learningdesign.Competence; -import org.lamsfoundation.lams.learningdesign.Group; import org.lamsfoundation.lams.learningdesign.Grouping; -import org.lamsfoundation.lams.learningdesign.GroupingActivity; import org.lamsfoundation.lams.learningdesign.LearningDesign; -import org.lamsfoundation.lams.learningdesign.SequenceActivity; import org.lamsfoundation.lams.learningdesign.Transition; import org.lamsfoundation.lams.learningdesign.dao.hibernate.ActivityDAO; import org.lamsfoundation.lams.learningdesign.dao.hibernate.GroupingDAO; @@ -87,7 +83,7 @@ private ArrayList activities; private ArrayList transitions; private ArrayList branchMappings; - private ArrayList competences; + private ArrayList competences; public LearningDesignDTO() { } @@ -133,7 +129,7 @@ this.activities = new ArrayList(); this.transitions = new ArrayList(); this.branchMappings = new ArrayList(); - this.competences = new ArrayList(); + this.competences = new ArrayList(); } public LearningDesignDTO(LearningDesign learningDesign, ActivityDAO activityDAO, GroupingDAO groupingDAO, @@ -459,7 +455,7 @@ return transitions; } - public ArrayList populateCompetences(LearningDesign design) { + public ArrayList populateCompetences(LearningDesign design) { ArrayList competenceDTOs = new ArrayList(); if (design.getCompetences() != null) { Iterator iterator = design.getCompetences().iterator(); @@ -802,11 +798,11 @@ this.branchMappings = branchMappings; } - public ArrayList getCompetences() { + public ArrayList getCompetences() { return competences; } - public void setCompetences(ArrayList competences) { + public void setCompetences(ArrayList competences) { this.competences = competences; } Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/ExportToolContentService.java =================================================================== diff -u -r9a772f5ba1954a3a719a19e7ae237b6b09dc76ef -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/ExportToolContentService.java (.../ExportToolContentService.java) (revision 9a772f5ba1954a3a719a19e7ae237b6b09dc76ef) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/service/ExportToolContentService.java (.../ExportToolContentService.java) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -76,12 +76,15 @@ import org.lamsfoundation.lams.contentrepository.RepositoryCheckedException; import org.lamsfoundation.lams.contentrepository.client.IToolContentHandler; import org.lamsfoundation.lams.dao.IBaseDAO; +import org.lamsfoundation.lams.learningdesign.ActivityEvaluation; import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.learningdesign.ActivityOrderComparator; import org.lamsfoundation.lams.learningdesign.BranchActivityEntry; import org.lamsfoundation.lams.learningdesign.BranchCondition; import org.lamsfoundation.lams.learningdesign.BranchingActivity; import org.lamsfoundation.lams.learningdesign.ChosenGrouping; +import org.lamsfoundation.lams.learningdesign.Competence; +import org.lamsfoundation.lams.learningdesign.CompetenceMapping; import org.lamsfoundation.lams.learningdesign.ComplexActivity; import org.lamsfoundation.lams.learningdesign.ConditionGateActivity; import org.lamsfoundation.lams.learningdesign.Group; @@ -107,6 +110,7 @@ import org.lamsfoundation.lams.learningdesign.dto.AuthoringActivityDTO; import org.lamsfoundation.lams.learningdesign.dto.BranchActivityEntryDTO; import org.lamsfoundation.lams.learningdesign.dto.BranchConditionDTO; +import org.lamsfoundation.lams.learningdesign.dto.CompetenceDTO; import org.lamsfoundation.lams.learningdesign.dto.GroupDTO; import org.lamsfoundation.lams.learningdesign.dto.GroupingDTO; import org.lamsfoundation.lams.learningdesign.dto.LearningDesignDTO; @@ -489,8 +493,8 @@ } /** - * This class is just for later system extent tool compaiblity strategy use. Currently, it just simple to get tool - * by same signature. + * This class is just for later system extent tool compaiblity strategy use. + * Currently, it just simple to get tool by same signature. * * @author Steve.Ni * @@ -885,9 +889,10 @@ } /** - * Generate the nodes for a property and the related conditions. The first element is the property, which goes in - * the tag, the second through fourth elements are the if-then-else that makes up the condition and - * goes in the tag. + * Generate the nodes for a property and the related conditions. The first + * element is the property, which goes in the tag, the second + * through fourth elements are the if-then-else that makes up the condition + * and goes in the tag. * * @param activityId * @return @@ -1046,8 +1051,9 @@ } /** - * Move LAMS tool.xml from tool folder to export content root folder and modify it to {toolContentID}.xml file. - * Cache all attachement files from this tool into ArrayList, which will be save into a temporary file + * Move LAMS tool.xml from tool folder to export content root folder and + * modify it to {toolContentID}.xml file. Cache all attachement files from + * this tool into ArrayList, which will be save into a temporary file * (resources.xml) and used by XSLT. * * @param rootDir @@ -1234,8 +1240,9 @@ } /** - * Import the learning design from the given path. Set the importer as the creator. If the workspaceFolderUid is - * null then saves the design in the user's own workspace folder. + * Import the learning design from the given path. Set the importer as the + * creator. If the workspaceFolderUid is null then saves the design in the + * user's own workspace folder. * * @param designFile * @param importer @@ -1889,6 +1896,15 @@ // persist act.setActivityId(null); activityDAO.insert(act); + + // Once the activity is saved, we can import the ActivityEvaluations + for (String toolOutputDefinition : actDto.getActivityEvaluations()) + { + ActivityEvaluation activityEvaluation = new ActivityEvaluation(); + activityEvaluation.setToolOutputDefinition(toolOutputDefinition); + activityEvaluation.setActivity(act); + baseDAO.insertOrUpdate(activityEvaluation); + } } // Process the "first child" for any sequence activities and the @@ -2001,6 +2017,47 @@ // leave it to learning design to save it. // transitionDAO.insert(trans); } + + // Once the learning design is saved, we can import the competences + Set competenceList = new HashSet(); + for (CompetenceDTO competenceDTO : dto.getCompetences()){ + Competence competence = new Competence(); + competence.setDescription(competenceDTO.getDescription()); + competence.setTitle(competenceDTO.getTitle()); + competenceList.add(competence); + } + + // TODO: Save competence mappings on import. +// for (AuthoringActivityDTO actDto : actDtoList) +// { +// if (removedActMap.containsKey(actDto.getActivityID())) { +// continue; +// } +// if (actDto.getIisToolActivity()) +// { +// for (Activity act : actList) +// { +// Set competenceMappings = new HashSet(); +// CompetenceMapping competenceMapping = new CompetenceMapping(); +// for(Competence competence : competenceList) +// { +// for (String comptenceMappingStr : actDto.getCompetenceMappingTitles()) +// { +// if (competence.getTitle() == comptenceMappingStr) +// { +// if (activityMapper.get(actDto.getActivityID()).getActivityId() == act.getActivityId() ) +// { +// competenceMapping.setToolActivity((ToolActivity)act); +// competenceMapping.setCompetence(competence); +// break; +// } +// } +// } +// } +// ((ToolActivity)activityMapper.get(actDto.getActivityID())).setCompetenceMappings(competenceMappings); +// } +// } +// } // branch mappings - maps groups to branches, map conditions to branches List entryDtoList = dto.getBranchMappings(); @@ -2011,9 +2068,9 @@ entryList.add(entry); } } + + LearningDesign ld = getLearningDesign(dto, importer, folder, actList, transList, activityMapper, competenceList); - LearningDesign ld = getLearningDesign(dto, importer, folder, actList, transList, activityMapper); - // validate learning design Vector listOfValidationErrorDTOs = getLearningDesignService().validateLearningDesign(ld); if (listOfValidationErrorDTOs.size() > 0) { @@ -2029,6 +2086,24 @@ // persist learningDesignDAO.insert(ld); + + + + + // Once we have the competences saved, we can save the competence mappings +// for (AuthoringActivityDTO actDto : actDtoList) { +// for (String competenceMappingStr : actDto.getActivityEvaluations()) { +// +// CompetenceMapping competenceMapping = new CompetenceMapping(); +// ActivityEvaluation activityEvaluation = new ActivityEvaluation(); +// activityEvaluation.setToolOutputDefinition(toolOutputDefinition); +// activityEvaluation.setActivity(act); +// activityEvaluation.setActivityEvaluationSessions(new HashSet()); +// baseDAO.insertOrUpdate(activityEvaluation); +// } +// } + + return ld.getLearningDesignId(); } @@ -2076,7 +2151,8 @@ } /** - * Get learning design object from this Learning design DTO object. It also following our import rules: + * Get learning design object from this Learning design DTO object. It also + * following our import rules: *

  • lams_license - Assume same in all lams system. Import same ID
  • *
  • lams_copy_type - Set to 1.This indicates it is "normal" design.
  • *
  • lams_workspace_folder - An input parameters to let user choose import workspace
  • @@ -2089,8 +2165,8 @@ * @throws ImportToolContentException */ private LearningDesign getLearningDesign(LearningDesignDTO dto, User importer, WorkspaceFolder folder, - Set actList, Set transList, Map activityMapper) - throws ImportToolContentException { + Set actList, Set transList, Map activityMapper, + Set competenceList) throws ImportToolContentException { LearningDesign ld = new LearningDesign(); if (dto == null) { @@ -2152,6 +2228,12 @@ } ld.setTransitions(transList); + // set learning design competences + for (Competence competence : competenceList) { + competence.setLearningDesign(ld); + } + ld.setCompetences(competenceList); + for (Activity act : actList) { act.setLearningDesign(ld); } @@ -2228,12 +2310,14 @@ } /** - * Creates the map entry between a branch sequence activity and a group. We need the group maps and the activity - * maps so that we can update the ids to the groups and the activities. Therefore this method must be done after all - * the groups are imported and the activities are imported. + * Creates the map entry between a branch sequence activity and a group. We + * need the group maps and the activity maps so that we can update the ids + * to the groups and the activities. Therefore this method must be done + * after all the groups are imported and the activities are imported. * - * Note: there isn't an set in the learning design for the branch mappings. The group objects actually contain the - * link to the mappings, so this method updates the group objects. + * Note: there isn't an set in the learning design for the branch mappings. + * The group objects actually contain the link to the mappings, so this + * method updates the group objects. */ private BranchActivityEntry getBranchActivityEntry(BranchActivityEntryDTO entryDto, Map groupByUIIDMapper, Map activityByUIIDMapper) { Index: lams_common/src/java/org/lamsfoundation/lams/tool/ToolSession.java =================================================================== diff -u -r920894ca746cba5e080023c5cc80167d64d1653d -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_common/src/java/org/lamsfoundation/lams/tool/ToolSession.java (.../ToolSession.java) (revision 920894ca746cba5e080023c5cc80167d64d1653d) +++ lams_common/src/java/org/lamsfoundation/lams/tool/ToolSession.java (.../ToolSession.java) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -34,19 +34,17 @@ import org.lamsfoundation.lams.lesson.Lesson; import org.lamsfoundation.lams.usermanagement.User; - -/** - * @hibernate.class - * table="lams_tool_session" - * -*/ +/** + * @hibernate.class table="lams_tool_session" + * + */ public abstract class ToolSession implements Serializable { - + /** Tool session type id for grouped */ public static final int GROUPED_TYPE = 1; /** Tool session type id for non-grouped - all learners in a separate session */ public static final int NON_GROUPED_TYPE = 2; - + /** Tool session state id for started tool session */ public static final int STARTED_STATE = 1; /** Tool session state id for completed tool session */ @@ -55,10 +53,10 @@ public static final String UNIQUE_KEY_PREFIX = "uq"; /** identifier field */ private Long toolSessionId; - - /** Persistent field **/ + + /** Persistent field * */ private String toolSessionName; - + /** persistent field */ private ToolActivity toolActivity; @@ -67,144 +65,136 @@ /** persistent field */ private int toolSessionStateId; - + private String uniqueKey; - + private Lesson lesson; /** Get all the learners who may be part of this tool session. */ - public abstract Set getLearners(); + public abstract Set getLearners(); /** full constructor */ - public ToolSession(Long toolSessionId, - ToolActivity toolActivity, - Date createDateTime, - int toolSessionStateId, - Lesson lesson) { - this.toolSessionId = toolSessionId; - this.toolActivity = toolActivity; - this.createDateTime = createDateTime; - this.toolSessionStateId = toolSessionStateId; - this.lesson = lesson; + public ToolSession(Long toolSessionId, ToolActivity toolActivity, Date createDateTime, int toolSessionStateId, + Lesson lesson) { + this.toolSessionId = toolSessionId; + this.toolActivity = toolActivity; + this.createDateTime = createDateTime; + this.toolSessionStateId = toolSessionStateId; + this.lesson = lesson; } /** default constructor */ public ToolSession() { } - /** - * @hibernate.id - * generator-class="native" - * type="java.lang.Long" - * column="tool_session_id" - * + /** + * @hibernate.id generator-class="native" type="java.lang.Long" + * column="tool_session_id" + * */ public Long getToolSessionId() { - return this.toolSessionId; + return this.toolSessionId; } public void setToolSessionId(Long toolSessionId) { - this.toolSessionId = toolSessionId; + this.toolSessionId = toolSessionId; } - /** + /** * * @hibernate.many-to-one not-null="true" - * @hibernate.column name="activity_id" + * @hibernate.column name="activity_id" */ public ToolActivity getToolActivity() { - return this.toolActivity; + return this.toolActivity; } public void setToolActivity(ToolActivity toolActivity) { - this.toolActivity = toolActivity; + this.toolActivity = toolActivity; } - /** - * @hibernate.property column="create_date_time" length="19" - * not-null="true" + /** + * @hibernate.property column="create_date_time" length="19" not-null="true" */ public Date getCreateDateTime() { - return this.createDateTime; + return this.createDateTime; } public void setCreateDateTime(Date createDateTime) { - this.createDateTime = createDateTime; + this.createDateTime = createDateTime; } + /** - * @hibernate.property column="unique_key" length="128" - * not-null="true" + * @hibernate.property column="unique_key" length="128" not-null="true" * @return Returns the uniqueKey. */ - public String getUniqueKey() - { - return uniqueKey; + public String getUniqueKey() { + return uniqueKey; } + /** - * @param uniqueKey The uniqueKey to set. + * @param uniqueKey + * The uniqueKey to set. */ - public void setUniqueKey(String uniqueKey) - { - this.uniqueKey = uniqueKey; + public void setUniqueKey(String uniqueKey) { + this.uniqueKey = uniqueKey; } + /** - * @hibernate.property column="tool_session_name" - * length="255" not-null="true" + * @hibernate.property column="tool_session_name" length="255" + * not-null="true" * @return */ - public String getToolSessionName() { - return toolSessionName; - } + public String getToolSessionName() { + return toolSessionName; + } - public void setToolSessionName(String toolSessionName) { - this.toolSessionName = toolSessionName; - } - /** - * @hibernate.many-to-one - * not-null="true" - * @hibernate.column name="tool_session_state_id" - * + public void setToolSessionName(String toolSessionName) { + this.toolSessionName = toolSessionName; + } + + /** + * @hibernate.many-to-one not-null="true" + * @hibernate.column name="tool_session_state_id" + * */ public int getToolSessionStateId() { - return this.toolSessionStateId; + return this.toolSessionStateId; } public void setToolSessionStateId(int toolSessionStateId) { - this.toolSessionStateId = toolSessionStateId; + this.toolSessionStateId = toolSessionStateId; } public String toString() { - return new ToStringBuilder(this) - .append("toolSessionId", getToolSessionId()) - .toString(); + return new ToStringBuilder(this).append("toolSessionId", getToolSessionId()).toString(); } public boolean equals(Object other) { - if ( (this == other ) ) return true; - if ( !(other instanceof ToolSession) ) return false; - ToolSession castOther = (ToolSession) other; - return new EqualsBuilder() - .append(this.getToolSessionId(), castOther.getToolSessionId()) - .isEquals(); + if ((this == other)) + return true; + if (!(other instanceof ToolSession)) + return false; + ToolSession castOther = (ToolSession) other; + return new EqualsBuilder().append(this.getToolSessionId(), castOther.getToolSessionId()).isEquals(); } public int hashCode() { - return new HashCodeBuilder() - .append(getToolSessionId()) - .toHashCode(); + return new HashCodeBuilder().append(getToolSessionId()).toHashCode(); } - public int getToolSessionTypeId() { - if(this instanceof NonGroupedToolSession) - return NON_GROUPED_TYPE; - else - return GROUPED_TYPE; - } - public Lesson getLesson() { - return lesson; + public int getToolSessionTypeId() { + if (this instanceof NonGroupedToolSession) + return NON_GROUPED_TYPE; + else + return GROUPED_TYPE; } - public void setLesson(Lesson lesson) { - this.lesson = lesson; + + public Lesson getLesson() { + return lesson; } + public void setLesson(Lesson lesson) { + this.lesson = lesson; + } } Index: lams_common/src/java/org/lamsfoundation/lams/util/LanguageUtil.java =================================================================== diff -u -r516eab2b292fd5234c4c2fc83057f72552947790 -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_common/src/java/org/lamsfoundation/lams/util/LanguageUtil.java (.../LanguageUtil.java) (revision 516eab2b292fd5234c4c2fc83057f72552947790) +++ lams_common/src/java/org/lamsfoundation/lams/util/LanguageUtil.java (.../LanguageUtil.java) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -29,6 +29,8 @@ import java.util.Map; import java.util.TimeZone; +import javax.servlet.ServletContext; + import org.apache.commons.lang.StringUtils; import org.lamsfoundation.lams.usermanagement.SupportedLocale; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; @@ -54,6 +56,7 @@ private static IUserManagementService getService() { if (service == null) { + ServletContext context = HttpSessionManager.getInstance().getServletContext(); WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(HttpSessionManager .getInstance().getServletContext()); service = (IUserManagementService) ctx.getBean("userManagementService"); Index: lams_common/src/java/org/lamsfoundation/lams/util/WebUtil.java =================================================================== diff -u -rbdd916337e3a48589da367f4c8b7705fe3197af2 -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_common/src/java/org/lamsfoundation/lams/util/WebUtil.java (.../WebUtil.java) (revision bdd916337e3a48589da367f4c8b7705fe3197af2) +++ lams_common/src/java/org/lamsfoundation/lams/util/WebUtil.java (.../WebUtil.java) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -1,8 +1,13 @@ package org.lamsfoundation.lams.util; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; +import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.security.Principal; @@ -478,5 +483,119 @@ return is; } + + /** + * Uploads a file to the given url. Uses a multi-part http post to + * post the file as well as the user, course, and hash server-authentication + * strings. + * + * Some of the java multipart posting libraries clashed with existing jboss + * libraries So instead, the multipart post is put together manually + * + * @param f + * @param urlString + * @param timestamp + * @param extUsername + * @param extCourseId + * @param hash + * @return + * @throws IOException + */ + public static InputStream performMultipartFilePost(File f, String fileParamName, String urlString, + HashMap params) throws MalformedURLException, IOException, Exception { + HttpURLConnection conn = null; + DataOutputStream dos = null; + String lineEnd = "\r\n"; + String twoHyphens = "--"; + String boundary = "*****"; + int bytesRead, bytesAvailable, bufferSize; + byte[] buffer; + int maxBufferSize = 1 * 1024 * 1024; + //------------------ CLIENT REQUEST + FileInputStream fileInputStream = new FileInputStream(f); + + log.debug("Performing multipart post to: " + urlString); + + // open a URL connection to the Servlet + URL url = new URL(urlString); + + // Open a HTTP connection to the URL + conn = (HttpURLConnection) url.openConnection(); + + + if (!(conn instanceof HttpURLConnection)) { + log.error("Fail to connect to external server though url: " + urlString); + throw new Exception("Fail to connect to external server though url: " + urlString); + } + + // Allow Inputs + conn.setDoInput(true); + + // Allow Outputs + conn.setDoOutput(true); + + // Don't use a cached copy. + conn.setUseCaches(false); + + String httpRequest = ""; + for (Entry entry : params.entrySet()) { + httpRequest += twoHyphens + boundary + lineEnd; + httpRequest += "Content-Disposition: form-data; name=\"" + entry.getKey() + "\";" + lineEnd; + httpRequest += lineEnd; + httpRequest += entry.getValue() + lineEnd; + } + httpRequest += twoHyphens + boundary + lineEnd; + httpRequest += "Content-Disposition: form-data; name=\"" + fileParamName + "\";" + " filename=\"" + f.getName() + + "\"" + lineEnd; + httpRequest += lineEnd; + + // Use a post method. + conn.setRequestMethod("POST"); + conn.setRequestProperty("Connection", "Keep-Alive"); + conn.setRequestProperty("Content-Length", new Long(f.length() + httpRequest.getBytes().length + 64).toString()); + log.debug(f.length()); + log.debug(httpRequest.getBytes().length); + log.debug("" + f.length() + httpRequest.getBytes().length + 64); + log.debug(httpRequest); + + conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); + + dos = new DataOutputStream(conn.getOutputStream()); + dos.writeBytes(httpRequest); + + // create a buffer of maximum size + bytesAvailable = fileInputStream.available(); + bufferSize = Math.min(bytesAvailable, maxBufferSize); + buffer = new byte[bufferSize]; + + // read file and write it into form... + bytesRead = fileInputStream.read(buffer, 0, bufferSize); + while (bytesRead > 0) { + dos.write(buffer, 0, bufferSize); + bytesAvailable = fileInputStream.available(); + bufferSize = Math.min(bytesAvailable, maxBufferSize); + bytesRead = fileInputStream.read(buffer, 0, bufferSize); + } + + // send multipart form data necessary after file data... + dos.writeBytes(lineEnd); + dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); + // Write the file part into the post------------------------------- + + // close streams + fileInputStream.close(); + dos.flush(); + dos.close(); + + InputStream ret = conn.getInputStream(); + if (ret == null) { + log.error("Fail to get response from extenal server, return InputStream null: " + urlString); + throw new Exception("Fail to fetch data from external server, return inputStream null: " + urlString); + } + + + return conn.getInputStream(); + } + } \ No newline at end of file Index: lams_common/src/java/org/lamsfoundation/lams/util/wddx/WDDXTAGS.java =================================================================== diff -u -rc4bbe0b084234edffd2c0c43dce7d7b1fbf14863 -r70a60f2862830ca6bd07e2b1252af3d79e4939af --- lams_common/src/java/org/lamsfoundation/lams/util/wddx/WDDXTAGS.java (.../WDDXTAGS.java) (revision c4bbe0b084234edffd2c0c43dce7d7b1fbf14863) +++ lams_common/src/java/org/lamsfoundation/lams/util/wddx/WDDXTAGS.java (.../WDDXTAGS.java) (revision 70a60f2862830ca6bd07e2b1252af3d79e4939af) @@ -238,5 +238,7 @@ /** Tool adapters specific tags */ public static final String CUSTOM_CSV = "customCSV"; - + + /** Evaluation tool output tag */ + public static final String TOOL_OUTPUT_DEFINITION = "gradebookToolOutputDefinitionName"; }