http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/iterators/AndingIterator.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/iterators/AndingIterator.java b/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/iterators/AndingIterator.java new file mode 100644 index 0000000..355fe14 --- /dev/null +++ b/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/iterators/AndingIterator.java @@ -0,0 +1,563 @@ +package mvm.rya.indexing.accumulo.freetext.iterators; + +/* + * 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. + */ + + + +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + +import org.apache.accumulo.core.client.IteratorSetting; +import org.apache.accumulo.core.data.ArrayByteSequence; +import org.apache.accumulo.core.data.ByteSequence; +import org.apache.accumulo.core.data.Key; +import org.apache.accumulo.core.data.PartialKey; +import org.apache.accumulo.core.data.Range; +import org.apache.accumulo.core.data.Value; +import org.apache.accumulo.core.iterators.IteratorEnvironment; +import org.apache.accumulo.core.iterators.SortedKeyValueIterator; +import org.apache.accumulo.core.iterators.user.IntersectingIterator; +import org.apache.accumulo.core.util.TextUtil; +import org.apache.commons.codec.binary.Base64; +import org.apache.hadoop.io.Text; +import org.apache.log4j.Logger; + +/** + * Adapted from {@link IntersectingIterator} with very slight modifications. Specifically, the comparator on the TermSource internal class was + * modified to handle exhausted iterators and multiple rows per tablet server. + */ +public class AndingIterator implements SortedKeyValueIterator<Key, Value> { + + protected Text nullText = new Text(); + + protected Text getPartition(Key key) { + return key.getRow(); + } + + protected Text getTerm(Key key) { + return key.getColumnFamily(); + } + + protected Text getDocID(Key key) { + return key.getColumnQualifier(); + } + + protected Key buildKey(Text partition, Text term) { + return new Key(partition, (term == null) ? nullText : term); + } + + protected Key buildKey(Text partition, Text term, Text docID) { + return new Key(partition, (term == null) ? nullText : term, docID); + } + + protected Key buildFollowingPartitionKey(Key key) { + return key.followingKey(PartialKey.ROW); + } + + protected static final Logger log = Logger.getLogger(AndingIterator.class); + + protected static class TermSource { + public SortedKeyValueIterator<Key, Value> iter; + public Text term; + public Collection<ByteSequence> seekColfams; + public boolean notFlag; + + public TermSource(TermSource other) { + this.iter = other.iter; + this.term = other.term; + this.notFlag = other.notFlag; + this.seekColfams = other.seekColfams; + } + + public TermSource(SortedKeyValueIterator<Key, Value> iter, Text term) { + this(iter, term, false); + } + + public TermSource(SortedKeyValueIterator<Key, Value> iter, Text term, boolean notFlag) { + this.iter = iter; + this.term = term; + this.notFlag = notFlag; + // The desired column families for this source is the term itself + + // handle the case where the term is null. + if (term == null) { + this.seekColfams = Collections.<ByteSequence> emptyList(); + } else { + this.seekColfams = Collections.<ByteSequence> singletonList(new ArrayByteSequence(term.getBytes(), 0, term.getLength())); + } + } + + public String getTermString() { + return (this.term == null) ? new String("Iterator") : this.term.toString(); + } + } + + TermSource[] sources; + int sourcesCount = 0; + + Range overallRange; + + // query-time settings + protected Text currentPartition = null; + protected Text currentDocID = new Text(emptyByteArray); + static final byte[] emptyByteArray = new byte[0]; + + protected Key topKey = null; + protected Value value = new Value(emptyByteArray); + + public AndingIterator() { + } + + @Override + public SortedKeyValueIterator<Key, Value> deepCopy(IteratorEnvironment env) { + return new AndingIterator(this, env); + } + + private AndingIterator(AndingIterator other, IteratorEnvironment env) { + if (other.sources != null) { + sourcesCount = other.sourcesCount; + sources = new TermSource[sourcesCount]; + for (int i = 0; i < sourcesCount; i++) { + sources[i] = new TermSource(other.sources[i].iter.deepCopy(env), other.sources[i].term); + } + } + } + + @Override + public Key getTopKey() { + return topKey; + } + + @Override + public Value getTopValue() { + // we don't really care about values + return value; + } + + @Override + public boolean hasTop() { + return currentPartition != null; + } + + // precondition: currentRow is not null + private boolean seekOneSource(int sourceID) throws IOException { + // find the next key in the appropriate column family that is at or beyond the cursor (currentRow, currentCQ) + // advance the cursor if this source goes beyond it + // return whether we advanced the cursor + + // within this loop progress must be made in one of the following forms: + // - currentRow or currentCQ must be increased + // - the given source must advance its iterator + // this loop will end when any of the following criteria are met + // - the iterator for the given source is pointing to the key (currentRow, columnFamilies[sourceID], currentCQ) + // - the given source is out of data and currentRow is set to null + // - the given source has advanced beyond the endRow and currentRow is set to null + boolean advancedCursor = false; + + if (sources[sourceID].notFlag) { + while (true) { + if (sources[sourceID].iter.hasTop() == false) { + // an empty column that you are negating is a valid condition + break; + } + // check if we're past the end key + int endCompare = -1; + // we should compare the row to the end of the range + if (overallRange.getEndKey() != null) { + endCompare = overallRange.getEndKey().getRow().compareTo(sources[sourceID].iter.getTopKey().getRow()); + if ((!overallRange.isEndKeyInclusive() && endCompare <= 0) || endCompare < 0) { + // an empty column that you are negating is a valid condition + break; + } + } + int partitionCompare = currentPartition.compareTo(getPartition(sources[sourceID].iter.getTopKey())); + // check if this source is already at or beyond currentRow + // if not, then seek to at least the current row + + if (partitionCompare > 0) { + // seek to at least the currentRow + Key seekKey = buildKey(currentPartition, sources[sourceID].term); + sources[sourceID].iter.seek(new Range(seekKey, true, null, false), sources[sourceID].seekColfams, true); + continue; + } + // check if this source has gone beyond currentRow + // if so, this is a valid condition for negation + if (partitionCompare < 0) { + break; + } + // we have verified that the current source is positioned in currentRow + // now we must make sure we're in the right columnFamily in the current row + // Note: Iterators are auto-magically set to the correct columnFamily + if (sources[sourceID].term != null) { + int termCompare = sources[sourceID].term.compareTo(getTerm(sources[sourceID].iter.getTopKey())); + // check if this source is already on the right columnFamily + // if not, then seek forwards to the right columnFamily + if (termCompare > 0) { + Key seekKey = buildKey(currentPartition, sources[sourceID].term, currentDocID); + sources[sourceID].iter.seek(new Range(seekKey, true, null, false), sources[sourceID].seekColfams, true); + continue; + } + // check if this source is beyond the right columnFamily + // if so, then this is a valid condition for negating + if (termCompare < 0) { + break; + } + } + + // we have verified that we are in currentRow and the correct column family + // make sure we are at or beyond columnQualifier + Text docID = getDocID(sources[sourceID].iter.getTopKey()); + int docIDCompare = currentDocID.compareTo(docID); + // If we are past the target, this is a valid result + if (docIDCompare < 0) { + break; + } + // if this source is not yet at the currentCQ then advance in this source + if (docIDCompare > 0) { + // seek forwards + Key seekKey = buildKey(currentPartition, sources[sourceID].term, currentDocID); + sources[sourceID].iter.seek(new Range(seekKey, true, null, false), sources[sourceID].seekColfams, true); + continue; + } + // if we are equal to the target, this is an invalid result. + // Force the entire process to go to the next row. + // We are advancing column 0 because we forced that column to not contain a ! + // when we did the init() + if (docIDCompare == 0) { + sources[0].iter.next(); + advancedCursor = true; + break; + } + } + } else { + while (true) { + if (sources[sourceID].iter.hasTop() == false) { + currentPartition = null; + // setting currentRow to null counts as advancing the cursor + return true; + } + // check if we're past the end key + int endCompare = -1; + // we should compare the row to the end of the range + + if (overallRange.getEndKey() != null) { + endCompare = overallRange.getEndKey().getRow().compareTo(sources[sourceID].iter.getTopKey().getRow()); + if ((!overallRange.isEndKeyInclusive() && endCompare <= 0) || endCompare < 0) { + currentPartition = null; + // setting currentRow to null counts as advancing the cursor + return true; + } + } + int partitionCompare = currentPartition.compareTo(getPartition(sources[sourceID].iter.getTopKey())); + // check if this source is already at or beyond currentRow + // if not, then seek to at least the current row + if (partitionCompare > 0) { + // seek to at least the currentRow + Key seekKey = buildKey(currentPartition, sources[sourceID].term); + sources[sourceID].iter.seek(new Range(seekKey, true, null, false), sources[sourceID].seekColfams, true); + continue; + } + // check if this source has gone beyond currentRow + // if so, advance currentRow + if (partitionCompare < 0) { + currentPartition.set(getPartition(sources[sourceID].iter.getTopKey())); + currentDocID.set(emptyByteArray); + advancedCursor = true; + continue; + } + // we have verified that the current source is positioned in currentRow + // now we must make sure we're in the right columnFamily in the current row + // Note: Iterators are auto-magically set to the correct columnFamily + + if (sources[sourceID].term != null) { + int termCompare = sources[sourceID].term.compareTo(getTerm(sources[sourceID].iter.getTopKey())); + // check if this source is already on the right columnFamily + // if not, then seek forwards to the right columnFamily + if (termCompare > 0) { + Key seekKey = buildKey(currentPartition, sources[sourceID].term, currentDocID); + sources[sourceID].iter.seek(new Range(seekKey, true, null, false), sources[sourceID].seekColfams, true); + continue; + } + // check if this source is beyond the right columnFamily + // if so, then seek to the next row + if (termCompare < 0) { + // we're out of entries in the current row, so seek to the next one + // byte[] currentRowBytes = currentRow.getBytes(); + // byte[] nextRow = new byte[currentRowBytes.length + 1]; + // System.arraycopy(currentRowBytes, 0, nextRow, 0, currentRowBytes.length); + // nextRow[currentRowBytes.length] = (byte)0; + // // we should reuse text objects here + // sources[sourceID].seek(new Key(new Text(nextRow),columnFamilies[sourceID])); + if (endCompare == 0) { + // we're done + currentPartition = null; + // setting currentRow to null counts as advancing the cursor + return true; + } + Key seekKey = buildFollowingPartitionKey(sources[sourceID].iter.getTopKey()); + sources[sourceID].iter.seek(new Range(seekKey, true, null, false), sources[sourceID].seekColfams, true); + continue; + } + } + // we have verified that we are in currentRow and the correct column family + // make sure we are at or beyond columnQualifier + Text docID = getDocID(sources[sourceID].iter.getTopKey()); + int docIDCompare = currentDocID.compareTo(docID); + // if this source has advanced beyond the current column qualifier then advance currentCQ and return true + if (docIDCompare < 0) { + currentDocID.set(docID); + advancedCursor = true; + break; + } + // if this source is not yet at the currentCQ then seek in this source + if (docIDCompare > 0) { + // seek forwards + Key seekKey = buildKey(currentPartition, sources[sourceID].term, currentDocID); + sources[sourceID].iter.seek(new Range(seekKey, true, null, false), sources[sourceID].seekColfams, true); + continue; + } + // this source is at the current row, in its column family, and at currentCQ + break; + } + } + return advancedCursor; + } + + @Override + public void next() throws IOException { + if (currentPartition == null) { + return; + } + // precondition: the current row is set up and the sources all have the same column qualifier + // while we don't have a match, seek in the source with the smallest column qualifier + sources[0].iter.next(); + advanceToIntersection(); + } + + protected void advanceToIntersection() throws IOException { + boolean cursorChanged = true; + while (cursorChanged) { + // seek all of the sources to at least the highest seen column qualifier in the current row + cursorChanged = false; + for (int i = 0; i < sourcesCount; i++) { + if (currentPartition == null) { + topKey = null; + return; + } + if (seekOneSource(i)) { + cursorChanged = true; + break; + } + } + } + topKey = buildKey(currentPartition, nullText, currentDocID); + } + + public static String stringTopKey(SortedKeyValueIterator<Key, Value> iter) { + if (iter.hasTop()) + return iter.getTopKey().toString(); + return ""; + } + + private static final String columnFamiliesOptionName = "columnFamilies"; + private static final String notFlagOptionName = "notFlag"; + + /** + * @param columns + * @return encoded columns + * @deprecated since 1.4. To be made protected. Do not interact with flags string directly, just use + * {@link #setColumnFamilies(IteratorSetting, Text[], boolean[])}. + */ + public static String encodeColumns(Text[] columns) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < columns.length; i++) { + sb.append(new String(Base64.encodeBase64(TextUtil.getBytes(columns[i])))); + sb.append('\n'); + } + return sb.toString(); + } + + /** + * @param flags + * @return encoded flags + * @deprecated since 1.4. To be made protected. Do not interact with flags string directly, just use + * {@link #setColumnFamilies(IteratorSetting, Text[], boolean[])}. + */ + public static String encodeBooleans(boolean[] flags) { + byte[] bytes = new byte[flags.length]; + for (int i = 0; i < flags.length; i++) { + if (flags[i]) + bytes[i] = 1; + else + bytes[i] = 0; + } + return new String(Base64.encodeBase64(bytes)); + } + + protected static Text[] decodeColumns(String columns) { + String[] columnStrings = columns.split("\n"); + Text[] columnTexts = new Text[columnStrings.length]; + for (int i = 0; i < columnStrings.length; i++) { + columnTexts[i] = new Text(Base64.decodeBase64(columnStrings[i].getBytes())); + } + return columnTexts; + } + + /** + * to be made protected + * + * @param flags + * @return decoded flags + * @deprecated since 1.4. To be made protected. Do not interact with flags string directly, just use + * {@link #setColumnFamilies(IteratorSetting, Text[], boolean[])}. + */ + public static boolean[] decodeBooleans(String flags) { + // return null of there were no flags + if (flags == null) + return null; + + byte[] bytes = Base64.decodeBase64(flags.getBytes()); + boolean[] bFlags = new boolean[bytes.length]; + for (int i = 0; i < bytes.length; i++) { + if (bytes[i] == 1) + bFlags[i] = true; + else + bFlags[i] = false; + } + return bFlags; + } + + @Override + public void init(SortedKeyValueIterator<Key, Value> source, Map<String, String> options, IteratorEnvironment env) throws IOException { + Text[] terms = decodeColumns(options.get(columnFamiliesOptionName)); + boolean[] notFlag = decodeBooleans(options.get(notFlagOptionName)); + + if (terms.length < 2) { + throw new IllegalArgumentException("IntersectionIterator requires two or more columns families"); + } + + // Scan the not flags. + // There must be at least one term that isn't negated + // And we are going to re-order such that the first term is not a ! term + if (notFlag == null) { + notFlag = new boolean[terms.length]; + for (int i = 0; i < terms.length; i++) + notFlag[i] = false; + } + if (notFlag[0]) { + for (int i = 1; i < notFlag.length; i++) { + if (notFlag[i] == false) { + Text swapFamily = new Text(terms[0]); + terms[0].set(terms[i]); + terms[i].set(swapFamily); + notFlag[0] = false; + notFlag[i] = true; + break; + } + } + if (notFlag[0]) { + throw new IllegalArgumentException("IntersectionIterator requires at lest one column family without not"); + } + } + + sources = new TermSource[terms.length]; + sources[0] = new TermSource(source, terms[0]); + for (int i = 1; i < terms.length; i++) { + sources[i] = new TermSource(source.deepCopy(env), terms[i], notFlag[i]); + } + sourcesCount = terms.length; + } + + @Override + public void seek(Range range, Collection<ByteSequence> seekColumnFamilies, boolean inclusive) throws IOException { + overallRange = new Range(range); + currentPartition = new Text(); + currentDocID.set(emptyByteArray); + + // seek each of the sources to the right column family within the row given by key + for (int i = 0; i < sourcesCount; i++) { + Key sourceKey; + if (range.getStartKey() != null) { + if (range.getStartKey().getColumnQualifier() != null) { + sourceKey = buildKey(getPartition(range.getStartKey()), sources[i].term, range.getStartKey().getColumnQualifier()); + } else { + sourceKey = buildKey(getPartition(range.getStartKey()), sources[i].term); + } + // Seek only to the term for this source as a column family + sources[i].iter.seek(new Range(sourceKey, true, null, false), sources[i].seekColfams, true); + } else { + // Seek only to the term for this source as a column family + sources[i].iter.seek(range, sources[i].seekColfams, true); + } + } + advanceToIntersection(); + } + + public void addSource(SortedKeyValueIterator<Key, Value> source, IteratorEnvironment env, Text term, boolean notFlag) { + // Check if we have space for the added Source + if (sources == null) { + sources = new TermSource[1]; + } else { + // allocate space for node, and copy current tree. + // TODO: Should we change this to an ArrayList so that we can just add() ? + TermSource[] localSources = new TermSource[sources.length + 1]; + int currSource = 0; + for (TermSource myTerm : sources) { + // TODO: Do I need to call new here? or can I just re-use the term? + localSources[currSource] = new TermSource(myTerm); + currSource++; + } + sources = localSources; + } + sources[sourcesCount] = new TermSource(source.deepCopy(env), term, notFlag); + sourcesCount++; + } + + /** + * Encode the columns to be used when iterating. + * + * @param cfg + * @param columns + */ + public static void setColumnFamilies(IteratorSetting cfg, Text[] columns) { + if (columns.length < 2) + throw new IllegalArgumentException("Must supply at least two terms to intersect"); + cfg.addOption(AndingIterator.columnFamiliesOptionName, AndingIterator.encodeColumns(columns)); + } + + /** + * Encode columns and NOT flags indicating which columns should be negated (docIDs will be excluded if matching negated columns, instead + * of included). + * + * @param cfg + * @param columns + * @param notFlags + */ + public static void setColumnFamilies(IteratorSetting cfg, Text[] columns, boolean[] notFlags) { + if (columns.length < 2) + throw new IllegalArgumentException("Must supply at least two terms to intersect"); + if (columns.length != notFlags.length) + throw new IllegalArgumentException("columns and notFlags arrays must be the same length"); + setColumnFamilies(cfg, columns); + cfg.addOption(AndingIterator.notFlagOptionName, AndingIterator.encodeBooleans(notFlags)); + } +}
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/iterators/BooleanTreeIterator.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/iterators/BooleanTreeIterator.java b/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/iterators/BooleanTreeIterator.java new file mode 100644 index 0000000..a69b78a --- /dev/null +++ b/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/iterators/BooleanTreeIterator.java @@ -0,0 +1,322 @@ +package mvm.rya.indexing.accumulo.freetext.iterators; + +/* + * 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. + */ + + + +import static mvm.rya.indexing.accumulo.freetext.query.ASTNodeUtils.allChildrenAreNot; +import static mvm.rya.indexing.accumulo.freetext.query.ASTNodeUtils.findFirstNonNotChild; +import static mvm.rya.indexing.accumulo.freetext.query.ASTNodeUtils.getNodeIterator; +import static mvm.rya.indexing.accumulo.freetext.query.ASTNodeUtils.isNotFlag; +import static mvm.rya.indexing.accumulo.freetext.query.ASTNodeUtils.pushChild; +import static mvm.rya.indexing.accumulo.freetext.query.ASTNodeUtils.swapChildren; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +import mvm.rya.indexing.accumulo.freetext.ColumnPrefixes; +import mvm.rya.indexing.accumulo.freetext.query.ASTExpression; +import mvm.rya.indexing.accumulo.freetext.query.ASTTerm; +import mvm.rya.indexing.accumulo.freetext.query.ParseException; +import mvm.rya.indexing.accumulo.freetext.query.QueryParser; +import mvm.rya.indexing.accumulo.freetext.query.QueryParserTreeConstants; +import mvm.rya.indexing.accumulo.freetext.query.SimpleNode; +import mvm.rya.indexing.accumulo.freetext.query.TokenMgrError; + +import org.apache.accumulo.core.client.IteratorSetting; +import org.apache.accumulo.core.data.ByteSequence; +import org.apache.accumulo.core.data.Key; +import org.apache.accumulo.core.data.Range; +import org.apache.accumulo.core.data.Value; +import org.apache.accumulo.core.iterators.IteratorEnvironment; +import org.apache.accumulo.core.iterators.OptionDescriber; +import org.apache.accumulo.core.iterators.SortedKeyValueIterator; +import org.apache.accumulo.core.iterators.system.MultiIterator; +import org.apache.commons.lang.Validate; +import org.apache.hadoop.io.Text; +import org.apache.log4j.Logger; + +public class BooleanTreeIterator implements SortedKeyValueIterator<Key, Value>, OptionDescriber { + private static Logger logger = Logger.getLogger(BooleanTreeIterator.class); + + private static String queryOptionName = "query"; + + private SortedKeyValueIterator<Key, Value> iter; + private SortedKeyValueIterator<Key, Value> docSource; + + @Override + public void init(SortedKeyValueIterator<Key, Value> source, Map<String, String> options, IteratorEnvironment env) throws IOException { + + // pull out the query + String query = options.get(queryOptionName); + + // create the parse tree + SimpleNode root; + try { + root = QueryParser.parse(query); + } catch (ParseException e) { + // log and wrap in IOException + logger.error("ParseException encountered while parsing: " + query, e); + throw new IOException(e); + } catch (TokenMgrError e) { + // log and wrap in IOException + logger.error("TokenMgrError encountered while parsing: " + query, e); + throw new IOException(e); + } + + docSource = source.deepCopy(env); + iter = createIterator((SimpleNode) root.jjtGetChild(0), source, env); + } + + private SortedKeyValueIterator<Key, Value> createIterator(SimpleNode root, SortedKeyValueIterator<Key, Value> source, + IteratorEnvironment env) { + // if the root is only a single term, wrap it in an expression node + if (root instanceof ASTTerm) { + ASTExpression expression = new ASTExpression(QueryParserTreeConstants.JJTEXPRESSION); + expression.setNotFlag(false); + expression.setType(ASTExpression.AND); + + pushChild(expression, root); + root.jjtSetParent(expression); + + root = expression; + } + + // Pre-process the tree to compensate for iterator specific issues with certain topologies + preProcessTree(root); + + // Build an iterator tree + return createIteratorRecursive(root, source, env); + } + + private SortedKeyValueIterator<Key, Value> createIteratorRecursive(SimpleNode node, SortedKeyValueIterator<Key, Value> source, + IteratorEnvironment env) { + + Validate.isTrue(node instanceof ASTExpression, "node must be of type ASTExpression. Node is instance of " + + node.getClass().getName()); + + ASTExpression expression = (ASTExpression) node; + + if (expression.getType().equals(ASTExpression.AND)) { + return getAndIterator(node, source, env); + } + + if (expression.getType().equals(ASTExpression.OR)) { + return getOrIterator(node, source, env); + } + + throw new IllegalArgumentException("Expression is of unknown type: " + expression.getType()); + + } + + private MultiIterator getOrIterator(SimpleNode node, SortedKeyValueIterator<Key, Value> source, IteratorEnvironment env) { + List<SortedKeyValueIterator<Key, Value>> iters = new ArrayList<SortedKeyValueIterator<Key, Value>>(); + + for (SimpleNode n : getNodeIterator(node)) { + if (n instanceof ASTExpression) { + iters.add(createIteratorRecursive(n, source, env)); + } else if (n instanceof ASTTerm) { + iters.add(getSimpleAndingIterator((ASTTerm) n, source, env)); + } else { + throw new IllegalArgumentException("Node is of unknown type: " + n.getClass().getName()); + } + } + + return new MultiIterator(iters, new Range()); + } + + private AndingIterator getAndIterator(SimpleNode node, SortedKeyValueIterator<Key, Value> source, IteratorEnvironment env) { + + AndingIterator anding = new AndingIterator(); + + for (SimpleNode n : getNodeIterator(node)) { + boolean isNotFlag = isNotFlag(n); + if (n instanceof ASTExpression) { + anding.addSource(createIteratorRecursive(n, source, env), env, null, isNotFlag); + } else if (n instanceof ASTTerm) { + ASTTerm term = ((ASTTerm) n); + anding.addSource(source, env, getTermColFam(term), isNotFlag); + } else { + throw new IllegalArgumentException("Node is of unknown type: " + n.getClass().getName()); + } + } + + return anding; + } + + private static Text getTermColFam(ASTTerm termnode) { + String term = termnode.getTerm(); + if (term == null) { + // if the term is null, then I want all of the documents + return ColumnPrefixes.DOCS_CF_PREFIX; + } + if (term.contains("\0")) { + // if the term is contain a null char, then it's already formated for a CF + return new Text(term); + } + + // otherwise, point to the term CF + return ColumnPrefixes.getTermColFam(term.toLowerCase()); + } + + private AndingIterator getSimpleAndingIterator(ASTTerm node, SortedKeyValueIterator<Key, Value> source, IteratorEnvironment env) { + Validate.isTrue(!node.isNotFlag(), "Simple Anding node must not have \"not\" flag set"); + + AndingIterator anding = new AndingIterator(); + anding.addSource(source, env, getTermColFam(node), false); + return anding; + } + + /** + * Handle "lonely nots" (i.e. expressions with only nots), "or" statements containing nots, and make sure that the first term in an + * "and" statement is not a not. This is due to implementation specific limitations of the iterators. + * <p> + * For example: + * <ul> + * <li>lonely nots: (!a & !b) -> [all] & !a & !b</li> + * <li>"or" nots: (!a | b) -> ( ([all] & !a) | b)</li> + * <li>reorder "and" nots: (!a & b) -> ( b & !a )</li> + * </ul> + **/ + public static void preProcessTree(SimpleNode s) { + for (SimpleNode child : getNodeIterator(s)) { + preProcessTree(child); + } + + if (s instanceof ASTExpression) { + ASTExpression expression = (ASTExpression) s; + + if (expression.getType().equals(ASTExpression.AND)) { + if (allChildrenAreNot(expression)) { + // lonely nots: (!a & !b) -> [all] & !a & !b + ASTTerm allDocsTerm = createAllDocTermNode(); + pushChild(expression, allDocsTerm); + } else if (isNotFlag(expression.jjtGetChild(0))) { + // reorder "and" nots: (!a & b) -> ( b & !a ) + int firstNonNotChild = findFirstNonNotChild(expression); + swapChildren(expression, 0, firstNonNotChild); + } + } + + if (expression.getType().equals(ASTExpression.OR)) { + for (int i = 0; i < expression.jjtGetNumChildren(); i++) { + SimpleNode child = (SimpleNode) expression.jjtGetChild(i); + if (isNotFlag(child)) { + // "or" nots: (!a | b) -> ( ([all] & !a) | b) + // create the new expression + ASTExpression newExpression = new ASTExpression(QueryParserTreeConstants.JJTEXPRESSION); + newExpression.setNotFlag(false); + newExpression.setType(ASTExpression.AND); + pushChild(newExpression, child); + pushChild(newExpression, createAllDocTermNode()); + + // tie the new expression to the old one + newExpression.jjtSetParent(expression); + expression.jjtAddChild(newExpression, i); + } + } + } + } + + } + + public static ASTTerm createAllDocTermNode() { + ASTTerm t = new ASTTerm(QueryParserTreeConstants.JJTTERM); + t.setNotFlag(false); + t.setType(ASTTerm.TERM); + // note: a "null" signifies "all docs" should be returned. + t.setTerm(null); + return t; + } + + @Override + public boolean hasTop() { + return iter.hasTop(); + } + + @Override + public void next() throws IOException { + iter.next(); + if (iter.hasTop()) { + seekDocSource(iter.getTopKey()); + } + } + + @Override + public void seek(Range range, Collection<ByteSequence> columnFamilies, boolean inclusive) throws IOException { + iter.seek(range, columnFamilies, inclusive); + if (iter.hasTop()) { + seekDocSource(iter.getTopKey()); + } + } + + private void seekDocSource(Key key) throws IOException { + Key docKey = new Key(key.getRow(), ColumnPrefixes.DOCS_CF_PREFIX, key.getColumnQualifier()); + docSource.seek(new Range(docKey, true, null, false), Collections.<ByteSequence> emptyList(), false); + } + + @Override + public Key getTopKey() { + // from intersecting iterator: + // RowID: shardID + // CF: (empty) + // CQ: docID + return iter.getTopKey(); + } + + @Override + public Value getTopValue() { + if (!iter.hasTop()) { + throw new NoSuchElementException(); + } + + return docSource.getTopValue(); + } + + @Override + public SortedKeyValueIterator<Key, Value> deepCopy(IteratorEnvironment env) { + throw new UnsupportedOperationException(); + } + + public static void setQuery(IteratorSetting cfg, String query) { + cfg.addOption(BooleanTreeIterator.queryOptionName, query); + } + + @Override + public IteratorOptions describeOptions() { + return new IteratorOptions("FreeTextBooleanTree", "Perform a FreeText Query on properly formated table", + Collections.singletonMap(queryOptionName, "the free text query"), + null); + } + + @Override + public boolean validateOptions(Map<String, String> options) { + String q = options.get(queryOptionName); + if (q == null || q.isEmpty()) + throw new IllegalArgumentException(queryOptionName + " must not be empty"); + return true; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTExpression.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTExpression.java b/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTExpression.java new file mode 100644 index 0000000..95783e5 --- /dev/null +++ b/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTExpression.java @@ -0,0 +1,63 @@ +package mvm.rya.indexing.accumulo.freetext.query; + +/* + * 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. + */ + + + +/** + * This is a slightly modified version of the ASTExpression file created by JavaCC. This version adds more state to the standard ASTTerm + * file including a "type", and "notFlag". + */ +public class ASTExpression extends SimpleNode { + public static final String AND = "AND"; + public static final String OR = "OR"; + + private String type = ""; + private boolean notFlag = false; + + public ASTExpression(int id) { + super(id); + } + + public ASTExpression(QueryParser p, int id) { + super(p, id); + } + + public void setType(String type) { + this.type = type; + } + + public String getType() { + return type; + } + + public boolean isNotFlag() { + return notFlag; + } + + public void setNotFlag(boolean notFlag) { + this.notFlag = notFlag; + } + + @Override + public String toString() { + return super.toString() + " [type: " + type + ", notFlag: " + notFlag + "]"; + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTNodeUtils.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTNodeUtils.java b/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTNodeUtils.java new file mode 100644 index 0000000..27edaac --- /dev/null +++ b/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTNodeUtils.java @@ -0,0 +1,210 @@ +package mvm.rya.indexing.accumulo.freetext.query; + +/* + * 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. + */ + + + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; + +public class ASTNodeUtils { + + /** + * Serialize a node (and it's children) to a parsable string. + * + * @param s + * @return + */ + public static String serializeExpression(Node s) { + if (s instanceof ASTTerm) { + ASTTerm a = (ASTTerm) s; + return (a.isNotFlag() ? "!" : "") + " " + a.getTerm(); + } + + String prefix = ""; + String suffix = ""; + String join = " "; + if (s instanceof ASTExpression) { + ASTExpression a = (ASTExpression) s; + prefix = (a.isNotFlag() ? "!" : "") + "("; + suffix = ")"; + join = " " + a.getType() + " "; + } + + List<String> children = new ArrayList<String>(); + for (int i = 0; i < s.jjtGetNumChildren(); i++) { + children.add(serializeExpression(s.jjtGetChild(i))); + } + return prefix + StringUtils.join(children, join) + suffix; + + } + + /** + * count the number of terms in this query tree. + * + * @param node + * @return + */ + public static int termCount(Node node) { + if (node instanceof SimpleNode) { + int count = 0; + for (SimpleNode n : getNodeIterator((SimpleNode) node)) { + count += termCount(n); + } + return count; + } else if (node instanceof ASTTerm) { + return 1; + } else { + throw new IllegalArgumentException("Node is of unknown type: " + node.getClass().getName()); + } + } + + /** + * Add the child as the parent's first child. + * + * @param parent + * @param child + */ + public static void pushChild(SimpleNode parent, SimpleNode child) { + // note: this implementation is very coupled with the SimpleNode jjt implementation + int parentSize = parent.jjtGetNumChildren(); + + // expand the parent node + parent.jjtAddChild(null, parentSize); + + // get the current head child + Node currentHeadChild = parent.jjtGetChild(0); + + // set the parameter as the parent's first child + parent.jjtAddChild(child, 0); + + // add the former head child to the end of the list + if (currentHeadChild != null) { + parent.jjtAddChild(currentHeadChild, parentSize); + } + + // tie the child to the parent + child.jjtSetParent(parent); + + } + + /** + * Get the index of the child, -1 if child not found. + * + * @param parent + * @param child + */ + public static int getChildIndex(SimpleNode parent, SimpleNode child) { + int parentSize = parent.jjtGetNumChildren(); + + for (int i = 0; i < parentSize; i++) { + if (child.equals(parent.jjtGetChild(i))) { + return i; + } + } + + return -1; + } + + /** + * return true is all of the node's children have the not flag enabled. + * + * @param node + * @return + */ + public static boolean allChildrenAreNot(ASTExpression node) { + for (SimpleNode child : getNodeIterator(node)) { + if (!isNotFlag(child)) { + return false; + } + } + return true; + } + + /** + * return the node's not flag value. node must be of type {@link ASTTerm} or {@link ASTExpression} + * + * @param node + * @return + */ + public static boolean isNotFlag(Node node) { + if (node instanceof ASTExpression) { + return ((ASTExpression) node).isNotFlag(); + } else if (node instanceof ASTTerm) { + return ((ASTTerm) node).isNotFlag(); + } else { + throw new IllegalArgumentException("Node is of unknown type: " + node.getClass().getName()); + } + } + + public static Iterable<SimpleNode> getNodeIterator(final SimpleNode n) { + return new Iterable<SimpleNode>() { + + @Override + public Iterator<SimpleNode> iterator() { + return new Iterator<SimpleNode>() { + int pointer = 0; + + @Override + public boolean hasNext() { + return pointer < n.jjtGetNumChildren(); + } + + @Override + public SimpleNode next() { + Node rtn = n.jjtGetChild(pointer); + pointer++; + return (SimpleNode) rtn; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + }; + } + + public static void swapChildren(ASTExpression parent, int childOneIndex, int childTwoIndex) { + Validate.isTrue(childOneIndex > -1 && childOneIndex < parent.jjtGetNumChildren()); + Validate.isTrue(childTwoIndex > -1 && childTwoIndex < parent.jjtGetNumChildren()); + + Node childOne = parent.jjtGetChild(childOneIndex); + Node childTwo = parent.jjtGetChild(childTwoIndex); + parent.jjtAddChild(childOne, childTwoIndex); + parent.jjtAddChild(childTwo, childOneIndex); + } + + public static int findFirstNonNotChild(ASTExpression expression) { + for (int i = 0; i < expression.jjtGetNumChildren(); i++) { + if (!isNotFlag(expression.jjtGetChild(i))) { + return i; + } + } + return -1; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTSimpleNode.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTSimpleNode.java b/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTSimpleNode.java new file mode 100644 index 0000000..71ff16a --- /dev/null +++ b/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTSimpleNode.java @@ -0,0 +1,917 @@ +/* Generated By:JJTree: Do not edit this line. ASTSimpleNode.java Version 4.3 */ +/* JavaCCOptions:MULTI=true,NODE_USES_PARSER=false,VISITOR=false,TRACK_TOKENS=false,NODE_PREFIX=AST,NODE_EXTENDS=,NODE_FACTORY=,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */ +package mvm.rya.indexing.accumulo.freetext.query; + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + +/* + * 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. + */ + + + +public +class ASTSimpleNode extends SimpleNode { + public ASTSimpleNode(int id) { + super(id); + } + + public ASTSimpleNode(QueryParser p, int id) { + super(p, id); + } + +} +/* JavaCC - OriginalChecksum=8a57fc385ee56c7039cbbc4132eb8e0c (do not edit this line) */ http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/44a2dcf0/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTTerm.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTTerm.java b/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTTerm.java new file mode 100644 index 0000000..6232096 --- /dev/null +++ b/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/freetext/query/ASTTerm.java @@ -0,0 +1,79 @@ +package mvm.rya.indexing.accumulo.freetext.query; + +/* + * 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. + */ + + + +/** + * This is a slightly modified version of the ASTTerm file created by JavaCC. This version adds more state to the standard ASTTerm file + * including a "term", "type", and "notFlag". + */ +public class ASTTerm extends SimpleNode { + public static final String WILDTERM = "WILDTERM"; + public static final String PREFIXTERM = "PREFIXTERM"; + public static final String QUOTED = "QUOTED"; + public static final String TERM = "TERM"; + + private String term = ""; + private boolean notFlag = false; + private String type = ""; + + public ASTTerm(int id) { + super(id); + } + + public ASTTerm(QueryParser p, int id) { + super(p, id); + } + + @Override + public String toString() { + return super.toString() + "[notFlag: " + notFlag + " term: " + term + " type: " + type + "]"; + } + + @Override + public String toString(String prefix) { + return super.toString(prefix); + } + + public String getTerm() { + return term; + } + + public void setTerm(String term) { + this.term = term; + } + + public boolean isNotFlag() { + return notFlag; + } + + public void setNotFlag(boolean notFlag) { + this.notFlag = notFlag; + } + + public void setType(String type) { + this.type = type; + } + + public String getType() { + return type; + } +}
