| #if FEATURE_XSLT |
| using System.Collections.Generic; |
| using System.IO; |
| using System.Xml; |
| using System.Xml.Xsl; |
| |
| namespace Lucene.Net.QueryParsers.Xml |
| { |
| /* |
| * 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. |
| */ |
| |
| /// <summary> |
| /// 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) |
| /// |
| /// LUCENENET (.NET Core): This is not compiled this because .NET Standard |
| /// does not currently support XSL Transform. |
| /// </summary> |
| public class QueryTemplateManager |
| { |
| IDictionary<string, XslCompiledTransform> compiledTemplatesCache = new Dictionary<string, XslCompiledTransform>(); |
| XslCompiledTransform defaultCompiledTemplates = null; |
| |
| public QueryTemplateManager() |
| { |
| } |
| |
| public QueryTemplateManager(Stream xslIs) |
| { |
| AddDefaultQueryTemplate(xslIs); |
| } |
| |
| public virtual void AddDefaultQueryTemplate(Stream xslIs) |
| { |
| defaultCompiledTemplates = GetTemplates(xslIs); |
| } |
| |
| public virtual void AddQueryTemplate(string name, Stream xslIs) |
| { |
| compiledTemplatesCache[name] = GetTemplates(xslIs); |
| } |
| |
| public virtual string GetQueryAsXmlString(IDictionary<string, string> formProperties, string queryTemplateName) |
| { |
| XslCompiledTransform ts = compiledTemplatesCache[queryTemplateName]; |
| return GetQueryAsXmlString(formProperties, ts); |
| } |
| |
| public virtual XmlDocument GetQueryAsDOM(IDictionary<string, string> formProperties, string queryTemplateName) |
| { |
| XslCompiledTransform ts = compiledTemplatesCache[queryTemplateName]; |
| return GetQueryAsDOM(formProperties, ts); |
| } |
| |
| public virtual string GetQueryAsXmlString(IDictionary<string, string> formProperties) |
| { |
| return GetQueryAsXmlString(formProperties, defaultCompiledTemplates); |
| } |
| |
| public virtual XmlDocument GetQueryAsDOM(IDictionary<string, string> formProperties) |
| { |
| return GetQueryAsDOM(formProperties, defaultCompiledTemplates); |
| } |
| |
| /// <summary> |
| /// Fast means of constructing query using a precompiled stylesheet |
| /// </summary> |
| public static string GetQueryAsXmlString(IDictionary<string, string> formProperties, XslCompiledTransform template) |
| { |
| // TODO: Suppress XML header with encoding (as Strings have no encoding) |
| using (var stream = new MemoryStream()) |
| { |
| TransformCriteria(formProperties, template, stream); |
| using (StreamReader reader = new StreamReader(stream)) |
| { |
| return reader.ReadToEnd(); |
| } |
| } |
| } |
| |
| /// <summary> |
| /// Slow means of constructing query parsing a stylesheet from an input stream |
| /// </summary> |
| public static string GetQueryAsXmlString(IDictionary<string, string> formProperties, Stream xslIs) |
| { |
| // TODO: Suppress XML header with encoding (as Strings have no encoding) |
| using (var stream = new MemoryStream()) |
| { |
| TransformCriteria(formProperties, xslIs, stream); |
| using (StreamReader reader = new StreamReader(stream)) |
| { |
| return reader.ReadToEnd(); |
| } |
| } |
| } |
| |
| /// <summary> |
| /// Fast means of constructing query using a cached,precompiled stylesheet |
| /// </summary> |
| public static XmlDocument GetQueryAsDOM(IDictionary<string, string> formProperties, XslCompiledTransform template) |
| { |
| XmlDocument result = new XmlDocument(); |
| using (var stream = new MemoryStream()) |
| { |
| TransformCriteria(formProperties, template, stream); |
| stream.Position = 0; |
| result.Load(stream); |
| } |
| return result; |
| } |
| |
| /// <summary> |
| /// Slow means of constructing query - parses stylesheet from input stream |
| /// </summary> |
| public static XmlDocument GetQueryAsDOM(IDictionary<string, string> formProperties, Stream xslIs) |
| { |
| XmlDocument result = new XmlDocument(); |
| using (var stream = new MemoryStream()) |
| { |
| TransformCriteria(formProperties, xslIs, stream); |
| stream.Position = 0; |
| result.Load(stream); |
| } |
| return result; |
| } |
| |
| /// <summary> |
| /// Slower transformation using an uncompiled stylesheet (suitable for development environment) |
| /// </summary> |
| public static void TransformCriteria(IDictionary<string, string> formProperties, Stream xslIs, Stream result) |
| { |
| XmlDocument xslDoc = new XmlDocument(); |
| xslDoc.Load(xslIs); |
| |
| XslCompiledTransform transformer = new XslCompiledTransform(); |
| transformer.Load(xslDoc); |
| |
| TransformCriteria(formProperties, transformer, result); |
| } |
| |
| /// <summary> |
| /// Fast transformation using a pre-compiled stylesheet (suitable for production environments) |
| /// </summary> |
| public static void TransformCriteria(IDictionary<string, string> formProperties, XslCompiledTransform transformer, Stream result) |
| { |
| XmlDocument doc = new XmlDocument(); |
| XmlElement root = doc.CreateElement("Document"); |
| doc.AppendChild(root); |
| |
| foreach (var prop in formProperties) |
| { |
| string propName = prop.Key; |
| string value = prop.Value; |
| if ((value != null) && (value.Length > 0)) |
| { |
| DOMUtils.InsertChild(root, propName, value); |
| } |
| } |
| |
| transformer.Transform(doc, null, result); |
| } |
| |
| /// <summary> |
| /// Parses a query stylesheet for repeated use |
| /// </summary> |
| public static XslCompiledTransform GetTemplates(Stream xslIs) |
| { |
| using (var reader = XmlReader.Create(xslIs)) |
| { |
| XslCompiledTransform xslt = new XslCompiledTransform(); |
| xslt.Load(reader); |
| return xslt; |
| } |
| } |
| } |
| } |
| #endif |