You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@lucene.apache.org by mh...@apache.org on 2007/02/04 23:51:29 UTC
svn commit: r503500 - in /lucene/java/trunk/contrib/xml-query-parser/src:
java/org/apache/lucene/xmlparser/QueryTemplateManager.java
test/org/apache/lucene/xmlparser/TestQueryTemplateManager.java
Author: mharwood
Date: Sun Feb 4 14:51:28 2007
New Revision: 503500
URL: http://svn.apache.org/viewvc?view=rev&rev=503500
Log:
Changes to improve server-side speed and thread safety by caching reusable, compiled stylesheets.
Modified:
lucene/java/trunk/contrib/xml-query-parser/src/java/org/apache/lucene/xmlparser/QueryTemplateManager.java
lucene/java/trunk/contrib/xml-query-parser/src/test/org/apache/lucene/xmlparser/TestQueryTemplateManager.java
Modified: lucene/java/trunk/contrib/xml-query-parser/src/java/org/apache/lucene/xmlparser/QueryTemplateManager.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/xml-query-parser/src/java/org/apache/lucene/xmlparser/QueryTemplateManager.java?view=diff&rev=503500&r1=503499&r2=503500
==============================================================================
--- lucene/java/trunk/contrib/xml-query-parser/src/java/org/apache/lucene/xmlparser/QueryTemplateManager.java (original)
+++ lucene/java/trunk/contrib/xml-query-parser/src/java/org/apache/lucene/xmlparser/QueryTemplateManager.java Sun Feb 4 14:51:28 2007
@@ -4,6 +4,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.Properties;
import javax.xml.parsers.DocumentBuilder;
@@ -11,7 +12,9 @@
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
@@ -21,6 +24,7 @@
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
+
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -43,49 +47,136 @@
* and changing how user input is turned into Lucene queries.
* Database applications often adopt similar practices by externalizing SQL in template files that can
* be easily changed/optimized by a DBA.
+ * The static methods can be used on their own or by creating an instance of this class you can store and
+ * re-use compiled stylesheets for fast use (e.g. in a server environment)
* @author Mark Harwood
*/
public class QueryTemplateManager
{
static DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance ();
static TransformerFactory tFactory = TransformerFactory.newInstance();
+
+ HashMap compiledTemplatesCache=new HashMap();
+ Templates defaultCompiledTemplates=null;
+
+
+ public QueryTemplateManager()
+ {
+
+ }
+ public QueryTemplateManager(InputStream xslIs) throws TransformerConfigurationException, ParserConfigurationException, SAXException, IOException
+ {
+ addDefaultQueryTemplate(xslIs);
+ }
+ public void addDefaultQueryTemplate(InputStream xslIs) throws TransformerConfigurationException, ParserConfigurationException, SAXException, IOException
+ {
+ defaultCompiledTemplates=getTemplates(xslIs);
+ }
+ public void addQueryTemplate(String name, InputStream xslIs) throws TransformerConfigurationException, ParserConfigurationException, SAXException, IOException
+ {
+ compiledTemplatesCache.put(name,getTemplates(xslIs));
+ }
+ public String getQueryAsXmlString(Properties formProperties,String queryTemplateName) throws SAXException, IOException, ParserConfigurationException, TransformerException
+ {
+ Templates ts=(Templates) compiledTemplatesCache.get(queryTemplateName);
+ return getQueryAsXmlString(formProperties, ts);
+ }
- public static String getQueryAsXmlString(Properties formProperties, String templateName) throws SAXException, IOException, ParserConfigurationException, TransformerException
+ public Document getQueryAsDOM(Properties formProperties,String queryTemplateName) throws SAXException, IOException, ParserConfigurationException, TransformerException
+ {
+ Templates ts=(Templates) compiledTemplatesCache.get(queryTemplateName);
+ return getQueryAsDOM(formProperties, ts);
+ }
+ public String getQueryAsXmlString(Properties formProperties) throws SAXException, IOException, ParserConfigurationException, TransformerException
{
- return getQueryAsXmlString(formProperties,
- getDOMSource(QueryTemplateManager.class.getResourceAsStream(templateName)));
+ return getQueryAsXmlString(formProperties, defaultCompiledTemplates);
}
- public static String getQueryAsXmlString(Properties formProperties, Source xslDs) throws SAXException, IOException, ParserConfigurationException, TransformerException
+ public Document getQueryAsDOM(Properties formProperties) throws SAXException, IOException, ParserConfigurationException, TransformerException
+ {
+ return getQueryAsDOM(formProperties, defaultCompiledTemplates);
+ }
+
+
+ /**
+ * Fast means of constructing query using a precompiled stylesheet
+ */
+ public static String getQueryAsXmlString(Properties formProperties, Templates template) throws SAXException, IOException, ParserConfigurationException, TransformerException
{
ByteArrayOutputStream baos=new ByteArrayOutputStream();
StreamResult result=new StreamResult(baos);
- transformCriteria(formProperties,xslDs,result);
- return baos.toString();
+ transformCriteria(formProperties,template,result);
+ return baos.toString();
}
- public static Document getQueryAsDOM(Properties formProperties, String templateName) throws SAXException, IOException, ParserConfigurationException, TransformerException
+ /**
+ * Slow means of constructing query parsing a stylesheet from an input stream
+ */
+ public static String getQueryAsXmlString(Properties formProperties, InputStream xslIs) throws SAXException, IOException, ParserConfigurationException, TransformerException
{
- return getQueryAsDOM(formProperties, getDOMSource(QueryTemplateManager.class.getResourceAsStream(templateName)));
+ ByteArrayOutputStream baos=new ByteArrayOutputStream();
+ StreamResult result=new StreamResult(baos);
+ transformCriteria(formProperties,xslIs,result);
+ return baos.toString();
}
- public static Document getQueryAsDOM(Properties formProperties, InputStream xslIs) throws SAXException, IOException, ParserConfigurationException, TransformerException
+
+
+ /**
+ * Fast means of constructing query using a cached,precompiled stylesheet
+ */
+ public static Document getQueryAsDOM(Properties formProperties, Templates template) throws SAXException, IOException, ParserConfigurationException, TransformerException
{
- return getQueryAsDOM(formProperties, getDOMSource(xslIs));
+ DOMResult result=new DOMResult();
+ transformCriteria(formProperties,template,result);
+ return (Document)result.getNode();
}
+
-
- public static Document getQueryAsDOM(Properties formProperties, Source xslDs) throws SAXException, IOException, ParserConfigurationException, TransformerException
+ /**
+ * Slow means of constructing query - parses stylesheet from input stream
+ */
+ public static Document getQueryAsDOM(Properties formProperties, InputStream xslIs) throws SAXException, IOException, ParserConfigurationException, TransformerException
{
DOMResult result=new DOMResult();
- transformCriteria(formProperties,xslDs,result);
+ transformCriteria(formProperties,xslIs,result);
return (Document)result.getNode();
}
- public static void transformCriteria(Properties formProperties, Source xslDs, Result result) throws SAXException, IOException, ParserConfigurationException, TransformerException
+
+
+
+ /**
+ * Slower transformation using an uncompiled stylesheet (suitable for development environment)
+ */
+ public static void transformCriteria(Properties formProperties, InputStream xslIs, Result result) throws SAXException, IOException, ParserConfigurationException, TransformerException
{
dbf.setNamespaceAware(true);
+ DocumentBuilder builder = dbf.newDocumentBuilder();
+ org.w3c.dom.Document xslDoc = builder.parse(xslIs);
+ DOMSource ds = new DOMSource(xslDoc);
- Transformer transformer = tFactory.newTransformer(xslDs);
+ Transformer transformer =null;
+ synchronized (tFactory)
+ {
+ transformer = tFactory.newTransformer(ds);
+ }
+ transformCriteria(formProperties,transformer,result);
+ }
+
+ /**
+ * Fast transformation using a pre-compiled stylesheet (suitable for production environments)
+ */
+ public static void transformCriteria(Properties formProperties, Templates template, Result result) throws SAXException, IOException, ParserConfigurationException, TransformerException
+ {
+ transformCriteria(formProperties,template.newTransformer(),result);
+ }
+
+
+
+ public static void transformCriteria(Properties formProperties, Transformer transformer, Result result) throws SAXException, IOException, ParserConfigurationException, TransformerException
+ {
+ dbf.setNamespaceAware(true);
+
//Create an XML document representing the search index document.
DocumentBuilder db = dbf.newDocumentBuilder ();
org.w3c.dom.Document doc = db.newDocument ();
@@ -107,11 +198,15 @@
transformer.transform(xml,result);
}
- public static DOMSource getDOMSource(InputStream xslIs) throws ParserConfigurationException, SAXException, IOException
+ /**
+ * Parses a query stylesheet for repeated use
+ */
+ public static Templates getTemplates(InputStream xslIs) throws ParserConfigurationException, SAXException, IOException, TransformerConfigurationException
{
dbf.setNamespaceAware(true);
DocumentBuilder builder = dbf.newDocumentBuilder();
org.w3c.dom.Document xslDoc = builder.parse(xslIs);
- return new DOMSource(xslDoc);
+ DOMSource ds = new DOMSource(xslDoc);
+ return tFactory.newTemplates(ds);
}
}
Modified: lucene/java/trunk/contrib/xml-query-parser/src/test/org/apache/lucene/xmlparser/TestQueryTemplateManager.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/xml-query-parser/src/test/org/apache/lucene/xmlparser/TestQueryTemplateManager.java?view=diff&rev=503500&r1=503499&r2=503500
==============================================================================
--- lucene/java/trunk/contrib/xml-query-parser/src/test/org/apache/lucene/xmlparser/TestQueryTemplateManager.java (original)
+++ lucene/java/trunk/contrib/xml-query-parser/src/test/org/apache/lucene/xmlparser/TestQueryTemplateManager.java Sun Feb 4 14:51:28 2007
@@ -1,15 +1,11 @@
package org.apache.lucene.xmlparser;
import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashMap;
import java.util.Properties;
import java.util.StringTokenizer;
import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Source;
import javax.xml.transform.TransformerException;
-import javax.xml.transform.dom.DOMSource;
import junit.framework.TestCase;
@@ -24,6 +20,7 @@
import org.apache.lucene.store.RAMDirectory;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
+
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -49,7 +46,6 @@
CoreParser builder;
Analyzer analyzer=new StandardAnalyzer();
- HashMap templates=new HashMap();
private IndexSearcher searcher;
//A collection of documents' field values for use in our tests
@@ -66,26 +62,31 @@
// a choice of query style template to use in the test, with expected number of hits
String queryForms[]=
{
- "artist=Fugazi \texpectedMatches=2 \ttemplate=albumBooleanQuery.xsl",
- "artist=Fugazi \treleaseDate=1990 \texpectedMatches=1 \ttemplate=albumBooleanQuery.xsl",
- "artist=Buckley \tgenre=rock \texpectedMatches=1 \ttemplate=albumFilteredQuery.xsl",
- "artist=Buckley \tgenre=electronic \texpectedMatches=0 \ttemplate=albumFilteredQuery.xsl",
- "queryString=artist:buckly~ NOT genre:electronic \texpectedMatches=1 \ttemplate=albumLuceneClassicQuery.xsl"
+ "artist=Fugazi \texpectedMatches=2 \ttemplate=albumBooleanQuery",
+ "artist=Fugazi \treleaseDate=1990 \texpectedMatches=1 \ttemplate=albumBooleanQuery",
+ "artist=Buckley \tgenre=rock \texpectedMatches=1 \ttemplate=albumFilteredQuery",
+ "artist=Buckley \tgenre=electronic \texpectedMatches=0 \ttemplate=albumFilteredQuery",
+ "queryString=artist:buckly~ NOT genre:electronic \texpectedMatches=1 \ttemplate=albumLuceneClassicQuery"
};
public void testFormTransforms() throws SAXException, IOException, ParserConfigurationException, TransformerException, ParserException
{
+ //Cache all the query templates we will be referring to.
+ QueryTemplateManager qtm=new QueryTemplateManager();
+ qtm.addQueryTemplate("albumBooleanQuery", getClass().getResourceAsStream("albumBooleanQuery.xsl"));
+ qtm.addQueryTemplate("albumFilteredQuery", getClass().getResourceAsStream("albumFilteredQuery.xsl"));
+ qtm.addQueryTemplate("albumLuceneClassicQuery", getClass().getResourceAsStream("albumLuceneClassicQuery.xsl"));
//Run all of our test queries
for (int i = 0; i < queryForms.length; i++)
{
Properties queryFormProperties=getPropsFromString(queryForms[i]);
//Get the required query XSL template for this test
- Source template=getTemplate(queryFormProperties.getProperty("template"));
+// Templates template=getTemplate(queryFormProperties.getProperty("template"));
//Transform the queryFormProperties into a Lucene XML query
- Document doc=QueryTemplateManager.getQueryAsDOM(queryFormProperties,template);
+ Document doc=qtm.getQueryAsDOM(queryFormProperties,queryFormProperties.getProperty("template"));
//Parse the XML query using the XML parser
Query q=builder.getQuery(doc.getDocumentElement());
@@ -100,20 +101,6 @@
}
}
-
- private Source getTemplate(String templateName) throws ParserConfigurationException, SAXException, IOException
- {
- Source result=(Source) templates.get(templateName);
- if(result==null)
- {
- //Not yet loaded - load the stylesheet
- result=QueryTemplateManager.getDOMSource(getClass().getResourceAsStream(templateName));
- templates.put(templateName,result);
- }
- return result;
- }
-
-
//Helper method to construct Lucene query forms used in our test
Properties getPropsFromString(String nameValuePairs)
{