Repository: ambari Updated Branches: refs/heads/trunk 51ff43834 -> 265f13f46
AMBARI-9153. Allow a set of property names to ignore to be passed into the predicate compiler Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/265f13f4 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/265f13f4 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/265f13f4 Branch: refs/heads/trunk Commit: 265f13f467f9d190cba4a0e59271b68d45d5caae Parents: 51ff438 Author: John Speidel <[email protected]> Authored: Thu Jan 15 13:32:22 2015 -0500 Committer: John Speidel <[email protected]> Committed: Thu Jan 15 14:22:23 2015 -0500 ---------------------------------------------------------------------- .../server/api/predicate/PredicateCompiler.java | 15 +++++++ .../ambari/server/api/predicate/QueryLexer.java | 44 +++++++++++++++++++- .../server/api/predicate/QueryLexerTest.java | 28 +++++++++++++ 3 files changed, 85 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/265f13f4/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/PredicateCompiler.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/PredicateCompiler.java b/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/PredicateCompiler.java index 7738d2c..7deabb2 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/PredicateCompiler.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/PredicateCompiler.java @@ -20,6 +20,8 @@ package org.apache.ambari.server.api.predicate; import org.apache.ambari.server.controller.spi.Predicate; +import java.util.Set; + /** * Compiler which takes a query expression as input and produces a predicate instance as output. */ @@ -46,4 +48,17 @@ public class PredicateCompiler { public Predicate compile(String exp) throws InvalidQueryException { return parser.parse(lexer.tokens(exp)); } + + /** + * Generate a predicate from a query expression. + * + * @param exp query expression + * @param ignoredProperties set of property names to ignore + * + * @return a predicate instance + * @throws InvalidQueryException if unable to compile the expression + */ + public Predicate compile(String exp, Set<String> ignoredProperties) throws InvalidQueryException { + return parser.parse(lexer.tokens(exp, ignoredProperties)); + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/265f13f4/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java b/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java index 3940c34..b645040 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/predicate/QueryLexer.java @@ -58,7 +58,7 @@ public class QueryLexer { new HashMap<Token.TYPE, List<TokenHandler>>(); /** - * Set of property names to ignore. + * Static set of property names to ignore. */ private static final Set<String> SET_IGNORE = new HashSet<String>(); @@ -108,8 +108,23 @@ public class QueryLexer { * @throws InvalidQueryException if the query is invalid */ public Token[] tokens(String exp) throws InvalidQueryException { + return tokens(exp, Collections.<String>emptySet()); + } + /** + * Scan the provided query and generate a token stream to be used by the query parser. + * + * @param exp the query expression to scan + * @param ignoreProperties property names which should be ignored + * + * @return an array of tokens + * @throws InvalidQueryException if the query is invalid + */ + public Token[] tokens(String exp, Set<String> ignoreProperties) throws InvalidQueryException { ScanContext ctx = new ScanContext(); + ctx.addPropertiesToIgnore(SET_IGNORE); + ctx.addPropertiesToIgnore(ignoreProperties); + for (String tok : parseStringTokens(exp)) { List<TokenHandler> listHandlers = TOKEN_HANDLERS.get(ctx.getLastTokenType()); boolean processed = false; @@ -214,6 +229,11 @@ public class QueryLexer { private Token.TYPE m_ignoreSegmentEndToken = null; /** + * Property names which are to be ignored. + */ + private Set<String> m_propertiesToIgnore = new HashSet<String>(); + + /** * Constructor. */ private ScanContext() { @@ -289,6 +309,26 @@ public class QueryLexer { public List<Token> getTokenList() { return m_listTokens; } + + /** + * Get the set of property names that are to be ignored. + * + * @return set of property names to ignore + */ + public Set<String> getPropertiesToIgnore() { + return m_propertiesToIgnore; + } + + /** + * Add property names to the set of property names to ignore. + * + * @param ignoredProperties set of property names to ignore + */ + public void addPropertiesToIgnore(Set<String> ignoredProperties) { + if (ignoredProperties != null) { + m_propertiesToIgnore.addAll(ignoredProperties); + } + } } /** @@ -350,7 +390,7 @@ public class QueryLexer { @Override public void _handleToken(String token, ScanContext ctx) throws InvalidQueryException { //don't add prop name token until after operator token - if (! SET_IGNORE.contains(token)) { + if (! ctx.getPropertiesToIgnore().contains(token)) { ctx.setPropertyOperand(token); } else { if (!ctx.getTokenList().isEmpty() ) { http://git-wip-us.apache.org/repos/asf/ambari/blob/265f13f4/ambari-server/src/test/java/org/apache/ambari/server/api/predicate/QueryLexerTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/predicate/QueryLexerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/predicate/QueryLexerTest.java index a587480..2c04d6c 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/predicate/QueryLexerTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/predicate/QueryLexerTest.java @@ -22,7 +22,11 @@ package org.apache.ambari.server.api.predicate; import org.junit.Test; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Set; + import static org.junit.Assert.*; /** @@ -304,6 +308,30 @@ public class QueryLexerTest { } @Test + public void testTokens_ignore__userDefined() throws InvalidQueryException { + List<Token> listTokens = new ArrayList<Token>(); + listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, "=")); + listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "foo")); + listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "1")); + listTokens.add(new Token(Token.TYPE.LOGICAL_OPERATOR, "&")); + listTokens.add(new Token(Token.TYPE.RELATIONAL_OPERATOR, "=")); + listTokens.add(new Token(Token.TYPE.PROPERTY_OPERAND, "bar")); + listTokens.add(new Token(Token.TYPE.VALUE_OPERAND, "2")); + + QueryLexer lexer = new QueryLexer(); + Set<String> propertiesToIgnore = new HashSet<String>(); + propertiesToIgnore.add("ignore1"); + propertiesToIgnore.add("otherIgnore"); + propertiesToIgnore.add("ba"); + propertiesToIgnore.add("ple"); + + Token[] tokens = lexer.tokens("ba=gone&foo=1&ignore1=pleaseIgnoreMe&fields=a/b&bar=2&otherIgnore=byebye", + propertiesToIgnore); + + assertArrayEquals(listTokens.toArray(new Token[listTokens.size()]), tokens); + } + + @Test public void testTokens_invalidRelationalOp() { try { new QueryLexer().tokens("foo=1&bar|5");
