blob: 575188b2b7016924fa8f698823fb27fb442954b2 [file] [log] [blame]
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);
}
}