From de7ab5b89819969d30a9822686cee3f1fc7025d7 Mon Sep 17 00:00:00 2001 From: Mark Harwood Date: Sat, 8 Nov 2008 00:20:32 +0000 Subject: [PATCH] Added new web application demo for contrib's XmlQueryParser. This change involves: * Adding Tomcat's Servlet jar into the lib directory and appropriate entry in NOTICE.txt following the lead from Solr's packaging * Adding new "demo" directory to XmlQueryParser src directory * Changing XMLQueryParser's build file to create a demo War file * Changing the main build to include the demo War file (and any other future contrib/*/war files) in the binary distributions The packaged source distribution has NOT been changed currently to add a lib directory with the servlet.jar so building from a cut-down src distro as opposed to the full subversion /trunk directory will not currently build the war file (the xml query parser build file detects the absence of servlet.jar). Not sure if this is a problem currently. TODO: Now that the servlet jar is available in Subversion I would recommend that the other existing WAR file,"luceneweb.war", is changed to move much of the java code which is currently embedded in JSP files into servlet .java files. This would ensure that the build system will check that the code in this application compiles cleanly with the latest Lucene APIs - otherwise any issue will only become apparent when a user tries to run a JSP. git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@712318 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 3 + NOTICE.txt | 4 +- build.xml | 2 +- contrib/xml-query-parser/build.xml | 41 +++++- .../src/demo/WebContent/META-INF/MANIFEST.MF | 3 + .../src/demo/WebContent/WEB-INF/data.tsv | 5 + .../src/demo/WebContent/WEB-INF/query.xsl | 58 ++++++++ .../src/demo/WebContent/WEB-INF/web.xml | 33 +++++ .../src/demo/WebContent/index.jsp | 129 +++++++++++++++++ .../src/demo/WebContent/stylesheet.css | 23 +++ .../webdemo/FormBasedXmlQueryDemo.java | 133 ++++++++++++++++++ lib/servlet-api-2.4.jar | 2 + 12 files changed, 431 insertions(+), 5 deletions(-) create mode 100644 contrib/xml-query-parser/src/demo/WebContent/META-INF/MANIFEST.MF create mode 100644 contrib/xml-query-parser/src/demo/WebContent/WEB-INF/data.tsv create mode 100644 contrib/xml-query-parser/src/demo/WebContent/WEB-INF/query.xsl create mode 100644 contrib/xml-query-parser/src/demo/WebContent/WEB-INF/web.xml create mode 100644 contrib/xml-query-parser/src/demo/WebContent/index.jsp create mode 100644 contrib/xml-query-parser/src/demo/WebContent/stylesheet.css create mode 100644 contrib/xml-query-parser/src/demo/java/org/apache/lucene/xmlparser/webdemo/FormBasedXmlQueryDemo.java create mode 100644 lib/servlet-api-2.4.jar diff --git a/CHANGES.txt b/CHANGES.txt index db4158f077a..3c6bd5c4a66 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -46,6 +46,9 @@ New features {set/get}DiscountOverlaps to DefaultSimilarity, to control whether overlapping tokens (tokens with 0 position increment) should be counted in lengthNorm. (Andrzej Bialecki via Mike McCandless) + + 5. Added web-based demo of functionality in contrib's XML Query Parser + packaged as War file (Mark Harwood) Optimizations diff --git a/NOTICE.txt b/NOTICE.txt index c826ff590be..8380d8fb163 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -13,4 +13,6 @@ The full snowball package is available from The Arabic stemmer (contrib/analyzer) comes with a default stopword list that is BSD-licensed created by Jacques Savoy. The file resides in contrib/analyzers/src/java/org/apache/lucene/analysis/ar/stopwords.txt -See http://members.unine.ch/jacques.savoy/clef/index.html. \ No newline at end of file +See http://members.unine.ch/jacques.savoy/clef/index.html. + +Includes lib/servlet-api-2.4.jar from Apache Tomcat diff --git a/build.xml b/build.xml index 4d4778be907..22066410f4b 100644 --- a/build.xml +++ b/build.xml @@ -61,7 +61,7 @@ excludes="contrib/db/*/lib/,contrib/*/ext-libs/,src/site/build/,contrib/benchmark/temp/**,contrib/benchmark/work/**" /> + + + @@ -34,12 +37,44 @@ + + + + + + XML Parser building dependency ${queries.jar} - + + + + + + + + + + + XML Parser compiling web demo + + + + + + + + + + + + + + diff --git a/contrib/xml-query-parser/src/demo/WebContent/META-INF/MANIFEST.MF b/contrib/xml-query-parser/src/demo/WebContent/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..5e9495128c0 --- /dev/null +++ b/contrib/xml-query-parser/src/demo/WebContent/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/contrib/xml-query-parser/src/demo/WebContent/WEB-INF/data.tsv b/contrib/xml-query-parser/src/demo/WebContent/WEB-INF/data.tsv new file mode 100644 index 00000000000..60805292a03 --- /dev/null +++ b/contrib/xml-query-parser/src/demo/WebContent/WEB-INF/data.tsv @@ -0,0 +1,5 @@ +South 100 Contract Java developer required to work within a small development group. Minimum 3+ years experience developing web applications in Java with exposure to Open Source technologies such as Spring, Hibernate, Eclipse, Struts, Lucene, Tomcat +North 078 Permanent Seeking developer with VB.NET, HTML, CSS, JavaScript, ASP. NET, SQL Query Analyzer, Visual Studio. NET, SQL Profiler +East 100 Permanent Project Manager - currently seeking a Project Manager to be based in London with experience of running multiple projects within budget. Candidate will come with a strong project management background, ideally from a technical background with web related experience and project management methodology such as Prince 2 +West 085 Contract Oracle DBA required to provide 3rd line support, maintenance and database restore for company's production systems. Experienced in SQL, PL/SQL Oracle databases (9i & 10GR2), Oracle RAC, RMAN and Data Guard. Ideally with, Linux and Windows experience +North 099 Permanent Search engine developer required with experience in the following technologies: Java, Lucene, Solr, Spring, JSP, MySQL, Tomcat, JavaScript, Ant / Ivy, Subversion \ No newline at end of file diff --git a/contrib/xml-query-parser/src/demo/WebContent/WEB-INF/query.xsl b/contrib/xml-query-parser/src/demo/WebContent/WEB-INF/query.xsl new file mode 100644 index 00000000000..2e49d9cc89d --- /dev/null +++ b/contrib/xml-query-parser/src/demo/WebContent/WEB-INF/query.xsl @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/contrib/xml-query-parser/src/demo/WebContent/WEB-INF/web.xml b/contrib/xml-query-parser/src/demo/WebContent/WEB-INF/web.xml new file mode 100644 index 00000000000..42671a81ce4 --- /dev/null +++ b/contrib/xml-query-parser/src/demo/WebContent/WEB-INF/web.xml @@ -0,0 +1,33 @@ + + + + LuceneXmlQueryWebDemo + + + Servlet demonstrating XMLQueryParser + + FormBasedXmlQueryDemo + FormBasedXmlQueryDemo + + org.apache.lucene.xmlparser.webdemo.FormBasedXmlQueryDemo + + + Name of query file held in /WEB-INF + xslFile + query.xsl + + + + Default field used in standard Lucene QueryParser used in UserQuery tag + defaultStandardQueryParserField + jobDescription + + + + FormBasedXmlQueryDemo + /FormBasedXmlQueryDemo + + + index.jsp + + diff --git a/contrib/xml-query-parser/src/demo/WebContent/index.jsp b/contrib/xml-query-parser/src/demo/WebContent/index.jsp new file mode 100644 index 00000000000..881206c2ca1 --- /dev/null +++ b/contrib/xml-query-parser/src/demo/WebContent/index.jsp @@ -0,0 +1,129 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" +import="org.apache.lucene.search.*,org.apache.lucene.document.*" +pageEncoding="ISO-8859-1"%> + + + + + + XML Query Parser demo + + +

Job Search

+<% + // Load form variables + String description=request.getParameter("description"); + String type=request.getParameter("type"); + String salaryRange=request.getParameter("salaryRange"); +%> +
+ + + + + + + + + + + + + + + + + + + + + + + +
Description + "/> +
Type + +
Salary + +
Locations +<% + String locs[]={"South","North","East","West"}; + boolean allLocsBlank=true; + for(int i=0;i + + checked="checked" +<% } +%> + type="checkbox"/> + +<% + } +%> +
+ +
+
+<% + Document[] results=(Document[])request.getAttribute("results"); + if(results!=null) + { +%> + + + + + + + + <% + for (int i = 0; i < results.length; i++) + { + Document doc = results[i]; + %> + + + + + + + + <% + } + %> +
TypeLocationSalaryDescription
<%=doc.get("type")%><%=doc.get("location")%><%=doc.get("salary")%>,000<%=doc.get("description")%>
+ +<% + }//end if has results +%> + + \ No newline at end of file diff --git a/contrib/xml-query-parser/src/demo/WebContent/stylesheet.css b/contrib/xml-query-parser/src/demo/WebContent/stylesheet.css new file mode 100644 index 00000000000..b832995cbd5 --- /dev/null +++ b/contrib/xml-query-parser/src/demo/WebContent/stylesheet.css @@ -0,0 +1,23 @@ +BODY {font: 10pt Tahoma; color: #000000; background-color: #FFFFFF} +P {font: 10pt Tahoma} +BIG {font: 14pt Tahoma} +#A { color: #FFFFFF;text-decoration: none underline} +A { text-decoration: none underline} +#A:hover {color: #ff33ff; text-decoration: none} +A:hover {color: #9A00C0; text-decoration: none} + + +.resultsHeader {font: bold 10pt Tahoma; color: #000000; background-color: #DCE2EE} +.formHeader {font: bold 10pt Tahoma; text-align:right; color: #000000; } +TD {font: 10pt Tahoma; color: #000000; } +TR.resultsRow:hover {font: 10pt Tahoma; color: #000000; background-color: #ECF2FE} +.resultNum {text-align:right} +FORM {display: inline} +H1 {font: bold 16pt Tahoma} +H2 {font: bold 14pt Tahoma} +H3 {font: bold 12pt Tahoma} +SPAN.h1 {font: bold 22pt Tahoma} +SPAN.h2 {font: bold 14pt Tahoma} + +SMALL {font: 8pt Tahoma} +SELECT {font: 10pt Tahoma; } diff --git a/contrib/xml-query-parser/src/demo/java/org/apache/lucene/xmlparser/webdemo/FormBasedXmlQueryDemo.java b/contrib/xml-query-parser/src/demo/java/org/apache/lucene/xmlparser/webdemo/FormBasedXmlQueryDemo.java new file mode 100644 index 00000000000..f8233db38bb --- /dev/null +++ b/contrib/xml-query-parser/src/demo/java/org/apache/lucene/xmlparser/webdemo/FormBasedXmlQueryDemo.java @@ -0,0 +1,133 @@ +package org.apache.lucene.xmlparser.webdemo; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Enumeration; +import java.util.Properties; +import java.util.StringTokenizer; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.index.CorruptIndexException; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.ScoreDoc; +import org.apache.lucene.search.TopDocs; +import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.xmlparser.CorePlusExtensionsParser; +import org.apache.lucene.xmlparser.QueryTemplateManager; + +public class FormBasedXmlQueryDemo extends HttpServlet { + + private QueryTemplateManager queryTemplateManager; + private CorePlusExtensionsParser xmlParser; + private IndexSearcher searcher; + private Analyzer analyzer=new StandardAnalyzer(); + + public void init(ServletConfig config) throws ServletException { + super.init(config); + try { + openExampleIndex(); + + //load servlet configuration settings + String xslFile=config.getInitParameter("xslFile"); + String defaultStandardQueryParserField = config.getInitParameter("defaultStandardQueryParserField"); + + + //Load and cache choice of XSL query template using QueryTemplateManager + queryTemplateManager=new QueryTemplateManager( + getServletContext().getResourceAsStream("/WEB-INF/"+xslFile)); + + //initialize an XML Query Parser for use by all threads + xmlParser=new CorePlusExtensionsParser(defaultStandardQueryParserField,analyzer); + } catch (Exception e) { + throw new ServletException("Error loading query template",e); + } + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + //Take all completed form fields and add to a Properties object + Properties completedFormFields=new Properties(); + Enumeration pNames = request.getParameterNames(); + while(pNames.hasMoreElements()){ + String propName=(String) pNames.nextElement(); + String value=request.getParameter(propName); + if((value!=null)&&(value.trim().length()>0)){ + completedFormFields.setProperty(propName, value); + } + } + + try{ + + //Create an XML query by populating template with given user criteria + org.w3c.dom.Document xmlQuery=queryTemplateManager.getQueryAsDOM(completedFormFields); + + //Parse the XML to produce a Lucene query + Query query=xmlParser.getQuery(xmlQuery.getDocumentElement()); + + //Run the query + TopDocs topDocs = searcher.search(query,10); + + //and package the results and forward to JSP + if(topDocs!=null) { + ScoreDoc[] sd = topDocs.scoreDocs; + Document[] results=new Document[sd.length]; + for (int i = 0; i < results.length; i++) { + results[i]=searcher.doc(sd[i].doc); + request.setAttribute("results", results); + } + } + RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/index.jsp"); + dispatcher.forward(request,response); + } + catch(Exception e){ + throw new ServletException("Error processing query",e); + } + } + + private void openExampleIndex() throws CorruptIndexException, IOException { + + //Create a RAM-based index from our test data file + RAMDirectory rd=new RAMDirectory(); + IndexWriter writer=new IndexWriter (rd,analyzer,IndexWriter.MaxFieldLength.LIMITED); + InputStream dataIn=getServletContext().getResourceAsStream("/WEB-INF/data.tsv"); + BufferedReader br = new BufferedReader(new InputStreamReader(dataIn)); + String line = br.readLine(); + while(line!=null) + { + line=line.trim(); + if(line.length()>0) + { + //parse row and create a document + StringTokenizer st=new StringTokenizer(line,"\t"); + Document doc=new Document(); + doc.add(new Field("location",st.nextToken(),Field.Store.YES, + Field.Index.ANALYZED_NO_NORMS)); + doc.add(new Field("salary",st.nextToken(),Field.Store.YES, + Field.Index.ANALYZED_NO_NORMS)); + doc.add(new Field("type",st.nextToken(),Field.Store.YES, + Field.Index.ANALYZED_NO_NORMS)); + doc.add(new Field("description",st.nextToken(),Field.Store.YES, + Field.Index.ANALYZED)); + writer.addDocument(doc); + } + line=br.readLine(); + } + writer.close(); + + //open searcher + searcher=new IndexSearcher(rd); + } +} diff --git a/lib/servlet-api-2.4.jar b/lib/servlet-api-2.4.jar new file mode 100644 index 00000000000..9e7f1e85a59 --- /dev/null +++ b/lib/servlet-api-2.4.jar @@ -0,0 +1,2 @@ +AnyObjectId[018d6effad3823d0ea59f1b58ab154fc2652f418] was removed in git history. +Apache SVN contains full history. \ No newline at end of file