Return-Path: Delivered-To: apmail-xml-cocoon-cvs-archive@xml.apache.org Received: (qmail 87822 invoked by uid 500); 24 Jan 2002 03:20:30 -0000 Mailing-List: contact cocoon-cvs-help@xml.apache.org; run by ezmlm Precedence: bulk Reply-To: cocoon-dev@xml.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list cocoon-cvs@xml.apache.org Received: (qmail 87813 invoked by uid 500); 24 Jan 2002 03:20:30 -0000 Delivered-To: apmail-xml-cocoon2-cvs@apache.org Date: 24 Jan 2002 03:20:26 -0000 Message-ID: <20020124032026.82865.qmail@icarus.apache.org> From: vgritsenko@apache.org To: xml-cocoon2-cvs@apache.org Subject: cvs commit: xml-cocoon2/src/java/org/apache/cocoon/generation SearchGenerator.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N vgritsenko 02/01/23 19:20:25 Modified: src/java/org/apache/cocoon/generation SearchGenerator.java Log: Refactor SearchGenerator: - optimize imports - add recycle() to fix re-usage bugs - remove Hits from instance variables Revision Changes Path 1.2 +170 -168 xml-cocoon2/src/java/org/apache/cocoon/generation/SearchGenerator.java Index: SearchGenerator.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/generation/SearchGenerator.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- SearchGenerator.java 3 Jan 2002 12:31:16 -0000 1.1 +++ SearchGenerator.java 24 Jan 2002 03:20:25 -0000 1.2 @@ -1,40 +1,48 @@ -/* - * Copyright (C) The Apache Software Foundation. All rights reserved. * - * ------------------------------------------------------------------------- * - * This software is published under the terms of the Apache Software License * - * version 1.1, a copy of which has been included with this distribution in * - * the LICENSE file. * - */ +/***************************************************************************** + * Copyright (C) The Apache Software Foundation. All rights reserved. * + * ------------------------------------------------------------------------- * + * This software is published under the terms of the Apache Software License * + * version 1.1, a copy of which has been included with this distribution in * + * the LICENSE file. * + *****************************************************************************/ package org.apache.cocoon.generation; -import java.io.File; -import java.io.IOException; -import java.util.*; -import org.apache.avalon.excalibur.pool.Recyclable; +import org.apache.avalon.framework.activity.Initializable; +import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.component.ComponentException; +import org.apache.avalon.framework.component.ComponentManager; import org.apache.avalon.framework.context.Context; import org.apache.avalon.framework.context.ContextException; import org.apache.avalon.framework.context.Contextualizable; - import org.apache.avalon.framework.parameters.Parameters; +import org.apache.avalon.excalibur.pool.Recyclable; + import org.apache.cocoon.Constants; import org.apache.cocoon.ProcessingException; - -import org.apache.cocoon.components.search.*; -import org.apache.cocoon.environment.*; +import org.apache.cocoon.components.search.LuceneCocoonSearcher; +import org.apache.cocoon.components.search.LuceneXMLIndexer; +import org.apache.cocoon.components.search.LuceneCocoonPager; +import org.apache.cocoon.components.search.LuceneCocoonHelper; +import org.apache.cocoon.environment.Request; import org.apache.cocoon.environment.SourceResolver; import org.apache.lucene.analysis.Analyzer; -import org.apache.lucene.document.*; +import org.apache.lucene.document.Document; import org.apache.lucene.search.Hits; -import org.apache.lucene.store.*; +import org.apache.lucene.store.Directory; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; +import java.io.File; +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + /** * Generates an XML representation of a search result. * @@ -70,10 +78,11 @@ * * * @author Bernhard Huber - * @version CVS $Id: SearchGenerator.java,v 1.1 2002/01/03 12:31:16 giacomo Exp $ + * @author Vadim Gritsenko + * @version CVS $Id: SearchGenerator.java,v 1.2 2002/01/24 03:20:25 vgritsenko Exp $ */ public class SearchGenerator extends ComposerGenerator - implements Recyclable, Contextualizable + implements Recyclable, Contextualizable, Initializable, Disposable { /** @@ -177,6 +186,7 @@ * @since */ protected final static String RANK_ATTRIBUTE = "rank"; + /** * Attribute score of hit element. * The value describes the score of this hits, ranging between 0, and 1.0. @@ -184,6 +194,7 @@ * @since */ protected final static String SCORE_ATTRIBUTE = "score"; + /** * Attribute uri of hit element. * The value describes the uri of a document matching the search query. @@ -199,6 +210,7 @@ * @since */ protected final static String NAVIGATION_ELEMENT = "navigation"; + /** * Child element of generated xml content, ie navigation. * This element describes the start-index of page containing hits. @@ -206,6 +218,7 @@ * @since */ protected final static String NAVIGATION_PAGE_ELEMENT = "navigation-page"; + /** * Attribute has-next of navigation-page element. * The value is true if a next navigation control should be presented. @@ -213,6 +226,7 @@ * @since */ protected final static String HAS_NEXT_ATTRIBUTE = "has-next"; + /** * Attribute has-next of navigation-page element. * The value is true if a previous navigation control should be presented. @@ -220,6 +234,7 @@ * @since */ protected final static String HAS_PREVIOUS_ATTRIBUTE = "has-previous"; + /** * Attribute next-index of navigation-page element. * The value describes the start-index of the next-to-be-presented page. @@ -227,6 +242,7 @@ * @since */ protected final static String NEXT_INDEX_ATTRIBUTE = "next-index"; + /** * Attribute previous-index of navigation-page element. * The value describes the start-index of the previous-to-be-presented page. @@ -256,6 +272,7 @@ * @since */ protected final static String QUERY_STRING_PARAM = "query-string"; + /** * Default value of setup parameter query-string, ie queryString. * @@ -270,6 +287,7 @@ * @since */ protected final static String START_INDEX_PARAM = "start-index"; + /** *Description of the Field * @@ -284,6 +302,7 @@ * @since */ protected final static String START_INDEX_NEXT_PARAM = "start-next-index"; + /** *Description of the Field * @@ -298,6 +317,7 @@ * @since */ protected final static String START_INDEX_PREVIOUS_PARAM = "start-previous-index"; + /** *Description of the Field * @@ -319,12 +339,14 @@ * @since */ protected final static String PAGE_LENGTH_PARAM = "page-length"; + /** *Description of the Field * * @since */ protected final static String PAGE_LENGTH_PARAM_DEFAULT = "pageLength"; + /** *Description of the Field * @@ -332,6 +354,8 @@ */ protected final static int PAGE_LENGTH_DEFAULT = 10; + + /** * Default home directory of index directories. *

@@ -354,42 +378,6 @@ private LuceneCocoonSearcher lcs; /** - * The lucene index directory used for searching, usally this directory is - * mapped onto a filesystem directory. - * - * @since - */ - private Directory directory; - - /** - * The analyzer to use for searching. - * - * @since - */ - private Analyzer analyzer; - - /** - * Stored query paramter hitsPerPage - * - * @since - */ - private int hitsPerPage = 10; - - /** - * Result of search, storing found hits - * - * @since - */ - private Hits hits; - - /** - * Helper object storing paging info of hits - * - * @since - */ - private LuceneCocoonPager luceneCocoonPager; - - /** * Absolute filesystem directory of lucene index directory * * @since @@ -408,7 +396,7 @@ * * @since */ - private AttributesImpl atts = new AttributesImpl(); + private final AttributesImpl atts = new AttributesImpl(); /** * startIndex of query parameter @@ -425,6 +413,17 @@ private Integer pageLength = null; + // TODO: parameterize() + + /** + * Set the current ComponentManager instance used by this + * Composable. + */ + public void compose(ComponentManager manager) throws ComponentException { + super.compose(manager); +// lcs = (LuceneCocoonSearcher) this.manager.lookup(LuceneCocoonSearcher.ROLE); + } + /** * setup all members of this generator. * @@ -438,7 +437,8 @@ Request request = (Request) objectModel.get(Constants.REQUEST_OBJECT); // get the analyzer - analyzer = LuceneCocoonHelper.getAnalyzer("org.apache.lucene.analysis.standard.StandardAnalyzer"); +// Analyzer analyzer = LuceneCocoonHelper.getAnalyzer("org.apache.lucene.analysis.standard.StandardAnalyzer"); +// lcs.setAnalyzer(analyzer); param_name = par.getParameter(INDEX_PARAM, INDEX_PARAM_DEFAULT); String index_file_name = param_name; @@ -505,6 +505,11 @@ workDir = (File) context.get(Constants.CONTEXT_WORK_DIR); } + public void initialize() throws IOException { + // get the directory where the index resides +// Directory directory = LuceneCocoonHelper.getDirectory(new File(workDir, "index"), false); +// lcs.setDirectory(directory); + } /** * Generate xml content describing search results. @@ -531,7 +536,7 @@ this.contentHandler.startPrefixMapping("search", namespace); this.contentHandler.startPrefixMapping("xlink", xlinkNamespace); - generateResults(this.contentHandler); + generateResults(); // End the document. this.contentHandler.endPrefixMapping("xlink"); @@ -596,55 +601,58 @@ * taking page index, and length into account. *

* - * @param ch the ContentHandler to send SAX events to. * @since * @throws SAXException when there is a problem creating the output SAX events. * @throws ProcessingException when there is a problem obtaining the hits */ - private void generateResults(ContentHandler ch) throws SAXException, ProcessingException { + private void generateResults() throws SAXException, ProcessingException { // Make the hits - buildHits(); + LuceneCocoonPager pager = buildHits(); // The current date and time. long time = System.currentTimeMillis(); atts.clear(); - atts.addAttribute(namespace, DATE_ATTRIBUTE, DATE_ATTRIBUTE, CDATA, String.valueOf(time)); - atts.addAttribute(namespace, QUERY_STRING_ATTRIBUTE, QUERY_STRING_ATTRIBUTE, CDATA, String.valueOf(queryString)); - atts.addAttribute(namespace, START_INDEX_ATTRIBUTE, START_INDEX_ATTRIBUTE, CDATA, String.valueOf(startIndex)); - atts.addAttribute(namespace, PAGE_LENGTH_ATTRIBUTE, PAGE_LENGTH_ATTRIBUTE, CDATA, String.valueOf(pageLength)); + atts.addAttribute(namespace, DATE_ATTRIBUTE, + DATE_ATTRIBUTE, CDATA, String.valueOf(time)); + if (queryString != null && queryString.length() > 0) + atts.addAttribute(namespace, QUERY_STRING_ATTRIBUTE, + QUERY_STRING_ATTRIBUTE, CDATA, String.valueOf(queryString)); + atts.addAttribute(namespace, START_INDEX_ATTRIBUTE, + START_INDEX_ATTRIBUTE, CDATA, String.valueOf(startIndex)); + atts.addAttribute(namespace, PAGE_LENGTH_ATTRIBUTE, + PAGE_LENGTH_ATTRIBUTE, CDATA, String.valueOf(pageLength)); - ch.startElement(namespace, RESULTS_ELEMENT, RESULTS_ELEMENT, atts); + contentHandler.startElement(namespace, RESULTS_ELEMENT, RESULTS_ELEMENT, atts); // build xml from the hits - generateHits(ch); + generateHits(pager); + generateNavigation(pager); // End root element. - ch.endElement(namespace, "results", "results"); + contentHandler.endElement(namespace, "results", "results"); } /** * Generate the xml content of all hits * - * @param ch the ContentHandler to send SAX events to. + * @param pager the LuceneContentPager with the search results * @since * @throws SAXException when there is a problem creating the output SAX events. * @throws ProcessingException when there is a problem obtaining the hits */ - private void generateHits(ContentHandler ch) throws SAXException, ProcessingException { - if (luceneCocoonPager != null && luceneCocoonPager.hasNext()) { + private void generateHits(LuceneCocoonPager pager) throws SAXException, ProcessingException { + if (pager != null && pager.hasNext()) { atts.clear(); - atts.addAttribute(namespace, TOTAL_COUNT_ATTRIBUTE, TOTAL_COUNT_ATTRIBUTE, CDATA, - String.valueOf(hits.length())); - atts.addAttribute(namespace, COUNT_OF_PAGES_ATTRIBUTE, COUNT_OF_PAGES_ATTRIBUTE, CDATA, - String.valueOf(luceneCocoonPager.getCountOfPages())); - ch.startElement(namespace, HITS_ELEMENT, HITS_ELEMENT, atts); - generateHit(ch); - ch.endElement(namespace, HITS_ELEMENT, HITS_ELEMENT); - - generateNavigation(ch); + atts.addAttribute(namespace, TOTAL_COUNT_ATTRIBUTE, TOTAL_COUNT_ATTRIBUTE, + CDATA, String.valueOf(pager.getCountOfHits())); + atts.addAttribute(namespace, COUNT_OF_PAGES_ATTRIBUTE, COUNT_OF_PAGES_ATTRIBUTE, + CDATA, String.valueOf(pager.getCountOfPages())); + contentHandler.startElement(namespace, HITS_ELEMENT, HITS_ELEMENT, atts); + generateHit(pager); + contentHandler.endElement(namespace, HITS_ELEMENT, HITS_ELEMENT); } } @@ -652,17 +660,17 @@ /** * Generate the xml content for each hit. * - * @param ch the ContentHandler to send SAX events to. + * @param pager the LuceneCocoonPager with the search results. * @since * @throws SAXException when there is a problem creating the output SAX events. * @throws ProcessingException when there is a problem obtaining the hits */ - private void generateHit(ContentHandler ch) throws SAXException, ProcessingException { + private void generateHit(LuceneCocoonPager pager) throws SAXException, ProcessingException { // get the off set to start from - int counter = luceneCocoonPager.getStartIndex(); + int counter = pager.getStartIndex(); // get an list of hits which should be placed onto a single page - List l = (List) luceneCocoonPager.next(); + List l = (List) pager.next(); Iterator i = l.iterator(); for (; i.hasNext(); counter++) { LuceneCocoonPager.HitWrapper hw = (LuceneCocoonPager.HitWrapper) i.next(); @@ -677,9 +685,9 @@ String.valueOf(score)); atts.addAttribute(namespace, URI_ATTRIBUTE, URI_ATTRIBUTE, CDATA, String.valueOf(uri)); - ch.startElement(namespace, HIT_ELEMENT, HIT_ELEMENT, atts); + contentHandler.startElement(namespace, HIT_ELEMENT, HIT_ELEMENT, atts); // fix me, add here a summary of this hit - ch.endElement(namespace, HIT_ELEMENT, HIT_ELEMENT); + contentHandler.endElement(namespace, HIT_ELEMENT, HIT_ELEMENT); } } @@ -687,51 +695,42 @@ /** * Generate the navigation element. * - * @param ch Description of Parameter + * @param pager Description of Parameter * @exception SAXException Description of Exception * @exception ProcessingException Description of Exception * @since */ - private void generateNavigation(ContentHandler ch) throws SAXException, ProcessingException { - boolean has_next = false; - boolean has_previous = false; - int next_index = 0; - int previous_index = 0; - if (luceneCocoonPager != null) { - has_next = luceneCocoonPager.hasNext(); - has_previous = luceneCocoonPager.hasPrevious(); - - next_index = luceneCocoonPager.nextIndex(); - previous_index = luceneCocoonPager.previousIndex(); - } + private void generateNavigation(LuceneCocoonPager pager) throws SAXException, ProcessingException { - // generate navigation element - atts.clear(); - atts.addAttribute(namespace, TOTAL_COUNT_ATTRIBUTE, TOTAL_COUNT_ATTRIBUTE, CDATA, - String.valueOf(hits.length())); - atts.addAttribute(namespace, COUNT_OF_PAGES_ATTRIBUTE, COUNT_OF_PAGES_ATTRIBUTE, CDATA, - String.valueOf(luceneCocoonPager.getCountOfPages())); - atts.addAttribute(namespace, HAS_NEXT_ATTRIBUTE, HAS_NEXT_ATTRIBUTE, CDATA, - String.valueOf(has_next)); - atts.addAttribute(namespace, HAS_PREVIOUS_ATTRIBUTE, HAS_PREVIOUS_ATTRIBUTE, CDATA, - String.valueOf(has_previous)); - atts.addAttribute(namespace, NEXT_INDEX_ATTRIBUTE, NEXT_INDEX_ATTRIBUTE, CDATA, - String.valueOf(next_index)); - atts.addAttribute(namespace, PREVIOUS_INDEX_ATTRIBUTE, PREVIOUS_INDEX_ATTRIBUTE, CDATA, - String.valueOf(previous_index)); - ch.startElement(namespace, NAVIGATION_ELEMENT, NAVIGATION_ELEMENT, atts); - int count_of_pages = luceneCocoonPager.getCountOfPages(); - for (int i = 0, page_start_index = 0; - i < count_of_pages; - i++, page_start_index += pageLength.intValue()) { + if (pager != null) { + // generate navigation element atts.clear(); - atts.addAttribute(namespace, START_INDEX_ATTRIBUTE, START_INDEX_ATTRIBUTE, CDATA, - String.valueOf(page_start_index)); - ch.startElement(namespace, NAVIGATION_PAGE_ELEMENT, NAVIGATION_PAGE_ELEMENT, atts); - ch.endElement(namespace, NAVIGATION_PAGE_ELEMENT, NAVIGATION_PAGE_ELEMENT); + atts.addAttribute(namespace, TOTAL_COUNT_ATTRIBUTE, TOTAL_COUNT_ATTRIBUTE, + CDATA, String.valueOf(pager.getCountOfHits())); + atts.addAttribute(namespace, COUNT_OF_PAGES_ATTRIBUTE, COUNT_OF_PAGES_ATTRIBUTE, + CDATA, String.valueOf(pager.getCountOfPages())); + atts.addAttribute(namespace, HAS_NEXT_ATTRIBUTE, HAS_NEXT_ATTRIBUTE, + CDATA, String.valueOf(pager.hasNext())); + atts.addAttribute(namespace, HAS_PREVIOUS_ATTRIBUTE, HAS_PREVIOUS_ATTRIBUTE, + CDATA, String.valueOf(pager.hasPrevious())); + atts.addAttribute(namespace, NEXT_INDEX_ATTRIBUTE, NEXT_INDEX_ATTRIBUTE, + CDATA, String.valueOf(pager.nextIndex())); + atts.addAttribute(namespace, PREVIOUS_INDEX_ATTRIBUTE, PREVIOUS_INDEX_ATTRIBUTE, + CDATA, String.valueOf(pager.previousIndex())); + contentHandler.startElement(namespace, NAVIGATION_ELEMENT, NAVIGATION_ELEMENT, atts); + int count_of_pages = pager.getCountOfPages(); + for (int i = 0, page_start_index = 0; + i < count_of_pages; + i++, page_start_index += pageLength.intValue()) { + atts.clear(); + atts.addAttribute(namespace, START_INDEX_ATTRIBUTE, START_INDEX_ATTRIBUTE, + CDATA, String.valueOf(page_start_index)); + contentHandler.startElement(namespace, NAVIGATION_PAGE_ELEMENT, NAVIGATION_PAGE_ELEMENT, atts); + contentHandler.endElement(namespace, NAVIGATION_PAGE_ELEMENT, NAVIGATION_PAGE_ELEMENT); + } + // navigation is EMPTY element + contentHandler.endElement(namespace, NAVIGATION_ELEMENT, NAVIGATION_ELEMENT); } - // navigation is EMPTY element - ch.endElement(namespace, NAVIGATION_ELEMENT, NAVIGATION_ELEMENT); } @@ -741,71 +740,74 @@ * @since * @throws ProcessingException iff an error occurs */ - private void buildHits() throws ProcessingException { + private LuceneCocoonPager buildHits() throws ProcessingException { + if (queryString != null && queryString.length() != 0) { - // do the search, search results are available in hits - hits = search(queryString); + Hits hits = null; + // TODO (VG): Move parts into compose/initialize/recycle + try { + lcs = (LuceneCocoonSearcher) this.manager.lookup(LuceneCocoonSearcher.ROLE); + Analyzer analyzer = LuceneCocoonHelper.getAnalyzer("org.apache.lucene.analysis.standard.StandardAnalyzer"); + lcs.setAnalyzer(analyzer); + // get the directory where the index resides + Directory directory = LuceneCocoonHelper.getDirectory(new File(workDir, "index"), false); + lcs.setDirectory(directory); + hits = lcs.search(queryString, LuceneXMLIndexer.BODY_FIELD); + } catch (IOException ioe) { + throw new ProcessingException("IOException in search", ioe); + } catch (ComponentException ce) { + throw new ProcessingException("ComponentException in search", ce); + } finally { + if (lcs != null) { + this.manager.release(lcs); + lcs = null; + } + } + // wrap the hits by an pager help object for accessing only a range of hits - luceneCocoonPager = new LuceneCocoonPager(hits); + LuceneCocoonPager pager = new LuceneCocoonPager(hits); int start_index = START_INDEX_DEFAULT; - if (startIndex != null) { - start_index = startIndex.intValue(); + if (this.startIndex != null) { + start_index = this.startIndex.intValue(); if (start_index <= 0) { start_index = 0; } - luceneCocoonPager.setStartIndex(start_index); + pager.setStartIndex(start_index); } int page_length = PAGE_LENGTH_DEFAULT; - if (pageLength != null) { - page_length = pageLength.intValue(); + if (this.pageLength != null) { + page_length = this.pageLength.intValue(); if (page_length <= 0) { page_length = hits.length(); } - luceneCocoonPager.setCountOfHitsPerPage(page_length); + pager.setCountOfHitsPerPage(page_length); } + + return pager; } - } + return null; + } /** - * Find hits matching a query. - * - * @param query_string use this query for searching - * @return Description of the Returned Value - * @since - * @throws ProcessingException iff an error occurs + * Recycle the generator */ - private Hits search(String query_string) throws ProcessingException { - Hits hits = null; - try { - lcs = (LuceneCocoonSearcher) this.manager.lookup(LuceneCocoonSearcher.ROLE); - lcs.setAnalyzer(analyzer); - // get the directory where the index resides - if (directory == null) { - directory = LuceneCocoonHelper.getDirectory(new File(workDir, "index"), false); - } - lcs.setDirectory(directory); - hits = lcs.search(query_string, LuceneXMLIndexer.BODY_FIELD); - } catch (IOException ioe) { - // ignore ?? - throw new ProcessingException("IOException in search", ioe); - } catch (ProcessingException pe) { - // ignore ?? - throw new ProcessingException("ProcessingException in search", pe); - } catch (ComponentException ce) { - // ignore ?? - throw new ProcessingException("ComponentException in search", ce); - } finally { - if (lcs != null) { - this.manager.release(lcs); - } - lcs = null; - } + public void recycle() { + super.recycle(); + this.queryString = null; + this.startIndex = null; + this.pageLength = null; + this.index = null; + } - return hits; + public void dispose() { +// if (lcs != null) { +// this.manager.release(lcs); +// lcs = null; +// } } } ---------------------------------------------------------------------- In case of troubles, e-mail: webmaster@xml.apache.org To unsubscribe, e-mail: cocoon-cvs-unsubscribe@xml.apache.org For additional commands, e-mail: cocoon-cvs-help@xml.apache.org