use of teamdash.wbs.AbstractWBSModelMerger.WBSNodeContent in project processdash by dtuma.
the class BlameDataFactory method recordNodeEdited.
private void recordNodeEdited(BlameModelData blameModelData, DataTableModel dataTableModel, TreeNodeChange<Integer, WBSNodeContent> tnc, TreeDiff<Integer, WBSNodeContent> diff) {
Integer nodeID = tnc.getNodeID();
WBSNodeContent base = diff.getBaseRoot().findNode(nodeID).getContent();
WBSNodeContent mod = tnc.getNode().getContent();
BlameNodeData nodeData = blameModelData.getNodeData(nodeID);
boolean isWBS = (diff == this.diff);
Set<String> attrNames = new HashSet<String>(base.keySet());
attrNames.addAll(mod.keySet());
Set<String> indivTimeAuthors = null;
boolean hasTotalTimeChange = false;
boolean hasExplicitTotalTimeChange = false;
for (String attr : attrNames) {
String baseVal = base.get(attr);
String modVal = mod.get(attr);
if (NullSafeObjectUtils.EQ(baseVal, modVal)) {
// no changes in this attr
} else if (attr == TEAM_TIME_EXPLICIT_FLAG) {
// no need to record changes to this pseudo flag
} else if (isWBS && attr.equals(TEAM_TIME_ATTR)) {
// the team time value was changed
hasTotalTimeChange = true;
// the sum of indiv times)
if (base.containsKey(TEAM_TIME_EXPLICIT_FLAG) || mod.containsKey(TEAM_TIME_EXPLICIT_FLAG))
hasExplicitTotalTimeChange = true;
} else if (isWBS && attr.endsWith(TEAM_MEMBER_TIME_SUFFIX)) {
// team member time changes can be reverse-synced, so we must
// determine the appropriate author for this change.
BlamePoint timeAuthor = getTimeAuthor(mod, attr);
if (indivTimeAuthors == null)
indivTimeAuthors = new TreeSet<String>();
indivTimeAuthors.add(timeAuthor.getAuthor());
String baseDisp = fmtTime(baseVal, UNASSIGNED);
String modDisp = fmtTime(modVal, UNASSIGNED);
nodeData.addAttributeChange(attr, indivTimeColumnIDs.get(attr), timeAuthor, baseDisp, modDisp);
} else if (attr.equals(NODE_NAME)) {
// the name of this node has changed
nodeData.addNodeNameChange(blamePoint, baseVal, modVal);
} else {
// possibly record an attribute change for this node
//
ConflictCapableDataColumn column = WBSModelMergeConflictNotificationFactory.findColumnForAttribute(dataTableModel, attr);
if (column != null) {
String baseDisp = fmt(column.getConflictDisplayValue(baseVal, base.getWBSNode()));
String modDisp = fmt(column.getConflictDisplayValue(modVal, mod.getWBSNode()));
nodeData.addAttributeChange(attr, column.getColumnID(), blamePoint, baseDisp, modDisp);
}
}
}
// "Assigned To" column
if (indivTimeAuthors != null && tnc.getNode().getChildren().isEmpty()) {
String oldWho = getAssignedToString(base, true);
String newWho = getAssignedToString(mod, false);
if (!NullSafeObjectUtils.EQ(oldWho, newWho))
nodeData.addAttributeChange(RESOURCES_PSEUDO_ATTR, TeamTimeColumn.RESOURCES_COL_ID, getMergedBlame(indivTimeAuthors), oldWho, newWho);
}
// record a change to the team time attribute if needed
if (hasTotalTimeChange) {
BlamePoint blame = blamePoint;
if (indivTimeAuthors != null) {
Set<String> allAuthors = indivTimeAuthors;
if (hasExplicitTotalTimeChange && !allAuthors.contains(author)) {
allAuthors = new TreeSet(indivTimeAuthors);
allAuthors.add(author);
}
blame = getMergedBlame(allAuthors);
}
if (blame != blamePoint)
wbsAttributesWithSpecialAuthors.add(TEAM_TIME_ATTR);
String oldTime = base.get(TEAM_TIME_ATTR);
String newTime = mod.get(TEAM_TIME_ATTR);
nodeData.addAttributeChange(TEAM_TIME_ATTR, TeamTimeColumn.COLUMN_ID, blame, fmtTime(oldTime, "0"), fmtTime(newTime, "0"));
}
}
use of teamdash.wbs.AbstractWBSModelMerger.WBSNodeContent in project processdash by dtuma.
the class ProjectChangeListFactory method buildChangesForEditedNode.
private void buildChangesForEditedNode(TreeNodeChange<Integer, WBSNodeContent> tnc, Map<Integer, ProjectWbsNodeChange> nodeChanges, Map<Integer, ProjectWbsTimeChange> timeChanges) {
Integer nodeID = tnc.getNodeID();
if (nodeID < 0)
// don't look for edits on the root node.
return;
WBSNodeContent base = diff.getBaseRoot().findNode(nodeID).getContent();
WBSNodeContent mod = tnc.getNode().getContent();
Set<String> attrNames = new HashSet<String>(base.keySet());
attrNames.addAll(mod.keySet());
boolean sawTimeChange = false;
for (String attr : attrNames) {
String baseVal = base.get(attr);
String modVal = mod.get(attr);
if (baseVal != null && baseVal.equals(modVal)) {
// no change in this attribute value
} else if (NODE_NAME.equals(attr)) {
Object changeType = new ProjectWbsNodeChange.Renamed(baseVal);
addNodeChange(tnc, nodeChanges, wbsB, changeType);
} else if (indivTimeAttrs.contains(attr) || TeamTimeColumn.TEAM_TIME_ATTR.equals(attr)) {
sawTimeChange = true;
}
}
if (sawTimeChange) {
WBSNode node = wbsB.getNodeMap().get(nodeID);
timeChanges.put(nodeID, new ProjectWbsTimeChange(node, base, mod, indivTimeAttrs, teamMemberNames, author, timestamp));
}
}
use of teamdash.wbs.AbstractWBSModelMerger.WBSNodeContent in project processdash by dtuma.
the class ProjectChangeListFactory method summarizeTimeChanges.
private boolean summarizeTimeChanges(Map<Integer, ProjectWbsTimeChange> timeChanges, TreeNode<Integer, WBSNodeContent> node) {
Map<Integer, ProjectWbsTimeChange> childChanges = new HashMap();
for (TreeNode<Integer, WBSNodeContent> child : node.getChildren()) {
// recursively summarize time changes for this branch of the tree
boolean childIsZero = summarizeTimeChanges(timeChanges, child);
if (childChanges != null) {
Integer childID = child.getID();
ProjectWbsTimeChange childChange = timeChanges.get(childID);
if (childChange != null)
// collect the changes for all of our children
childChanges.put(childID, childChange);
else if (!childIsZero)
// if this child has time but no time change, do not
// consider creating a summary at the parent node level
childChanges = null;
}
}
// if we found a child with no time changes, don't summarize this node
if (childChanges == null)
return false;
if (childChanges.isEmpty()) {
// true to indicate that this node is zero as well.
if (!node.getChildren().isEmpty())
return true;
// this is a leaf node. Return true if we have zero time.
ProjectWbsTimeChange test = new ProjectWbsTimeChange(null, node.getContent(), node.getContent(), indivTimeAttrs, teamMemberNames, author, timestamp);
return test.getNewTotalTime() == 0;
}
// summarization to succeed.
if (childChanges.size() == 1) {
Integer childID = childChanges.keySet().iterator().next();
ProjectWbsTimeChange single = timeChanges.remove(childID);
timeChanges.put(node.getID(), single);
return false;
}
// if all of our children had time changes, this is indicative of a
// top-down edit (such as scaling, task assignment, etc). create a
// summarized change to represent the time changes that have occurred
// in this branch of the tree.
WBSNode wbsNode = node.getContent().getWBSNode();
ProjectWbsTimeChange summarized = new ProjectWbsTimeChange(wbsNode, new ArrayList(childChanges.values()), indivTimeAttrs, teamMemberNames, author, timestamp);
timeChanges.put(node.getID(), summarized);
// remove the children's now-redundant changes from the change list
for (Integer childID : childChanges.keySet()) timeChanges.remove(childID);
return false;
}