Commit 44ad89714dabe8e1178baf9092ec4a3060a20c33

Authored by Matthijs Brouwer
1 parent 26a9542a

bugfixes, upgrade, fullyalignedwith

Showing 36 changed files with 2008 additions and 946 deletions

Too many changes to show.

To preserve performance only 28 of 36 files are displayed.

docker/Dockerfile
1 1 # Automatically generated Dockerfile
2   -# - Build 2017-03-09 09:09
  2 +# - Build 2017-03-09 09:11
3 3 # - Lucene/Solr version 6.4.2
4 4 # - Mtas release 20170309
5 5 #
... ... @@ -55,7 +55,7 @@ RUN apt-get update && apt-get install -y lsof software-properties-common python-
55 55 && chmod -R 755 /var/www/html \
56 56 && printf "echo\n" >> /start.sh \
57 57 && printf "echo \"================ Mtas -- Multi Tier Annotation Search =================\"\n" >> /start.sh \
58   -&& printf "echo \" Timestamp 2017-03-09 09:09\"\n" >> /start.sh \
  58 +&& printf "echo \" Timestamp 2017-03-09 09:11\"\n" >> /start.sh \
59 59 && printf "echo \" Lucene/Solr version 6.4.2\"\n" >> /start.sh \
60 60 && printf "echo \" Mtas release 20170309\"\n" >> /start.sh \
61 61 && printf "echo \" See https://meertensinstituut.github.io/mtas/ for more information\"\n" >> /start.sh \
... ...
src/mtas/codec/util/CodecCollector.java
... ... @@ -800,7 +800,8 @@ public class CodecCollector {
800 800 for (GroupHit hit : occurences) {
801 801 MtasSpanQuery queryHit = createQueryFromGroupHit(prefixes, field, hit);
802 802 if (queryHit != null) {
803   - SpanWeight weight = (SpanWeight) queryHit.rewrite(reader)
  803 + MtasSpanQuery queryHitRewritten = queryHit.rewrite(reader);
  804 + SpanWeight weight = (SpanWeight) queryHitRewritten
804 805 .createWeight(searcher, false);
805 806 Spans spans = weight.getSpans(lrc, SpanWeight.Postings.POSITIONS);
806 807 if (spans != null) {
... ... @@ -1480,7 +1481,6 @@ public class CodecCollector {
1480 1481 if (mtasCodecInfo != null && groupList != null) {
1481 1482 ArrayList<Match> matchList;
1482 1483 HashMap<Integer, ArrayList<Match>> matchData;
1483   - long time = System.nanoTime();
1484 1484 for (ComponentGroup group : groupList) {
1485 1485 group.dataCollector.setWithTotal();
1486 1486 if (group.prefixes.size() > 0) {
... ... @@ -1635,7 +1635,7 @@ public class CodecCollector {
1635 1635 .ceil(boundaryMinimumNumberOfDocuments * 1.2);
1636 1636 boundaryMaximumNumberOfDocuments = (int) Math
1637 1637 .ceil(boundaryMaximumNumberOfDocuments * 1.2);
1638   - }
  1638 + }
1639 1639 }
1640 1640 }
1641 1641 }
... ... @@ -1645,7 +1645,7 @@ public class CodecCollector {
1645 1645 group.dataCollector.add(hit.toString(), occurencesSum.get(hit),
1646 1646 occurencesN.get(hit));
1647 1647 }
1648   - group.dataCollector.closeNewList();
  1648 + group.dataCollector.closeNewList();
1649 1649 }
1650 1650 }
1651 1651 }
... ... @@ -1762,8 +1762,7 @@ public class CodecCollector {
1762 1762 HashMap<GroupHit, Integer> occurencesN) throws IOException {
1763 1763 int total = 0;
1764 1764 if (docCounter + 1 < docSet.size()) {
1765   - // analyze matches for future documents with spans from
1766   - // previous
  1765 + // initialize
1767 1766 int nextDocCounter = docCounter + 1;
1768 1767 long[] subSum = new long[list.size()];
1769 1768 int[] subN = new int[list.size()];
... ... @@ -1776,6 +1775,7 @@ public class CodecCollector {
1776 1775 Spans[] spansList = new Spans[list.size()];
1777 1776 boolean[] finishedSpansList = new boolean[list.size()];
1778 1777 newNextDoc = true;
  1778 + // advance spans, find nextDoc
1779 1779 for (int i = 0; i < hitList.length; i++) {
1780 1780 newNextDocs[i] = true;
1781 1781 spansList[i] = list.get(hitList[i]);
... ... @@ -1791,19 +1791,22 @@ public class CodecCollector {
1791 1791 && docSet.get(nextDocCounter) < (nextDoc + docBase)) {
1792 1792 nextDocCounter++;
1793 1793 }
  1794 + // finish, if no more docs in set
1794 1795 if (nextDocCounter >= docSet.size()) {
1795 1796 break;
1796 1797 }
1797   - // matches found
  1798 + // go to the matches
1798 1799 if (docSet.get(nextDocCounter) == nextDoc + docBase) {
1799 1800 matchList = matchData.get(nextDoc + docBase);
1800 1801 if (matchList != null && matchList.size() > 0) {
  1802 + // initialize
1801 1803 int currentMatchPosition = 0;
1802 1804 int lastMatchStartPosition = matchList
1803 1805 .get(matchList.size() - 1).startPosition;
1804 1806 ArrayList<Match> newMatchList = new ArrayList<Match>(
1805 1807 matchList.size());
1806 1808 int currentSpanPosition = Spans.NO_MORE_POSITIONS;
  1809 + // check and initialize for each span
1807 1810 for (int i = 0; i < spansList.length; i++) {
1808 1811 if (spansList[i].docID() == nextDoc) {
1809 1812 int tmpStartPosition = spansList[i].nextStartPosition();
... ... @@ -1812,6 +1815,7 @@ public class CodecCollector {
1812 1815 } else {
1813 1816 finishedSpansList[i] = true;
1814 1817 }
  1818 + // compute position
1815 1819 currentSpanPosition = (currentSpanPosition == Spans.NO_MORE_POSITIONS)
1816 1820 ? tmpStartPosition
1817 1821 : Math.min(currentSpanPosition, tmpStartPosition);
... ... @@ -1819,19 +1823,22 @@ public class CodecCollector {
1819 1823 finishedSpansList[i] = true;
1820 1824 }
1821 1825 }
  1826 + // loop over matches
1822 1827 while (currentMatchPosition < matchList.size()
1823 1828 && currentSpanPosition < Spans.NO_MORE_POSITIONS) {
  1829 +
1824 1830 if (currentSpanPosition < matchList
1825 1831 .get(currentMatchPosition).startPosition) {
1826   - // do nothing
  1832 + // do nothing, match not reached
1827 1833 } else if (currentSpanPosition > lastMatchStartPosition) {
1828   - // finish
  1834 + // finish, past last match
1829 1835 break;
1830 1836 } else {
1831 1837 // advance matches
1832 1838 while (currentMatchPosition < matchList.size()
1833 1839 && currentSpanPosition > matchList
1834 1840 .get(currentMatchPosition).startPosition) {
  1841 + // store current match, not relevant
1835 1842 newMatchList.add(matchList.get(currentMatchPosition));
1836 1843 currentMatchPosition++;
1837 1844 }
... ... @@ -1839,24 +1846,15 @@ public class CodecCollector {
1839 1846 while (currentMatchPosition < matchList.size()
1840 1847 && currentSpanPosition == matchList
1841 1848 .get(currentMatchPosition).startPosition) {
  1849 + // check for each span
1842 1850 for (int i = 0; i < spansList.length; i++) {
  1851 + // equal start and end, therefore match
1843 1852 if (!finishedSpansList[i] && spansList[i].docID() == nextDoc
1844 1853 && spansList[i].startPosition() == matchList
1845 1854 .get(currentMatchPosition).startPosition
1846 1855 && spansList[i].endPosition() == matchList
1847 1856 .get(currentMatchPosition).endPosition) {
1848   - // StringBuilder newKey = new StringBuilder("");
1849   - // GroupHit.keyToObject(hitList[i].toString(), newKey);
1850   - // System.out
1851   - // .println("FOUND " + newKey + " - doc "
1852   - // + (nextDoc + docBase) + " ["
1853   - // + spansList[i].startPosition() + ","
1854   - // + spansList[i].endPosition() + "] == ["
1855   - // + matchList
1856   - // .get(currentMatchPosition).startPosition
1857   - // + ","
1858   - // + matchList.get(currentMatchPosition).endPosition
1859   - // + "]");
  1857 + // administration
1860 1858 total++;
1861 1859 subSum[i]++;
1862 1860 if (newNextDocs[i]) {
... ... @@ -1868,36 +1866,26 @@ public class CodecCollector {
1868 1866 && spansList[i].docID() == nextDoc
1869 1867 && spansList[i].startPosition() == matchList
1870 1868 .get(currentMatchPosition).startPosition) {
1871   - // System.out
1872   - // .println("NOT FOUND " + hitList[i] + " - doc "
1873   - // + (nextDoc + docBase) + " ["
1874   - // + spansList[i].startPosition() + ","
1875   - // + spansList[i].endPosition() + "] ipv ["
1876   - // + matchList
1877   - // .get(currentMatchPosition).startPosition
1878   - // + ","
1879   - // + matchList.get(currentMatchPosition).endPosition
1880   - // + "]");
  1869 + // no match, store
  1870 + newMatchList.add(matchList.get(currentMatchPosition));
1881 1871 }
1882 1872 }
1883 1873 currentMatchPosition++;
1884 1874 }
1885 1875 }
  1876 +
1886 1877 // advance spans
1887 1878 if (currentMatchPosition < matchList.size()) {
1888 1879 currentSpanPosition = Spans.NO_MORE_POSITIONS;
1889 1880 for (int i = 0; i < spansList.length; i++) {
1890   - if (spansList[i].docID() == nextDoc) {
1891   - if (!finishedSpansList[i]
  1881 + if (!finishedSpansList[i]
  1882 + && (spansList[i].docID() == nextDoc)) {
  1883 + while (!finishedSpansList[i]
1892 1884 && spansList[i].startPosition() < matchList
1893 1885 .get(currentMatchPosition).startPosition) {
1894   - while (!finishedSpansList[i]
1895   - && spansList[i].startPosition() < matchList
1896   - .get(currentMatchPosition).startPosition) {
1897   - int tmpStartPosition = spansList[i].nextStartPosition();
1898   - if (tmpStartPosition == Spans.NO_MORE_POSITIONS) {
1899   - finishedSpansList[i] = true;
1900   - }
  1886 + int tmpStartPosition = spansList[i].nextStartPosition();
  1887 + if (tmpStartPosition == Spans.NO_MORE_POSITIONS) {
  1888 + finishedSpansList[i] = true;
1901 1889 }
1902 1890 }
1903 1891 if (!finishedSpansList[i]) {
... ... @@ -1913,14 +1901,16 @@ public class CodecCollector {
1913 1901 }
1914 1902 }
1915 1903 if (!newNextDoc) {
  1904 + // add other matches
1916 1905 while (currentMatchPosition < matchList.size()) {
1917 1906 newMatchList.add(matchList.get(currentMatchPosition));
1918 1907 currentMatchPosition++;
1919 1908 }
  1909 + // update administration
1920 1910 if (newMatchList.size() > 0) {
1921 1911 matchData.put(nextDoc + docBase, newMatchList);
1922 1912 } else {
1923   - matchData.remove(nextDoc + docBase);
  1913 + matchData.put(nextDoc + docBase, null);
1924 1914 }
1925 1915 }
1926 1916 }
... ... @@ -1934,6 +1924,7 @@ public class CodecCollector {
1934 1924 // advance spans
1935 1925 if (nextDocCounter < docSet.size()) {
1936 1926 nextDoc = Spans.NO_MORE_DOCS;
  1927 + // advance spans
1937 1928 for (int i = 0; i < hitList.length; i++) {
1938 1929 if (spansNextDoc[i] < (docSet.get(nextDocCounter) - docBase)) {
1939 1930 spansNextDoc[i] = spansList[i]
... ... @@ -1960,6 +1951,7 @@ public class CodecCollector {
1960 1951 return total;
1961 1952 }
1962 1953  
  1954 +
1963 1955 /**
1964 1956 * Sort match list.
1965 1957 *
... ... @@ -2935,7 +2927,7 @@ public class CodecCollector {
2935 2927 double valueFunction = function.parserFunction
2936 2928 .getValueDouble(numberBasic.valueSum, 0);
2937 2929 function.dataCollector.add(key, valueFunction,
2938   - numberBasic.docNumber);
  2930 + numberBasic.docNumber);
2939 2931 }
2940 2932 }
2941 2933 }
... ...
src/mtas/codec/util/CodecComponent.java
... ... @@ -1900,14 +1900,16 @@ public class CodecComponent {
1900 1900 public GroupHit(ArrayList<MtasTreeHit<String>> list, int start, int end,
1901 1901 int hitStart, int hitEnd, ComponentGroup group,
1902 1902 HashSet<String> knownPrefixes) throws UnsupportedEncodingException {
  1903 + //System.out.println("init: "+start+"-"+end+"\t"+hitStart+"-"+hitEnd);
1903 1904 // compute dimensions
1904 1905 int leftRangeStart = start;
1905 1906 int leftRangeEnd = Math.min(end - 1, hitStart - 1);
1906 1907 int leftRangeLength = Math.max(0, 1 + leftRangeEnd - leftRangeStart);
1907 1908 int hitLength = 1 + hitEnd - hitStart;
1908 1909 int rightRangeStart = Math.max(start, hitEnd + 1);
1909   - int rightRangeEnd = end - 1;
  1910 + int rightRangeEnd = end;
1910 1911 int rightRangeLength = Math.max(0, 1 + rightRangeEnd - rightRangeStart);
  1912 + //System.out.println(leftRangeStart+"\t"+leftRangeEnd+"\t"+leftRangeLength+" - "+rightRangeStart+"\t"+rightRangeEnd+"\t"+rightRangeLength);
1911 1913 // create initial arrays
1912 1914 if (leftRangeLength > 0) {
1913 1915 keyLeft = "";
... ... @@ -1981,15 +1983,15 @@ public class CodecComponent {
1981 1983 }
1982 1984 }
1983 1985 if (group.hitInsideRight != null) {
1984   - System.out.println(missingHit.length + " items in missingHit");
1985   - System.out.println(
1986   - group.hitInsideRight.length + " items in group.hitInsideRight");
  1986 + //System.out.println(missingHit.length + " items in missingHit");
  1987 + //System.out.println(
  1988 + // group.hitInsideRight.length + " items in group.hitInsideRight");
1987 1989 for (int p = 0; p < group.hitInsideRight.length; p++) {
1988   - System.out.println(" - " + group.hitInsideRight[p]);
  1990 + //System.out.println(" - " + group.hitInsideRight[p]);
1989 1991 }
1990 1992 for (int p = Math.max(hitStart,
1991 1993 hitEnd - group.hitInsideRight.length + 1); p <= hitEnd; p++) {
1992   - System.out.println("Test voor p is " + (p - hitStart));
  1994 + //System.out.println("Test voor p is " + (p - hitStart));
1993 1995 if (group.hitInsideRight[hitEnd - p] != null) {
1994 1996 missingHit[p - hitStart].addAll(group.hitInsideRight[hitEnd - p]);
1995 1997 }
... ...
src/mtas/parser/cql/MtasCQLParser.java
... ... @@ -17,6 +17,7 @@ import mtas.search.spans.util.MtasSpanQuery;
17 17 import mtas.search.spans.MtasSpanContainingQuery;
18 18 import mtas.search.spans.MtasSpanWithinQuery;
19 19 import mtas.search.spans.MtasSpanIntersectingQuery;
  20 +import mtas.search.spans.MtasSpanFullyAlignedWithQuery;
20 21 import mtas.search.spans.MtasSpanNotQuery;
21 22 import mtas.search.spans.MtasSpanSequenceItem;
22 23 import mtas.search.spans.MtasSpanSequenceQuery;
... ... @@ -27,14 +28,17 @@ import java.util.regex.Matcher;
27 28 import java.util.regex.Pattern;
28 29  
29 30 public class MtasCQLParser implements MtasCQLParserConstants {
30   - public MtasSpanQuery parse(String field, String defaultPrefix, HashMap<String, String[] > variables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException
  31 + public MtasSpanQuery parse(String field, String defaultPrefix, HashMap < String, String [] > variables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException
31 32 {
32   - HashSet<String> usedVariables = new HashSet<String>();
  33 + HashSet < String > usedVariables = new HashSet < String > ();
33 34 MtasSpanQuery query = cql(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength);
34   - if(variables!=null && variables.size() > usedVariables.size()) {
35   - for(String key : variables.keySet()) {
36   - if(!usedVariables.contains(key)) {
37   - throw new ParseException("variable $"+key+" not used");
  35 + if (variables != null && variables.size() > usedVariables.size())
  36 + {
  37 + for (String key : variables.keySet())
  38 + {
  39 + if (!usedVariables.contains(key))
  40 + {
  41 + throw new ParseException("variable $" + key + " not used");
38 42 }
39 43 }
40 44 throw new ParseException("unused variables defined");
... ... @@ -61,7 +65,7 @@ public class MtasCQLParser implements MtasCQLParserConstants {
61 65 return variable;
62 66 }
63 67  
64   - final private MtasSpanQuery cql(String field, String defaultPrefix, HashMap<String, String[] > variables, HashSet<String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException, ParseException {
  68 + final private MtasSpanQuery cql(String field, String defaultPrefix, HashMap < String, String [ ] > variables, HashSet < String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException, ParseException {
65 69 MtasSpanSequenceItem si;
66 70 ArrayList < MtasSpanSequenceItem > itemList = new ArrayList < MtasSpanSequenceItem > ();
67 71 si = cqlBlock(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength);
... ... @@ -88,9 +92,9 @@ public class MtasCQLParser implements MtasCQLParserConstants {
88 92 throw new Error("Missing return statement in function");
89 93 }
90 94  
91   - final private MtasSpanSequenceItem cqlBlock(String field, String defaultPrefix, HashMap<String, String[] > variables, HashSet<String > usedVariables, MtasSpanQuery ignore,Integer maximumIgnoreLength) throws ParseException, ParseException {
  95 + final private MtasSpanSequenceItem cqlBlock(String field, String defaultPrefix, HashMap < String, String [ ] > variables, HashSet < String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException, ParseException {
92 96 MtasCQLParserSentenceCondition sc1 = null, sc2 = null;
93   - MtasSpanSequenceItem si1 = null, si2=null;
  97 + MtasSpanSequenceItem si1 = null, si2 = null;
94 98 ArrayList < MtasSpanSequenceItem > itemList1 = new ArrayList < MtasSpanSequenceItem > ();
95 99 ArrayList < MtasSpanSequenceItem > itemList2 = new ArrayList < MtasSpanSequenceItem > ();
96 100 MtasSpanQuery q1 = null, q2 = null;
... ... @@ -102,12 +106,14 @@ public class MtasCQLParser implements MtasCQLParserConstants {
102 106 String OPERATOR_NOT_WITHIN = "not_within";
103 107 String OPERATOR_INTERSECTING = "intersecting";
104 108 String OPERATOR_NOT_INTERSECTING = "not_intersecting";
  109 + String OPERATOR_FULLYALIGNEDWITH = "fullyalignedwith";
  110 + String OPERATOR_NOT_FULLYALIGNEDWITH = "not_fullyalignedwith";
105 111 if (jj_2_3(1000)) {
106 112 sc1 = sentence(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength);
107 113 } else if (jj_2_4(1000)) {
108 114 jj_consume_token(BRACKET_START);
109 115 si1 = cqlBlock(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength);
110   - itemList1.add(si1);
  116 + itemList1.add(si1);
111 117 label_2:
112 118 while (true) {
113 119 if (jj_2_2(1000)) {
... ... @@ -116,14 +122,14 @@ public class MtasCQLParser implements MtasCQLParserConstants {
116 122 break label_2;
117 123 }
118 124 si1 = cqlBlock(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength);
119   - itemList1.add(si1);
  125 + itemList1.add(si1);
120 126 }
121 127 jj_consume_token(BRACKET_END);
122 128 } else {
123 129 jj_consume_token(-1);
124 130 throw new ParseException();
125 131 }
126   - if (jj_2_14(1000)) {
  132 + if (jj_2_16(1000)) {
127 133 if (jj_2_5(1000)) {
128 134 jj_consume_token(CONTAINING);
129 135 operator = OPERATOR_CONTAINING;
... ... @@ -142,19 +148,25 @@ public class MtasCQLParser implements MtasCQLParserConstants {
142 148 } else if (jj_2_10(1000)) {
143 149 jj_consume_token(NOT_INTERSECTING);
144 150 operator = OPERATOR_NOT_INTERSECTING;
  151 + } else if (jj_2_11(1000)) {
  152 + jj_consume_token(FULLYALIGNEDWITH);
  153 + operator = OPERATOR_FULLYALIGNEDWITH;
  154 + } else if (jj_2_12(1000)) {
  155 + jj_consume_token(NOT_FULLYALIGNEDWITH);
  156 + operator = OPERATOR_NOT_FULLYALIGNEDWITH;
145 157 } else {
146 158 jj_consume_token(-1);
147 159 throw new ParseException();
148 160 }
149   - if (jj_2_12(1000)) {
  161 + if (jj_2_14(1000)) {
150 162 sc2 = sentence(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength);
151   - } else if (jj_2_13(1000)) {
  163 + } else if (jj_2_15(1000)) {
152 164 jj_consume_token(BRACKET_START);
153 165 si2 = cqlBlock(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength);
154 166 itemList2.add(si2);
155 167 label_3:
156 168 while (true) {
157   - if (jj_2_11(1000)) {
  169 + if (jj_2_13(1000)) {
158 170 ;
159 171 } else {
160 172 break label_3;
... ... @@ -172,10 +184,14 @@ public class MtasCQLParser implements MtasCQLParserConstants {
172 184 }
173 185 if (sc1 != null)
174 186 {
175   - si1 = new MtasSpanSequenceItem(sc1.getQuery(),sc1.isOptional());
176   - } else if(itemList1.size()==1) {
  187 + si1 = new MtasSpanSequenceItem(sc1.getQuery(), sc1.isOptional());
  188 + }
  189 + else if (itemList1.size() == 1)
  190 + {
177 191 si1 = itemList1.get(0);
178   - } else {
  192 + }
  193 + else
  194 + {
179 195 MtasSpanQuery q = new MtasSpanSequenceQuery(itemList1, ignore, maximumIgnoreLength);
180 196 si1 = new MtasSpanSequenceItem(q, false);
181 197 }
... ... @@ -183,10 +199,14 @@ public class MtasCQLParser implements MtasCQLParserConstants {
183 199 {
184 200 if (sc2 != null)
185 201 {
186   - si2 = new MtasSpanSequenceItem(sc2.getQuery(),sc2.isOptional());
187   - } else if(itemList2.size()==1) {
  202 + si2 = new MtasSpanSequenceItem(sc2.getQuery(), sc2.isOptional());
  203 + }
  204 + else if (itemList2.size() == 1)
  205 + {
188 206 si2 = itemList2.get(0);
189   - } else {
  207 + }
  208 + else
  209 + {
190 210 MtasSpanQuery q = new MtasSpanSequenceQuery(itemList2, ignore, maximumIgnoreLength);
191 211 si2 = new MtasSpanSequenceItem(q, false);
192 212 }
... ... @@ -220,6 +240,16 @@ public class MtasCQLParser implements MtasCQLParserConstants {
220 240 MtasSpanQuery q = new MtasSpanNotQuery(si1.getQuery(), new MtasSpanIntersectingQuery(si1.getQuery(), si2.getQuery()));
221 241 {if (true) return new MtasSpanSequenceItem(q, si1.isOptional());}
222 242 }
  243 + else if (operator.equals(OPERATOR_FULLYALIGNEDWITH))
  244 + {
  245 + MtasSpanQuery q = new MtasSpanFullyAlignedWithQuery(si1.getQuery(), si2.getQuery());
  246 + {if (true) return new MtasSpanSequenceItem(q, si1.isOptional());}
  247 + }
  248 + else if (operator.equals(OPERATOR_NOT_FULLYALIGNEDWITH))
  249 + {
  250 + MtasSpanQuery q = new MtasSpanNotQuery(si1.getQuery(), new MtasSpanFullyAlignedWithQuery(si1.getQuery(), si2.getQuery()));
  251 + {if (true) return new MtasSpanSequenceItem(q, si1.isOptional());}
  252 + }
223 253 else
224 254 {
225 255 {if (true) throw new ParseException("unexpected operator " + operator);}
... ... @@ -232,7 +262,7 @@ public class MtasCQLParser implements MtasCQLParserConstants {
232 262 throw new Error("Missing return statement in function");
233 263 }
234 264  
235   - final private MtasCQLParserSentenceCondition sentence(String field, String defaultPrefix, HashMap<String, String[] > variables, HashSet<String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException, ParseException {
  265 + final private MtasCQLParserSentenceCondition sentence(String field, String defaultPrefix, HashMap < String, String [ ] > variables, HashSet < String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException, ParseException {
236 266 MtasCQLParserSentenceCondition sentenceCondition;
237 267 MtasCQLParserSentencePartCondition condition;
238 268 Token questionMark = null;
... ... @@ -246,7 +276,7 @@ public class MtasCQLParser implements MtasCQLParserConstants {
246 276 throw new Error("Missing return statement in function");
247 277 }
248 278  
249   - final private MtasCQLParserSentencePartCondition sentencePart(String field, String defaultPrefix, HashMap<String, String[] > variables, HashSet<String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException, ParseException {
  279 + final private MtasCQLParserSentencePartCondition sentencePart(String field, String defaultPrefix, HashMap < String, String [ ] > variables, HashSet < String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException, ParseException {
250 280 Token operator;
251 281 MtasCQLParserSentencePartCondition condition, sentencePart;
252 282 MtasCQLParserBasicSentenceCondition basicSentence;
... ... @@ -255,26 +285,26 @@ public class MtasCQLParser implements MtasCQLParserConstants {
255 285 Token maxValue = null;
256 286 int minimumOccurence = 1;
257 287 int maximumOccurence = 1;
258   - if (jj_2_19(1000)) {
  288 + if (jj_2_21(1000)) {
259 289 basicSentence = basicSentence(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength);
260 290 condition = new MtasCQLParserSentencePartCondition(basicSentence, ignore, maximumIgnoreLength);
261   - } else if (jj_2_20(1000)) {
  291 + } else if (jj_2_22(1000)) {
262 292 jj_consume_token(BRACKET_START);
263 293 sentencePart = sentencePart(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength);
264 294 jj_consume_token(BRACKET_END);
265   - if (jj_2_18(1000)) {
  295 + if (jj_2_20(1000)) {
266 296 questionMark = null;
267   - if (jj_2_15(1000)) {
  297 + if (jj_2_17(1000)) {
268 298 jj_consume_token(CURLY_BRACKET_START);
269 299 minValue = jj_consume_token(NUMBER);
270 300 jj_consume_token(KOMMA);
271 301 maxValue = jj_consume_token(NUMBER);
272 302 jj_consume_token(CURLY_BRACKET_END);
273   - } else if (jj_2_16(1000)) {
  303 + } else if (jj_2_18(1000)) {
274 304 jj_consume_token(CURLY_BRACKET_START);
275 305 minValue = jj_consume_token(NUMBER);
276 306 jj_consume_token(CURLY_BRACKET_END);
277   - } else if (jj_2_17(1000)) {
  307 + } else if (jj_2_19(1000)) {
278 308 questionMark = jj_consume_token(QUESTION_MARK);
279 309 } else {
280 310 jj_consume_token(-1);
... ... @@ -306,9 +336,9 @@ public class MtasCQLParser implements MtasCQLParserConstants {
306 336 jj_consume_token(-1);
307 337 throw new ParseException();
308 338 }
309   - if (jj_2_22(1000)) {
  339 + if (jj_2_24(1000)) {
310 340 operator = null;
311   - if (jj_2_21(1000)) {
  341 + if (jj_2_23(1000)) {
312 342 operator = jj_consume_token(OR);
313 343 } else {
314 344 ;
... ... @@ -330,14 +360,14 @@ public class MtasCQLParser implements MtasCQLParserConstants {
330 360 throw new Error("Missing return statement in function");
331 361 }
332 362  
333   - final private MtasCQLParserBasicSentenceCondition basicSentence(String field, String defaultPrefix, HashMap<String, String[] > variables, HashSet<String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException, ParseException {
  363 + final private MtasCQLParserBasicSentenceCondition basicSentence(String field, String defaultPrefix, HashMap < String, String [ ] > variables, HashSet < String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException, ParseException {
334 364 MtasCQLParserWordFullCondition subWordCondition;
335 365 MtasCQLParserGroupFullCondition subGroupCondition;
336 366 MtasCQLParserBasicSentenceCondition condition = new MtasCQLParserBasicSentenceCondition(ignore, maximumIgnoreLength);
337   - if (jj_2_23(1000)) {
  367 + if (jj_2_25(1000)) {
338 368 subWordCondition = word(field, defaultPrefix, variables, usedVariables);
339 369 condition.addWord(subWordCondition);
340   - } else if (jj_2_24(1000)) {
  370 + } else if (jj_2_26(1000)) {
341 371 subGroupCondition = group(field);
342 372 condition.addGroup(subGroupCondition);
343 373 } else {
... ... @@ -346,15 +376,15 @@ public class MtasCQLParser implements MtasCQLParserConstants {
346 376 }
347 377 label_4:
348 378 while (true) {
349   - if (jj_2_25(1000)) {
  379 + if (jj_2_27(1000)) {
350 380 ;
351 381 } else {
352 382 break label_4;
353 383 }
354   - if (jj_2_26(1000)) {
  384 + if (jj_2_28(1000)) {
355 385 subWordCondition = word(field, defaultPrefix, variables, usedVariables);
356 386 condition.addWord(subWordCondition);
357   - } else if (jj_2_27(1000)) {
  387 + } else if (jj_2_29(1000)) {
358 388 subGroupCondition = group(field);
359 389 condition.addGroup(subGroupCondition);
360 390 } else {
... ... @@ -377,9 +407,9 @@ public class MtasCQLParser implements MtasCQLParserConstants {
377 407 int minimumOccurence = 1;
378 408 int maximumOccurence = 1;
379 409 jj_consume_token(GROUP_START);
380   - if (jj_2_29(1000)) {
  410 + if (jj_2_31(1000)) {
381 411 condition = groupCondition(field);
382   - if (jj_2_28(1000)) {
  412 + if (jj_2_30(1000)) {
383 413 slash = jj_consume_token(SLASH);
384 414 } else {
385 415 ;
... ... @@ -394,7 +424,7 @@ public class MtasCQLParser implements MtasCQLParserConstants {
394 424 startGroup = false;
395 425 endGroup = false;
396 426 }
397   - } else if (jj_2_30(1000)) {
  427 + } else if (jj_2_32(1000)) {
398 428 jj_consume_token(SLASH);
399 429 condition = groupCondition(field);
400 430 startGroup = false;
... ... @@ -404,19 +434,19 @@ public class MtasCQLParser implements MtasCQLParserConstants {
404 434 throw new ParseException();
405 435 }
406 436 jj_consume_token(GROUP_END);
407   - if (jj_2_34(1000)) {
  437 + if (jj_2_36(1000)) {
408 438 questionMark = null;
409   - if (jj_2_31(1000)) {
  439 + if (jj_2_33(1000)) {
410 440 jj_consume_token(CURLY_BRACKET_START);
411 441 minValue = jj_consume_token(NUMBER);
412 442 jj_consume_token(KOMMA);
413 443 maxValue = jj_consume_token(NUMBER);
414 444 jj_consume_token(CURLY_BRACKET_END);
415   - } else if (jj_2_32(1000)) {
  445 + } else if (jj_2_34(1000)) {
416 446 jj_consume_token(CURLY_BRACKET_START);
417 447 minValue = jj_consume_token(NUMBER);
418 448 jj_consume_token(CURLY_BRACKET_END);
419   - } else if (jj_2_33(1000)) {
  449 + } else if (jj_2_35(1000)) {
420 450 questionMark = jj_consume_token(QUESTION_MARK);
421 451 } else {
422 452 jj_consume_token(-1);
... ... @@ -462,11 +492,11 @@ public class MtasCQLParser implements MtasCQLParserConstants {
462 492 final private MtasCQLParserGroupCondition groupCondition(String field) throws ParseException, ParseException {
463 493 Token prefix;
464 494 Token value = null;
465   - if (jj_2_35(1000)) {
  495 + if (jj_2_37(1000)) {
466 496 prefix = jj_consume_token(UNQUOTED_VALUE);
467 497 jj_consume_token(TOKEN_EQUALS);
468 498 value = jj_consume_token(QUOTED_VALUE);
469   - } else if (jj_2_36(1000)) {
  499 + } else if (jj_2_38(1000)) {
470 500 prefix = jj_consume_token(UNQUOTED_VALUE);
471 501 value = null;
472 502 } else {
... ... @@ -488,7 +518,7 @@ public class MtasCQLParser implements MtasCQLParserConstants {
488 518 throw new Error("Missing return statement in function");
489 519 }
490 520  
491   - final private MtasCQLParserWordFullCondition word(String field, String defaultPrefix, HashMap<String, String[] > variables, HashSet<String > usedVariables) throws ParseException, ParseException {
  521 + final private MtasCQLParserWordFullCondition word(String field, String defaultPrefix, HashMap < String, String [ ] > variables, HashSet < String > usedVariables) throws ParseException, ParseException {
492 522 Token questionMark = null;
493 523 Token value;
494 524 MtasCQLParserWordFullCondition wordCondition;
... ... @@ -497,14 +527,14 @@ public class MtasCQLParser implements MtasCQLParserConstants {
497 527 Token maxValue = null;
498 528 int minimumOccurence = 1;
499 529 int maximumOccurence = 1;
500   - if (jj_2_43(1000)) {
  530 + if (jj_2_45(1000)) {
501 531 value = jj_consume_token(QUOTED_VALUE);
502 532 condition = new MtasCQLParserDefaultPrefixCondition(field, defaultPrefix, unquoteString(value.image), variables, usedVariables);
503   - } else if (jj_2_44(1000)) {
  533 + } else if (jj_2_46(1000)) {
504 534 jj_consume_token(WORD_START);
505   - if (jj_2_41(1000)) {
  535 + if (jj_2_43(1000)) {
506 536 subCondition = wordCondition(field, variables, usedVariables);
507   - if (jj_2_39(1000)) {
  537 + if (jj_2_41(1000)) {
508 538 jj_consume_token(AND);
509 539 condition = new MtasCQLParserWordCondition(field, MtasCQLParserWordCondition.TYPE_AND);
510 540 condition.addCondition(subCondition);
... ... @@ -512,7 +542,7 @@ public class MtasCQLParser implements MtasCQLParserConstants {
512 542 condition.addCondition(subCondition);
513 543 label_5:
514 544 while (true) {
515   - if (jj_2_37(1000)) {
  545 + if (jj_2_39(1000)) {
516 546 ;
517 547 } else {
518 548 break label_5;
... ... @@ -521,7 +551,7 @@ public class MtasCQLParser implements MtasCQLParserConstants {
521 551 subCondition = wordCondition(field, variables, usedVariables);
522 552 condition.addCondition(subCondition);
523 553 }
524   - } else if (jj_2_40(1000)) {
  554 + } else if (jj_2_42(1000)) {
525 555 jj_consume_token(OR);
526 556 condition = new MtasCQLParserWordCondition(field, MtasCQLParserWordCondition.TYPE_OR);
527 557 condition.addCondition(subCondition);
... ... @@ -529,7 +559,7 @@ public class MtasCQLParser implements MtasCQLParserConstants {
529 559 condition.addCondition(subCondition);
530 560 label_6:
531 561 while (true) {
532   - if (jj_2_38(1000)) {
  562 + if (jj_2_40(1000)) {
533 563 ;
534 564 } else {
535 565 break label_6;
... ... @@ -542,14 +572,14 @@ public class MtasCQLParser implements MtasCQLParserConstants {
542 572 jj_consume_token(-1);
543 573 throw new ParseException();
544 574 }
545   - } else if (jj_2_42(1000)) {
  575 + } else if (jj_2_44(1000)) {
546 576 condition = wordCondition(field, variables, usedVariables);
547 577 } else {
548 578 jj_consume_token(-1);
549 579 throw new ParseException();
550 580 }
551 581 jj_consume_token(WORD_END);
552   - } else if (jj_2_45(1000)) {
  582 + } else if (jj_2_47(1000)) {
553 583 condition = new MtasCQLParserWordCondition(field, MtasCQLParserWordCondition.TYPE_AND);
554 584 jj_consume_token(WORD_START);
555 585 jj_consume_token(WORD_END);
... ... @@ -557,19 +587,19 @@ public class MtasCQLParser implements MtasCQLParserConstants {
557 587 jj_consume_token(-1);
558 588 throw new ParseException();
559 589 }
560   - if (jj_2_49(1000)) {
  590 + if (jj_2_51(1000)) {
561 591 questionMark = null;
562   - if (jj_2_46(1000)) {
  592 + if (jj_2_48(1000)) {
563 593 jj_consume_token(CURLY_BRACKET_START);
564 594 minValue = jj_consume_token(NUMBER);
565 595 jj_consume_token(KOMMA);
566 596 maxValue = jj_consume_token(NUMBER);
567 597 jj_consume_token(CURLY_BRACKET_END);
568   - } else if (jj_2_47(1000)) {
  598 + } else if (jj_2_49(1000)) {
569 599 jj_consume_token(CURLY_BRACKET_START);
570 600 minValue = jj_consume_token(NUMBER);
571 601 jj_consume_token(CURLY_BRACKET_END);
572   - } else if (jj_2_48(1000)) {
  602 + } else if (jj_2_50(1000)) {
573 603 questionMark = jj_consume_token(QUESTION_MARK);
574 604 } else {
575 605 jj_consume_token(-1);
... ... @@ -603,21 +633,21 @@ public class MtasCQLParser implements MtasCQLParserConstants {
603 633 throw new Error("Missing return statement in function");
604 634 }
605 635  
606   - final private MtasCQLParserWordCondition wordCondition(String field, HashMap<String, String[] > variables, HashSet<String > usedVariables) throws ParseException, ParseException {
  636 + final private MtasCQLParserWordCondition wordCondition(String field, HashMap < String, String [ ] > variables, HashSet < String > usedVariables) throws ParseException, ParseException {
607 637 Token negation = null;
608 638 MtasCQLParserWordCondition condition, subCondition;
609   - if (jj_2_70(1000)) {
610   - if (jj_2_50(1000)) {
  639 + if (jj_2_72(1000)) {
  640 + if (jj_2_52(1000)) {
611 641 negation = jj_consume_token(NEGATION);
612 642 } else {
613 643 ;
614 644 }
615 645 jj_consume_token(BRACKET_START);
616   - if (jj_2_67(1000)) {
  646 + if (jj_2_69(1000)) {
617 647 condition = new MtasCQLParserWordCondition(field, MtasCQLParserWordCondition.TYPE_AND);
618   - if (jj_2_51(1000)) {
  648 + if (jj_2_53(1000)) {
619 649 subCondition = wordAtomCondition(field, variables, usedVariables);
620   - } else if (jj_2_52(1000)) {
  650 + } else if (jj_2_54(1000)) {
621 651 subCondition = wordCondition(field, variables, usedVariables);
622 652 } else {
623 653 jj_consume_token(-1);
... ... @@ -625,9 +655,9 @@ public class MtasCQLParser implements MtasCQLParserConstants {
625 655 }
626 656 condition.addCondition(subCondition);
627 657 jj_consume_token(AND);
628   - if (jj_2_53(1000)) {
  658 + if (jj_2_55(1000)) {
629 659 subCondition = wordAtomCondition(field, variables, usedVariables);
630   - } else if (jj_2_54(1000)) {
  660 + } else if (jj_2_56(1000)) {
631 661 subCondition = wordCondition(field, variables, usedVariables);
632 662 } else {
633 663 jj_consume_token(-1);
... ... @@ -636,15 +666,15 @@ public class MtasCQLParser implements MtasCQLParserConstants {
636 666 condition.addCondition(subCondition);
637 667 label_7:
638 668 while (true) {
639   - if (jj_2_55(1000)) {
  669 + if (jj_2_57(1000)) {
640 670 ;
641 671 } else {
642 672 break label_7;
643 673 }
644 674 jj_consume_token(AND);
645   - if (jj_2_56(1000)) {
  675 + if (jj_2_58(1000)) {
646 676 subCondition = wordAtomCondition(field, variables, usedVariables);
647   - } else if (jj_2_57(1000)) {
  677 + } else if (jj_2_59(1000)) {
648 678 subCondition = wordCondition(field, variables, usedVariables);
649 679 } else {
650 680 jj_consume_token(-1);
... ... @@ -652,11 +682,11 @@ public class MtasCQLParser implements MtasCQLParserConstants {
652 682 }
653 683 condition.addCondition(subCondition);
654 684 }
655   - } else if (jj_2_68(1000)) {
  685 + } else if (jj_2_70(1000)) {
656 686 condition = new MtasCQLParserWordCondition(field, MtasCQLParserWordCondition.TYPE_OR);
657   - if (jj_2_58(1000)) {
  687 + if (jj_2_60(1000)) {
658 688 subCondition = wordAtomCondition(field, variables, usedVariables);
659   - } else if (jj_2_59(1000)) {
  689 + } else if (jj_2_61(1000)) {
660 690 subCondition = wordCondition(field, variables, usedVariables);
661 691 } else {
662 692 jj_consume_token(-1);
... ... @@ -664,9 +694,9 @@ public class MtasCQLParser implements MtasCQLParserConstants {
664 694 }
665 695 condition.addCondition(subCondition);
666 696 jj_consume_token(OR);
667   - if (jj_2_60(1000)) {
  697 + if (jj_2_62(1000)) {
668 698 subCondition = wordAtomCondition(field, variables, usedVariables);
669   - } else if (jj_2_61(1000)) {
  699 + } else if (jj_2_63(1000)) {
670 700 subCondition = wordCondition(field, variables, usedVariables);
671 701 } else {
672 702 jj_consume_token(-1);
... ... @@ -675,15 +705,15 @@ public class MtasCQLParser implements MtasCQLParserConstants {
675 705 condition.addCondition(subCondition);
676 706 label_8:
677 707 while (true) {
678   - if (jj_2_62(1000)) {
  708 + if (jj_2_64(1000)) {
679 709 ;
680 710 } else {
681 711 break label_8;
682 712 }
683 713 jj_consume_token(OR);
684   - if (jj_2_63(1000)) {
  714 + if (jj_2_65(1000)) {
685 715 subCondition = wordAtomCondition(field, variables, usedVariables);
686   - } else if (jj_2_64(1000)) {
  716 + } else if (jj_2_66(1000)) {
687 717 subCondition = wordCondition(field, variables, usedVariables);
688 718 } else {
689 719 jj_consume_token(-1);
... ... @@ -691,10 +721,10 @@ public class MtasCQLParser implements MtasCQLParserConstants {
691 721 }
692 722 condition.addCondition(subCondition);
693 723 }
694   - } else if (jj_2_69(1000)) {
695   - if (jj_2_65(1000)) {
  724 + } else if (jj_2_71(1000)) {
  725 + if (jj_2_67(1000)) {
696 726 condition = wordAtomCondition(field, variables, usedVariables);
697   - } else if (jj_2_66(1000)) {
  727 + } else if (jj_2_68(1000)) {
698 728 condition = wordCondition(field, variables, usedVariables);
699 729 } else {
700 730 jj_consume_token(-1);
... ... @@ -711,7 +741,7 @@ public class MtasCQLParser implements MtasCQLParserConstants {
711 741 }
712 742 //System.out.println("=== wordCondition ===\n" + condition + "\n");
713 743 {if (true) return condition;}
714   - } else if (jj_2_71(1000)) {
  744 + } else if (jj_2_73(1000)) {
715 745 //plain atom is a valid condition
716 746 subCondition = wordAtomCondition(field, variables, usedVariables);
717 747 //System.out.println("=== wordCondition ===\n" + subCondition + "\n");
... ... @@ -725,21 +755,21 @@ public class MtasCQLParser implements MtasCQLParserConstants {
725 755 throw new Error("Missing return statement in function");
726 756 }
727 757  
728   - final private MtasCQLParserWordCondition wordAtomCondition(String field, HashMap<String, String[] > variables, HashSet<String > usedVariables) throws ParseException, ParseException {
  758 + final private MtasCQLParserWordCondition wordAtomCondition(String field, HashMap < String, String [ ] > variables, HashSet < String > usedVariables) throws ParseException, ParseException {
729 759 Token negation = null;
730 760 Token nequals = null;
731 761 Token prefix;
732 762 Token value;
733   - if (jj_2_72(1000)) {
  763 + if (jj_2_74(1000)) {
734 764 negation = jj_consume_token(NEGATION);
735 765 } else {
736 766 ;
737 767 }
738   - if (jj_2_79(1000)) {
  768 + if (jj_2_81(1000)) {
739 769 jj_consume_token(OCTOTHORPE);
740   - if (jj_2_73(1000)) {
  770 + if (jj_2_75(1000)) {
741 771 value = jj_consume_token(NUMBER);
742   - } else if (jj_2_74(1000)) {
  772 + } else if (jj_2_76(1000)) {
743 773 value = jj_consume_token(UNQUOTED_VALUE);
744 774 } else {
745 775 jj_consume_token(-1);
... ... @@ -775,11 +805,11 @@ public class MtasCQLParser implements MtasCQLParserConstants {
775 805 {if (true) throw new ParseException("invalid range");}
776 806 }
777 807 {if (true) return condition;}
778   - } else if (jj_2_80(1000)) {
  808 + } else if (jj_2_82(1000)) {
779 809 prefix = jj_consume_token(UNQUOTED_VALUE);
780   - if (jj_2_75(1000)) {
  810 + if (jj_2_77(1000)) {
781 811 nequals = jj_consume_token(TOKEN_NOTEQUALS);
782   - } else if (jj_2_76(1000)) {
  812 + } else if (jj_2_78(1000)) {
783 813 jj_consume_token(TOKEN_EQUALS);
784 814 } else {
785 815 jj_consume_token(-1);
... ... @@ -804,11 +834,11 @@ public class MtasCQLParser implements MtasCQLParserConstants {
804 834 //System.out.println("=== wordAtomCondition ===\n" + condition + "\n");
805 835 {if (true) return condition;}
806 836 }
807   - } else if (jj_2_81(1000)) {
  837 + } else if (jj_2_83(1000)) {
808 838 prefix = jj_consume_token(UNQUOTED_VALUE);
809   - if (jj_2_77(1000)) {
  839 + if (jj_2_79(1000)) {
810 840 nequals = jj_consume_token(TOKEN_NOTEQUALS);
811   - } else if (jj_2_78(1000)) {
  841 + } else if (jj_2_80(1000)) {
812 842 jj_consume_token(TOKEN_EQUALS);
813 843 } else {
814 844 jj_consume_token(-1);
... ... @@ -1407,39 +1437,51 @@ public class MtasCQLParser implements MtasCQLParserConstants {
1407 1437 finally { jj_save(80, xla); }
1408 1438 }
1409 1439  
1410   - private boolean jj_3_29() {
1411   - if (jj_3R_15()) return true;
1412   - Token xsp;
1413   - xsp = jj_scanpos;
1414   - if (jj_3_28()) jj_scanpos = xsp;
  1440 + private boolean jj_2_82(int xla) {
  1441 + jj_la = xla; jj_lastpos = jj_scanpos = token;
  1442 + try { return !jj_3_82(); }
  1443 + catch(LookaheadSuccess ls) { return true; }
  1444 + finally { jj_save(81, xla); }
  1445 + }
  1446 +
  1447 + private boolean jj_2_83(int xla) {
  1448 + jj_la = xla; jj_lastpos = jj_scanpos = token;
  1449 + try { return !jj_3_83(); }
  1450 + catch(LookaheadSuccess ls) { return true; }
  1451 + finally { jj_save(82, xla); }
  1452 + }
  1453 +
  1454 + private boolean jj_3_47() {
  1455 + if (jj_scan_token(WORD_START)) return true;
  1456 + if (jj_scan_token(WORD_END)) return true;
1415 1457 return false;
1416 1458 }
1417 1459  
1418   - private boolean jj_3R_14() {
1419   - if (jj_scan_token(GROUP_START)) return true;
1420   - Token xsp;
1421   - xsp = jj_scanpos;
1422   - if (jj_3_29()) {
1423   - jj_scanpos = xsp;
1424   - if (jj_3_30()) return true;
1425   - }
1426   - if (jj_scan_token(GROUP_END)) return true;
1427   - xsp = jj_scanpos;
1428   - if (jj_3_34()) jj_scanpos = xsp;
  1460 + private boolean jj_3_25() {
  1461 + if (jj_3R_13()) return true;
1429 1462 return false;
1430 1463 }
1431 1464  
1432   - private boolean jj_3_78() {
1433   - if (jj_scan_token(TOKEN_EQUALS)) return true;
  1465 + private boolean jj_3_44() {
  1466 + if (jj_3R_16()) return true;
1434 1467 return false;
1435 1468 }
1436 1469  
1437   - private boolean jj_3_77() {
1438   - if (jj_scan_token(TOKEN_NOTEQUALS)) return true;
  1470 + private boolean jj_3R_11() {
  1471 + Token xsp;
  1472 + xsp = jj_scanpos;
  1473 + if (jj_3_25()) {
  1474 + jj_scanpos = xsp;
  1475 + if (jj_3_26()) return true;
  1476 + }
  1477 + while (true) {
  1478 + xsp = jj_scanpos;
  1479 + if (jj_3_27()) { jj_scanpos = xsp; break; }
  1480 + }
1439 1481 return false;
1440 1482 }
1441 1483  
1442   - private boolean jj_3_81() {
  1484 + private boolean jj_3_82() {
1443 1485 if (jj_scan_token(UNQUOTED_VALUE)) return true;
1444 1486 Token xsp;
1445 1487 xsp = jj_scanpos;
... ... @@ -1447,103 +1489,62 @@ public class MtasCQLParser implements MtasCQLParserConstants {
1447 1489 jj_scanpos = xsp;
1448 1490 if (jj_3_78()) return true;
1449 1491 }
1450   - if (jj_scan_token(QUOTED_VALUE)) return true;
1451   - return false;
1452   - }
1453   -
1454   - private boolean jj_3_11() {
1455   - if (jj_3R_9()) return true;
1456   - return false;
1457   - }
1458   -
1459   - private boolean jj_3_27() {
1460   - if (jj_3R_14()) return true;
1461   - return false;
1462   - }
1463   -
1464   - private boolean jj_3_48() {
1465   - if (jj_scan_token(QUESTION_MARK)) return true;
1466   - return false;
1467   - }
1468   -
1469   - private boolean jj_3_47() {
1470   - if (jj_scan_token(CURLY_BRACKET_START)) return true;
1471   - if (jj_scan_token(NUMBER)) return true;
1472   - if (jj_scan_token(CURLY_BRACKET_END)) return true;
1473   - return false;
1474   - }
1475   -
1476   - private boolean jj_3_26() {
1477   - if (jj_3R_13()) return true;
  1492 + if (jj_scan_token(VARIABLE)) return true;
1478 1493 return false;
1479 1494 }
1480 1495  
1481   - private boolean jj_3_46() {
1482   - if (jj_scan_token(CURLY_BRACKET_START)) return true;
1483   - if (jj_scan_token(NUMBER)) return true;
1484   - if (jj_scan_token(KOMMA)) return true;
1485   - if (jj_scan_token(NUMBER)) return true;
1486   - if (jj_scan_token(CURLY_BRACKET_END)) return true;
  1496 + private boolean jj_3_40() {
  1497 + if (jj_scan_token(OR)) return true;
  1498 + if (jj_3R_16()) return true;
1487 1499 return false;
1488 1500 }
1489 1501  
1490   - private boolean jj_3_13() {
  1502 + private boolean jj_3_15() {
1491 1503 if (jj_scan_token(BRACKET_START)) return true;
1492 1504 if (jj_3R_9()) return true;
1493 1505 Token xsp;
1494 1506 while (true) {
1495 1507 xsp = jj_scanpos;
1496   - if (jj_3_11()) { jj_scanpos = xsp; break; }
  1508 + if (jj_3_13()) { jj_scanpos = xsp; break; }
1497 1509 }
1498 1510 if (jj_scan_token(BRACKET_END)) return true;
1499 1511 return false;
1500 1512 }
1501 1513  
1502   - private boolean jj_3_12() {
  1514 + private boolean jj_3_14() {
1503 1515 if (jj_3R_10()) return true;
1504 1516 return false;
1505 1517 }
1506 1518  
1507   - private boolean jj_3_25() {
1508   - Token xsp;
1509   - xsp = jj_scanpos;
1510   - if (jj_3_26()) {
1511   - jj_scanpos = xsp;
1512   - if (jj_3_27()) return true;
1513   - }
  1519 + private boolean jj_3_12() {
  1520 + if (jj_scan_token(NOT_FULLYALIGNEDWITH)) return true;
1514 1521 return false;
1515 1522 }
1516 1523  
1517   - private boolean jj_3_49() {
  1524 + private boolean jj_3_42() {
  1525 + if (jj_scan_token(OR)) return true;
  1526 + if (jj_3R_16()) return true;
1518 1527 Token xsp;
1519   - xsp = jj_scanpos;
1520   - if (jj_3_46()) {
1521   - jj_scanpos = xsp;
1522   - if (jj_3_47()) {
1523   - jj_scanpos = xsp;
1524   - if (jj_3_48()) return true;
1525   - }
  1528 + while (true) {
  1529 + xsp = jj_scanpos;
  1530 + if (jj_3_40()) { jj_scanpos = xsp; break; }
1526 1531 }
1527 1532 return false;
1528 1533 }
1529 1534  
1530   - private boolean jj_3_76() {
1531   - if (jj_scan_token(TOKEN_EQUALS)) return true;
1532   - return false;
1533   - }
1534   -
1535   - private boolean jj_3_10() {
1536   - if (jj_scan_token(NOT_INTERSECTING)) return true;
  1535 + private boolean jj_3_11() {
  1536 + if (jj_scan_token(FULLYALIGNEDWITH)) return true;
1537 1537 return false;
1538 1538 }
1539 1539  
1540   - private boolean jj_3_75() {
1541   - if (jj_scan_token(TOKEN_NOTEQUALS)) return true;
  1540 + private boolean jj_3_39() {
  1541 + if (jj_scan_token(AND)) return true;
  1542 + if (jj_3R_16()) return true;
1542 1543 return false;
1543 1544 }
1544 1545  
1545   - private boolean jj_3_24() {
1546   - if (jj_3R_14()) return true;
  1546 + private boolean jj_3_10() {
  1547 + if (jj_scan_token(NOT_INTERSECTING)) return true;
1547 1548 return false;
1548 1549 }
1549 1550  
... ... @@ -1552,61 +1553,58 @@ public class MtasCQLParser implements MtasCQLParserConstants {
1552 1553 return false;
1553 1554 }
1554 1555  
1555   - private boolean jj_3_45() {
1556   - if (jj_scan_token(WORD_START)) return true;
1557   - if (jj_scan_token(WORD_END)) return true;
1558   - return false;
1559   - }
1560   -
1561 1556 private boolean jj_3_23() {
1562   - if (jj_3R_13()) return true;
  1557 + if (jj_scan_token(OR)) return true;
1563 1558 return false;
1564 1559 }
1565 1560  
1566   - private boolean jj_3_42() {
1567   - if (jj_3R_16()) return true;
  1561 + private boolean jj_3_8() {
  1562 + if (jj_scan_token(NOT_WITHIN)) return true;
1568 1563 return false;
1569 1564 }
1570 1565  
1571   - private boolean jj_3R_11() {
  1566 + private boolean jj_3_41() {
  1567 + if (jj_scan_token(AND)) return true;
  1568 + if (jj_3R_16()) return true;
1572 1569 Token xsp;
1573   - xsp = jj_scanpos;
1574   - if (jj_3_23()) {
1575   - jj_scanpos = xsp;
1576   - if (jj_3_24()) return true;
1577   - }
1578 1570 while (true) {
1579 1571 xsp = jj_scanpos;
1580   - if (jj_3_25()) { jj_scanpos = xsp; break; }
  1572 + if (jj_3_39()) { jj_scanpos = xsp; break; }
1581 1573 }
1582 1574 return false;
1583 1575 }
1584 1576  
1585   - private boolean jj_3_80() {
1586   - if (jj_scan_token(UNQUOTED_VALUE)) return true;
  1577 + private boolean jj_3_24() {
1587 1578 Token xsp;
1588 1579 xsp = jj_scanpos;
1589   - if (jj_3_75()) {
1590   - jj_scanpos = xsp;
1591   - if (jj_3_76()) return true;
1592   - }
1593   - if (jj_scan_token(VARIABLE)) return true;
  1580 + if (jj_3_23()) jj_scanpos = xsp;
  1581 + if (jj_3R_12()) return true;
1594 1582 return false;
1595 1583 }
1596 1584  
1597   - private boolean jj_3_8() {
1598   - if (jj_scan_token(NOT_WITHIN)) return true;
  1585 + private boolean jj_3_7() {
  1586 + if (jj_scan_token(WITHIN)) return true;
1599 1587 return false;
1600 1588 }
1601 1589  
1602   - private boolean jj_3_38() {
1603   - if (jj_scan_token(OR)) return true;
  1590 + private boolean jj_3_43() {
1604 1591 if (jj_3R_16()) return true;
  1592 + Token xsp;
  1593 + xsp = jj_scanpos;
  1594 + if (jj_3_41()) {
  1595 + jj_scanpos = xsp;
  1596 + if (jj_3_42()) return true;
  1597 + }
1605 1598 return false;
1606 1599 }
1607 1600  
1608   - private boolean jj_3_7() {
1609   - if (jj_scan_token(WITHIN)) return true;
  1601 + private boolean jj_3_76() {
  1602 + if (jj_scan_token(UNQUOTED_VALUE)) return true;
  1603 + return false;
  1604 + }
  1605 +
  1606 + private boolean jj_3_75() {
  1607 + if (jj_scan_token(NUMBER)) return true;
1610 1608 return false;
1611 1609 }
1612 1610  
... ... @@ -1615,23 +1613,40 @@ public class MtasCQLParser implements MtasCQLParserConstants {
1615 1613 return false;
1616 1614 }
1617 1615  
  1616 + private boolean jj_3_46() {
  1617 + if (jj_scan_token(WORD_START)) return true;
  1618 + Token xsp;
  1619 + xsp = jj_scanpos;
  1620 + if (jj_3_43()) {
  1621 + jj_scanpos = xsp;
  1622 + if (jj_3_44()) return true;
  1623 + }
  1624 + if (jj_scan_token(WORD_END)) return true;
  1625 + return false;
  1626 + }
  1627 +
1618 1628 private boolean jj_3_5() {
1619 1629 if (jj_scan_token(CONTAINING)) return true;
1620 1630 return false;
1621 1631 }
1622 1632  
1623   - private boolean jj_3_40() {
1624   - if (jj_scan_token(OR)) return true;
1625   - if (jj_3R_16()) return true;
  1633 + private boolean jj_3_45() {
  1634 + if (jj_scan_token(QUOTED_VALUE)) return true;
  1635 + return false;
  1636 + }
  1637 +
  1638 + private boolean jj_3_81() {
  1639 + if (jj_scan_token(OCTOTHORPE)) return true;
1626 1640 Token xsp;
1627   - while (true) {
1628   - xsp = jj_scanpos;
1629   - if (jj_3_38()) { jj_scanpos = xsp; break; }
  1641 + xsp = jj_scanpos;
  1642 + if (jj_3_75()) {
  1643 + jj_scanpos = xsp;
  1644 + if (jj_3_76()) return true;
1630 1645 }
1631 1646 return false;
1632 1647 }
1633 1648  
1634   - private boolean jj_3_14() {
  1649 + private boolean jj_3_16() {
1635 1650 Token xsp;
1636 1651 xsp = jj_scanpos;
1637 1652 if (jj_3_5()) {
... ... @@ -1644,228 +1659,150 @@ public class MtasCQLParser implements MtasCQLParserConstants {
1644 1659 jj_scanpos = xsp;
1645 1660 if (jj_3_9()) {
1646 1661 jj_scanpos = xsp;
1647   - if (jj_3_10()) return true;
  1662 + if (jj_3_10()) {
  1663 + jj_scanpos = xsp;
  1664 + if (jj_3_11()) {
  1665 + jj_scanpos = xsp;
  1666 + if (jj_3_12()) return true;
  1667 + }
  1668 + }
1648 1669 }
1649 1670 }
1650 1671 }
1651 1672 }
1652 1673 }
1653 1674 xsp = jj_scanpos;
1654   - if (jj_3_12()) {
  1675 + if (jj_3_14()) {
1655 1676 jj_scanpos = xsp;
1656   - if (jj_3_13()) return true;
  1677 + if (jj_3_15()) return true;
1657 1678 }
1658 1679 return false;
1659 1680 }
1660 1681  
1661   - private boolean jj_3_37() {
1662   - if (jj_scan_token(AND)) return true;
1663   - if (jj_3R_16()) return true;
  1682 + private boolean jj_3R_13() {
  1683 + Token xsp;
  1684 + xsp = jj_scanpos;
  1685 + if (jj_3_45()) {
  1686 + jj_scanpos = xsp;
  1687 + if (jj_3_46()) {
  1688 + jj_scanpos = xsp;
  1689 + if (jj_3_47()) return true;
  1690 + }
  1691 + }
  1692 + xsp = jj_scanpos;
  1693 + if (jj_3_51()) jj_scanpos = xsp;
1664 1694 return false;
1665 1695 }
1666 1696  
1667   - private boolean jj_3_2() {
1668   - if (jj_3R_9()) return true;
1669   - return false;
1670   - }
1671   -
1672   - private boolean jj_3_21() {
1673   - if (jj_scan_token(OR)) return true;
1674   - return false;
1675   - }
1676   -
1677   - private boolean jj_3_39() {
1678   - if (jj_scan_token(AND)) return true;
1679   - if (jj_3R_16()) return true;
1680   - Token xsp;
1681   - while (true) {
1682   - xsp = jj_scanpos;
1683   - if (jj_3_37()) { jj_scanpos = xsp; break; }
1684   - }
1685   - return false;
1686   - }
1687   -
1688   - private boolean jj_3_4() {
1689   - if (jj_scan_token(BRACKET_START)) return true;
1690   - if (jj_3R_9()) return true;
1691   - Token xsp;
1692   - while (true) {
1693   - xsp = jj_scanpos;
1694   - if (jj_3_2()) { jj_scanpos = xsp; break; }
1695   - }
1696   - if (jj_scan_token(BRACKET_END)) return true;
  1697 + private boolean jj_3_74() {
  1698 + if (jj_scan_token(NEGATION)) return true;
1697 1699 return false;
1698 1700 }
1699 1701  
1700   - private boolean jj_3_22() {
  1702 + private boolean jj_3R_17() {
1701 1703 Token xsp;
1702 1704 xsp = jj_scanpos;
1703   - if (jj_3_21()) jj_scanpos = xsp;
1704   - if (jj_3R_12()) return true;
1705   - return false;
1706   - }
1707   -
1708   - private boolean jj_3_3() {
1709   - if (jj_3R_10()) return true;
1710   - return false;
1711   - }
1712   -
1713   - private boolean jj_3_41() {
1714   - if (jj_3R_16()) return true;
1715   - Token xsp;
  1705 + if (jj_3_74()) jj_scanpos = xsp;
1716 1706 xsp = jj_scanpos;
1717   - if (jj_3_39()) {
  1707 + if (jj_3_81()) {
1718 1708 jj_scanpos = xsp;
1719   - if (jj_3_40()) return true;
1720   - }
1721   - return false;
1722   - }
1723   -
1724   - private boolean jj_3_74() {
1725   - if (jj_scan_token(UNQUOTED_VALUE)) return true;
1726   - return false;
1727   - }
1728   -
1729   - private boolean jj_3R_9() {
1730   - Token xsp;
1731   - xsp = jj_scanpos;
1732   - if (jj_3_3()) {
  1709 + if (jj_3_82()) {
1733 1710 jj_scanpos = xsp;
1734   - if (jj_3_4()) return true;
  1711 + if (jj_3_83()) return true;
  1712 + }
1735 1713 }
1736   - xsp = jj_scanpos;
1737   - if (jj_3_14()) jj_scanpos = xsp;
1738 1714 return false;
1739 1715 }
1740 1716  
1741   - private boolean jj_3_73() {
1742   - if (jj_scan_token(NUMBER)) return true;
  1717 + private boolean jj_3_2() {
  1718 + if (jj_3R_9()) return true;
1743 1719 return false;
1744 1720 }
1745 1721  
1746   - private boolean jj_3_44() {
1747   - if (jj_scan_token(WORD_START)) return true;
1748   - Token xsp;
1749   - xsp = jj_scanpos;
1750   - if (jj_3_41()) {
1751   - jj_scanpos = xsp;
1752   - if (jj_3_42()) return true;
1753   - }
1754   - if (jj_scan_token(WORD_END)) return true;
  1722 + private boolean jj_3_19() {
  1723 + if (jj_scan_token(QUESTION_MARK)) return true;
1755 1724 return false;
1756 1725 }
1757 1726  
1758   - private boolean jj_3_43() {
1759   - if (jj_scan_token(QUOTED_VALUE)) return true;
  1727 + private boolean jj_3_18() {
  1728 + if (jj_scan_token(CURLY_BRACKET_START)) return true;
  1729 + if (jj_scan_token(NUMBER)) return true;
  1730 + if (jj_scan_token(CURLY_BRACKET_END)) return true;
1760 1731 return false;
1761 1732 }
1762 1733  
1763   - private boolean jj_3_79() {
1764   - if (jj_scan_token(OCTOTHORPE)) return true;
1765   - Token xsp;
1766   - xsp = jj_scanpos;
1767   - if (jj_3_73()) {
1768   - jj_scanpos = xsp;
1769   - if (jj_3_74()) return true;
1770   - }
  1734 + private boolean jj_3_17() {
  1735 + if (jj_scan_token(CURLY_BRACKET_START)) return true;
  1736 + if (jj_scan_token(NUMBER)) return true;
  1737 + if (jj_scan_token(KOMMA)) return true;
  1738 + if (jj_scan_token(NUMBER)) return true;
  1739 + if (jj_scan_token(CURLY_BRACKET_END)) return true;
1771 1740 return false;
1772 1741 }
1773 1742  
1774   - private boolean jj_3R_13() {
  1743 + private boolean jj_3_4() {
  1744 + if (jj_scan_token(BRACKET_START)) return true;
  1745 + if (jj_3R_9()) return true;
1775 1746 Token xsp;
1776   - xsp = jj_scanpos;
1777   - if (jj_3_43()) {
1778   - jj_scanpos = xsp;
1779   - if (jj_3_44()) {
1780   - jj_scanpos = xsp;
1781   - if (jj_3_45()) return true;
1782   - }
  1747 + while (true) {
  1748 + xsp = jj_scanpos;
  1749 + if (jj_3_2()) { jj_scanpos = xsp; break; }
1783 1750 }
1784   - xsp = jj_scanpos;
1785   - if (jj_3_49()) jj_scanpos = xsp;
  1751 + if (jj_scan_token(BRACKET_END)) return true;
1786 1752 return false;
1787 1753 }
1788 1754  
1789   - private boolean jj_3_72() {
1790   - if (jj_scan_token(NEGATION)) return true;
  1755 + private boolean jj_3_3() {
  1756 + if (jj_3R_10()) return true;
1791 1757 return false;
1792 1758 }
1793 1759  
1794   - private boolean jj_3R_17() {
  1760 + private boolean jj_3_20() {
1795 1761 Token xsp;
1796 1762 xsp = jj_scanpos;
1797   - if (jj_3_72()) jj_scanpos = xsp;
1798   - xsp = jj_scanpos;
1799   - if (jj_3_79()) {
  1763 + if (jj_3_17()) {
1800 1764 jj_scanpos = xsp;
1801   - if (jj_3_80()) {
  1765 + if (jj_3_18()) {
1802 1766 jj_scanpos = xsp;
1803   - if (jj_3_81()) return true;
  1767 + if (jj_3_19()) return true;
1804 1768 }
1805 1769 }
1806 1770 return false;
1807 1771 }
1808 1772  
1809   - private boolean jj_3_17() {
1810   - if (jj_scan_token(QUESTION_MARK)) return true;
1811   - return false;
1812   - }
1813   -
1814   - private boolean jj_3_16() {
1815   - if (jj_scan_token(CURLY_BRACKET_START)) return true;
1816   - if (jj_scan_token(NUMBER)) return true;
1817   - if (jj_scan_token(CURLY_BRACKET_END)) return true;
1818   - return false;
1819   - }
1820   -
1821   - private boolean jj_3_15() {
1822   - if (jj_scan_token(CURLY_BRACKET_START)) return true;
1823   - if (jj_scan_token(NUMBER)) return true;
1824   - if (jj_scan_token(KOMMA)) return true;
1825   - if (jj_scan_token(NUMBER)) return true;
1826   - if (jj_scan_token(CURLY_BRACKET_END)) return true;
1827   - return false;
1828   - }
1829   -
1830   - private boolean jj_3_18() {
  1773 + private boolean jj_3R_9() {
1831 1774 Token xsp;
1832 1775 xsp = jj_scanpos;
1833   - if (jj_3_15()) {
1834   - jj_scanpos = xsp;
1835   - if (jj_3_16()) {
  1776 + if (jj_3_3()) {
1836 1777 jj_scanpos = xsp;
1837   - if (jj_3_17()) return true;
1838   - }
  1778 + if (jj_3_4()) return true;
1839 1779 }
  1780 + xsp = jj_scanpos;
  1781 + if (jj_3_16()) jj_scanpos = xsp;
1840 1782 return false;
1841 1783 }
1842 1784  
1843   - private boolean jj_3_71() {
  1785 + private boolean jj_3_73() {
1844 1786 if (jj_3R_17()) return true;
1845 1787 return false;
1846 1788 }
1847 1789  
1848   - private boolean jj_3_20() {
  1790 + private boolean jj_3_22() {
1849 1791 if (jj_scan_token(BRACKET_START)) return true;
1850 1792 if (jj_3R_12()) return true;
1851 1793 if (jj_scan_token(BRACKET_END)) return true;
1852 1794 Token xsp;
1853 1795 xsp = jj_scanpos;
1854   - if (jj_3_18()) jj_scanpos = xsp;
  1796 + if (jj_3_20()) jj_scanpos = xsp;
1855 1797 return false;
1856 1798 }
1857 1799  
1858   - private boolean jj_3_1() {
1859   - if (jj_3R_9()) return true;
1860   - return false;
1861   - }
1862   -
1863   - private boolean jj_3_19() {
  1800 + private boolean jj_3_21() {
1864 1801 if (jj_3R_11()) return true;
1865 1802 return false;
1866 1803 }
1867 1804  
1868   - private boolean jj_3_66() {
  1805 + private boolean jj_3_68() {
1869 1806 if (jj_3R_16()) return true;
1870 1807 return false;
1871 1808 }
... ... @@ -1873,38 +1810,38 @@ public class MtasCQLParser implements MtasCQLParserConstants {
1873 1810 private boolean jj_3R_12() {
1874 1811 Token xsp;
1875 1812 xsp = jj_scanpos;
1876   - if (jj_3_19()) {
  1813 + if (jj_3_21()) {
1877 1814 jj_scanpos = xsp;
1878   - if (jj_3_20()) return true;
  1815 + if (jj_3_22()) return true;
1879 1816 }
1880 1817 xsp = jj_scanpos;
1881   - if (jj_3_22()) jj_scanpos = xsp;
  1818 + if (jj_3_24()) jj_scanpos = xsp;
1882 1819 return false;
1883 1820 }
1884 1821  
1885   - private boolean jj_3_65() {
  1822 + private boolean jj_3_67() {
1886 1823 if (jj_3R_17()) return true;
1887 1824 return false;
1888 1825 }
1889 1826  
1890   - private boolean jj_3_36() {
  1827 + private boolean jj_3_38() {
1891 1828 if (jj_scan_token(UNQUOTED_VALUE)) return true;
1892 1829 return false;
1893 1830 }
1894 1831  
1895   - private boolean jj_3_35() {
  1832 + private boolean jj_3_37() {
1896 1833 if (jj_scan_token(UNQUOTED_VALUE)) return true;
1897 1834 if (jj_scan_token(TOKEN_EQUALS)) return true;
1898 1835 if (jj_scan_token(QUOTED_VALUE)) return true;
1899 1836 return false;
1900 1837 }
1901 1838  
1902   - private boolean jj_3_69() {
  1839 + private boolean jj_3_71() {
1903 1840 Token xsp;
1904 1841 xsp = jj_scanpos;
1905   - if (jj_3_65()) {
  1842 + if (jj_3_67()) {
1906 1843 jj_scanpos = xsp;
1907   - if (jj_3_66()) return true;
  1844 + if (jj_3_68()) return true;
1908 1845 }
1909 1846 return false;
1910 1847 }
... ... @@ -1912,40 +1849,40 @@ public class MtasCQLParser implements MtasCQLParserConstants {
1912 1849 private boolean jj_3R_15() {
1913 1850 Token xsp;
1914 1851 xsp = jj_scanpos;
1915   - if (jj_3_35()) {
  1852 + if (jj_3_37()) {
1916 1853 jj_scanpos = xsp;
1917   - if (jj_3_36()) return true;
  1854 + if (jj_3_38()) return true;
1918 1855 }
1919 1856 return false;
1920 1857 }
1921 1858  
1922   - private boolean jj_3_64() {
  1859 + private boolean jj_3_66() {
1923 1860 if (jj_3R_16()) return true;
1924 1861 return false;
1925 1862 }
1926 1863  
1927   - private boolean jj_3_63() {
  1864 + private boolean jj_3_65() {
1928 1865 if (jj_3R_17()) return true;
1929 1866 return false;
1930 1867 }
1931 1868  
1932   - private boolean jj_3_62() {
  1869 + private boolean jj_3_64() {
1933 1870 if (jj_scan_token(OR)) return true;
1934 1871 Token xsp;
1935 1872 xsp = jj_scanpos;
1936   - if (jj_3_63()) {
  1873 + if (jj_3_65()) {
1937 1874 jj_scanpos = xsp;
1938   - if (jj_3_64()) return true;
  1875 + if (jj_3_66()) return true;
1939 1876 }
1940 1877 return false;
1941 1878 }
1942 1879  
1943   - private boolean jj_3_61() {
  1880 + private boolean jj_3_63() {
1944 1881 if (jj_3R_16()) return true;
1945 1882 return false;
1946 1883 }
1947 1884  
1948   - private boolean jj_3_60() {
  1885 + private boolean jj_3_62() {
1949 1886 if (jj_3R_17()) return true;
1950 1887 return false;
1951 1888 }
... ... @@ -1955,80 +1892,85 @@ public class MtasCQLParser implements MtasCQLParserConstants {
1955 1892 return false;
1956 1893 }
1957 1894  
1958   - private boolean jj_3_59() {
  1895 + private boolean jj_3_1() {
  1896 + if (jj_3R_9()) return true;
  1897 + return false;
  1898 + }
  1899 +
  1900 + private boolean jj_3_61() {
1959 1901 if (jj_3R_16()) return true;
1960 1902 return false;
1961 1903 }
1962 1904  
1963   - private boolean jj_3_58() {
  1905 + private boolean jj_3_60() {
1964 1906 if (jj_3R_17()) return true;
1965 1907 return false;
1966 1908 }
1967 1909  
1968   - private boolean jj_3_68() {
  1910 + private boolean jj_3_70() {
1969 1911 Token xsp;
1970 1912 xsp = jj_scanpos;
1971   - if (jj_3_58()) {
  1913 + if (jj_3_60()) {
1972 1914 jj_scanpos = xsp;
1973   - if (jj_3_59()) return true;
  1915 + if (jj_3_61()) return true;
1974 1916 }
1975 1917 if (jj_scan_token(OR)) return true;
1976 1918 xsp = jj_scanpos;
1977   - if (jj_3_60()) {
  1919 + if (jj_3_62()) {
1978 1920 jj_scanpos = xsp;
1979   - if (jj_3_61()) return true;
  1921 + if (jj_3_63()) return true;
1980 1922 }
1981 1923 while (true) {
1982 1924 xsp = jj_scanpos;
1983   - if (jj_3_62()) { jj_scanpos = xsp; break; }
  1925 + if (jj_3_64()) { jj_scanpos = xsp; break; }
1984 1926 }
1985 1927 return false;
1986 1928 }
1987 1929  
1988   - private boolean jj_3_57() {
  1930 + private boolean jj_3_59() {
1989 1931 if (jj_3R_16()) return true;
1990 1932 return false;
1991 1933 }
1992 1934  
1993   - private boolean jj_3_56() {
  1935 + private boolean jj_3_58() {
1994 1936 if (jj_3R_17()) return true;
1995 1937 return false;
1996 1938 }
1997 1939  
1998   - private boolean jj_3_28() {
  1940 + private boolean jj_3_30() {
1999 1941 if (jj_scan_token(SLASH)) return true;
2000 1942 return false;
2001 1943 }
2002 1944  
2003   - private boolean jj_3_55() {
  1945 + private boolean jj_3_57() {
2004 1946 if (jj_scan_token(AND)) return true;
2005 1947 Token xsp;
2006 1948 xsp = jj_scanpos;
2007   - if (jj_3_56()) {
  1949 + if (jj_3_58()) {
2008 1950 jj_scanpos = xsp;
2009   - if (jj_3_57()) return true;
  1951 + if (jj_3_59()) return true;
2010 1952 }
2011 1953 return false;
2012 1954 }
2013 1955  
2014   - private boolean jj_3_33() {
  1956 + private boolean jj_3_35() {
2015 1957 if (jj_scan_token(QUESTION_MARK)) return true;
2016 1958 return false;
2017 1959 }
2018 1960  
2019   - private boolean jj_3_32() {
  1961 + private boolean jj_3_34() {
2020 1962 if (jj_scan_token(CURLY_BRACKET_START)) return true;
2021 1963 if (jj_scan_token(NUMBER)) return true;
2022 1964 if (jj_scan_token(CURLY_BRACKET_END)) return true;
2023 1965 return false;
2024 1966 }
2025 1967  
2026   - private boolean jj_3_54() {
  1968 + private boolean jj_3_56() {
2027 1969 if (jj_3R_16()) return true;
2028 1970 return false;
2029 1971 }
2030 1972  
2031   - private boolean jj_3_31() {
  1973 + private boolean jj_3_33() {
2032 1974 if (jj_scan_token(CURLY_BRACKET_START)) return true;
2033 1975 if (jj_scan_token(NUMBER)) return true;
2034 1976 if (jj_scan_token(KOMMA)) return true;
... ... @@ -2037,76 +1979,76 @@ public class MtasCQLParser implements MtasCQLParserConstants {
2037 1979 return false;
2038 1980 }
2039 1981  
2040   - private boolean jj_3_53() {
  1982 + private boolean jj_3_55() {
2041 1983 if (jj_3R_17()) return true;
2042 1984 return false;
2043 1985 }
2044 1986  
2045   - private boolean jj_3_34() {
  1987 + private boolean jj_3_36() {
2046 1988 Token xsp;
2047 1989 xsp = jj_scanpos;
2048   - if (jj_3_31()) {
  1990 + if (jj_3_33()) {
2049 1991 jj_scanpos = xsp;
2050   - if (jj_3_32()) {
  1992 + if (jj_3_34()) {
2051 1993 jj_scanpos = xsp;
2052   - if (jj_3_33()) return true;
  1994 + if (jj_3_35()) return true;
2053 1995 }
2054 1996 }
2055 1997 return false;
2056 1998 }
2057 1999  
2058   - private boolean jj_3_52() {
  2000 + private boolean jj_3_54() {
2059 2001 if (jj_3R_16()) return true;
2060 2002 return false;
2061 2003 }
2062 2004  
2063   - private boolean jj_3_51() {
  2005 + private boolean jj_3_53() {
2064 2006 if (jj_3R_17()) return true;
2065 2007 return false;
2066 2008 }
2067 2009  
2068   - private boolean jj_3_30() {
  2010 + private boolean jj_3_32() {
2069 2011 if (jj_scan_token(SLASH)) return true;
2070 2012 if (jj_3R_15()) return true;
2071 2013 return false;
2072 2014 }
2073 2015  
2074   - private boolean jj_3_67() {
  2016 + private boolean jj_3_69() {
2075 2017 Token xsp;
2076 2018 xsp = jj_scanpos;
2077   - if (jj_3_51()) {
  2019 + if (jj_3_53()) {
2078 2020 jj_scanpos = xsp;
2079   - if (jj_3_52()) return true;
  2021 + if (jj_3_54()) return true;
2080 2022 }
2081 2023 if (jj_scan_token(AND)) return true;
2082 2024 xsp = jj_scanpos;
2083   - if (jj_3_53()) {
  2025 + if (jj_3_55()) {
2084 2026 jj_scanpos = xsp;
2085   - if (jj_3_54()) return true;
  2027 + if (jj_3_56()) return true;
2086 2028 }
2087 2029 while (true) {
2088 2030 xsp = jj_scanpos;
2089   - if (jj_3_55()) { jj_scanpos = xsp; break; }
  2031 + if (jj_3_57()) { jj_scanpos = xsp; break; }
2090 2032 }
2091 2033 return false;
2092 2034 }
2093 2035  
2094   - private boolean jj_3_50() {
  2036 + private boolean jj_3_52() {
2095 2037 if (jj_scan_token(NEGATION)) return true;
2096 2038 return false;
2097 2039 }
2098 2040  
2099   - private boolean jj_3_70() {
  2041 + private boolean jj_3_72() {
2100 2042 Token xsp;
2101 2043 xsp = jj_scanpos;
2102   - if (jj_3_50()) jj_scanpos = xsp;
  2044 + if (jj_3_52()) jj_scanpos = xsp;
2103 2045 if (jj_scan_token(BRACKET_START)) return true;
2104 2046 xsp = jj_scanpos;
2105   - if (jj_3_67()) {
  2047 + if (jj_3_69()) {
2106 2048 jj_scanpos = xsp;
2107   - if (jj_3_68()) {
  2049 + if (jj_3_70()) {
2108 2050 jj_scanpos = xsp;
2109   - if (jj_3_69()) return true;
  2051 + if (jj_3_71()) return true;
2110 2052 }
2111 2053 }
2112 2054 if (jj_scan_token(BRACKET_END)) return true;
... ... @@ -2116,13 +2058,131 @@ public class MtasCQLParser implements MtasCQLParserConstants {
2116 2058 private boolean jj_3R_16() {
2117 2059 Token xsp;
2118 2060 xsp = jj_scanpos;
2119   - if (jj_3_70()) {
  2061 + if (jj_3_72()) {
2120 2062 jj_scanpos = xsp;
2121   - if (jj_3_71()) return true;
  2063 + if (jj_3_73()) return true;
2122 2064 }
2123 2065 return false;
2124 2066 }
2125 2067  
  2068 + private boolean jj_3_31() {
  2069 + if (jj_3R_15()) return true;
  2070 + Token xsp;
  2071 + xsp = jj_scanpos;
  2072 + if (jj_3_30()) jj_scanpos = xsp;
  2073 + return false;
  2074 + }
  2075 +
  2076 + private boolean jj_3R_14() {
  2077 + if (jj_scan_token(GROUP_START)) return true;
  2078 + Token xsp;
  2079 + xsp = jj_scanpos;
  2080 + if (jj_3_31()) {
  2081 + jj_scanpos = xsp;
  2082 + if (jj_3_32()) return true;
  2083 + }
  2084 + if (jj_scan_token(GROUP_END)) return true;
  2085 + xsp = jj_scanpos;
  2086 + if (jj_3_36()) jj_scanpos = xsp;
  2087 + return false;
  2088 + }
  2089 +
  2090 + private boolean jj_3_80() {
  2091 + if (jj_scan_token(TOKEN_EQUALS)) return true;
  2092 + return false;
  2093 + }
  2094 +
  2095 + private boolean jj_3_79() {
  2096 + if (jj_scan_token(TOKEN_NOTEQUALS)) return true;
  2097 + return false;
  2098 + }
  2099 +
  2100 + private boolean jj_3_83() {
  2101 + if (jj_scan_token(UNQUOTED_VALUE)) return true;
  2102 + Token xsp;
  2103 + xsp = jj_scanpos;
  2104 + if (jj_3_79()) {
  2105 + jj_scanpos = xsp;
  2106 + if (jj_3_80()) return true;
  2107 + }
  2108 + if (jj_scan_token(QUOTED_VALUE)) return true;
  2109 + return false;
  2110 + }
  2111 +
  2112 + private boolean jj_3_29() {
  2113 + if (jj_3R_14()) return true;
  2114 + return false;
  2115 + }
  2116 +
  2117 + private boolean jj_3_50() {
  2118 + if (jj_scan_token(QUESTION_MARK)) return true;
  2119 + return false;
  2120 + }
  2121 +
  2122 + private boolean jj_3_49() {
  2123 + if (jj_scan_token(CURLY_BRACKET_START)) return true;
  2124 + if (jj_scan_token(NUMBER)) return true;
  2125 + if (jj_scan_token(CURLY_BRACKET_END)) return true;
  2126 + return false;
  2127 + }
  2128 +
  2129 + private boolean jj_3_28() {
  2130 + if (jj_3R_13()) return true;
  2131 + return false;
  2132 + }
  2133 +
  2134 + private boolean jj_3_48() {
  2135 + if (jj_scan_token(CURLY_BRACKET_START)) return true;
  2136 + if (jj_scan_token(NUMBER)) return true;
  2137 + if (jj_scan_token(KOMMA)) return true;
  2138 + if (jj_scan_token(NUMBER)) return true;
  2139 + if (jj_scan_token(CURLY_BRACKET_END)) return true;
  2140 + return false;
  2141 + }
  2142 +
  2143 + private boolean jj_3_27() {
  2144 + Token xsp;
  2145 + xsp = jj_scanpos;
  2146 + if (jj_3_28()) {
  2147 + jj_scanpos = xsp;
  2148 + if (jj_3_29()) return true;
  2149 + }
  2150 + return false;
  2151 + }
  2152 +
  2153 + private boolean jj_3_51() {
  2154 + Token xsp;
  2155 + xsp = jj_scanpos;
  2156 + if (jj_3_48()) {
  2157 + jj_scanpos = xsp;
  2158 + if (jj_3_49()) {
  2159 + jj_scanpos = xsp;
  2160 + if (jj_3_50()) return true;
  2161 + }
  2162 + }
  2163 + return false;
  2164 + }
  2165 +
  2166 + private boolean jj_3_78() {
  2167 + if (jj_scan_token(TOKEN_EQUALS)) return true;
  2168 + return false;
  2169 + }
  2170 +
  2171 + private boolean jj_3_77() {
  2172 + if (jj_scan_token(TOKEN_NOTEQUALS)) return true;
  2173 + return false;
  2174 + }
  2175 +
  2176 + private boolean jj_3_26() {
  2177 + if (jj_3R_14()) return true;
  2178 + return false;
  2179 + }
  2180 +
  2181 + private boolean jj_3_13() {
  2182 + if (jj_3R_9()) return true;
  2183 + return false;
  2184 + }
  2185 +
2126 2186 /** Generated Token Manager. */
2127 2187 public MtasCQLParserTokenManager token_source;
2128 2188 SimpleCharStream jj_input_stream;
... ... @@ -2147,7 +2207,7 @@ public class MtasCQLParser implements MtasCQLParserConstants {
2147 2207 private static void jj_la1_init_1() {
2148 2208 jj_la1_1 = new int[] {};
2149 2209 }
2150   - final private JJCalls[] jj_2_rtns = new JJCalls[81];
  2210 + final private JJCalls[] jj_2_rtns = new JJCalls[83];
2151 2211 private boolean jj_rescan = false;
2152 2212 private int jj_gc = 0;
2153 2213  
... ... @@ -2331,7 +2391,7 @@ public class MtasCQLParser implements MtasCQLParserConstants {
2331 2391 /** Generate ParseException. */
2332 2392 public ParseException generateParseException() {
2333 2393 jj_expentries.clear();
2334   - boolean[] la1tokens = new boolean[34];
  2394 + boolean[] la1tokens = new boolean[36];
2335 2395 if (jj_kind >= 0) {
2336 2396 la1tokens[jj_kind] = true;
2337 2397 jj_kind = -1;
... ... @@ -2348,7 +2408,7 @@ public class MtasCQLParser implements MtasCQLParserConstants {
2348 2408 }
2349 2409 }
2350 2410 }
2351   - for (int i = 0; i < 34; i++) {
  2411 + for (int i = 0; i < 36; i++) {
2352 2412 if (la1tokens[i]) {
2353 2413 jj_expentry = new int[1];
2354 2414 jj_expentry[0] = i;
... ... @@ -2375,7 +2435,7 @@ public class MtasCQLParser implements MtasCQLParserConstants {
2375 2435  
2376 2436 private void jj_rescan_token() {
2377 2437 jj_rescan = true;
2378   - for (int i = 0; i < 81; i++) {
  2438 + for (int i = 0; i < 83; i++) {
2379 2439 try {
2380 2440 JJCalls p = jj_2_rtns[i];
2381 2441 do {
... ... @@ -2463,6 +2523,8 @@ public class MtasCQLParser implements MtasCQLParserConstants {
2463 2523 case 78: jj_3_79(); break;
2464 2524 case 79: jj_3_80(); break;
2465 2525 case 80: jj_3_81(); break;
  2526 + case 81: jj_3_82(); break;
  2527 + case 82: jj_3_83(); break;
2466 2528 }
2467 2529 }
2468 2530 p = p.next;
... ...
src/mtas/parser/cql/MtasCQLParser.jj
... ... @@ -6,6 +6,7 @@ options
6 6 DEBUG_PARSER = false;
7 7 DEBUG_LOOKAHEAD = false;
8 8 DEBUG_TOKEN_MANAGER = false;
  9 +
9 10 LOOKAHEAD= 1000;
10 11 }
11 12  
... ... @@ -28,27 +29,31 @@ import mtas.search.spans.util.MtasSpanQuery;
28 29 import mtas.search.spans.MtasSpanContainingQuery;
29 30 import mtas.search.spans.MtasSpanWithinQuery;
30 31 import mtas.search.spans.MtasSpanIntersectingQuery;
  32 +import mtas.search.spans.MtasSpanFullyAlignedWithQuery;
31 33 import mtas.search.spans.MtasSpanNotQuery;
32 34 import mtas.search.spans.MtasSpanSequenceItem;
33 35 import mtas.search.spans.MtasSpanSequenceQuery;
34 36 import java.util.ArrayList;
35   -import java.util.HashMap;
  37 +import java.util.HashMap;
36 38 import java.util.HashSet;
37 39 import java.util.regex.Matcher;
38 40 import java.util.regex.Pattern;
39 41  
40 42 public class MtasCQLParser
41 43 {
42   - public MtasSpanQuery parse(String field, String defaultPrefix, HashMap<String, String[] > variables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException
  44 + public MtasSpanQuery parse(String field, String defaultPrefix, HashMap < String, String [] > variables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException
43 45 {
44   - HashSet<String> usedVariables = new HashSet<String>();
  46 + HashSet < String > usedVariables = new HashSet < String > ();
45 47 MtasSpanQuery query = cql(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength);
46   - if(variables!=null && variables.size() > usedVariables.size()) {
47   - for(String key : variables.keySet()) {
48   - if(!usedVariables.contains(key)) {
49   - throw new ParseException("variable $"+key+" not used");
  48 + if (variables != null && variables.size() > usedVariables.size())
  49 + {
  50 + for (String key : variables.keySet())
  51 + {
  52 + if (!usedVariables.contains(key))
  53 + {
  54 + throw new ParseException("variable $" + key + " not used");
50 55 }
51   - }
  56 + }
52 57 throw new ParseException("unused variables defined");
53 58 }
54 59 return query;
... ... @@ -116,6 +121,16 @@ TOKEN :
116 121  
117 122 TOKEN :
118 123 {
  124 + < FULLYALIGNEDWITH : "fullyalignedwith" >
  125 +}
  126 +
  127 +TOKEN :
  128 +{
  129 + < NOT_FULLYALIGNEDWITH : "!fullyalignedwith" >
  130 +}
  131 +
  132 +TOKEN :
  133 +{
119 134 < GROUP_START : "<" >
120 135 }
121 136  
... ... @@ -245,7 +260,7 @@ TOKEN :
245 260 >
246 261 }
247 262  
248   -private MtasSpanQuery cql(String field, String defaultPrefix, HashMap<String, String[] > variables, HashSet<String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException :
  263 +private MtasSpanQuery cql(String field, String defaultPrefix, HashMap < String, String [ ] > variables, HashSet < String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException :
249 264 {
250 265 MtasSpanSequenceItem si;
251 266 ArrayList < MtasSpanSequenceItem > itemList = new ArrayList < MtasSpanSequenceItem > ();
... ... @@ -274,10 +289,10 @@ private MtasSpanQuery cql(String field, String defaultPrefix, HashMap&lt;String, St
274 289 }
275 290 }
276 291  
277   -private MtasSpanSequenceItem cqlBlock(String field, String defaultPrefix, HashMap<String, String[] > variables, HashSet<String > usedVariables, MtasSpanQuery ignore,Integer maximumIgnoreLength) throws ParseException :
  292 +private MtasSpanSequenceItem cqlBlock(String field, String defaultPrefix, HashMap < String, String [ ] > variables, HashSet < String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException :
278 293 {
279 294 MtasCQLParserSentenceCondition sc1 = null, sc2 = null;
280   - MtasSpanSequenceItem si1 = null, si2=null;
  295 + MtasSpanSequenceItem si1 = null, si2 = null;
281 296 ArrayList < MtasSpanSequenceItem > itemList1 = new ArrayList < MtasSpanSequenceItem > ();
282 297 ArrayList < MtasSpanSequenceItem > itemList2 = new ArrayList < MtasSpanSequenceItem > ();
283 298 MtasSpanQuery q1 = null, q2 = null;
... ... @@ -289,22 +304,24 @@ private MtasSpanSequenceItem cqlBlock(String field, String defaultPrefix, HashMa
289 304 String OPERATOR_NOT_WITHIN = "not_within";
290 305 String OPERATOR_INTERSECTING = "intersecting";
291 306 String OPERATOR_NOT_INTERSECTING = "not_intersecting";
  307 + String OPERATOR_FULLYALIGNEDWITH = "fullyalignedwith";
  308 + String OPERATOR_NOT_FULLYALIGNEDWITH = "not_fullyalignedwith";
292 309 }
293 310 {
294 311 (
295 312 sc1 = sentence(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength)
296 313 |
297   - < BRACKET_START >
  314 + < BRACKET_START >
  315 + si1 = cqlBlock(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength)
  316 + {
  317 + itemList1.add(si1);
  318 + }
  319 + (
298 320 si1 = cqlBlock(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength)
299 321 {
300 322 itemList1.add(si1);
301 323 }
302   - (
303   - si1 = cqlBlock(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength)
304   - {
305   - itemList1.add(si1);
306   - }
307   - )*
  324 + )*
308 325 < BRACKET_END >
309 326 )
310 327 [
... ... @@ -325,7 +342,7 @@ private MtasSpanSequenceItem cqlBlock(String field, String defaultPrefix, HashMa
325 342 {
326 343 operator = OPERATOR_NOT_WITHIN;
327 344 }
328   - | < INTERSECTING >
  345 + | < INTERSECTING >
329 346 {
330 347 operator = OPERATOR_INTERSECTING;
331 348 }
... ... @@ -333,10 +350,18 @@ private MtasSpanSequenceItem cqlBlock(String field, String defaultPrefix, HashMa
333 350 {
334 351 operator = OPERATOR_NOT_INTERSECTING;
335 352 }
  353 + | < FULLYALIGNEDWITH >
  354 + {
  355 + operator = OPERATOR_FULLYALIGNEDWITH;
  356 + }
  357 + | < NOT_FULLYALIGNEDWITH >
  358 + {
  359 + operator = OPERATOR_NOT_FULLYALIGNEDWITH;
  360 + }
336 361 )
337 362 (
338 363 sc2 = sentence(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength)
339   - | < BRACKET_START >
  364 + | < BRACKET_START >
340 365 si2 = cqlBlock(field, defaultPrefix, variables, usedVariables, ignore, maximumIgnoreLength)
341 366 {
342 367 itemList2.add(si2);
... ... @@ -347,16 +372,20 @@ private MtasSpanSequenceItem cqlBlock(String field, String defaultPrefix, HashMa
347 372 itemList2.add(si2);
348 373 }
349 374 )*
350   - < BRACKET_END >
  375 + < BRACKET_END >
351 376 )
352 377 ]
353 378 {
354 379 if (sc1 != null)
355 380 {
356   - si1 = new MtasSpanSequenceItem(sc1.getQuery(),sc1.isOptional());
357   - } else if(itemList1.size()==1) {
  381 + si1 = new MtasSpanSequenceItem(sc1.getQuery(), sc1.isOptional());
  382 + }
  383 + else if (itemList1.size() == 1)
  384 + {
358 385 si1 = itemList1.get(0);
359   - } else {
  386 + }
  387 + else
  388 + {
360 389 MtasSpanQuery q = new MtasSpanSequenceQuery(itemList1, ignore, maximumIgnoreLength);
361 390 si1 = new MtasSpanSequenceItem(q, false);
362 391 }
... ... @@ -364,13 +393,17 @@ private MtasSpanSequenceItem cqlBlock(String field, String defaultPrefix, HashMa
364 393 {
365 394 if (sc2 != null)
366 395 {
367   - si2 = new MtasSpanSequenceItem(sc2.getQuery(),sc2.isOptional());
368   - } else if(itemList2.size()==1) {
  396 + si2 = new MtasSpanSequenceItem(sc2.getQuery(), sc2.isOptional());
  397 + }
  398 + else if (itemList2.size() == 1)
  399 + {
369 400 si2 = itemList2.get(0);
370   - } else {
  401 + }
  402 + else
  403 + {
371 404 MtasSpanQuery q = new MtasSpanSequenceQuery(itemList2, ignore, maximumIgnoreLength);
372 405 si2 = new MtasSpanSequenceItem(q, false);
373   - }
  406 + }
374 407 if (operator.equals(OPERATOR_CONTAINING))
375 408 {
376 409 MtasSpanQuery q = new MtasSpanContainingQuery(si1.getQuery(), si2.getQuery());
... ... @@ -401,6 +434,16 @@ private MtasSpanSequenceItem cqlBlock(String field, String defaultPrefix, HashMa
401 434 MtasSpanQuery q = new MtasSpanNotQuery(si1.getQuery(), new MtasSpanIntersectingQuery(si1.getQuery(), si2.getQuery()));
402 435 return new MtasSpanSequenceItem(q, si1.isOptional());
403 436 }
  437 + else if (operator.equals(OPERATOR_FULLYALIGNEDWITH))
  438 + {
  439 + MtasSpanQuery q = new MtasSpanFullyAlignedWithQuery(si1.getQuery(), si2.getQuery());
  440 + return new MtasSpanSequenceItem(q, si1.isOptional());
  441 + }
  442 + else if (operator.equals(OPERATOR_NOT_FULLYALIGNEDWITH))
  443 + {
  444 + MtasSpanQuery q = new MtasSpanNotQuery(si1.getQuery(), new MtasSpanFullyAlignedWithQuery(si1.getQuery(), si2.getQuery()));
  445 + return new MtasSpanSequenceItem(q, si1.isOptional());
  446 + }
404 447 else
405 448 {
406 449 throw new ParseException("unexpected operator " + operator);
... ... @@ -413,7 +456,7 @@ private MtasSpanSequenceItem cqlBlock(String field, String defaultPrefix, HashMa
413 456 }
414 457 }
415 458  
416   -private MtasCQLParserSentenceCondition sentence(String field, String defaultPrefix, HashMap<String, String[] > variables, HashSet<String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException :
  459 +private MtasCQLParserSentenceCondition sentence(String field, String defaultPrefix, HashMap < String, String [ ] > variables, HashSet < String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException :
417 460 {
418 461 MtasCQLParserSentenceCondition sentenceCondition;
419 462 MtasCQLParserSentencePartCondition condition;
... ... @@ -431,7 +474,7 @@ private MtasCQLParserSentenceCondition sentence(String field, String defaultPref
431 474 }
432 475 }
433 476  
434   -private MtasCQLParserSentencePartCondition sentencePart(String field, String defaultPrefix, HashMap<String, String[] > variables, HashSet<String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException :
  477 +private MtasCQLParserSentencePartCondition sentencePart(String field, String defaultPrefix, HashMap < String, String [ ] > variables, HashSet < String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException :
435 478 {
436 479 Token operator;
437 480 MtasCQLParserSentencePartCondition condition, sentencePart;
... ... @@ -509,13 +552,13 @@ private MtasCQLParserSentencePartCondition sentencePart(String field, String def
509 552 }
510 553 }
511 554  
512   -private MtasCQLParserBasicSentenceCondition basicSentence(String field, String defaultPrefix, HashMap<String, String[] > variables, HashSet<String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException :
  555 +private MtasCQLParserBasicSentenceCondition basicSentence(String field, String defaultPrefix, HashMap < String, String [ ] > variables, HashSet < String > usedVariables, MtasSpanQuery ignore, Integer maximumIgnoreLength) throws ParseException :
513 556 {
514 557 MtasCQLParserWordFullCondition subWordCondition;
515 558 MtasCQLParserGroupFullCondition subGroupCondition;
516 559 MtasCQLParserBasicSentenceCondition condition = new MtasCQLParserBasicSentenceCondition(ignore, maximumIgnoreLength);
517 560 }
518   -{
  561 +{
519 562 (
520 563 subWordCondition = word(field, defaultPrefix, variables, usedVariables)
521 564 {
... ... @@ -569,7 +612,7 @@ private MtasCQLParserGroupFullCondition group(String field) throws ParseExceptio
569 612 {
570 613 startGroup = false;
571 614 endGroup = false;
572   - }
  615 + }
573 616 }
574 617 | < SLASH > condition = groupCondition(field)
575 618 {
... ... @@ -652,7 +695,7 @@ private MtasCQLParserGroupCondition groupCondition(String field) throws ParseExc
652 695 }
653 696 }
654 697  
655   -private MtasCQLParserWordFullCondition word(String field, String defaultPrefix, HashMap<String, String[] > variables, HashSet<String > usedVariables) throws ParseException :
  698 +private MtasCQLParserWordFullCondition word(String field, String defaultPrefix, HashMap < String, String [ ] > variables, HashSet < String > usedVariables) throws ParseException :
656 699 {
657 700 Token questionMark = null;
658 701 Token value;
... ... @@ -749,7 +792,7 @@ private MtasCQLParserWordFullCondition word(String field, String defaultPrefix,
749 792 }
750 793 }
751 794  
752   -private MtasCQLParserWordCondition wordCondition(String field, HashMap<String, String[] > variables, HashSet<String > usedVariables) throws ParseException :
  795 +private MtasCQLParserWordCondition wordCondition(String field, HashMap < String, String [ ] > variables, HashSet < String > usedVariables) throws ParseException :
753 796 {
754 797 Token negation = null;
755 798 MtasCQLParserWordCondition condition, subCondition;
... ... @@ -839,7 +882,7 @@ private MtasCQLParserWordCondition wordCondition(String field, HashMap&lt;String, S
839 882 }
840 883 }
841 884  
842   -private MtasCQLParserWordCondition wordAtomCondition(String field, HashMap<String, String[] > variables, HashSet<String > usedVariables) throws ParseException :
  885 +private MtasCQLParserWordCondition wordAtomCondition(String field, HashMap < String, String [ ] > variables, HashSet < String > usedVariables) throws ParseException :
843 886 {
844 887 Token negation = null;
845 888 Token nequals = null;
... ...
src/mtas/parser/cql/MtasCQLParserConstants.java
... ... @@ -23,51 +23,55 @@ public interface MtasCQLParserConstants {
23 23 /** RegularExpression Id. */
24 24 int NOT_INTERSECTING = 10;
25 25 /** RegularExpression Id. */
26   - int GROUP_START = 11;
  26 + int FULLYALIGNEDWITH = 11;
27 27 /** RegularExpression Id. */
28   - int GROUP_END = 12;
  28 + int NOT_FULLYALIGNEDWITH = 12;
29 29 /** RegularExpression Id. */
30   - int WORD_START = 13;
  30 + int GROUP_START = 13;
31 31 /** RegularExpression Id. */
32   - int WORD_END = 14;
  32 + int GROUP_END = 14;
33 33 /** RegularExpression Id. */
34   - int BRACKET_START = 15;
  34 + int WORD_START = 15;
35 35 /** RegularExpression Id. */
36   - int BRACKET_END = 16;
  36 + int WORD_END = 16;
37 37 /** RegularExpression Id. */
38   - int CURLY_BRACKET_START = 17;
  38 + int BRACKET_START = 17;
39 39 /** RegularExpression Id. */
40   - int CURLY_BRACKET_END = 18;
  40 + int BRACKET_END = 18;
41 41 /** RegularExpression Id. */
42   - int SLASH = 19;
  42 + int CURLY_BRACKET_START = 19;
43 43 /** RegularExpression Id. */
44   - int QUESTION_MARK = 20;
  44 + int CURLY_BRACKET_END = 20;
45 45 /** RegularExpression Id. */
46   - int NEGATION = 21;
  46 + int SLASH = 21;
47 47 /** RegularExpression Id. */
48   - int AND = 22;
  48 + int QUESTION_MARK = 22;
49 49 /** RegularExpression Id. */
50   - int OR = 23;
  50 + int NEGATION = 23;
51 51 /** RegularExpression Id. */
52   - int KOMMA = 24;
  52 + int AND = 24;
53 53 /** RegularExpression Id. */
54   - int TOKEN_NOTEQUALS = 25;
  54 + int OR = 25;
55 55 /** RegularExpression Id. */
56   - int TOKEN_EQUALS = 26;
  56 + int KOMMA = 26;
57 57 /** RegularExpression Id. */
58   - int NUMBER = 27;
  58 + int TOKEN_NOTEQUALS = 27;
59 59 /** RegularExpression Id. */
60   - int VARIABLE = 28;
  60 + int TOKEN_EQUALS = 28;
61 61 /** RegularExpression Id. */
62   - int QUOTED_VALUE = 29;
  62 + int NUMBER = 29;
63 63 /** RegularExpression Id. */
64   - int UNQUOTED_VALUE = 30;
  64 + int VARIABLE = 30;
65 65 /** RegularExpression Id. */
66   - int OCTOTHORPE = 31;
  66 + int QUOTED_VALUE = 31;
67 67 /** RegularExpression Id. */
68   - int DIGIT = 32;
  68 + int UNQUOTED_VALUE = 32;
69 69 /** RegularExpression Id. */
70   - int ALLOWED_UNQUOTED_CHARACTER = 33;
  70 + int OCTOTHORPE = 33;
  71 + /** RegularExpression Id. */
  72 + int DIGIT = 34;
  73 + /** RegularExpression Id. */
  74 + int ALLOWED_UNQUOTED_CHARACTER = 35;
71 75  
72 76 /** Lexical state. */
73 77 int DEFAULT = 0;
... ... @@ -85,6 +89,8 @@ public interface MtasCQLParserConstants {
85 89 "\"!within\"",
86 90 "\"intersecting\"",
87 91 "\"!intersecting\"",
  92 + "\"fullyalignedwith\"",
  93 + "\"!fullyalignedwith\"",
88 94 "\"<\"",
89 95 "\">\"",
90 96 "\"[\"",
... ...
src/mtas/parser/cql/MtasCQLParserTokenManager.java
... ... @@ -17,6 +17,7 @@ import mtas.search.spans.util.MtasSpanQuery;
17 17 import mtas.search.spans.MtasSpanContainingQuery;
18 18 import mtas.search.spans.MtasSpanWithinQuery;
19 19 import mtas.search.spans.MtasSpanIntersectingQuery;
  20 +import mtas.search.spans.MtasSpanFullyAlignedWithQuery;
20 21 import mtas.search.spans.MtasSpanNotQuery;
21 22 import mtas.search.spans.MtasSpanSequenceItem;
22 23 import mtas.search.spans.MtasSpanSequenceQuery;
... ... @@ -39,74 +40,74 @@ private final int jjStopStringLiteralDfa_0(int pos, long active0)
39 40 switch (pos)
40 41 {
41 42 case 0:
42   - if ((active0 & 0x2a0L) != 0L)
  43 + if ((active0 & 0xaa0L) != 0L)
43 44 {
44   - jjmatchedKind = 30;
  45 + jjmatchedKind = 32;
45 46 return 8;
46 47 }
47 48 return -1;
48 49 case 1:
49   - if ((active0 & 0x2a0L) != 0L)
  50 + if ((active0 & 0xaa0L) != 0L)
50 51 {
51   - jjmatchedKind = 30;
  52 + jjmatchedKind = 32;
52 53 jjmatchedPos = 1;
53 54 return 8;
54 55 }
55 56 return -1;
56 57 case 2:
57   - if ((active0 & 0x2a0L) != 0L)
  58 + if ((active0 & 0xaa0L) != 0L)
58 59 {
59   - jjmatchedKind = 30;
  60 + jjmatchedKind = 32;
60 61 jjmatchedPos = 2;
61 62 return 8;
62 63 }
63 64 return -1;
64 65 case 3:
65   - if ((active0 & 0x2a0L) != 0L)
  66 + if ((active0 & 0xaa0L) != 0L)
66 67 {
67   - jjmatchedKind = 30;
  68 + jjmatchedKind = 32;
68 69 jjmatchedPos = 3;
69 70 return 8;
70 71 }
71 72 return -1;
72 73 case 4:
73   - if ((active0 & 0x2a0L) != 0L)
  74 + if ((active0 & 0xaa0L) != 0L)
74 75 {
75   - jjmatchedKind = 30;
  76 + jjmatchedKind = 32;
76 77 jjmatchedPos = 4;
77 78 return 8;
78 79 }
79 80 return -1;
80 81 case 5:
81   - if ((active0 & 0x220L) != 0L)
  82 + if ((active0 & 0x80L) != 0L)
  83 + return 8;
  84 + if ((active0 & 0xa20L) != 0L)
82 85 {
83   - jjmatchedKind = 30;
  86 + jjmatchedKind = 32;
84 87 jjmatchedPos = 5;
85 88 return 8;
86 89 }
87   - if ((active0 & 0x80L) != 0L)
88   - return 8;
89 90 return -1;
90 91 case 6:
91   - if ((active0 & 0x220L) != 0L)
  92 + if ((active0 & 0xa20L) != 0L)
92 93 {
93   - jjmatchedKind = 30;
  94 + jjmatchedKind = 32;
94 95 jjmatchedPos = 6;
95 96 return 8;
96 97 }
97 98 return -1;
98 99 case 7:
99   - if ((active0 & 0x220L) != 0L)
  100 + if ((active0 & 0xa20L) != 0L)
100 101 {
101   - jjmatchedKind = 30;
  102 + jjmatchedKind = 32;
102 103 jjmatchedPos = 7;
103 104 return 8;
104 105 }
105 106 return -1;
106 107 case 8:
107   - if ((active0 & 0x220L) != 0L)
  108 + if ((active0 & 0xa20L) != 0L)
108 109 {
109   - jjmatchedKind = 30;
  110 + jjmatchedKind = 32;
110 111 jjmatchedPos = 8;
111 112 return 8;
112 113 }
... ... @@ -114,17 +115,17 @@ private final int jjStopStringLiteralDfa_0(int pos, long active0)
114 115 case 9:
115 116 if ((active0 & 0x20L) != 0L)
116 117 return 8;
117   - if ((active0 & 0x200L) != 0L)
  118 + if ((active0 & 0xa00L) != 0L)
118 119 {
119   - jjmatchedKind = 30;
  120 + jjmatchedKind = 32;
120 121 jjmatchedPos = 9;
121 122 return 8;
122 123 }
123 124 return -1;
124 125 case 10:
125   - if ((active0 & 0x200L) != 0L)
  126 + if ((active0 & 0xa00L) != 0L)
126 127 {
127   - jjmatchedKind = 30;
  128 + jjmatchedKind = 32;
128 129 jjmatchedPos = 10;
129 130 return 8;
130 131 }
... ... @@ -132,6 +133,40 @@ private final int jjStopStringLiteralDfa_0(int pos, long active0)
132 133 case 11:
133 134 if ((active0 & 0x200L) != 0L)
134 135 return 8;
  136 + if ((active0 & 0x800L) != 0L)
  137 + {
  138 + jjmatchedKind = 32;
  139 + jjmatchedPos = 11;
  140 + return 8;
  141 + }
  142 + return -1;
  143 + case 12:
  144 + if ((active0 & 0x800L) != 0L)
  145 + {
  146 + jjmatchedKind = 32;
  147 + jjmatchedPos = 12;
  148 + return 8;
  149 + }
  150 + return -1;
  151 + case 13:
  152 + if ((active0 & 0x800L) != 0L)
  153 + {
  154 + jjmatchedKind = 32;
  155 + jjmatchedPos = 13;
  156 + return 8;
  157 + }
  158 + return -1;
  159 + case 14:
  160 + if ((active0 & 0x800L) != 0L)
  161 + {
  162 + jjmatchedKind = 32;
  163 + jjmatchedPos = 14;
  164 + return 8;
  165 + }
  166 + return -1;
  167 + case 15:
  168 + if ((active0 & 0x800L) != 0L)
  169 + return 8;
135 170 return -1;
136 171 default :
137 172 return -1;
... ... @@ -152,42 +187,44 @@ private int jjMoveStringLiteralDfa0_0()
152 187 switch(curChar)
153 188 {
154 189 case 33:
155   - jjmatchedKind = 21;
156   - return jjMoveStringLiteralDfa1_0(0x2000540L);
  190 + jjmatchedKind = 23;
  191 + return jjMoveStringLiteralDfa1_0(0x8001540L);
157 192 case 38:
158   - return jjStopAtPos(0, 22);
  193 + return jjStopAtPos(0, 24);
159 194 case 40:
160   - return jjStopAtPos(0, 15);
  195 + return jjStopAtPos(0, 17);
161 196 case 41:
162   - return jjStopAtPos(0, 16);
  197 + return jjStopAtPos(0, 18);
163 198 case 44:
164   - return jjStopAtPos(0, 24);
  199 + return jjStopAtPos(0, 26);
165 200 case 47:
166   - return jjStopAtPos(0, 19);
  201 + return jjStopAtPos(0, 21);
167 202 case 60:
168   - return jjStopAtPos(0, 11);
  203 + return jjStopAtPos(0, 13);
169 204 case 61:
170   - return jjStopAtPos(0, 26);
  205 + return jjStopAtPos(0, 28);
171 206 case 62:
172   - return jjStopAtPos(0, 12);
  207 + return jjStopAtPos(0, 14);
173 208 case 63:
174   - return jjStopAtPos(0, 20);
  209 + return jjStopAtPos(0, 22);
175 210 case 91:
176   - return jjStopAtPos(0, 13);
  211 + return jjStopAtPos(0, 15);
177 212 case 93:
178   - return jjStopAtPos(0, 14);
  213 + return jjStopAtPos(0, 16);
179 214 case 99:
180 215 return jjMoveStringLiteralDfa1_0(0x20L);
  216 + case 102:
  217 + return jjMoveStringLiteralDfa1_0(0x800L);
181 218 case 105:
182 219 return jjMoveStringLiteralDfa1_0(0x200L);
183 220 case 119:
184 221 return jjMoveStringLiteralDfa1_0(0x80L);
185 222 case 123:
186   - return jjStopAtPos(0, 17);
  223 + return jjStopAtPos(0, 19);
187 224 case 124:
188   - return jjStopAtPos(0, 23);
  225 + return jjStopAtPos(0, 25);
189 226 case 125:
190   - return jjStopAtPos(0, 18);
  227 + return jjStopAtPos(0, 20);
191 228 default :
192 229 return jjMoveNfa_0(1, 0);
193 230 }
... ... @@ -202,17 +239,21 @@ private int jjMoveStringLiteralDfa1_0(long active0)
202 239 switch(curChar)
203 240 {
204 241 case 61:
205   - if ((active0 & 0x2000000L) != 0L)
206   - return jjStopAtPos(1, 25);
  242 + if ((active0 & 0x8000000L) != 0L)
  243 + return jjStopAtPos(1, 27);
207 244 break;
208 245 case 99:
209 246 return jjMoveStringLiteralDfa2_0(active0, 0x40L);
  247 + case 102:
  248 + return jjMoveStringLiteralDfa2_0(active0, 0x1000L);
210 249 case 105:
211 250 return jjMoveStringLiteralDfa2_0(active0, 0x480L);
212 251 case 110:
213 252 return jjMoveStringLiteralDfa2_0(active0, 0x200L);
214 253 case 111:
215 254 return jjMoveStringLiteralDfa2_0(active0, 0x20L);
  255 + case 117:
  256 + return jjMoveStringLiteralDfa2_0(active0, 0x800L);
216 257 case 119:
217 258 return jjMoveStringLiteralDfa2_0(active0, 0x100L);
218 259 default :
... ... @@ -233,12 +274,16 @@ private int jjMoveStringLiteralDfa2_0(long old0, long active0)
233 274 {
234 275 case 105:
235 276 return jjMoveStringLiteralDfa3_0(active0, 0x100L);
  277 + case 108:
  278 + return jjMoveStringLiteralDfa3_0(active0, 0x800L);
236 279 case 110:
237 280 return jjMoveStringLiteralDfa3_0(active0, 0x420L);
238 281 case 111:
239 282 return jjMoveStringLiteralDfa3_0(active0, 0x40L);
240 283 case 116:
241 284 return jjMoveStringLiteralDfa3_0(active0, 0x280L);
  285 + case 117:
  286 + return jjMoveStringLiteralDfa3_0(active0, 0x1000L);
242 287 default :
243 288 break;
244 289 }
... ... @@ -259,6 +304,8 @@ private int jjMoveStringLiteralDfa3_0(long old0, long active0)
259 304 return jjMoveStringLiteralDfa4_0(active0, 0x200L);
260 305 case 104:
261 306 return jjMoveStringLiteralDfa4_0(active0, 0x80L);
  307 + case 108:
  308 + return jjMoveStringLiteralDfa4_0(active0, 0x1800L);
262 309 case 110:
263 310 return jjMoveStringLiteralDfa4_0(active0, 0x40L);
264 311 case 116:
... ... @@ -287,10 +334,14 @@ private int jjMoveStringLiteralDfa4_0(long old0, long active0)
287 334 return jjMoveStringLiteralDfa5_0(active0, 0x100L);
288 335 case 105:
289 336 return jjMoveStringLiteralDfa5_0(active0, 0x80L);
  337 + case 108:
  338 + return jjMoveStringLiteralDfa5_0(active0, 0x1000L);
290 339 case 114:
291 340 return jjMoveStringLiteralDfa5_0(active0, 0x200L);
292 341 case 116:
293 342 return jjMoveStringLiteralDfa5_0(active0, 0x40L);
  343 + case 121:
  344 + return jjMoveStringLiteralDfa5_0(active0, 0x800L);
294 345 default :
295 346 break;
296 347 }
... ... @@ -308,7 +359,7 @@ private int jjMoveStringLiteralDfa5_0(long old0, long active0)
308 359 switch(curChar)
309 360 {
310 361 case 97:
311   - return jjMoveStringLiteralDfa6_0(active0, 0x40L);
  362 + return jjMoveStringLiteralDfa6_0(active0, 0x840L);
312 363 case 105:
313 364 return jjMoveStringLiteralDfa6_0(active0, 0x120L);
314 365 case 110:
... ... @@ -319,6 +370,8 @@ private int jjMoveStringLiteralDfa5_0(long old0, long active0)
319 370 return jjMoveStringLiteralDfa6_0(active0, 0x400L);
320 371 case 115:
321 372 return jjMoveStringLiteralDfa6_0(active0, 0x200L);
  373 + case 121:
  374 + return jjMoveStringLiteralDfa6_0(active0, 0x1000L);
322 375 default :
323 376 break;
324 377 }
... ... @@ -335,10 +388,14 @@ private int jjMoveStringLiteralDfa6_0(long old0, long active0)
335 388 }
336 389 switch(curChar)
337 390 {
  391 + case 97:
  392 + return jjMoveStringLiteralDfa7_0(active0, 0x1000L);
338 393 case 101:
339 394 return jjMoveStringLiteralDfa7_0(active0, 0x200L);
340 395 case 105:
341 396 return jjMoveStringLiteralDfa7_0(active0, 0x40L);
  397 + case 108:
  398 + return jjMoveStringLiteralDfa7_0(active0, 0x800L);
342 399 case 110:
343 400 if ((active0 & 0x100L) != 0L)
344 401 return jjStopAtPos(6, 8);
... ... @@ -366,7 +423,9 @@ private int jjMoveStringLiteralDfa7_0(long old0, long active0)
366 423 case 101:
367 424 return jjMoveStringLiteralDfa8_0(active0, 0x400L);
368 425 case 105:
369   - return jjMoveStringLiteralDfa8_0(active0, 0x20L);
  426 + return jjMoveStringLiteralDfa8_0(active0, 0x820L);
  427 + case 108:
  428 + return jjMoveStringLiteralDfa8_0(active0, 0x1000L);
370 429 case 110:
371 430 return jjMoveStringLiteralDfa8_0(active0, 0x40L);
372 431 default :
... ... @@ -387,8 +446,10 @@ private int jjMoveStringLiteralDfa8_0(long old0, long active0)
387 446 {
388 447 case 99:
389 448 return jjMoveStringLiteralDfa9_0(active0, 0x400L);
  449 + case 103:
  450 + return jjMoveStringLiteralDfa9_0(active0, 0x800L);
390 451 case 105:
391   - return jjMoveStringLiteralDfa9_0(active0, 0x40L);
  452 + return jjMoveStringLiteralDfa9_0(active0, 0x1040L);
392 453 case 110:
393 454 return jjMoveStringLiteralDfa9_0(active0, 0x20L);
394 455 case 116:
... ... @@ -412,11 +473,11 @@ private int jjMoveStringLiteralDfa9_0(long old0, long active0)
412 473 case 103:
413 474 if ((active0 & 0x20L) != 0L)
414 475 return jjStartNfaWithStates_0(9, 5, 8);
415   - break;
  476 + return jjMoveStringLiteralDfa10_0(active0, 0x1000L);
416 477 case 105:
417 478 return jjMoveStringLiteralDfa10_0(active0, 0x200L);
418 479 case 110:
419   - return jjMoveStringLiteralDfa10_0(active0, 0x40L);
  480 + return jjMoveStringLiteralDfa10_0(active0, 0x840L);
420 481 case 116:
421 482 return jjMoveStringLiteralDfa10_0(active0, 0x400L);
422 483 default :
... ... @@ -435,6 +496,8 @@ private int jjMoveStringLiteralDfa10_0(long old0, long active0)
435 496 }
436 497 switch(curChar)
437 498 {
  499 + case 101:
  500 + return jjMoveStringLiteralDfa11_0(active0, 0x800L);
438 501 case 103:
439 502 if ((active0 & 0x40L) != 0L)
440 503 return jjStopAtPos(10, 6);
... ... @@ -442,7 +505,7 @@ private int jjMoveStringLiteralDfa10_0(long old0, long active0)
442 505 case 105:
443 506 return jjMoveStringLiteralDfa11_0(active0, 0x400L);
444 507 case 110:
445   - return jjMoveStringLiteralDfa11_0(active0, 0x200L);
  508 + return jjMoveStringLiteralDfa11_0(active0, 0x1200L);
446 509 default :
447 510 break;
448 511 }
... ... @@ -459,6 +522,10 @@ private int jjMoveStringLiteralDfa11_0(long old0, long active0)
459 522 }
460 523 switch(curChar)
461 524 {
  525 + case 100:
  526 + return jjMoveStringLiteralDfa12_0(active0, 0x800L);
  527 + case 101:
  528 + return jjMoveStringLiteralDfa12_0(active0, 0x1000L);
462 529 case 103:
463 530 if ((active0 & 0x200L) != 0L)
464 531 return jjStartNfaWithStates_0(11, 9, 8);
... ... @@ -481,15 +548,101 @@ private int jjMoveStringLiteralDfa12_0(long old0, long active0)
481 548 }
482 549 switch(curChar)
483 550 {
  551 + case 100:
  552 + return jjMoveStringLiteralDfa13_0(active0, 0x1000L);
484 553 case 103:
485 554 if ((active0 & 0x400L) != 0L)
486 555 return jjStopAtPos(12, 10);
487 556 break;
  557 + case 119:
  558 + return jjMoveStringLiteralDfa13_0(active0, 0x800L);
488 559 default :
489 560 break;
490 561 }
491 562 return jjStartNfa_0(11, active0);
492 563 }
  564 +private int jjMoveStringLiteralDfa13_0(long old0, long active0)
  565 +{
  566 + if (((active0 &= old0)) == 0L)
  567 + return jjStartNfa_0(11, old0);
  568 + try { curChar = input_stream.readChar(); }
  569 + catch(java.io.IOException e) {
  570 + jjStopStringLiteralDfa_0(12, active0);
  571 + return 13;
  572 + }
  573 + switch(curChar)
  574 + {
  575 + case 105:
  576 + return jjMoveStringLiteralDfa14_0(active0, 0x800L);
  577 + case 119:
  578 + return jjMoveStringLiteralDfa14_0(active0, 0x1000L);
  579 + default :
  580 + break;
  581 + }
  582 + return jjStartNfa_0(12, active0);
  583 +}
  584 +private int jjMoveStringLiteralDfa14_0(long old0, long active0)
  585 +{
  586 + if (((active0 &= old0)) == 0L)
  587 + return jjStartNfa_0(12, old0);
  588 + try { curChar = input_stream.readChar(); }
  589 + catch(java.io.IOException e) {
  590 + jjStopStringLiteralDfa_0(13, active0);
  591 + return 14;
  592 + }
  593 + switch(curChar)
  594 + {
  595 + case 105:
  596 + return jjMoveStringLiteralDfa15_0(active0, 0x1000L);
  597 + case 116:
  598 + return jjMoveStringLiteralDfa15_0(active0, 0x800L);
  599 + default :
  600 + break;
  601 + }
  602 + return jjStartNfa_0(13, active0);
  603 +}
  604 +private int jjMoveStringLiteralDfa15_0(long old0, long active0)
  605 +{
  606 + if (((active0 &= old0)) == 0L)
  607 + return jjStartNfa_0(13, old0);
  608 + try { curChar = input_stream.readChar(); }
  609 + catch(java.io.IOException e) {
  610 + jjStopStringLiteralDfa_0(14, active0);
  611 + return 15;
  612 + }
  613 + switch(curChar)
  614 + {
  615 + case 104:
  616 + if ((active0 & 0x800L) != 0L)
  617 + return jjStartNfaWithStates_0(15, 11, 8);
  618 + break;
  619 + case 116:
  620 + return jjMoveStringLiteralDfa16_0(active0, 0x1000L);
  621 + default :
  622 + break;
  623 + }
  624 + return jjStartNfa_0(14, active0);
  625 +}
  626 +private int jjMoveStringLiteralDfa16_0(long old0, long active0)
  627 +{
  628 + if (((active0 &= old0)) == 0L)
  629 + return jjStartNfa_0(14, old0);
  630 + try { curChar = input_stream.readChar(); }
  631 + catch(java.io.IOException e) {
  632 + jjStopStringLiteralDfa_0(15, active0);
  633 + return 16;
  634 + }
  635 + switch(curChar)
  636 + {
  637 + case 104:
  638 + if ((active0 & 0x1000L) != 0L)
  639 + return jjStopAtPos(16, 12);
  640 + break;
  641 + default :
  642 + break;
  643 + }
  644 + return jjStartNfa_0(15, active0);
  645 +}
493 646 private int jjStartNfaWithStates_0(int pos, int kind, int state)
494 647 {
495 648 jjmatchedKind = kind;
... ... @@ -525,14 +678,14 @@ private int jjMoveNfa_0(int startState, int curPos)
525 678 case 1:
526 679 if ((0x3ff600000000000L & l) != 0L)
527 680 {
528   - if (kind > 30)
529   - kind = 30;
  681 + if (kind > 32)
  682 + kind = 32;
530 683 jjCheckNAdd(8);
531 684 }
532 685 else if (curChar == 35)
533 686 {
534   - if (kind > 31)
535   - kind = 31;
  687 + if (kind > 33)
  688 + kind = 33;
536 689 }
537 690 else if (curChar == 34)
538 691 jjCheckNAddStates(0, 2);
... ... @@ -540,23 +693,23 @@ private int jjMoveNfa_0(int startState, int curPos)
540 693 jjCheckNAdd(2);
541 694 if ((0x3ff000000000000L & l) != 0L)
542 695 {
543   - if (kind > 27)
544   - kind = 27;
  696 + if (kind > 29)
  697 + kind = 29;
545 698 jjCheckNAdd(0);
546 699 }
547 700 break;
548 701 case 0:
549 702 if ((0x3ff000000000000L & l) == 0L)
550 703 break;
551   - if (kind > 27)
552   - kind = 27;
  704 + if (kind > 29)
  705 + kind = 29;
553 706 jjCheckNAdd(0);
554 707 break;
555 708 case 2:
556 709 if ((0x3ff600000000000L & l) == 0L)
557 710 break;
558   - if (kind > 28)
559   - kind = 28;
  711 + if (kind > 30)
  712 + kind = 30;
560 713 jjCheckNAdd(2);
561 714 break;
562 715 case 3:
... ... @@ -571,19 +724,19 @@ private int jjMoveNfa_0(int startState, int curPos)
571 724 jjCheckNAddStates(0, 2);
572 725 break;
573 726 case 7:
574   - if (curChar == 34 && kind > 29)
575   - kind = 29;
  727 + if (curChar == 34 && kind > 31)
  728 + kind = 31;
576 729 break;
577 730 case 8:
578 731 if ((0x3ff600000000000L & l) == 0L)
579 732 break;
580   - if (kind > 30)
581   - kind = 30;
  733 + if (kind > 32)
  734 + kind = 32;
582 735 jjCheckNAdd(8);
583 736 break;
584 737 case 9:
585   - if (curChar == 35 && kind > 31)
586   - kind = 31;
  738 + if (curChar == 35 && kind > 33)
  739 + kind = 33;
587 740 break;
588 741 default : break;
589 742 }
... ... @@ -600,15 +753,15 @@ private int jjMoveNfa_0(int startState, int curPos)
600 753 case 8:
601 754 if ((0x7fffffe87fffffeL & l) == 0L)
602 755 break;
603   - if (kind > 30)
604   - kind = 30;
  756 + if (kind > 32)
  757 + kind = 32;
605 758 jjCheckNAdd(8);
606 759 break;
607 760 case 2:
608 761 if ((0x7fffffe87fffffeL & l) == 0L)
609 762 break;
610   - if (kind > 28)
611   - kind = 28;
  763 + if (kind > 30)
  764 + kind = 30;
612 765 jjstateSet[jjnewStateCnt++] = 2;
613 766 break;
614 767 case 4:
... ... @@ -679,16 +832,17 @@ private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, lo
679 832 public static final String[] jjstrLiteralImages = {
680 833 "", null, null, null, null, "\143\157\156\164\141\151\156\151\156\147",
681 834 "\41\143\157\156\164\141\151\156\151\156\147", "\167\151\164\150\151\156", "\41\167\151\164\150\151\156",
682   -"\151\156\164\145\162\163\145\143\164\151\156\147", "\41\151\156\164\145\162\163\145\143\164\151\156\147", "\74", "\76", "\133",
683   -"\135", "\50", "\51", "\173", "\175", "\57", "\77", "\41", "\46", "\174", "\54",
684   -"\41\75", "\75", null, null, null, null, null, null, null, };
  835 +"\151\156\164\145\162\163\145\143\164\151\156\147", "\41\151\156\164\145\162\163\145\143\164\151\156\147",
  836 +"\146\165\154\154\171\141\154\151\147\156\145\144\167\151\164\150", "\41\146\165\154\154\171\141\154\151\147\156\145\144\167\151\164\150", "\74",
  837 +"\76", "\133", "\135", "\50", "\51", "\173", "\175", "\57", "\77", "\41", "\46",
  838 +"\174", "\54", "\41\75", "\75", null, null, null, null, null, null, null, };
685 839  
686 840 /** Lexer state names. */
687 841 public static final String[] lexStateNames = {
688 842 "DEFAULT",
689 843 };
690 844 static final long[] jjtoToken = {
691   - 0xffffffe1L,
  845 + 0x3ffffffe1L,
692 846 };
693 847 static final long[] jjtoSkip = {
694 848 0x1eL,
... ...
src/mtas/parser/cql/util/MtasCQLParserGroupQuery.java
... ... @@ -41,6 +41,7 @@ public class MtasCQLParserGroupQuery extends MtasSpanQuery {
41 41 * @param prefix the prefix
42 42 */
43 43 public MtasCQLParserGroupQuery(String field, String prefix) {
  44 + super(null,null);
44 45 term = new Term(field, prefix + MtasToken.DELIMITER);
45 46 query = new MtasSpanPrefixQuery(term, false);
46 47 }
... ... @@ -66,6 +67,7 @@ public class MtasCQLParserGroupQuery extends MtasSpanQuery {
66 67 */
67 68 public MtasCQLParserGroupQuery(String field, String prefix, String value,
68 69 String type) {
  70 + super(null,null);
69 71 if (value == null || value.trim().equals("")) {
70 72 term = new Term(field, prefix + MtasToken.DELIMITER);
71 73 query = new MtasSpanPrefixQuery(term, false);
... ...
src/mtas/parser/cql/util/MtasCQLParserWordPositionQuery.java
... ... @@ -28,6 +28,7 @@ public class MtasCQLParserWordPositionQuery extends MtasSpanQuery {
28 28 * @param position the position
29 29 */
30 30 public MtasCQLParserWordPositionQuery(String field, int position) {
  31 + super(1,1);
31 32 term = new Term(field);
32 33 query = new MtasSpanPositionQuery(field, position);
33 34 }
... ... @@ -40,6 +41,7 @@ public class MtasCQLParserWordPositionQuery extends MtasSpanQuery {
40 41 * @param end the end
41 42 */
42 43 public MtasCQLParserWordPositionQuery(String field, int start, int end) {
  44 + super(1,1);
43 45 term = new Term(field);
44 46 query = new MtasSpanPositionQuery(field, start, end);
45 47 }
... ...
src/mtas/parser/cql/util/MtasCQLParserWordQuery.java
... ... @@ -50,6 +50,7 @@ public class MtasCQLParserWordQuery extends MtasSpanQuery {
50 50 */
51 51 public MtasCQLParserWordQuery(String field, String prefix,
52 52 HashMap<String, String[]> variables) {
  53 + super(1,1);
53 54 term = new Term(field, prefix + MtasToken.DELIMITER);
54 55 query = new MtasSpanPrefixQuery(term, true);
55 56 }
... ... @@ -84,6 +85,7 @@ public class MtasCQLParserWordQuery extends MtasSpanQuery {
84 85 public MtasCQLParserWordQuery(String field, String prefix, String value,
85 86 String type, HashMap<String, String[]> variables,
86 87 HashSet<String> usedVariables) throws ParseException {
  88 + super(1,1);
87 89 String termBase = prefix + MtasToken.DELIMITER + value;
88 90 if (type.equals(MTAS_CQL_REGEXP_QUERY)) {
89 91 term = new Term(field, termBase + "\u0000*");
... ...
src/mtas/search/spans/MtasSpanAndQuery.java
... ... @@ -20,7 +20,7 @@ public class MtasSpanAndQuery extends MtasSpanQuery {
20 20 /** The base query. */
21 21 private SpanNearQuery baseQuery;
22 22 private List<MtasSpanQuery> clauses;
23   -
  23 +
24 24 /**
25 25 * Instantiates a new mtas span and query.
26 26 *
... ... @@ -29,13 +29,25 @@ public class MtasSpanAndQuery extends MtasSpanQuery {
29 29 * @throws IOException
30 30 */
31 31 public MtasSpanAndQuery(MtasSpanQuery... initialClauses) {
32   - super();
  32 + super(null, null);
  33 + Integer minimum = null, maximum = null;
33 34 clauses = new ArrayList<MtasSpanQuery>();
34   - for(MtasSpanQuery item : initialClauses) {
35   - if(!clauses.contains(item)) {
  35 + for (MtasSpanQuery item : initialClauses) {
  36 + if (!clauses.contains(item)) {
36 37 clauses.add(item);
  38 + if (item.getMinimumWidth() != null) {
  39 + minimum = (minimum != null)
  40 + ? Math.max(minimum, item.getMinimumWidth())
  41 + : item.getMinimumWidth();
  42 + }
  43 + if (item.getMaximumWidth() != null) {
  44 + maximum = (maximum != null)
  45 + ? Math.min(maximum, item.getMaximumWidth())
  46 + : item.getMaximumWidth();
  47 + }
37 48 }
38   - }
  49 + }
  50 + setWidth(minimum, maximum);
39 51 baseQuery = new MtasExtendedSpanAndQuery(
40 52 clauses.toArray(new MtasSpanQuery[clauses.size()]));
41 53 }
... ... @@ -58,29 +70,68 @@ public class MtasSpanAndQuery extends MtasSpanQuery {
58 70 * search.IndexSearcher, boolean)
59 71 */
60 72 @Override
61   - public SpanWeight createWeight(IndexSearcher searcher,
62   - boolean needsScores) throws IOException {
63   - return baseQuery.createWeight(searcher, needsScores);
  73 + public SpanWeight createWeight(IndexSearcher searcher, boolean needsScores)
  74 + throws IOException {
  75 + return baseQuery.createWeight(searcher, needsScores);
64 76 }
65 77  
66 78 @Override
67 79 public MtasSpanQuery rewrite(IndexReader reader) throws IOException {
68 80 if (clauses.size() > 1) {
  81 + // rewrite, count MtasSpanMatchAllQuery and check for MtasSpanMatchNoneQuery
69 82 MtasSpanQuery[] newClauses = new MtasSpanQuery[clauses.size()];
  83 + int singlePositionQueries = 0;
  84 + int matchAllSinglePositionQueries = 0;
70 85 boolean actuallyRewritten = false;
71 86 for (int i = 0; i < clauses.size(); i++) {
72 87 newClauses[i] = clauses.get(i).rewrite(reader);
73 88 actuallyRewritten |= clauses.get(i) != newClauses[i];
  89 + if (newClauses[i] instanceof MtasSpanMatchNoneQuery) {
  90 + return (new MtasSpanMatchNoneQuery(this.getField())).rewrite(reader);
  91 + } else {
  92 + if (newClauses[i].isSinglePositionQuery()) {
  93 + singlePositionQueries++;
  94 + if (newClauses[i] instanceof MtasSpanMatchAllQuery) {
  95 + matchAllSinglePositionQueries++;
  96 + }
  97 + }
  98 + }
74 99 }
75   - if (actuallyRewritten) {
  100 + // filter clauses
  101 + if (matchAllSinglePositionQueries > 0) {
  102 + // compute new number of clauses
  103 + int newNumber = newClauses.length - matchAllSinglePositionQueries;
  104 + if (matchAllSinglePositionQueries == singlePositionQueries) {
  105 + newNumber++;
  106 + }
  107 + MtasSpanQuery[] newFilteredClauses = new MtasSpanQuery[newNumber];
  108 + int j = 0;
  109 + for (int i = 0; i < newClauses.length; i++) {
  110 + if (!(newClauses[i].isSinglePositionQuery()
  111 + && (newClauses[i] instanceof MtasSpanMatchAllQuery))) {
  112 + newFilteredClauses[j] = newClauses[i];
  113 + j++;
  114 + } else if (matchAllSinglePositionQueries == singlePositionQueries) {
  115 + newFilteredClauses[j] = newClauses[i];
  116 + j++;
  117 + singlePositionQueries++; // only match this condition once
  118 + }
  119 + }
  120 + newClauses = newFilteredClauses;
  121 + }
  122 + if (newClauses.length == 0) {
  123 + return (new MtasSpanMatchNoneQuery(this.getField())).rewrite(reader);
  124 + } else if(newClauses.length==1) {
  125 + return newClauses[0].rewrite(reader);
  126 + } else if(actuallyRewritten || newClauses.length!=clauses.size()) {
76 127 return new MtasSpanAndQuery(newClauses).rewrite(reader);
77 128 } else {
78 129 return super.rewrite(reader);
79   - }
80   - } else if(clauses.size()==1) {
81   - return clauses.get(0).rewrite(reader);
  130 + }
  131 + } else if (clauses.size() == 1) {
  132 + return clauses.get(0).rewrite(reader);
82 133 } else {
83   - return super.rewrite(reader);
  134 + return (new MtasSpanMatchNoneQuery(this.getField())).rewrite(reader);
84 135 }
85 136 }
86 137  
... ...
src/mtas/search/spans/MtasSpanContainingQuery.java
... ... @@ -6,6 +6,9 @@ import org.apache.lucene.index.IndexReader;
6 6 import org.apache.lucene.search.IndexSearcher;
7 7 import org.apache.lucene.search.spans.SpanContainingQuery;
8 8 import org.apache.lucene.search.spans.SpanWeight;
  9 +
  10 +import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIFactoryMethod;
  11 +
9 12 import mtas.search.spans.util.MtasSpanQuery;
10 13  
11 14 /**
... ... @@ -15,7 +18,8 @@ public class MtasSpanContainingQuery extends MtasSpanQuery {
15 18  
16 19 /** The base query. */
17 20 private SpanContainingQuery baseQuery;
18   -
  21 + private MtasSpanQuery bigQuery, smallQuery;
  22 +
19 23 /**
20 24 * Instantiates a new mtas span containing query.
21 25 *
... ... @@ -23,8 +27,15 @@ public class MtasSpanContainingQuery extends MtasSpanQuery {
23 27 * @param q2 the q2
24 28 */
25 29 public MtasSpanContainingQuery(MtasSpanQuery q1, MtasSpanQuery q2) {
26   - super();
27   - baseQuery = new SpanContainingQuery(q1, q2);
  30 + super(q1!=null?q1.getMinimumWidth():null, q1!=null?q1.getMaximumWidth():null);
  31 + if(q2!=null && q2.getMinimumWidth()!=null) {
  32 + if(this.getMinimumWidth()==null || this.getMinimumWidth()<q2.getMinimumWidth()) {
  33 + this.setWidth(q2.getMinimumWidth(), this.getMaximumWidth());
  34 + }
  35 + }
  36 + bigQuery=q1;
  37 + smallQuery=q2;
  38 + baseQuery = new SpanContainingQuery(bigQuery, smallQuery);
28 39 }
29 40  
30 41 /*
... ... @@ -68,8 +79,16 @@ public class MtasSpanContainingQuery extends MtasSpanQuery {
68 79 */
69 80 @Override
70 81 public MtasSpanQuery rewrite(IndexReader reader) throws IOException {
71   - baseQuery = (SpanContainingQuery) baseQuery.rewrite(reader);
72   - return this;
  82 + MtasSpanQuery newBigQuery = bigQuery.rewrite(reader);
  83 + MtasSpanQuery newSmallQuery = smallQuery.rewrite(reader);
  84 + if(newBigQuery!=bigQuery || newSmallQuery!=smallQuery) {
  85 + return new MtasSpanContainingQuery(newBigQuery, newSmallQuery).rewrite(reader);
  86 + } else if(newBigQuery!=null && newSmallQuery!=null && newBigQuery.equals(newSmallQuery)) {
  87 + return newBigQuery;
  88 + } else {
  89 + baseQuery = (SpanContainingQuery) baseQuery.rewrite(reader);
  90 + return super.rewrite(reader);
  91 + }
73 92 }
74 93  
75 94 /*
... ...
src/mtas/search/spans/MtasSpanEndQuery.java
... ... @@ -22,7 +22,7 @@ import mtas.search.spans.util.MtasSpanQuery;
22 22 public class MtasSpanEndQuery extends MtasSpanQuery {
23 23  
24 24 /** The query. */
25   - private MtasSpanQuery query;
  25 + private MtasSpanQuery clause;
26 26  
27 27 /**
28 28 * Instantiates a new mtas span end query.
... ... @@ -31,8 +31,8 @@ public class MtasSpanEndQuery extends MtasSpanQuery {
31 31 * the query
32 32 */
33 33 public MtasSpanEndQuery(MtasSpanQuery query) {
34   - super();
35   - this.query = query;
  34 + super(0,0);
  35 + clause = query;
36 36 }
37 37  
38 38 /*
... ... @@ -43,8 +43,14 @@ public class MtasSpanEndQuery extends MtasSpanQuery {
43 43 */
44 44 @Override
45 45 public MtasSpanQuery rewrite(IndexReader reader) throws IOException {
46   - query = query.rewrite(reader);
47   - return this;
  46 + MtasSpanQuery newClause = clause.rewrite(reader);
  47 + if(newClause!=clause) {
  48 + return new MtasSpanEndQuery(newClause).rewrite(reader);
  49 + } else if(newClause.getMaximumWidth()!=null && newClause.getMaximumWidth()==0) {
  50 + return newClause;
  51 + } else {
  52 + return super.rewrite(reader);
  53 + }
48 54 }
49 55  
50 56 /*
... ... @@ -57,7 +63,7 @@ public class MtasSpanEndQuery extends MtasSpanQuery {
57 63 public String toString(String field) {
58 64 StringBuilder buffer = new StringBuilder();
59 65 buffer.append(this.getClass().getSimpleName() + "([");
60   - buffer.append(this.query.toString(field));
  66 + buffer.append(clause.toString(field));
61 67 buffer.append("])");
62 68 return buffer.toString();
63 69 }
... ... @@ -69,7 +75,7 @@ public class MtasSpanEndQuery extends MtasSpanQuery {
69 75 */
70 76 @Override
71 77 public String getField() {
72   - return query.getField();
  78 + return clause.getField();
73 79 }
74 80  
75 81 /*
... ... @@ -82,10 +88,11 @@ public class MtasSpanEndQuery extends MtasSpanQuery {
82 88 @Override
83 89 public SpanWeight createWeight(IndexSearcher searcher, boolean needsScores)
84 90 throws IOException {
85   - SpanWeight spanWeight = ((SpanQuery) searcher.rewrite(query))
  91 + SpanWeight spanWeight = ((SpanQuery) searcher.rewrite(clause))
86 92 .createWeight(searcher, needsScores);
87 93 return new SpanTermWeight(spanWeight, searcher);
88 94 }
  95 +
89 96  
90 97 /**
91 98 * The Class SpanTermWeight.
... ... @@ -163,7 +170,7 @@ public class MtasSpanEndQuery extends MtasSpanQuery {
163 170 if (getClass() != obj.getClass())
164 171 return false;
165 172 final MtasSpanEndQuery that = (MtasSpanEndQuery) obj;
166   - return query.equals(that.query);
  173 + return clause.equals(that.clause);
167 174 }
168 175  
169 176 /*
... ... @@ -174,7 +181,7 @@ public class MtasSpanEndQuery extends MtasSpanQuery {
174 181 @Override
175 182 public int hashCode() {
176 183 int h = this.getClass().getSimpleName().hashCode();
177   - h = (h * 7) ^ query.hashCode();
  184 + h = (h * 7) ^ clause.hashCode();
178 185 return h;
179 186 }
180 187  
... ...
src/mtas/search/spans/MtasSpanFullyAlignedWithQuery.java 0 โ†’ 100644
  1 +package mtas.search.spans;
  2 +
  3 +import java.io.IOException;
  4 +import java.util.ArrayList;
  5 +import java.util.List;
  6 +import java.util.Map;
  7 +import java.util.Set;
  8 +
  9 +import org.apache.lucene.index.IndexReader;
  10 +import org.apache.lucene.index.LeafReaderContext;
  11 +import org.apache.lucene.index.Term;
  12 +import org.apache.lucene.index.TermContext;
  13 +import org.apache.lucene.index.Terms;
  14 +import org.apache.lucene.search.IndexSearcher;
  15 +import org.apache.lucene.search.spans.SpanQuery;
  16 +import org.apache.lucene.search.spans.SpanWeight;
  17 +import org.apache.lucene.search.spans.Spans;
  18 +import mtas.search.spans.util.MtasSpanQuery;
  19 +
  20 +/**
  21 + * The Class MtasSpanFullyAlignedWithQuery.
  22 + */
  23 +public class MtasSpanFullyAlignedWithQuery extends MtasSpanQuery {
  24 +
  25 + /** The field. */
  26 + private String field;
  27 +
  28 + /** The q 2. */
  29 + private SpanQuery q1, q2;
  30 +
  31 + /**
  32 + * Instantiates a new mtas span fully aligned with query.
  33 + *
  34 + * @param q1 the q 1
  35 + * @param q2 the q 2
  36 + */
  37 + public MtasSpanFullyAlignedWithQuery(MtasSpanQuery q1, MtasSpanQuery q2) {
  38 + super(q1 != null ? q1.getMinimumWidth() : null,
  39 + q1 != null ? q1.getMaximumWidth() : null);
  40 + if (q1 != null && (field = q1.getField()) != null) {
  41 + if (q2 != null && ((field == null && q2.getField() != null)
  42 + || !q2.getField().equals(field))) {
  43 + throw new IllegalArgumentException("Clauses must have same field.");
  44 + }
  45 + } else if (q2 != null) {
  46 + field = q2.getField();
  47 + } else {
  48 + field = null;
  49 + }
  50 + this.q1 = q1;
  51 + this.q2 = q2;
  52 + }
  53 +
  54 + /*
  55 + * (non-Javadoc)
  56 + *
  57 + * @see org.apache.lucene.search.spans.SpanQuery#getField()
  58 + */
  59 + @Override
  60 + public String getField() {
  61 + return field;
  62 + }
  63 +
  64 + /*
  65 + * (non-Javadoc)
  66 + *
  67 + * @see
  68 + * org.apache.lucene.search.spans.SpanQuery#createWeight(org.apache.lucene.
  69 + * search.IndexSearcher, boolean)
  70 + */
  71 + @Override
  72 + public SpanWeight createWeight(IndexSearcher searcher, boolean needsScores)
  73 + throws IOException {
  74 + if (q1 == null || q2 == null) {
  75 + return null;
  76 + } else {
  77 + MtasSpanFullyAlignedWithQueryWeight w1 = new MtasSpanFullyAlignedWithQueryWeight(
  78 + q1.createWeight(searcher, needsScores));
  79 + MtasSpanFullyAlignedWithQueryWeight w2 = new MtasSpanFullyAlignedWithQueryWeight(
  80 + q2.createWeight(searcher, needsScores));
  81 + // subWeights
  82 + List<MtasSpanFullyAlignedWithQueryWeight> subWeights = new ArrayList<MtasSpanFullyAlignedWithQueryWeight>();
  83 + subWeights.add(w1);
  84 + subWeights.add(w2);
  85 + // return
  86 + return new SpanFullyAlignedWithWeight(w1, w2, searcher,
  87 + needsScores ? getTermContexts(subWeights) : null);
  88 + }
  89 + }
  90 +
  91 + /**
  92 + * Gets the term contexts.
  93 + *
  94 + * @param items the items
  95 + * @return the term contexts
  96 + */
  97 + protected Map<Term, TermContext> getTermContexts(
  98 + List<MtasSpanFullyAlignedWithQueryWeight> items) {
  99 + List<SpanWeight> weights = new ArrayList<SpanWeight>();
  100 + for (MtasSpanFullyAlignedWithQueryWeight item : items) {
  101 + weights.add(item.spanWeight);
  102 + }
  103 + return getTermContexts(weights);
  104 + }
  105 +
  106 + /*
  107 + * (non-Javadoc)
  108 + *
  109 + * @see org.apache.lucene.search.Query#toString(java.lang.String)
  110 + */
  111 + @Override
  112 + public String toString(String field) {
  113 + StringBuilder buffer = new StringBuilder();
  114 + buffer.append(this.getClass().getSimpleName() + "([");
  115 + if (q1 != null) {
  116 + buffer.append(q1.toString(q1.getField()));
  117 + } else {
  118 + buffer.append("null");
  119 + }
  120 + buffer.append(",");
  121 + if (q2 != null) {
  122 + buffer.append(q2.toString(q2.getField()));
  123 + } else {
  124 + buffer.append("null");
  125 + }
  126 + buffer.append("])");
  127 + return buffer.toString();
  128 + }
  129 +
  130 + /*
  131 + * (non-Javadoc)
  132 + *
  133 + * @see org.apache.lucene.search.Query#equals(java.lang.Object)
  134 + */
  135 + @Override
  136 + public boolean equals(Object obj) {
  137 + if (this == obj)
  138 + return true;
  139 + if (obj == null)
  140 + return false;
  141 + if (getClass() != obj.getClass())
  142 + return false;
  143 + final MtasSpanFullyAlignedWithQuery other = (MtasSpanFullyAlignedWithQuery) obj;
  144 + return q1.equals(other.q1) && q2.equals(other.q2);
  145 + }
  146 +
  147 + /*
  148 + * (non-Javadoc)
  149 + *
  150 + * @see org.apache.lucene.search.Query#hashCode()
  151 + */
  152 + @Override
  153 + public int hashCode() {
  154 + int h = Integer.rotateLeft(classHash(), 1);
  155 + h ^= q1.hashCode();
  156 + h = Integer.rotateLeft(h, 1);
  157 + h ^= q2.hashCode();
  158 + return h;
  159 + }
  160 +
  161 + /*
  162 + * (non-Javadoc)
  163 + *
  164 + * @see mtas.search.spans.util.MtasSpanQuery#rewrite(org.apache.lucene.index.
  165 + * IndexReader)
  166 + */
  167 + @Override
  168 + public MtasSpanQuery rewrite(IndexReader reader) throws IOException {
  169 + MtasSpanQuery newQ1 = (MtasSpanQuery) q1.rewrite(reader);
  170 + MtasSpanQuery newQ2 = (MtasSpanQuery) q2.rewrite(reader);
  171 + if (newQ1 != q1 || newQ2 != q2) {
  172 + return new MtasSpanFullyAlignedWithQuery(newQ1, newQ2).rewrite(reader);
  173 + } else if (newQ1 == null || newQ2 == null) {
  174 + return new MtasSpanMatchNoneQuery(this.getField());
  175 + } else if(newQ1.equals(newQ2)) {
  176 + return newQ1;
  177 + } else if (newQ1.getMaximumWidth() != null
  178 + && newQ1.getMaximumWidth() == 0) {
  179 + return new MtasSpanMatchNoneQuery(this.getField());
  180 + } else if (newQ2.getMaximumWidth() != null
  181 + && newQ2.getMaximumWidth() == 0) {
  182 + return new MtasSpanMatchNoneQuery(this.getField());
  183 + } else if(newQ1.getMinimumWidth()!=null && newQ2.getMaximumWidth()!=null && newQ1.getMinimumWidth()>newQ2.getMaximumWidth()) {
  184 + return new MtasSpanMatchNoneQuery(this.getField());
  185 + } else if(newQ2.getMinimumWidth()!=null && newQ1.getMaximumWidth()!=null && newQ2.getMinimumWidth()>newQ1.getMaximumWidth()) {
  186 + return new MtasSpanMatchNoneQuery(this.getField());
  187 + } else {
  188 + return super.rewrite(reader);
  189 + }
  190 + }
  191 +
  192 + /**
  193 + * The Class SpanIntersectingWeight.
  194 + */
  195 + public class SpanFullyAlignedWithWeight extends SpanWeight {
  196 +
  197 + /** The w 2. */
  198 + MtasSpanFullyAlignedWithQueryWeight w1, w2;
  199 +
  200 + /**
  201 + * Instantiates a new span intersecting weight.
  202 + *
  203 + * @param w1 the w 1
  204 + * @param w2 the w 2
  205 + * @param searcher the searcher
  206 + * @param terms the terms
  207 + * @throws IOException Signals that an I/O exception has occurred.
  208 + */
  209 + public SpanFullyAlignedWithWeight(MtasSpanFullyAlignedWithQueryWeight w1,
  210 + MtasSpanFullyAlignedWithQueryWeight w2, IndexSearcher searcher,
  211 + Map<Term, TermContext> terms) throws IOException {
  212 + super(MtasSpanFullyAlignedWithQuery.this, searcher, terms);
  213 + this.w1 = w1;
  214 + this.w2 = w2;
  215 + }
  216 +
  217 + /*
  218 + * (non-Javadoc)
  219 + *
  220 + * @see
  221 + * org.apache.lucene.search.spans.SpanWeight#extractTermContexts(java.util.
  222 + * Map)
  223 + */
  224 + @Override
  225 + public void extractTermContexts(Map<Term, TermContext> contexts) {
  226 + w1.spanWeight.extractTermContexts(contexts);
  227 + w2.spanWeight.extractTermContexts(contexts);
  228 + }
  229 +
  230 + /*
  231 + * (non-Javadoc)
  232 + *
  233 + * @see
  234 + * org.apache.lucene.search.spans.SpanWeight#getSpans(org.apache.lucene.
  235 + * index.LeafReaderContext,
  236 + * org.apache.lucene.search.spans.SpanWeight.Postings)
  237 + */
  238 + @Override
  239 + public Spans getSpans(LeafReaderContext context, Postings requiredPostings)
  240 + throws IOException {
  241 + Terms terms = context.reader().terms(field);
  242 + if (terms == null) {
  243 + return null; // field does not exist
  244 + }
  245 + MtasSpanFullyAlignedWithQuerySpans s1 = new MtasSpanFullyAlignedWithQuerySpans(
  246 + w1.spanWeight.getSpans(context, requiredPostings));
  247 + MtasSpanFullyAlignedWithQuerySpans s2 = new MtasSpanFullyAlignedWithQuerySpans(
  248 + w2.spanWeight.getSpans(context, requiredPostings));
  249 + return new MtasSpanFullyAlignedWithSpans(MtasSpanFullyAlignedWithQuery.this, s1,
  250 + s2);
  251 + }
  252 +
  253 + /*
  254 + * (non-Javadoc)
  255 + *
  256 + * @see org.apache.lucene.search.Weight#extractTerms(java.util.Set)
  257 + */
  258 + @Override
  259 + public void extractTerms(Set<Term> terms) {
  260 + w1.spanWeight.extractTerms(terms);
  261 + w2.spanWeight.extractTerms(terms);
  262 + }
  263 +
  264 + }
  265 +
  266 + /**
  267 + * The Class MtasSpanIntersectingQuerySpans.
  268 + */
  269 + public class MtasSpanFullyAlignedWithQuerySpans {
  270 +
  271 + /** The spans. */
  272 + public Spans spans;
  273 +
  274 + /**
  275 + * Instantiates a new mtas span intersecting query spans.
  276 + *
  277 + * @param spans the spans
  278 + */
  279 + public MtasSpanFullyAlignedWithQuerySpans(Spans spans) {
  280 + this.spans = spans;
  281 + }
  282 +
  283 + }
  284 +
  285 + /**
  286 + * The Class MtasSpanIntersectingQueryWeight.
  287 + */
  288 + public class MtasSpanFullyAlignedWithQueryWeight {
  289 +
  290 + /** The span weight. */
  291 + public SpanWeight spanWeight;
  292 +
  293 + /**
  294 + * Instantiates a new mtas span intersecting query weight.
  295 + *
  296 + * @param spanWeight the span weight
  297 + */
  298 + public MtasSpanFullyAlignedWithQueryWeight(SpanWeight spanWeight) {
  299 + this.spanWeight = spanWeight;
  300 + }
  301 + }
  302 +
  303 +}
... ...
src/mtas/search/spans/MtasSpanFullyAlignedWithSpans.java 0 โ†’ 100644
  1 +package mtas.search.spans;
  2 +
  3 +import java.io.IOException;
  4 +import java.util.HashSet;
  5 +
  6 +import org.apache.lucene.search.spans.SpanCollector;
  7 +import org.apache.lucene.search.spans.Spans;
  8 +
  9 +import mtas.search.spans.MtasSpanFullyAlignedWithQuery.MtasSpanFullyAlignedWithQuerySpans;
  10 +import mtas.search.spans.util.MtasSpans;
  11 +
  12 +/**
  13 + * The Class MtasSpanIntersectingSpans.
  14 + */
  15 +public class MtasSpanFullyAlignedWithSpans extends Spans implements MtasSpans {
  16 +
  17 + /** The spans2. */
  18 + private MtasSpanFullyAlignedWithQuerySpans spans1, spans2;
  19 +
  20 + /** The last spans2 end position. */
  21 + private int lastSpans2StartPosition, lastSpans2EndPosition,
  22 + previousSpans2StartPosition;
  23 + private HashSet<Integer> previousSpans2EndPositions;
  24 +
  25 + /** The no more positions. */
  26 + private boolean calledNextStartPosition, noMorePositions;
  27 +
  28 + /** The doc id. */
  29 + private int docId;
  30 +
  31 + /**
  32 + * Instantiates a new mtas span intersecting spans.
  33 + *
  34 + * @param mtasSpanFullyAlignedWithQuery
  35 + * the mtas span intersecting query
  36 + * @param spans1
  37 + * the spans1
  38 + * @param spans2
  39 + * the spans2
  40 + */
  41 + public MtasSpanFullyAlignedWithSpans(
  42 + MtasSpanFullyAlignedWithQuery mtasSpanFullyAlignedWithQuery,
  43 + MtasSpanFullyAlignedWithQuerySpans spans1,
  44 + MtasSpanFullyAlignedWithQuerySpans spans2) {
  45 + super();
  46 + docId = -1;
  47 + this.spans1 = spans1;
  48 + this.spans2 = spans2;
  49 + previousSpans2EndPositions = new HashSet<Integer>();
  50 + }
  51 +
  52 + /*
  53 + * (non-Javadoc)
  54 + *
  55 + * @see org.apache.lucene.search.spans.Spans#nextStartPosition()
  56 + */
  57 + @Override
  58 + public int nextStartPosition() throws IOException {
  59 + // no document
  60 + if (docId == -1 || docId == NO_MORE_DOCS) {
  61 + throw new IOException("no document");
  62 + // finished
  63 + } else if (noMorePositions) {
  64 + return NO_MORE_POSITIONS;
  65 + // littleSpans already at start match, because of check for matching
  66 + // document
  67 + } else if (!calledNextStartPosition) {
  68 + calledNextStartPosition = true;
  69 + return spans1.spans.startPosition();
  70 + // compute next match
  71 + } else {
  72 + if (goToNextStartPosition()) {
  73 + // match found
  74 + return spans1.spans.startPosition();
  75 + } else {
  76 + // no more matches: document finished
  77 + return NO_MORE_POSITIONS;
  78 + }
  79 + }
  80 + }
  81 +
  82 + /*
  83 + * (non-Javadoc)
  84 + *
  85 + * @see org.apache.lucene.search.spans.Spans#startPosition()
  86 + */
  87 + @Override
  88 + public int startPosition() {
  89 + return calledNextStartPosition
  90 + ? (noMorePositions ? NO_MORE_POSITIONS : spans1.spans.startPosition())
  91 + : -1;
  92 + }
  93 +
  94 + /*
  95 + * (non-Javadoc)
  96 + *
  97 + * @see org.apache.lucene.search.spans.Spans#endPosition()
  98 + */
  99 + @Override
  100 + public int endPosition() {
  101 + return calledNextStartPosition
  102 + ? (noMorePositions ? NO_MORE_POSITIONS : spans1.spans.endPosition())
  103 + : -1;
  104 + }
  105 +
  106 + /*
  107 + * (non-Javadoc)
  108 + *
  109 + * @see org.apache.lucene.search.spans.Spans#width()
  110 + */
  111 + @Override
  112 + public int width() {
  113 + return calledNextStartPosition ? (noMorePositions ? 0
  114 + : spans1.spans.endPosition() - spans1.spans.startPosition()) : 0;
  115 + }
  116 +
  117 + /*
  118 + * (non-Javadoc)
  119 + *
  120 + * @see
  121 + * org.apache.lucene.search.spans.Spans#collect(org.apache.lucene.search.spans
  122 + * .SpanCollector)
  123 + */
  124 + @Override
  125 + public void collect(SpanCollector collector) throws IOException {
  126 + spans1.spans.collect(collector);
  127 + spans2.spans.collect(collector);
  128 + }
  129 +
  130 + /*
  131 + * (non-Javadoc)
  132 + *
  133 + * @see org.apache.lucene.search.spans.Spans#positionsCost()
  134 + */
  135 + @Override
  136 + public float positionsCost() {
  137 + return 0;
  138 + }
  139 +
  140 + /*
  141 + * (non-Javadoc)
  142 + *
  143 + * @see org.apache.lucene.search.DocIdSetIterator#docID()
  144 + */
  145 + @Override
  146 + public int docID() {
  147 + return docId;
  148 + }
  149 +
  150 + /*
  151 + * (non-Javadoc)
  152 + *
  153 + * @see org.apache.lucene.search.DocIdSetIterator#nextDoc()
  154 + */
  155 + @Override
  156 + public int nextDoc() throws IOException {
  157 + reset();
  158 + while (!goToNextDoc())
  159 + ;
  160 + return docId;
  161 + }
  162 +
  163 + /*
  164 + * (non-Javadoc)
  165 + *
  166 + * @see org.apache.lucene.search.DocIdSetIterator#advance(int)
  167 + */
  168 + @Override
  169 + public int advance(int target) throws IOException {
  170 + reset();
  171 + if (docId == NO_MORE_DOCS) {
  172 + return docId;
  173 + } else if (target < docId) {
  174 + // should not happen
  175 + docId = NO_MORE_DOCS;
  176 + return docId;
  177 + } else {
  178 + // advance 1
  179 + int spans1DocId = spans1.spans.docID();
  180 + if (spans1DocId < target) {
  181 + spans1DocId = spans1.spans.advance(target);
  182 + if (spans1DocId == NO_MORE_DOCS) {
  183 + docId = NO_MORE_DOCS;
  184 + return docId;
  185 + }
  186 + target = Math.max(target, spans1DocId);
  187 + }
  188 + int spans2DocId = spans2.spans.docID();
  189 + // advance 2
  190 + if (spans2DocId < target) {
  191 + spans2DocId = spans2.spans.advance(target);
  192 + if (spans2DocId == NO_MORE_DOCS) {
  193 + docId = NO_MORE_DOCS;
  194 + return docId;
  195 + }
  196 + }
  197 + // check equal docId, otherwise next
  198 + if (spans1DocId == spans2DocId) {
  199 + docId = spans1DocId;
  200 + // check match
  201 + if (goToNextStartPosition()) {
  202 + return docId;
  203 + } else {
  204 + return nextDoc();
  205 + }
  206 + } else {
  207 + return nextDoc();
  208 + }
  209 + }
  210 + }
  211 +
  212 + /**
  213 + * Go to next doc.
  214 + *
  215 + * @return true, if successful
  216 + * @throws IOException
  217 + * Signals that an I/O exception has occurred.
  218 + */
  219 + private boolean goToNextDoc() throws IOException {
  220 + if (docId == NO_MORE_DOCS) {
  221 + return true;
  222 + } else {
  223 + int spans1DocId = spans1.spans.nextDoc();
  224 + int spans2DocId = spans2.spans.docID();
  225 + docId = Math.max(spans1DocId, spans2DocId);
  226 + while (spans1DocId != spans2DocId && docId != NO_MORE_DOCS) {
  227 + if (spans1DocId < spans2DocId) {
  228 + spans1DocId = spans1.spans.advance(spans2DocId);
  229 + docId = spans1DocId;
  230 + } else {
  231 + spans2DocId = spans2.spans.advance(spans1DocId);
  232 + docId = spans2DocId;
  233 + }
  234 + }
  235 + if (docId != NO_MORE_DOCS) {
  236 + if (!goToNextStartPosition()) {
  237 + reset();
  238 + return false;
  239 + }
  240 + }
  241 + return true;
  242 + }
  243 + }
  244 +
  245 + /**
  246 + * Go to next start position.
  247 + *
  248 + * @return true, if successful
  249 + * @throws IOException
  250 + * Signals that an I/O exception has occurred.
  251 + */
  252 + private boolean goToNextStartPosition() throws IOException {
  253 + int nextSpans1StartPosition, nextSpans1EndPosition;
  254 + int nextSpans2StartPosition, nextSpans2EndPosition;
  255 + while ((nextSpans1StartPosition = spans1.spans
  256 + .nextStartPosition()) != NO_MORE_POSITIONS) {
  257 + nextSpans1EndPosition = spans1.spans.endPosition();
  258 + if (nextSpans1StartPosition == previousSpans2StartPosition) {
  259 + if (previousSpans2EndPositions.contains(nextSpans1EndPosition)) {
  260 + return true;
  261 + }
  262 + } else if (nextSpans1StartPosition == lastSpans2StartPosition) {
  263 + if (nextSpans1EndPosition == lastSpans2EndPosition) {
  264 + return true;
  265 + }
  266 + } else {
  267 + while (lastSpans2StartPosition <= nextSpans1StartPosition) {
  268 + nextSpans2StartPosition = spans2.spans.nextStartPosition();
  269 + if (nextSpans2StartPosition == NO_MORE_POSITIONS) {
  270 + noMorePositions = true;
  271 + return false;
  272 + } else {
  273 + nextSpans2EndPosition = spans2.spans.endPosition();
  274 + if (lastSpans2StartPosition == nextSpans2StartPosition
  275 + && nextSpans1StartPosition == nextSpans2StartPosition) {
  276 + if (previousSpans2StartPosition != lastSpans2StartPosition) {
  277 + previousSpans2StartPosition = lastSpans2StartPosition;
  278 + previousSpans2EndPositions.clear();
  279 + }
  280 + previousSpans2EndPositions.add(lastSpans2EndPosition);
  281 + }
  282 + lastSpans2StartPosition = nextSpans2StartPosition;
  283 + lastSpans2EndPosition = nextSpans2EndPosition;
  284 + if (nextSpans1StartPosition == nextSpans2StartPosition
  285 + && nextSpans1StartPosition == nextSpans2StartPosition) {
  286 + return true;
  287 + }
  288 + }
  289 + }
  290 +
  291 + }
  292 + }
  293 + noMorePositions = true;
  294 + return false;
  295 + }
  296 +
  297 + /**
  298 + * Reset.
  299 + */
  300 + private void reset() {
  301 + calledNextStartPosition = false;
  302 + noMorePositions = false;
  303 + lastSpans2StartPosition = -1;
  304 + lastSpans2EndPosition = -1;
  305 + previousSpans2StartPosition = -1;
  306 + previousSpans2EndPositions.clear();
  307 + }
  308 +
  309 + /*
  310 + * (non-Javadoc)
  311 + *
  312 + * @see org.apache.lucene.search.DocIdSetIterator#cost()
  313 + */
  314 + @Override
  315 + public long cost() {
  316 + return 0;
  317 + }
  318 +
  319 +}
... ...
src/mtas/search/spans/MtasSpanIntersectingQuery.java
... ... @@ -37,8 +37,11 @@ public class MtasSpanIntersectingQuery extends MtasSpanQuery {
37 37 * the q2
38 38 */
39 39 public MtasSpanIntersectingQuery(MtasSpanQuery q1, MtasSpanQuery q2) {
40   - if (q1 != null && (field = q1.getField())!=null) {
41   - if (q2 != null && ((field==null && q2.getField()!=null) || !q2.getField().equals(field))) {
  40 + super(q1 != null ? q1.getMinimumWidth() : null,
  41 + q1 != null ? q1.getMaximumWidth() : null);
  42 + if (q1 != null && (field = q1.getField()) != null) {
  43 + if (q2 != null && ((field == null && q2.getField() != null)
  44 + || !q2.getField().equals(field))) {
42 45 throw new IllegalArgumentException("Clauses must have same field.");
43 46 }
44 47 } else if (q2 != null) {
... ... @@ -169,9 +172,19 @@ public class MtasSpanIntersectingQuery extends MtasSpanQuery {
169 172 MtasSpanQuery newQ1 = (MtasSpanQuery) q1.rewrite(reader);
170 173 MtasSpanQuery newQ2 = (MtasSpanQuery) q2.rewrite(reader);
171 174 if (newQ1 != q1 || newQ2 != q2) {
172   - return new MtasSpanIntersectingQuery(newQ1, newQ2);
  175 + return new MtasSpanIntersectingQuery(newQ1, newQ2).rewrite(reader);
  176 + } else if (newQ1 == null || newQ2 == null) {
  177 + return new MtasSpanMatchNoneQuery(this.getField());
  178 + } else if(newQ1.equals(newQ2)) {
  179 + return newQ1;
  180 + } else if (newQ1.getMaximumWidth() != null
  181 + && newQ1.getMaximumWidth() == 0) {
  182 + return new MtasSpanMatchNoneQuery(this.getField());
  183 + } else if (newQ2.getMaximumWidth() != null
  184 + && newQ2.getMaximumWidth() == 0) {
  185 + return new MtasSpanMatchNoneQuery(this.getField());
173 186 } else {
174   - return this;
  187 + return super.rewrite(reader);
175 188 }
176 189 }
177 190  
... ...
src/mtas/search/spans/MtasSpanMatchAllQuery.java
... ... @@ -8,6 +8,7 @@ import mtas.codec.util.CodecInfo;
8 8 import mtas.search.similarities.MtasSimScorer;
9 9 import mtas.search.spans.util.MtasSpanQuery;
10 10 import org.apache.lucene.codecs.FieldsProducer;
  11 +import org.apache.lucene.index.IndexReader;
11 12 import org.apache.lucene.index.IndexReaderContext;
12 13 import org.apache.lucene.index.LeafReader;
13 14 import org.apache.lucene.index.LeafReaderContext;
... ... @@ -34,6 +35,7 @@ public class MtasSpanMatchAllQuery extends MtasSpanQuery {
34 35 * the field
35 36 */
36 37 public MtasSpanMatchAllQuery(String field) {
  38 + super(1,1);
37 39 this.field = field;
38 40 }
39 41  
... ... @@ -60,6 +62,11 @@ public class MtasSpanMatchAllQuery extends MtasSpanQuery {
60 62 //keep things simple
61 63 return new SpanAllWeight(searcher, null);
62 64 }
  65 +
  66 + @Override
  67 + public MtasSpanQuery rewrite(IndexReader reader) throws IOException {
  68 + return super.rewrite(reader);
  69 + }
63 70  
64 71 /**
65 72 * The Class SpanAllWeight.
... ...
src/mtas/search/spans/MtasSpanMatchNoneQuery.java
... ... @@ -7,6 +7,7 @@ import java.util.Set;
7 7 import mtas.search.similarities.MtasSimScorer;
8 8 import mtas.search.spans.util.MtasSpanQuery;
9 9  
  10 +import org.apache.lucene.index.IndexReader;
10 11 import org.apache.lucene.index.LeafReader;
11 12 import org.apache.lucene.index.LeafReaderContext;
12 13 import org.apache.lucene.index.Term;
... ... @@ -31,6 +32,7 @@ public class MtasSpanMatchNoneQuery extends MtasSpanQuery {
31 32 * the field
32 33 */
33 34 public MtasSpanMatchNoneQuery(String field) {
  35 + super(null,null);
34 36 this.field = field;
35 37 }
36 38  
... ... @@ -56,6 +58,11 @@ public class MtasSpanMatchNoneQuery extends MtasSpanQuery {
56 58 throws IOException {
57 59 return new SpanNoneWeight(searcher, null);
58 60 }
  61 +
  62 + @Override
  63 + public MtasSpanQuery rewrite(IndexReader reader) throws IOException {
  64 + return super.rewrite(reader);
  65 + }
59 66  
60 67 /**
61 68 * The Class SpanNoneWeight.
... ...
src/mtas/search/spans/MtasSpanNotQuery.java
... ... @@ -5,22 +5,39 @@ import java.io.IOException;
5 5 import org.apache.lucene.index.IndexReader;
6 6 import org.apache.lucene.search.IndexSearcher;
7 7 import org.apache.lucene.search.spans.SpanNotQuery;
  8 +import org.apache.lucene.search.spans.SpanQuery;
8 9 import org.apache.lucene.search.spans.SpanWeight;
9 10  
10 11 import mtas.search.spans.util.MtasSpanQuery;
11 12  
12 13 public class MtasSpanNotQuery extends MtasSpanQuery {
  14 + private String field;
  15 +
13 16 /** The base query. */
14 17 private SpanNotQuery baseQuery;
  18 +
  19 + private SpanQuery q1, q2;
15 20  
16 21 public MtasSpanNotQuery(MtasSpanQuery q1, MtasSpanQuery q2) {
17   - super();
  22 + super(q1!=null?q1.getMinimumWidth():null, q2!=null?q2.getMaximumWidth():null);
  23 + if (q1 != null && (field = q1.getField()) != null) {
  24 + if (q2 != null && ((field == null && q2.getField() != null)
  25 + || !q2.getField().equals(field))) {
  26 + throw new IllegalArgumentException("Clauses must have same field.");
  27 + }
  28 + } else if (q2 != null) {
  29 + field = q2.getField();
  30 + } else {
  31 + field = null;
  32 + }
  33 + this.q1 = q1;
  34 + this.q2 = q2;
18 35 baseQuery = new SpanNotQuery(q1, q2);
19 36 }
20 37  
21 38 @Override
22 39 public String getField() {
23   - return baseQuery.getField();
  40 + return field;
24 41 }
25 42  
26 43 @Override
... ... @@ -31,8 +48,13 @@ public class MtasSpanNotQuery extends MtasSpanQuery {
31 48  
32 49 @Override
33 50 public MtasSpanQuery rewrite(IndexReader reader) throws IOException {
34   - baseQuery = (SpanNotQuery) baseQuery.rewrite(reader);
35   - return this;
  51 + MtasSpanQuery newQ1 = (MtasSpanQuery) q1.rewrite(reader);
  52 + MtasSpanQuery newQ2 = (MtasSpanQuery) q2.rewrite(reader);
  53 + if (newQ1 != q1 || newQ2 != q2) {
  54 + return new MtasSpanNotQuery(newQ1, newQ2).rewrite(reader);
  55 + } else {
  56 + return super.rewrite(reader);
  57 + }
36 58 }
37 59  
38 60 @Override
... ...
src/mtas/search/spans/MtasSpanOrQuery.java
... ... @@ -2,7 +2,6 @@ package mtas.search.spans;
2 2  
3 3 import java.io.IOException;
4 4 import java.util.ArrayList;
5   -import java.util.HashSet;
6 5 import java.util.Iterator;
7 6 import java.util.List;
8 7  
... ... @@ -21,7 +20,7 @@ public class MtasSpanOrQuery extends MtasSpanQuery {
21 20  
22 21 /** The clauses. */
23 22 private List<MtasSpanQuery> clauses;
24   -
  23 +
25 24 private SpanQuery baseQuery;
26 25  
27 26 /**
... ... @@ -31,16 +30,25 @@ public class MtasSpanOrQuery extends MtasSpanQuery {
31 30 * the clauses
32 31 */
33 32 public MtasSpanOrQuery(MtasSpanQuery... initialClauses) {
34   - super();
  33 + super(null, null);
  34 + Integer minimum = null, maximum = null;
35 35 clauses = new ArrayList<MtasSpanQuery>();
36   - for(MtasSpanQuery item : initialClauses) {
37   - if(!clauses.contains(item)) {
38   - clauses.add(item);
  36 + for (MtasSpanQuery item : initialClauses) {
  37 + if (!clauses.contains(item)) {
  38 + minimum = clauses.isEmpty() ? item.getMinimumWidth()
  39 + : (minimum != null && item.getMinimumWidth() != null)
  40 + ? Math.min(minimum, item.getMinimumWidth()) : null;
  41 + maximum = clauses.isEmpty() ? item.getMaximumWidth()
  42 + : (maximum != null && item.getMaximumWidth() != null)
  43 + ? Math.max(maximum, item.getMaximumWidth()) : null;
  44 + clauses.add(item);
39 45 }
40   - }
41   - baseQuery = new SpanOrQuery(clauses.toArray(new MtasSpanQuery[clauses.size()]));
  46 + }
  47 + setWidth(minimum, maximum);
  48 + baseQuery = new SpanOrQuery(
  49 + clauses.toArray(new MtasSpanQuery[clauses.size()]));
42 50 }
43   -
  51 +
44 52 @Override
45 53 public String getField() {
46 54 return baseQuery.getField();
... ... @@ -51,27 +59,69 @@ public class MtasSpanOrQuery extends MtasSpanQuery {
51 59 throws IOException {
52 60 return baseQuery.createWeight(searcher, needsScores);
53 61 }
54   -
  62 +
55 63 @Override
56 64 public MtasSpanQuery rewrite(IndexReader reader) throws IOException {
57   - super.rewrite(reader);
58   - if(clauses.size()>1) {
  65 + if (clauses.size() > 1) {
  66 + // rewrite, count MtasSpanMatchAllQuery and check for
  67 + // MtasSpanMatchNoneQuery
59 68 MtasSpanQuery[] newClauses = new MtasSpanQuery[clauses.size()];
  69 + int singlePositionQueries = 0;
  70 + int matchAllSinglePositionQueries = 0;
  71 + int matchNoneQueries = 0;
60 72 boolean actuallyRewritten = false;
61   - for(int i=0; i<clauses.size(); i++) {
  73 + for (int i = 0; i < clauses.size(); i++) {
62 74 newClauses[i] = clauses.get(i).rewrite(reader);
63   - actuallyRewritten |= clauses.get(i)!=newClauses[i];
  75 + actuallyRewritten |= clauses.get(i) != newClauses[i];
  76 + if (newClauses[i] instanceof MtasSpanMatchNoneQuery) {
  77 + matchNoneQueries++;
  78 + } else if (newClauses[i].isSinglePositionQuery()) {
  79 + singlePositionQueries++;
  80 + if (newClauses[i] instanceof MtasSpanMatchAllQuery) {
  81 + matchAllSinglePositionQueries++;
  82 + }
  83 + }
64 84 }
65   - if(actuallyRewritten) {
66   - return new MtasSpanOrQuery(newClauses).rewrite(reader);
  85 + // filter clauses
  86 + if (matchNoneQueries > 0 || matchAllSinglePositionQueries > 0) {
  87 + // compute new number of clauses
  88 + int newNumber = newClauses.length - matchNoneQueries;
  89 + if (matchAllSinglePositionQueries > 0) {
  90 + newNumber -= singlePositionQueries - 1;
  91 + }
  92 + MtasSpanQuery[] newFilteredClauses = new MtasSpanQuery[newNumber];
  93 + int j = 0;
  94 + for (int i = 0; i < newClauses.length; i++) {
  95 + if (!(newClauses[i] instanceof MtasSpanMatchNoneQuery)) {
  96 + if (!newClauses[i].isSinglePositionQuery()) {
  97 + newFilteredClauses[j] = newClauses[i];
  98 + j++;
  99 + } else if (matchAllSinglePositionQueries == 0) {
  100 + newFilteredClauses[j] = newClauses[i];
  101 + j++;
  102 + } else if (singlePositionQueries > 0) {
  103 + newFilteredClauses[j] = newClauses[i];
  104 + j++;
  105 + singlePositionQueries = 0; // only match this condition once
  106 + }
  107 + }
  108 + }
  109 + newClauses = newFilteredClauses;
  110 + }
  111 + if (newClauses.length == 0) {
  112 + return (new MtasSpanMatchNoneQuery(this.getField())).rewrite(reader);
  113 + } else if (newClauses.length == 1) {
  114 + return newClauses[0].rewrite(reader);
  115 + } else if (actuallyRewritten || newClauses.length != clauses.size()) {
  116 + return new MtasSpanOrQuery(newClauses).rewrite(reader);
67 117 } else {
68 118 return super.rewrite(reader);
69 119 }
70   - } else if(clauses.size()==1) {
71   - return clauses.get(0).rewrite(reader);
  120 + } else if (clauses.size() == 1) {
  121 + return clauses.get(0).rewrite(reader);
72 122 } else {
73   - return super.rewrite(reader);
74   - }
  123 + return (new MtasSpanMatchNoneQuery(this.getField())).rewrite(reader);
  124 + }
75 125 }
76 126  
77 127 /*
... ... @@ -123,6 +173,6 @@ public class MtasSpanOrQuery extends MtasSpanQuery {
123 173 int h = this.getClass().getSimpleName().hashCode();
124 174 h = (h * 7) ^ baseQuery.hashCode();
125 175 return h;
126   - }
  176 + }
127 177  
128 178 }
... ...
src/mtas/search/spans/MtasSpanPositionQuery.java
... ... @@ -9,6 +9,7 @@ import mtas.search.similarities.MtasSimScorer;
9 9 import mtas.search.spans.util.MtasSpanQuery;
10 10  
11 11 import org.apache.lucene.codecs.FieldsProducer;
  12 +import org.apache.lucene.index.IndexReader;
12 13 import org.apache.lucene.index.LeafReader;
13 14 import org.apache.lucene.index.LeafReaderContext;
14 15 import org.apache.lucene.index.Term;
... ... @@ -39,9 +40,7 @@ public class MtasSpanPositionQuery extends MtasSpanQuery {
39 40 * the position
40 41 */
41 42 public MtasSpanPositionQuery(String field, int position) {
42   - this.field = field;
43   - this.start = position;
44   - this.end = position;
  43 + this(field, position, position);
45 44 }
46 45  
47 46 /**
... ... @@ -55,6 +54,7 @@ public class MtasSpanPositionQuery extends MtasSpanQuery {
55 54 * the end
56 55 */
57 56 public MtasSpanPositionQuery(String field, int start, int end) {
  57 + super(1,1);
58 58 this.field = field;
59 59 this.start = start;
60 60 this.end = end;
... ... @@ -82,6 +82,11 @@ public class MtasSpanPositionQuery extends MtasSpanQuery {
82 82 throws IOException {
83 83 return new SpanAllWeight(searcher, null);
84 84 }
  85 +
  86 + @Override
  87 + public MtasSpanQuery rewrite(IndexReader reader) throws IOException {
  88 + return super.rewrite(reader);
  89 + }
85 90  
86 91 /**
87 92 * The Class SpanAllWeight.
... ...
src/mtas/search/spans/MtasSpanPrefixQuery.java
... ... @@ -55,7 +55,7 @@ public class MtasSpanPrefixQuery extends MtasSpanQuery {
55 55 * the single position
56 56 */
57 57 public MtasSpanPrefixQuery(Term term, boolean singlePosition) {
58   - super();
  58 + super(singlePosition?1:null,singlePosition?1:null);
59 59 PrefixQuery pfq = new PrefixQuery(term);
60 60 query = new SpanMultiTermQueryWrapper<PrefixQuery>(pfq);
61 61 this.term = term;
... ... @@ -86,12 +86,12 @@ public class MtasSpanPrefixQuery extends MtasSpanQuery {
86 86 for (int i = 0; i < clauses.length; i++) {
87 87 if (clauses[i] instanceof SpanTermQuery) {
88 88 newClauses[i] = new MtasSpanTermQuery((SpanTermQuery) clauses[i],
89   - singlePosition);
  89 + singlePosition).rewrite(reader);
90 90 } else {
91 91 throw new IOException("no SpanTermQuery after rewrite");
92 92 }
93 93 }
94   - return new MtasSpanOrQuery(newClauses);
  94 + return new MtasSpanOrQuery(newClauses).rewrite(reader);
95 95 } else {
96 96 throw new IOException("no SpanOrQuery after rewrite");
97 97 }
... ...
src/mtas/search/spans/MtasSpanRecurrenceQuery.java
... ... @@ -42,14 +42,21 @@ public class MtasSpanRecurrenceQuery extends MtasSpanQuery
42 42 /**
43 43 * Instantiates a new mtas span recurrence query.
44 44 *
45   - * @param clause the clause
46   - * @param minimumRecurrence the minimum recurrence
47   - * @param maximumRecurrence the maximum recurrence
48   - * @param ignore the ignore
49   - * @param maximumIgnoreLength the maximum ignore length
  45 + * @param clause
  46 + * the clause
  47 + * @param minimumRecurrence
  48 + * the minimum recurrence
  49 + * @param maximumRecurrence
  50 + * the maximum recurrence
  51 + * @param ignore
  52 + * the ignore
  53 + * @param maximumIgnoreLength
  54 + * the maximum ignore length
50 55 */
51 56 public MtasSpanRecurrenceQuery(MtasSpanQuery clause, int minimumRecurrence,
52   - int maximumRecurrence, MtasSpanQuery ignore, Integer maximumIgnoreLength) {
  57 + int maximumRecurrence, MtasSpanQuery ignore,
  58 + Integer maximumIgnoreLength) {
  59 + super(null, null);
53 60 if (minimumRecurrence > maximumRecurrence) {
54 61 throw new IllegalArgumentException(
55 62 "minimumRecurrence > maximumRecurrence");
... ... @@ -74,6 +81,23 @@ public class MtasSpanRecurrenceQuery extends MtasSpanQuery
74 81 this.ignoreClause = null;
75 82 this.maximumIgnoreLength = null;
76 83 }
  84 + // set minimum/maximum
  85 + Integer minimum = null, maximum = null;
  86 + if (clause.getMinimumWidth() != null) {
  87 + minimum = minimumRecurrence * clause.getMinimumWidth();
  88 + }
  89 + if (clause.getMaximumWidth() != null) {
  90 + maximum = maximumRecurrence * clause.getMaximumWidth();
  91 + if (ignore != null && maximumIgnoreLength != null) {
  92 + if (ignore.getMaximumWidth() != null) {
  93 + maximum += (maximumRecurrence - 1) * maximumIgnoreLength
  94 + * ignore.getMaximumWidth();
  95 + } else {
  96 + maximum = null;
  97 + }
  98 + }
  99 + }
  100 + setWidth(minimum, maximum);
77 101 }
78 102  
79 103 /**
... ... @@ -95,14 +119,6 @@ public class MtasSpanRecurrenceQuery extends MtasSpanQuery
95 119 return field;
96 120 }
97 121  
98   - // @Override
99   - // public MtasSpanRecurrenceQuery clone() {
100   - // MtasSpanRecurrenceQuery soq = new
101   - // MtasSpanRecurrenceQuery((SpanQuery)clause.clone(), minimumRecurrence,
102   - // maximumRecurrence);
103   - // return soq;
104   - // }
105   -
106 122 /*
107 123 * (non-Javadoc)
108 124 *
... ... @@ -111,16 +127,18 @@ public class MtasSpanRecurrenceQuery extends MtasSpanQuery
111 127 */
112 128 @Override
113 129 public MtasSpanQuery rewrite(IndexReader reader) throws IOException {
114   - MtasSpanQuery query = clause.rewrite(reader);
115   - MtasSpanQuery ignoreQuery = null;
116   - if (ignoreClause != null) {
117   - ignoreQuery = ignoreClause.rewrite(reader);
  130 + MtasSpanQuery newClause = clause.rewrite(reader);
  131 + MtasSpanQuery newIgnoreClause = (ignoreClause != null)
  132 + ? ignoreClause.rewrite(reader) : null;
  133 + if(newClause instanceof MtasSpanRecurrenceQuery) {
  134 + //for now too difficult, possibly merge later
118 135 }
119   - if (query != clause) { // clause rewrote: must clone
120   - return new MtasSpanRecurrenceQuery(query, minimumRecurrence,
121   - maximumRecurrence, ignoreQuery, maximumIgnoreLength);
  136 + if (newClause != clause
  137 + || (newIgnoreClause != null && newIgnoreClause != ignoreClause)) {
  138 + return new MtasSpanRecurrenceQuery(newClause, minimumRecurrence,
  139 + maximumRecurrence, newIgnoreClause, maximumIgnoreLength).rewrite(reader);
122 140 } else {
123   - return this; // no rewrote
  141 + return super.rewrite(reader);
124 142 }
125 143 }
126 144  
... ... @@ -214,12 +232,18 @@ public class MtasSpanRecurrenceQuery extends MtasSpanQuery
214 232 /**
215 233 * Instantiates a new span recurrence weight.
216 234 *
217   - * @param subWeight the sub weight
218   - * @param ignoreWeight the ignore weight
219   - * @param maximumIgnoreLength the maximum ignore length
220   - * @param searcher the searcher
221   - * @param terms the terms
222   - * @throws IOException Signals that an I/O exception has occurred.
  235 + * @param subWeight
  236 + * the sub weight
  237 + * @param ignoreWeight
  238 + * the ignore weight
  239 + * @param maximumIgnoreLength
  240 + * the maximum ignore length
  241 + * @param searcher
  242 + * the searcher
  243 + * @param terms
  244 + * the terms
  245 + * @throws IOException
  246 + * Signals that an I/O exception has occurred.
223 247 */
224 248 public SpanRecurrenceWeight(SpanWeight subWeight, SpanWeight ignoreWeight,
225 249 Integer maximumIgnoreLength, IndexSearcher searcher,
... ...
src/mtas/search/spans/MtasSpanRegexQuery.java deleted
1   -package mtas.search.spans;
2   -
3   -import java.io.IOException;
4   -
5   -import mtas.codec.util.CodecUtil;
6   -import mtas.search.spans.util.MtasSpanQuery;
7   -
8   -import org.apache.lucene.index.IndexReader;
9   -import org.apache.lucene.index.Term;
10   -import org.apache.lucene.search.IndexSearcher;
11   -import org.apache.lucene.search.Query;
12   -import org.apache.lucene.search.RegexpQuery;
13   -import org.apache.lucene.search.spans.SpanMultiTermQueryWrapper;
14   -import org.apache.lucene.search.spans.SpanOrQuery;
15   -import org.apache.lucene.search.spans.SpanQuery;
16   -import org.apache.lucene.search.spans.SpanTermQuery;
17   -import org.apache.lucene.search.spans.SpanWeight;
18   -
19   -/**
20   - * The Class MtasSpanRegexQuery.
21   - */
22   -public class MtasSpanRegexQuery extends MtasSpanQuery {
23   -
24   - /** The Constant MTAS_REGEX_EXPAND_BOUNDARY. */
25   - private static final int MTAS_REGEX_EXPAND_BOUNDARY = 1000000;
26   -
27   - /** The prefix. */
28   - private String prefix;
29   -
30   - /** The value. */
31   - private String value;
32   -
33   - /** The single position. */
34   - private boolean singlePosition;
35   -
36   - /** The term. */
37   - private Term term;
38   -
39   - /** The query. */
40   - private SpanMultiTermQueryWrapper<RegexpQuery> query;
41   -
42   - /*
43   - * (non-Javadoc)
44   - *
45   - * @see
46   - * org.apache.lucene.search.Query#rewrite(org.apache.lucene.index.IndexReader)
47   - */
48   - @Override
49   - public MtasSpanQuery rewrite(IndexReader reader) throws IOException {
50   - Query q = query.rewrite(reader);
51   - if (q instanceof SpanOrQuery) {
52   - SpanQuery[] clauses = ((SpanOrQuery) q).getClauses();
53   - if (clauses.length > MTAS_REGEX_EXPAND_BOUNDARY) {
54   - // TODO : forward index solution
55   - throw new IOException("Regex \""
56   - + CodecUtil.termValue(term.text()) + "\" expands to "
57   - + clauses.length + " terms, too many (boundary "
58   - + MTAS_REGEX_EXPAND_BOUNDARY + ")!");
59   - }
60   - MtasSpanQuery[] newClauses = new MtasSpanQuery[clauses.length];
61   - for (int i = 0; i < clauses.length; i++) {
62   - if (clauses[i] instanceof SpanTermQuery) {
63   - newClauses[i] = new MtasSpanTermQuery((SpanTermQuery) clauses[i],
64   - singlePosition);
65   - } else {
66   - throw new IOException("no SpanTermQuery after rewrite");
67   - }
68   - }
69   - return new MtasSpanOrQuery(newClauses);
70   - } else {
71   - throw new IOException("no SpanOrQuery after rewrite");
72   - }
73   - }
74   -
75   - /*
76   - * (non-Javadoc)
77   - *
78   - * @see
79   - * org.apache.lucene.search.spans.SpanTermQuery#toString(java.lang.String)
80   - */
81   - @Override
82   - public String toString(String field) {
83   - StringBuilder buffer = new StringBuilder();
84   - buffer.append(this.getClass().getSimpleName() + "([");
85   - if (value == null) {
86   - buffer.append(this.query.getField() + ":" + prefix);
87   - } else {
88   - buffer.append(this.query.getField() + ":" + prefix + "=" + value);
89   - }
90   - buffer.append("])");
91   - return buffer.toString();
92   - }
93   -
94   - /*
95   - * (non-Javadoc)
96   - *
97   - * @see org.apache.lucene.search.spans.SpanQuery#getField()
98   - */
99   - @Override
100   - public String getField() {
101   - return term.field();
102   - }
103   -
104   - /*
105   - * (non-Javadoc)
106   - *
107   - * @see
108   - * org.apache.lucene.search.spans.SpanQuery#createWeight(org.apache.lucene.
109   - * search.IndexSearcher, boolean)
110   - */
111   - @Override
112   - public SpanWeight createWeight(IndexSearcher searcher, boolean needsScores)
113   - throws IOException {
114   - return ((SpanQuery) searcher.rewrite(query)).createWeight(searcher,
115   - needsScores);
116   - }
117   -
118   - /*
119   - * (non-Javadoc)
120   - *
121   - * @see org.apache.lucene.search.Query#equals(java.lang.Object)
122   - */
123   - @Override
124   - public boolean equals(Object obj) {
125   - if (this == obj)
126   - return true;
127   - if (obj == null)
128   - return false;
129   - if (getClass() != obj.getClass())
130   - return false;
131   - MtasSpanRegexQuery that = (MtasSpanRegexQuery) obj;
132   - return term.equals(that.term) && singlePosition == that.singlePosition;
133   - }
134   -
135   - /*
136   - * (non-Javadoc)
137   - *
138   - * @see org.apache.lucene.search.Query#hashCode()
139   - */
140   - @Override
141   - public int hashCode() {
142   - int h = this.getClass().getSimpleName().hashCode();
143   - h = (h * 7) ^ term.hashCode();
144   - h += (singlePosition ? 1 : 0);
145   - return h;
146   - }
147   -
148   -}
src/mtas/search/spans/MtasSpanRegexpQuery.java
... ... @@ -59,7 +59,7 @@ public class MtasSpanRegexpQuery extends MtasSpanQuery {
59 59 * the single position
60 60 */
61 61 public MtasSpanRegexpQuery(Term term, boolean singlePosition) {
62   - super();
  62 + super(singlePosition?1:null, singlePosition?1:null);
63 63 RegexpQuery req = new RegexpQuery(term);
64 64 query = new SpanMultiTermQueryWrapper<RegexpQuery>(req);
65 65 this.term = term;
... ... @@ -97,12 +97,12 @@ public class MtasSpanRegexpQuery extends MtasSpanQuery {
97 97 for (int i = 0; i < clauses.length; i++) {
98 98 if (clauses[i] instanceof SpanTermQuery) {
99 99 newClauses[i] = new MtasSpanTermQuery((SpanTermQuery) clauses[i],
100   - singlePosition);
  100 + singlePosition).rewrite(reader);
101 101 } else {
102 102 throw new IOException("no SpanTermQuery after rewrite");
103 103 }
104 104 }
105   - return new MtasSpanOrQuery(newClauses);
  105 + return new MtasSpanOrQuery(newClauses).rewrite(reader);
106 106 } else {
107 107 throw new IOException("no SpanOrQuery after rewrite");
108 108 }
... ...
src/mtas/search/spans/MtasSpanSequenceItem.java
1 1 package mtas.search.spans;
2 2  
  3 +import java.io.IOException;
  4 +
  5 +import org.apache.lucene.index.IndexReader;
  6 +
3 7 import mtas.search.spans.util.MtasSpanQuery;
4 8  
5 9 /**
... ... @@ -81,6 +85,15 @@ public class MtasSpanSequenceItem {
81 85 }
82 86 }
83 87  
  88 + public MtasSpanSequenceItem rewrite(IndexReader reader) throws IOException {
  89 + MtasSpanQuery newSpanQuery = spanQuery.rewrite(reader);
  90 + if(newSpanQuery!=spanQuery) {
  91 + return new MtasSpanSequenceItem(newSpanQuery, optional);
  92 + } else {
  93 + return this;
  94 + }
  95 + }
  96 +
84 97 @Override
85 98 public String toString() {
86 99 return "["+spanQuery.toString()+" - "+(optional?"OPTIONAL":"NOT OPTIONAL")+"]";
... ...
src/mtas/search/spans/MtasSpanSequenceQuery.java
... ... @@ -21,7 +21,7 @@ import mtas.search.spans.util.MtasSpanQuery;
21 21 /**
22 22 * The Class MtasSpanSequenceQuery.
23 23 */
24   -public class MtasSpanSequenceQuery extends MtasSpanQuery implements Cloneable {
  24 +public class MtasSpanSequenceQuery extends MtasSpanQuery {
25 25  
26 26 /** The items. */
27 27 private List<MtasSpanSequenceItem> items;
... ... @@ -38,12 +38,17 @@ public class MtasSpanSequenceQuery extends MtasSpanQuery implements Cloneable {
38 38 /**
39 39 * Instantiates a new mtas span sequence query.
40 40 *
41   - * @param items the items
42   - * @param ignore the ignore
43   - * @param maximumIgnoreLength the maximum ignore length
  41 + * @param items
  42 + * the items
  43 + * @param ignore
  44 + * the ignore
  45 + * @param maximumIgnoreLength
  46 + * the maximum ignore length
44 47 */
45 48 public MtasSpanSequenceQuery(List<MtasSpanSequenceItem> items,
46   - MtasSpanQuery ignore, Integer maximumIgnoreLength) {
  49 + MtasSpanQuery ignore, Integer maximumIgnoreLength) {
  50 + super(null, null);
  51 + Integer minimum = 0, maximum = 0;
47 52 this.items = items;
48 53 // get field and do checks
49 54 for (MtasSpanSequenceItem item : items) {
... ... @@ -53,8 +58,16 @@ public class MtasSpanSequenceQuery extends MtasSpanQuery implements Cloneable {
53 58 && !item.getQuery().getField().equals(field)) {
54 59 throw new IllegalArgumentException("Clauses must have same field.");
55 60 }
  61 + if (minimum != null && !item.isOptional()) {
  62 + minimum = item.getQuery().getMinimumWidth() != null
  63 + ? minimum + item.getQuery().getMinimumWidth() : null;
  64 + }
  65 + if (maximum != null) {
  66 + maximum = item.getQuery().getMaximumWidth() != null
  67 + ? maximum + item.getQuery().getMaximumWidth() : null;
  68 + }
56 69 }
57   - //check ignore
  70 + // check ignore
58 71 if (field != null && ignore != null) {
59 72 if (ignore.getField() == null || field.equals(ignore.getField())) {
60 73 this.ignoreClause = ignore;
... ... @@ -63,10 +76,19 @@ public class MtasSpanSequenceQuery extends MtasSpanQuery implements Cloneable {
63 76 throw new IllegalArgumentException(
64 77 "ignore must have same field as clauses");
65 78 }
  79 + if (maximum != null && items.size() > 1) {
  80 + if (ignore.getMaximumWidth() != null) {
  81 + maximum += (items.size() - 1) * maximumIgnoreLength
  82 + * ignoreClause.getMaximumWidth();
  83 + } else {
  84 + maximum = null;
  85 + }
  86 + }
66 87 } else {
67 88 this.ignoreClause = null;
68 89 this.maximumIgnoreLength = null;
69   - }
  90 + }
  91 + setWidth(minimum, maximum);
70 92 }
71 93  
72 94 /*
... ... @@ -82,51 +104,34 @@ public class MtasSpanSequenceQuery extends MtasSpanQuery implements Cloneable {
82 104 /*
83 105 * (non-Javadoc)
84 106 *
85   - * @see java.lang.Object#clone()
86   - */
87   - @Override
88   - public MtasSpanSequenceQuery clone() {
89   - int sz = items.size();
90   - List<MtasSpanSequenceItem> newItems = new ArrayList<MtasSpanSequenceItem>();
91   - for (int i = 0; i < sz; i++) {
92   - newItems.add(items.get(i).clone());
93   - }
94   - MtasSpanSequenceQuery soq = new MtasSpanSequenceQuery(newItems,
95   - ignoreClause, maximumIgnoreLength);
96   - return soq;
97   - }
98   -
99   - /*
100   - * (non-Javadoc)
101   - *
102 107 * @see
103 108 * org.apache.lucene.search.Query#rewrite(org.apache.lucene.index.IndexReader)
104 109 */
105 110 @Override
106 111 public MtasSpanQuery rewrite(IndexReader reader) throws IOException {
107   - MtasSpanSequenceQuery clone = null;
108   - for (int i = 0; i < items.size(); i++) {
109   - MtasSpanQuery c = items.get(i).getQuery();
110   - MtasSpanQuery query = (MtasSpanQuery) c.rewrite(reader);
111   - if (query != c) { // clause rewrote: must clone
112   - if (clone == null) {
113   - clone = this.clone();
114   - }
115   - clone.items.get(i).setQuery(query);
  112 + if (items.size() == 1) {
  113 + return items.get(0).getQuery().rewrite(reader);
  114 + } else {
  115 + MtasSpanSequenceItem newItem;
  116 + ArrayList<MtasSpanSequenceItem> newItems = new ArrayList<MtasSpanSequenceItem>(
  117 + items.size());
  118 + MtasSpanQuery newIgnoreClause = ignoreClause != null
  119 + ? ignoreClause.rewrite(reader) : null;
  120 + boolean actuallyRewritten = ignoreClause != null
  121 + ? newIgnoreClause != ignoreClause : false;
  122 + for (int i = 0; i < items.size(); i++) {
  123 + newItem = items.get(i).rewrite(reader);
  124 + actuallyRewritten |= items.get(i) != newItem;
  125 + // for now too difficult, possibly later merge with previous if possible
  126 + newItems.add(newItem);
116 127 }
117   - }
118   - if (ignoreClause != null) {
119   - MtasSpanQuery query = (MtasSpanQuery) ignoreClause.rewrite(reader);
120   - if (query != ignoreClause) {
121   - clone = this.clone();
122   - clone.ignoreClause = query;
  128 + if (!actuallyRewritten) {
  129 + return super.rewrite(reader);
  130 + } else {
  131 + return new MtasSpanSequenceQuery(newItems, newIgnoreClause,
  132 + maximumIgnoreLength).rewrite(reader);
123 133 }
124 134 }
125   - if (clone != null) {
126   - return clone; // some clauses rewrote
127   - } else {
128   - return this; // no clauses rewrote
129   - }
130 135 }
131 136  
132 137 /*
... ... @@ -216,7 +221,8 @@ public class MtasSpanSequenceQuery extends MtasSpanQuery implements Cloneable {
216 221 /**
217 222 * Gets the term contexts.
218 223 *
219   - * @param items the items
  224 + * @param items
  225 + * the items
220 226 * @return the term contexts
221 227 */
222 228 protected Map<Term, TermContext> getTermContexts(
... ... @@ -245,12 +251,18 @@ public class MtasSpanSequenceQuery extends MtasSpanQuery implements Cloneable {
245 251 /**
246 252 * Instantiates a new span sequence weight.
247 253 *
248   - * @param subWeights the sub weights
249   - * @param ignoreWeight the ignore weight
250   - * @param maximumIgnoreLength the maximum ignore length
251   - * @param searcher the searcher
252   - * @param terms the terms
253   - * @throws IOException Signals that an I/O exception has occurred.
  254 + * @param subWeights
  255 + * the sub weights
  256 + * @param ignoreWeight
  257 + * the ignore weight
  258 + * @param maximumIgnoreLength
  259 + * the maximum ignore length
  260 + * @param searcher
  261 + * the searcher
  262 + * @param terms
  263 + * the terms
  264 + * @throws IOException
  265 + * Signals that an I/O exception has occurred.
254 266 */
255 267 public SpanSequenceWeight(List<MtasSpanSequenceQueryWeight> subWeights,
256 268 SpanWeight ignoreWeight, Integer maximumIgnoreLength,
... ... @@ -290,36 +302,41 @@ public class MtasSpanSequenceQuery extends MtasSpanQuery implements Cloneable {
290 302 @Override
291 303 public Spans getSpans(LeafReaderContext context, Postings requiredPostings)
292 304 throws IOException {
293   - Terms terms = context.reader().terms(field);
294   - if (terms == null) {
295   - return null; // field does not exist
296   - }
297   - List<MtasSpanSequenceQuerySpans> setSequenceSpans = new ArrayList<>(
298   - items.size());
299   - Spans ignoreSpans = null;
300   - boolean allSpansEmpty = true;
301   - for (MtasSpanSequenceQueryWeight w : subWeights) {
302   - Spans sequenceSpans = w.spanWeight.getSpans(context, requiredPostings);
303   - if (sequenceSpans != null) {
304   - setSequenceSpans
305   - .add(new MtasSpanSequenceQuerySpans(sequenceSpans, w.optional));
306   - allSpansEmpty = false;
307   - } else {
308   - if (w.optional) {
  305 + if (field == null) {
  306 + return null;
  307 + } else {
  308 + Terms terms = context.reader().terms(field);
  309 + if (terms == null) {
  310 + return null; // field does not exist
  311 + }
  312 + List<MtasSpanSequenceQuerySpans> setSequenceSpans = new ArrayList<>(
  313 + items.size());
  314 + Spans ignoreSpans = null;
  315 + boolean allSpansEmpty = true;
  316 + for (MtasSpanSequenceQueryWeight w : subWeights) {
  317 + Spans sequenceSpans = w.spanWeight.getSpans(context,
  318 + requiredPostings);
  319 + if (sequenceSpans != null) {
309 320 setSequenceSpans
310   - .add(new MtasSpanSequenceQuerySpans(null, w.optional));
  321 + .add(new MtasSpanSequenceQuerySpans(sequenceSpans, w.optional));
  322 + allSpansEmpty = false;
311 323 } else {
312   - return null;
  324 + if (w.optional) {
  325 + setSequenceSpans
  326 + .add(new MtasSpanSequenceQuerySpans(null, w.optional));
  327 + } else {
  328 + return null;
  329 + }
313 330 }
314 331 }
  332 + if (allSpansEmpty) {
  333 + return null; // at least one required
  334 + } else if (ignoreWeight != null) {
  335 + ignoreSpans = ignoreWeight.getSpans(context, requiredPostings);
  336 + }
  337 + return new MtasSpanSequenceSpans(MtasSpanSequenceQuery.this,
  338 + setSequenceSpans, ignoreSpans, maximumIgnoreLength);
315 339 }
316   - if (allSpansEmpty) {
317   - return null; // at least one required
318   - } else if (ignoreWeight != null) {
319   - ignoreSpans = ignoreWeight.getSpans(context, requiredPostings);
320   - }
321   - return new MtasSpanSequenceSpans(MtasSpanSequenceQuery.this,
322   - setSequenceSpans, ignoreSpans, maximumIgnoreLength);
323 340 }
324 341  
325 342 /*
... ... @@ -353,8 +370,10 @@ public class MtasSpanSequenceQuery extends MtasSpanQuery implements Cloneable {
353 370 /**
354 371 * Instantiates a new mtas span sequence query spans.
355 372 *
356   - * @param spans the spans
357   - * @param optional the optional
  373 + * @param spans
  374 + * the spans
  375 + * @param optional
  376 + * the optional
358 377 */
359 378 public MtasSpanSequenceQuerySpans(Spans spans, boolean optional) {
360 379 this.spans = spans;
... ... @@ -376,8 +395,10 @@ public class MtasSpanSequenceQuery extends MtasSpanQuery implements Cloneable {
376 395 /**
377 396 * Instantiates a new mtas span sequence query weight.
378 397 *
379   - * @param spanWeight the span weight
380   - * @param optional the optional
  398 + * @param spanWeight
  399 + * the span weight
  400 + * @param optional
  401 + * the optional
381 402 */
382 403 public MtasSpanSequenceQueryWeight(SpanWeight spanWeight,
383 404 boolean optional) {
... ...
src/mtas/search/spans/MtasSpanStartQuery.java
... ... @@ -21,7 +21,7 @@ import mtas.search.spans.util.MtasSpanQuery;
21 21 public class MtasSpanStartQuery extends MtasSpanQuery {
22 22  
23 23 /** The query. */
24   - private MtasSpanQuery query;
  24 + private MtasSpanQuery clause;
25 25  
26 26 /**
27 27 * Instantiates a new mtas span start query.
... ... @@ -30,8 +30,8 @@ public class MtasSpanStartQuery extends MtasSpanQuery {
30 30 * the query
31 31 */
32 32 public MtasSpanStartQuery(MtasSpanQuery query) {
33   - super();
34   - this.query = query;
  33 + super(0, 0);
  34 + clause = query;
35 35 }
36 36  
37 37 /*
... ... @@ -42,8 +42,14 @@ public class MtasSpanStartQuery extends MtasSpanQuery {
42 42 */
43 43 @Override
44 44 public MtasSpanQuery rewrite(IndexReader reader) throws IOException {
45   - query = query.rewrite(reader);
46   - return this;
  45 + MtasSpanQuery newClause = clause.rewrite(reader);
  46 + if (newClause != clause) {
  47 + return new MtasSpanStartQuery(newClause).rewrite(reader);
  48 + } else if(newClause.getMaximumWidth()!=null && newClause.getMaximumWidth()==0) {
  49 + return newClause;
  50 + } else {
  51 + return super.rewrite(reader);
  52 + }
47 53 }
48 54  
49 55 /*
... ... @@ -56,7 +62,7 @@ public class MtasSpanStartQuery extends MtasSpanQuery {
56 62 public String toString(String field) {
57 63 StringBuilder buffer = new StringBuilder();
58 64 buffer.append(this.getClass().getSimpleName() + "([");
59   - buffer.append(this.query.toString(field));
  65 + buffer.append(clause.toString(field));
60 66 buffer.append("])");
61 67 return buffer.toString();
62 68 }
... ... @@ -68,7 +74,7 @@ public class MtasSpanStartQuery extends MtasSpanQuery {
68 74 */
69 75 @Override
70 76 public String getField() {
71   - return query.getField();
  77 + return clause.getField();
72 78 }
73 79  
74 80 /*
... ... @@ -81,7 +87,7 @@ public class MtasSpanStartQuery extends MtasSpanQuery {
81 87 @Override
82 88 public SpanWeight createWeight(IndexSearcher searcher, boolean needsScores)
83 89 throws IOException {
84   - SpanWeight spanWeight = ((SpanQuery) searcher.rewrite(query))
  90 + SpanWeight spanWeight = ((SpanQuery) searcher.rewrite(clause))
85 91 .createWeight(searcher, needsScores);
86 92 return new SpanTermWeight(spanWeight, searcher);
87 93 }
... ... @@ -162,7 +168,7 @@ public class MtasSpanStartQuery extends MtasSpanQuery {
162 168 if (getClass() != obj.getClass())
163 169 return false;
164 170 final MtasSpanStartQuery that = (MtasSpanStartQuery) obj;
165   - return query.equals(that.query);
  171 + return clause.equals(that.clause);
166 172 }
167 173  
168 174 /*
... ... @@ -173,7 +179,7 @@ public class MtasSpanStartQuery extends MtasSpanQuery {
173 179 @Override
174 180 public int hashCode() {
175 181 int h = this.getClass().getSimpleName().hashCode();
176   - h = (h * 7) ^ query.hashCode();
  182 + h = (h * 7) ^ clause.hashCode();
177 183 return h;
178 184 }
179 185  
... ...