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