Index: lams_learning/conf/language/lams/ApplicationResources.properties =================================================================== diff -u -r8386a3fecd9c7baf6ed69d499016dedd8a83eac6 -r240f5a89847764532283243060c07572f88cc5cf --- lams_learning/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 8386a3fecd9c7baf6ed69d499016dedd8a83eac6) +++ lams_learning/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision 240f5a89847764532283243060c07572f88cc5cf) @@ -94,6 +94,8 @@ label.choose.group.button =Choose label.condition.gate.title =Condition Gate label.condition.gate.close.message =You have reached a condition gate. You have not satisfied the required conditions and you may not pass. Please return to previous activities. After you correct your answers, please press the button to proceed to next activities. - - +export.portfolio.competences.defined.table.title=Competences defined +export.portfolio.competences.defined.title=Title +export.portfolio.competences.defined.description=Description +export.portfolio.competences.covered.title=Competences covered #======= End labels: Exported 88 labels for en AU ===== Index: lams_learning/conf/language/lams/ApplicationResources_en_AU.properties =================================================================== diff -u -r8386a3fecd9c7baf6ed69d499016dedd8a83eac6 -r240f5a89847764532283243060c07572f88cc5cf --- lams_learning/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision 8386a3fecd9c7baf6ed69d499016dedd8a83eac6) +++ lams_learning/conf/language/lams/ApplicationResources_en_AU.properties (.../ApplicationResources_en_AU.properties) (revision 240f5a89847764532283243060c07572f88cc5cf) @@ -95,5 +95,8 @@ label.condition.gate.title =Condition Gate label.condition.gate.close.message =You have reached a condition gate. You have not satisfied the required conditions and you may not pass. Please return to previous activities. After you correct your answers, please press the button to proceed to next activities. - +export.portfolio.competences.defined.table.title=Competences defined +export.portfolio.competences.defined.title=Title +export.portfolio.competences.defined.description=Description +export.portfolio.competences.covered.title=Competences covered #======= End labels: Exported 88 labels for en AU ===== Index: lams_learning/src/java/org/lamsfoundation/lams/learning/export/ActivityPortfolio.java =================================================================== diff -u -ra47f62d9ef96db1cddec04678d6d828f37c23d81 -r240f5a89847764532283243060c07572f88cc5cf --- lams_learning/src/java/org/lamsfoundation/lams/learning/export/ActivityPortfolio.java (.../ActivityPortfolio.java) (revision a47f62d9ef96db1cddec04678d6d828f37c23d81) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/export/ActivityPortfolio.java (.../ActivityPortfolio.java) (revision 240f5a89847764532283243060c07572f88cc5cf) @@ -21,122 +21,144 @@ * **************************************************************** */ -/* $$Id$$ */ +/* $$Id$$ */ package org.lamsfoundation.lams.learning.export; import java.util.List; +import java.util.Set; +import java.util.TreeSet; /** * Models the portfolio for any type of activity, including tools, groupings, gates, optional and parallel activities + * * @author mtruong, fmalikoff - * + * */ public class ActivityPortfolio { - - private Long activityId; - private String activityDescription; - private String activityName; - private String exportUrl; - private List childPortfolios; - /* The link to the tool page from the main export page */ - private String toolLink; - private boolean headingNoPage; - - /** - * @return Returns the toolLink. - */ - public String getToolLink() { - return toolLink; - } - /** - * @param toolLink The toolLink to set. - */ - public void setToolLink(String toolLink) { - this.toolLink = toolLink; - } - public ActivityPortfolio() - { - this.activityId = null; - this.activityDescription = null; - this.activityName = null; - this.exportUrl = null; - this.toolLink = null; - this.childPortfolios = null; - this.headingNoPage = false; - } - - + private Long activityId; + private String activityDescription; + private String activityName; + private String exportUrl; + private List childPortfolios; + /* The link to the tool page from the main export page */ + private String toolLink; + private boolean headingNoPage; + private Set competencesCovered = new TreeSet(); - /** - * @return Returns the activityName. - */ - public String getActivityName() { - return activityName; - } - /** - * @param activityName The activityName to set. - */ - public void setActivityName(String activityName) { - this.activityName = activityName; - } - - /** - * @return Returns the exportUrl. - */ - public String getExportUrl() { - return exportUrl; - } - /** - * @param exportUrl The exportUrl to set. - */ - public void setExportUrl(String exportUrl) { - this.exportUrl = exportUrl; - } - - /** - * @return Returns the activityId. - */ - public Long getActivityId() { - return activityId; - } - /** - * @param activityId The activityId to set. - */ - public void setActivityId(Long activityId) { - this.activityId = activityId; - } - - /** - * @return Returns the activityDescription. - */ - public String getActivityDescription() { - return activityDescription; - } - /** - * @param activityDescription The activityDescription to set. - */ - public void setActivityDescription(String activityDescription) { - this.activityDescription = activityDescription; - } - /** Get the portfolios for any sub activities. Will return null for tool portfolios */ - public List getChildPortfolios() { - return childPortfolios; - } - public void setChildPortfolios(List childPortfolios) { - this.childPortfolios = childPortfolios; - } - /** Generate just a heading for this portfolio, don't try to link to a page. This is - * used for Parallel and Sequence activities in both learner and teacher modes, - * and for Branching in learner mode. - * @return - */ - public boolean isHeadingNoPage() { - return headingNoPage; - } - public void setHeadingNoPage(boolean headingNoPage) { - this.headingNoPage = headingNoPage; - } - - -} + /** + * @return Returns the toolLink. + */ + public String getToolLink() { + return toolLink; + } + + /** + * @param toolLink + * The toolLink to set. + */ + public void setToolLink(String toolLink) { + this.toolLink = toolLink; + } + + public ActivityPortfolio() { + activityId = null; + activityDescription = null; + activityName = null; + exportUrl = null; + toolLink = null; + childPortfolios = null; + headingNoPage = false; + } + + /** + * @return Returns the activityName. + */ + public String getActivityName() { + return activityName; + } + + /** + * @param activityName + * The activityName to set. + */ + public void setActivityName(String activityName) { + this.activityName = activityName; + } + + /** + * @return Returns the exportUrl. + */ + public String getExportUrl() { + return exportUrl; + } + + /** + * @param exportUrl + * The exportUrl to set. + */ + public void setExportUrl(String exportUrl) { + this.exportUrl = exportUrl; + } + + /** + * @return Returns the activityId. + */ + public Long getActivityId() { + return activityId; + } + + /** + * @param activityId + * The activityId to set. + */ + public void setActivityId(Long activityId) { + this.activityId = activityId; + } + + /** + * @return Returns the activityDescription. + */ + public String getActivityDescription() { + return activityDescription; + } + + /** + * @param activityDescription + * The activityDescription to set. + */ + public void setActivityDescription(String activityDescription) { + this.activityDescription = activityDescription; + } + + /** Get the portfolios for any sub activities. Will return null for tool portfolios */ + public List getChildPortfolios() { + return childPortfolios; + } + + public void setChildPortfolios(List childPortfolios) { + this.childPortfolios = childPortfolios; + } + + /** + * Generate just a heading for this portfolio, don't try to link to a page. This is used for Parallel and Sequence + * activities in both learner and teacher modes, and for Branching in learner mode. + * + * @return + */ + public boolean isHeadingNoPage() { + return headingNoPage; + } + + public void setHeadingNoPage(boolean headingNoPage) { + this.headingNoPage = headingNoPage; + } + + public Set getCompetencesCovered() { + return competencesCovered; + } + + public void setCompetencesCovered(Set competencesCovered) { + this.competencesCovered = competencesCovered; + } +} \ No newline at end of file Index: lams_learning/src/java/org/lamsfoundation/lams/learning/export/Portfolio.java =================================================================== diff -u -r61af83f89920627fddfc62ef81dc712130058157 -r240f5a89847764532283243060c07572f88cc5cf --- lams_learning/src/java/org/lamsfoundation/lams/learning/export/Portfolio.java (.../Portfolio.java) (revision 61af83f89920627fddfc62ef81dc712130058157) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/export/Portfolio.java (.../Portfolio.java) (revision 240f5a89847764532283243060c07572f88cc5cf) @@ -21,19 +21,21 @@ * **************************************************************** */ -/* $$Id$$ */ +/* $$Id$$ */ package org.lamsfoundation.lams.learning.export; import java.util.Date; +import java.util.HashSet; +import java.util.Set; +import org.lamsfoundation.lams.learningdesign.Competence; - /** * @author mtruong - */ + */ public class Portfolio { - - private String exportID; + + private String exportID; private String exportTmpDir; private String contentFolderID; private String lessonName; @@ -45,127 +47,140 @@ private Date portfolioCreatedDate; private String notebookLink; private String notebookDir; - - public Portfolio(String exportID) - { - this.exportTmpDir = null; - this.activityPortfolios = null; - this.exportID = exportID; - this.portfolioCreatedDate = new Date(); - this.notebookLink = null; - this.notebookDir = null; + private Set competencesDefined = new HashSet(); + + public Portfolio(String exportID) { + exportTmpDir = null; + activityPortfolios = null; + this.exportID = exportID; + portfolioCreatedDate = new Date(); + notebookLink = null; + notebookDir = null; } /** * @return Returns the exportTmpDir. */ public String getExportTmpDir() { - return exportTmpDir; + return exportTmpDir; } + /** - * @param exportTmpDir The exportTmpDir to set. + * @param exportTmpDir + * The exportTmpDir to set. */ public void setExportTmpDir(String exportTmpDir) { - this.exportTmpDir = exportTmpDir; + this.exportTmpDir = exportTmpDir; } - + /** * @return Returns the 32-character content folder name. */ public String getContentFolderID() { - return contentFolderID; + return contentFolderID; } - + /** - * @param contentFolderID The 32-character content folder name to set. + * @param contentFolderID + * The 32-character content folder name to set. */ public void setContentFolderID(String contentFolderID) { - this.contentFolderID = contentFolderID; + this.contentFolderID = contentFolderID; } - + public String getNotebookDir() { - return notebookDir; + return notebookDir; } + public void setNotebookDir(String notebookDir) { - this.notebookDir = notebookDir; + this.notebookDir = notebookDir; } - + /** * @return Returns the toolPortfolios. */ public ActivityPortfolio[] getActivityPortfolios() { - return activityPortfolios; + return activityPortfolios; } - + /** - * @param toolPortfolios The toolPortfolios to set. + * @param toolPortfolios + * The toolPortfolios to set. */ public void setActivityPortfolios(ActivityPortfolio[] activityPortfolios) { - this.activityPortfolios = activityPortfolios; + this.activityPortfolios = activityPortfolios; } - + public NotebookPortfolio[] getNotebookPortfolios() { - return notebookPortfolios; + return notebookPortfolios; } - + public void setNotebookPortfolios(NotebookPortfolio[] notebookPortfolios) { - this.notebookPortfolios = notebookPortfolios; + this.notebookPortfolios = notebookPortfolios; } - - public String getLessonName() { - return lessonName; - } - public void setLessonName(String lessonName) { - this.lessonName = lessonName; - } + public String getLessonName() { + return lessonName; + } - public String getLessonDescription() { - return lessonDescription; - } + public void setLessonName(String lessonName) { + this.lessonName = lessonName; + } - public void setLessonDescription(String lessonDescription) { - this.lessonDescription = lessonDescription; - } + public String getLessonDescription() { + return lessonDescription; + } - /** Get the internal id generated to keep this unique. Used in the directory name */ - public String getExportID() { - return exportID; - } + public void setLessonDescription(String lessonDescription) { + this.lessonDescription = lessonDescription; + } - public void setExportID(String exportID) { - this.exportID = exportID; - } + /** Get the internal id generated to keep this unique. Used in the directory name */ + public String getExportID() { + return exportID; + } - public String getLearnerName() { - return learnerName; - } + public void setExportID(String exportID) { + this.exportID = exportID; + } - public void setLearnerName(String learnerName) { - this.learnerName = learnerName; - } + public String getLearnerName() { + return learnerName; + } - public Date getLessonStartDate() { - return lessonStartDate; - } + public void setLearnerName(String learnerName) { + this.learnerName = learnerName; + } - public void setLessonStartDate(Date lessonStartDate) { - this.lessonStartDate = lessonStartDate; - } + public Date getLessonStartDate() { + return lessonStartDate; + } - public Date getPortfolioCreatedDate() { - return portfolioCreatedDate; - } + public void setLessonStartDate(Date lessonStartDate) { + this.lessonStartDate = lessonStartDate; + } - public void setPortfolioCreatedDate(Date portfolioCreatedDate) { - this.portfolioCreatedDate = portfolioCreatedDate; - } - - public String getNotebookLink() { - return notebookLink; - } - - public void setNotebookLink(String notebookLink) { - this.notebookLink = notebookLink; - } + public Date getPortfolioCreatedDate() { + return portfolioCreatedDate; + } + + public void setPortfolioCreatedDate(Date portfolioCreatedDate) { + this.portfolioCreatedDate = portfolioCreatedDate; + } + + public String getNotebookLink() { + return notebookLink; + } + + public void setNotebookLink(String notebookLink) { + this.notebookLink = notebookLink; + } + + public Set getCompetencesDefined() { + return competencesDefined; + } + + public void setCompetencesDefined(Set competencesDefined) { + this.competencesDefined = competencesDefined; + } } Index: lams_learning/src/java/org/lamsfoundation/lams/learning/export/service/ExportPortfolioService.java =================================================================== diff -u -r61af83f89920627fddfc62ef81dc712130058157 -r240f5a89847764532283243060c07572f88cc5cf --- lams_learning/src/java/org/lamsfoundation/lams/learning/export/service/ExportPortfolioService.java (.../ExportPortfolioService.java) (revision 61af83f89920627fddfc62ef81dc712130058157) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/export/service/ExportPortfolioService.java (.../ExportPortfolioService.java) (revision 240f5a89847764532283243060c07572f88cc5cf) @@ -21,7 +21,7 @@ * **************************************************************** */ -/* $$Id$$ */ +/* $$Id$$ */ package org.lamsfoundation.lams.learning.export.service; import java.io.BufferedWriter; @@ -49,6 +49,7 @@ import org.lamsfoundation.lams.learning.export.NotebookPortfolio; import org.lamsfoundation.lams.learning.export.Portfolio; import org.lamsfoundation.lams.learning.service.ICoreLearnerService; +import org.lamsfoundation.lams.learningdesign.Competence; import org.lamsfoundation.lams.learningdesign.dao.IActivityDAO; import org.lamsfoundation.lams.lesson.LearnerProgress; import org.lamsfoundation.lams.lesson.Lesson; @@ -70,488 +71,455 @@ import org.lamsfoundation.lams.util.zipfile.ZipFileUtilException; import org.lamsfoundation.lams.web.util.AttributeNames; - - - /** - * Generates the learner and teacher portfolios. These are designed to be offline versions of a sequence, - * so that learners and teachers can refer to them after the lesson has finished. + * Generates the learner and teacher portfolios. These are designed to be offline versions of a sequence, so that + * learners and teachers can refer to them after the lesson has finished. * - * In general, anything that the learner sees should be in their portfolio. The teacher version - * should have the details for all students in the lesson. + * In general, anything that the learner sees should be in their portfolio. The teacher version should have the details + * for all students in the lesson. * * @author mtruong,fmalikoff - * + * */ public class ExportPortfolioService implements IExportPortfolioService { - + private static Logger log = Logger.getLogger(ExportPortfolioService.class); - - private ILamsCoreToolService lamsCoreToolService; - private ICoreNotebookService coreNotebookService; - private IActivityDAO activityDAO; + + private ILamsCoreToolService lamsCoreToolService; + private ICoreNotebookService coreNotebookService; + private IActivityDAO activityDAO; private ICoreLearnerService learnerService; private IBaseDAO baseDAO; private ILessonDAO lessonDAO; protected MessageService messageService; private IThemeService themeService; - - - /** - * @param learnerService The learnerService to set. - */ - public void setLearnerService(ICoreLearnerService learnerService) { - this.learnerService = learnerService; - } - - /** - * @param learnerService The learnerService to set. - */ - public void setCoreNotebookService(ICoreNotebookService coreNotebookService) { - this.coreNotebookService = coreNotebookService; - } - - /** - * @param activityDAO The activityDAO to set. + + /** + * @param learnerService + * The learnerService to set. */ + public void setLearnerService(ICoreLearnerService learnerService) { + this.learnerService = learnerService; + } + + /** + * @param learnerService + * The learnerService to set. + */ + public void setCoreNotebookService(ICoreNotebookService coreNotebookService) { + this.coreNotebookService = coreNotebookService; + } + + /** + * @param activityDAO + * The activityDAO to set. + */ public void setActivityDAO(IActivityDAO activityDAO) { - this.activityDAO = activityDAO; + this.activityDAO = activityDAO; } - + /** - * @param lessonDAO The lessonDAO to set. + * @param lessonDAO + * The lessonDAO to set. */ public void setLessonDAO(ILessonDAO lessonDAO) { - this.lessonDAO = lessonDAO; + this.lessonDAO = lessonDAO; } - - public void setBaseDAO(IBaseDAO baseDAO) { - this.baseDAO = baseDAO; + + public void setBaseDAO(IBaseDAO baseDAO) { + this.baseDAO = baseDAO; + } + + /** + * @param lamsCoreToolService + * The lamsCoreToolService to set. + */ + public void setLamsCoreToolService(ILamsCoreToolService lamsCoreToolService) { + this.lamsCoreToolService = lamsCoreToolService; + } + + public void setMessageService(MessageService messageService) { + this.messageService = messageService; + } + + public void setThemeService(IThemeService themeService) { + this.themeService = themeService; + } + + /** @see org.lamsfoundation.lams.learning.export.service.IExportPortfolioService#exportPortfolioForTeacher(org.lamsfoundation.lams.lesson.Lesson) */ + public Portfolio exportPortfolioForTeacher(Long lessonId, Cookie[] cookies) { + Lesson lesson = lessonDAO.getLesson(lessonId); + + ArrayList portfolios = null; // each portfolio contains information about its activity, + // ordered in the same sequence as the ordered activity list. + Portfolio exports = null; + + if (lesson != null) { + try { + PortfolioBuilder builder = new PortfolioBuilder(lesson.getLearningDesign(), activityDAO, + lamsCoreToolService, coreNotebookService, ToolAccessMode.TEACHER, lesson, null, null); + builder.parseLearningDesign(); + portfolios = builder.getPortfolioList(); + + exports = doExport(portfolios, null, cookies, lesson); + + } catch (LamsToolServiceException e) { + /** TODO avoid throwing exceptions if possible */ + throw new ExportPortfolioException( + "An exception has occurred while generating portfolios. The error is: " + e); + } + } else { + String error = "The Lesson with lessonID " + lessonId + "is null."; + ExportPortfolioService.log.error(error); + /* + * Instead of throwing an exception, create the Portfolio object with the ToolPortfolio[] set to null. Set + * the value of exportTmpDir using createDirectory() method, so that the main file can be generated in that + * directory. + */ + exports = createPortfolioIndicatingErrorHasOccurred(lesson); } - /** - * @param lamsCoreToolService The lamsCoreToolService to set. - */ - public void setLamsCoreToolService(ILamsCoreToolService lamsCoreToolService) { - this.lamsCoreToolService = lamsCoreToolService; + return exports; + + } + + /** + * @see org.lamsfoundation.lams.learning.export.service.IExportPortfolioService#exportPortfolioForStudent(java.lang.Long, + * org.lamsfoundation.lams.usermanagement.User,boolean) + */ + public Portfolio exportPortfolioForStudent(Integer userId, Long lessonID, boolean anonymity, + ToolAccessMode accessMode, Cookie[] cookies) { + ArrayList portfolios = null; + ArrayList notes = null; + Portfolio exports = null; + + User learner = (User) baseDAO.find(User.class, userId); + Lesson lesson = lessonDAO.getLesson(lessonID); + + if (learner != null) { + LearnerProgress learnerProgress = learnerService.getProgress(learner.getUserId(), lessonID); + + if (learnerProgress != null) { + + try { + + PortfolioBuilder builder = new PortfolioBuilder(lesson.getLearningDesign(), activityDAO, + lamsCoreToolService, coreNotebookService, ToolAccessMode.LEARNER, lesson, learnerProgress, + learner); + + builder.parseLearningDesign(); + builder.processNotebook(accessMode); + + portfolios = builder.getPortfolioList(); + notes = builder.getNotebookList(); + + if (portfolios.size() >= 0) { + exports = doExport(portfolios, notes, cookies, lesson); + exports.setLearnerName(learner.getFirstName() + " " + learner.getLastName() + " (" + + learner.getLogin() + ")"); + } else { + ExportPortfolioService.log.error("The learner has not completed or attempted any activities"); + } + + } catch (LamsToolServiceException e) { + ExportPortfolioService.log.error("An exception has occurred while generating portfolios.", e); + } + + } else { + ExportPortfolioService.log.error("The LearnerProgress cannot be found for userId " + userId + + " participating in lessonId " + lessonID); + } + } else { + ExportPortfolioService.log.error("The User object with userId" + userId + "or Lesson object with lessonId" + + lessonID + " is null. Cannot Continue"); } - public void setMessageService(MessageService messageService) { - this.messageService = messageService; + if (exports == null) { + exports = createPortfolioIndicatingErrorHasOccurred(lesson); } - public void setThemeService(IThemeService themeService) { - this.themeService = themeService; + return exports; + + } + + private Portfolio createPortfolioIndicatingErrorHasOccurred(Lesson lesson) { + String tempDir = createDirectory(ExportPortfolioConstants.DIR_SUFFIX_EXPORT); + File dir = new File(tempDir); + String exportID = dir.getName(); + + Portfolio dummyPortfolio = new Portfolio(exportID); + dummyPortfolio.setExportTmpDir(tempDir); + dummyPortfolio.setLessonDescription(lesson.getLessonDescription()); + dummyPortfolio.setLessonName(lesson.getLessonName()); + return dummyPortfolio; + } + + /** @see org.lamsfoundation.lams.learning.export.service.IExportPortfolioService#zipPortfolio(String, String) */ + public String zipPortfolio(String filename, String directoryToZip) { + String zipfileName, dirToPutZip; + // create tmp dir to put zip file + + try { + dirToPutZip = FileUtil.createTempDirectory(ExportPortfolioConstants.DIR_SUFFIX_ZIP); + zipfileName = ZipFileUtil.createZipFile(filename, directoryToZip, dirToPutZip); + } catch (FileUtilException e) { + throw new ExportPortfolioException("Cannot create the temporary directory for this export", e); + } catch (ZipFileUtilException e) { + throw new ExportPortfolioException("An error has occurred while zipping up the directory ", e); } + int index = dirToPutZip.lastIndexOf(File.separator); + return index > -1 ? dirToPutZip.substring(index + 1) : dirToPutZip; + } - /** @see org.lamsfoundation.lams.learning.export.service.IExportPortfolioService#exportPortfolioForTeacher(org.lamsfoundation.lams.lesson.Lesson) */ - public Portfolio exportPortfolioForTeacher(Long lessonId, Cookie[] cookies) - { - Lesson lesson = lessonDAO.getLesson(lessonId); + /** @see org.lamsfoundation.lams.learning.export.service.IExportPortfolioService#doExport(Vector, Cookie[]) */ + public Portfolio doExport(ArrayList portfolios, ArrayList notes, + Cookie[] cookies, Lesson lesson) { + String tempDirectoryName; - ArrayList portfolios = null; //each portfolio contains information about its activity, ordered in the same sequence as the ordered activity list. - Portfolio exports = null; - - if (lesson != null) - { - try - { - PortfolioBuilder builder = new PortfolioBuilder(lesson.getLearningDesign(), activityDAO, lamsCoreToolService, coreNotebookService, ToolAccessMode.TEACHER, lesson, null, null); - builder.parseLearningDesign(); - portfolios = builder.getPortfolioList(); + // create the root directory for the export + tempDirectoryName = createDirectory(ExportPortfolioConstants.DIR_SUFFIX_EXPORT); + File dir = new File(tempDirectoryName); + String exportID = dir.getName(); - exports = doExport(portfolios, null, cookies,lesson); - - } - catch (LamsToolServiceException e) - { - /** TODO avoid throwing exceptions if possible */ - throw new ExportPortfolioException("An exception has occurred while generating portfolios. The error is: " + e); - } - } - else - { - String error="The Lesson with lessonID " + lessonId + "is null."; - log.error(error); - /* - * Instead of throwing an exception, create the Portfolio object with - * the ToolPortfolio[] set to null. Set the value of exportTmpDir using - * createDirectory() method, so that the main file can be generated in - * that directory. - */ - exports = createPortfolioIndicatingErrorHasOccurred(lesson); - } - - return exports; - - + Portfolio portfolio = new Portfolio(exportID); + portfolio.setExportTmpDir(tempDirectoryName); + portfolio.setContentFolderID(lesson.getLearningDesign().getContentFolderID()); + portfolio.setLessonName(lesson.getLessonName()); + portfolio.setLessonDescription(lesson.getLessonDescription()); + portfolio.setLessonStartDate(lesson.getStartDateTime()); + + if (portfolios != null) { + processPortfolios(portfolios, cookies, tempDirectoryName); + portfolio.setActivityPortfolios(portfolios.toArray(new ActivityPortfolio[portfolios.size()])); } - - /** @see org.lamsfoundation.lams.learning.export.service.IExportPortfolioService#exportPortfolioForStudent(java.lang.Long, org.lamsfoundation.lams.usermanagement.User,boolean) */ - public Portfolio exportPortfolioForStudent(Integer userId, Long lessonID, boolean anonymity, ToolAccessMode accessMode, Cookie[] cookies) - { - ArrayList portfolios = null; - ArrayList notes = null; - Portfolio exports = null; - - User learner = (User)baseDAO.find(User.class,userId); - Lesson lesson = lessonDAO.getLesson(lessonID); - - if (learner != null) - { - LearnerProgress learnerProgress = learnerService.getProgress(learner.getUserId(), lessonID); - - if (learnerProgress != null) - { + if (notes != null) { + processNotes(notes, tempDirectoryName, portfolio); + portfolio.setNotebookPortfolios(notes.toArray(new NotebookPortfolio[notes.size()])); + } - try - { - - PortfolioBuilder builder = new PortfolioBuilder(lesson.getLearningDesign(), activityDAO, lamsCoreToolService, coreNotebookService, ToolAccessMode.LEARNER, lesson, learnerProgress, learner); - - builder.parseLearningDesign(); - builder.processNotebook(accessMode); - - portfolios = builder.getPortfolioList(); - notes = builder.getNotebookList(); - - if ( portfolios.size() >= 0 ) { - exports = doExport(portfolios, notes, cookies,lesson); - exports.setLearnerName(learner.getFirstName()+" "+learner.getLastName()+" ("+learner.getLogin()+")"); - } else { - log.error("The learner has not completed or attempted any activities"); - } + Set competences = lesson.getLearningDesign().getCompetences(); + if (competences != null) { + portfolio.getCompetencesDefined().addAll(competences); + } - } - catch (LamsToolServiceException e) - { - log.error("An exception has occurred while generating portfolios.",e); - } - - } - else - { - log.error("The LearnerProgress cannot be found for userId " + userId + " participating in lessonId " + lessonID); - } + return portfolio; + + } + + private void processPortfolios(List portfolios, Cookie[] cookies, String tempDirectoryName) { + + Iterator i = portfolios.iterator(); + // iterate through the list of portfolios, create subdirectory, + while (i.hasNext()) { + ActivityPortfolio activityPortfolio = (ActivityPortfolio) i.next(); + + // create a subdirectory with the name ActivityXX where XX is the activityId + String subDirectoryName = ExportPortfolioConstants.SUBDIRECTORY_BASENAME + + activityPortfolio.getActivityId().toString(); + if (!createSubDirectory(tempDirectoryName, subDirectoryName)) { + throw new ExportPortfolioException("The subdirectory " + subDirectoryName + " could not be created."); } - else - { - log.error("The User object with userId" + userId + "or Lesson object with lessonId" + lessonID + " is null. Cannot Continue"); + + // The directory in which the activity must place its files + String activitySubDirectory = tempDirectoryName + File.separator + subDirectoryName; + + // for security reasons, append the relative directory name to the end of the export url instead of the + // whole path + String relativePath = activitySubDirectory.substring(FileUtil.TEMP_DIR.length() + 1, activitySubDirectory + .length()); + + // Some activities (parallel, optional, sequence) don't have export urls. + if (!activityPortfolio.isHeadingNoPage()) { + activityPortfolio.setExportUrl(ExportPortfolioConstants.HOST + activityPortfolio.getExportUrl()); + activityPortfolio.setExportUrl(WebUtil.appendParameterToURL(activityPortfolio.getExportUrl(), + AttributeNames.PARAM_DIRECTORY_NAME, relativePath)); + + // get tool to export its files, mainFileName is the name of the main HTML page that the tool exported. + String mainFileName = connectToToolViaExportURL(activityPortfolio.getActivityName(), activityPortfolio + .getExportUrl(), cookies, activitySubDirectory); + + // toolLink is used in main page, so that it can link with the tools export pages. + String toolLink = subDirectoryName + "/" + mainFileName; + activityPortfolio.setToolLink(toolLink); } - - if ( exports == null ) { - exports = createPortfolioIndicatingErrorHasOccurred(lesson); + + if (activityPortfolio.getChildPortfolios() != null && activityPortfolio.getChildPortfolios().size() > 0) { + processPortfolios(activityPortfolio.getChildPortfolios(), cookies, tempDirectoryName); } - - return exports; - - } - - private Portfolio createPortfolioIndicatingErrorHasOccurred(Lesson lesson) - { - String tempDir = createDirectory(ExportPortfolioConstants.DIR_SUFFIX_EXPORT); - File dir = new File(tempDir); - String exportID = dir.getName(); - Portfolio dummyPortfolio = new Portfolio(exportID); - dummyPortfolio.setExportTmpDir(tempDir); - dummyPortfolio.setLessonDescription(lesson.getLessonDescription()); - dummyPortfolio.setLessonName(lesson.getLessonName()); - return dummyPortfolio; - } - - /** @see org.lamsfoundation.lams.learning.export.service.IExportPortfolioService#zipPortfolio(String, String) */ - public String zipPortfolio(String filename, String directoryToZip) - { - String zipfileName, dirToPutZip; - //create tmp dir to put zip file - - try - { - dirToPutZip = FileUtil.createTempDirectory(ExportPortfolioConstants.DIR_SUFFIX_ZIP); - zipfileName = ZipFileUtil.createZipFile(filename, directoryToZip, dirToPutZip); - } - catch(FileUtilException e) - { - throw new ExportPortfolioException("Cannot create the temporary directory for this export", e); - } - catch(ZipFileUtilException e) - { - throw new ExportPortfolioException("An error has occurred while zipping up the directory ", e); - } - int index = dirToPutZip.lastIndexOf(File.separator); - return (index > -1 ? dirToPutZip.substring(index+1) : dirToPutZip); - } - - /** @see org.lamsfoundation.lams.learning.export.service.IExportPortfolioService#doExport(Vector, Cookie[]) */ - public Portfolio doExport(ArrayList portfolios, ArrayList notes, Cookie[] cookies, Lesson lesson) - { - String tempDirectoryName; - - //create the root directory for the export - tempDirectoryName = createDirectory(ExportPortfolioConstants.DIR_SUFFIX_EXPORT); - File dir = new File(tempDirectoryName); - String exportID = dir.getName(); - - Portfolio portfolio = new Portfolio(exportID); - portfolio.setExportTmpDir(tempDirectoryName); - portfolio.setContentFolderID(lesson.getLearningDesign().getContentFolderID()); - portfolio.setLessonName(lesson.getLessonName()); - portfolio.setLessonDescription(lesson.getLessonDescription()); - portfolio.setLessonStartDate(lesson.getStartDateTime()); - - if(portfolios != null) { - processPortfolios(portfolios, cookies, tempDirectoryName); - portfolio.setActivityPortfolios((ActivityPortfolio[])portfolios.toArray(new ActivityPortfolio[portfolios.size()])); - } - - if(notes != null) { - processNotes(notes, tempDirectoryName, portfolio); - portfolio.setNotebookPortfolios((NotebookPortfolio[])notes.toArray(new NotebookPortfolio[notes.size()])); - } - - return portfolio; - + } + private void processNotes(List notes, String tempDirectoryName, Portfolio portfolio) { + + if (notes.size() > 0) { + + // create a subdirectory with the name Notebook + String subDirectoryName = ExportPortfolioConstants.SUBDIRECTORY_NOTEBOOK_BASENAME; + + if (!createSubDirectory(tempDirectoryName, subDirectoryName)) { + throw new ExportPortfolioException("The subdirectory " + subDirectoryName + " could not be created."); + } else { + File dir = new File(tempDirectoryName, subDirectoryName); + portfolio.setNotebookDir(dir.getAbsolutePath()); + } + + String mainFileName = ExportPortfolioConstants.MAIN_NOTEBOOK_FILENAME; + + // notebookLink is used in main page, so that it can link with the tools export pages. + String notebookLink = subDirectoryName + "/" + mainFileName; + portfolio.setNotebookLink(notebookLink); + } - - private void processPortfolios(List portfolios, Cookie[] cookies, String tempDirectoryName) { + } - Iterator i = portfolios.iterator(); - //iterate through the list of portfolios, create subdirectory, - while(i.hasNext()) - { - ActivityPortfolio activityPortfolio = (ActivityPortfolio)i.next(); - - //create a subdirectory with the name ActivityXX where XX is the activityId - String subDirectoryName = ExportPortfolioConstants.SUBDIRECTORY_BASENAME + activityPortfolio.getActivityId().toString(); - if(!createSubDirectory(tempDirectoryName, subDirectoryName)) - { - throw new ExportPortfolioException("The subdirectory " + subDirectoryName + " could not be created."); - } - - // The directory in which the activity must place its files - String activitySubDirectory = tempDirectoryName + File.separator + subDirectoryName; - - //for security reasons, append the relative directory name to the end of the export url instead of the whole path - String relativePath = activitySubDirectory.substring(FileUtil.TEMP_DIR.length()+1, activitySubDirectory.length()); - - // Some activities (parallel, optional, sequence) don't have export urls. - if ( ! activityPortfolio.isHeadingNoPage() ) { - activityPortfolio.setExportUrl( ExportPortfolioConstants.HOST + activityPortfolio.getExportUrl() ); - activityPortfolio.setExportUrl( WebUtil.appendParameterToURL(activityPortfolio.getExportUrl(), AttributeNames.PARAM_DIRECTORY_NAME, relativePath) ); + /** + * Helper method which calls the FileUtil to create a subdirectory. This method might not be needed, can be used why + * calling the FileUtil directly. + * + * @param parentDir + * The name of the parent directory + * @param subDir + * The name of the child directory to create. + * @return true is the subdirectory was created, false otherwise + */ + private boolean createSubDirectory(String parentDir, String subDir) { + boolean created; + try { + created = FileUtil.createDirectory(parentDir, subDir); - //get tool to export its files, mainFileName is the name of the main HTML page that the tool exported. - String mainFileName = connectToToolViaExportURL(activityPortfolio.getActivityName(), activityPortfolio.getExportUrl(), cookies, activitySubDirectory); - - //toolLink is used in main page, so that it can link with the tools export pages. - String toolLink = subDirectoryName + "/" + mainFileName; - activityPortfolio.setToolLink(toolLink); - } - - if ( activityPortfolio.getChildPortfolios() != null && activityPortfolio.getChildPortfolios().size() > 0 ) { - processPortfolios(activityPortfolio.getChildPortfolios(), cookies, tempDirectoryName); - } - } - - + } catch (FileUtilException e) { + /** TODO avoid throwing exceptions if possible */ + throw new ExportPortfolioException("An error has occurred while creating the sub directory " + subDir); } - - private void processNotes(List notes, String tempDirectoryName, Portfolio portfolio) { - if(notes.size() > 0) { - - // create a subdirectory with the name Notebook - String subDirectoryName = ExportPortfolioConstants.SUBDIRECTORY_NOTEBOOK_BASENAME; - - if(!createSubDirectory(tempDirectoryName, subDirectoryName)) - { - throw new ExportPortfolioException("The subdirectory " + subDirectoryName + " could not be created."); - } else { - File dir = new File(tempDirectoryName, subDirectoryName); - portfolio.setNotebookDir(dir.getAbsolutePath()); - } - - String mainFileName = ExportPortfolioConstants.MAIN_NOTEBOOK_FILENAME; - - //notebookLink is used in main page, so that it can link with the tools export pages. - String notebookLink = subDirectoryName + "/" + mainFileName; - portfolio.setNotebookLink(notebookLink); - - } + return created; + } + + /** + * Helper method which calls the FileUtil to create directory. It will check whether the directory exists, if so, + * then it will overwrite the existing directory. (It is assumed that the cron jobs should delete the directory + + * files anyway, after the export is done) + * + * @param parentDir + * The name of the parent directory + * @param subDir + * The name of the child directory to create. + * @return true is the subdirectory was created, false otherwise + */ + private String createDirectory(String name) { + String tmpDir = null; + try { + tmpDir = FileUtil.createTempDirectory(name); + } catch (FileUtilException e) { + throw new ExportPortfolioException("Unable to create temporary directory " + name + " for export.", e); } - - /** - * Helper method which calls the FileUtil to create a subdirectory. This method might not be needed, - * can be used why calling the FileUtil directly. - * @param parentDir The name of the parent directory - * @param subDir The name of the child directory to create. - * @return true is the subdirectory was created, false otherwise - */ - private boolean createSubDirectory(String parentDir, String subDir) - { - boolean created; - try - { - created = FileUtil.createDirectory(parentDir, subDir); - - } - catch (FileUtilException e) - { - /** TODO avoid throwing exceptions if possible */ - throw new ExportPortfolioException("An error has occurred while creating the sub directory " + subDir); - } - - return created; - } - - /** - * Helper method which calls the FileUtil to create directory. - * It will check whether the directory exists, if so, then it will - * overwrite the existing directory. (It is assumed that the cron jobs - * should delete the directory + files anyway, after the export is done) - * @param parentDir The name of the parent directory - * @param subDir The name of the child directory to create. - * @return true is the subdirectory was created, false otherwise - */ - private String createDirectory(String name) - { - String tmpDir=null; - try - { - tmpDir = FileUtil.createTempDirectory(name); + return tmpDir; + } + + /** @see org.lamsfoundation.lams.learning.export.service.IExportPortfolioService#exportToolPortfolio(org.lamsfoundation.lams.learning.export.Portfolio) */ + public String connectToToolViaExportURL(String activityName, String exportURL, Cookie[] cookies, + String directoryToStoreErrorFile) { + String filename = null; + try { + if (exportURL != null) { + filename = HttpUrlConnectionUtil.connectToToolExportURL(exportURL, cookies); } - catch(FileUtilException e) - { - throw new ExportPortfolioException("Unable to create temporary directory " + name + " for export.", e); + if (filename == null) { + filename = ExportPortfolioConstants.EXPORT_ERROR_FILENAME; + ExportPortfolioService.log + .error("A problem has occurred while connecting to the tool's export url. The export url may be invalid or may not exist"); + writeErrorMessageToFile(directoryToStoreErrorFile, activityName); } - return tmpDir; + + } catch (MalformedURLException e) { + ExportPortfolioService.log.error("The URL " + exportURL + " given is invalid.", e); + writeErrorMessageToFile(directoryToStoreErrorFile, activityName); + } catch (FileNotFoundException e) { + ExportPortfolioService.log.error("The directory " + directoryToStoreErrorFile + " may not exist.", e); + writeErrorMessageToFile(directoryToStoreErrorFile, activityName); + } catch (IOException e) { + ExportPortfolioService.log.error("A problem has occurred while writing the contents of " + exportURL + + " to file.", e); + writeErrorMessageToFile(directoryToStoreErrorFile, activityName); + } - - /** @see org.lamsfoundation.lams.learning.export.service.IExportPortfolioService#exportToolPortfolio(org.lamsfoundation.lams.learning.export.Portfolio) */ - public String connectToToolViaExportURL(String activityName, String exportURL, Cookie[] cookies, String directoryToStoreErrorFile) - { - String filename = null; - try - { - if ( exportURL != null ) { - filename = HttpUrlConnectionUtil.connectToToolExportURL(exportURL, cookies); - } - if (filename == null) - { - filename = ExportPortfolioConstants.EXPORT_ERROR_FILENAME; - log.error("A problem has occurred while connecting to the tool's export url. The export url may be invalid or may not exist"); - writeErrorMessageToFile(directoryToStoreErrorFile, activityName); - } - - } - catch(MalformedURLException e) - { - log.error("The URL "+exportURL+" given is invalid.",e); - writeErrorMessageToFile(directoryToStoreErrorFile, activityName); - } - catch(FileNotFoundException e) - { - log.error("The directory "+directoryToStoreErrorFile+" may not exist.",e); - writeErrorMessageToFile(directoryToStoreErrorFile, activityName); - } - catch(IOException e) - { - log.error("A problem has occurred while writing the contents of " + exportURL + " to file.", e); - writeErrorMessageToFile(directoryToStoreErrorFile, activityName); - - } - - return filename; + return filename; + } + + /** Generate the main page, given this portfolio */ + public void generateMainPage(HttpServletRequest request, Portfolio portfolio, Cookie[] cookies) { + + String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + + request.getContextPath(); + String url = basePath + "/exportPortfolio/main.jsp"; + + String filename = ExportPortfolioConstants.MAIN_EXPORT_FILENAME; + try { + request.getSession().setAttribute("portfolio", portfolio); + HttpUrlConnectionUtil.writeResponseToFile(url, portfolio.getExportTmpDir(), filename, cookies); + request.getSession().removeAttribute("portfolio"); + } catch (MalformedURLException e) { + ExportPortfolioService.log.error("The URL given is invalid. Exception Message was: " + e); + } catch (FileNotFoundException e) { + ExportPortfolioService.log.error("The directory or file may not exist. Exception Message was: " + e); + } catch (IOException e) { + ExportPortfolioService.log.error("A problem has occurred while writing the contents of " + url + + " to file. Exception Message was: " + e); } - - /** Generate the main page, given this portfolio */ - public void generateMainPage(HttpServletRequest request, Portfolio portfolio, Cookie[] cookies) { + } - String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath(); - String url = basePath + "/exportPortfolio/main.jsp"; - - String filename = ExportPortfolioConstants.MAIN_EXPORT_FILENAME; - try - { - request.getSession().setAttribute("portfolio", portfolio); - HttpUrlConnectionUtil.writeResponseToFile(url, portfolio.getExportTmpDir(), filename, cookies); - request.getSession().removeAttribute("portfolio"); - } - catch(MalformedURLException e) - { - log.error("The URL given is invalid. Exception Message was: " +e); - } - catch(FileNotFoundException e) - { - log.error("The directory or file may not exist. Exception Message was: " +e); - } - catch(IOException e) - { - log.error("A problem has occurred while writing the contents of " + url + " to file. Exception Message was: " +e); - } + /** Generate the main page, given this portfolio */ + public void generateNotebookPage(HttpServletRequest request, Portfolio portfolio, Cookie[] cookies) { + + String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + + request.getContextPath(); + String url = basePath + "/exportPortfolio/notebook.jsp"; + + String filename = ExportPortfolioConstants.MAIN_NOTEBOOK_FILENAME; + try { + request.getSession().setAttribute("portfolio", portfolio); + HttpUrlConnectionUtil.writeResponseToFile(url, portfolio.getNotebookDir(), filename, cookies); + request.getSession().removeAttribute("portfolio"); + } catch (MalformedURLException e) { + ExportPortfolioService.log.error("The URL given is invalid. Exception Message was: " + e); + } catch (FileNotFoundException e) { + ExportPortfolioService.log.error("The directory or file may not exist. Exception Message was: " + e); + } catch (IOException e) { + ExportPortfolioService.log.error("A problem has occurred while writing the contents of " + url + + " to file. Exception Message was: " + e); } - - /** Generate the main page, given this portfolio */ - public void generateNotebookPage(HttpServletRequest request, Portfolio portfolio, Cookie[] cookies) { + } - String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath(); - String url = basePath + "/exportPortfolio/notebook.jsp"; - - String filename = ExportPortfolioConstants.MAIN_NOTEBOOK_FILENAME; - try - { - request.getSession().setAttribute("portfolio", portfolio); - HttpUrlConnectionUtil.writeResponseToFile(url, portfolio.getNotebookDir(), filename, cookies); - request.getSession().removeAttribute("portfolio"); - } - catch(MalformedURLException e) - { - log.error("The URL given is invalid. Exception Message was: " +e); - } - catch(FileNotFoundException e) - { - log.error("The directory or file may not exist. Exception Message was: " +e); - } - catch(IOException e) - { - log.error("A problem has occurred while writing the contents of " + url + " to file. Exception Message was: " +e); - } + private void writeErrorMessageToFile(String directoryToStoreFile, String activityTitle) { + try { + String errorMessage = messageService.getMessage(ExportPortfolioConstants.EXPORT_ACTIVITY_ERROR_KEY, + new Object[] { activityTitle }); + String filepath = directoryToStoreFile + File.separator + ExportPortfolioConstants.EXPORT_ERROR_FILENAME; + BufferedWriter fileout = new BufferedWriter(new FileWriter(filepath)); + fileout.write(errorMessage); + fileout.close(); + } catch (IOException e) { + ExportPortfolioService.log.error("Exception occured trying to write out error message to file.", e); } - - private void writeErrorMessageToFile(String directoryToStoreFile, String activityTitle) - { - try - { - String errorMessage = messageService.getMessage(ExportPortfolioConstants.EXPORT_ACTIVITY_ERROR_KEY, new Object[]{activityTitle}); - String filepath = directoryToStoreFile + File.separator + ExportPortfolioConstants.EXPORT_ERROR_FILENAME; - BufferedWriter fileout = new BufferedWriter(new FileWriter(filepath)); - fileout.write(errorMessage); - fileout.close(); - } - catch(IOException e) - { - log.error("Exception occured trying to write out error message to file.",e); - } + } + + /** + * Gets the themes for the current user. This is used to determine the stylesheets included in the export file. We + * need the full theme, not just the name, so we can get the directory names for the images. + */ + public Collection getUserThemes() { + List themeNames = CSSThemeUtil.getAllUserThemes(); + Set userThemes = new HashSet(); + for (String themeName : themeNames) { + CSSThemeVisualElement theme = themeService.getTheme(themeName); + if (theme != null) { + userThemes.add(theme); + } } - - /** Gets the themes for the current user. This is used to determine the stylesheets - * included in the export file. We need the full theme, not just the name, so we can get - * the directory names for the images. */ - public Collection getUserThemes() { - List themeNames = CSSThemeUtil.getAllUserThemes(); - Set userThemes = new HashSet(); - for ( String themeName: themeNames) { - CSSThemeVisualElement theme = themeService.getTheme(themeName); - if ( theme != null ) { - userThemes.add(theme); - } - } - return userThemes; - } + return userThemes; + } - } Index: lams_learning/src/java/org/lamsfoundation/lams/learning/export/service/PortfolioBuilder.java =================================================================== diff -u -r936afcc05958171399ef80d72ea8234c7a67e268 -r240f5a89847764532283243060c07572f88cc5cf --- lams_learning/src/java/org/lamsfoundation/lams/learning/export/service/PortfolioBuilder.java (.../PortfolioBuilder.java) (revision 936afcc05958171399ef80d72ea8234c7a67e268) +++ lams_learning/src/java/org/lamsfoundation/lams/learning/export/service/PortfolioBuilder.java (.../PortfolioBuilder.java) (revision 240f5a89847764532283243060c07572f88cc5cf) @@ -24,16 +24,18 @@ package org.lamsfoundation.lams.learning.export.service; -import java.util.List; import java.util.ArrayList; import java.util.Iterator; +import java.util.List; +import java.util.Set; import org.apache.commons.collections.ArrayStack; import org.apache.log4j.Logger; import org.lamsfoundation.lams.learning.export.ActivityPortfolio; -import org.lamsfoundation.lams.learning.export.NotebookPortfolio; import org.lamsfoundation.lams.learning.export.ExportPortfolioException; +import org.lamsfoundation.lams.learning.export.NotebookPortfolio; import org.lamsfoundation.lams.learningdesign.Activity; +import org.lamsfoundation.lams.learningdesign.CompetenceMapping; import org.lamsfoundation.lams.learningdesign.ComplexActivity; import org.lamsfoundation.lams.learningdesign.ISystemToolActivity; import org.lamsfoundation.lams.learningdesign.LearningDesign; @@ -44,14 +46,14 @@ import org.lamsfoundation.lams.learningdesign.exception.LearningDesignProcessorException; import org.lamsfoundation.lams.lesson.LearnerProgress; import org.lamsfoundation.lams.lesson.Lesson; +import org.lamsfoundation.lams.notebook.model.NotebookEntry; +import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; +import org.lamsfoundation.lams.notebook.service.ICoreNotebookService; import org.lamsfoundation.lams.tool.SystemTool; import org.lamsfoundation.lams.tool.Tool; import org.lamsfoundation.lams.tool.ToolAccessMode; import org.lamsfoundation.lams.tool.ToolSession; import org.lamsfoundation.lams.tool.service.ILamsCoreToolService; -import org.lamsfoundation.lams.notebook.service.ICoreNotebookService; -import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; -import org.lamsfoundation.lams.notebook.model.NotebookEntry; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.util.AttributeNames; @@ -62,301 +64,336 @@ ArrayList mainPortfolioList; ArrayList mainNotebookList; - ArrayStack activityListStack; - ArrayList currentPortfolioList; - ArrayList currentNotebookList; - ToolAccessMode accessMode; - ILamsCoreToolService lamsCoreToolService; - ICoreNotebookService coreNotebookService; - User user; - LearnerProgress progress; - Lesson lesson; + ArrayStack activityListStack; + ArrayList currentPortfolioList; + ArrayList currentNotebookList; + ToolAccessMode accessMode; + ILamsCoreToolService lamsCoreToolService; + ICoreNotebookService coreNotebookService; + User user; + LearnerProgress progress; + Lesson lesson; - /** Create the builder. Supply all the data that will be needed to parse the design and build the portfolio entries. - * - * If accessMode == LEARNER then progress and user must not be null. This will create a list of portfolio objects for - * all activities that the LEARNER has completed or attempted. - * - * If accessMode == TEACHER then progress and user will be null and all activities will be included. Note: Because - * the progress is null we can't rely on getting the lesson from the progress. - * - * @param design - * @param activityDAO - * @param lamsCoreToolService - * @param accessMode - * @param lesson - * @param progress - * @param user - */ - public PortfolioBuilder(LearningDesign design, IActivityDAO activityDAO, - ILamsCoreToolService lamsCoreToolService, ICoreNotebookService coreNotebookService, ToolAccessMode accessMode, - Lesson lesson, LearnerProgress progress, User user) { - super(design, activityDAO); - this.mainPortfolioList = new ArrayList(); - this.mainNotebookList = new ArrayList(); - this.currentPortfolioList = mainPortfolioList; - this.currentNotebookList = mainNotebookList; - this.activityListStack = new ArrayStack(5); - this.accessMode = accessMode; - this.lamsCoreToolService = lamsCoreToolService; - this.coreNotebookService = coreNotebookService; - - this.user = user; - this.lesson = lesson; - this.progress = progress; - } + /** + * Create the builder. Supply all the data that will be needed to parse the design and build the portfolio entries. + * + * If accessMode == LEARNER then progress and user must not be null. This will create a list of portfolio objects + * for all activities that the LEARNER has completed or attempted. + * + * If accessMode == TEACHER then progress and user will be null and all activities will be included. Note: Because + * the progress is null we can't rely on getting the lesson from the progress. + * + * @param design + * @param activityDAO + * @param lamsCoreToolService + * @param accessMode + * @param lesson + * @param progress + * @param user + */ + public PortfolioBuilder(LearningDesign design, IActivityDAO activityDAO, ILamsCoreToolService lamsCoreToolService, + ICoreNotebookService coreNotebookService, ToolAccessMode accessMode, Lesson lesson, + LearnerProgress progress, User user) { + super(design, activityDAO); + mainPortfolioList = new ArrayList(); + mainNotebookList = new ArrayList(); + currentPortfolioList = mainPortfolioList; + currentNotebookList = mainNotebookList; + activityListStack = new ArrayStack(5); + this.accessMode = accessMode; + this.lamsCoreToolService = lamsCoreToolService; + this.coreNotebookService = coreNotebookService; - /** Prepares to process children */ - public boolean startComplexActivity(ComplexActivity activity) throws LearningDesignProcessorException { - // Create a new current activity list, putting the old current one on the stack. - // An exception to this is when we reach a branching activity in learner mode. The children are added to the current list. - boolean flattenLearnerBranching = (activity.isBranchingActivity() || (activity.isSequenceActivity() - && activity.getParentActivity().isBranchingActivity())) && accessMode == ToolAccessMode.LEARNER; + this.user = user; + this.lesson = lesson; + this.progress = progress; + } - if (!flattenLearnerBranching) { - activityListStack.push(currentPortfolioList); - currentPortfolioList = new ArrayList(); - } - return true; + /** Prepares to process children */ + @Override + public boolean startComplexActivity(ComplexActivity activity) throws LearningDesignProcessorException { + // Create a new current activity list, putting the old current one on the stack. + // An exception to this is when we reach a branching activity in learner mode. The children are added to the + // current list. + boolean flattenLearnerBranching = (activity.isBranchingActivity() || activity.isSequenceActivity() + && activity.getParentActivity().isBranchingActivity()) + && accessMode == ToolAccessMode.LEARNER; + + if (!flattenLearnerBranching) { + activityListStack.push(currentPortfolioList); + currentPortfolioList = new ArrayList(); } + return true; + } - /** Creates an ActivityPortfolio and sets up the list of its children. Doesn't create an entry if there are no children. */ - public void endComplexActivity(ComplexActivity activity) throws LearningDesignProcessorException { - - ActivityPortfolio complexPortfolio = null; - - boolean flattenLearnerBranching = (activity.isBranchingActivity() || (activity.isSequenceActivity() - && activity.getParentActivity().isBranchingActivity())) && accessMode == ToolAccessMode.LEARNER; - - if ( currentPortfolioList.size()>0 || accessMode == ToolAccessMode.TEACHER) { - complexPortfolio = createActivityPortfolio(activity); + /** + * Creates an ActivityPortfolio and sets up the list of its children. Doesn't create an entry if there are no + * children. + */ + @Override + public void endComplexActivity(ComplexActivity activity) throws LearningDesignProcessorException { - if ( currentPortfolioList.size()>0 ) { - complexPortfolio.setChildPortfolios(currentPortfolioList); - } - - if ( activity.isSystemToolActivity() ) { - String exportURL = getExportURLForSystemTool(activity); - complexPortfolio = complexPortfolio == null ? createActivityPortfolio(activity) : complexPortfolio; - complexPortfolio.setExportUrl(exportURL); - // if there isn't a url, we assume we just want a heading - complexPortfolio.setHeadingNoPage(exportURL == null); - } else { - // sequence, parallel, etc - complexPortfolio.setHeadingNoPage(true); - } - } + ActivityPortfolio complexPortfolio = null; - if (!flattenLearnerBranching) { - currentPortfolioList = (ArrayList) activityListStack.pop(); - } + boolean flattenLearnerBranching = (activity.isBranchingActivity() || activity.isSequenceActivity() + && activity.getParentActivity().isBranchingActivity()) + && accessMode == ToolAccessMode.LEARNER; - if ( complexPortfolio != null && !flattenLearnerBranching) - currentPortfolioList.add(complexPortfolio); + if (currentPortfolioList.size() > 0 || accessMode == ToolAccessMode.TEACHER) { + complexPortfolio = createActivityPortfolio(activity); + + if (currentPortfolioList.size() > 0) { + complexPortfolio.setChildPortfolios(currentPortfolioList); + } + + if (activity.isSystemToolActivity()) { + String exportURL = getExportURLForSystemTool(activity); + complexPortfolio = complexPortfolio == null ? createActivityPortfolio(activity) : complexPortfolio; + complexPortfolio.setExportUrl(exportURL); + // if there isn't a url, we assume we just want a heading + complexPortfolio.setHeadingNoPage(exportURL == null); + } else { + // sequence, parallel, etc + complexPortfolio.setHeadingNoPage(true); + } } - public void startSimpleActivity(SimpleActivity activity) throws LearningDesignProcessorException { - // everything done by endSimpleActivity + if (!flattenLearnerBranching) { + currentPortfolioList = (ArrayList) activityListStack.pop(); } - /** Creates an ActivityPortfolio. */ - public void endSimpleActivity(SimpleActivity activity) throws LearningDesignProcessorException { - - // if learner only include the attempted and completed activities - if (accessMode == ToolAccessMode.LEARNER && - ! ( progress.getCompletedActivities().contains(activity) || progress.getAttemptedActivities().contains(activity)) ) { - return; - } + if (complexPortfolio != null && !flattenLearnerBranching) { + currentPortfolioList.add(complexPortfolio); + } + } - String exportUrlForTool = null; - - if ( activity.isToolActivity() ) { - - // if the tool does not have an export url, then the processor will include an "not supported" error page - - ToolActivity toolActivity = (ToolActivity) activity; - Tool tool = toolActivity.getTool(); - if (accessMode == ToolAccessMode.TEACHER) - exportUrlForTool = tool.getExportPortfolioClassUrl(); - else - exportUrlForTool = tool.getExportPortfolioLearnerUrl(); - - /* - * Append parameters to the export url. - * If the export is done by teacher: mode, toolContentId is appended - * If the export is done by learner: mode, userId, toolSessionId is appended - */ - if ( exportUrlForTool != null ) { - if (accessMode == ToolAccessMode.LEARNER) - { - exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_USER_ID, user.getUserId().toString()); - ToolSession toolSession = lamsCoreToolService.getToolSessionByActivity(user, toolActivity); - if (toolSession != null) { - exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_TOOL_SESSION_ID, toolSession.getToolSessionId().toString()); - } - } - else if (accessMode == ToolAccessMode.TEACHER) - { - exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_TOOL_CONTENT_ID, toolActivity.getToolContentId().toString()); - } - exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_OFFLINE, activity.getRunOffline().toString()); - } + @Override + public void startSimpleActivity(SimpleActivity activity) throws LearningDesignProcessorException { + // everything done by endSimpleActivity + } - ActivityPortfolio p = createActivityPortfolio(activity); - p.setExportUrl(exportUrlForTool); - currentPortfolioList.add(p); - - } else if ( activity.isSystemToolActivity() ) { - - exportUrlForTool = getExportURLForSystemTool(activity); - if ( exportUrlForTool != null ) { - ActivityPortfolio p = createActivityPortfolio(activity); - p.setExportUrl(exportUrlForTool); - currentPortfolioList.add(p); - } - } + /** Creates an ActivityPortfolio. */ + @Override + public void endSimpleActivity(SimpleActivity activity) throws LearningDesignProcessorException { - + // if learner only include the attempted and completed activities + if (accessMode == ToolAccessMode.LEARNER + && !(progress.getCompletedActivities().contains(activity) || progress.getAttemptedActivities() + .contains(activity))) { + return; } - /** - * A system tool may be a simple or a complex activity, so the logic is in a method called by both endSimpleActivity() - * and endComplexActivity(). Only include the gates and branching in the teacher version, but always include grouping. This is - * controlled by the urls in the db - if there isn't a url in the system table then we assume that there shouldn't - * be a screen. - *

- * System tools don't use the modes or the tool session id but need to add them or the validation fails in - * AbstractExportPortfolio servlet. So why leave the validation there - because system tools are the exception rather than the rule. - * In the future, they may need these parameters. - * - * @param activity: an activity which also meets the ISystemToolActivity interface - * @param exportUrlForTool - */ - private String getExportURLForSystemTool(Activity activity) { - - // At present the sequence activity always has a page, which is a bit redundant for when it is a branch. - // If we just want the sequence activity to be a heading when it is a branch (rather than in an optional activity) - // then uncomment this code. - // if ( activity.isSequenceActivity() && activity.getParentActivity() != null && activity.getParentActivity().isBranchingActivity() ) { - // return null; - //} - - String exportUrlForTool = null; - ISystemToolActivity sysToolActivity = (ISystemToolActivity) activity; - SystemTool tool = sysToolActivity.getSystemTool(); - - if ( tool != null ) { - if (accessMode == ToolAccessMode.LEARNER) { - exportUrlForTool = tool.getExportPortfolioLearnerUrl(); - } else { - exportUrlForTool = tool.getExportPortfolioClassUrl(); - } + String exportUrlForTool = null; + + if (activity.isToolActivity()) { + + // if the tool does not have an export url, then the processor will include an "not supported" error page + + ToolActivity toolActivity = (ToolActivity) activity; + Tool tool = toolActivity.getTool(); + if (accessMode == ToolAccessMode.TEACHER) { + exportUrlForTool = tool.getExportPortfolioClassUrl(); + } else { + exportUrlForTool = tool.getExportPortfolioLearnerUrl(); + } + + /* + * Append parameters to the export url. If the export is done by teacher: mode, toolContentId is appended If + * the export is done by learner: mode, userId, toolSessionId is appended + */ + if (exportUrlForTool != null) { + if (accessMode == ToolAccessMode.LEARNER) { + exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_USER_ID, + user.getUserId().toString()); + ToolSession toolSession = lamsCoreToolService.getToolSessionByActivity(user, toolActivity); + if (toolSession != null) { + exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, + AttributeNames.PARAM_TOOL_SESSION_ID, toolSession.getToolSessionId().toString()); + } + } else if (accessMode == ToolAccessMode.TEACHER) { + exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, + AttributeNames.PARAM_TOOL_CONTENT_ID, toolActivity.getToolContentId().toString()); } - if ( exportUrlForTool != null ) { - if (accessMode == ToolAccessMode.LEARNER) { - exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_USER_ID, user.getUserId().toString()); - exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_TOOL_SESSION_ID, "0"); - } else { - exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_TOOL_CONTENT_ID, "0"); - } - exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_ACTIVITY_ID, activity.getActivityId().toString()); - exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_LESSON_ID, lesson.getLessonId().toString()); - exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_OFFLINE, activity.getRunOffline().toString()); + exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_OFFLINE, + activity.getRunOffline().toString()); + } + + ActivityPortfolio p = createActivityPortfolio(activity); + p.setExportUrl(exportUrlForTool); + if (toolActivity.getCompetenceMappings() != null) { + Set competencesCovered = p.getCompetencesCovered(); + for (CompetenceMapping mapping : toolActivity.getCompetenceMappings()) { + competencesCovered.add(mapping.getCompetence().getTitle()); } - return exportUrlForTool; + } + + currentPortfolioList.add(p); + + } else if (activity.isSystemToolActivity()) { + + exportUrlForTool = getExportURLForSystemTool(activity); + if (exportUrlForTool != null) { + ActivityPortfolio p = createActivityPortfolio(activity); + p.setExportUrl(exportUrlForTool); + currentPortfolioList.add(p); + } } - - /** - * Process all Notebook (Scratchpad) entries into portfolio objects. - * @param notebookAccessMode The access mode that determines what entries are returned. - */ - public void processNotebook(ToolAccessMode notebookAccessMode) throws ExportPortfolioException { - List entries = null; - - if(lesson == null || user == null) { - throw new ExportPortfolioException(); - } - - if(notebookAccessMode == null) - entries = coreNotebookService.getEntry(lesson.getLessonId(),CoreNotebookConstants.SCRATCH_PAD, user.getUserId()); - else if(notebookAccessMode.equals(ToolAccessMode.TEACHER)) - entries = coreNotebookService.getEntry(lesson.getLessonId(),CoreNotebookConstants.SCRATCH_PAD,CoreNotebookConstants.JOURNAL_SIG, user.getUserId()); - - if(entries == null) { - throw new ExportPortfolioException(); - } - - Iterator it = entries.iterator(); - - while(it.hasNext()) { - NotebookEntry entry = (NotebookEntry) it.next(); - NotebookPortfolio portfolio = createNotebookPortfolio(entry); - currentNotebookList.add(portfolio); - } + + } + + /** + * A system tool may be a simple or a complex activity, so the logic is in a method called by both + * endSimpleActivity() and endComplexActivity(). Only include the gates and branching in the teacher version, but + * always include grouping. This is controlled by the urls in the db - if there isn't a url in the system table then + * we assume that there shouldn't be a screen. + *

+ * System tools don't use the modes or the tool session id but need to add them or the validation fails in + * AbstractExportPortfolio servlet. So why leave the validation there - because system tools are the exception + * rather than the rule. In the future, they may need these parameters. + * + * @param activity: + * an activity which also meets the ISystemToolActivity interface + * @param exportUrlForTool + */ + private String getExportURLForSystemTool(Activity activity) { + + // At present the sequence activity always has a page, which is a bit redundant for when it is a branch. + // If we just want the sequence activity to be a heading when it is a branch (rather than in an optional + // activity) + // then uncomment this code. + // if ( activity.isSequenceActivity() && activity.getParentActivity() != null && + // activity.getParentActivity().isBranchingActivity() ) { + // return null; + // } + + String exportUrlForTool = null; + ISystemToolActivity sysToolActivity = (ISystemToolActivity) activity; + SystemTool tool = sysToolActivity.getSystemTool(); + + if (tool != null) { + if (accessMode == ToolAccessMode.LEARNER) { + exportUrlForTool = tool.getExportPortfolioLearnerUrl(); + } else { + exportUrlForTool = tool.getExportPortfolioClassUrl(); + } } + if (exportUrlForTool != null) { + if (accessMode == ToolAccessMode.LEARNER) { + exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_USER_ID, user + .getUserId().toString()); + exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_TOOL_SESSION_ID, + "0"); + } else { + exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_TOOL_CONTENT_ID, + "0"); + } + exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_ACTIVITY_ID, + activity.getActivityId().toString()); + exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_LESSON_ID, lesson + .getLessonId().toString()); + exportUrlForTool = WebUtil.appendParameterToURL(exportUrlForTool, AttributeNames.PARAM_OFFLINE, activity + .getRunOffline().toString()); + } + return exportUrlForTool; + } - /** - * Obtains the Tool from the ToolActivity and creates a portfolio object with properties activityId, activityName, - * activityDescription, exportURL set to the value of the ToolActivity's properties activityId, toolDisplayName - * (retrieved from Tool object), title, exportPortfolioUrl respestively. - * - * @param activity The Tool Activity - * @return a Portfolio object - */ - protected ActivityPortfolio createActivityPortfolio(Activity activity) - { - if (activity == null) - { - String error="Cannot create portfolio for this activity as the activity is null."; - log.error(error); - throw new ExportPortfolioException(error); - } - ActivityPortfolio p = new ActivityPortfolio(); - p.setActivityId(activity.getActivityId()); - p.setActivityName(activity.getTitle()); - p.setActivityDescription(activity.getDescription()); - return p; + /** + * Process all Notebook (Scratchpad) entries into portfolio objects. + * + * @param notebookAccessMode + * The access mode that determines what entries are returned. + */ + public void processNotebook(ToolAccessMode notebookAccessMode) throws ExportPortfolioException { + List entries = null; + + if (lesson == null || user == null) { + throw new ExportPortfolioException(); } - - /** - * Creates a portfolio object with properties title and entry from the NotebookEntry. - * @param entry The Notebook Entry - * @return a Portfolio object - */ - protected NotebookPortfolio createNotebookPortfolio(NotebookEntry entry) - { - if (entry == null) - { - String error="Cannot create portfolio for this notebook entry as the entry is null."; - log.error(error); - throw new ExportPortfolioException(error); - } - - NotebookPortfolio p = new NotebookPortfolio(); - p.setEntry(entry.getEntry()); - p.setTitle(entry.getTitle()); - p.setCreated(entry.getCreateDate()); - p.setModified(entry.getLastModified()); - - if(entry.getExternalSignature().equals(CoreNotebookConstants.JOURNAL_SIG)) - p.setTeacherViewable(true); - else - p.setTeacherViewable(false); - - return p; + + if (notebookAccessMode == null) { + entries = coreNotebookService.getEntry(lesson.getLessonId(), CoreNotebookConstants.SCRATCH_PAD, user + .getUserId()); + } else if (notebookAccessMode.equals(ToolAccessMode.TEACHER)) { + entries = coreNotebookService.getEntry(lesson.getLessonId(), CoreNotebookConstants.SCRATCH_PAD, + CoreNotebookConstants.JOURNAL_SIG, user.getUserId()); } - /** Get the list of all the activity portfolios, which in turn may contain other activity portfolios */ - public ArrayList getPortfolioList() { - return mainPortfolioList; + if (entries == null) { + throw new ExportPortfolioException(); } - - /** - * Get the list of notebook entries - * @return - */ - public ArrayList getNotebookList() { - return mainNotebookList; + + Iterator it = entries.iterator(); + + while (it.hasNext()) { + NotebookEntry entry = (NotebookEntry) it.next(); + NotebookPortfolio portfolio = createNotebookPortfolio(entry); + currentNotebookList.add(portfolio); } - + } + + /** + * Obtains the Tool from the ToolActivity and creates a portfolio object with properties activityId, activityName, + * activityDescription, exportURL set to the value of the ToolActivity's properties activityId, toolDisplayName + * (retrieved from Tool object), title, exportPortfolioUrl respestively. + * + * @param activity + * The Tool Activity + * @return a Portfolio object + */ + protected ActivityPortfolio createActivityPortfolio(Activity activity) { + if (activity == null) { + String error = "Cannot create portfolio for this activity as the activity is null."; + PortfolioBuilder.log.error(error); + throw new ExportPortfolioException(error); + } + ActivityPortfolio p = new ActivityPortfolio(); + p.setActivityId(activity.getActivityId()); + p.setActivityName(activity.getTitle()); + p.setActivityDescription(activity.getDescription()); + return p; + } + + /** + * Creates a portfolio object with properties title and entry from the NotebookEntry. + * + * @param entry + * The Notebook Entry + * @return a Portfolio object + */ + protected NotebookPortfolio createNotebookPortfolio(NotebookEntry entry) { + if (entry == null) { + String error = "Cannot create portfolio for this notebook entry as the entry is null."; + PortfolioBuilder.log.error(error); + throw new ExportPortfolioException(error); + } + + NotebookPortfolio p = new NotebookPortfolio(); + p.setEntry(entry.getEntry()); + p.setTitle(entry.getTitle()); + p.setCreated(entry.getCreateDate()); + p.setModified(entry.getLastModified()); + + if (entry.getExternalSignature().equals(CoreNotebookConstants.JOURNAL_SIG)) { + p.setTeacherViewable(true); + } else { + p.setTeacherViewable(false); + } + + return p; + } + + /** Get the list of all the activity portfolios, which in turn may contain other activity portfolios */ + public ArrayList getPortfolioList() { + return mainPortfolioList; + } + + /** + * Get the list of notebook entries + * + * @return + */ + public ArrayList getNotebookList() { + return mainNotebookList; + } + } Index: lams_learning/web/WEB-INF/tags/ExportPortOutput.tag =================================================================== diff -u -r7ca6b86e6407b3720c327feaeda3b1c5e8dc19b5 -r240f5a89847764532283243060c07572f88cc5cf --- lams_learning/web/WEB-INF/tags/ExportPortOutput.tag (.../ExportPortOutput.tag) (revision 7ca6b86e6407b3720c327feaeda3b1c5e8dc19b5) +++ lams_learning/web/WEB-INF/tags/ExportPortOutput.tag (.../ExportPortOutput.tag) (revision 240f5a89847764532283243060c07572f88cc5cf) @@ -34,6 +34,7 @@ <%@ attribute name="actport" required="true" rtexprvalue="true" type="org.lamsfoundation.lams.learning.export.ActivityPortfolio" %> <%@ taglib uri="tags-core" prefix="c" %> <%@ taglib uri="tags-lams" prefix="lams" %> +<%@ taglib uri="tags-fmt" prefix="fmt" %>

  • @@ -54,6 +55,14 @@ + +
    +
      + +
    • ${competenceName}
    • +
      +
    +
  • Index: lams_learning/web/exportPortfolio/main.jsp =================================================================== diff -u -r64938df458cbab9999f9a826ef2902d061648d7d -r240f5a89847764532283243060c07572f88cc5cf --- lams_learning/web/exportPortfolio/main.jsp (.../main.jsp) (revision 64938df458cbab9999f9a826ef2902d061648d7d) +++ lams_learning/web/exportPortfolio/main.jsp (.../main.jsp) (revision 240f5a89847764532283243060c07572f88cc5cf) @@ -61,13 +61,31 @@

    +

    - + + +

    + + + + + + + + + + + +
    ${competence.title}${competence.description}
    +
    +
    +