in source/com.microsoft.tfs.core/src/com/microsoft/tfs/core/clients/workitem/internal/wiqlparse/WIQLAdapter.java [1026:1202]
private void verifyCondition(
final NodeFieldName left,
final Node right,
final Condition op,
final Node errorNode,
final LinkQueryMode mode) {
Tools.ensureSyntax(op != Condition.NONE, SyntaxError.INVALID_CONDITIONAL_OPERATOR, errorNode);
final FieldDefinition fd = (FieldDefinition) left.getTag();
if (NodeType.FIELD_NAME.equals(right.getNodeType())) {
if (!witContext.getServerInfo().isSupported(SupportedFeatures.QUERY_FIELDS_COMPARISON)) {
throw new NotSupportedException(
Messages.getString("WiqlAdapter.CannotRunQueryThatComparesFieldsOnThisServer")); //$NON-NLS-1$
}
if (LinkQueryMode.LINKS_MUST_CONTAIN.equals(mode)
|| LinkQueryMode.LINKS_MAY_CONTAIN.equals(mode)
|| LinkQueryMode.LINKS_DOES_NOT_CONTAIN.equals(mode)
|| LinkQueryMode.LINKS_RECURSIVE.equals(mode)) {
Tools.ensureSyntax(
left.getPrefix().equalsIgnoreCase(((NodeFieldName) right).getPrefix()),
SyntaxError.FIELD_CONDITIONS_IN_LINK_QUERIES,
errorNode);
}
// Long text fields cannot be used in expressions
Tools.ensureSyntax(
(!FieldType.PLAINTEXT.equals(fd.getFieldType()))
&& (!FieldType.HTML.equals(fd.getFieldType()))
&& (!FieldType.HISTORY.equals(fd.getFieldType())),
SyntaxError.INVALID_FIELD_TYPE_FOR_CONDITION,
errorNode);
final FieldDefinition rfd = (FieldDefinition) ((NodeFieldName) right).getTag();
Tools.ensureSyntax(
(!FieldType.PLAINTEXT.equals(rfd.getFieldType()))
&& (!FieldType.HTML.equals(rfd.getFieldType()))
&& (!FieldType.HISTORY.equals(rfd.getFieldType())),
SyntaxError.INVALID_FIELD_TYPE_FOR_CONDITION,
errorNode);
return;
}
// Check possible operators and right part types
final String rightString = right.getConstStringValue();
if (op == Condition.IN) {
final NodeValueList valueList = (NodeValueList) right;
for (final Iterator<Node> it = valueList.iterator(); it.hasNext();) {
// check all values inside list.
verifyCondition(left, it.next(), Condition.EQUALS, errorNode, mode);
}
return;
} else if (op == Condition.GROUP) {
if (fd.getID() == CoreFields.WORK_ITEM_TYPE) {
if (!witContext.getServerInfo().isSupported(SupportedFeatures.WORK_ITEM_TYPE_CATEGORIES)) {
throw new NotSupportedException(
Messages.getString("WiqlAdapter.CannotCreateCategoriesOfWorkItemsOnThisServer")); //$NON-NLS-1$
}
} else {
if (!witContext.getServerInfo().isSupported(SupportedFeatures.QUERY_IN_GROUP_FILTER)) {
throw new NotSupportedException(
Messages.getString("WiqlAdapter.CannotUseInGroupOperatorToRunQueryOnThisServer")); //$NON-NLS-1$
}
// "in group" works for string fields only
if (!FieldType.STRING.equals(fd.getFieldType())) {
throw new NotSupportedException(
MessageFormat.format(
Messages.getString("WiqlAdapter.CannotUseInGroupOperatorWithFieldOnThisServerFormat"), //$NON-NLS-1$
fd.getName(),
ProvisionValues.FIELD_TYPE_STRING));
}
}
}
// Comparing with empty string
if (rightString != null && rightString.length() == 0) {
Tools.ensureSyntax(
op == Condition.EQUALS || op == Condition.NOT_EQUALS,
SyntaxError.INVALID_CONDITION_FOR_EMPTY_STRING,
errorNode);
}
// Check Tree path operators and constant
if (FieldType.TREEPATH == fd.getFieldType()) {
Tools.ensureSyntax(
op == Condition.EQUALS || op == Condition.NOT_EQUALS || op == Condition.UNDER,
SyntaxError.INVALID_CONDITION_FOR_TREE_FIELD,
errorNode);
Tools.ensureSyntax(
right.getDataType() == DataType.STRING,
SyntaxError.PATH_MUST_BE_A_STRING_NOT_STARTING_WITH_BACKSLASH,
right);
if (rightString != null && (rightString.length() != 0 || op == Condition.UNDER)) {
Tools.ensureSyntax(
!rightString.startsWith("\\"), //$NON-NLS-1$
SyntaxError.PATH_MUST_BE_A_STRING_NOT_STARTING_WITH_BACKSLASH,
right);
final int type =
fd.getID() == CoreFields.AREA_PATH ? NodeStructureType.AREA : NodeStructureType.ITERATION;
Tools.ensureSyntax(
getTreeID(rightString, type) != -1,
SyntaxError.TREE_PATH_IS_NOT_FOUND_IN_HIERARCHY,
right);
}
} else if (FieldType.PLAINTEXT == fd.getFieldType()
|| FieldType.HISTORY == fd.getFieldType()
|| FieldType.HTML == fd.getFieldType()) {
// Long text fields
if (rightString != null) {
Tools.ensureSyntax(
op == Condition.CONTAINS || op == Condition.CONTAINS_WORDS,
SyntaxError.INVALID_CONDITION_FOR_LONG_TEXT_FIELD,
errorNode);
Tools.ensureSyntax(
rightString.trim().length() > 0,
SyntaxError.INVALID_LONG_TEXT_SEARCH_FOR_WHITESPACE,
errorNode);
}
} else if (FieldType.STRING == fd.getFieldType() && CoreFields.TEAM_PROJECT == fd.getID()) {
// Check valid operators for tree fields
Tools.ensureSyntax(
op == Condition.EQUALS || op == Condition.NOT_EQUALS,
SyntaxError.INVALID_CONDITION_FOR_NODE_FIELD,
errorNode);
if (rightString != null && (rightString.length() != 0 || op == Condition.UNDER)) {
Tools.ensureSyntax(rightString.indexOf("\\") == -1, SyntaxError.INVALID_PROJECT_NAME, right); //$NON-NLS-1$
final int treeId = getTreeID(rightString, NodeStructureType.AREA);
Tools.ensureSyntax(treeId != -1, SyntaxError.PROJECT_NOT_FOUND, right);
}
} else if (FieldType.INTEGER == fd.getFieldType() && fd.getID() == CoreFields.LINK_TYPE) {
// Check valid operators for the link field
Tools.ensureSyntax(
op == Condition.EQUALS || op == Condition.NOT_EQUALS,
SyntaxError.INVALID_CONDITION_FOR_LINK_TYPE,
errorNode);
// Check string
if (rightString != null && !(rightString.length() == 0 && op == Condition.NOT_EQUALS)) {
final WorkItemLinkTypeEnd linkTypeEnd = getLinkTypeByName(rightString);
Tools.ensureSyntax(linkTypeEnd != null, SyntaxError.INVALID_LINK_TYPE_NAME, right);
if (LinkQueryMode.LINKS_RECURSIVE.equals(mode)) {
Tools.ensureSyntax(
Topology.TREE == linkTypeEnd.getLinkType().getLinkTopology() && linkTypeEnd.isForwardLink(),
SyntaxError.INVALID_LINK_TYPE_NAME_RECURSIVE,
right);
}
}
}
else if (FieldType.INTEGER == fd.getFieldType() && rightString != null && rightString.length() != 0) {
if (rightString != null && rightString.length() > 0) {
Tools.ensureSyntax(
Pattern.matches("[+-]?[0-9]+", rightString), //$NON-NLS-1$
SyntaxError.INCOMPATIBLE_RIGHT_CONST,
right);
}
}
if (op == Condition.UNDER) {
Tools.ensureSyntax(
FieldType.TREEPATH == fd.getFieldType(),
SyntaxError.UNDER_CAN_BE_USED_FOR_TREE_PATH_FIELD_ONLY,
left);
}
}