001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010: package org.mmbase.storage.search.implementation;
011:
012: import java.util.*;
013: import org.mmbase.bridge.Field;
014: import org.mmbase.storage.search.*;
015:
016: /**
017: * Basic implementation.
018: *
019: * @author Rob van Maris
020: * @version $Id: BasicStringSearchConstraint.java,v 1.10 2007/02/24 21:57:51 nklasens Exp $
021: * @since MMBase-1.7
022: */
023: public class BasicStringSearchConstraint extends BasicFieldConstraint
024: implements StringSearchConstraint {
025:
026: /** The search type. */
027: private int searchType = 0;
028:
029: /** The match type. */
030: private int matchType = 0;
031:
032: /** Map storing additional parameters. */
033: private Map<String, Object> parameters = new HashMap<String, Object>(
034: 3);
035:
036: /** List of searchterms. */
037: private List<String> searchTerms = null;
038:
039: /**
040: * Creates a new instance of BasicStringSearchConstraint.
041: *
042: * @param field The associated field.
043: * @param searchType The search type.
044: * @param matchType The match type.
045: * @param searchTerms the searchterms
046: * @throws IllegalArgumentValue when an invalid argument is supplied.
047: * @see #getSearchType
048: * @see #getMatchType
049: */
050: public BasicStringSearchConstraint(StepField field, int searchType,
051: int matchType, List<String> searchTerms) {
052: this (field, searchType, matchType);
053: setSearchTerms(searchTerms);
054: }
055:
056: /**
057: * Creates a new instance of BasicStringSearchConstraint.
058: *
059: * @param field The associated field.
060: * @param searchType The search type.
061: * @param matchType The match type.
062: * @param searchTerms String containing searchterms as words separated
063: * by white space.
064: * @throws IllegalArgumentValue when an invalid argument is supplied.
065: * @see #getSearchType
066: * @see #getMatchType
067: */
068: public BasicStringSearchConstraint(StepField field, int searchType,
069: int matchType, String searchTerms) {
070: this (field, searchType, matchType);
071: setSearchTerms(searchTerms);
072: }
073:
074: /**
075: * Creates a new instance of BasicStringSearchConstraint.
076: * Private, is to be called from all other creators.
077: *
078: * @param field The associated field.
079: * @param searchType The search type.
080: * @param matchType The match type.
081: * @throws IllegalArgumentValue when an invalid argument is supplied.
082: * @see #getSearchType
083: * @see #getMatchType
084: */
085: private BasicStringSearchConstraint(StepField field,
086: int searchType, int matchType) {
087: super (field);
088: if (field.getType() != Field.TYPE_STRING
089: && field.getType() != Field.TYPE_XML) {
090: throw new IllegalArgumentException(
091: "StringSearchConstraint not allowed for this field type: "
092: + getField().getType());
093: }
094: setSearchType(searchType);
095: setMatchType(matchType);
096: }
097:
098: /**
099: * Sets the match type.
100: *
101: * @param matchType The matchtype.
102: * @return This <code>BasicStringSearchConstraint</code> instance.
103: * @throws IllegalArgumentValue when an invalid argument is supplied.
104: * @see #getMatchType
105: */
106: public BasicStringSearchConstraint setMatchType(int matchType) {
107: if (matchType != StringSearchConstraint.MATCH_TYPE_LITERAL
108: && matchType != StringSearchConstraint.MATCH_TYPE_FUZZY
109: && matchType != StringSearchConstraint.MATCH_TYPE_SYNONYM) {
110: throw new IllegalArgumentException(
111: "Invalid match type value: " + matchType);
112: }
113: this .matchType = matchType;
114: if (matchType != StringSearchConstraint.MATCH_TYPE_FUZZY) {
115: parameters.remove(StringSearchConstraint.PARAM_FUZZINESS);
116: }
117: return this ;
118: }
119:
120: /**
121: * Sets the search type.
122: *
123: * @param searchType The searchType.
124: * @return This <code>BasicStringSearchConstraint</code> instance.
125: * @throws IllegalArgumentValue when an invalid argument is supplied.
126: * @see #getSearchType
127: */
128: public BasicStringSearchConstraint setSearchType(int searchType) {
129: if (searchType != StringSearchConstraint.SEARCH_TYPE_WORD_ORIENTED
130: && searchType != StringSearchConstraint.SEARCH_TYPE_PHRASE_ORIENTED
131: && searchType != StringSearchConstraint.SEARCH_TYPE_PROXIMITY_ORIENTED) {
132: throw new IllegalArgumentException(
133: "Invalid search type value: " + searchType);
134: }
135: this .searchType = searchType;
136: if (searchType != StringSearchConstraint.SEARCH_TYPE_PROXIMITY_ORIENTED) {
137: parameters
138: .remove(StringSearchConstraint.PARAM_PROXIMITY_LIMIT);
139: }
140: return this ;
141: }
142:
143: /**
144: * Adds searchterm to list of searchterms.
145: *
146: * @param searchTerm the searchterms
147: * @return This <code>BasicStringSearchConstraint</code> instance.
148: * @throws IllegalArgumentException when an invalid argument is supplied.
149: */
150: public BasicStringSearchConstraint addSearchTerm(String searchTerm) {
151: if (searchTerm.trim().length() == 0) {
152: throw new IllegalArgumentException(
153: "Invalid search term value: \"" + searchTerm + "\"");
154: }
155: searchTerms.add(searchTerm);
156: return this ;
157: }
158:
159: /**
160: * Sets searchterms to elements in specified list.
161: *
162: * @param searchTerms the searchterms
163: * @return This <code>BasicStringSearchConstraint</code> instance.
164: */
165: public BasicStringSearchConstraint setSearchTerms(
166: List<String> searchTerms) {
167: if (searchTerms.size() == 0) {
168: throw new IllegalArgumentException(
169: "Invalid search terms value: " + searchTerms);
170: }
171: List<String> newSearchTerms = new ArrayList<String>();
172: Iterator<String> iSearchTerms = searchTerms.iterator();
173: while (iSearchTerms.hasNext()) {
174: String searchTerm = iSearchTerms.next();
175: newSearchTerms.add(searchTerm);
176: }
177: this .searchTerms = newSearchTerms;
178: return this ;
179: }
180:
181: /**
182: * Sets searchterms to searchterms in string.
183: *
184: * @param searchTerms String containing searchterms as words separated
185: * by white space.
186: * @return This <code>BasicStringSearchConstraint</code> instance.
187: * @throws IllegalArgumentException when an invalid argument is supplied.
188: */
189: public BasicStringSearchConstraint setSearchTerms(String searchTerms) {
190: if (searchTerms.trim().length() == 0) {
191: throw new IllegalArgumentException(
192: "Invalid search terms value: \"" + searchTerms
193: + "\"");
194: }
195: List<String> newSearchTerms = new ArrayList<String>();
196: StringTokenizer st = new StringTokenizer(searchTerms);
197: while (st.hasMoreTokens()) {
198: newSearchTerms.add(st.nextToken());
199: }
200: this .searchTerms = newSearchTerms;
201: return this ;
202: }
203:
204: /**
205: * Sets parameter. Ignored if parameter is not relavant to the present
206: * search- and matchtype.
207: *
208: * @param name The parameter name.
209: * @param value The parameter value.
210: * @return This <code>BasicStringSearchConstraint</code> instance.
211: * @throws IllegalArgumentValue when an invalid argument is supplied.
212: * @see #getParameters
213: */
214: public BasicStringSearchConstraint setParameter(String name,
215: Object value) {
216: if (name.equals(StringSearchConstraint.PARAM_FUZZINESS)
217: && matchType == StringSearchConstraint.MATCH_TYPE_FUZZY) {
218: if (!(value instanceof Float)) {
219: throw new IllegalArgumentException(
220: "Invalid type for parameter \"" + name + "\": "
221: + value.getClass().getName());
222: }
223: float floatValue = ((Float) value).floatValue();
224: if (floatValue < 0 || floatValue > 1) {
225: throw new IllegalArgumentException(
226: "Invalid fuzziness value: " + floatValue);
227: }
228: } else if (name
229: .equals(StringSearchConstraint.PARAM_PROXIMITY_LIMIT)
230: && searchType == StringSearchConstraint.SEARCH_TYPE_PROXIMITY_ORIENTED) {
231: if (!(value instanceof Integer)) {
232: throw new IllegalArgumentException(
233: "Invalid type for parameter \"" + name + "\": "
234: + value.getClass().getName());
235: }
236: int intValue = ((Integer) value).intValue();
237: if (intValue < 1) {
238: throw new IllegalArgumentException(
239: "Invalid proximity limit value: " + intValue);
240: }
241: } else {
242: throw new IllegalArgumentException(
243: "Invalid parameter name: \"" + name + "\"");
244: }
245: parameters.put(name, value);
246: return this ;
247: }
248:
249: // javadoc is inherited
250: public Map<String, Object> getParameters() {
251: return Collections.unmodifiableMap(parameters);
252: }
253:
254: // javadoc is inherited
255: public int getMatchType() {
256: return matchType;
257: }
258:
259: /**
260: * Returns a description of the match type
261: */
262: public String getMatchTypeDescription() {
263: try {
264: return StringSearchConstraint.MATCH_TYPE_DESCRIPTIONS[matchType];
265: } catch (IndexOutOfBoundsException ioobe) {
266: return null;
267: }
268: }
269:
270: // javadoc is inherited
271: public int getSearchType() {
272: return searchType;
273: }
274:
275: /**
276: * Returns a description of the search type
277: */
278: public String getSearchTypeDescription() {
279: try {
280: return StringSearchConstraint.SEARCH_TYPE_DESCRIPTIONS[searchType];
281: } catch (IndexOutOfBoundsException ioobe) {
282: return null;
283: }
284: }
285:
286: // javadoc is inherited
287: public List<String> getSearchTerms() {
288: return Collections.unmodifiableList(searchTerms);
289: }
290:
291: // javadoc is inherited
292: public int getBasicSupportLevel() {
293: // no basic support
294: return SearchQueryHandler.SUPPORT_NONE;
295: }
296:
297: // javadoc is inherited
298: public boolean equals(Object obj) {
299: // Must be same class (subclasses should override this)!
300: if (obj != null && obj.getClass() == getClass()) {
301: BasicStringSearchConstraint constraint = (BasicStringSearchConstraint) obj;
302: return isInverse() == constraint.isInverse()
303: && isCaseSensitive() == constraint
304: .isCaseSensitive()
305: && getField().getFieldName().equals(
306: constraint.getField().getFieldName())
307: && getField().getStep().getAlias().equals(
308: constraint.getField().getStep().getAlias())
309: && searchType == constraint.getSearchType()
310: && matchType == constraint.getMatchType()
311: && parameters.equals(constraint.parameters)
312: && searchTerms.equals(constraint.searchTerms);
313: } else {
314: return false;
315: }
316: }
317:
318: // javadoc is inherited
319: public int hashCode() {
320: return super .hashCode() + 117 * searchType + 127 * matchType
321: + 131 * parameters.hashCode() + 137
322: + searchTerms.hashCode();
323: }
324:
325: // javadoc is inherited
326: public String toString() {
327: StringBuilder sb = new StringBuilder(
328: "StringSearchConstraint(inverse:").append(isInverse())
329: .append("field:").append(getFieldName()).append(
330: ", casesensitive:").append(isCaseSensitive())
331: .append(", searchtype:").append(
332: getSearchTypeDescription()).append(
333: ", matchtype:").append(
334: getMatchTypeDescription()).append(
335: ", parameters:").append(parameters).append(
336: ", searchterms:").append(searchTerms).append(
337: ")");
338: return sb.toString();
339: }
340: }
|