You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by bi...@apache.org on 2011/12/05 21:05:51 UTC
svn commit: r1210600 [12/16] - in
/incubator/accumulo/trunk/contrib/accumulo_sample: ./ ingest/
ingest/src/main/java/aggregator/ ingest/src/main/java/ingest/
ingest/src/main/java/iterator/ ingest/src/main/java/normalizer/
ingest/src/main/java/protobuf/...
Modified: incubator/accumulo/trunk/contrib/accumulo_sample/query/src/main/java/parser/FieldIndexQueryReWriter.java
URL: http://svn.apache.org/viewvc/incubator/accumulo/trunk/contrib/accumulo_sample/query/src/main/java/parser/FieldIndexQueryReWriter.java?rev=1210600&r1=1210599&r2=1210600&view=diff
==============================================================================
--- incubator/accumulo/trunk/contrib/accumulo_sample/query/src/main/java/parser/FieldIndexQueryReWriter.java (original)
+++ incubator/accumulo/trunk/contrib/accumulo_sample/query/src/main/java/parser/FieldIndexQueryReWriter.java Mon Dec 5 20:05:49 2011
@@ -1,19 +1,19 @@
/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You 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.
-*/
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 parser;
import java.util.ArrayList;
@@ -54,1116 +54,1097 @@ import com.google.common.collect.HashMul
import com.google.common.collect.Multimap;
/**
- * The server-side field index queries can only support operations on indexed
- * fields. Additionally, queries that have differing ranges (i.e. one range at
- * the fieldname level and another at the fieldValue level) are not currently
- * supported. This class removes these conflicts from the query as well as
- * sets proper capitalization configurations etc.
- *
- * Once the query has been modified, you can pass it to the BooleanLogicIterator
- * on the server-side via the options map.
+ * The server-side field index queries can only support operations on indexed fields. Additionally, queries that have differing ranges (i.e. one range at the
+ * fieldname level and another at the fieldValue level) are not currently supported. This class removes these conflicts from the query as well as sets proper
+ * capitalization configurations etc.
+ *
+ * Once the query has been modified, you can pass it to the BooleanLogicIterator on the server-side via the options map.
*
*/
public class FieldIndexQueryReWriter {
-
- protected static final Logger log = Logger.getLogger(FieldIndexQueryReWriter.class);
- public static final String INDEXED_TERMS_LIST = "INDEXED_TERMS_LIST"; // comma separated list of indexed terms.
- public static Set<Integer> rangeNodeSet;
-
- static {
- rangeNodeSet = new HashSet<Integer>();
- rangeNodeSet.add(ParserTreeConstants.JJTLENODE);
- rangeNodeSet.add(ParserTreeConstants.JJTLTNODE);
- rangeNodeSet.add(ParserTreeConstants.JJTGENODE);
- rangeNodeSet.add(ParserTreeConstants.JJTGTNODE);
- rangeNodeSet = Collections.unmodifiableSet(rangeNodeSet);
+
+ protected static final Logger log = Logger.getLogger(FieldIndexQueryReWriter.class);
+ public static final String INDEXED_TERMS_LIST = "INDEXED_TERMS_LIST"; // comma separated list of indexed terms.
+ public static Set<Integer> rangeNodeSet;
+
+ static {
+ rangeNodeSet = new HashSet<Integer>();
+ rangeNodeSet.add(ParserTreeConstants.JJTLENODE);
+ rangeNodeSet.add(ParserTreeConstants.JJTLTNODE);
+ rangeNodeSet.add(ParserTreeConstants.JJTGENODE);
+ rangeNodeSet.add(ParserTreeConstants.JJTGTNODE);
+ rangeNodeSet = Collections.unmodifiableSet(rangeNodeSet);
+ }
+
+ /*
+ * Given a JEXL Query, rewrite it and return it.
+ *
+ * 1. ParseQuery 2. Transform query 3. Refactor query 4. remove non-indexed terms a. remove any tree conflicts b. collapse any branches 7. add normalized
+ * values 8. adjust for case sensitivity 9. add prefix.. but jexl chokes on null byte
+ */
+ public static void setLogLevel(Level lev) {
+ log.setLevel(lev);
+ }
+
+ /**
+ *
+ * @param query
+ * @param options
+ * @return
+ * @throws ParseException
+ * @throws Exception
+ */
+ public String removeNonIndexedTermsAndInvalidRanges(String query, Map<String,String> options) throws ParseException, Exception {
+ Multimap indexedTerms = parseIndexedTerms(options);
+ RewriterTreeNode node = parseJexlQuery(query);
+ if (log.isDebugEnabled()) {
+ log.debug("Tree: " + node.getContents());
}
-
- /*
- * Given a JEXL Query, rewrite it and return it.
- *
- * 1. ParseQuery
- * 2. Transform query
- * 3. Refactor query
- * 4. remove non-indexed terms
- * a. remove any tree conflicts
- * b. collapse any branches
- * 7. add normalized values
- * 8. adjust for case sensitivity
- * 9. add prefix.. but jexl chokes on null byte
- */
- public static void setLogLevel(Level lev) {
- log.setLevel(lev);
+ node = removeNonIndexedTerms(node, indexedTerms);
+ node = removeTreeConflicts(node, indexedTerms);
+ node = collapseBranches(node);
+ node = removeNegationViolations(node);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Tree -NonIndexed: " + node.getContents());
}
-
- /**
- *
- * @param query
- * @param options
- * @return
- * @throws ParseException
- * @throws Exception
- */
- public String removeNonIndexedTermsAndInvalidRanges(String query, Map<String, String> options) throws ParseException, Exception {
- Multimap indexedTerms = parseIndexedTerms(options);
- RewriterTreeNode node = parseJexlQuery(query);
- if (log.isDebugEnabled()) {
- log.debug("Tree: " + node.getContents());
- }
- node = removeNonIndexedTerms(node, indexedTerms);
- node = removeTreeConflicts(node, indexedTerms);
- node = collapseBranches(node);
- node = removeNegationViolations(node);
-
- if (log.isDebugEnabled()) {
- log.debug("Tree -NonIndexed: " + node.getContents());
- }
- return rebuildQueryFromTree(node);
+ return rebuildQueryFromTree(node);
+ }
+
+ /**
+ *
+ * @param query
+ * @param options
+ * @return
+ * @throws ParseException
+ * @throws Exception
+ */
+ public String applyNormalizedTerms(String query, Map<String,String> options) throws ParseException, Exception {
+ if (log.isDebugEnabled()) {
+ log.debug("applyNormalizedTerms, query: " + query);
}
-
- /**
+ Multimap normalizedTerms = parseIndexedTerms(options);
+ RewriterTreeNode node = parseJexlQuery(query);
+ if (log.isDebugEnabled()) {
+ log.debug("applyNormalizedTerms, Tree: " + node.getContents());
+ }
+ node = orNormalizedTerms(node, normalizedTerms);
+ if (log.isDebugEnabled()) {
+ log.debug("applyNormalizedTerms,Normalized: " + node.getContents());
+ }
+ return rebuildQueryFromTree(node);
+ }
+
+ /**
+ *
+ * @param query
+ * @param fNameUpper
+ * @param fValueUpper
+ * @return
+ * @throws ParseException
+ */
+ public String applyCaseSensitivity(String query, boolean fNameUpper, boolean fValueUpper) throws ParseException {
+ RewriterTreeNode node = parseJexlQuery(query);
+ if (log.isDebugEnabled()) {
+ log.debug("Tree: " + node.getContents());
+ }
+ node = applyCaseSensitivity(node, fNameUpper, fValueUpper);
+ if (log.isDebugEnabled()) {
+ log.debug("Case: " + node.getContents());
+ }
+ return rebuildQueryFromTree(node);
+ }
+
+ private String rebuildQueryFromTree(RewriterTreeNode node) {
+ if (node.isLeaf()) {
+ String fName = node.getFieldName();
+ String fValue = node.getFieldValue();
+ String operator = node.getOperator();
+ if (node.isNegated()) {
+ if (node.getType() == JexlOperatorConstants.JJTEQNODE) {
+ operator = JexlOperatorConstants.getOperator(JexlOperatorConstants.JJTNENODE);
+ } else if (node.getType() == JexlOperatorConstants.JJTERNODE) {
+ operator = JexlOperatorConstants.getOperator(JexlOperatorConstants.JJTNRNODE);
+ } else if (node.getType() == JexlOperatorConstants.JJTLTNODE) {
+ operator = JexlOperatorConstants.getOperator(JexlOperatorConstants.JJTGENODE);
+ } else if (node.getType() == JexlOperatorConstants.JJTLENODE) {
+ operator = JexlOperatorConstants.getOperator(JexlOperatorConstants.JJTGTNODE);
+ } else if (node.getType() == JexlOperatorConstants.JJTGTNODE) {
+ operator = JexlOperatorConstants.getOperator(JexlOperatorConstants.JJTLENODE);
+ } else if (node.getType() == JexlOperatorConstants.JJTGENODE) {
+ operator = JexlOperatorConstants.getOperator(JexlOperatorConstants.JJTLTNODE);
+ }
+ }
+ return fName + operator + "'" + fValue + "'";
+ } else {
+ List<String> parts = new ArrayList<String>();
+ Enumeration<?> children = node.children();
+ while (children.hasMoreElements()) {
+ RewriterTreeNode child = (RewriterTreeNode) children.nextElement();
+ parts.add(rebuildQueryFromTree(child));
+ }
+ if (node.getType() == ParserTreeConstants.JJTJEXLSCRIPT) {
+ return org.apache.commons.lang.StringUtils.join(parts, "");
+ }
+ String op = " " + JexlOperatorConstants.getOperator(node.getType()) + " ";
+ if (log.isDebugEnabled()) {
+ log.debug("Operator: " + op);
+ }
+ String query = org.apache.commons.lang.StringUtils.join(parts, op);
+ query = "(" + query + ")";
+ return query;
+ }
+ }
+
+ /*
+ * Don't use this, Jexl currently chokes on null bytes in the query
+ */
+ // public String applyFieldNamePrefix(String query, String prefix) throws ParseException {
+ // NuwaveTreeNode node = parseJexlQuery(query);
+ // if (log.isDebugEnabled()) {
+ // log.debug("Tree: " + node.getContents());
+ // }
+ // node = applyFieldNamePrefix(node, prefix);
+ // if (log.isDebugEnabled()) {
+ // log.debug("Prefix: " + node.getContents());
+ // }
+ // return null;
+ // }
+ private RewriterTreeNode parseJexlQuery(String query) throws ParseException {
+ if (log.isDebugEnabled()) {
+ log.debug("parseJexlQuery, query: " + query);
+ }
+ QueryParser parser = new QueryParser();
+ parser.execute(query);
+ TreeNode tree = parser.getIteratorTree();
+ RewriterTreeNode root = transformTreeNode(tree);
+ if (log.isDebugEnabled()) {
+ log.debug("parseJexlQuery, transformedTree: " + root.getContents());
+ }
+ root = refactorTree(root);
+ if (log.isDebugEnabled()) {
+ log.debug("parseJexlQuery, refactorTree: " + root.getContents());
+ }
+ return root;
+ }
+
+ /*
*
- * @param query
- * @param options
- * @return
- * @throws ParseException
- * @throws Exception
*/
- public String applyNormalizedTerms(String query, Map<String, String> options) throws ParseException, Exception {
- if (log.isDebugEnabled()) {
- log.debug("applyNormalizedTerms, query: " + query);
- }
- Multimap normalizedTerms = parseIndexedTerms(options);
- RewriterTreeNode node = parseJexlQuery(query);
- if (log.isDebugEnabled()) {
- log.debug("applyNormalizedTerms, Tree: " + node.getContents());
- }
- node = orNormalizedTerms(node, normalizedTerms);
- if (log.isDebugEnabled()) {
- log.debug("applyNormalizedTerms,Normalized: " + node.getContents());
+ private RewriterTreeNode transformTreeNode(TreeNode node) throws ParseException {
+ if (node.getType().equals(ASTEQNode.class) || node.getType().equals(ASTNENode.class)) {
+ if (log.isDebugEnabled()) {
+ log.debug("transformTreeNode, Equals Node");
+ }
+
+ Multimap<String,QueryTerm> terms = node.getTerms();
+ for (String fName : terms.keySet()) {
+ Collection<QueryTerm> values = terms.get(fName);
+
+ for (QueryTerm t : values) {
+ if (null == t || null == t.getValue()) {
+ continue;
+ }
+ String fValue = t.getValue().toString();
+ fValue = fValue.replaceAll("'", "");
+ boolean negated = t.getOperator().equals("!=");
+ RewriterTreeNode child = new RewriterTreeNode(ParserTreeConstants.JJTEQNODE, fName, fValue, negated);
+ return child;
}
- return rebuildQueryFromTree(node);
+ }
}
-
- /**
- *
- * @param query
- * @param fNameUpper
- * @param fValueUpper
- * @return
- * @throws ParseException
- */
- public String applyCaseSensitivity(String query, boolean fNameUpper, boolean fValueUpper) throws ParseException {
- RewriterTreeNode node = parseJexlQuery(query);
- if (log.isDebugEnabled()) {
- log.debug("Tree: " + node.getContents());
+
+ if (node.getType().equals(ASTERNode.class) || node.getType().equals(ASTNRNode.class)) {
+ if (log.isDebugEnabled()) {
+ log.debug("transformTreeNode, Regex Node");
+ }
+
+ Multimap<String,QueryTerm> terms = node.getTerms();
+ for (String fName : terms.keySet()) {
+ Collection<QueryTerm> values = terms.get(fName);
+ for (QueryTerm t : values) {
+ if (null == t || null == t.getValue()) {
+ continue;
+ }
+ String fValue = t.getValue().toString();
+ fValue = fValue.replaceAll("'", "");
+ boolean negated = node.getType().equals(ASTNRNode.class);
+ RewriterTreeNode child = new RewriterTreeNode(ParserTreeConstants.JJTERNODE, fName, fValue, negated);
+ return child;
}
- node = applyCaseSensitivity(node, fNameUpper, fValueUpper);
- if (log.isDebugEnabled()) {
- log.debug("Case: " + node.getContents());
+ }
+ }
+
+ if (node.getType().equals(ASTLTNode.class) || node.getType().equals(ASTLENode.class) || node.getType().equals(ASTGTNode.class)
+ || node.getType().equals(ASTGENode.class)) {
+ if (log.isDebugEnabled()) {
+ log.debug("transformTreeNode, LT/LE/GT/GE node");
+ }
+ Multimap<String,QueryTerm> terms = node.getTerms();
+ for (String fName : terms.keySet()) {
+ Collection<QueryTerm> values = terms.get(fName);
+ for (QueryTerm t : values) {
+ if (null == t || null == t.getValue()) {
+ continue;
+ }
+ String fValue = t.getValue().toString();
+ fValue = fValue.replaceAll("'", "").toLowerCase();
+ boolean negated = false; // to be negated, must be child of Not, which is handled elsewhere.
+ int mytype = JexlOperatorConstants.getJJTNodeType(t.getOperator());
+ RewriterTreeNode child = new RewriterTreeNode(mytype, fName, fValue, negated);
+ return child;
}
- return rebuildQueryFromTree(node);
+ }
}
-
- private String rebuildQueryFromTree(RewriterTreeNode node) {
- if (node.isLeaf()) {
- String fName = node.getFieldName();
- String fValue = node.getFieldValue();
- String operator = node.getOperator();
- if (node.isNegated()) {
- if (node.getType() == JexlOperatorConstants.JJTEQNODE) {
- operator = JexlOperatorConstants.getOperator(JexlOperatorConstants.JJTNENODE);
- } else if (node.getType() == JexlOperatorConstants.JJTERNODE) {
- operator = JexlOperatorConstants.getOperator(JexlOperatorConstants.JJTNRNODE);
- } else if (node.getType() == JexlOperatorConstants.JJTLTNODE) {
- operator = JexlOperatorConstants.getOperator(JexlOperatorConstants.JJTGENODE);
- } else if (node.getType() == JexlOperatorConstants.JJTLENODE) {
- operator = JexlOperatorConstants.getOperator(JexlOperatorConstants.JJTGTNODE);
- } else if (node.getType() == JexlOperatorConstants.JJTGTNODE) {
- operator = JexlOperatorConstants.getOperator(JexlOperatorConstants.JJTLENODE);
- } else if (node.getType() == JexlOperatorConstants.JJTGENODE) {
- operator = JexlOperatorConstants.getOperator(JexlOperatorConstants.JJTLTNODE);
- }
- }
- return fName + operator + "'" + fValue + "'";
- } else {
- List<String> parts = new ArrayList<String>();
- Enumeration<?> children = node.children();
- while (children.hasMoreElements()) {
- RewriterTreeNode child = (RewriterTreeNode) children.nextElement();
- parts.add(rebuildQueryFromTree(child));
- }
- if (node.getType() == ParserTreeConstants.JJTJEXLSCRIPT) {
- return org.apache.commons.lang.StringUtils.join(parts, "");
- }
- String op = " " + JexlOperatorConstants.getOperator(node.getType()) + " ";
+
+ RewriterTreeNode returnNode = null;
+
+ if (node.getType().equals(ASTAndNode.class) || node.getType().equals(ASTOrNode.class)) {
+ int parentType = node.getType().equals(ASTAndNode.class) ? ParserTreeConstants.JJTANDNODE : ParserTreeConstants.JJTORNODE;
+ if (log.isDebugEnabled()) {
+ log.debug("transformTreeNode, AND/OR node: " + parentType);
+ }
+ if (node.isLeaf() || !node.getTerms().isEmpty()) {
+ returnNode = new RewriterTreeNode(parentType);
+ Multimap<String,QueryTerm> terms = node.getTerms();
+ for (String fName : terms.keySet()) {
+ Collection<QueryTerm> values = terms.get(fName);
+ for (QueryTerm t : values) {
+ if (null == t || null == t.getValue()) {
+ continue;
+ }
+ String fValue = t.getValue().toString();
+ fValue = fValue.replaceAll("'", "");
+ boolean negated = t.getOperator().equals("!=");
+ int childType = JexlOperatorConstants.getJJTNodeType(t.getOperator());
+ RewriterTreeNode child = new RewriterTreeNode(childType, fName, fValue, negated);
if (log.isDebugEnabled()) {
- log.debug("Operator: " + op);
+ log.debug("adding child node: " + child.getContents());
}
- String query = org.apache.commons.lang.StringUtils.join(parts, op);
- query = "(" + query + ")";
- return query;
+ returnNode.add(child);
+ }
}
+ } else {
+ returnNode = new RewriterTreeNode(parentType);
+ }
+ } else if (node.getType().equals(ASTNotNode.class)) {
+ if (log.isDebugEnabled()) {
+ log.debug("transformTreeNode, NOT node");
+ }
+ if (node.isLeaf()) {
+ // NOTE: this should be cleaned up a bit.
+ Multimap<String,QueryTerm> terms = node.getTerms();
+ for (String fName : terms.keySet()) {
+ Collection<QueryTerm> values = terms.get(fName);
+ for (QueryTerm t : values) {
+ if (null == t || null == t.getValue()) {
+ continue;
+ }
+ String fValue = t.getValue().toString();
+ fValue = fValue.replaceAll("'", "").toLowerCase();
+ boolean negated = !t.getOperator().equals("!=");
+ int mytype = JexlOperatorConstants.getJJTNodeType(t.getOperator());
+ return new RewriterTreeNode(mytype, fName, fValue, negated);
+ }
+ }
+ } else {
+ returnNode = new RewriterTreeNode(ParserTreeConstants.JJTNOTNODE);
+ }
+ } else if (node.getType().equals(ASTJexlScript.class) || node.getType().getSimpleName().equals("RootNode")) {
+
+ if (log.isDebugEnabled()) {
+ log.debug("transformTreeNode, ROOT/JexlScript node");
+ }
+ if (node.isLeaf()) {
+ returnNode = new RewriterTreeNode(ParserTreeConstants.JJTJEXLSCRIPT);
+ // NOTE: this should be cleaned up a bit.
+ Multimap<String,QueryTerm> terms = node.getTerms();
+ for (String fName : terms.keySet()) {
+ Collection<QueryTerm> values = terms.get(fName);
+ for (QueryTerm t : values) {
+ if (null == t || null == t.getValue()) {
+ continue;
+ }
+ String fValue = t.getValue().toString();
+ fValue = fValue.replaceAll("'", "");
+ boolean negated = t.getOperator().equals("!=");
+ int mytype = JexlOperatorConstants.getJJTNodeType(t.getOperator());
+ RewriterTreeNode child = new RewriterTreeNode(mytype, fName, fValue, negated);
+ returnNode.add(child);
+ return returnNode;
+ }
+ }
+ } else {
+ returnNode = new RewriterTreeNode(ParserTreeConstants.JJTJEXLSCRIPT);
+ }
+ } else {
+ log.error("transformTreeNode, Currently Unsupported Node type: " + node.getClass().getName() + " \t" + node.getType());
}
-
- /*
- * Don't use this, Jexl currently chokes on null bytes in the query
- */
-// public String applyFieldNamePrefix(String query, String prefix) throws ParseException {
-// NuwaveTreeNode node = parseJexlQuery(query);
-// if (log.isDebugEnabled()) {
-// log.debug("Tree: " + node.getContents());
-// }
-// node = applyFieldNamePrefix(node, prefix);
-// if (log.isDebugEnabled()) {
-// log.debug("Prefix: " + node.getContents());
-// }
-// return null;
-// }
- private RewriterTreeNode parseJexlQuery(String query) throws ParseException {
- if (log.isDebugEnabled()) {
- log.debug("parseJexlQuery, query: " + query);
- }
- QueryParser parser = new QueryParser();
- parser.execute(query);
- TreeNode tree = parser.getIteratorTree();
- RewriterTreeNode root = transformTreeNode(tree);
+ for (TreeNode child : node.getChildren()) {
+ returnNode.add(transformTreeNode(child));
+ }
+
+ return returnNode;
+ }
+
+ private RewriterTreeNode removeNonIndexedTerms(RewriterTreeNode root, Multimap indexedTerms) throws Exception {
+ // public void removeNonIndexedTerms(BooleanLogicTreeNodeJexl myroot, String indexedTerms) throws Exception {
+ if (indexedTerms.isEmpty()) {
+ throw new Exception("removeNonIndexedTerms, indexed Terms empty");
+ }
+
+ // NOTE: doing a depth first enumeration didn't work when I started
+ // removing nodes halfway through. The following method does work,
+ // it's essentially a reverse breadth first traversal.
+ List<RewriterTreeNode> nodes = new ArrayList<RewriterTreeNode>();
+ Enumeration<?> bfe = root.breadthFirstEnumeration();
+
+ while (bfe.hasMoreElements()) {
+ RewriterTreeNode node = (RewriterTreeNode) bfe.nextElement();
+ nodes.add(node);
+ }
+
+ // walk backwards
+ for (int i = nodes.size() - 1; i >= 0; i--) {
+ RewriterTreeNode node = nodes.get(i);
+ if (log.isDebugEnabled()) {
+ log.debug("removeNonIndexedTerms, analyzing node: " + node.toString() + " " + node.printNode());
+ }
+ if (node.getType() == ParserTreeConstants.JJTANDNODE || node.getType() == ParserTreeConstants.JJTORNODE) {
+ // If all of your children are gone, AND/OR has no purpose, remove
+ if (node.getChildCount() == 0) {
+ node.removeFromParent();
+
+ // If AND/OR has only 1 child, attach it to the parent directly.
+ } else if (node.getChildCount() == 1) {
+ RewriterTreeNode p = (RewriterTreeNode) node.getParent();
+ RewriterTreeNode c = (RewriterTreeNode) node.getFirstChild();
+ node.removeFromParent();
+ p.add(c);
+ }
+ } else if (node.getType() == ParserTreeConstants.JJTJEXLSCRIPT) { // Head node
+ // If head node has no children, we have nothing to search on.
+ if (node.getChildCount() == 0) {
+ throw new Exception();
+ }
+ } else if (rangeNodeSet.contains(node.getType())) { // leave it alone
+ // leave ranges untouched, they'll be handled elsewhere.
+ continue;
+ } else {
if (log.isDebugEnabled()) {
- log.debug("parseJexlQuery, transformedTree: " + root.getContents());
+ log.debug("removeNonIndexedTerms, Testing: " + node.getFieldName() + ":" + node.getFieldValue());
}
- root = refactorTree(root);
- if (log.isDebugEnabled()) {
- log.debug("parseJexlQuery, refactorTree: " + root.getContents());
+
+ if (!indexedTerms.containsKey(node.getFieldName().toString() + ":" + node.getFieldValue().toString())) {
+ if (log.isDebugEnabled()) {
+ log.debug(node.getFieldName() + ":" + node.getFieldValue() + " is NOT indexed");
+ }
+ node.removeFromParent();
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug(node.getFieldName() + ":" + node.getFieldValue() + " is indexed");
+ }
}
- return root;
+ }
}
-
- /*
- *
- */
- private RewriterTreeNode transformTreeNode(TreeNode node) throws ParseException {
- if (node.getType().equals(ASTEQNode.class) || node.getType().equals(ASTNENode.class)) {
- if (log.isDebugEnabled()) {
- log.debug("transformTreeNode, Equals Node");
- }
-
- Multimap<String, QueryTerm> terms = node.getTerms();
- for (String fName : terms.keySet()) {
- Collection<QueryTerm> values = terms.get(fName);
-
- for (QueryTerm t : values) {
- if (null == t || null == t.getValue()) {
- continue;
- }
- String fValue = t.getValue().toString();
- fValue = fValue.replaceAll("'", "");
- boolean negated = t.getOperator().equals("!=");
- RewriterTreeNode child = new RewriterTreeNode(ParserTreeConstants.JJTEQNODE, fName, fValue, negated);
- return child;
- }
- }
- }
-
- if (node.getType().equals(ASTERNode.class) || node.getType().equals(ASTNRNode.class)) {
- if (log.isDebugEnabled()) {
- log.debug("transformTreeNode, Regex Node");
- }
-
- Multimap<String, QueryTerm> terms = node.getTerms();
- for (String fName : terms.keySet()) {
- Collection<QueryTerm> values = terms.get(fName);
- for (QueryTerm t : values) {
- if (null == t || null == t.getValue()) {
- continue;
- }
- String fValue = t.getValue().toString();
- fValue = fValue.replaceAll("'", "");
- boolean negated = node.getType().equals(ASTNRNode.class);
- RewriterTreeNode child = new RewriterTreeNode(ParserTreeConstants.JJTERNODE, fName, fValue, negated);
- return child;
- }
- }
- }
-
- if (node.getType().equals(ASTLTNode.class) || node.getType().equals(ASTLENode.class)
- || node.getType().equals(ASTGTNode.class) || node.getType().equals(ASTGENode.class)) {
- if (log.isDebugEnabled()) {
- log.debug("transformTreeNode, LT/LE/GT/GE node");
- }
- Multimap<String, QueryTerm> terms = node.getTerms();
- for (String fName : terms.keySet()) {
- Collection<QueryTerm> values = terms.get(fName);
- for (QueryTerm t : values) {
- if (null == t || null == t.getValue()) {
- continue;
- }
- String fValue = t.getValue().toString();
- fValue = fValue.replaceAll("'", "").toLowerCase();
- boolean negated = false; // to be negated, must be child of Not, which is handled elsewhere.
- int mytype = JexlOperatorConstants.getJJTNodeType(t.getOperator());
- RewriterTreeNode child = new RewriterTreeNode(mytype, fName, fValue, negated);
- return child;
- }
- }
+
+ return root;
+ }
+
+ private RewriterTreeNode orNormalizedTerms(RewriterTreeNode myroot, Multimap indexedTerms) throws Exception {
+ // we have multimap of FieldName to multiple FieldValues
+ if (indexedTerms.isEmpty()) {
+ throw new Exception("indexed Terms empty");
+ }
+ try {
+ // NOTE: doing a depth first enumeration didn't work when I started
+ // removing nodes halfway through. The following method does work,
+ // it's essentially a reverse breadth first traversal.
+ List<RewriterTreeNode> nodes = new ArrayList<RewriterTreeNode>();
+ Enumeration<?> bfe = myroot.breadthFirstEnumeration();
+
+ while (bfe.hasMoreElements()) {
+ RewriterTreeNode node = (RewriterTreeNode) bfe.nextElement();
+ nodes.add(node);
+ }
+
+ // walk backwards
+ for (int i = nodes.size() - 1; i >= 0; i--) {
+ RewriterTreeNode node = nodes.get(i);
+ if (log.isDebugEnabled()) {
+ log.debug("orNormalizedTerms, analyzing node: " + node.toString() + " " + node.printNode());
}
-
-
- RewriterTreeNode returnNode = null;
-
- if (node.getType().equals(ASTAndNode.class) || node.getType().equals(ASTOrNode.class)) {
- int parentType = node.getType().equals(ASTAndNode.class) ? ParserTreeConstants.JJTANDNODE : ParserTreeConstants.JJTORNODE;
- if (log.isDebugEnabled()) {
- log.debug("transformTreeNode, AND/OR node: " + parentType);
- }
- if (node.isLeaf() || !node.getTerms().isEmpty()) {
- returnNode = new RewriterTreeNode(parentType);
- Multimap<String, QueryTerm> terms = node.getTerms();
- for (String fName : terms.keySet()) {
- Collection<QueryTerm> values = terms.get(fName);
- for (QueryTerm t : values) {
- if (null == t || null == t.getValue()) {
- continue;
- }
- String fValue = t.getValue().toString();
- fValue = fValue.replaceAll("'", "");
- boolean negated = t.getOperator().equals("!=");
- int childType = JexlOperatorConstants.getJJTNodeType(t.getOperator());
- RewriterTreeNode child = new RewriterTreeNode(childType, fName, fValue, negated);
- if (log.isDebugEnabled()) {
- log.debug("adding child node: " + child.getContents());
- }
- returnNode.add(child);
- }
- }
- } else {
- returnNode = new RewriterTreeNode(parentType);
- }
- } else if (node.getType().equals(ASTNotNode.class)) {
- if (log.isDebugEnabled()) {
- log.debug("transformTreeNode, NOT node");
- }
- if (node.isLeaf()) {
- //NOTE: this should be cleaned up a bit.
- Multimap<String, QueryTerm> terms = node.getTerms();
- for (String fName : terms.keySet()) {
- Collection<QueryTerm> values = terms.get(fName);
- for (QueryTerm t : values) {
- if (null == t || null == t.getValue()) {
- continue;
- }
- String fValue = t.getValue().toString();
- fValue = fValue.replaceAll("'", "").toLowerCase();
- boolean negated = !t.getOperator().equals("!=");
- int mytype = JexlOperatorConstants.getJJTNodeType(t.getOperator());
- return new RewriterTreeNode(mytype, fName, fValue, negated);
- }
- }
- } else {
- returnNode = new RewriterTreeNode(ParserTreeConstants.JJTNOTNODE);
- }
- } else if (node.getType().equals(ASTJexlScript.class) || node.getType().getSimpleName().equals("RootNode")) {
-
+ if (node.getType() == ParserTreeConstants.JJTANDNODE || node.getType() == ParserTreeConstants.JJTORNODE) {
+ continue;
+ } else if (node.getType() == ParserTreeConstants.JJTJEXLSCRIPT) {
+ if (node.getChildCount() == 0) {
if (log.isDebugEnabled()) {
- log.debug("transformTreeNode, ROOT/JexlScript node");
- }
- if (node.isLeaf()) {
- returnNode = new RewriterTreeNode(ParserTreeConstants.JJTJEXLSCRIPT);
- //NOTE: this should be cleaned up a bit.
- Multimap<String, QueryTerm> terms = node.getTerms();
- for (String fName : terms.keySet()) {
- Collection<QueryTerm> values = terms.get(fName);
- for (QueryTerm t : values) {
- if (null == t || null == t.getValue()) {
- continue;
- }
- String fValue = t.getValue().toString();
- fValue = fValue.replaceAll("'", "");
- boolean negated = t.getOperator().equals("!=");
- int mytype = JexlOperatorConstants.getJJTNodeType(t.getOperator());
- RewriterTreeNode child = new RewriterTreeNode(mytype, fName, fValue, negated);
- returnNode.add(child);
- return returnNode;
- }
- }
- } else {
- returnNode = new RewriterTreeNode(ParserTreeConstants.JJTJEXLSCRIPT);
+ log.debug("orNormalizedTerms: Head node has no children!");
}
+ throw new Exception(); // Head node has no children.
+ }
} else {
- log.error("transformTreeNode, Currently Unsupported Node type: " + node.getClass().getName() + " \t" + node.getType());
- }
- for (TreeNode child : node.getChildren()) {
- returnNode.add(transformTreeNode(child));
- }
-
- return returnNode;
+ if (log.isDebugEnabled()) {
+ log.debug("Testing data location: " + node.getFieldName());
+ }
+ String fName = node.getFieldName().toString();
+ String fValue = node.getFieldValue().toString();
+ if (indexedTerms.containsKey(fName + ":" + fValue)) {
+
+ if (indexedTerms.get(fName + ":" + fValue).size() > 1) {
+ // Replace node with an OR, and make children from the multimap collection
+ node.setType(ParserTreeConstants.JJTORNODE);
+ boolean neg = node.isNegated();
+ node.setNegated(false);
+ node.setFieldName(null);
+ node.setFieldValue(null);
+ Collection<String> values = indexedTerms.get(fName + ":" + fValue);
+ for (String value : values) {
+ RewriterTreeNode n = new RewriterTreeNode(ParserTreeConstants.JJTEQNODE, fName, value, neg);
+ node.add(n);
+ }
+ } else if (indexedTerms.get(fName + ":" + fValue).size() == 1) {
+ // Straight replace
+ Collection<String> values = indexedTerms.get(fName + ":" + fValue);
+ for (String val : values) {
+ // should only be 1
+ node.setFieldValue(val);
+ }
+ }
+
+ } else {
+ // throw new Exception("orNormalizedTerms, encountered a non-indexed term: " + node.getFieldName().toString());
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.debug("Caught exception in orNormalizedTerms(): " + e);
+ throw new Exception("exception in: orNormalizedTerms");
}
-
- private RewriterTreeNode removeNonIndexedTerms(RewriterTreeNode root, Multimap indexedTerms) throws Exception {
- //public void removeNonIndexedTerms(BooleanLogicTreeNodeJexl myroot, String indexedTerms) throws Exception {
- if (indexedTerms.isEmpty()) {
- throw new Exception("removeNonIndexedTerms, indexed Terms empty");
+
+ return myroot;
+ }
+
+ /***
+ * We only want to pass ranges on if they meet a very narrow set of conditions. All ranges must be bounded i.e. x between(1,5) so their parent is an AND. We
+ * will only pass a range if 1. The AND is the direct child of HEAD node 2. The AND is a child of an OR which is a direct child of HEAD node.
+ *
+ * If there is an HEAD-AND[x,OR[b,AND[range]]], and you remove the range, this turns the tree into HEAD-AND[X,OR[B]] which becomes HEAD-AND[X,B] which will
+ * miss entries, so you need to cut out the entire OR at this point and let the positive side of the AND pick it up.
+ */
+ private RewriterTreeNode removeTreeConflicts(RewriterTreeNode root, Multimap indexedTerms) {
+ if (log.isDebugEnabled()) {
+ log.debug("removeTreeConflicts");
+ }
+
+ /*
+ * You can't modify the enumeration, so save it into a list. We want to walk backwards in a breadthFirstEnumeration. So we don't throw null pointers when we
+ * erase nodes and shorten our list.
+ */
+ List<RewriterTreeNode> nodeList = new ArrayList<RewriterTreeNode>();
+ Enumeration<?> nodes = root.breadthFirstEnumeration();
+ while (nodes.hasMoreElements()) {
+ RewriterTreeNode child = (RewriterTreeNode) nodes.nextElement();
+ nodeList.add(child);
+ }
+
+ // walk backwards
+ for (int i = nodeList.size() - 1; i >= 0; i--) {
+ RewriterTreeNode node = nodeList.get(i);
+
+ if (node.isRemoval()) {
+ node.removeFromParent();
+ continue;
+ }
+
+ RewriterTreeNode parent = (RewriterTreeNode) node.getParent();
+ /*
+ * All ranges must be bounded! This means the range must be part of an AND, and the parent of AND must be a HEAD node or an OR whose parent is a HEAD
+ * node.
+ */
+ if (node.getType() == ParserTreeConstants.JJTANDNODE
+ && (node.getLevel() == 1 || (parent.getType() == ParserTreeConstants.JJTORNODE && parent.getLevel() == 1))) {
+
+ if (log.isDebugEnabled()) {
+ log.debug("AND at level 1 or with OR parent at level 1");
}
-
- // NOTE: doing a depth first enumeration didn't work when I started
- // removing nodes halfway through. The following method does work,
- // it's essentially a reverse breadth first traversal.
- List<RewriterTreeNode> nodes = new ArrayList<RewriterTreeNode>();
- Enumeration<?> bfe = root.breadthFirstEnumeration();
-
- while (bfe.hasMoreElements()) {
- RewriterTreeNode node = (RewriterTreeNode) bfe.nextElement();
- nodes.add(node);
+ Map<Text,RangeBounds> rangeMap = getBoundedRangeMap(node);
+
+ // can't modify the enumeration... save children to a list.
+ List<RewriterTreeNode> childList = new ArrayList<RewriterTreeNode>();
+ Enumeration<?> children = node.children();
+ while (children.hasMoreElements()) {
+ RewriterTreeNode child = (RewriterTreeNode) children.nextElement();
+ childList.add(child);
}
-
- // walk backwards
- for (int i = nodes.size() - 1; i >= 0; i--) {
- RewriterTreeNode node = nodes.get(i);
+
+ for (int j = childList.size() - 1; j >= 0; j--) {
+ RewriterTreeNode child = childList.get(j);
+ // currently we are not allowing unbounded ranges, so they must sit under an AND node.
+ if (rangeNodeSet.contains(child.getType())) {
if (log.isDebugEnabled()) {
- log.debug("removeNonIndexedTerms, analyzing node: " + node.toString() + " " + node.printNode());
+ log.debug("child type: " + JexlOperatorConstants.getOperator(child.getType()));
}
- if (node.getType() == ParserTreeConstants.JJTANDNODE || node.getType() == ParserTreeConstants.JJTORNODE) {
- // If all of your children are gone, AND/OR has no purpose, remove
- if (node.getChildCount() == 0) {
- node.removeFromParent();
-
- // If AND/OR has only 1 child, attach it to the parent directly.
- } else if (node.getChildCount() == 1) {
- RewriterTreeNode p = (RewriterTreeNode) node.getParent();
- RewriterTreeNode c = (RewriterTreeNode) node.getFirstChild();
- node.removeFromParent();
- p.add(c);
- }
- } else if (node.getType() == ParserTreeConstants.JJTJEXLSCRIPT) { // Head node
- // If head node has no children, we have nothing to search on.
- if (node.getChildCount() == 0) {
- throw new Exception();
- }
- } else if (rangeNodeSet.contains(node.getType())) { // leave it alone
- //leave ranges untouched, they'll be handled elsewhere.
- continue;
+ if (rangeMap == null) {
+ // remove
+ child.removeFromParent();
} else {
+ if (!rangeMap.containsKey(new Text(child.getFieldName()))) {
+ child.removeFromParent();
+ } else {
+ // check if it has a single non-range sibling
+ boolean singleSib = false;
if (log.isDebugEnabled()) {
- log.debug("removeNonIndexedTerms, Testing: " + node.getFieldName() + ":" + node.getFieldValue());
+ log.debug("checking for singleSib.");
}
-
- if (!indexedTerms.containsKey(node.getFieldName().toString() + ":" + node.getFieldValue().toString())) {
- if (log.isDebugEnabled()) {
- log.debug(node.getFieldName() + ":" + node.getFieldValue() + " is NOT indexed");
- }
- node.removeFromParent();
- } else {
- if (log.isDebugEnabled()) {
- log.debug(node.getFieldName() + ":" + node.getFieldValue() + " is indexed");
- }
- }
- }
- }
-
- return root;
- }
-
- private RewriterTreeNode orNormalizedTerms(RewriterTreeNode myroot, Multimap indexedTerms) throws Exception {
- // we have multimap of FieldName to multiple FieldValues
- if (indexedTerms.isEmpty()) {
- throw new Exception("indexed Terms empty");
- }
- try {
- // NOTE: doing a depth first enumeration didn't work when I started
- // removing nodes halfway through. The following method does work,
- // it's essentially a reverse breadth first traversal.
- List<RewriterTreeNode> nodes = new ArrayList<RewriterTreeNode>();
- Enumeration<?> bfe = myroot.breadthFirstEnumeration();
-
- while (bfe.hasMoreElements()) {
- RewriterTreeNode node = (RewriterTreeNode) bfe.nextElement();
- nodes.add(node);
- }
-
- // walk backwards
- for (int i = nodes.size() - 1; i >= 0; i--) {
- RewriterTreeNode node = nodes.get(i);
- if (log.isDebugEnabled()) {
- log.debug("orNormalizedTerms, analyzing node: " + node.toString() + " " + node.printNode());
+ Enumeration<?> sibs = child.getParent().children();
+ while (sibs.hasMoreElements()) {
+ RewriterTreeNode sib = (RewriterTreeNode) sibs.nextElement();
+ if (!rangeNodeSet.contains(sib.getType())) {
+ singleSib = true;
+ break;
+ }
}
- if (node.getType() == ParserTreeConstants.JJTANDNODE || node.getType() == ParserTreeConstants.JJTORNODE) {
- continue;
- } else if (node.getType() == ParserTreeConstants.JJTJEXLSCRIPT) {
- if (node.getChildCount() == 0) {
- if (log.isDebugEnabled()) {
- log.debug("orNormalizedTerms: Head node has no children!");
- }
- throw new Exception(); //Head node has no children.
- }
+ if (singleSib) {
+ child.removeFromParent();
} else {
+ if (indexedTerms.containsKey(child.getFieldName() + ":" + child.getFieldValue())) {
if (log.isDebugEnabled()) {
- log.debug("Testing data location: " + node.getFieldName());
+ log.debug("removeTreeConflicts, node: " + node.getContents());
}
- String fName = node.getFieldName().toString();
- String fValue = node.getFieldValue().toString();
- if (indexedTerms.containsKey(fName + ":" + fValue)) {
-
- if (indexedTerms.get(fName + ":" + fValue).size() > 1) {
- // Replace node with an OR, and make children from the multimap collection
- node.setType(ParserTreeConstants.JJTORNODE);
- boolean neg = node.isNegated();
- node.setNegated(false);
- node.setFieldName(null);
- node.setFieldValue(null);
- Collection<String> values = indexedTerms.get(fName + ":" + fValue);
- for (String value : values) {
- RewriterTreeNode n = new RewriterTreeNode(ParserTreeConstants.JJTEQNODE, fName, value, neg);
- node.add(n);
- }
- } else if (indexedTerms.get(fName + ":" + fValue).size() == 1) {
- //Straight replace
- Collection<String> values = indexedTerms.get(fName + ":" + fValue);
- for (String val : values) {
- //should only be 1
- node.setFieldValue(val);
- }
- }
-
- } else {
- //throw new Exception("orNormalizedTerms, encountered a non-indexed term: " + node.getFieldName().toString());
+ // swap parent AND with an OR
+ node.removeAllChildren();
+ node.setType(ParserTreeConstants.JJTORNODE);
+
+ Collection<String> values = indexedTerms.get(child.getFieldName() + ":" + child.getFieldValue());
+ for (String value : values) {
+ RewriterTreeNode n = new RewriterTreeNode(ParserTreeConstants.JJTEQNODE, child.getFieldName(), value, child.isNegated());
+ node.add(n);
}
- }
- }
- } catch (Exception e) {
- log.debug("Caught exception in orNormalizedTerms(): " + e);
- throw new Exception("exception in: orNormalizedTerms");
- }
-
- return myroot;
- }
-
- /***
- * We only want to pass ranges on if they meet a very narrow set of conditions.
- * All ranges must be bounded i.e. x between(1,5) so their parent is an AND.
- * We will only pass a range if
- * 1. The AND is the direct child of HEAD node
- * 2. The AND is a child of an OR which is a direct child of HEAD node.
- *
- * If there is an HEAD-AND[x,OR[b,AND[range]]], and you remove the range, this turns
- * the tree into HEAD-AND[X,OR[B]] which becomes HEAD-AND[X,B] which will miss entries, so you
- * need to cut out the entire OR at this point and let the positive side of the AND
- * pick it up.
- */
- private RewriterTreeNode removeTreeConflicts(RewriterTreeNode root, Multimap indexedTerms) {
- if (log.isDebugEnabled()) {
- log.debug("removeTreeConflicts");
- }
-
- /*
- * You can't modify the enumeration, so save it into a list.
- * We want to walk backwards in a breadthFirstEnumeration. So we don't
- * throw null pointers when we erase nodes and shorten our list.
- */
- List<RewriterTreeNode> nodeList = new ArrayList<RewriterTreeNode>();
- Enumeration<?> nodes = root.breadthFirstEnumeration();
- while (nodes.hasMoreElements()) {
- RewriterTreeNode child = (RewriterTreeNode) nodes.nextElement();
- nodeList.add(child);
- }
-
- //walk backwards
- for (int i = nodeList.size() - 1; i >= 0; i--) {
- RewriterTreeNode node = nodeList.get(i);
-
- if (node.isRemoval()) {
- node.removeFromParent();
- continue;
- }
-
- RewriterTreeNode parent = (RewriterTreeNode) node.getParent();
- /*
- * All ranges must be bounded! This means the range must be part of an AND, and
- * the parent of AND must be a HEAD node or an OR whose parent is a HEAD node.
- */
- if (node.getType() == ParserTreeConstants.JJTANDNODE
- && (node.getLevel() == 1 || (parent.getType() == ParserTreeConstants.JJTORNODE && parent.getLevel() == 1))) {
-
- if (log.isDebugEnabled()) {
- log.debug("AND at level 1 or with OR parent at level 1");
- }
- Map<Text, RangeBounds> rangeMap = getBoundedRangeMap(node);
-
- // can't modify the enumeration... save children to a list.
- List<RewriterTreeNode> childList = new ArrayList<RewriterTreeNode>();
- Enumeration<?> children = node.children();
- while (children.hasMoreElements()) {
- RewriterTreeNode child = (RewriterTreeNode) children.nextElement();
- childList.add(child);
- }
-
- for (int j = childList.size() - 1; j >= 0; j--) {
- RewriterTreeNode child = childList.get(j);
- // currently we are not allowing unbounded ranges, so they must sit under an AND node.
- if (rangeNodeSet.contains(child.getType())) {
- if (log.isDebugEnabled()) {
- log.debug("child type: " + JexlOperatorConstants.getOperator(child.getType()));
- }
- if (rangeMap == null) {
- //remove
- child.removeFromParent();
- } else {
- if (!rangeMap.containsKey(new Text(child.getFieldName()))) {
- child.removeFromParent();
- } else {
- //check if it has a single non-range sibling
- boolean singleSib = false;
- if (log.isDebugEnabled()) {
- log.debug("checking for singleSib.");
- }
- Enumeration<?> sibs = child.getParent().children();
- while (sibs.hasMoreElements()) {
- RewriterTreeNode sib = (RewriterTreeNode) sibs.nextElement();
- if (!rangeNodeSet.contains(sib.getType())) {
- singleSib = true;
- break;
- }
- }
- if (singleSib) {
- child.removeFromParent();
- } else {
- if (indexedTerms.containsKey(child.getFieldName() + ":" + child.getFieldValue())) {
- if(log.isDebugEnabled()){
- log.debug("removeTreeConflicts, node: "+node.getContents());
- }
- //swap parent AND with an OR
- node.removeAllChildren();
- node.setType(ParserTreeConstants.JJTORNODE);
-
- Collection<String> values = indexedTerms.get(child.getFieldName() + ":" + child.getFieldValue());
- for (String value : values) {
- RewriterTreeNode n = new RewriterTreeNode(ParserTreeConstants.JJTEQNODE, child.getFieldName(), value, child.isNegated());
- node.add(n);
- }
- if(log.isDebugEnabled()){
- log.debug("removeTreeConflicts, node: "+node.getContents());
- }
-
- break;
- }else{
- child.removeFromParent();
- }
-
- }
- }
- }
- }
- }//end inner for
-
- } else { // remove all ranges!
- if (node.isLeaf()) {
- continue;
- }
- // can't modify the enumeration...
- List<RewriterTreeNode> childList = new ArrayList<RewriterTreeNode>();
- Enumeration<?> children = node.children();
- while (children.hasMoreElements()) {
- RewriterTreeNode child = (RewriterTreeNode) children.nextElement();
- childList.add(child);
- }
-
- //walk backwards
- for (int j = childList.size() - 1; j >= 0; j--) {
-
- RewriterTreeNode child = childList.get(j);
if (log.isDebugEnabled()) {
- log.debug("removeTreeConflicts, looking at node: " + node);
- }
- if (rangeNodeSet.contains(child.getType())) {
- // if grand parent is an OR and not top level, mark whole thing for removal.
- RewriterTreeNode grandParent = (RewriterTreeNode) child.getParent().getParent();
- if (grandParent.getType() == ParserTreeConstants.JJTORNODE && grandParent.getLevel() != 1) {
- grandParent.setRemoval(true);
- }
- child.removeFromParent();
+ log.debug("removeTreeConflicts, node: " + node.getContents());
}
+
+ break;
+ } else {
+ child.removeFromParent();
+ }
+
}
+ }
}
-
- }// end outer for
-
-
- return root;
- }
-
- private RewriterTreeNode removeNegationViolations(RewriterTreeNode node) throws Exception {
- // Double check the top level node for negation violations
- // if AND, one child must be positive, if OR, no negatives allowed.
- RewriterTreeNode one = (RewriterTreeNode) node.getFirstChild(); //Head node has only 1 child.
- ArrayList<RewriterTreeNode> childrenList = new ArrayList<RewriterTreeNode>();
- Enumeration<?> children = one.children();
+ }
+ }// end inner for
+
+ } else { // remove all ranges!
+ if (node.isLeaf()) {
+ continue;
+ }
+ // can't modify the enumeration...
+ List<RewriterTreeNode> childList = new ArrayList<RewriterTreeNode>();
+ Enumeration<?> children = node.children();
while (children.hasMoreElements()) {
- RewriterTreeNode child = (RewriterTreeNode) children.nextElement();
- childrenList.add(child);
+ RewriterTreeNode child = (RewriterTreeNode) children.nextElement();
+ childList.add(child);
}
- if (one.getType() == JexlOperatorConstants.JJTORNODE) {
- for (RewriterTreeNode child : childrenList) {
- if (child.isNegated()) {
- child.removeFromParent();
- }
- }
- if (one.getChildCount() == 0) {
- throw new Exception("FieldIndexQueryReWriter: Top level query node cannot be processed.");
- }
- } else if (one.getType() == JexlOperatorConstants.JJTANDNODE) {
- boolean ok = false;
- for (RewriterTreeNode child : childrenList) {
- if (!child.isNegated()) {
- ok = true;
- break;
- }
- }
- if (!ok) {
- throw new Exception("FieldIndexQueryReWriter: Top level query node cannot be processed.");
- }
+
+ // walk backwards
+ for (int j = childList.size() - 1; j >= 0; j--) {
+
+ RewriterTreeNode child = childList.get(j);
+ if (log.isDebugEnabled()) {
+ log.debug("removeTreeConflicts, looking at node: " + node);
+ }
+ if (rangeNodeSet.contains(child.getType())) {
+ // if grand parent is an OR and not top level, mark whole thing for removal.
+ RewriterTreeNode grandParent = (RewriterTreeNode) child.getParent().getParent();
+ if (grandParent.getType() == ParserTreeConstants.JJTORNODE && grandParent.getLevel() != 1) {
+ grandParent.setRemoval(true);
+ }
+ child.removeFromParent();
+ }
+ }
+ }
+
+ }// end outer for
+
+ return root;
+ }
+
+ private RewriterTreeNode removeNegationViolations(RewriterTreeNode node) throws Exception {
+ // Double check the top level node for negation violations
+ // if AND, one child must be positive, if OR, no negatives allowed.
+ RewriterTreeNode one = (RewriterTreeNode) node.getFirstChild(); // Head node has only 1 child.
+ ArrayList<RewriterTreeNode> childrenList = new ArrayList<RewriterTreeNode>();
+ Enumeration<?> children = one.children();
+ while (children.hasMoreElements()) {
+ RewriterTreeNode child = (RewriterTreeNode) children.nextElement();
+ childrenList.add(child);
+ }
+ if (one.getType() == JexlOperatorConstants.JJTORNODE) {
+ for (RewriterTreeNode child : childrenList) {
+ if (child.isNegated()) {
+ child.removeFromParent();
+ }
+ }
+ if (one.getChildCount() == 0) {
+ throw new Exception("FieldIndexQueryReWriter: Top level query node cannot be processed.");
+ }
+ } else if (one.getType() == JexlOperatorConstants.JJTANDNODE) {
+ boolean ok = false;
+ for (RewriterTreeNode child : childrenList) {
+ if (!child.isNegated()) {
+ ok = true;
+ break;
+ }
+ }
+ if (!ok) {
+ throw new Exception("FieldIndexQueryReWriter: Top level query node cannot be processed.");
+ }
+ }
+
+ return node;
+ }
+
+ // After tree conflicts have been resolve, we can collapse branches where
+ // leaves have been pruned.
+ private RewriterTreeNode collapseBranches(RewriterTreeNode myroot) throws Exception {
+
+ // NOTE: doing a depth first enumeration didn't wory when I started
+ // removing nodes halfway through. The following method does work,
+ // it's essentially a reverse breadth first traversal.
+ List<RewriterTreeNode> nodes = new ArrayList<RewriterTreeNode>();
+ Enumeration<?> bfe = myroot.breadthFirstEnumeration();
+
+ while (bfe.hasMoreElements()) {
+ RewriterTreeNode node = (RewriterTreeNode) bfe.nextElement();
+ nodes.add(node);
+ }
+
+ // walk backwards
+ for (int i = nodes.size() - 1; i >= 0; i--) {
+ RewriterTreeNode node = nodes.get(i);
+ if (log.isDebugEnabled()) {
+ log.debug("collapseBranches, inspecting node: " + node.toString() + " " + node.printNode());
+ }
+
+ if (node.getType() == ParserTreeConstants.JJTANDNODE || node.getType() == ParserTreeConstants.JJTORNODE) {
+ if (node.getChildCount() == 0) {
+ node.removeFromParent();
+ } else if (node.getChildCount() == 1) {
+ RewriterTreeNode p = (RewriterTreeNode) node.getParent();
+ RewriterTreeNode c = (RewriterTreeNode) node.getFirstChild();
+ node.removeFromParent();
+ p.add(c);
+
+ }
+ } else if (node.getType() == ParserTreeConstants.JJTJEXLSCRIPT) {
+ if (node.getChildCount() == 0) {
+ throw new Exception();
}
-
- return node;
+ }
}
-
- // After tree conflicts have been resolve, we can collapse branches where
- // leaves have been pruned.
- private RewriterTreeNode collapseBranches(RewriterTreeNode myroot) throws Exception {
-
- // NOTE: doing a depth first enumeration didn't wory when I started
- // removing nodes halfway through. The following method does work,
- // it's essentially a reverse breadth first traversal.
- List<RewriterTreeNode> nodes = new ArrayList<RewriterTreeNode>();
- Enumeration<?> bfe = myroot.breadthFirstEnumeration();
-
- while (bfe.hasMoreElements()) {
- RewriterTreeNode node = (RewriterTreeNode) bfe.nextElement();
- nodes.add(node);
+ return myroot;
+ }
+
+ /**
+ *
+ * @param options
+ * @return
+ */
+ public Multimap<String,String> parseIndexedTerms(Map<String,String> options) {
+ if (options.get(INDEXED_TERMS_LIST) != null) {
+ Multimap<String,String> mmap = HashMultimap.create();
+ String[] items = options.get(INDEXED_TERMS_LIST).split(";");
+ for (String item : items) {
+ item = item.trim();
+ if (log.isDebugEnabled()) {}
+ String[] parts = item.split(":");
+ if (log.isDebugEnabled()) {
+ log.debug("adding: " + parts[0]);
}
-
- // walk backwards
- for (int i = nodes.size() - 1; i >= 0; i--) {
- RewriterTreeNode node = nodes.get(i);
- if (log.isDebugEnabled()) {
- log.debug("collapseBranches, inspecting node: " + node.toString() + " " + node.printNode());
- }
-
- if (node.getType() == ParserTreeConstants.JJTANDNODE || node.getType() == ParserTreeConstants.JJTORNODE) {
- if (node.getChildCount() == 0) {
- node.removeFromParent();
- } else if (node.getChildCount() == 1) {
- RewriterTreeNode p = (RewriterTreeNode) node.getParent();
- RewriterTreeNode c = (RewriterTreeNode) node.getFirstChild();
- node.removeFromParent();
- p.add(c);
-
- }
- } else if (node.getType() == ParserTreeConstants.JJTJEXLSCRIPT) {
- if (node.getChildCount() == 0) {
- throw new Exception();
- }
- }
+ for (int i = 2; i < parts.length; i++) {
+ // key is original query token, i.e. color:red
+ mmap.put(parts[0] + ":" + parts[1], parts[i]);
+
+ }
+
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("multimap: " + mmap);
+ }
+ return mmap;
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("parseIndexedTerms: returning null");
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param root
+ * @return
+ */
+ public RewriterTreeNode refactorTree(RewriterTreeNode root) {
+ Enumeration<?> dfe = root.breadthFirstEnumeration();
+
+ while (dfe.hasMoreElements()) {
+ RewriterTreeNode n = (RewriterTreeNode) dfe.nextElement();
+
+ if (n.getType() == ParserTreeConstants.JJTNOTNODE) {// BooleanLogicTreeNode.NodeType.NOT) {
+ RewriterTreeNode child = (RewriterTreeNode) n.getChildAt(0);
+ child.setNegated(true);
+ RewriterTreeNode parent = (RewriterTreeNode) n.getParent();
+ parent.remove(n);
+ parent.add(child);
+ }
+ }
+
+ // cycle through again and distribute nots
+ Enumeration<?> bfe = root.breadthFirstEnumeration();
+ RewriterTreeNode child;
+
+ while (bfe.hasMoreElements()) {
+ child = (RewriterTreeNode) bfe.nextElement();
+
+ if (child.isNegated()) {
+ if (child.getChildCount() > 0) {
+ demorganSubTree(child);
+
}
- return myroot;
+ }
}
-
+ return root;
+
+ }
+
+ private void demorganSubTree(RewriterTreeNode root) {
+
+ root.setNegated(false);
+ // root.setChildrenAllNegated(true);
+
+ if (root.getType() == ParserTreeConstants.JJTANDNODE) {// BooleanLogicTreeNode.NodeType.AND) {
+ // root.setType(BooleanLogicTreeNode.NodeType.OR);
+ root.setType(ParserTreeConstants.JJTORNODE);
+ } else if (root.getType() == ParserTreeConstants.JJTORNODE) {// BooleanLogicTreeNode.NodeType.OR) {
+ // root.setType(BooleanLogicTreeNode.NodeType.AND);
+ root.setType(ParserTreeConstants.JJTANDNODE);
+ } else if (root.getType() == ParserTreeConstants.JJTEQNODE || root.getType() == ParserTreeConstants.JJTERNODE) {
+ // do nothing
+ } else {
+ log.error("refactorSubTree, node type not supported");
+ }
+
+ Enumeration<?> children = root.children();
+ RewriterTreeNode child = null;
+ // now distribute the negative
+
+ while (children.hasMoreElements()) {
+ child = (RewriterTreeNode) children.nextElement();
+ if (child.isNegated()) {
+ child.setNegated(false);
+ } else {
+ child.setNegated(true);
+ }
+ }
+ }
+
+ private RewriterTreeNode applyCaseSensitivity(RewriterTreeNode root, boolean fnUpper, boolean fvUpper) {
+ // for each leaf, apply case sensitivity
+ Enumeration<?> bfe = root.breadthFirstEnumeration();
+ while (bfe.hasMoreElements()) {
+ RewriterTreeNode node = (RewriterTreeNode) bfe.nextElement();
+ if (node.isLeaf()) {
+ String fName = fnUpper ? node.getFieldName().toUpperCase() : node.getFieldName().toLowerCase();
+ node.setFieldName(fName);
+
+ String fValue = fvUpper ? node.getFieldValue().toUpperCase() : node.getFieldValue().toLowerCase();
+ node.setFieldValue(fValue);
+
+ }
+ }
+ return root;
+ }
+
+ private Map<Text,RangeBounds> getBoundedRangeMap(RewriterTreeNode node) {
+
+ boolean upper = false;
+ boolean lower = false;
+ if (node.getType() == ParserTreeConstants.JJTANDNODE || node.getType() == ParserTreeConstants.JJTORNODE) {
+ Enumeration<?> children = node.children();
+ Map<Text,RangeBounds> rangeMap = new HashMap<Text,RangeBounds>();
+ while (children.hasMoreElements()) {
+ RewriterTreeNode child = (RewriterTreeNode) children.nextElement();
+ if (child.getType() == ParserTreeConstants.JJTLENODE || child.getType() == ParserTreeConstants.JJTLTNODE) {
+ Text fName = new Text(child.getFieldName());
+ if (rangeMap.containsKey(fName)) {
+ RangeBounds rb = rangeMap.get(fName);
+ if (rb.getLower() != null) {
+ log.error("testBoundedRangeExistence, two lower bounds exist for bounded range.");
+ }
+ rb.setLower(new Text(child.getFieldValue()));
+ } else {
+ RangeBounds rb = new RangeBounds();
+ rb.setLower(new Text(child.getFieldValue()));
+ rangeMap.put(new Text(child.getFieldName()), rb);
+ }
+
+ } else if (child.getType() == ParserTreeConstants.JJTGENODE || child.getType() == ParserTreeConstants.JJTGTNODE) {
+ Text fName = new Text(child.getFieldName());
+ if (rangeMap.containsKey(fName)) {
+ RangeBounds rb = rangeMap.get(fName);
+ if (rb.getUpper() != null) {
+ log.error("testBoundedRangeExistence, two Upper bounds exist for bounded range.");
+ }
+ rb.setUpper(new Text(child.getFieldValue()));
+ } else {
+ RangeBounds rb = new RangeBounds();
+ rb.setUpper(new Text(child.getFieldValue()));
+ rangeMap.put(new Text(child.getFieldName()), rb);
+ }
+ }
+ }
+
+ for (Entry<Text,RangeBounds> entry : rangeMap.entrySet()) {
+ RangeBounds rb = entry.getValue();
+ if (rb.getLower() == null || rb.getUpper() == null) {
+ // unbounded range, remove
+ if (log.isDebugEnabled()) {
+ log.debug("testBoundedRangeExistence: Unbounded Range detected, removing entry from rangeMap");
+ }
+ rangeMap.remove(entry.getKey());
+ }
+ }
+ if (!rangeMap.isEmpty()) {
+ return rangeMap;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * INNER CLASSES
+ */
+ public class RewriterTreeNode extends DefaultMutableTreeNode {
+
+ private static final long serialVersionUID = 1L;
+ private boolean negated = false;
+ private String fieldName;
+ private String fieldValue;
+ private String operator;
+ private int type;
+ private boolean removal = false;
+
/**
- *
- * @param options
+ *
+ * @param type
+ */
+ public RewriterTreeNode(int type) {
+ super();
+ this.type = type;
+ }
+
+ /**
+ *
+ * @param type
+ * @param fName
+ * @param fValue
+ */
+ public RewriterTreeNode(int type, String fName, String fValue) {
+ super();
+ init(type, fName, fValue);
+ }
+
+ /**
+ *
+ * @param type
+ * @param fName
+ * @param fValue
+ * @param negate
+ */
+ public RewriterTreeNode(int type, String fName, String fValue, boolean negate) {
+ super();
+ init(type, fName, fValue, negate);
+ }
+
+ private void init(int type, String fName, String fValue) {
+ init(type, fName, fValue, false);
+ }
+
+ private void init(int type, String fName, String fValue, boolean negate) {
+ this.type = type;
+ this.fieldName = fName;
+ this.fieldValue = fValue;
+ this.negated = negate;
+ this.operator = JexlOperatorConstants.getOperator(type);
+ if (log.isDebugEnabled()) {
+ log.debug("FN: " + this.fieldName + " FV: " + this.fieldValue + " Op: " + this.operator);
+ }
+ }
+
+ /**
+ *
* @return
*/
- public Multimap<String, String> parseIndexedTerms(Map<String, String> options) {
- if (options.get(INDEXED_TERMS_LIST) != null) {
- Multimap<String, String> mmap = HashMultimap.create();
- String[] items = options.get(INDEXED_TERMS_LIST).split(";");
- for (String item : items) {
- item = item.trim();
- if (log.isDebugEnabled()) {
- }
- String[] parts = item.split(":");
- if (log.isDebugEnabled()) {
- log.debug("adding: " + parts[0]);
- }
- for (int i = 2; i < parts.length; i++) {
- //key is original query token, i.e. color:red
- mmap.put(parts[0] + ":" + parts[1], parts[i]);
-
- }
-
- }
- if (log.isDebugEnabled()) {
- log.debug("multimap: " + mmap);
- }
- return mmap;
- }
- if (log.isDebugEnabled()) {
- log.debug("parseIndexedTerms: returning null");
- }
- return null;
+ public String getFieldName() {
+ return fieldName;
}
-
+
/**
- *
- * @param root
+ *
+ * @param fieldName
+ */
+ public void setFieldName(String fieldName) {
+ this.fieldName = fieldName;
+ }
+
+ /**
+ *
* @return
*/
- public RewriterTreeNode refactorTree(RewriterTreeNode root) {
- Enumeration<?> dfe = root.breadthFirstEnumeration();
-
- while (dfe.hasMoreElements()) {
- RewriterTreeNode n = (RewriterTreeNode) dfe.nextElement();
-
- if (n.getType() == ParserTreeConstants.JJTNOTNODE) {//BooleanLogicTreeNode.NodeType.NOT) {
- RewriterTreeNode child = (RewriterTreeNode) n.getChildAt(0);
- child.setNegated(true);
- RewriterTreeNode parent = (RewriterTreeNode) n.getParent();
- parent.remove(n);
- parent.add(child);
- }
- }
-
- //cycle through again and distribute nots
- Enumeration<?> bfe = root.breadthFirstEnumeration();
- RewriterTreeNode child;
-
- while (bfe.hasMoreElements()) {
- child = (RewriterTreeNode) bfe.nextElement();
-
- if (child.isNegated()) {
- if (child.getChildCount() > 0) {
- demorganSubTree(child);
-
- }
- }
- }
- return root;
-
+ public String getFieldValue() {
+ return fieldValue;
}
-
- private void demorganSubTree(RewriterTreeNode root) {
-
- root.setNegated(false);
- //root.setChildrenAllNegated(true);
-
- if (root.getType() == ParserTreeConstants.JJTANDNODE) {//BooleanLogicTreeNode.NodeType.AND) {
- //root.setType(BooleanLogicTreeNode.NodeType.OR);
- root.setType(ParserTreeConstants.JJTORNODE);
- } else if (root.getType() == ParserTreeConstants.JJTORNODE) {//BooleanLogicTreeNode.NodeType.OR) {
- //root.setType(BooleanLogicTreeNode.NodeType.AND);
- root.setType(ParserTreeConstants.JJTANDNODE);
- } else if (root.getType() == ParserTreeConstants.JJTEQNODE || root.getType() == ParserTreeConstants.JJTERNODE) {
- //do nothing
- } else {
- log.error("refactorSubTree, node type not supported");
- }
-
- Enumeration<?> children = root.children();
- RewriterTreeNode child = null;
- // now distribute the negative
-
- while (children.hasMoreElements()) {
- child = (RewriterTreeNode) children.nextElement();
- if (child.isNegated()) {
- child.setNegated(false);
- } else {
- child.setNegated(true);
- }
- }
+
+ /**
+ *
+ * @param fieldValue
+ */
+ public void setFieldValue(String fieldValue) {
+ this.fieldValue = fieldValue;
}
-
- private RewriterTreeNode applyCaseSensitivity(RewriterTreeNode root, boolean fnUpper, boolean fvUpper) {
- // for each leaf, apply case sensitivity
- Enumeration<?> bfe = root.breadthFirstEnumeration();
- while (bfe.hasMoreElements()) {
- RewriterTreeNode node = (RewriterTreeNode) bfe.nextElement();
- if (node.isLeaf()) {
- String fName = fnUpper ? node.getFieldName().toUpperCase() : node.getFieldName().toLowerCase();
- node.setFieldName(fName);
-
- String fValue = fvUpper ? node.getFieldValue().toUpperCase() : node.getFieldValue().toLowerCase();
- node.setFieldValue(fValue);
-
- }
- }
- return root;
+
+ /**
+ *
+ * @return
+ */
+ public boolean isNegated() {
+ return negated;
}
-
- private Map<Text, RangeBounds> getBoundedRangeMap(RewriterTreeNode node) {
-
- boolean upper = false;
- boolean lower = false;
- if (node.getType() == ParserTreeConstants.JJTANDNODE || node.getType() == ParserTreeConstants.JJTORNODE) {
- Enumeration<?> children = node.children();
- Map<Text, RangeBounds> rangeMap = new HashMap<Text, RangeBounds>();
- while (children.hasMoreElements()) {
- RewriterTreeNode child = (RewriterTreeNode) children.nextElement();
- if (child.getType() == ParserTreeConstants.JJTLENODE || child.getType() == ParserTreeConstants.JJTLTNODE) {
- Text fName = new Text(child.getFieldName());
- if (rangeMap.containsKey(fName)) {
- RangeBounds rb = rangeMap.get(fName);
- if (rb.getLower() != null) {
- log.error("testBoundedRangeExistence, two lower bounds exist for bounded range.");
- }
- rb.setLower(new Text(child.getFieldValue()));
- } else {
- RangeBounds rb = new RangeBounds();
- rb.setLower(new Text(child.getFieldValue()));
- rangeMap.put(new Text(child.getFieldName()), rb);
- }
-
- } else if (child.getType() == ParserTreeConstants.JJTGENODE || child.getType() == ParserTreeConstants.JJTGTNODE) {
- Text fName = new Text(child.getFieldName());
- if (rangeMap.containsKey(fName)) {
- RangeBounds rb = rangeMap.get(fName);
- if (rb.getUpper() != null) {
- log.error("testBoundedRangeExistence, two Upper bounds exist for bounded range.");
- }
- rb.setUpper(new Text(child.getFieldValue()));
- } else {
- RangeBounds rb = new RangeBounds();
- rb.setUpper(new Text(child.getFieldValue()));
- rangeMap.put(new Text(child.getFieldName()), rb);
- }
- }
- }
-
- for (Entry<Text, RangeBounds> entry : rangeMap.entrySet()) {
- RangeBounds rb = entry.getValue();
- if (rb.getLower() == null || rb.getUpper() == null) {
- // unbounded range, remove
- if (log.isDebugEnabled()) {
- log.debug("testBoundedRangeExistence: Unbounded Range detected, removing entry from rangeMap");
- }
- rangeMap.remove(entry.getKey());
- }
- }
- if (!rangeMap.isEmpty()) {
- return rangeMap;
- }
- }
-
- return null;
+
+ /**
+ *
+ * @param negated
+ */
+ public void setNegated(boolean negated) {
+ this.negated = negated;
}
-
+
/**
- * INNER CLASSES
+ *
+ * @return
*/
- public class RewriterTreeNode extends DefaultMutableTreeNode {
-
- private static final long serialVersionUID = 1L;
- private boolean negated = false;
- private String fieldName;
- private String fieldValue;
- private String operator;
- private int type;
- private boolean removal = false;
-
- /**
- *
- * @param type
- */
- public RewriterTreeNode(int type) {
- super();
- this.type = type;
- }
-
- /**
- *
- * @param type
- * @param fName
- * @param fValue
- */
- public RewriterTreeNode(int type, String fName, String fValue) {
- super();
- init(type, fName, fValue);
- }
-
- /**
- *
- * @param type
- * @param fName
- * @param fValue
- * @param negate
- */
- public RewriterTreeNode(int type, String fName, String fValue, boolean negate) {
- super();
- init(type, fName, fValue, negate);
- }
-
- private void init(int type, String fName, String fValue) {
- init(type, fName, fValue, false);
- }
-
- private void init(int type, String fName, String fValue, boolean negate) {
- this.type = type;
- this.fieldName = fName;
- this.fieldValue = fValue;
- this.negated = negate;
- this.operator = JexlOperatorConstants.getOperator(type);
- if (log.isDebugEnabled()) {
- log.debug("FN: " + this.fieldName + " FV: " + this.fieldValue + " Op: " + this.operator);
- }
- }
-
- /**
- *
- * @return
- */
- public String getFieldName() {
- return fieldName;
- }
-
- /**
- *
- * @param fieldName
- */
- public void setFieldName(String fieldName) {
- this.fieldName = fieldName;
- }
-
- /**
- *
- * @return
- */
- public String getFieldValue() {
- return fieldValue;
- }
-
- /**
- *
- * @param fieldValue
- */
- public void setFieldValue(String fieldValue) {
- this.fieldValue = fieldValue;
- }
-
- /**
- *
- * @return
- */
- public boolean isNegated() {
- return negated;
- }
-
- /**
- *
- * @param negated
- */
- public void setNegated(boolean negated) {
- this.negated = negated;
- }
-
- /**
- *
- * @return
- */
- public String getOperator() {
- return operator;
- }
-
- /**
- *
- * @param operator
- */
- public void setOperator(String operator) {
- this.operator = operator;
- }
-
- /**
- *
- * @return
- */
- public int getType() {
- return type;
- }
-
- /**
- *
- * @param type
- */
- public void setType(int type) {
- this.type = type;
- }
-
- public boolean isRemoval() {
- return removal;
- }
-
- public void setRemoval(boolean removal) {
- this.removal = removal;
- }
-
- /**
- *
- * @return
- */
- public String getContents() {
- StringBuilder s = new StringBuilder("[");
- s.append(toString());
-
- if (children != null) {
- Enumeration<?> e = this.children();
- while (e.hasMoreElements()) {
- RewriterTreeNode n = (RewriterTreeNode) e.nextElement();
- s.append(",");
- s.append(n.getContents());
- }
- }
- s.append("]");
- return s.toString();
- }
-
- /**
- *
- * @return
- */
- public String printNode() {
- StringBuilder s = new StringBuilder("[");
- s.append("Full Location & Term = ");
- if (this.fieldName != null) {
- s.append(this.fieldName.toString());
- } else {
- s.append("BlankDataLocation");
- }
- s.append(" ");
- if (this.fieldValue != null) {
- s.append(this.fieldValue.toString());
- } else {
- s.append("BlankTerm");
- }
- s.append("]");
- return s.toString();
- }
-
- @Override
- public String toString() {
- switch (type) {
- case ParserTreeConstants.JJTEQNODE:
- return fieldName + ":" + fieldValue + ":negated=" + isNegated();
- case ParserTreeConstants.JJTNENODE:
- return fieldName + ":" + fieldValue + ":negated=" + isNegated();
- case ParserTreeConstants.JJTERNODE:
- return fieldName + ":" + fieldValue + ":negated=" + isNegated();
- case ParserTreeConstants.JJTNRNODE:
- return fieldName + ":" + fieldValue + ":negated=" + isNegated();
- case ParserTreeConstants.JJTLENODE:
- return fieldName + ":" + fieldValue + ":negated=" + isNegated();
- case ParserTreeConstants.JJTLTNODE:
- return fieldName + ":" + fieldValue + ":negated=" + isNegated();
- case ParserTreeConstants.JJTGENODE:
- return fieldName + ":" + fieldValue + ":negated=" + isNegated();
- case ParserTreeConstants.JJTGTNODE:
- return fieldName + ":" + fieldValue + ":negated=" + isNegated();
- case ParserTreeConstants.JJTJEXLSCRIPT:
- return "HEAD";
- case ParserTreeConstants.JJTANDNODE:
- return "AND";
- case ParserTreeConstants.JJTNOTNODE:
- return "NOT";
- case ParserTreeConstants.JJTORNODE:
- return "OR";
- default:
- System.out.println("Problem in NuwaveTreeNode.toString()");
- return null;
- }
- }
+ public String getOperator() {
+ return operator;
+ }
+
+ /**
+ *
+ * @param operator
+ */
+ public void setOperator(String operator) {
+ this.operator = operator;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public int getType() {
+ return type;
+ }
+
+ /**
+ *
+ * @param type
+ */
+ public void setType(int type) {
+ this.type = type;
+ }
+
+ public boolean isRemoval() {
+ return removal;
+ }
+
+ public void setRemoval(boolean removal) {
+ this.removal = removal;
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String getContents() {
+ StringBuilder s = new StringBuilder("[");
+ s.append(toString());
+
+ if (children != null) {
+ Enumeration<?> e = this.children();
+ while (e.hasMoreElements()) {
+ RewriterTreeNode n = (RewriterTreeNode) e.nextElement();
+ s.append(",");
+ s.append(n.getContents());
+ }
+ }
+ s.append("]");
+ return s.toString();
+ }
+
+ /**
+ *
+ * @return
+ */
+ public String printNode() {
+ StringBuilder s = new StringBuilder("[");
+ s.append("Full Location & Term = ");
+ if (this.fieldName != null) {
+ s.append(this.fieldName.toString());
+ } else {
+ s.append("BlankDataLocation");
+ }
+ s.append(" ");
+ if (this.fieldValue != null) {
+ s.append(this.fieldValue.toString());
+ } else {
+ s.append("BlankTerm");
+ }
+ s.append("]");
+ return s.toString();
+ }
+
+ @Override
+ public String toString() {
+ switch (type) {
+ case ParserTreeConstants.JJTEQNODE:
+ return fieldName + ":" + fieldValue + ":negated=" + isNegated();
+ case ParserTreeConstants.JJTNENODE:
+ return fieldName + ":" + fieldValue + ":negated=" + isNegated();
+ case ParserTreeConstants.JJTERNODE:
+ return fieldName + ":" + fieldValue + ":negated=" + isNegated();
+ case ParserTreeConstants.JJTNRNODE:
+ return fieldName + ":" + fieldValue + ":negated=" + isNegated();
+ case ParserTreeConstants.JJTLENODE:
+ return fieldName + ":" + fieldValue + ":negated=" + isNegated();
+ case ParserTreeConstants.JJTLTNODE:
+ return fieldName + ":" + fieldValue + ":negated=" + isNegated();
+ case ParserTreeConstants.JJTGENODE:
+ return fieldName + ":" + fieldValue + ":negated=" + isNegated();
+ case ParserTreeConstants.JJTGTNODE:
+ return fieldName + ":" + fieldValue + ":negated=" + isNegated();
+ case ParserTreeConstants.JJTJEXLSCRIPT:
+ return "HEAD";
+ case ParserTreeConstants.JJTANDNODE:
+ return "AND";
+ case ParserTreeConstants.JJTNOTNODE:
+ return "NOT";
+ case ParserTreeConstants.JJTORNODE:
+ return "OR";
+ default:
+ System.out.println("Problem in NuwaveTreeNode.toString()");
+ return null;
+ }
}
+ }
}