001: package org.apache.lucene.xmlparser;
002:
003: import java.io.IOException;
004: import java.util.Properties;
005: import java.util.StringTokenizer;
006:
007: import javax.xml.parsers.ParserConfigurationException;
008: import javax.xml.transform.TransformerException;
009:
010: import junit.framework.TestCase;
011:
012: import org.apache.lucene.analysis.Analyzer;
013: import org.apache.lucene.analysis.standard.StandardAnalyzer;
014: import org.apache.lucene.document.Field;
015: import org.apache.lucene.index.IndexWriter;
016: import org.apache.lucene.queryParser.QueryParser;
017: import org.apache.lucene.search.Hits;
018: import org.apache.lucene.search.IndexSearcher;
019: import org.apache.lucene.search.Query;
020: import org.apache.lucene.store.RAMDirectory;
021: import org.w3c.dom.Document;
022: import org.xml.sax.SAXException;
023:
024: /**
025: * Licensed to the Apache Software Foundation (ASF) under one or more
026: * contributor license agreements. See the NOTICE file distributed with
027: * this work for additional information regarding copyright ownership.
028: * The ASF licenses this file to You under the Apache License, Version 2.0
029: * (the "License"); you may not use this file except in compliance with
030: * the License. You may obtain a copy of the License at
031: *
032: * http://www.apache.org/licenses/LICENSE-2.0
033: *
034: * Unless required by applicable law or agreed to in writing, software
035: * distributed under the License is distributed on an "AS IS" BASIS,
036: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
037: * See the License for the specific language governing permissions and
038: * limitations under the License.
039: */
040: /**
041: * This class illustrates how form input (such as from a web page or Swing gui) can be
042: * turned into Lucene queries using a choice of XSL templates for different styles of queries.
043: * @author maharwood
044: */
045: public class TestQueryTemplateManager extends TestCase {
046:
047: CoreParser builder;
048: Analyzer analyzer = new StandardAnalyzer();
049: private IndexSearcher searcher;
050:
051: //A collection of documents' field values for use in our tests
052: String docFieldValues[] = {
053: "artist=Jeff Buckley \talbum=Grace \treleaseDate=1999 \tgenre=rock",
054: "artist=Fugazi \talbum=Repeater \treleaseDate=1990 \tgenre=alternative",
055: "artist=Fugazi \talbum=Red Medicine \treleaseDate=1995 \tgenre=alternative",
056: "artist=Peeping Tom \talbum=Peeping Tom \treleaseDate=2006 \tgenre=rock",
057: "artist=Red Snapper \talbum=Prince Blimey \treleaseDate=1996 \tgenre=electronic" };
058:
059: //A collection of example queries, consisting of name/value pairs representing form content plus
060: // a choice of query style template to use in the test, with expected number of hits
061: String queryForms[] = {
062: "artist=Fugazi \texpectedMatches=2 \ttemplate=albumBooleanQuery",
063: "artist=Fugazi \treleaseDate=1990 \texpectedMatches=1 \ttemplate=albumBooleanQuery",
064: "artist=Buckley \tgenre=rock \texpectedMatches=1 \ttemplate=albumFilteredQuery",
065: "artist=Buckley \tgenre=electronic \texpectedMatches=0 \ttemplate=albumFilteredQuery",
066: "queryString=artist:buckly~ NOT genre:electronic \texpectedMatches=1 \ttemplate=albumLuceneClassicQuery" };
067:
068: public void testFormTransforms() throws SAXException, IOException,
069: ParserConfigurationException, TransformerException,
070: ParserException {
071: //Cache all the query templates we will be referring to.
072: QueryTemplateManager qtm = new QueryTemplateManager();
073: qtm.addQueryTemplate("albumBooleanQuery", getClass()
074: .getResourceAsStream("albumBooleanQuery.xsl"));
075: qtm.addQueryTemplate("albumFilteredQuery", getClass()
076: .getResourceAsStream("albumFilteredQuery.xsl"));
077: qtm.addQueryTemplate("albumLuceneClassicQuery", getClass()
078: .getResourceAsStream("albumLuceneClassicQuery.xsl"));
079: //Run all of our test queries
080: for (int i = 0; i < queryForms.length; i++) {
081: Properties queryFormProperties = getPropsFromString(queryForms[i]);
082:
083: //Get the required query XSL template for this test
084: // Templates template=getTemplate(queryFormProperties.getProperty("template"));
085:
086: //Transform the queryFormProperties into a Lucene XML query
087: Document doc = qtm.getQueryAsDOM(queryFormProperties,
088: queryFormProperties.getProperty("template"));
089:
090: //Parse the XML query using the XML parser
091: Query q = builder.getQuery(doc.getDocumentElement());
092:
093: //Run the query
094: Hits h = searcher.search(q);
095:
096: //Check we have the expected number of results
097: int expectedHits = Integer.parseInt(queryFormProperties
098: .getProperty("expectedMatches"));
099: assertEquals("Number of results should match for query "
100: + queryForms[i], expectedHits, h.length());
101:
102: }
103: }
104:
105: //Helper method to construct Lucene query forms used in our test
106: Properties getPropsFromString(String nameValuePairs) {
107: Properties result = new Properties();
108: StringTokenizer st = new StringTokenizer(nameValuePairs, "\t=");
109: while (st.hasMoreTokens()) {
110: String name = st.nextToken().trim();
111: if (st.hasMoreTokens()) {
112: String value = st.nextToken().trim();
113: result.setProperty(name, value);
114: }
115: }
116: return result;
117: }
118:
119: //Helper method to construct Lucene documents used in our tests
120: org.apache.lucene.document.Document getDocumentFromString(
121: String nameValuePairs) {
122: org.apache.lucene.document.Document result = new org.apache.lucene.document.Document();
123: StringTokenizer st = new StringTokenizer(nameValuePairs, "\t=");
124: while (st.hasMoreTokens()) {
125: String name = st.nextToken().trim();
126: if (st.hasMoreTokens()) {
127: String value = st.nextToken().trim();
128: result.add(new Field(name, value, Field.Store.YES,
129: Field.Index.TOKENIZED));
130: }
131: }
132: return result;
133: }
134:
135: /*
136: * @see TestCase#setUp()
137: */
138: protected void setUp() throws Exception {
139: super .setUp();
140:
141: //Create an index
142: RAMDirectory dir = new RAMDirectory();
143: IndexWriter w = new IndexWriter(dir, analyzer, true);
144: for (int i = 0; i < docFieldValues.length; i++) {
145: w.addDocument(getDocumentFromString(docFieldValues[i]));
146: }
147: w.optimize();
148: w.close();
149: searcher = new IndexSearcher(dir);
150:
151: //initialize the parser
152: builder = new CorePlusExtensionsParser(analyzer,
153: new QueryParser("artist", analyzer));
154:
155: }
156:
157: protected void tearDown() throws Exception {
158: searcher.close();
159: }
160: }
|