You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rya.apache.org by mi...@apache.org on 2016/10/15 20:06:24 UTC
[04/69] [abbrv] [partial] incubator-rya git commit: RYA-198 Renaming
Files
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;
+ }
+}