We get the search string from the UI. Based on the search parameters we need to create a back-end query. This is similar to "Feed Item Query Language(FIQL)". I have wrote the code to find the logical operators in the search parameters like ||
(or operator) and ;
(And operator).
The code is working as expected, but I want to know if we can improve the code.
For example, the below search parameter:
- And operator (
;
) is outer group - Or operator (
||
) is inner group
status:eq(A);sourceKey.entityId:eq(36KAG);[hostProductLineCode:eq(YB)||hostProductLineCode:eq(PB)]
package com.guthyrenker.soma.ws.rest.v1.client;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.junit.Assert;
public class TestOperator
{
public static void main(String[] args) {
String outerOperator = null;
String filter = "status:eq(A)";
outerOperator = validateAndGetOuterOperator(filter);
Assert.assertEquals("Outer operator is and condition",";", outerOperator);
filter = "status:eq(A);";
outerOperator = validateAndGetOuterOperator(filter);
Assert.assertEquals("Outer operator is and condition",";", outerOperator);
filter = "status:eq(A);sourceKey.entityId:eq(36KAG);[hostProductLineCode:eq(YB)||hostProductLineCode:eq(PB)]";
outerOperator = validateAndGetOuterOperator(filter);
Assert.assertEquals("Outer operator is and condition",";", outerOperator);
filter =
"status:eq(A)||sourceKey.entityId:eq(36KAG)||[hostProductLineCode:eq(YB);hostProductLineCode:eq(PB)]||[productLineCode:eq(YB);productLineCode:eq(PB)]";
outerOperator = validateAndGetOuterOperator(filter);
Assert.assertEquals("Outer operator is or condition","||", outerOperator);
filter =
"status:eq(A)||sourceKey.entityId:eq(36KAG)||[hostProductLineCode:eq(YB);hostProductLineCode:eq(PB)]||[productLineCode:eq(YB);productLineCode:eq(PB)]||readyDate:eq(2014-01-01T00:00:00)";
outerOperator = validateAndGetOuterOperator(filter);
Assert.assertEquals("Outer operator is or condition","||", outerOperator);
filter = "[hostProductLineCode:eq(YB);hostProductLineCode:eq(PB)]||[productLineCode:eq(YB);productLineCode:eq(PB)]";
outerOperator = validateAndGetOuterOperator(filter);
Assert.assertEquals("Outer operator is or condition","||", outerOperator);
filter = "[hostProductLineCode:eq(YB)||hostProductLineCode:eq(PB)];[productLineCode:eq(YB)||productLineCode:eq(PB)]";
outerOperator = validateAndGetOuterOperator(filter);
Assert.assertEquals("Outer operator is and condition",";", outerOperator);
filter =
"status:eq(A);sourceKey.entityId:eq(36KAG);[hostProductLineCode:eq(YB)||hostProductLineCode:eq(PB)];readyDate:eq(2014-01-01T00:00:00)";
outerOperator = validateAndGetOuterOperator(filter);
Assert.assertEquals("Outer operator is and condition",";", outerOperator);
// Exception Cases
filter = "[hostProductLineCode:eq(YB);hostProductLineCode:eq(PB)];[productLineCode:eq(YB)||productLineCode:eq(PB)]";
try {
outerOperator = validateAndGetOuterOperator(filter);
} catch (IllegalArgumentException e) {
Assert.assertTrue(true);
}
try {
filter =
"[hostProductLineCode:eq(YB)||hostProductLineCode:eq(PB)];[productLineCode:eq(YB)||productLineCode:eq(PB)||[productLineCode:eq(ZB)]]";
outerOperator = validateAndGetOuterOperator(filter);
} catch (IllegalArgumentException e) {
Assert.assertTrue(true);
}
try {
filter = "status:eq(A);status:eq(P)||status:eq(C)";
outerOperator = validateAndGetOuterOperator(filter);
} catch (IllegalArgumentException e) {
Assert.assertTrue(true);
}
try {
filter = "status:eq(A);sourceKey.entityId:eq(36KAG);[hostProductLineCode:eq(YB)||hostProductLineCode:eq(PB)]||status:eq(C)";
outerOperator = validateAndGetOuterOperator(filter);
} catch (IllegalArgumentException e) {
Assert.assertTrue(true);
}
try {
filter = "status:eq(A)-sourceKey.entityId:eq(36KAG);[hostProductLineCode:eq(YB)||hostProductLineCode:eq(PB)]";
outerOperator = validateAndGetOuterOperator(filter);
} catch (IllegalArgumentException e) {
Assert.assertTrue(true);
}
}
public static String validateAndFindSubgroupOperator(String filter) {
String previousOperator = null;
String curOperator = null;
String REGEX_SUBGROUP = "\\[(.*?)\\]";
Pattern pattern = Pattern.compile(REGEX_SUBGROUP);
Matcher matcher = pattern.matcher(filter);
List<String> matches = new ArrayList<String>();
while (matcher.find()) {
String group = matcher.group();
matches.add(group);
}
for(String subGroupFilter : matches){
curOperator = validateGroup(subGroupFilter);
if(previousOperator!=null && !curOperator.equals(previousOperator)){
throw new IllegalArgumentException("All subgroups should have same operator.");
}else {
String subGroupNoBraces = subGroupFilter.substring(1, subGroupFilter.length()-1);
if(subGroupNoBraces.indexOf("[")>0 || subGroupNoBraces.indexOf("]")>0){
throw new IllegalArgumentException("Nested subgroups are not allowed.");
}
}
previousOperator = curOperator;
}
return curOperator;
}
public static String validateAndFindOuterOperator(String filter) {
String REGEX_SUBGROUP = "\\[(.*?)\\]";
filter = filter.replaceAll(REGEX_SUBGROUP, "");
return validateGroup(filter);
}
public static String validateGroup(String filter) {
// Parameter regular expression
String REGEX_PARAMETER = "([A-Za-z0-9.]+):([A-Za-z]+)(\\({1})(\\')?([a-zA-Z0-9-+,:]+)(\\')?(\\){1})";
if ((filter.indexOf(";") >= 0 && filter.indexOf("||") >= 0)) {
throw new IllegalArgumentException("Expected same operator, but found different operator.");
} else if (filter.indexOf("||") >= 0) { // or logical operator is found for the subgroups
return "||";
} else if (filter.indexOf(";") >= 0 || filter.matches(REGEX_PARAMETER)) { // and logical operator is found for the subgroups
return ";";
} else {
throw new IllegalArgumentException("Filter is not valid.");
}
}
private static String validateAndGetOuterOperator(String filter){
String subGroupOperator = validateAndFindSubgroupOperator(filter);
String outerGroupOperator = validateAndFindOuterOperator(filter);
return outerGroup;
}
}
outerGroup
invalidateAndGetOuterOperator
, but it doesn't exist). Is this maybe just a copy-paste error? – tim Oct 29 '14 at 10:36outerGroupOperator
(in that case, all your tests pass), but why are you callingvalidateAndFindSubgroupOperator
then? For that matter, that method seems to be entirely unused. – tim Oct 29 '14 at 11:57