--- /dev/null
+package org.apache.lucene.xmlparser;
+
+import java.io.ByteArrayOutputStream;
+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;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Result;
+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;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+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
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Provides utilities for turning query form input (such as from a web page or Swing gui) into
+ * Lucene XML queries by using XSL templates. This approach offers a convenient way of externalizing
+ * 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)
+ */
+public class QueryTemplateManager
+{
+ static DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance ();
+ static TransformerFactory tFactory = TransformerFactory.newInstance();
+
+ HashMap<String,Templates> compiledTemplatesCache=new HashMap<String,Templates>();
+ 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= compiledTemplatesCache.get(queryTemplateName);
+ return getQueryAsXmlString(formProperties, ts);
+ }
+
+ public Document getQueryAsDOM(Properties formProperties,String queryTemplateName) throws SAXException, IOException, ParserConfigurationException, TransformerException
+ {
+ Templates ts= compiledTemplatesCache.get(queryTemplateName);
+ return getQueryAsDOM(formProperties, ts);
+ }
+ public String getQueryAsXmlString(Properties formProperties) throws SAXException, IOException, ParserConfigurationException, TransformerException
+ {
+ return getQueryAsXmlString(formProperties, defaultCompiledTemplates);
+ }
+
+ 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,template,result);
+ return baos.toString();
+ }
+
+ /**
+ * 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
+ {
+ ByteArrayOutputStream baos=new ByteArrayOutputStream();
+ StreamResult result=new StreamResult(baos);
+ transformCriteria(formProperties,xslIs,result);
+ return baos.toString();
+ }
+
+
+ /**
+ * Fast means of constructing query using a cached,precompiled stylesheet
+ */
+ public static Document getQueryAsDOM(Properties formProperties, Templates template) throws SAXException, IOException, ParserConfigurationException, TransformerException
+ {
+ DOMResult result=new DOMResult();
+ transformCriteria(formProperties,template,result);
+ return (Document)result.getNode();
+ }
+
+
+ /**
+ * 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,xslIs,result);
+ return (Document)result.getNode();
+ }
+
+
+
+
+ /**
+ * 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 =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 ();
+ Element root = doc.createElement ("Document");
+ doc.appendChild (root);
+
+ Enumeration keysEnum = formProperties.keys();
+ while(keysEnum.hasMoreElements())
+ {
+ String propName=(String) keysEnum.nextElement();
+ String value=formProperties.getProperty(propName);
+ if((value!=null)&&(value.length()>0))
+ {
+ DOMUtils.insertChild(root,propName,value);
+ }
+ }
+ //Use XSLT to to transform into an XML query string using the queryTemplate
+ DOMSource xml=new DOMSource(doc);
+ transformer.transform(xml,result);
+ }
+
+ /**
+ * 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);
+ DOMSource ds = new DOMSource(xslDoc);
+ return tFactory.newTemplates(ds);
+ }
+}