use of org.olat.core.util.tree.TreeVisitor in project OpenOLAT by OpenOLAT.
the class MoveCopySubtreeController method doInsert.
private void doInsert(UserRequest ureq, TreePosition tp) {
ICourse course = CourseFactory.getCourseEditSession(ores.getResourceableId());
int insertPos = tp.getChildpos();
CourseNode selectedNode = getCourseNode(tp.getParentTreeNode());
CourseEditorTreeNode insertParent = course.getEditorTreeModel().getCourseEditorNodeById(selectedNode.getIdent());
// check if insert position is within the to-be-copied tree
if (course.getEditorTreeModel().checkIfIsChild(insertParent, moveCopyFrom)) {
showError("movecopynode.error.overlap");
fireEvent(ureq, Event.CANCELLED_EVENT);
} else if (copy) {
// do a copy
// copy subtree and save model
recursiveCopy(moveCopyFrom, insertParent, insertPos, true, CourseFactory.getCourseEditSession(ores.getResourceableId()));
CourseFactory.saveCourseEditorTreeModel(course.getResourceableId());
ThreadLocalUserActivityLogger.log(CourseLoggingAction.COURSE_EDITOR_NODE_COPIED, getClass());
fireEvent(ureq, Event.DONE_EVENT);
} else {
// move only
if (insertParent.getIdent().equals(moveCopyFrom.getParent().getIdent())) {
// same parent, adjust insertPos
if (insertPos > moveCopyFrom.getPosition())
insertPos--;
}
insertParent.insert(moveCopyFrom, insertPos);
moveCopyFrom.setDirty(true);
// mark subtree as dirty
TreeVisitor tv = new TreeVisitor(new Visitor() {
@Override
public void visit(INode node) {
CourseEditorTreeNode cetn = (CourseEditorTreeNode) node;
cetn.setDirty(true);
}
}, moveCopyFrom, true);
tv.visitAll();
CourseFactory.saveCourseEditorTreeModel(course.getResourceableId());
showInfo("movecopynode.info.condmoved");
ThreadLocalUserActivityLogger.log(CourseLoggingAction.COURSE_EDITOR_NODE_MOVED, getClass());
fireEvent(ureq, Event.DONE_EVENT);
}
}
use of org.olat.core.util.tree.TreeVisitor in project OpenOLAT by OpenOLAT.
the class CourseEditorEnvImpl method listCycles.
/**
* @see org.olat.course.editor.CourseEditorEnv#listCycles()
*/
@Override
public Set<String> listCycles() {
/*
* convert nodeRefs datastructure to a directed graph
*/
DirectedGraph dg = new DefaultDirectedGraph();
DirectedEdgeFactory def = new EdgeFactories.DirectedEdgeFactory();
/*
* add the course structure as directed graph, where
*/
Visitor v = new Convert2DGVisitor(dg);
(new TreeVisitor(v, cetm.getRootNode(), true)).visitAll();
/*
* iterate over nodeRefs, add each not existing node id as vertex, for each
* key - child relation add an edge to the directed graph.
*/
Map<String, Set<String>> nodeSoftRefs = new HashMap<>();
for (Iterator<String> iter = softRefs.keySet().iterator(); iter.hasNext(); ) {
String nodeId = iter.next();
List<ConditionExpression> conditionExprs = softRefs.get(nodeId);
for (int i = 0; i < conditionExprs.size(); i++) {
ConditionExpression ce = conditionExprs.get(i);
Set<String> refs = ce.getSoftReferencesForCycleDetectorOf("courseNodeId");
if (refs != null && refs.size() > 0) {
if (nodeSoftRefs.containsKey(nodeId)) {
nodeSoftRefs.get(nodeId).addAll(refs);
} else {
nodeSoftRefs.put(nodeId, refs);
}
}
}
}
for (Iterator<String> keys = nodeSoftRefs.keySet().iterator(); keys.hasNext(); ) {
// a node
String key = keys.next();
if (!dg.containsVertex(key)) {
dg.addVertex(key);
}
// and its children
Set<String> children = nodeSoftRefs.get(key);
for (Iterator<String> childrenIt = children.iterator(); childrenIt.hasNext(); ) {
String child = childrenIt.next();
if (!dg.containsVertex(child)) {
dg.addVertex(child);
}
// add edge, precondition: vertex key - child are already added to the graph
Edge de = def.createEdge(key, child);
dg.addEdge(de);
}
}
/*
* find the id's participating in the cycle, and return the intersection
* with set of id's which actually produce references.
*/
CycleDetector cd = new CycleDetector(dg);
Set<String> cycleIds = cd.findCycles();
cycleIds.retainAll(nodeSoftRefs.keySet());
return cycleIds;
}
use of org.olat.core.util.tree.TreeVisitor in project OpenOLAT by OpenOLAT.
the class CourseEditorEnvImpl method validateCourse.
/**
* @see org.olat.course.editor.CourseEditorEnv#validateCourse()
*/
@Override
public void validateCourse() {
/*
* collect all condition error messages and soft references collect all
* configuration errors.
*/
String currentNodeWas = currentCourseNodeId;
// reset all
softRefs = new HashMap<String, List<ConditionExpression>>();
Visitor v = new CollectConditionExpressionsVisitor();
(new TreeVisitor(v, cetm.getRootNode(), true)).visitAll();
// refresh,create status descriptions of the course
statusDescs = new HashMap<String, List<StatusDescription>>();
v = new CollectStatusDescriptionVisitor(this);
(new TreeVisitor(v, cetm.getRootNode(), true)).visitAll();
//
currentCourseNodeId = currentNodeWas;
}
use of org.olat.core.util.tree.TreeVisitor in project OpenOLAT by OpenOLAT.
the class CourseOptionsController method checkFolderNodes.
private boolean checkFolderNodes(INode rootNode, ICourse course) {
hasFolderNode = false;
Visitor visitor = new Visitor() {
public void visit(INode node) {
CourseEditorTreeNode courseNode = (CourseEditorTreeNode) course.getEditorTreeModel().getNodeById(node.getIdent());
if (!courseNode.isDeleted() && courseNode.getCourseNode() instanceof BCCourseNode) {
BCCourseNode bcNode = (BCCourseNode) courseNode.getCourseNode();
if (bcNode.isSharedFolder()) {
hasFolderNode = true;
}
}
}
};
TreeVisitor v = new TreeVisitor(visitor, rootNode, false);
v.visitAll();
return hasFolderNode;
}
use of org.olat.core.util.tree.TreeVisitor in project OpenOLAT by OpenOLAT.
the class ScoreAccounting method evaluateAll.
public boolean evaluateAll(boolean update) {
Identity identity = userCourseEnvironment.getIdentityEnvironment().getIdentity();
List<AssessmentEntry> entries = userCourseEnvironment.getCourseEnvironment().getAssessmentManager().getAssessmentEntries(identity);
AssessableTreeVisitor visitor = new AssessableTreeVisitor(entries, update);
// collect all assessable nodes and eval 'em
CourseNode root = userCourseEnvironment.getCourseEnvironment().getRunStructure().getRootNode();
// breadth first traversal gives an easier order of evaluation for debugging
// however, for live it is absolutely mandatory to use depth first since using breadth first
// the score accoutings local cache hash map will never be used. this can slow down things like
// crazy (course with 10 tests, 300 users and some crazy score and passed calculations will have
// 10 time performance differences)
cachedScoreEvals.clear();
for (AssessmentEntry entry : entries) {
String nodeIdent = entry.getSubIdent();
CourseNode courseNode = userCourseEnvironment.getCourseEnvironment().getRunStructure().getNode(nodeIdent);
if (courseNode instanceof AssessableCourseNode) {
AssessableCourseNode acn = (AssessableCourseNode) courseNode;
AssessmentEvaluation se = AssessmentEvaluation.toAssessmentEvalutation(entry, acn);
cachedScoreEvals.put(acn, se);
}
}
// true=depth first
TreeVisitor tv = new TreeVisitor(visitor, root, true);
tv.visitAll();
return visitor.hasChanges();
}
Aggregations