Source Code Cross Referenced for SearchGenerator.java in  » Content-Management-System » apache-lenya-2.0 » org » apache » cocoon » generation » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Content Management System » apache lenya 2.0 » org.apache.cocoon.generation 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         *
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         *
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:        package org.apache.cocoon.generation;
018:
019:        import org.apache.avalon.framework.context.Context;
020:        import org.apache.avalon.framework.context.ContextException;
021:        import org.apache.avalon.framework.context.Contextualizable;
022:        import org.apache.avalon.framework.parameters.Parameters;
023:        import org.apache.avalon.framework.service.ServiceException;
024:
025:        import org.apache.cocoon.Constants;
026:        import org.apache.cocoon.ProcessingException;
027:        import org.apache.cocoon.components.search.LuceneCocoonHelper;
028:        import org.apache.cocoon.components.search.LuceneCocoonPager;
029:        import org.apache.cocoon.components.search.LuceneCocoonSearcher;
030:        import org.apache.cocoon.components.search.LuceneXMLIndexer;
031:        import org.apache.cocoon.environment.ObjectModelHelper;
032:        import org.apache.cocoon.environment.Request;
033:        import org.apache.cocoon.environment.SourceResolver;
034:
035:        import org.apache.lucene.analysis.Analyzer;
036:        import org.apache.lucene.document.Document;
037:        import org.apache.lucene.document.Field;
038:        import org.apache.lucene.search.Hits;
039:        import org.apache.lucene.store.Directory;
040:
041:        import org.xml.sax.SAXException;
042:        import org.xml.sax.helpers.AttributesImpl;
043:
044:        import java.io.File;
045:        import java.io.IOException;
046:        import java.util.Enumeration;
047:        import java.util.Iterator;
048:        import java.util.List;
049:        import java.util.Map;
050:
051:        /**
052:         * Generates an XML representation of a search result.
053:         *
054:         * <p>
055:         *  This generator generates xml content representening an XML search.
056:         *  The generated xml content contains the search result,
057:         *  the search query information, and navigation information about the
058:         *  search results.
059:         *  The query is sent to the generator, either via the 'queryString' request parameter
060:         *  or the 'query' SiteMap parameter. The sitemap overides the request.
061:         * </p>
062:         *
063:         * <p>
064:         *  Search xml sample generated by this generator:
065:         * </p>
066:         * <pre><tt>
067:         * &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
068:         *
069:         * &lt;search:results date=&quot;1008437081064&quot; query-string=&quot;cocoon&quot;
070:         *     start-index=&quot;0&quot; page-length=&quot;10&quot;
071:         *     xmlns:search=&quot;http://apache.org/cocoon/search/1.0&quot;
072:         *     xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot;&gt;
073:         *   &lt;search:hits total-count=&quot;125&quot; count-of-pages=&quot;13&quot;&gt;
074:         *     &lt;search:hit rank=&quot;0&quot; score=&quot;1.0&quot;
075:         *         uri=&quot;http://localhost:8080/cocoon/documents/hosting.html&quot;&gt;
076:         *       &lt;search:field name="title"&gt;Document Title&lt;search:field/&gt;
077:         *     &lt;search:hit/&gt;
078:         *     ...
079:         *   &lt;/search:hits&gt;
080:         *
081:         *   &lt;search:navigation total-count=&quot;125&quot; count-of-pages=&quot;13&quot;
082:         *       has-next=&quot;true&quot; has-previous=&quot;false&quot; next-index=&quot;10&quot; previous-index=&quot;0&quot;&gt;
083:         *     &lt;search:navigation-page start-index=&quot;0&quot;/&gt;
084:         *     &lt;search:navigation-page start-index=&quot;10&quot;/&gt;
085:         *     ...
086:         *     &lt;search:navigation-page start-index=&quot;120&quot;/&gt;
087:         *   &lt;/search:navigation&gt;
088:         * &lt;/search:results&gt;
089:         * </tt></pre>
090:         *
091:         * @author <a href="mailto:berni_huber@a1.net">Bernhard Huber</a>
092:         * @author <a href="mailto:vgritsenko@apache.org">Vadim Gritsenko</a>
093:         * @author <a href="mailto:jeremy@apache.org">Jeremy Quinn</a>
094:         * @author <a href="mailto:conal@nzetc.org">Conal Tuohy</a>
095:         * @version CVS $Id: SearchGenerator.java 465914 2006-10-19 22:38:41Z joerg $
096:         */
097:        public class SearchGenerator extends ServiceableGenerator implements 
098:                Contextualizable {
099:
100:            /**
101:             * The XML namespace for the output document.
102:             */
103:            protected final static String NAMESPACE = "http://apache.org/cocoon/search/1.0";
104:
105:            /**
106:             * The XML namespace prefix for the output document.
107:             */
108:            protected final static String PREFIX = "search";
109:
110:            /**
111:             * The XML namespace for xlink
112:             */
113:            protected final static String XLINK_NAMESPACE = "http://www.w3.org/1999/xlink";
114:
115:            /**
116:             * Description of the Field
117:             */
118:            protected final static String CDATA = "CDATA";
119:
120:            /**
121:             * Name of root element of generated xml content, ie <code>results</code>.
122:             */
123:            protected final static String RESULTS_ELEMENT = "results";
124:
125:            /**
126:             * Qualified name of root element of generated xml content, ie <code>search:results</code>.
127:             */
128:            protected final static String Q_RESULTS_ELEMENT = PREFIX + ":"
129:                    + RESULTS_ELEMENT;
130:
131:            /**
132:             * Attribute <code>date</code> of <code>results</code> element.
133:             * It contains the date a long value, indicating when a search
134:             * generated this xml content.
135:             */
136:            protected final static String DATE_ATTRIBUTE = "date";
137:
138:            /**
139:             * Attribute <code>query-string</code> of <code>results</code> element.
140:             * Echos the <code>queryString</code> query parameter.
141:             */
142:            protected final static String QUERY_STRING_ATTRIBUTE = "query-string";
143:
144:            /**
145:             * Attribute <code>start-index</code> of <code>results</code> element.
146:             * Echoes the <code>startIndex</code> query parameter.
147:             */
148:            protected final static String START_INDEX_ATTRIBUTE = "start-index";
149:
150:            /**
151:             * Attribute <code>page-length</code> of <code>results</code> element.
152:             * Echoes the <code>pageLenth</code> query parameter.
153:             */
154:            protected final static String PAGE_LENGTH_ATTRIBUTE = "page-length";
155:
156:            /**
157:             * Attribute <code>name</code> of <code>hit</code> element.
158:             */
159:            protected final static String NAME_ATTRIBUTE = "name";
160:
161:            /**
162:             * Child element of generated xml content, ie <code>hits</code>.
163:             * This element describes all hits.
164:             */
165:            protected final static String HITS_ELEMENT = "hits";
166:
167:            /**
168:             * QName of child element of generated xml content, ie <code>search:hits</code>.
169:             * This element describes all hits.
170:             */
171:            protected final static String Q_HITS_ELEMENT = PREFIX + ":"
172:                    + HITS_ELEMENT;
173:
174:            /**
175:             * Attribute <code>total-count</code> of <code>hits</code> element.
176:             * The value describes total number of hits found by the search engine.
177:             */
178:            protected final static String TOTAL_COUNT_ATTRIBUTE = "total-count";
179:
180:            /**
181:             * Attribute <code>count-of-pages</code> of <code>hits</code> element.
182:             * The value describes number of pages needed for all hits.
183:             */
184:            protected final static String COUNT_OF_PAGES_ATTRIBUTE = "count-of-pages";
185:
186:            /**
187:             * Child element of generated xml content, ie <code>hit</code>.
188:             * This element describes a single hit.
189:             */
190:            protected final static String HIT_ELEMENT = "hit";
191:
192:            /**
193:             * QName of child element of generated xml content, ie <code>search:hit</code>.
194:             * This element describes a single hit.
195:             */
196:            protected final static String Q_HIT_ELEMENT = PREFIX + ":"
197:                    + HIT_ELEMENT;
198:
199:            /**
200:             * Attribute <code>rank</code> of <code>hit</code> element.
201:             * The value describes the count index of this hits, ranging between 0, and
202:             * total-count minus 1.
203:             */
204:            protected final static String RANK_ATTRIBUTE = "rank";
205:
206:            /**
207:             * Attribute <code>score</code> of <code>hit</code> element.
208:             * The value describes the score of this hits, ranging between 0, and 1.0.
209:             */
210:            protected final static String SCORE_ATTRIBUTE = "score";
211:
212:            /**
213:             * Attribute <code>uri</code> of <code>hit</code> element.
214:             * The value describes the uri of a document matching the search query.
215:             */
216:            protected final static String URI_ATTRIBUTE = "uri";
217:
218:            /**
219:             * Child element <code>field</code> of the <code>hit</code> element.
220:             * This element contains value of the stored field of a hit.
221:             */
222:            protected final static String FIELD_ELEMENT = "field";
223:
224:            /**
225:             * QName of child element <code>search:field</code> of the <code>hit</code> element.
226:             */
227:            protected final static String Q_FIELD_ELEMENT = PREFIX + ":"
228:                    + FIELD_ELEMENT;
229:
230:            /**
231:             * Child element of generated xml content, ie <code>navigation</code>.
232:             * This element describes some hints for easier navigation.
233:             */
234:            protected final static String NAVIGATION_ELEMENT = "navigation";
235:
236:            /**
237:             * QName of child element of generated xml content, ie <code>search:navigation</code>.
238:             */
239:            protected final static String Q_NAVIGATION_ELEMENT = PREFIX + ":"
240:                    + NAVIGATION_ELEMENT;
241:
242:            /**
243:             * Child element of generated xml content, ie <code>navigation-page</code>.
244:             * This element describes the start-index of page containing hits.
245:             */
246:            protected final static String NAVIGATION_PAGE_ELEMENT = "navigation-page";
247:
248:            /**
249:             * QName of child element of generated xml content, ie <code>search:navigation-page</code>.
250:             * This element describes the start-index of page containing hits.
251:             */
252:            protected final static String Q_NAVIGATION_PAGE_ELEMENT = PREFIX
253:                    + ":" + NAVIGATION_PAGE_ELEMENT;
254:
255:            /**
256:             * Attribute <code>has-next</code> of <code>navigation-page</code> element.
257:             * The value is true if a next navigation control should be presented.
258:             */
259:            protected final static String HAS_NEXT_ATTRIBUTE = "has-next";
260:
261:            /**
262:             * Attribute <code>has-next</code> of <code>navigation-page</code> element.
263:             * The value is true if a previous navigation control should be presented.
264:             */
265:            protected final static String HAS_PREVIOUS_ATTRIBUTE = "has-previous";
266:
267:            /**
268:             * Attribute <code>next-index</code> of <code>navigation-page</code> element.
269:             * The value describes the start-index of the next-to-be-presented page.
270:             */
271:            protected final static String NEXT_INDEX_ATTRIBUTE = "next-index";
272:
273:            /**
274:             * Attribute <code>previous-index</code> of <code>navigation-page</code> element.
275:             * The value describes the start-index of the previous-to-be-presented page.
276:             */
277:            protected final static String PREVIOUS_INDEX_ATTRIBUTE = "previous-index";
278:
279:            /**
280:             * Setup parameter name of index directory, ie <code>index</code>.
281:             */
282:            protected final static String INDEX_PARAM = "index";
283:
284:            /**
285:             * Default value of setup parameter <code>index</code>, ie <code>index</code>.
286:             */
287:            protected final static String INDEX_PARAM_DEFAULT = "index";
288:
289:            /**
290:             * Setup parameter name of analyzer name, ie <code>analyzer</code>.
291:             */
292:            protected final static String ANALYZER_PARAM = "analyzer";
293:
294:            /**
295:             * Default value of analyzer parameter <code>analyzer</code>, ie <code>org.apache.lucene.analysis.standard.StandardAnalyzer</code>.
296:             */
297:            protected final static String ANALYZER_PARAM_DEFAULT = "org.apache.lucene.analysis.standard.StandardAnalyzer";
298:
299:            /**
300:             * Setup the actual query from generator parameter,
301:             * ie <code>query</code>.
302:             */
303:            protected final static String QUERY_PARAM = "query";
304:
305:            /**
306:             * Setup parameter name specifying the name of query-string query parameter,
307:             * ie <code>query-string</code>.
308:             */
309:            protected final static String QUERY_STRING_PARAM = "query-string";
310:
311:            /**
312:             * Default value of setup parameter <code>query-string</code>, ie <code>queryString</code>.
313:             */
314:            protected final static String QUERY_STRING_PARAM_DEFAULT = "queryString";
315:
316:            /**
317:             * Setup parameter name specifying the name of start-index query parameter,
318:             * ie <code>start-index</code>.
319:             */
320:            protected final static String START_INDEX_PARAM = "start-index";
321:
322:            /**
323:             * Default value of setup parameter <code>start-index</code>, ie <code>startIndex</code>.
324:             */
325:            protected final static String START_INDEX_PARAM_DEFAULT = "startIndex";
326:
327:            /**
328:             * Setup parameter name specifying the name of start-next-index query parameter,
329:             * ie <code>start-next-index</code>.
330:             */
331:            protected final static String START_INDEX_NEXT_PARAM = "start-next-index";
332:
333:            /**
334:             * Default value of setup parameter <code>start-next-index</code>, ie <code>startNextIndex</code>.
335:             */
336:            protected final static String START_INDEX_NEXT_PARAM_DEFAULT = "startNextIndex";
337:
338:            /**
339:             * Setup parameter name specifying the name of start-previous-index query parameter,
340:             * ie <code>start-previous-index</code>.
341:             */
342:            protected final static String START_INDEX_PREVIOUS_PARAM = "start-previous-index";
343:
344:            /**
345:             * Default value of setup parameter <code>start-previous-index</code>, ie <code>startPreviousIndex</code>.
346:             */
347:            protected final static String START_INDEX_PREVIOUS_PARAM_DEFAULT = "startPreviousIndex";
348:
349:            protected final static int START_INDEX_DEFAULT = 0;
350:
351:            /**
352:             * Setup parameter name specifying the name of page-length query parameter,
353:             * ie <code>page-length</code>.
354:             */
355:            protected final static String PAGE_LENGTH_PARAM = "page-length";
356:
357:            protected final static String PAGE_LENGTH_PARAM_DEFAULT = "pageLength";
358:
359:            protected final static int PAGE_LENGTH_DEFAULT = 10;
360:
361:            /**
362:             * Default home directory of index directories.
363:             * <p>
364:             *   Releative index directories specified in the setup of this generator are resolved
365:             *   relative to this directory.
366:             * </p>
367:             * <p>
368:             *   By default this directory is set to the <code>WORKING_DIR</code> of Cocoon.
369:             * </p>
370:             */
371:            private File workDir = null;
372:
373:            /**
374:             * The avalon component to use for searching.
375:             */
376:            private LuceneCocoonSearcher lcs;
377:
378:            /**
379:             * Analyzer used for searching
380:             */
381:            private String analyzer = null;
382:
383:            /**
384:             * Absolute filesystem directory of lucene index directory
385:             */
386:            private File index = null;
387:
388:            /**
389:             * Query-string to search for
390:             */
391:            private String queryString = "";
392:
393:            /**
394:             * Attributes used when generating xml content.
395:             */
396:            private final AttributesImpl atts = new AttributesImpl();
397:
398:            /**
399:             * startIndex of query parameter
400:             */
401:            private Integer startIndex = null;
402:
403:            /**
404:             * pageLength of query parameter
405:             */
406:            private Integer pageLength = null;
407:
408:            /**
409:             * Contextualize this class.
410:             *
411:             * <p>
412:             *   Especially retrieve the work directory.
413:             *   If the index directory is specified relativly, the working directory is
414:             *   used as home directory of the index directory.
415:             * </p>
416:             *
417:             * @param  context               Context to use
418:             * @exception  ContextException  If contextualizing fails.
419:             */
420:            public void contextualize(Context context) throws ContextException {
421:                // retrieve the working directory, assuming that the index may reside there
422:                workDir = (File) context.get(Constants.CONTEXT_WORK_DIR);
423:            }
424:
425:            // TODO: parameterize()
426:
427:            /**
428:             * setup all members of this generator.
429:             */
430:            public void setup(SourceResolver resolver, Map objectModel,
431:                    String src, Parameters par) throws ProcessingException,
432:                    SAXException, IOException {
433:                super .setup(resolver, objectModel, src, par);
434:
435:                try {
436:                    lcs = (LuceneCocoonSearcher) this .manager
437:                            .lookup(LuceneCocoonSearcher.ROLE);
438:                } catch (ServiceException e) {
439:                    throw new ProcessingException("Unable to lookup "
440:                            + LuceneCocoonSearcher.ROLE, e);
441:                }
442:
443:                String param_name;
444:                Request request = ObjectModelHelper.getRequest(objectModel);
445:
446:                String index_file_name = par.getParameter(INDEX_PARAM,
447:                        INDEX_PARAM_DEFAULT);
448:                if (request.getParameter(INDEX_PARAM) != null) {
449:                    index_file_name = request.getParameter(INDEX_PARAM);
450:                }
451:
452:                // now set the index
453:                index = new File(index_file_name);
454:                if (!index.isAbsolute()) {
455:                    index = new File(workDir, index.toString());
456:                }
457:
458:                // try to get the analyzer from the sitemap parameter
459:                this .analyzer = par.getParameter(ANALYZER_PARAM,
460:                        ANALYZER_PARAM_DEFAULT);
461:                if (getLogger().isDebugEnabled()) {
462:                    getLogger().debug("Analyzer is set to: " + this .analyzer);
463:                }
464:
465:                // try getting the queryString from the generator sitemap params
466:
467:                queryString = par.getParameter(QUERY_PARAM, "");
468:
469:                // try getting the queryString from the request params
470:                if (queryString.length() == 0) {
471:                    param_name = par.getParameter(QUERY_STRING_PARAM,
472:                            QUERY_STRING_PARAM_DEFAULT);
473:                    if (request.getParameter(param_name) != null) {
474:                        queryString = request.getParameter(param_name);
475:                    }
476:                }
477:                if (getLogger().isDebugEnabled()) {
478:                    getLogger()
479:                            .debug("Search index with query: " + queryString);
480:                }
481:
482:                // always try lookup the start index from the request params
483:                // get startIndex
484:                startIndex = null;
485:                param_name = par.getParameter(START_INDEX_NEXT_PARAM,
486:                        START_INDEX_NEXT_PARAM_DEFAULT);
487:                if (request.getParameter(param_name) != null) {
488:                    startIndex = createInteger(request.getParameter(param_name));
489:                }
490:
491:                if (startIndex == null) {
492:                    param_name = par.getParameter(START_INDEX_PREVIOUS_PARAM,
493:                            START_INDEX_PREVIOUS_PARAM_DEFAULT);
494:                    if (request.getParameter(param_name) != null) {
495:                        startIndex = createInteger(request
496:                                .getParameter(param_name));
497:                    }
498:                }
499:                if (startIndex == null) {
500:                    param_name = par.getParameter(START_INDEX_PARAM,
501:                            START_INDEX_PARAM_DEFAULT);
502:                    if (request.getParameter(param_name) != null) {
503:                        startIndex = createInteger(request
504:                                .getParameter(param_name));
505:                    }
506:                }
507:
508:                // get pageLength
509:                param_name = par.getParameter(PAGE_LENGTH_PARAM,
510:                        PAGE_LENGTH_PARAM_DEFAULT);
511:                if (request.getParameter(param_name) != null) {
512:                    pageLength = createInteger(request.getParameter(param_name));
513:                }
514:            }
515:
516:            /**
517:             * Generate xml content describing search results.
518:             * Entry point of the ComposerGenerator.
519:             * The xml content is generated from the hits object.
520:             *
521:             * @exception  IOException       when there is a problem reading the from file system.
522:             * @throws  SAXException         when there is a problem creating the output SAX events.
523:             * @throws  ProcessingException  when there is a problem obtaining the hits
524:             */
525:            public void generate() throws IOException, SAXException,
526:                    ProcessingException {
527:                // set default parameter value, in case of no values are set yet.
528:                if (startIndex == null) {
529:                    startIndex = new Integer(START_INDEX_DEFAULT);
530:                }
531:                if (pageLength == null) {
532:                    pageLength = new Integer(PAGE_LENGTH_DEFAULT);
533:                }
534:
535:                // Start the document and set the namespace.
536:                this .contentHandler.startDocument();
537:                this .contentHandler.startPrefixMapping(PREFIX, NAMESPACE);
538:                this .contentHandler
539:                        .startPrefixMapping("xlink", XLINK_NAMESPACE);
540:
541:                generateResults();
542:
543:                // End the document.
544:                this .contentHandler.endPrefixMapping("xlink");
545:                this .contentHandler.endPrefixMapping(PREFIX);
546:                this .contentHandler.endDocument();
547:            }
548:
549:            /**
550:             * Create an Integer.
551:             * <p>
552:             *   Create an Integer from String s, if conversion fails return null.
553:             * </p>
554:             *
555:             * @param  s  Converting s to an Integer
556:             * @return    Integer converted value originating from s, or null
557:             */
558:            private Integer createInteger(String s) {
559:                Integer i = null;
560:                try {
561:                    i = new Integer(s);
562:                } catch (NumberFormatException nfe) {
563:                    // ignore it, write only warning
564:                    if (getLogger().isWarnEnabled()) {
565:                        getLogger().warn("Cannot convert " + s + " to Integer",
566:                                nfe);
567:                    }
568:                }
569:                return i;
570:            }
571:
572:            /**
573:             * Build and generate the search results.
574:             * <p>
575:             *  First build the hits, next generate xml content from the hits,
576:             *  taking page index, and length into account.
577:             * </p>
578:             *
579:             * @throws  SAXException         when there is a problem creating the output SAX events.
580:             * @throws  ProcessingException  when there is a problem obtaining the hits
581:             */
582:            private void generateResults() throws SAXException,
583:                    ProcessingException, IOException {
584:                // Make the hits
585:                LuceneCocoonPager pager = buildHits();
586:
587:                // The current date and time.
588:                long time = System.currentTimeMillis();
589:
590:                atts.clear();
591:                atts.addAttribute("", DATE_ATTRIBUTE, DATE_ATTRIBUTE, CDATA,
592:                        String.valueOf(time));
593:                if (queryString != null && queryString.length() > 0)
594:                    atts.addAttribute("", QUERY_STRING_ATTRIBUTE,
595:                            QUERY_STRING_ATTRIBUTE, CDATA, String
596:                                    .valueOf(queryString));
597:                atts.addAttribute("", START_INDEX_ATTRIBUTE,
598:                        START_INDEX_ATTRIBUTE, CDATA, String
599:                                .valueOf(startIndex));
600:                atts.addAttribute("", PAGE_LENGTH_ATTRIBUTE,
601:                        PAGE_LENGTH_ATTRIBUTE, CDATA, String
602:                                .valueOf(pageLength));
603:
604:                contentHandler.startElement(NAMESPACE, RESULTS_ELEMENT,
605:                        Q_RESULTS_ELEMENT, atts);
606:
607:                // build xml from the hits
608:                generateHits(pager);
609:                generateNavigation(pager);
610:
611:                // End root element.
612:                contentHandler.endElement(NAMESPACE, RESULTS_ELEMENT,
613:                        Q_RESULTS_ELEMENT);
614:            }
615:
616:            /**
617:             * Generate the xml content of all hits
618:             *
619:             * @param  pager                 the LuceneContentPager with the search results
620:             * @throws  SAXException         when there is a problem creating the output SAX events.
621:             */
622:            private void generateHits(LuceneCocoonPager pager)
623:                    throws SAXException {
624:                if (pager != null) {
625:                    atts.clear();
626:                    atts.addAttribute("", TOTAL_COUNT_ATTRIBUTE,
627:                            TOTAL_COUNT_ATTRIBUTE, CDATA, String.valueOf(pager
628:                                    .getCountOfHits()));
629:                    atts.addAttribute("", COUNT_OF_PAGES_ATTRIBUTE,
630:                            COUNT_OF_PAGES_ATTRIBUTE, CDATA, String
631:                                    .valueOf(pager.getCountOfPages()));
632:                    contentHandler.startElement(NAMESPACE, HITS_ELEMENT,
633:                            Q_HITS_ELEMENT, atts);
634:                    generateHit(pager);
635:                    contentHandler.endElement(NAMESPACE, HITS_ELEMENT,
636:                            Q_HITS_ELEMENT);
637:                }
638:            }
639:
640:            /**
641:             * Generate the xml content for each hit.
642:             *
643:             * @param  pager                 the LuceneCocoonPager with the search results.
644:             * @throws  SAXException         when there is a problem creating the output SAX events.
645:             */
646:            private void generateHit(LuceneCocoonPager pager)
647:                    throws SAXException {
648:                // get the off set to start from
649:                int counter = pager.getStartIndex();
650:
651:                // get an list of hits which should be placed onto a single page
652:                List l = (List) pager.next();
653:                Iterator i = l.iterator();
654:                for (; i.hasNext(); counter++) {
655:                    LuceneCocoonPager.HitWrapper hw = (LuceneCocoonPager.HitWrapper) i
656:                            .next();
657:                    Document doc = hw.getDocument();
658:                    float score = hw.getScore();
659:                    String uri = doc.get(LuceneXMLIndexer.URL_FIELD);
660:
661:                    atts.clear();
662:                    atts.addAttribute("", RANK_ATTRIBUTE, RANK_ATTRIBUTE,
663:                            CDATA, String.valueOf(counter));
664:                    atts.addAttribute("", SCORE_ATTRIBUTE, SCORE_ATTRIBUTE,
665:                            CDATA, String.valueOf(score));
666:                    atts.addAttribute("", URI_ATTRIBUTE, URI_ATTRIBUTE, CDATA,
667:                            String.valueOf(uri));
668:                    contentHandler.startElement(NAMESPACE, HIT_ELEMENT,
669:                            Q_HIT_ELEMENT, atts);
670:                    // fix me, add here a summary of this hit
671:                    for (Enumeration e = doc.fields(); e.hasMoreElements();) {
672:                        Field field = (Field) e.nextElement();
673:                        if (field.isStored()) {
674:                            if (LuceneXMLIndexer.URL_FIELD.equals(field.name()))
675:                                continue;
676:                            atts.clear();
677:                            atts.addAttribute("", NAME_ATTRIBUTE,
678:                                    NAME_ATTRIBUTE, CDATA, field.name());
679:                            contentHandler.startElement(NAMESPACE,
680:                                    FIELD_ELEMENT, Q_FIELD_ELEMENT, atts);
681:                            String value = field.stringValue();
682:                            contentHandler.characters(value.toCharArray(), 0,
683:                                    value.length());
684:                            contentHandler.endElement(NAMESPACE, FIELD_ELEMENT,
685:                                    Q_FIELD_ELEMENT);
686:                        }
687:                    }
688:
689:                    contentHandler.endElement(NAMESPACE, HIT_ELEMENT,
690:                            Q_HIT_ELEMENT);
691:                }
692:            }
693:
694:            /**
695:             * Generate the navigation element.
696:             *
697:             * @param  pager                    Description of Parameter
698:             * @exception  SAXException         Description of Exception
699:             */
700:            private void generateNavigation(LuceneCocoonPager pager)
701:                    throws SAXException {
702:                if (pager != null) {
703:                    // generate navigation element
704:                    atts.clear();
705:                    atts.addAttribute("", TOTAL_COUNT_ATTRIBUTE,
706:                            TOTAL_COUNT_ATTRIBUTE, CDATA, String.valueOf(pager
707:                                    .getCountOfHits()));
708:                    atts.addAttribute("", COUNT_OF_PAGES_ATTRIBUTE,
709:                            COUNT_OF_PAGES_ATTRIBUTE, CDATA, String
710:                                    .valueOf(pager.getCountOfPages()));
711:                    atts.addAttribute("", HAS_NEXT_ATTRIBUTE,
712:                            HAS_NEXT_ATTRIBUTE, CDATA, String.valueOf(pager
713:                                    .hasNext()));
714:                    atts.addAttribute("", HAS_PREVIOUS_ATTRIBUTE,
715:                            HAS_PREVIOUS_ATTRIBUTE, CDATA, String.valueOf(pager
716:                                    .hasPrevious()));
717:                    atts.addAttribute("", NEXT_INDEX_ATTRIBUTE,
718:                            NEXT_INDEX_ATTRIBUTE, CDATA, String.valueOf(pager
719:                                    .nextIndex()));
720:                    atts.addAttribute("", PREVIOUS_INDEX_ATTRIBUTE,
721:                            PREVIOUS_INDEX_ATTRIBUTE, CDATA, String
722:                                    .valueOf(pager.previousIndex()));
723:                    contentHandler.startElement(NAMESPACE, NAVIGATION_ELEMENT,
724:                            Q_NAVIGATION_ELEMENT, atts);
725:                    int count_of_pages = pager.getCountOfPages();
726:                    for (int i = 0, page_start_index = 0; i < count_of_pages; i++, page_start_index += pageLength
727:                            .intValue()) {
728:                        atts.clear();
729:                        atts.addAttribute("", START_INDEX_ATTRIBUTE,
730:                                START_INDEX_ATTRIBUTE, CDATA, String
731:                                        .valueOf(page_start_index));
732:                        contentHandler.startElement(NAMESPACE,
733:                                NAVIGATION_PAGE_ELEMENT,
734:                                Q_NAVIGATION_PAGE_ELEMENT, atts);
735:                        contentHandler.endElement(NAMESPACE,
736:                                NAVIGATION_PAGE_ELEMENT,
737:                                Q_NAVIGATION_PAGE_ELEMENT);
738:                    }
739:                    // navigation is EMPTY element
740:                    contentHandler.endElement(NAMESPACE, NAVIGATION_ELEMENT,
741:                            Q_NAVIGATION_ELEMENT);
742:                }
743:            }
744:
745:            /**
746:             * Build hits from a query input, and setup paging object.
747:             *
748:             * @throws  ProcessingException  if an error occurs
749:             */
750:            private LuceneCocoonPager buildHits() throws ProcessingException,
751:                    IOException {
752:                if (queryString != null && queryString.length() != 0) {
753:                    Hits hits = null;
754:
755:                    Analyzer analyzer = LuceneCocoonHelper
756:                            .getAnalyzer(this .analyzer);
757:                    lcs.setAnalyzer(analyzer);
758:                    // get the directory where the index resides
759:                    Directory directory = LuceneCocoonHelper.getDirectory(
760:                            index, false);
761:                    lcs.setDirectory(directory);
762:                    hits = lcs.search(queryString, LuceneXMLIndexer.BODY_FIELD);
763:
764:                    // wrap the hits by an pager help object for accessing only a range of hits
765:                    LuceneCocoonPager pager = new LuceneCocoonPager(hits);
766:
767:                    int start_index = START_INDEX_DEFAULT;
768:                    if (this .startIndex != null) {
769:                        start_index = this .startIndex.intValue();
770:                        if (start_index <= 0) {
771:                            start_index = 0;
772:                        }
773:                        pager.setStartIndex(start_index);
774:                    }
775:
776:                    int page_length = PAGE_LENGTH_DEFAULT;
777:                    if (this .pageLength != null) {
778:                        page_length = this .pageLength.intValue();
779:                        if (page_length <= 0) {
780:                            page_length = hits.length();
781:                        }
782:                        pager.setCountOfHitsPerPage(page_length);
783:                    }
784:
785:                    return pager;
786:                }
787:
788:                return null;
789:            }
790:
791:            /**
792:             * Recycle the generator
793:             */
794:            public void recycle() {
795:                super.recycle();
796:                if (lcs != null) {
797:                    this.manager.release(lcs);
798:                }
799:                this.queryString = null;
800:                this.startIndex = null;
801:                this.pageLength = null;
802:                this.index = null;
803:                this.analyzer = null;
804:            }
805:
806:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.