001: /*
002: Copyright (C) 2003-2006 Know Gate S.L. All rights reserved.
003: C/Oņa, 107 1ē2 28050 Madrid (Spain)
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions
007: are met:
008:
009: 1. Redistributions of source code must retain the above copyright
010: notice, this list of conditions and the following disclaimer.
011:
012: 2. The end-user documentation included with the redistribution,
013: if any, must include the following acknowledgment:
014: "This product includes software parts from hipergate
015: (http://www.hipergate.org/)."
016: Alternately, this acknowledgment may appear in the software itself,
017: if and wherever such third-party acknowledgments normally appear.
018:
019: 3. The name hipergate must not be used to endorse or promote products
020: derived from this software without prior written permission.
021: Products derived from this software may not be called hipergate,
022: nor may hipergate appear in their name, without prior written
023: permission.
024:
025: This library is distributed in the hope that it will be useful,
026: but WITHOUT ANY WARRANTY; without even the implied warranty of
027: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
028:
029: You should have received a copy of hipergate License with this code;
030: if not, visit http://www.hipergate.org or mail to info@hipergate.org
031: */
032:
033: package com.knowgate.lucene;
034:
035: import java.util.Arrays;
036: import java.util.Date;
037: import java.util.Comparator;
038: import java.io.IOException;
039:
040: import org.apache.lucene.document.*;
041: import org.apache.lucene.search.*;
042: import org.apache.lucene.queryParser.*;
043: import org.apache.lucene.analysis.SimpleAnalyzer;
044:
045: import com.knowgate.debug.DebugFile;
046: import com.knowgate.misc.Gadgets;
047:
048: /**
049: * Search into a Lucene full text index for bugs
050: * @author Sergio Montoro Ten
051: * @version 3.0
052: */
053: public class BugSearcher {
054:
055: public BugSearcher() {
056: }
057:
058: /**
059: * Compose a Lucene query based on given parameters
060: * @param sLuceneIndexPath String Base path for Lucene indexes excluding WorkArea and table name
061: * @param sWorkArea String GUID of WorkArea to be searched, cannot be null
062: * @param sProject String GUID f project to which bug belongs
063: * @param sReportedBy String
064: * @param sWrittenBy String
065: * @param sTitle String
066: * @param sFromDate String
067: * @param sToDate String
068: * @param sType String
069: * @param sPriority String
070: * @param sSeverity String
071: * @param sStatus String
072: * @param sText String
073: * @param sComments String
074: * @param iLimit int
075: * @param oSortBy Comparator
076: * @return BugRecord[]
077: * @throws ParseException
078: * @throws IOException
079: * @throws NullPointerException
080: */
081: public static BugRecord[] search(String sLuceneIndexPath,
082: String sWorkArea, String sProjectGUID, String sReportedBy,
083: String sWrittenBy, String sTitle, String sFromDate,
084: String sToDate, String sType, String sPriority,
085: String sSeverity, String sStatus, String sText,
086: String sComments, int iLimit, Comparator oSortBy)
087: throws ParseException, IOException, NullPointerException {
088:
089: if (null == sLuceneIndexPath)
090: throw new NullPointerException(
091: "BugSearcher.search() luceindex parameter cannot be null");
092:
093: if (null == sWorkArea)
094: throw new NullPointerException(
095: "BugSearcher.search() workarea parameter cannot be null");
096:
097: if (DebugFile.trace) {
098: DebugFile.writeln("Begin BugSearcher.search("
099: + sLuceneIndexPath + "," + sWorkArea + ","
100: + sProjectGUID + "," + sReportedBy + ","
101: + sWrittenBy + "," + sTitle + "," + sFromDate + ","
102: + sToDate + "," + sType + "," + sPriority + ","
103: + sSeverity + "," + "," + sStatus + "," + sText
104: + String.valueOf(iLimit) + ")");
105: DebugFile.incIdent();
106: }
107:
108: BugRecord[] aRetArr;
109:
110: String sQry = "workarea:" + sWorkArea;
111:
112: if (null != sProjectGUID)
113: if (sProjectGUID.length() > 0)
114: sQry += " AND container:\"" + sProjectGUID + "\"";
115:
116: if (null != sWrittenBy)
117: if (sWrittenBy.length() > 0)
118: sQry += " AND writer:\"" + sWrittenBy + "\"";
119:
120: if (null != sReportedBy)
121: if (sReportedBy.length() > 0)
122: sQry += " AND author:\""
123: + Gadgets.ASCIIEncode(sReportedBy) + "\"";
124:
125: if (null != sTitle)
126: if (sTitle.length() > 0)
127: sQry += " AND title:\"" + Gadgets.ASCIIEncode(sTitle)
128: + "\"";
129:
130: if (null != sType)
131: if (sType.length() > 0)
132: sQry += " AND type:\"" + sType + "\"";
133:
134: if (null != sStatus)
135: if (sStatus.length() > 0)
136: sQry += " AND status:\"" + sStatus + "\"";
137:
138: if (null != sPriority)
139: if (sPriority.length() > 0)
140: sQry += " AND priority:\"" + sPriority + "\"";
141:
142: if (null != sSeverity)
143: if (sSeverity.length() > 0)
144: sQry += " AND severity:\"" + sSeverity + "\"";
145:
146: if (sFromDate != null && sToDate != null)
147: sQry += " AND created:["
148: + Gadgets.removeChar(sFromDate, '-') + " TO "
149: + Gadgets.removeChar(sToDate, '-') + "]";
150: else if (sFromDate != null)
151: sQry += " AND created:["
152: + Gadgets.removeChar(sFromDate, '-')
153: + " TO 21991231]";
154: else if (sToDate != null)
155: sQry += " AND created:[19790101 TO "
156: + Gadgets.removeChar(sToDate, '-') + "]";
157:
158: if (null != sText)
159: if (sText.length() > 0)
160: sQry += " AND text:\"" + Gadgets.ASCIIEncode(sText)
161: + "\"";
162:
163: if (null != sComments)
164: if (sComments.length() > 0)
165: sQry += " AND comments:\""
166: + Gadgets.ASCIIEncode(sComments) + "\"";
167:
168: QueryParser oQpr = new QueryParser("text", new SimpleAnalyzer());
169: if (DebugFile.trace)
170: DebugFile.writeln("QueryParser.parse(" + sQry + ")");
171: Query oQry = oQpr.parse(sQry);
172:
173: if (DebugFile.trace)
174: DebugFile.writeln("new IndexSearcher(" + sLuceneIndexPath
175: + ")");
176: IndexSearcher oSearch = new IndexSearcher(sLuceneIndexPath);
177: Document oDoc;
178:
179: if (iLimit > 0) {
180: TopDocs oTopSet = oSearch.search(oQry, null, iLimit);
181: if (oTopSet.scoreDocs != null) {
182: ScoreDoc[] oTopDoc = oTopSet.scoreDocs;
183: int iDocCount = oTopDoc.length;
184: aRetArr = new BugRecord[iDocCount];
185: for (int d = 0; d < iDocCount; d++) {
186: oDoc = oSearch.doc(oTopDoc[d].doc);
187: String[] aAbstract = Gadgets.split(oSearch.doc(
188: oTopDoc[d].doc).get("abstract"), '¨');
189: aRetArr[d] = new BugRecord(Integer.parseInt(oDoc
190: .get("number")), oDoc.get("guid"), oDoc
191: .get("container"), oDoc.get("title"), oDoc
192: .get("author"), oDoc.get("created"), oDoc
193: .get("type"), oDoc.get("status"), oDoc
194: .get("priority"), oDoc.get("severity"),
195: oDoc.get("abstract"));
196: } // next
197: } else {
198: aRetArr = null;
199: }
200: } else {
201: Hits oHitSet = oSearch.search(oQry);
202: int iHitCount = oHitSet.length();
203: if (iHitCount > 0) {
204: aRetArr = new BugRecord[iHitCount];
205: for (int h = 0; h < iHitCount; h++) {
206: oDoc = oHitSet.doc(h);
207: aRetArr[h] = new BugRecord(Integer.parseInt(oDoc
208: .get("number")), oDoc.get("guid"), oDoc
209: .get("container"), oDoc.get("title"), oDoc
210: .get("author"), oDoc.get("created"), oDoc
211: .get("type"), oDoc.get("status"), oDoc
212: .get("priority"), oDoc.get("severity"),
213: oDoc.get("abstract"));
214: } // next
215: } else {
216: aRetArr = null;
217: }
218: } // fi (iLimit>0)
219:
220: if (oSortBy != null) {
221: Arrays.sort(aRetArr, oSortBy);
222: }
223:
224: if (DebugFile.trace) {
225: DebugFile.decIdent();
226: if (null == aRetArr)
227: DebugFile
228: .writeln("End BugSearcher.search() : no records found");
229: else
230: DebugFile.writeln("End BugSearcher.search() : "
231: + String.valueOf(aRetArr.length));
232: }
233: return aRetArr;
234: } // search
235: }
|