#region Apache Notice /***************************************************************************** * $Revision: 408099 $ * $LastChangedDate$ * $LastChangedBy$ * * iBATIS.NET Data Mapper * Copyright (C) 2008/2005 - The Apache Software Foundation * * * Licensed 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. * ********************************************************************************/ #endregion using System; using System.Collections.Generic; using System.Reflection; using Apache.Ibatis.Common.Configuration; using Apache.Ibatis.Common.Contracts; using Apache.Ibatis.Common.Exceptions; using Apache.Ibatis.Common.Logging; using Apache.Ibatis.Common.Resources; using Apache.Ibatis.DataMapper.Configuration.Interpreters.Config; using Apache.Ibatis.DataMapper.Model; using Apache.Ibatis.DataMapper.Configuration.Module; namespace Apache.Ibatis.DataMapper.Configuration { /// /// The default implementation. /// /// /// Use: /// /// IConfigurationEngine engine = /// new DefaultConfigurationEngine( /// new XmlConfigurationInterpreter( /// new new FileResource("SqlMap.config") ) ); /// public class DefaultConfigurationEngine : IConfigurationEngine { private readonly IConfigurationStore configurationStore = null; private readonly ConfigurationSetting configurationSetting = null; private readonly IList modules = null; private IModelStore modelStore = null; private IConfigurationInterpreter interpreter = null; /// /// Event launch on processing file resource /// public event EventHandler FileResourceLoad = delegate { }; private static readonly ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); #region constructors /// /// Initializes a new instance of the class. /// public DefaultConfigurationEngine() { configurationStore = new DefaultConfigurationStore(); configurationSetting = new ConfigurationSetting(); modules = new List(); ResourceLoaderRegistry.ResetEventHandler(); ResourceLoaderRegistry.LoadFileResource += FileResourceEventHandler; } /// /// Initializes a new instance of the class. /// /// The configuration setting. public DefaultConfigurationEngine(ConfigurationSetting configurationSetting):this() { Contract.Require.That(configurationSetting, Is.Not.Null).When("retrieving argument ConfigurationSetting in DefaultConfigurationEngine constructor"); this.configurationSetting = configurationSetting; if (configurationSetting.Properties.Count > 0) { IEnumerator> properties = configurationSetting.Properties.GetEnumerator(); while (properties.MoveNext()) { IConfiguration config = new MutableConfiguration( ConfigConstants.ELEMENT_PROPERTY, properties.Current.Key, properties.Current.Value); configurationStore.AddPropertyConfiguration(config); } } } #endregion #region IConfigurationEngine Members /// /// Gets the model store. /// /// The model store. public IModelStore ModelStore { get { return modelStore; } } /// /// Gets the configuration store. /// /// The configuration store. public IConfigurationStore ConfigurationStore { get { return configurationStore; } } /// /// Registers the . /// /// The interpreter. public void RegisterInterpreter(IConfigurationInterpreter interpreter) { Contract.Require.That(interpreter, Is.Not.Null).When("retrieving argument interpreter in RegisterInterpreter method"); this.interpreter = interpreter; } /// /// Add a module to the . /// /// The module. public void RegisterModule(IModule module) { Contract.Require.That(module, Is.Not.Null).When("retrieving argument module in RegisterModule method"); modules.Add(module); } /// /// Builds the mapper factory. /// /// the mapper factory public IMapperFactory BuildMapperFactory() { // Registers file Xml, ... configuration element if (interpreter!=null) { interpreter.ProcessResource(configurationStore); // ensure that the default configuration settings get updated after the interpreter runs configurationSetting.PreserveWhitespace = TryGetSettingBoolean(ConfigConstants.ATTRIBUTE_PRESERVEWHITSPACE, configurationSetting.PreserveWhitespace); configurationSetting.UseReflectionOptimizer = TryGetSettingBoolean(ConfigConstants.ATTRIBUTE_USE_REFLECTION_OPTIMIZER, configurationSetting.UseReflectionOptimizer); configurationSetting.IsCacheModelsEnabled = TryGetSettingBoolean(ConfigConstants.ATTRIBUTE_CACHE_MODELS_ENABLED, configurationSetting.IsCacheModelsEnabled); configurationSetting.UseStatementNamespaces = TryGetSettingBoolean(ConfigConstants.ATTRIBUTE_USE_STATEMENT_NAMESPACES, configurationSetting.UseStatementNamespaces); configurationSetting.ValidateMapperConfigFile = TryGetSettingBoolean(ConfigConstants.ATTRIBUTE_VALIDATE_SQLMAP, configurationSetting.ValidateMapperConfigFile); } // Registers code configuration element for(int i=0;i resolved = new List(); for (int i = 0; i < configurationStore.ResultMaps.Length; i++) { ResolveExtendResultMap(resolved, configurationStore.ResultMaps[i]); } // Process Extends ParameterMap resolved = new List(); for (int i = 0; i < configurationStore.ParameterMaps.Length; i++) { ResolveExtendParameterMap(resolved, configurationStore.ParameterMaps[i]); } // Process Include Sql statement for (int i = 0; i < configurationStore.Statements.Length; i++) { ConfigurationCollection includes = configurationStore.Statements[i].Children.RecursiveFind(ConfigConstants.ELEMENT_INCLUDE); if (includes.Count > 0) { ResolveIncludeStatement(includes); } } // Process Extends statement resolved = new List(); for (int i = 0; i < configurationStore.Statements.Length; i++) { ResolveExtendStatement(resolved, configurationStore.Statements[i]); } modelStore = new DefaultModelStore(); IModelBuilder builder = new DefaultModelBuilder(modelStore); builder.BuildModel(configurationSetting, configurationStore); IDataMapper dataMapper = new DataMapper(modelStore); return new DefaultMapperFactory(dataMapper); } /// /// Used by BuildMapperFactory to retrieve configuration values from configurationStore. /// private bool TryGetSettingBoolean(string attributeKey, bool defaultValue) { var setting = configurationStore.Settings[attributeKey]; if (setting != null) { return (bool)setting.GetValue(typeof(bool), defaultValue); } return defaultValue; } #endregion private IConfiguration ResolveExtendResultMap(IList resolvedResultMap, IConfiguration resultMap) { if (resultMap.Attributes.ContainsKey(ConfigConstants.ATTRIBUTE_EXTENDS)) { if (!resolvedResultMap.Contains(resultMap)) { resolvedResultMap.Add(resultMap); // Find the extended resultMap string extends = resultMap.Attributes[ConfigConstants.ATTRIBUTE_EXTENDS]; IConfiguration father = configurationStore.GetResultMapConfiguration(extends); if (father == null) { throw new ConfigurationException("There's no extended resultMap named '" + extends + "' for the resultMap '" + resultMap.Id + "'"); } father = ResolveExtendResultMap(resolvedResultMap, father); resultMap.Children.AddRange(father.Children.Remove(ConfigConstants.ELEMENT_DISCRIMINATOR)); // Copy the groupBy attribute if (father.Attributes.ContainsKey(ConfigConstants.ATTRIBUTE_GROUPBY)) { resultMap.Attributes[ConfigConstants.ATTRIBUTE_GROUPBY] = father.Attributes[ConfigConstants.ATTRIBUTE_GROUPBY]; } } } return resultMap; } private IConfiguration ResolveExtendParameterMap(IList resolvedParameterMap, IConfiguration parameterMap) { if (parameterMap.Attributes.ContainsKey(ConfigConstants.ATTRIBUTE_EXTENDS)) { if (!resolvedParameterMap.Contains(parameterMap)) { resolvedParameterMap.Add(parameterMap); // Find the extended resultMap string extends = parameterMap.Attributes[ConfigConstants.ATTRIBUTE_EXTENDS]; IConfiguration father = configurationStore.GetParameterMapConfiguration(extends); if (father == null) { throw new ConfigurationException("There's no extended parameterMap named '" + extends + "' for the parameterMap '" + parameterMap.Id + "'"); } father = ResolveExtendParameterMap(resolvedParameterMap, father); parameterMap.Children.InsertRange(0,father.Children); } } return parameterMap; } private void ResolveIncludeStatement(ConfigurationCollection includes) { for (int i = 0; i < includes.Count;i++ ) { IConfiguration include = includes[i]; IConfiguration toInclude = configurationStore.GetStatementConfiguration(include.Id); if (toInclude == null) { throw new ConfigurationException("There's no include statement named '" + include.Id + "'"); } IConfiguration parent = include.Parent; int childIndex = include.Parent.Children.IndexOf(include); parent.Children.RemoveAt(childIndex); parent.Children.InsertRange(childIndex, toInclude.Children); } } private IConfiguration ResolveExtendStatement(IList resolvedStatement, IConfiguration statement) { if (statement.Attributes.ContainsKey(ConfigConstants.ATTRIBUTE_EXTENDS)) { if (!resolvedStatement.Contains(statement)) { resolvedStatement.Add(statement); // Find the extended resultMap string extends = statement.Attributes[ConfigConstants.ATTRIBUTE_EXTENDS]; IConfiguration father = configurationStore.GetStatementConfiguration(extends); if (father==null) { throw new ConfigurationException("There's no extended statement named '" + extends + "' for the statement '" + statement.Id+"'"); } father = ResolveExtendStatement(resolvedStatement, father); statement.Children.InsertRange(0, father.Children); } } return statement; } private void FileResourceEventHandler(object sender, FileResourceLoadEventArgs evnt) { FileResourceLoad(sender, evnt); } } }