Search in sources :

Example 31 with CourseEditorTreeModel

use of org.olat.course.tree.CourseEditorTreeModel in project OpenOLAT by OpenOLAT.

the class PublishProcess method testPublishSet.

/**
 * can only be called after createPublishSetFor method. The method calculates the
 * resulting runstructure, and checks them against error and warning messages.
 * These are returned as a list of StatusDescriptions.<br>
 * If status ok -> apply the publish set -> this changes the course effectively
 *
 * @param locale
 * @return
 */
public PublishSetInformations testPublishSet(Locale locale) {
    // check for valid references to tests, resource folder, wiki
    List<StatusDescription> damagedRefsInsertedNodes = checkRefs(editorModelInsertedNodes);
    if (damagedRefsInsertedNodes.size() > 0) {
        // abort testing as a blocking error found!
        StatusDescription[] status = new StatusDescription[damagedRefsInsertedNodes.size()];
        status = damagedRefsInsertedNodes.toArray(status);
        return new PublishSetInformations(status);
    }
    List<StatusDescription> damagedRefsModifiedNodes = checkRefs(editorModelModifiedNodes);
    if (damagedRefsModifiedNodes.size() > 0) {
        // abort testing as a blocking error found
        StatusDescription[] status = new StatusDescription[damagedRefsModifiedNodes.size()];
        status = damagedRefsModifiedNodes.toArray(status);
        return new PublishSetInformations(status);
    }
    CourseNode clonedCourseNode = (CourseNode) ObjectCloner.deepCopy(resultingCourseRun.getRootNode());
    CourseEditorTreeNode clonedRoot = new CourseEditorTreeNode(clonedCourseNode);
    convertInCourseEditorTreeNode(clonedRoot, clonedCourseNode);
    // Do remove all children after convertInCourseEditorTreeNode
    clonedCourseNode.removeAllChildren();
    CourseEditorTreeModel cloneCETM = new CourseEditorTreeModel();
    cloneCETM.setRootNode(clonedRoot);
    /*
		 * now we have the cloned editor tree synchronized with the pre-published
		 * runstructure. The cloned editor tree is used within a new
		 * CourseEditorEnvironment which is placed in a new Editor User Course
		 * Session for evaluation only. This is like opening the runstructure in a
		 * virtual course editor for using the validation facilities of the editor
		 * environment.
		 */
    CourseEditorEnv tmpCEV = new CourseEditorEnvImpl(cloneCETM, course.getCourseEnvironment().getCourseGroupManager(), locale);
    // the resulting object is not needed, but constructor makes
    // initializations within tmpCEV!! thus important step.
    new EditorUserCourseEnvironmentImpl(tmpCEV, null);
    // 
    tmpCEV.setCurrentCourseNodeId(cloneCETM.getRootNode().getIdent());
    tmpCEV.validateCourse();
    StatusDescription[] status = tmpCEV.getCourseStatus();
    // check if the resulting course contains cycles.
    Set<String> nodesInCycle = tmpCEV.listCycles();
    if (nodesInCycle.size() > 0) {
        // there are nodes generating cylces -> error! this is not a publishable
        // set!
        StringBuilder sb = new StringBuilder();
        for (String id : nodesInCycle) {
            String title = editorTreeModel.getCourseEditorNodeById(id).getTitle();
            sb.append("<b>").append(title).append("</b> ").append("(id:").append(id).append(")<br>");
        }
        StatusDescription sd = new StatusDescription(ValidationStatus.ERROR, "pbl.error.cycles", "pbl.error.cycles", new String[] { sb.toString() }, PACKAGE);
        status = new StatusDescription[] { sd };
    } else {
        /*
			 * these are now status description as they are helpful in the editor
			 * context. The same errors in the publish context have a kind of
			 * different meaning --- Let the nodes explain what it means in publish
			 * mode.
			 */
        for (int i = 0; i < status.length; i++) {
            StatusDescription description = status[i];
            String nodeId = description.getDescriptionForUnit();
            CourseNode cn = cloneCETM.getCourseNode(nodeId);
            status[i] = cn.explainThisDuringPublish(description);
        }
    }
    List<StatusDescription> updateNotifications = testUpdateSet(tmpCEV);
    return new PublishSetInformations(status, updateNotifications);
}
Also used : CourseEditorTreeModel(org.olat.course.tree.CourseEditorTreeModel) CourseEditorTreeNode(org.olat.course.tree.CourseEditorTreeNode) CourseNode(org.olat.course.nodes.CourseNode)

Example 32 with CourseEditorTreeModel

use of org.olat.course.tree.CourseEditorTreeModel in project OpenOLAT by OpenOLAT.

the class ChooseNodeController method doCreateNode.

private void doCreateNode(String type) {
    ICourse course = CourseFactory.getCourseEditSession(courseOres.getResourceableId());
    // user chose a position to insert a new node
    CourseNodeConfiguration newNodeConfig = CourseNodeFactory.getInstance().getCourseNodeConfiguration(type);
    createdNode = newNodeConfig.getInstance();
    // Set some default values
    String title = new String(newNodeConfig.getLinkText(getLocale()));
    createdNode.setShortTitle(title);
    createdNode.setNoAccessExplanation(translate("form.noAccessExplanation.default"));
    // Insert it now
    CourseEditorTreeModel editorTreeModel = course.getEditorTreeModel();
    if (editorTreeModel.getRootNode().equals(currentNode)) {
        // root, add as last child
        int pos = currentNode.getChildCount();
        CourseNode selectedNode = currentNode.getCourseNode();
        editorTreeModel.insertCourseNodeAt(createdNode, selectedNode, pos);
    } else {
        CourseEditorTreeNode parentNode = (CourseEditorTreeNode) currentNode.getParent();
        CourseNode selectedNode = parentNode.getCourseNode();
        int pos = currentNode.getPosition();
        editorTreeModel.insertCourseNodeAt(createdNode, selectedNode, pos + 1);
    }
    CourseFactory.saveCourseEditorTreeModel(course.getResourceableId());
}
Also used : CourseEditorTreeModel(org.olat.course.tree.CourseEditorTreeModel) CourseEditorTreeNode(org.olat.course.tree.CourseEditorTreeNode) ICourse(org.olat.course.ICourse) CourseNodeConfiguration(org.olat.course.nodes.CourseNodeConfiguration) CourseNode(org.olat.course.nodes.CourseNode)

Example 33 with CourseEditorTreeModel

use of org.olat.course.tree.CourseEditorTreeModel in project OpenOLAT by OpenOLAT.

the class NodeExportVisitor method exportToFilesystem.

/**
 * @see org.olat.course.ICourse#exportToFilesystem(java.io.File)
 * <p>
 * See OLAT-5368: Course Export can take longer than say 2min.
 * <p>
 */
@Override
public void exportToFilesystem(OLATResource originalCourseResource, File exportDirectory, boolean runtimeDatas, boolean backwardsCompatible) {
    long s = System.currentTimeMillis();
    log.info("exportToFilesystem: exporting course " + this + " to " + exportDirectory + "...");
    File fCourseBase = getCourseBaseContainer().getBasefile();
    // make the folder structure
    File fExportedDataDir = new File(exportDirectory, EXPORTED_DATA_FOLDERNAME);
    fExportedDataDir.mkdirs();
    // export course config
    FileUtils.copyFileToDir(new File(fCourseBase, CourseConfigManager.COURSECONFIG_XML), exportDirectory, "course export courseconfig");
    // export business groups
    CourseEnvironmentMapper envMapper = getCourseEnvironment().getCourseGroupManager().getBusinessGroupEnvironment();
    if (backwardsCompatible) {
        // prevents duplicate names
        envMapper.avoidDuplicateNames();
    }
    getCourseEnvironment().getCourseGroupManager().exportCourseBusinessGroups(fExportedDataDir, envMapper, runtimeDatas, backwardsCompatible);
    if (backwardsCompatible) {
        XStream xstream = CourseXStreamAliases.getReadCourseXStream();
        Structure exportedStructure = (Structure) XStreamHelper.readObject(xstream, new File(fCourseBase, RUNSTRUCTURE_XML));
        visit(new NodePostExportVisitor(envMapper, backwardsCompatible), exportedStructure.getRootNode());
        XStreamHelper.writeObject(xstream, new File(exportDirectory, RUNSTRUCTURE_XML), exportedStructure);
        CourseEditorTreeModel exportedEditorModel = (CourseEditorTreeModel) XStreamHelper.readObject(xstream, new File(fCourseBase, EDITORTREEMODEL_XML));
        visit(new NodePostExportVisitor(envMapper, backwardsCompatible), exportedEditorModel.getRootNode());
        XStreamHelper.writeObject(xstream, new File(exportDirectory, EDITORTREEMODEL_XML), exportedEditorModel);
    } else {
        // export editor structure
        FileUtils.copyFileToDir(new File(fCourseBase, EDITORTREEMODEL_XML), exportDirectory, "course export exitortreemodel");
        // export run structure
        FileUtils.copyFileToDir(new File(fCourseBase, RUNSTRUCTURE_XML), exportDirectory, "course export runstructure");
    }
    // export layout and media folder
    FileUtils.copyDirToDir(new File(fCourseBase, "layout"), exportDirectory, "course export layout folder");
    FileUtils.copyDirToDir(new File(fCourseBase, "media"), exportDirectory, "course export media folder");
    // export course folder
    FileUtils.copyDirToDir(getIsolatedCourseBaseFolder(), exportDirectory, "course export folder");
    // export any node data
    log.info("exportToFilesystem: exporting course " + this + ": exporting all nodes...");
    Visitor visitor = new NodeExportVisitor(fExportedDataDir, this);
    TreeVisitor tv = new TreeVisitor(visitor, getEditorTreeModel().getRootNode(), true);
    tv.visitAll();
    log.info("exportToFilesystem: exporting course " + this + ": exporting all nodes...done.");
    // OLAT-5368: do intermediate commit to avoid transaction timeout
    // discussion intermediatecommit vs increased transaction timeout:
    // pro intermediatecommit: not much
    // pro increased transaction timeout: would fix OLAT-5368 but only move the problem
    // @TODO OLAT-2597: real solution is a long-running background-task concept...
    DBFactory.getInstance().intermediateCommit();
    // export shared folder
    CourseConfig config = getCourseConfig();
    if (config.hasCustomSharedFolder()) {
        log.info("exportToFilesystem: exporting course " + this + ": shared folder...");
        if (!SharedFolderManager.getInstance().exportSharedFolder(config.getSharedFolderSoftkey(), fExportedDataDir)) {
            // export failed, delete reference to shared folder in the course config
            log.info("exportToFilesystem: exporting course " + this + ": export of shared folder failed.");
            config.setSharedFolderSoftkey(CourseConfig.VALUE_EMPTY_SHAREDFOLDER_SOFTKEY);
            CourseConfigManagerImpl.getInstance().saveConfigTo(this, config);
        }
        log.info("exportToFilesystem: exporting course " + this + ": shared folder...done.");
    }
    // OLAT-5368: do intermediate commit to avoid transaction timeout
    // discussion intermediatecommit vs increased transaction timeout:
    // pro intermediatecommit: not much
    // pro increased transaction timeout: would fix OLAT-5368 but only move the problem
    // @TODO OLAT-2597: real solution is a long-running background-task concept...
    DBFactory.getInstance().intermediateCommit();
    // export glossary
    if (config.hasGlossary()) {
        log.info("exportToFilesystem: exporting course " + this + ": glossary...");
        if (!GlossaryManager.getInstance().exportGlossary(config.getGlossarySoftKey(), fExportedDataDir)) {
            // export failed, delete reference to glossary in the course config
            log.info("exportToFilesystem: exporting course " + this + ": export of glossary failed.");
            config.setGlossarySoftKey(null);
            CourseConfigManagerImpl.getInstance().saveConfigTo(this, config);
        }
        log.info("exportToFilesystem: exporting course " + this + ": glossary...done.");
    }
    // OLAT-5368: do intermediate commit to avoid transaction timeout
    // discussion intermediatecommit vs increased transaction timeout:
    // pro intermediatecommit: not much
    // pro increased transaction timeout: would fix OLAT-5368 but only move the problem
    // @TODO OLAT-2597: real solution is a long-running background-task concept...
    DBFactory.getInstance().intermediateCommit();
    log.info("exportToFilesystem: exporting course " + this + ": configuration and repo data...");
    // export configuration file
    FileUtils.copyFileToDir(new File(fCourseBase, CourseConfigManager.COURSECONFIG_XML), exportDirectory, "course export configuration and repo info");
    // export repo metadata
    RepositoryManager rm = RepositoryManager.getInstance();
    RepositoryEntry myRE = rm.lookupRepositoryEntry(this, true);
    RepositoryEntryImportExport importExport = new RepositoryEntryImportExport(myRE, fExportedDataDir);
    importExport.exportDoExportProperties();
    // OLAT-5368: do intermediate commit to avoid transaction timeout
    // discussion intermediatecommit vs increased transaction timeout:
    // pro intermediatecommit: not much
    // pro increased transaction timeout: would fix OLAT-5368 but only move the problem
    // @TODO OLAT-2597: real solution is a long-running background-task concept...
    DBFactory.getInstance().intermediateCommit();
    // export reminders
    CoreSpringFactory.getImpl(ReminderService.class).exportReminders(myRE, fExportedDataDir);
    log.info("exportToFilesystem: exporting course " + this + " to " + exportDirectory + " done.");
    log.info("finished export course '" + getCourseTitle() + "' in t=" + Long.toString(System.currentTimeMillis() - s));
}
Also used : CourseEditorTreeModel(org.olat.course.tree.CourseEditorTreeModel) TreeVisitor(org.olat.core.util.tree.TreeVisitor) Visitor(org.olat.core.util.tree.Visitor) RepositoryEntryImportExport(org.olat.repository.RepositoryEntryImportExport) ReminderService(org.olat.modules.reminder.ReminderService) XStream(com.thoughtworks.xstream.XStream) RepositoryEntry(org.olat.repository.RepositoryEntry) CourseConfig(org.olat.course.config.CourseConfig) TreeVisitor(org.olat.core.util.tree.TreeVisitor) RepositoryManager(org.olat.repository.RepositoryManager) File(java.io.File) CourseEnvironmentMapper(org.olat.course.export.CourseEnvironmentMapper)

Example 34 with CourseEditorTreeModel

use of org.olat.course.tree.CourseEditorTreeModel in project OpenOLAT by OpenOLAT.

the class NodeExportVisitor method postImport.

@Override
public void postImport(File importDirectory, CourseEnvironmentMapper envMapper) {
    Structure importedStructure = getRunStructure();
    visit(new NodePostImportVisitor(importDirectory, this, envMapper, Processing.runstructure), importedStructure.getRootNode());
    saveRunStructure();
    CourseEditorTreeModel importedEditorModel = getEditorTreeModel();
    visit(new NodePostImportVisitor(importDirectory, this, envMapper, Processing.editor), importedEditorModel.getRootNode());
    saveEditorTreeModel();
}
Also used : CourseEditorTreeModel(org.olat.course.tree.CourseEditorTreeModel)

Example 35 with CourseEditorTreeModel

use of org.olat.course.tree.CourseEditorTreeModel in project openolat by klemens.

the class PublishProcessTest method testPublishANotReallyNewNodeButDeleted.

/**
 * Publish a course with a node marked as new and deleted but the
 * node exists already in the run structure.
 *
 * @throws URISyntaxException
 */
@Test
public void testPublishANotReallyNewNodeButDeleted() throws URISyntaxException {
    Identity author = JunitTestHelper.createAndPersistIdentityAsAdmin("publisher-" + UUID.randomUUID().toString());
    RepositoryEntry re = deployTestCourse("simple_course_err2_new_deleted.zip");
    // change node 1
    ICourse course = CourseFactory.loadCourse(re.getOlatResource().getResourceableId());
    CourseEditorTreeModel cetm = course.getEditorTreeModel();
    CourseEditorTreeNode node1 = (CourseEditorTreeNode) cetm.getRootNode().getChildAt(0);
    // publish the course and must survive this without exception
    // as the course has no changes but we try to publish it
    List<String> nodeIds = Collections.singletonList(node1.getIdent());
    publishCourse(nodeIds, re, author);
    // check the change
    ICourse reloadedCourse = CourseFactory.loadCourse(re.getOlatResource().getResourceableId());
    Assert.assertEquals(2, reloadedCourse.getRunStructure().getRootNode().getChildCount());
    INode runNode2 = reloadedCourse.getRunStructure().getRootNode().getChildAt(0);
    Assert.assertNotNull(runNode2);
    CourseNode runNode2Impl = (CourseNode) runNode2;
    Assert.assertEquals("Node 2", runNode2Impl.getShortTitle());
}
Also used : INode(org.olat.core.util.nodes.INode) CourseEditorTreeModel(org.olat.course.tree.CourseEditorTreeModel) CourseEditorTreeNode(org.olat.course.tree.CourseEditorTreeNode) ICourse(org.olat.course.ICourse) RepositoryEntry(org.olat.repository.RepositoryEntry) CourseNode(org.olat.course.nodes.CourseNode) Identity(org.olat.core.id.Identity) Test(org.junit.Test)

Aggregations

CourseEditorTreeModel (org.olat.course.tree.CourseEditorTreeModel)46 ICourse (org.olat.course.ICourse)26 CourseNode (org.olat.course.nodes.CourseNode)26 CourseEditorTreeNode (org.olat.course.tree.CourseEditorTreeNode)24 Test (org.junit.Test)18 RepositoryEntry (org.olat.repository.RepositoryEntry)16 Identity (org.olat.core.id.Identity)14 INode (org.olat.core.util.nodes.INode)12 ArrayList (java.util.ArrayList)6 CourseNodeConfiguration (org.olat.course.nodes.CourseNodeConfiguration)6 File (java.io.File)4 URI (java.net.URI)4 HttpEntity (org.apache.http.HttpEntity)4 HttpResponse (org.apache.http.HttpResponse)4 HttpPost (org.apache.http.client.methods.HttpPost)4 HttpPut (org.apache.http.client.methods.HttpPut)4 AssertException (org.olat.core.logging.AssertException)4 CourseConfig (org.olat.course.config.CourseConfig)4 PublishProcess (org.olat.course.editor.PublishProcess)4 PublishSetInformations (org.olat.course.editor.PublishSetInformations)4