/** * OLAT - Online Learning and Training<br> * http://www.olat.org * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> * you may not use this file except in compliance with the License.<br> * You may obtain a copy of the License at * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * Unless required by applicable law or agreed to in writing,<br> * software distributed under the License is distributed on an "AS IS" BASIS, <br> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> * See the License for the specific language governing permissions and <br> * limitations under the License. * <p> * Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> * University of Zurich, Switzerland. * <hr> * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * This file has been modified by the OpenOLAT community. Changes are licensed * under the Apache 2.0 license as the original file. * <p> * Initial code contributed and copyrighted by<br> * Technische Universitaet Chemnitz Lehrstuhl Technische Informatik<br> * <br> * Author Marcel Karras (toka@freebits.de)<br> * Author Norbert Englisch (norbert.englisch@informatik.tu-chemnitz.de)<br> * Author Sebastian Fritzsche (seb.fritzsche@googlemail.com) */ package de.tuchemnitz.wizard.workflows.coursecreation; import java.util.ArrayList; import java.util.List; import java.util.Locale; import org.olat.basesecurity.BaseSecurityManager; import org.olat.collaboration.CollaborationTools; import org.olat.collaboration.CollaborationToolsFactory; import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.translator.Translator; import org.olat.core.id.UserConstants; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.Util; import org.olat.course.CourseFactory; import org.olat.course.ICourse; import org.olat.course.condition.Condition; import org.olat.course.editor.CourseEditorHelper; import org.olat.course.editor.PublishProcess; import org.olat.course.editor.PublishSetInformations; import org.olat.course.editor.StatusDescription; import org.olat.course.nodes.AbstractAccessableCourseNode; import org.olat.course.nodes.BCCourseNode; import org.olat.course.nodes.COCourseNode; import org.olat.course.nodes.CourseNode; import org.olat.course.nodes.ENCourseNode; import org.olat.course.nodes.FOCourseNode; import org.olat.course.nodes.SPCourseNode; import org.olat.course.nodes.co.COEditController; import org.olat.course.nodes.sp.SPEditController; import org.olat.course.tree.CourseEditorTreeModel; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; import org.olat.repository.CatalogEntry; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; import org.olat.repository.manager.CatalogManager; import de.tuchemnitz.wizard.helper.course.CourseExtensionHelper; import de.tuchemnitz.wizard.helper.course.HTMLDocumentHelper; import de.tuchemnitz.wizard.workflows.coursecreation.model.CourseCreationConfiguration; /** * * Description:<br> * This helper class is responsible for finalizing the course creation wizard. * It reads the prepared configuration and creates the course with the necessary * course nodes and contents. * * <P> * @author Marcel Karras (toka@freebits.de) * @author Norbert Englisch (norbert.englisch@informatik.tu-chemnitz.de) * @author Sebastian Fritzsche (seb.fritzsche@googlemail.com) */ public class CourseCreationHelper { private static final OLog log = Tracing.createLoggerFor(CourseCreationHelper.class); private CourseCreationConfiguration courseConfig; private final Translator translator; private ICourse course; private RepositoryEntry addedEntry; /** * Beendet den CourseCreationWizard * * @param ureq * @param control * @param repoEntry * @param courseConfig * @param course * @author Norbert Englisch (norbert.englisch@informatik.tu-chemnitz.de) * @author Sebastian Fritzsche (seb.fritzsche@googlemail.com) */ public CourseCreationHelper(Locale locale, final RepositoryEntry repoEntry, CourseCreationConfiguration courseConfig, ICourse course) { this.translator = Util.createPackageTranslator(CourseCreationHelper.class, locale); this.addedEntry = repoEntry; this.course = course; this.courseConfig = courseConfig; } /** * @return the created course */ public final RepositoryEntry getUserObject() { return addedEntry; } /** * @return the currently course configuration */ public final CourseCreationConfiguration getConfiguration() { return courseConfig; } /** * Finalizes the course creation workflow via wizard. * @param ureq */ public void finalizeWorkflow(final UserRequest ureq) { // -------------------------- // 1. insert the course nodes // -------------------------- // single page node CourseNode singlePageNode = null; if (courseConfig.isCreateSinglePage()) { singlePageNode = CourseExtensionHelper.createSinglePageNode(course, translator.translate("cce.informationpage"), translator .translate("cce.informationpage.descr")); if (singlePageNode instanceof SPCourseNode) { final String relPath = CourseEditorHelper.createUniqueRelFilePathFromShortTitle(singlePageNode, course.getCourseFolderContainer()); HTMLDocumentHelper.createHtmlDocument(course, relPath, courseConfig.getSinglePageText(translator)); ((SPCourseNode) singlePageNode).getModuleConfiguration().set(SPEditController.CONFIG_KEY_FILE, relPath); } } // enrollment node CourseNode enCourseNode = null; if (courseConfig.isCreateEnrollment()) { enCourseNode = CourseExtensionHelper.createEnrollmentNode(course, translator.translate("cce.enrollment"), translator .translate("cce.enrollment.descr")); } // download folder node CourseNode downloadFolderNode = null; if (courseConfig.isCreateDownloadFolder()) { downloadFolderNode = CourseExtensionHelper.createDownloadFolderNode(course, translator.translate("cce.downloadfolder"), translator.translate("cce.downloadfolder.descr")); } // forum node CourseNode forumNode = null; if (courseConfig.isCreateForum()) { forumNode = CourseExtensionHelper.createForumNode(course, translator.translate("cce.forum"), translator .translate("cce.forum.descr")); } // contact form node CourseNode contactNode = null; if (courseConfig.isCreateContactForm()) { contactNode = CourseExtensionHelper.createContactFormNode(course, translator.translate("cce.contactform"), translator .translate("cce.contactform.descr")); if (contactNode instanceof COCourseNode) { final List<String> emails = new ArrayList<String>(); String subject = translator.translate("cce.contactform.subject") + " " + courseConfig.getCourseTitle(); emails.add(ureq.getIdentity().getUser().getProperty(UserConstants.EMAIL, ureq.getLocale())); COCourseNode cocn = (COCourseNode) contactNode; cocn.getModuleConfiguration().set(COEditController.CONFIG_KEY_EMAILTOADRESSES, emails); cocn.getModuleConfiguration().set(COEditController.CONFIG_KEY_MSUBJECT_DEFAULT, subject); } } // enrollment node if (courseConfig.isCreateEnrollment()) { // -------------------------- // 2. setup enrollment // -------------------------- final String groupBaseName = createGroupBaseName(); final BusinessGroupService bgs = CoreSpringFactory.getImpl(BusinessGroupService.class); // get default context for learning groups // create n learning groups with m allowed members String comma = ""; String tmpGroupList = ""; String groupNamesList = ""; for (int i = 0; i < courseConfig.getGroupCount(); i++) { // create group String name = groupBaseName + " " + (i + 1); BusinessGroup learningGroup = bgs.createBusinessGroup(ureq.getIdentity(), name, null, 0, courseConfig.getSubscriberCount(), courseConfig.getEnableWaitlist(), courseConfig.getEnableFollowup(), addedEntry); // enable the contact collaboration tool CollaborationTools ct = CollaborationToolsFactory.getInstance().getOrCreateCollaborationTools(learningGroup); ct.setToolEnabled(CollaborationTools.TOOL_CONTACT, true); // append to current learning group list groupNamesList = tmpGroupList + comma + learningGroup.getName(); enCourseNode.getModuleConfiguration().set(ENCourseNode.CONFIG_GROUPNAME, groupNamesList); if (i == 0) { comma = ","; } tmpGroupList = (String) enCourseNode.getModuleConfiguration().get(ENCourseNode.CONFIG_GROUPNAME); } // set signout property enCourseNode.getModuleConfiguration().set(ENCourseNode.CONF_CANCEL_ENROLL_ENABLED, courseConfig.getEnableSignout()); // access limits on chosen course elements if (courseConfig.getEnableAccessLimit()) { if (courseConfig.isEnableAclContactForm()) { if (contactNode instanceof COCourseNode) { Condition c = ((COCourseNode) contactNode).getPreConditionVisibility(); c.setEasyModeGroupAccess(groupNamesList); ((COCourseNode) contactNode).setNoAccessExplanation(translator.translate("noaccessexplain")); // calculate expression from easy mode form String condString = c.getConditionFromEasyModeConfiguration(); c.setConditionExpression(condString); c.setExpertMode(false); } } if (courseConfig.isEnableAclSinglePage()) { if (singlePageNode instanceof SPCourseNode) { Condition c = ((SPCourseNode) singlePageNode).getPreConditionVisibility(); c.setEasyModeGroupAccess(groupNamesList); ((SPCourseNode) singlePageNode).setNoAccessExplanation(translator.translate("noaccessexplain")); // calculate expression from easy mode form String condString = c.getConditionFromEasyModeConfiguration(); c.setConditionExpression(condString); c.setExpertMode(false); } } if (courseConfig.isEnableAclForum()) { if (forumNode instanceof FOCourseNode) { Condition c = ((FOCourseNode) forumNode).getPreConditionVisibility(); c.setEasyModeGroupAccess(groupNamesList); ((FOCourseNode) forumNode).setNoAccessExplanation(translator.translate("noaccessexplain")); // calculate expression from easy mode form String condString = c.getConditionFromEasyModeConfiguration(); c.setConditionExpression(condString); c.setExpertMode(false); } } if (courseConfig.isEnableAclDownloadFolder()) { if (downloadFolderNode instanceof BCCourseNode) { Condition c = ((BCCourseNode) downloadFolderNode).getPreConditionVisibility(); c.setEasyModeGroupAccess(groupNamesList); ((BCCourseNode) downloadFolderNode).setNoAccessExplanation(translator.translate("noaccessexplain")); // calculate expression from easy mode form String condString = c.getConditionFromEasyModeConfiguration(); c.setConditionExpression(condString); c.setExpertMode(false); } } } } // -------------------------- // 3. persist complete course // -------------------------- // -------------------------- // 3.1. setup rights // -------------------------- if (courseConfig.getPublish()) { int access = RepositoryEntry.ACC_OWNERS; if (courseConfig.getAclType().equals(CourseCreationConfiguration.ACL_GUEST)) { // set "BARG" as rule access = RepositoryEntry.ACC_USERS_GUESTS; } else if (courseConfig.getAclType().equals(CourseCreationConfiguration.ACL_OLAT)) { // set "BAR" as rule access = RepositoryEntry.ACC_USERS; } else if (courseConfig.getAclType().equals(CourseCreationConfiguration.ACL_UNI)) { // set "BAR" rule + expert rule on university // hasAttribute("institution","[Hochschule]") access = RepositoryEntry.ACC_USERS; final CourseNode cnRoot = course.getEditorTreeModel().getCourseEditorNodeById(course.getEditorTreeModel().getRootNode().getIdent()) .getCourseNode(); String shibInstitution = ureq.getIdentity().getUser().getProperty(UserConstants.INSTITUTIONALNAME, ureq.getLocale()); if (shibInstitution == null) { shibInstitution = ureq.getUserSession().getSessionInfo().getAuthProvider(); } cnRoot.setNoAccessExplanation(translator.translate("noaccessroot", new String[] {shibInstitution})); if (cnRoot instanceof AbstractAccessableCourseNode) { ((AbstractAccessableCourseNode) cnRoot).setPreConditionAccess(new Condition("hasAttribute(\"institution\",\"" + shibInstitution + "\")")); } } else { log.error("No valid ACL Rule: " + courseConfig.getAclType()); } addedEntry = RepositoryManager.getInstance().setAccess(addedEntry, access, false); } course = CourseFactory.openCourseEditSession(course.getResourceableId()); course.getRunStructure().getRootNode().setShortTitle(addedEntry.getDisplayname()); course.getRunStructure().getRootNode().setLongTitle(addedEntry.getDisplayname()); CourseFactory.saveCourse(course.getResourceableId()); final CourseEditorTreeModel cetm = course.getEditorTreeModel(); final CourseNode rootNode = cetm.getCourseNode(course.getRunStructure().getRootNode().getIdent()); rootNode.setShortTitle(addedEntry.getDisplayname()); rootNode.setLongTitle(addedEntry.getDisplayname()); course.getEditorTreeModel().nodeConfigChanged(course.getRunStructure().getRootNode()); CourseFactory.saveCourseEditorTreeModel(course.getResourceableId()); // -------------------------- // 3.2 publish the course // -------------------------- // fetch publish process final PublishProcess pp = PublishProcess.getInstance(course, cetm, ureq.getLocale()); final StatusDescription[] sds; // create publish node list List<String> nodeIds = new ArrayList<String>(); nodeIds.add(cetm.getRootNode().getIdent()); for (int i = 0; i < cetm.getRootNode().getChildCount(); i++) { nodeIds.add(cetm.getRootNode().getChildAt(i).getIdent()); } pp.createPublishSetFor(nodeIds); PublishSetInformations set = pp.testPublishSet(ureq.getLocale()); sds = set.getWarnings(); boolean isValid = sds.length == 0; if (!isValid) { // no error and no warnings -> return immediate log.error("Course Publishing failed", new AssertionError()); } pp.applyPublishSet(ureq.getIdentity(), ureq.getLocale(), true); CourseFactory.closeCourseEditSession(course.getResourceableId(), true); // save catalog entry if (getConfiguration().getSelectedCatalogEntry() != null) { CatalogManager cm = CoreSpringFactory.getImpl(CatalogManager.class); CatalogEntry newEntry = cm.createCatalogEntry(); newEntry.setRepositoryEntry(addedEntry); newEntry.setName(addedEntry.getDisplayname()); newEntry.setDescription(addedEntry.getDescription()); newEntry.setType(CatalogEntry.TYPE_LEAF); newEntry.setOwnerGroup(BaseSecurityManager.getInstance().createAndPersistSecurityGroup()); // save entry cm.addCatalogEntry(getConfiguration().getSelectedCatalogEntry(), newEntry); } } /** * Internal helper method to create the group names * @return group name */ private String createGroupBaseName() { String groupBaseName = course.getCourseTitle() + " " + translator.translate("group"); groupBaseName = groupBaseName.replace("\"", "'"); groupBaseName = groupBaseName.replace(",", " "); return groupBaseName; } }