import java.util.*; import java.io.IOException; import com.allaire.cfx.*; import org.apache.lucene.analysis.*; import org.apache.lucene.document.*; import org.apache.lucene.index.*; import org.apache.lucene.queryParser.*; import org.apache.lucene.search.*; /** * @author Aaron Johnson: ajohnson@cephas.net * Description: This CFX tag will, given a keyword(s) and * a starting/ending point, search a Lucene full text index * and return a query object to for ColdFusion to loop * over and display the results. * * Usage: */ public class lucene implements CustomTag { // for debugging public static void main(String args[]) { int startindex = 0; //the first index displayed on this page int maxpage = 50; //the maximum items displayed on this page String queryString = null; //the query entered in the previous page String indexName = "c:\\hosts\\mysite.com\\myindex"; // gather values from the command line if necessary if(args.length == 0) { System.err.println("Useage: java lucene "); return; } else { queryString = args[0]; } // Do a test of the search Hits hits; try { hits = doSearch(indexName,startindex,maxpage,queryString); System.out.println("Found " + hits.length() + " results"); Document doc; for(int i=0;i" + e.toString()); } } else { errors.add("Skipping doing the search owing to a previous error"); } // Always add the query to the page, otherwise coldfusion // will barf about our query variable not existing // Define column indexes String[] columns = { "URL", "TITLE", "SUMMARY" } ; int iUrl = 1, iTitle = 2, iSummary = 3 ; // Create a query which contains these columns com.allaire.cfx.Query q = res.addQuery(query, columns) ; // do the query.... if (errors.isEmpty() && hits != null) { thispage = maxPage; // only return up to the max the user requested if ((startIndex + maxPage) > hits.length()) { thispage = hits.length() - startIndex; } // loop over all the results, add each to the query for (int i = startIndex; i < (thispage + startIndex); i++) { Document doc = null; try { // get the next document doc = hits.doc(i); } catch (IOException ie) { errors.add("Error fetching document for result " + i + ", " + ie); } // Data entries String doctitle = null; String url = null; String docSummary = null; if(doc != null) { doctitle = doc.get("title"); // get its title if we can url = doc.get("url"); docSummary = doc.get("summary"); // use url if document title doesn't exist if ((doctitle == null) || doctitle.equals("")) { //use the url if it has no title doctitle = url; } } // add the data to the query int iRow = q.addRow() ; q.setData( iRow, iUrl, url) ; q.setData( iRow, iTitle, doctitle); q.setData( iRow, iSummary, docSummary); } } else { errors.add("No results found due to a previous error"); } // everything should be done now... if we have errors, write // those out to the calling template if (!errors.isEmpty()) { for (int i=0; i < errors.size(); i++) { res.write("

Error:" + errors.get(i) + "

\n"); } } } // Actually do the search private static Hits doSearch(String indexName, int startIndex, int maxPage, String queryString) throws Exception { IndexSearcher searcher = null; // absolute named because because Query is also an object // in the com.allaire.cfx package org.apache.lucene.search.Query luceneQuery = null; Hits hits = null; int thispage = 0; // Make a new searcher searcher = new IndexSearcher(IndexReader.open(indexName) ); if(searcher == null) { throw new Exception("Unable to open index"); } // Build up the query Analyzer analyzer = new StopAnalyzer(); luceneQuery = QueryParser.parse(queryString, "contents", analyzer); //parse the if(luceneQuery == null) { throw new Exception("Unable to build Query"); } // Do the search hits = searcher.search(luceneQuery); // Return the search return hits; } }