/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* See LICENSE.txt included in this distribution for the specific
* language governing permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at LICENSE.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2011 Jens Elkner.
*/
/**
* complexity from UI design.
*
* @author Jens Elkner
* @version $Revision$
*/
public class SearchHelper {
/** opengrok's data root: used to find the search index file */
/** context path, i.e. the applications context path (usually /source) to
* use when generating a redirect URL */
/** piggyback: the source root directory. */
/** piggyback: the eftar filereader to use. */
/** the result cursor start index, i.e. where to start displaying results */
public int start;
/** max. number of result items to show */
public int maxItems;
/** the QueryBuilder used to create the query */
/** the order to use to ordery query results */
/** if {@code true} multi-threaded search will be used. */
public boolean parallel;
/** Indicate, whether this is search from a cross reference. If {@code true}
* {@link #executeQuery()} sets {@link #redirect} if certain conditions are
* met. */
public boolean isCrossRefSearch;
/** if not {@code null}, the consumer should redirect the client to a
* separate result page denoted by the value of this field. Automatically
* set via {@link #prepareExec(SortedSet)} and {@link #executeQuery()}. */
/** if not {@code null}, the UI should show this error message and stop
* processing the search. Automatically set via {@link #prepareExec(SortedSet)}
* and {@link #executeQuery()}.*/
* {@link #prepareExec(SortedSet)}. */
/** list of docs which result from the executing the query */
/** total number of hits */
public int totalHits;
/** the query created by the used {@link QueryBuilder} via
* {@link #prepareExec(SortedSet)}. */
/** the lucene sort instruction based on {@link #order} created via
* {@link #prepareExec(SortedSet)}. */
/** projects to use to setup indexer searchers. Usually setup via
* {@link #prepareExec(SortedSet)}. */
/** opengrok summary context. Usually created via {@link #prepareSummary()}. */
/** result summarizer usually created via {@link #prepareSummary()}. */
/** history context usually created via {@link #prepareSummary()}.*/
/** Default query parse error message prefix */
/**
* Create the searcher to use wrt. to currently set parameters and the given
* projects. Does not produce any {@link #redirect} link. It also does
* nothing if {@link #redirect} or {@link #errorMsg} have a none-{@code null}
* value.
* <p>
* <ul>
* <li>{@link #builder}</li>
* <li>{@link #dataRoot}</li>
* <li>{@link #order} (falls back to relevance if unset)</li>
* <li>{@link #parallel} (default: false)</li>
* </ul>
* <ul>
* <li>{@link #query}</li>
* <li>{@link #searcher}</li>
* <li>{@link #sort}</li>
* <li>{@link #projects}</li>
* <li>{@link #errorMsg} if an error occurs</li>
* </ul>
*
* @param projects project to use query. If empty, a none-project opengrok
* @return this instance
*/
@SuppressWarnings("resource")
return this;
}
// the Query created by the QueryBuilder
try {
errorMsg = "No project selected!";
return this;
}
//no project setup
// just 1 project selected
} else {
//more projects
int ii = 0;
//TODO might need to rewrite to Project instead of
// String , need changes in projects.jspf too
}
if (parallel) {
//TODO there might be a better way for counting this
int noThreads =
}
: new IndexSearcher(searchables);
}
// TODO check if below is somehow reusing sessions so we don't
// requery again and again, I guess 2min timeout sessions could be
// usefull, since you click on the next page within 2mins, if not,
// then wait ;)
switch (order) {
case LASTMODIFIED:
break;
case BY_PATH:
break;
default:
break;
}
} catch (ParseException e) {
} catch (FileNotFoundException e) {
// errorMsg = "Index database(s) not found: " + e.getMessage();
errorMsg = "Index database(s) not found.";
} catch (Exception e) {
errorMsg = e.getMessage();
}
return this;
}
/**
* Start the search prepared by {@link #prepareExec(SortedSet)}.
* It does nothing if {@link #redirect} or {@link #errorMsg} have a
* none-{@code null} value.
* <p>
* <ul>
* <li>all fields required for and populated by {@link #prepareExec(SortedSet)})</li>
* <li>{@link #start} (default: 0)</li>
* <li>{@link #maxItems} (default: 0)</li>
* <li>{@link #isCrossRefSearch} (default: false)</li>
* </ul>
* <ul>
* <li>{@link #hits} (see {@link TopFieldDocs#scoreDocs})</li>
* <li>{@link #totalHits} (see {@link TopFieldDocs#totalHits})</li>
* <li>{@link #contextPath}</li>
* <li>{@link #errorMsg} if an error occurs</li>
* <li>{@link #redirect} if certain conditions are met</li>
* </ul>
* @return this instance
*/
return this;
}
try {
// Bug #3900: Check if this is a search for a single term, and that
// term is a definition. If that's the case, and we only have one match,
// we'll generate a direct link instead of a listing.
boolean isSingleDefinitionSearch =
// Attempt to create a direct link to the definition if we search for
// one single definition term AND we have exactly one match AND there
// is only one definition of that symbol in the document that matches.
boolean uniqueDefinition = false;
uniqueDefinition = true;
}
}
}
// @TODO fix me. I should try to figure out where the exact hit is
// instead of returning a page with just _one_ entry in....
}
} catch (BooleanQuery.TooManyClauses e) {
errorMsg = "Too many results for wildcard!";
} catch (Exception e) {
errorMsg = e.getMessage();
}
return this;
}
return;
}
continue;
}
}
}
/**
* If a search did not return a hit, one may use this method to obtain
* suggestions for a new search.
*
* <p>
* <ul>
* <li>{@link #projects}</li>
* <li>{@link #dataRoot}</li>
* <li>{@link #builder}</li>
* </ul>
* @return a possible empty list of sugeestions.
*/
@SuppressWarnings("resource")
}
spellIndex = new File[]{
};
} else {
int ii = 0;
}
}
continue;
}
try {
// TODO it seems the only true spellchecker is for
// below field, see IndexDatabase
// createspellingsuggestions ...
}
} catch (IOException e) {
+ e.getMessage());
} finally {
}
}
return res;
}
/**
* Prepare the fields to support printing a fullblown summary. Does nothing
* if {@link #redirect} or {@link #errorMsg} have a none-{@code null} value.
*
* <p>
* <ul>
* <li>{@link #query}</li>
* <li>{@link #builder}</li>
* </ul>
* Otherwise the following fields are set (includes {@code null}):
* <ul>
* <li>{@link #sourceContext}</li>
* <li>{@link #summerizer}</li>
* <li>{@link #historyContext}</li>
* </ul>
*
* @return this instance.
*/
return this;
}
try {
} catch (Exception e) {
}
try {
} catch (Exception e) {
}
return this;
}
/**
* Free any resources associated with this helper (that includes closing
* the used {@link #searcher}).
*/
public void destroy() {
}
try {
} catch (SecurityException se) {
}
}
}
}
}