1   /**
2    * Distribution License:
3    * JSword is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU Lesser General Public License, version 2.1 as published by
5    * the Free Software Foundation. This program is distributed in the hope
6    * that it will be useful, but WITHOUT ANY WARRANTY; without even the
7    * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU Lesser General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *       http://www.gnu.org/copyleft/lgpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * Copyright: 2005
18   *     The copyright to this program is held by it's authors.
19   *
20   * ID: $Id: LuceneQueryDecorator.java 2046 2010-12-06 21:42:24Z dmsmith $
21   */
22  package org.crosswire.jsword.index.lucene;
23  
24  import org.crosswire.common.util.StringUtil;
25  import org.crosswire.jsword.index.query.QueryDecorator;
26  
27  /**
28   * LuceneQueryDecorator represents the extension of stock Lucene syntax with
29   * passage ranges and with blurring (searching in nearby verses).
30   * 
31   * @see gnu.lgpl.License for license details.<br>
32   *      The copyright to this program is held by it's authors.
33   * @author DM Smith [ dmsmith555 at yahoo dot com]
34   */
35  public class LuceneQueryDecorator implements QueryDecorator {
36      /*
37       * (non-Javadoc)
38       * 
39       * @see
40       * org.crosswire.jsword.index.search.SearchSyntax#decorateAllWords(java.
41       * lang.String)
42       */
43      public String decorateAllWords(String queryWords) {
44          String[] words = queryWords.split(SPACE);
45          StringBuilder search = new StringBuilder();
46          search.append(PLUS);
47          search.append(StringUtil.join(words, SPACE_PLUS));
48          return search.toString();
49      }
50  
51      /*
52       * (non-Javadoc)
53       * 
54       * @see
55       * org.crosswire.jsword.index.search.SearchSyntax#decorateAnyWords(java.
56       * lang.String)
57       */
58      public String decorateAnyWords(String queryWords) {
59          // Don't need to do anything, this is the default behavior
60          return queryWords;
61      }
62  
63      /*
64       * (non-Javadoc)
65       * 
66       * @see
67       * org.crosswire.jsword.index.search.SearchSyntax#decoratePhrase(java.lang
68       * .String)
69       */
70      public String decoratePhrase(String queryWords) {
71          // This performs a best match
72          StringBuilder search = new StringBuilder();
73          search.append(QUOTE);
74          search.append(queryWords);
75          search.append(QUOTE);
76          return search.toString();
77      }
78  
79      /*
80       * (non-Javadoc)
81       * 
82       * @see
83       * org.crosswire.jsword.index.search.SearchSyntax#decorateNotWords(java.
84       * lang.String)
85       */
86      public String decorateNotWords(String queryWords) {
87          String[] words = queryWords.split(SPACE);
88          StringBuilder search = new StringBuilder();
89          search.append(MINUS);
90          search.append(StringUtil.join(words, SPACE_MINUS));
91          return search.toString();
92      }
93  
94      /*
95       * (non-Javadoc)
96       * 
97       * @see
98       * org.crosswire.jsword.index.search.SearchSyntax#decorateRange(java.lang
99       * .String)
100      */
101     public String decorateRange(String queryWords) {
102         StringBuilder search = new StringBuilder();
103         search.append(PLUS);
104         search.append(OPEN);
105         search.append(queryWords);
106         search.append(CLOSE);
107         return search.toString();
108     }
109 
110     /*
111      * (non-Javadoc)
112      * 
113      * @see
114      * org.crosswire.jsword.index.search.SearchSyntax#decorateSpellWords(java
115      * .lang.String)
116      */
117     public String decorateSpellWords(String queryWords) {
118         String[] words = queryWords.split(SPACE);
119         StringBuilder search = new StringBuilder(StringUtil.join(words, FUZZY_SPACE));
120         search.append(FUZZY);
121         return search.toString();
122     }
123 
124     /*
125      * (non-Javadoc)
126      * 
127      * @see
128      * org.crosswire.jsword.index.search.SearchSyntax#decorateStartWords(java
129      * .lang.String)
130      */
131     public String decorateStartWords(String queryWords) {
132         String[] words = queryWords.split(SPACE);
133         StringBuilder search = new StringBuilder(StringUtil.join(words, WILD_SPACE));
134         search.append(WILD);
135         return search.toString();
136     }
137 
138     /**
139      * In our parsing we use space quite a lot and this ensures there is only one.
140      */
141     private static final String SPACE = " ";
142     private static final char QUOTE = '"';
143     private static final char PLUS = '+';
144     private static final String SPACE_PLUS = " +";
145 
146     private static final char MINUS = '-';
147     private static final String SPACE_MINUS = " -";
148 
149     private static final char OPEN = '[';
150     private static final char CLOSE = ']';
151 
152     private static final char FUZZY = '~';
153     private static final String FUZZY_SPACE = "~ ";
154 
155     private static final char WILD = '*';
156     private static final String WILD_SPACE = "* ";
157 
158 }
159