// Copyright 2012 Georg-August-Universität Göttingen, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package de.ugoe.cs.autoquest.tasktrees.nodeequality; import java.util.List; import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode; /** *

* This class is capable of comparing any task tree node which is not a selection with a * selection. This is needed, because selections may contain exactly that node. Therefore, if * this node is selected out of a selection the selection is equal to the node itself. * The rule returns lexically equal, it the selection contains a lexically equal node. The same * applies for syntactical and semantical equality. *

* @author Patrick Harms */ public class NodeAndSelectionComparisonRule implements NodeComparisonRule { /** the rule manager for internally comparing task tree nodes */ private NodeEqualityRuleManager mRuleManager; /** *

* simple constructor to provide the rule with the node equality rule manager to be able * to perform comparisons of the children of provided task tree nodes *

* * @param ruleManager the rule manager for comparing task tree nodes */ NodeAndSelectionComparisonRule(NodeEqualityRuleManager ruleManager) { super(); mRuleManager = ruleManager; } /* (non-Javadoc) * @see NodeComparisonRule#isApplicable(ITaskTreeNode, ITaskTreeNode) */ @Override public boolean isApplicable(ITaskTreeNode node1, ITaskTreeNode node2) { return ((node1 instanceof ISelection) && (!(node2 instanceof ISelection))) || ((node2 instanceof ISelection) && (!(node1 instanceof ISelection))); } /* (non-Javadoc) * @see NodeComparisonRule#areLexicallyEqual(ITaskTreeNode, ITaskTreeNode) */ @Override public boolean areLexicallyEqual(ITaskTreeNode node1, ITaskTreeNode node2) { NodeEquality equality = getEquality(node1, node2, NodeEquality.LEXICALLY_EQUAL); return (equality != null) && (equality.isAtLeast(NodeEquality.LEXICALLY_EQUAL)); } /* (non-Javadoc) * @see NodeComparisonRule#areSyntacticallyEqual(ITaskTreeNode, ITaskTreeNode) */ @Override public boolean areSyntacticallyEqual(ITaskTreeNode node1, ITaskTreeNode node2) { NodeEquality equality = getEquality(node1, node2, NodeEquality.SYNTACTICALLY_EQUAL); return (equality != null) && (equality.isAtLeast(NodeEquality.SYNTACTICALLY_EQUAL)); } /* (non-Javadoc) * @see NodeComparisonRule#areSemanticallyEqual(ITaskTreeNode, ITaskTreeNode) */ @Override public boolean areSemanticallyEqual(ITaskTreeNode node1, ITaskTreeNode node2) { NodeEquality equality = getEquality(node1, node2, NodeEquality.SEMANTICALLY_EQUAL); return (equality != null) && (equality.isAtLeast(NodeEquality.SEMANTICALLY_EQUAL)); } /* (non-Javadoc) * @see NodeComparisonRule#compare(ITaskTreeNode, ITaskTreeNode) */ @Override public NodeEquality compare(ITaskTreeNode node1, ITaskTreeNode node2) { return getEquality(node1, node2, null); } /** * */ private NodeEquality getEquality(ITaskTreeNode node1, ITaskTreeNode node2, NodeEquality requiredEqualityLevel) { ISelection selection = null; ITaskTreeNode node = null; if (node1 instanceof ISelection) { if (node2 instanceof ISelection) { // the rule is not responsible for two selections return null; } selection = (ISelection) node1; node = node2; } else if (node2 instanceof ISelection) { if (node1 instanceof ISelection) { // the rule is not responsible for two selections return null; } selection = (ISelection) node2; node = node1; } else { return null; } // now, that we found the selection and the node, lets compare the children of the selection // with the node. List children = selection.getChildren(); if (children.size() < 1) { return null; } NodeEquality mostConcreteNodeEquality = null; for (ITaskTreeNode child : children) { NodeEquality nodeEquality = callRuleManager(child, node, requiredEqualityLevel); if (nodeEquality != NodeEquality.UNEQUAL) { if (mostConcreteNodeEquality == null) { mostConcreteNodeEquality = nodeEquality; } else if (mostConcreteNodeEquality.isAtLeast(nodeEquality)) { mostConcreteNodeEquality = nodeEquality; } if ((requiredEqualityLevel != null) && (mostConcreteNodeEquality.isAtLeast(requiredEqualityLevel))) { // if we found one child of the selection that is as equal as required, then // we can consider the selection to be sufficiently equal to the other node. // So we break up checking further children. break; } } } // although the subtask may be identical to the node, we can not return identical, as // the selection is not identical to the node, but at most lexically equal if (mostConcreteNodeEquality == NodeEquality.IDENTICAL) { return NodeEquality.LEXICALLY_EQUAL; } else { return mostConcreteNodeEquality; } } /** *

* TODO: comment *

* * @param child1 * @param child2 * @param requiredEqualityLevel * @return */ private NodeEquality callRuleManager(ITaskTreeNode child1, ITaskTreeNode child2, NodeEquality requiredEqualityLevel) { if (requiredEqualityLevel == null) { return mRuleManager.compare(child1, child2); } else if (mRuleManager.areAtLeastEqual(child1, child2, requiredEqualityLevel)) { return requiredEqualityLevel; } else { return NodeEquality.UNEQUAL; } } }