pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / queryparser / src / java / org / apache / lucene / queryParser / ext / Extensions.java
1 package org.apache.lucene.queryParser.ext;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 import java.util.HashMap;
20 import java.util.Map;
21
22 import org.apache.lucene.queryParser.QueryParser;
23
24 /**
25  * The {@link Extensions} class represents an extension mapping to associate
26  * {@link ParserExtension} instances with extension keys. An extension key is a
27  * string encoded into a Lucene standard query parser field symbol recognized by
28  * {@link ExtendableQueryParser}. The query parser passes each extension field
29  * token to {@link #splitExtensionField(String, String)} to separate the
30  * extension key from the field identifier.
31  * <p>
32  * In addition to the key to extension mapping this class also defines the field
33  * name overloading scheme. {@link ExtendableQueryParser} uses the given
34  * extension to split the actual field name and extension key by calling
35  * {@link #splitExtensionField(String, String)}. To change the order or the key
36  * / field name encoding scheme users can subclass {@link Extensions} to
37  * implement their own.
38  * 
39  * @see ExtendableQueryParser
40  * @see ParserExtension
41  */
42 public class Extensions {
43   private final Map<String,ParserExtension> extensions = new HashMap<String,ParserExtension>();
44   private final char extensionFieldDelimiter;
45   /**
46    * The default extension field delimiter character. This constant is set to
47    * ':'
48    */
49   public static final char DEFAULT_EXTENSION_FIELD_DELIMITER = ':';
50
51   /**
52    * Creates a new {@link Extensions} instance with the
53    * {@link #DEFAULT_EXTENSION_FIELD_DELIMITER} as a delimiter character.
54    */
55   public Extensions() {
56     this(DEFAULT_EXTENSION_FIELD_DELIMITER);
57   }
58
59   /**
60    * Creates a new {@link Extensions} instance
61    * 
62    * @param extensionFieldDelimiter
63    *          the extensions field delimiter character
64    */
65   public Extensions(char extensionFieldDelimiter) {
66     this.extensionFieldDelimiter = extensionFieldDelimiter;
67   }
68
69   /**
70    * Adds a new {@link ParserExtension} instance associated with the given key.
71    * 
72    * @param key
73    *          the parser extension key
74    * @param extension
75    *          the parser extension
76    */
77   public void add(String key, ParserExtension extension) {
78     this.extensions.put(key, extension);
79   }
80
81   /**
82    * Returns the {@link ParserExtension} instance for the given key or
83    * <code>null</code> if no extension can be found for the key.
84    * 
85    * @param key
86    *          the extension key
87    * @return the {@link ParserExtension} instance for the given key or
88    *         <code>null</code> if no extension can be found for the key.
89    */
90   public final ParserExtension getExtension(String key) {
91     return this.extensions.get(key);
92   }
93
94   /**
95    * Returns the extension field delimiter
96    * 
97    * @return the extension field delimiter
98    */
99   public char getExtensionFieldDelimiter() {
100     return extensionFieldDelimiter;
101   }
102
103   /**
104    * Splits a extension field and returns the field / extension part as a
105    * {@link Pair}. This method tries to split on the first occurrence of the
106    * extension field delimiter, if the delimiter is not present in the string
107    * the result will contain a <code>null</code> value for the extension key and
108    * the given field string as the field value. If the given extension field
109    * string contains no field identifier the result pair will carry the given
110    * default field as the field value.
111    * 
112    * @param defaultField
113    *          the default query field
114    * @param field
115    *          the extension field string
116    * @return a {@link Pair} with the field name as the {@link Pair#cur} and the
117    *         extension key as the {@link Pair#cud}
118    */
119   public Pair<String,String> splitExtensionField(String defaultField,
120       String field) {
121     int indexOf = field.indexOf(this.extensionFieldDelimiter);
122     if (indexOf < 0)
123       return new Pair<String,String>(field, null);
124     final String indexField = indexOf == 0 ? defaultField : field.substring(0,
125         indexOf);
126     final String extensionKey = field.substring(indexOf + 1);
127     return new Pair<String,String>(indexField, extensionKey);
128
129   }
130
131   /**
132    * Escapes an extension field. The default implementation is equivalent to
133    * {@link QueryParser#escape(String)}.
134    * 
135    * @param extfield
136    *          the extension field identifier
137    * @return the extension field identifier with all special chars escaped with
138    *         a backslash character.
139    */
140   public String escapeExtensionField(String extfield) {
141     return QueryParser.escape(extfield);
142   }
143
144   /**
145    * Builds an extension field string from a given extension key and the default
146    * query field. The default field and the key are delimited with the extension
147    * field delimiter character. This method makes no assumption about the order
148    * of the extension key and the field. By default the extension key is
149    * appended to the end of the returned string while the field is added to the
150    * beginning. Special Query characters are escaped in the result.
151    * <p>
152    * Note: {@link Extensions} subclasses must maintain the contract between
153    * {@link #buildExtensionField(String)} and
154    * {@link #splitExtensionField(String, String)} where the latter inverts the
155    * former.
156    * </p>
157    */
158   public String buildExtensionField(String extensionKey) {
159     return buildExtensionField(extensionKey, "");
160   }
161
162   /**
163    * Builds an extension field string from a given extension key and the
164    * extensions field. The field and the key are delimited with the extension
165    * field delimiter character. This method makes no assumption about the order
166    * of the extension key and the field. By default the extension key is
167    * appended to the end of the returned string while the field is added to the
168    * beginning. Special Query characters are escaped in the result.
169    * <p>
170    * Note: {@link Extensions} subclasses must maintain the contract between
171    * {@link #buildExtensionField(String, String)} and
172    * {@link #splitExtensionField(String, String)} where the latter inverts the
173    * former.
174    * </p>
175    * 
176    * @param extensionKey
177    *          the extension key
178    * @param field
179    *          the field to apply the extension on.
180    * @return escaped extension field identifier
181    * @see #buildExtensionField(String) to use the default query field
182    */
183   public String buildExtensionField(String extensionKey, String field) {
184     StringBuilder builder = new StringBuilder(field);
185     builder.append(this.extensionFieldDelimiter);
186     builder.append(extensionKey);
187     return escapeExtensionField(builder.toString());
188   }
189
190   /**
191    * This class represents a generic pair.
192    * 
193    * @param <Cur>
194    *          the pairs first element
195    * @param <Cud>
196    *          the pairs last element of the pair.
197    */
198   public static class Pair<Cur,Cud> {
199
200     public final Cur cur;
201     public final Cud cud;
202
203     /**
204      * Creates a new Pair
205      * 
206      * @param cur
207      *          the pairs first element
208      * @param cud
209      *          the pairs last element
210      */
211     public Pair(Cur cur, Cud cud) {
212       this.cur = cur;
213       this.cud = cud;
214     }
215   }
216
217 }