|
|||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
SpecialQueryParser.java | 35% | 44.4% | 50% | 41.2% |
|
1 | /* | |
2 | * Licensed to the Apache Software Foundation (ASF) under one or more | |
3 | * contributor license agreements. See the NOTICE file distributed with | |
4 | * this work for additional information regarding copyright ownership. | |
5 | * The ASF licenses this file to You under the Apache License, Version 2.0 | |
6 | * (the "License"); you may not use this file except in compliance with | |
7 | * the License. You may obtain a copy of the License at | |
8 | * | |
9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
10 | * | |
11 | * Unless required by applicable law or agreed to in writing, software | |
12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | * See the License for the specific language governing permissions and | |
15 | * limitations under the License. | |
16 | * | |
17 | * $Id: SpecialQueryParser.java 710170 2008-11-03 21:35:52Z natalia $ | |
18 | */ | |
19 | ||
20 | package org.apache.xindice.core.query.ftsearch; | |
21 | ||
22 | import org.apache.lucene.analysis.Analyzer; | |
23 | import org.apache.lucene.queryParser.CharStream; | |
24 | import org.apache.lucene.queryParser.QueryParser; | |
25 | import org.apache.lucene.queryParser.QueryParserTokenManager; | |
26 | import org.apache.lucene.search.BooleanClause; | |
27 | import org.apache.lucene.search.Query; | |
28 | ||
29 | import java.util.List; | |
30 | ||
31 | /** | |
32 | * Specialized parser for text queries that ignores query clauses that have | |
33 | * 'prohibited' modifier. This is only used for XPath full text search | |
34 | * extention function to search existing text index, if any. | |
35 | * | |
36 | * @version $Revision: 710170 $, $Date: 2008-11-03 21:35:52 +0000 (Mon, 03 Nov 2008) $ | |
37 | */ | |
38 | public class SpecialQueryParser extends QueryParser { | |
39 | private static final int CONJ_AND = 1; | |
40 | private static final int CONJ_OR = 2; | |
41 | ||
42 | private static final int MOD_NOT = 10; | |
43 | private static final int MOD_REQ = 11; | |
44 | ||
45 | 9 | public SpecialQueryParser(String f, Analyzer a) { |
46 | 9 | super(f, a); |
47 | } | |
48 | ||
49 | 0 | public SpecialQueryParser(CharStream stream) { |
50 | 0 | super(stream); |
51 | } | |
52 | ||
53 | 0 | public SpecialQueryParser(QueryParserTokenManager tm) { |
54 | 0 | super(tm); |
55 | } | |
56 | ||
57 | /** | |
58 | * This method is slightly modified copy of superclass method, where it ignores | |
59 | * boolean clauses that have 'prohibited' modifier. | |
60 | * @see QueryParser#addClause(java.util.Vector, int, int, org.apache.lucene.search.Query) | |
61 | */ | |
62 | 9 | protected void addClause(List clauses, int conj, int mods, Query q) { |
63 | ||
64 | // If this term is introduced by AND, make the preceding term required, | |
65 | // unless it's already prohibited | |
66 | 9 | if (clauses.size() > 0 && conj == CONJ_AND) { |
67 | 0 | BooleanClause c = (BooleanClause) clauses.get(clauses.size()-1); |
68 | 0 | if (!c.isProhibited()) |
69 | 0 | c.setOccur(BooleanClause.Occur.MUST); |
70 | } | |
71 | ||
72 | 9 | if (clauses.size() > 0 && getDefaultOperator() == AND_OPERATOR && conj == CONJ_OR) { |
73 | // If this term is introduced by OR, make the preceding term optional, | |
74 | // unless it's prohibited (that means we leave -a OR b but +a OR b-->a OR b) | |
75 | // notice if the input is a OR b, first term is parsed as required; without | |
76 | // this modification a OR b would parsed as +a OR b | |
77 | 0 | BooleanClause c = (BooleanClause) clauses.get(clauses.size()-1); |
78 | 0 | if (!c.isProhibited()) |
79 | 0 | c.setOccur(BooleanClause.Occur.SHOULD); |
80 | } | |
81 | ||
82 | // We might have been passed a null query; the term might have been | |
83 | // filtered away by the analyzer. | |
84 | 9 | if (q == null) |
85 | 0 | return; |
86 | ||
87 | 9 | boolean required, prohibited; |
88 | 9 | if (getDefaultOperator() == OR_OPERATOR) { |
89 | // We set REQUIRED if we're introduced by AND or +; PROHIBITED if | |
90 | // introduced by NOT or -; make sure not to set both. | |
91 | 9 | prohibited = (mods == MOD_NOT); |
92 | 9 | required = (mods == MOD_REQ); |
93 | 9 | if (conj == CONJ_AND && !prohibited) { |
94 | 0 | required = true; |
95 | } | |
96 | } else { | |
97 | // We set PROHIBITED if we're introduced by NOT or -; We set REQUIRED | |
98 | // if not PROHIBITED and not introduced by OR | |
99 | 0 | prohibited = (mods == MOD_NOT); |
100 | 0 | required = (!prohibited && conj != CONJ_OR); |
101 | } | |
102 | 9 | if (required && !prohibited) { |
103 | 0 | clauses.add(new BooleanClause(q, BooleanClause.Occur.MUST)); |
104 | 9 | } else if (!required && !prohibited) { |
105 | 9 | clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD)); |
106 | 0 | } else if (required && prohibited) { |
107 | 0 | throw new RuntimeException("Clause cannot be both required and prohibited"); |
108 | } | |
109 | } | |
110 | } |
|