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 018package org.apache.lucene.demo.xmlparser; 019 020import java.io.BufferedReader; 021import java.io.IOException; 022import java.io.InputStream; 023import java.io.InputStreamReader; 024import java.util.Enumeration; 025import java.util.Properties; 026import java.util.StringTokenizer; 027import javax.servlet.RequestDispatcher; 028import javax.servlet.ServletConfig; 029import javax.servlet.ServletException; 030import javax.servlet.http.HttpServlet; 031import javax.servlet.http.HttpServletRequest; 032import javax.servlet.http.HttpServletResponse; 033 034import org.apache.lucene.analysis.Analyzer; 035import org.apache.lucene.analysis.standard.StandardAnalyzer; 036import org.apache.lucene.document.Document; 037import org.apache.lucene.document.Field; 038import org.apache.lucene.document.FieldType; 039import org.apache.lucene.document.TextField; 040import org.apache.lucene.index.DirectoryReader; 041import org.apache.lucene.index.IndexReader; 042import org.apache.lucene.index.IndexWriter; 043import org.apache.lucene.index.IndexWriterConfig; 044import org.apache.lucene.queryparser.xml.CorePlusExtensionsParser; 045import org.apache.lucene.queryparser.xml.QueryTemplateManager; 046import org.apache.lucene.search.IndexSearcher; 047import org.apache.lucene.search.Query; 048import org.apache.lucene.search.ScoreDoc; 049import org.apache.lucene.search.TopDocs; 050import org.apache.lucene.store.RAMDirectory; 051import org.apache.lucene.util.IOUtils; 052import org.apache.lucene.util.Version; 053 054/** 055 * Example servlet that uses the XML queryparser. 056 * <p> 057 * NOTE: you must provide CSV data in <code>/WEB-INF/data.tsv</code> 058 * for the demo to work! 059 */ 060public class FormBasedXmlQueryDemo extends HttpServlet { 061 062 private QueryTemplateManager queryTemplateManager; 063 private CorePlusExtensionsParser xmlParser; 064 private IndexSearcher searcher; 065 private Analyzer analyzer = new StandardAnalyzer(org.apache.lucene.util.Version.LUCENE_CURRENT); 066 067 /** for instantiation by the servlet container */ 068 public FormBasedXmlQueryDemo() {} 069 070 @Override 071 public void init(ServletConfig config) throws ServletException { 072 super.init(config); 073 try { 074 openExampleIndex(); 075 076 //load servlet configuration settings 077 String xslFile = config.getInitParameter("xslFile"); 078 String defaultStandardQueryParserField = config.getInitParameter("defaultStandardQueryParserField"); 079 080 081 //Load and cache choice of XSL query template using QueryTemplateManager 082 queryTemplateManager = new QueryTemplateManager( 083 getServletContext().getResourceAsStream("/WEB-INF/" + xslFile)); 084 085 //initialize an XML Query Parser for use by all threads 086 xmlParser = new CorePlusExtensionsParser(defaultStandardQueryParserField, analyzer); 087 } catch (Exception e) { 088 throw new ServletException("Error loading query template", e); 089 } 090 } 091 092 @Override 093 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 094 //Take all completed form fields and add to a Properties object 095 Properties completedFormFields = new Properties(); 096 Enumeration<?> pNames = request.getParameterNames(); 097 while (pNames.hasMoreElements()) { 098 String propName = (String) pNames.nextElement(); 099 String value = request.getParameter(propName); 100 if ((value != null) && (value.trim().length() > 0)) { 101 completedFormFields.setProperty(propName, value); 102 } 103 } 104 105 try { 106 //Create an XML query by populating template with given user criteria 107 org.w3c.dom.Document xmlQuery = queryTemplateManager.getQueryAsDOM(completedFormFields); 108 109 //Parse the XML to produce a Lucene query 110 Query query = xmlParser.getQuery(xmlQuery.getDocumentElement()); 111 112 //Run the query 113 TopDocs topDocs = searcher.search(query, 10); 114 115 //and package the results and forward to JSP 116 if (topDocs != null) { 117 ScoreDoc[] sd = topDocs.scoreDocs; 118 Document[] results = new Document[sd.length]; 119 for (int i = 0; i < results.length; i++) { 120 results[i] = searcher.doc(sd[i].doc); 121 request.setAttribute("results", results); 122 } 123 } 124 RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/index.jsp"); 125 dispatcher.forward(request, response); 126 } 127 catch (Exception e) { 128 throw new ServletException("Error processing query", e); 129 } 130 } 131 132 private void openExampleIndex() throws IOException { 133 //Create a RAM-based index from our test data file 134 RAMDirectory rd = new RAMDirectory(); 135 IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_CURRENT, analyzer); 136 IndexWriter writer = new IndexWriter(rd, iwConfig); 137 InputStream dataIn = getServletContext().getResourceAsStream("/WEB-INF/data.tsv"); 138 BufferedReader br = new BufferedReader(new InputStreamReader(dataIn, IOUtils.CHARSET_UTF_8)); 139 String line = br.readLine(); 140 final FieldType textNoNorms = new FieldType(TextField.TYPE_STORED); 141 textNoNorms.setOmitNorms(true); 142 while (line != null) { 143 line = line.trim(); 144 if (line.length() > 0) { 145 //parse row and create a document 146 StringTokenizer st = new StringTokenizer(line, "\t"); 147 Document doc = new Document(); 148 doc.add(new Field("location", st.nextToken(), textNoNorms)); 149 doc.add(new Field("salary", st.nextToken(), textNoNorms)); 150 doc.add(new Field("type", st.nextToken(), textNoNorms)); 151 doc.add(new Field("description", st.nextToken(), textNoNorms)); 152 writer.addDocument(doc); 153 } 154 line = br.readLine(); 155 } 156 writer.close(); 157 158 //open searcher 159 // this example never closes it reader! 160 IndexReader reader = DirectoryReader.open(rd); 161 searcher = new IndexSearcher(reader); 162 } 163}