/*
Kooboo is a content management system based on ASP.NET MVC framework. Copyright 2009 Yardi Technology Limited.
This program is free software: you can redistribute it and/or modify it under the terms of the
GNU General Public License version 3 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program.
If not, see http://www.kooboo.com/gpl3/.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Configuration;
using Everest.Library;
using Everest.Library.Providers.Caching;
using Lucene.Net.Documents;
using Lucene.Net.Search;
using Lucene.Net.Analysis;
namespace Everest.Search.Configuration{
internal class SearchConfiguration
{
public string Directory { get; set; }
public IDictionary<Type, DocumentTypeConfiguration> Types { get; set; }
/// <summary>
/// Deserializes this instance.
/// </summary>
/// <returns></returns>
protected static SearchConfiguration Deserialize(string fileName)
{
XmlDocument xDom = new XmlDocument();
xDom.Load(fileName);
XmlNode searchNode = xDom.SelectSingleNode("search");
if (searchNode != null)
{
SearchConfiguration config = new SearchConfiguration();
DesignByContract.Require(searchNode.Attributes["directory"] != null && !string.IsNullOrEmpty(searchNode.Attributes["directory"].Value),
string.Format(Resources.AttributeRequired, "directory", searchNode.InnerXml));
config.Directory = searchNode.Attributes["directory"].Value;
XmlNodeList typeNodes = searchNode.SelectNodes("types/type");
if (typeNodes != null)
{
IDictionary<Type, DocumentTypeConfiguration> types = new Dictionary<Type, DocumentTypeConfiguration>();
foreach (XmlNode typeNode in typeNodes)
{
DocumentTypeConfiguration type = new DocumentTypeConfiguration();
DesignByContract.Require(typeNode.Attributes["classType"] != null && !string.IsNullOrEmpty(typeNode.Attributes["classType"].Value),
string.Format(Resources.AttributeRequired, "classType", typeNode.InnerXml));
type.ClassType = Type.GetType(typeNode.Attributes["classType"].Value);
//the classType could not be null...
DesignByContract.Require(type.ClassType != null, string.Format(Resources.TypeCouldNotBeFound, typeNode.Attributes["classType"].Value));
if (typeNode.Attributes["primaryField"] != null)
{
type.PrimaryField = typeNode.Attributes["primaryField"].Value;
}
type.Directory = typeNode.Attributes["directory"].Value;
//get analyzer
if (typeNode.Attributes["analyzer"] != null)
{
Type analyzerType = Type.GetType(typeNode.Attributes["analyzer"].Value);
DesignByContract.Require(type.Analyzer != null, string.Format(Resources.TypeCouldNotBeFound, typeNode.Attributes["analyzer"].Value));
type.Analyzer = (Analyzer)Activator.CreateInstance(analyzerType);
}
DeserializeFields(typeNode, ref type);
DeserializeQuery(typeNode, ref type);
types.Add(type.ClassType, type);
}
config.Types = types;
return config;
}
}
return null;
}
/// <summary>
/// Opens this instance.
/// </summary>
/// <returns></returns>
public static SearchConfiguration Open()
{
string fileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "search.config");
return Open(fileName);
}
private static object lockHelper = new object();
/// <summary>
/// Opens the specified file name.
/// </summary>
/// <param name="fileName">Name of the file.</param>
/// <returns></returns>
public static SearchConfiguration Open(string filePath)
{
string cacheKey = string.Format("Serach:Cache:FileName:{0}", filePath);
SearchConfiguration config = CacheManager.Get(cacheKey) as SearchConfiguration;
if (config == null)
{
lock (lockHelper)
{
if (config == null)
{
config = Deserialize(filePath);
CacheManager.Add(cacheKey, config, CacheItemPriority.Normal, null, new FileDependency(filePath));
}
}
}
return config;
}
/// <summary>
/// Deserializes the fields.
/// </summary>
/// <param name="typeNode">The type node.</param>
/// <param name="type">The type.</param>
private static void DeserializeFields(XmlNode typeNode, ref DocumentTypeConfiguration type)
{
XmlNode fieldsNode = typeNode.SelectSingleNode("fields");
if (fieldsNode != null)
{
Fields fields = new Fields();
if (fieldsNode.Attributes["convertor"] != null && !string.IsNullOrEmpty(fieldsNode.Attributes["convertor"].Value.Trim()))
{
fields.ConvertorType = Type.GetType(fieldsNode.Attributes["convertor"].Value.Trim());
//the classType could not be null...
DesignByContract.Require(type.ClassType != null, string.Format(Resources.TypeCouldNotBeFound, fieldsNode.Attributes["convertor"].Value.Trim()));
}
DeserializeCompositionFields(fieldsNode, ref fields);
DeserializePropertyFields(fieldsNode, ref fields);
type.Fields = fields;
}
}
/// <summary>
/// Deserializes the query.
/// </summary>
/// <param name="typeNode">The type node.</param>
/// <param name="type">The type.</param>
private static void DeserializeQuery(XmlNode typeNode, ref DocumentTypeConfiguration type)
{
XmlNode queryNode = typeNode.SelectSingleNode("query");
if (queryNode != null)
{
List<QueryField> queryFields = new List<QueryField>();
foreach (XmlNode fieldNode in queryNode.ChildNodes)
{
QueryField field = new QueryField();
queryFields.Add(field);
DesignByContract.Require(fieldNode.Attributes["name"] != null && !string.IsNullOrEmpty(fieldNode.Attributes["name"].Value),
string.Format(Resources.AttributeRequired, "name", fieldNode.InnerXml));
DesignByContract.Require(fieldNode.Attributes["occur"] != null && !string.IsNullOrEmpty(fieldNode.Attributes["occur"].Value),
string.Format(Resources.AttributeRequired, "occur", fieldNode.InnerXml));
field.Name = fieldNode.Attributes["name"].Value;
field.Occur = ConverToOccur(fieldNode.Attributes["occur"].Value);
}
type.QueryFields = queryFields.ToArray();
}
}
private static void DeserializeCompositionFields(XmlNode fieldsNodes, ref Fields fields)
{
XmlNodeList compositionFieldNodes = fieldsNodes.SelectNodes("composition/field");
if (compositionFieldNodes != null)
{
List<CompositionField> compositionFields = new List<CompositionField>();
foreach (XmlNode compositionFiedNode in compositionFieldNodes)
{
CompositionField field = new CompositionField();
field.Index = compositionFiedNode.Attributes["index"] == null ? Field.Index.TOKENIZED : ConvertToFieldIndex(compositionFiedNode.Attributes["index"].Value);
field.Name = compositionFiedNode.Attributes["name"].Value;
DesignByContract.Require(string.IsNullOrEmpty(field.Name), string.Format(Resources.AttributeRequired, "name", compositionFiedNode.InnerXml));
List<string> properties = new List<string>();
foreach (XmlNode addNode in compositionFiedNode.ChildNodes)
{
DesignByContract.Require(addNode.Attributes["name"] != null && !string.IsNullOrEmpty(addNode.Attributes["name"].Value),
string.Format(Resources.AttributeRequired, "name", addNode.InnerXml));
properties.Add(addNode.Attributes["name"].Value);
}
field.Properties = properties.ToArray();
compositionFields.Add(field);
}
fields.CompositionFields = compositionFields.ToArray();
}
}
private static void DeserializePropertyFields(XmlNode fieldsNodes, ref Fields fields)
{
XmlNodeList propertyFieldNodes = fieldsNodes.SelectNodes("properties/add");
if (propertyFieldNodes != null)
{
Dictionary<string, PropertyField> propertyFields = new Dictionary<string, PropertyField>();
foreach (XmlNode propertyNode in propertyFieldNodes)
{
PropertyField field = new PropertyField();
DesignByContract.Require(propertyNode.Attributes["name"] != null && !string.IsNullOrEmpty(propertyNode.Attributes["name"].Value),
string.Format(Resources.AttributeRequired, "name", propertyNode.InnerXml));
DesignByContract.Require(propertyNode.Attributes["property"] != null && !string.IsNullOrEmpty(propertyNode.Attributes["property"].Value),
string.Format(Resources.AttributeRequired, "property", propertyNode.InnerXml));
field.Name = propertyNode.Attributes["name"].Value;
field.Property = propertyNode.Attributes["property"].Value;
field.Index = propertyNode.Attributes["index"] == null ? Field.Index.TOKENIZED : ConvertToFieldIndex(propertyNode.Attributes["index"].Value);
field.Store = propertyNode.Attributes["store"] == null ? Field.Store.NO : ConvertToFieldStore(propertyNode.Attributes["store"].Value);
propertyFields.Add(field.Name, field);
}
fields.PropertyFields = propertyFields;
}
}
private static Field.Store ConvertToFieldStore(string value)
{
switch (value.ToUpper())
{
case "COMPRESS": return Field.Store.COMPRESS;
case "NO": return Field.Store.NO;
case "YES": return Field.Store.YES;
default:
throw new ArgumentException(string.Format(Resources.NotRecognizedFieldStore, value));
}
}
private static Field.Index ConvertToFieldIndex(string value)
{
switch (value.ToUpper())
{
case "NO": return Field.Index.NO;
case "NO_NORMS": return Field.Index.NO_NORMS;
case "TOKENIZED": return Field.Index.TOKENIZED;
case "UN_TOKENIZED": return Field.Index.UN_TOKENIZED;
default:
throw new ArgumentException(string.Format(Resources.NotRecognizedFieldIndex, value));
}
}
private static BooleanClause.Occur ConverToOccur(string value)
{
switch (value.ToUpper())
{
case "MUST": return BooleanClause.Occur.MUST;
case "MUST_NOT": return BooleanClause.Occur.MUST_NOT;
case "SHOULD": return BooleanClause.Occur.SHOULD;
default:
throw new ArgumentException(string.Format(Resources.NotRecognizedOccurValue, value));
}
}
}
}
|