Clover.NET coverage report - Coverage

Coverage timestamp: Friday, May 20, 2005 9:17:00 PM

File Stats: LOC: 1359   Methods: 20
NCLOC: 898 Classes: 1
 
Source File Conditionals Statements Methods TOTAL
Configuration\DomSqlMapBuilder.cs 68.8 % 92.2 % 90.0 % 87.0 %
coverage coverage
1  
2   #region Apache Notice
3   /*****************************************************************************
4   * $Header: $
5   * $Revision: $
6   * $Date: $
7   *
8   * iBATIS.NET Data Mapper
9   * Copyright (C) 2004 - Gilles Bayon
10   *
11   *
12   * Licensed under the Apache License, Version 2.0 (the "License");
13   * you may not use this file except in compliance with the License.
14   * You may obtain a copy of the License at
15   *
16   * http://www.apache.org/licenses/LICENSE-2.0
17   *
18   * Unless required by applicable law or agreed to in writing, software
19   * distributed under the License is distributed on an "AS IS" BASIS,
20   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21   * See the License for the specific language governing permissions and
22   * limitations under the License.
23   *
24   ********************************************************************************/
25   #endregion
26  
27   #region Using
28  
29   using System;
30   using System.Collections;
31   using System.IO;
32   using System.Reflection;
33   using System.Text;
34   using System.Xml;
35   using System.Xml.Schema;
36   using System.Xml.Serialization;
37   using IBatisNet.Common;
38   using IBatisNet.Common.Exceptions;
39   using IBatisNet.Common.Utilities;
40   using IBatisNet.DataMapper.Configuration.Alias;
41   using IBatisNet.DataMapper.Configuration.Cache;
42   using IBatisNet.DataMapper.Configuration.ParameterMapping;
43   using IBatisNet.DataMapper.Configuration.ResultMapping;
44   using IBatisNet.DataMapper.Configuration.Sql;
45   using IBatisNet.DataMapper.Configuration.Sql.Dynamic;
46   using IBatisNet.DataMapper.Configuration.Sql.Dynamic.Elements;
47   using IBatisNet.DataMapper.Configuration.Sql.SimpleDynamic;
48   using IBatisNet.DataMapper.Configuration.Sql.Static;
49   using IBatisNet.DataMapper.Configuration.Statements;
50   using IBatisNet.DataMapper.MappedStatements;
51   using IBatisNet.DataMapper.Scope;
52   using IBatisNet.DataMapper.TypeHandlers;
53  
54   #endregion
55  
56   namespace IBatisNet.DataMapper.Configuration
57   {
58   /// <summary>
59   /// Builds SqlMapClient instances from a supplied resource (e.g. XML configuration file)
60   /// </summary>
61   public class DomSqlMapBuilder
62   {
63   #region Embedded resource
64  
65   // Which files must we allow to be used as Embedded Resources ?
66   // - slqMap.config [No]
67   // - providers.config [No]
68   // - sqlMap files [yes]
69   // - properties file (like Database.config) [Yes]
70   // see contribution, NHibernate usage,
71   // see http://www.codeproject.com/csharp/EmbeddedResourceStrings.asp
72   // see http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=75
73   #endregion
74  
75   #region Constant
76   private const string DEFAULT_PROVIDER_NAME = "_DEFAULT_PROVIDER_NAME";
77   /// <summary>
78   /// Dot representation
79   /// </summary>
80   public const string DOT = ".";
81  
82   /// <summary>
83   /// Token for SqlMapConfig xml root.
84   /// </summary>
85   private const string XML_CONFIG_ROOT = "sqlMapConfig";
86  
87   /// <summary>
88   /// Token for xml path to SqlMapConfig settings element.
89   /// </summary>
90   private const string XML_CONFIG_SETTINGS = "/sqlMapConfig/settings/setting";
91  
92   /// <summary>
93   /// Token for providers config file name.
94   /// </summary>
95   private const string PROVIDERS_FILE_NAME = "providers.config";
96  
97   // TODO: Other XML paths.
98  
99   /// <summary>
100   /// Token for useStatementNamespaces attribute.
101   /// </summary>
102   private const string ATR_USE_STATEMENT_NAMESPACES = "useStatementNamespaces";
103   /// <summary>
104   /// Token for cacheModelsEnabled attribute.
105   /// </summary>
106   private const string ATR_CACHE_MODELS_ENABLED = "cacheModelsEnabled";
107   /// <summary>
108   /// Token for validateSqlMap attribute.
109   /// </summary>
110   private const string ATR_VALIDATE_SQLMAP = "validateSqlMap";
111   /// <summary>
112   /// Token for embedStatementParams attribute.
113   /// </summary>
114   private const string ATR_EMBED_STATEMENT_PARAMS = "useEmbedStatementParams";
115  
116   #endregion
117  
118   #region Fields
119  
120   private ConfigurationScope _configScope = null;
121   private InlineParameterMapParser _paramParser = null;
122  
123   #endregion
124  
125   #region Constructor
126  
127   /// <summary>
128   /// Default constructor
129   /// </summary>
130 170 public DomSqlMapBuilder()
131   {
132 170 _configScope = new ConfigurationScope();
133 170 _paramParser = new InlineParameterMapParser(_configScope.ErrorContext);
134   }
135   #endregion
136  
137   #region Methods
138  
139   /// <summary>
140   /// Build a SqlMapper instance
141   /// </summary>
142   /// <param name="document">An xml configuration document</param>
143   /// <param name="dataSource">A data source</param>
144   /// <param name="useConfigFileWatcher"></param>
145   /// <param name="isCallFromDao"></param>
146   /// <returns>return an a SqlMapper instance</returns>
147 170 private SqlMapper Build(XmlDocument document,
148   DataSource dataSource,
149   bool useConfigFileWatcher, bool isCallFromDao)
150   {
151 170 _configScope.SqlMapConfigDocument = document;
152 170 _configScope.DataSource = dataSource;
153 170 _configScope.IsCallFromDao = isCallFromDao;
154 170 _configScope.UseConfigFileWatcher = useConfigFileWatcher;
155  
156  
157 170 try
158   {
159 170 ValidateSchema( document.ChildNodes[1], "SqlMapConfig.xsd" );
160 170 Initialize();
161 170 return _configScope.SqlMapper;
162   }
163   catch(Exception e)
164   {
165 0 throw new ConfigurationException(_configScope.ErrorContext.ToString(), e);
166   }
167   }
168  
169   /// <summary>
170   /// validate againts schema
171   /// </summary>
172   /// <param name="section">The doc to validate</param>
173   /// <param name="schemaFileName">schema File Name</param>
174 170 private void ValidateSchema( XmlNode section, string schemaFileName )
175   {
176 170 XmlValidatingReader validatingReader = null;
177 170 Stream xsdFile = null;
178 170 StreamReader streamReader = null;
179  
180 170 _configScope.ErrorContext.Activity = "Validate SqlMap config";
181 170 try
182   {
183   //Validate the document using a schema
184 170 validatingReader = new XmlValidatingReader( new XmlTextReader( new StringReader( section.OuterXml ) ) );
185 170 validatingReader.ValidationType = ValidationType.Schema;
186  
187 170 xsdFile = GetStream( schemaFileName );
188 170 streamReader = new StreamReader( xsdFile );
189  
190 170 validatingReader.Schemas.Add( XmlSchema.Read( new XmlTextReader( streamReader ), new ValidationEventHandler(ValidationCallBack) ) );
191  
192   // Wire up the call back. The ValidationEvent is fired when the
193   // XmlValidatingReader hits an issue validating a section of the xml
194 170 validatingReader.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
195  
196   // Validate the document
197 6800 while (validatingReader.Read()){}
198  
199 170 if(! _configScope.IsXmlValid )
200   {
201 0 throw new ConfigurationException( "Invalid SqlMap.config document. cause :"+_configScope.ErrorContext.Resource);
202   //( Resource.ResourceManager.FormatMessage( Resource.MessageKeys.DocumentNotValidated, _schemaErrors )) );
203   }
204   }
205   finally
206   {
207 170 if( validatingReader != null ) validatingReader.Close();
208 170 if( xsdFile != null ) xsdFile.Close();
209 170 if( streamReader != null ) streamReader.Close();
210   }
211   }
212  
213 0 private void ValidationCallBack( object sender, ValidationEventArgs args )
214   {
215   _configScope.IsXmlValid = false;
216   _configScope.ErrorContext.Resource += args.Message + Environment.NewLine;
217   }
218  
219   /// <summary>
220   /// Load statement, parameters, resultmap.
221   /// Used by Dao
222   /// </summary>
223 0 public SqlMapper Build(XmlDocument document, DataSource dataSource, bool useConfigFileWatcher)
224   {
225   return Build(document, dataSource, useConfigFileWatcher, true);
226   }
227  
228  
229   /// <summary>
230   /// Load SqlMap configuration from
231   /// from the XmlDocument passed in parameter.
232   /// </summary>
233   /// <param name="document">The xml sql map configuration.</param>
234   /// <param name="useConfigFileWatcher"></param>
235 170 public SqlMapper Build(XmlDocument document, bool useConfigFileWatcher)
236   {
237 170 return Build(document, null, useConfigFileWatcher, false);
238   }
239  
240  
241   /// <summary>
242   /// Reset PreparedStatements cache
243   /// </summary>
244 170 private void Reset()
245   {
246   }
247  
248   /// <summary>
249   /// Intilaize an SqlMap.
250   /// </summary>
251 170 private void Initialize()
252   {
253 170 Reset();
254  
255 170 _configScope.SqlMapper = new SqlMapper( new TypeHandlerFactory() );
256  
257   #region Load settings
258  
259 170 _configScope.ErrorContext.Activity = "loading global settings";
260  
261 170 XmlNodeList settings = _configScope.SqlMapConfigDocument.SelectNodes(XML_CONFIG_SETTINGS);
262  
263 170 if (settings!=null)
264   {
265 170 foreach (XmlNode setting in settings)
266   {
267 510 if (setting.Attributes[ATR_USE_STATEMENT_NAMESPACES] != null )
268   {
269 170 _configScope.UseStatementNamespaces = Convert.ToBoolean(setting.Attributes[ATR_USE_STATEMENT_NAMESPACES].Value);
270   }
271 510 if (setting.Attributes[ATR_CACHE_MODELS_ENABLED] != null )
272   {
273 170 _configScope.IsCacheModelsEnabled = Convert.ToBoolean(setting.Attributes[ATR_CACHE_MODELS_ENABLED].Value);
274   }
275 510 if (setting.Attributes[ATR_EMBED_STATEMENT_PARAMS] != null )
276   {
277 0 _configScope.UseEmbedStatementParams = Convert.ToBoolean(setting.Attributes[ATR_EMBED_STATEMENT_PARAMS].Value);
278   }
279  
280 510 if (setting.Attributes[ATR_VALIDATE_SQLMAP] != null )
281   {
282 170 _configScope.ValidateSqlMap = Convert.ToBoolean(setting.Attributes[ATR_VALIDATE_SQLMAP].Value);
283   }
284   }
285   }
286  
287 170 _configScope.SqlMapper.SetCacheModelsEnabled(_configScope.IsCacheModelsEnabled);
288 170 _configScope.SqlMapper.SetUseEmbedStatementParams(_configScope.UseEmbedStatementParams);
289  
290   #endregion
291  
292   #region Load Global Properties
293 170 if (_configScope.IsCallFromDao == false)
294   {
295 170 _configScope.NodeContext = _configScope.SqlMapConfigDocument.SelectSingleNode(XML_CONFIG_ROOT);
296 170 ParseGlobalProperties();
297   }
298   #endregion
299  
300   #region Load providers
301 170 if (_configScope.IsCallFromDao == false)
302   {
303 170 GetProviders();
304   }
305   #endregion
306  
307   #region Load DataBase
308   #region Choose the provider
309 170 Provider provider = null;
310 170 if ( _configScope.IsCallFromDao==false )
311   {
312 170 provider = ParseProvider();
313 170 _configScope.ErrorContext.Reset();
314   }
315   #endregion
316  
317   #region Load the DataSources
318  
319 170 _configScope.ErrorContext.Activity = "loading Database DataSource";
320 170 XmlNode nodeDataSource = _configScope.SqlMapConfigDocument.SelectSingleNode("/sqlMapConfig/database/dataSource");
321 170 if (nodeDataSource == null)
322   {
323 0 if (_configScope.IsCallFromDao == false)
324   {
325   throw new ConfigurationException("There's no dataSource tag in SqlMap.config.");
326   }
327   else // patch from Luke Yang
328   {
329   _configScope.SqlMapper.DataSource = _configScope.DataSource;
330   }
331   }
332   else
333   {
334 170 if (_configScope.IsCallFromDao == false)
335   {
336 170 _configScope.ErrorContext.Resource = nodeDataSource.OuterXml.ToString();
337 170 _configScope.ErrorContext.MoreInfo = "parse DataSource";
338 170 XmlSerializer serializer = null;
339 170 serializer = new XmlSerializer(typeof(DataSource));
340 170 DataSource dataSource = (DataSource) serializer.Deserialize(new XmlNodeReader(nodeDataSource));
341  
342 170 dataSource.Provider = provider;
343   // Use Global Properties if any
344 170 dataSource.ConnectionString = Resources.ParsePropertyTokens(dataSource.ConnectionString, _configScope.Properties);
345  
346 170 _configScope.DataSource = dataSource;
347 170 _configScope.SqlMapper.DataSource = _configScope.DataSource;
348   }
349   else
350   {
351 0 _configScope.SqlMapper.DataSource = _configScope.DataSource;
352   }
353 170 _configScope.ErrorContext.Reset();
354   }
355   #endregion
356   #endregion
357  
358   #region Load Global TypeAlias
359 170 foreach (XmlNode xmlNode in _configScope.SqlMapConfigDocument.SelectNodes("/sqlMapConfig/alias/typeAlias"))
360   {
361 340 _configScope.ErrorContext.Activity = "loading global Type alias";
362 340 TypeAlias typeAlias = null;
363 340 XmlSerializer serializer = new XmlSerializer(typeof(TypeAlias));
364  
365 340 typeAlias = (TypeAlias) serializer.Deserialize(new XmlNodeReader(xmlNode));
366 340 _configScope.ErrorContext.ObjectId = typeAlias.ClassName;
367 340 _configScope.ErrorContext.MoreInfo = "initialize type alias";
368 340 typeAlias.Initialize();
369  
370 340 _configScope.SqlMapper.AddTypeAlias( typeAlias.Name, typeAlias );
371   }
372 170 _configScope.ErrorContext.Reset();
373   #endregion
374  
375   #region Load TypeHandlers
376 170 foreach (XmlNode xmlNode in _configScope.SqlMapConfigDocument.SelectNodes("/sqlMapConfig/typeHandlers/typeHandler"))
377   {
378 170 try
379   {
380 170 _configScope.ErrorContext.Activity = "loading typeHandler";
381 170 TypeHandler handler = null;
382 170 XmlSerializer serializer = new XmlSerializer(typeof(TypeHandler));
383  
384 170 handler = (TypeHandler) serializer.Deserialize(new XmlNodeReader(xmlNode));
385 170 _configScope.ErrorContext.ObjectId = handler.ClassName;
386 170 _configScope.ErrorContext.MoreInfo = "initialize typeHandler";
387 170 handler.Initialize();
388  
389  
390 170 _configScope.ErrorContext.MoreInfo = "Check the callback attribute '" + handler.ClassName + "' (must be a classname).";
391 170 ITypeHandler typeHandler = null;
392 170 Type type = _configScope.SqlMapper.GetType(handler.CallBackName);
393 170 object impl = Activator.CreateInstance( type );
394 170 if (impl is ITypeHandlerCallback)
395   {
396 170 typeHandler = new CustomTypeHandler((ITypeHandlerCallback) impl);
397   }
398 0 else if (impl is ITypeHandler)
399   {
400   typeHandler = (ITypeHandler) impl;
401   }
402   else
403   {
404   throw new ConfigurationException("The callBack type is not a valid implementation of ITypeHandler or ITypeHandlerCallback");
405   }
406  
407 170 _configScope.ErrorContext.MoreInfo = "Check the type attribute '" + handler.ClassName + "' (must be a class name) or the dbType '" + handler.DbType + "' (must be a DbType type name).";
408 170 if (handler.DbType!= null && handler.DbType.Length > 0)
409   {
410 170 _configScope.TypeHandlerFactory.Register(Resources.TypeForName(handler.ClassName), handler.DbType, typeHandler);
411   }
412   else
413   {
414 0 _configScope.TypeHandlerFactory.Register(Resources.TypeForName(handler.ClassName), typeHandler);
415   }
416   }
417   catch (Exception e)
418   {
419 0 throw new ConfigurationException("Error registering occurred. Cause: " + e.Message, e);
420   }
421   }
422 170 _configScope.ErrorContext.Reset();
423   #endregion
424  
425   #region Load sqlMap mapping files
426  
427 170 foreach (XmlNode xmlNode in _configScope.SqlMapConfigDocument.SelectNodes("/sqlMapConfig/sqlMaps/sqlMap"))
428   {
429 1870 _configScope.NodeContext = xmlNode;
430 1870 ConfigureSqlMap();
431   }
432  
433   #endregion
434  
435   #region Attach CacheModel to statement
436  
437 170 if (_configScope.IsCacheModelsEnabled)
438   {
439 170 foreach(DictionaryEntry entry in _configScope.SqlMapper.MappedStatements)
440   {
441 26520 _configScope.ErrorContext.Activity = "Set CacheModel to statement";
442  
443 26520 MappedStatement mappedStatement = (MappedStatement)entry.Value;
444 26520 if (mappedStatement.Statement.CacheModelName.Length >0)
445   {
446 510 _configScope.ErrorContext.MoreInfo = "statement : "+mappedStatement.Statement.Id;
447 510 _configScope.ErrorContext.Resource = "cacheModel : " +mappedStatement.Statement.CacheModelName;
448 510 mappedStatement.Statement.CacheModel = _configScope.SqlMapper.GetCache(mappedStatement.Statement.CacheModelName);
449   }
450   }
451   }
452 170 _configScope.ErrorContext.Reset();
453   #endregion
454  
455  
456   #region Resolve "resultMap" attribute on Result Property + initialize Discriminator property
457  
458 170 foreach(DictionaryEntry entry in _configScope.SqlMapper.ResultMaps)
459   {
460 4930 _configScope.ErrorContext.Activity = "Resolve 'resultMap' attribute on Result Property";
461  
462 4930 ResultMap resultMap = (ResultMap)entry.Value;
463 4930 foreach(DictionaryEntry item in resultMap.ColumnsToPropertiesMap)
464   {
465 31280 ResultProperty result = (ResultProperty)item.Value;
466 31280 if(result.NestedResultMapName.Length >0)
467   {
468 170 result.NestedResultMap = _configScope.SqlMapper.GetResultMap(result.NestedResultMapName);
469   }
470   }
471 4930 if (resultMap.Discriminator != null)
472   {
473 340 resultMap.Discriminator.Initialize(_configScope);
474   }
475   }
476  
477 170 _configScope.ErrorContext.Reset();
478  
479   #endregion
480  
481  
482   }
483  
484   /// <summary>
485   /// Load and initialize providers from specified file.
486   /// </summary>
487 170 private void GetProviders()
488   {
489 170 XmlSerializer serializer = null;
490 170 Provider provider = null;
491  
492 170 _configScope.ErrorContext.Activity = "loading Providers";
493  
494 170 XmlDocument xmlProviders = Resources.GetConfigAsXmlDocument(PROVIDERS_FILE_NAME);
495  
496 170 serializer = new XmlSerializer(typeof(Provider));
497  
498 170 foreach (XmlNode node in xmlProviders.SelectNodes("/providers/provider"))
499   {
500 2040 _configScope.ErrorContext.Resource = node.InnerXml.ToString();
501  
502 2040 provider = (Provider) serializer.Deserialize(new XmlNodeReader(node));
503  
504 2040 if (provider.IsEnabled == true)
505   {
506 1360 _configScope.ErrorContext.ObjectId = provider.Name;
507 1360 _configScope.ErrorContext.MoreInfo = "initialize provider";
508  
509 1360 provider.Initialisation();
510 1360 _configScope.Providers.Add(provider.Name, provider);
511  
512 1360 if (provider.IsDefault == true)
513   {
514 170 if (_configScope.Providers[DEFAULT_PROVIDER_NAME] == null)
515   {
516 170 _configScope.Providers.Add(DEFAULT_PROVIDER_NAME,provider);
517   }
518   else
519   {
520 0 throw new ConfigurationException(
521   string.Format("Error while configuring the Provider named \"{0}\" There can be only one default Provider.",provider.Name));
522   }
523   }
524   }
525   }
526 170 _configScope.ErrorContext.Reset();
527   }
528  
529  
530   /// <summary>
531   /// Parse the provider tag.
532   /// </summary>
533   /// <returns>A provider object.</returns>
534 170 private Provider ParseProvider()
535   {
536 170 _configScope.ErrorContext.Activity = "load DataBase Provider";
537 170 XmlNode node = _configScope.SqlMapConfigDocument.SelectSingleNode("//database/provider");
538  
539 170 if (node != null)
540   {
541 170 _configScope.ErrorContext.Resource = node.OuterXml.ToString();
542   // name
543 170 string providerName = Resources.ParsePropertyTokens(node.Attributes["name"].Value, _configScope.Properties);
544  
545 170 _configScope.ErrorContext.ObjectId = providerName;
546  
547 170 if (_configScope.Providers.Contains(providerName) == true)
548   {
549 170 return (Provider) _configScope.Providers[providerName];
550   }
551   else
552   {
553 0 throw new ConfigurationException(
554   string.Format("Error while configuring the Provider named \"{0}\". Cause : The provider is not in 'providers.config'.",
555   providerName));
556   }
557   }
558   else
559   {
560 0 if (_configScope.Providers.Contains(DEFAULT_PROVIDER_NAME) == true)
561   {
562   return (Provider) _configScope.Providers[DEFAULT_PROVIDER_NAME];
563   }
564   else
565   {
566   throw new ConfigurationException(
567   string.Format("Error while configuring the SqlMap. There is no provider marked default in 'providers.config' file."));
568   }
569   }
570   }
571  
572  
573   /// <summary>
574   /// Load sqlMap statement.
575   /// </summary>
576 1870 private void ConfigureSqlMap( )
577   {
578 1870 XmlSerializer serializer = null;
579 1870 XmlNode sqlMapNode = _configScope.NodeContext;
580  
581 1870 _configScope.ErrorContext.Activity = "loading SqlMap ";
582 1870 _configScope.ErrorContext.Resource = sqlMapNode.OuterXml.ToString();
583  
584 1870 if (_configScope.UseConfigFileWatcher == true)
585   {
586 1870 if (sqlMapNode.Attributes["resource"] != null || sqlMapNode.Attributes["url"] != null)
587   {
588 1870 ConfigWatcherHandler.AddFileToWatch( Resources.GetFileInfo( Resources.GetValueOfNodeResourceUrl(sqlMapNode) ) );
589   }
590   }
591  
592   // Load the file
593 1870 _configScope.SqlMapDocument = Resources.GetAsXmlDocument(sqlMapNode);
594  
595 1870 if (_configScope.ValidateSqlMap)
596   {
597 0 ValidateSchema( _configScope.SqlMapDocument.ChildNodes[1], "SqlMap.xsd" );
598   }
599  
600 1870 _configScope.SqlMapNamespace = _configScope.SqlMapDocument.SelectSingleNode("sqlMap").Attributes["namespace"].Value;
601  
602   #region Load TypeAlias
603  
604 1870 foreach (XmlNode xmlNode in _configScope.SqlMapDocument.SelectNodes("/sqlMap/alias/typeAlias"))
605   {
606 2380 _configScope.ErrorContext.MoreInfo = "loading type alias";
607 2380 TypeAlias typeAlias = null;
608 2380 serializer = new XmlSerializer(typeof(TypeAlias));
609 2380 typeAlias = (TypeAlias) serializer.Deserialize(new XmlNodeReader(xmlNode));
610 2380 _configScope.ErrorContext.ObjectId = typeAlias.ClassName;
611 2380 _configScope.ErrorContext.MoreInfo = "initialize type alias";
612 2380 typeAlias.Initialize();
613  
614 2380 _configScope.SqlMapper.AddTypeAlias( typeAlias.Name, typeAlias );
615   }
616 1870 _configScope.ErrorContext.MoreInfo = string.Empty;
617 1870 _configScope.ErrorContext.ObjectId = string.Empty;
618  
619   #endregion
620  
621   #region Load resultMap
622  
623 1870 foreach (XmlNode xmlNode in _configScope.SqlMapDocument.SelectNodes("/sqlMap/resultMaps/resultMap"))
624   {
625 4930 _configScope.ErrorContext.MoreInfo = "loading ResultMap tag";
626 4930 _configScope.NodeContext = xmlNode; // A ResultMap node
627  
628 4930 BuildResultMap();
629   }
630  
631   #endregion
632  
633   #region Load parameterMaps
634  
635 1870 foreach (XmlNode xmlNode in _configScope.SqlMapDocument.SelectNodes("/sqlMap/parameterMaps/parameterMap"))
636   {
637 3400 _configScope.ErrorContext.MoreInfo = "loading ParameterMap tag";
638 3400 _configScope.NodeContext = xmlNode; // A ParameterMap node
639  
640 3400 BuildParameterMap();
641   }
642  
643   #endregion
644  
645   #region Load statements
646  
647   #region Statement tag
648 1870 Statement statement = null;
649 1870 serializer = new XmlSerializer(typeof(Statement));
650 1870 foreach (XmlNode xmlNode in _configScope.SqlMapDocument.SelectNodes("/sqlMap/statements/statement"))
651   {
652 12070 _configScope.ErrorContext.MoreInfo = "loading statement tag";
653 12070 _configScope.NodeContext = xmlNode; // A statement tag
654  
655 12070 MappedStatement mappedStatement = null;
656  
657 12070 statement = (Statement) serializer.Deserialize(new XmlNodeReader(xmlNode));
658 12070 statement.CacheModelName = ApplyNamespace( statement.CacheModelName );
659 12070 statement.ParameterMapName = ApplyNamespace( statement.ParameterMapName );
660 12070 statement.ResultMapName = ApplyNamespace( statement.ResultMapName );
661  
662 12070 if (_configScope.UseStatementNamespaces == true)
663   {
664 0 statement.Id = ApplyNamespace(statement.Id);
665   }
666 12070 _configScope.ErrorContext.ObjectId = statement.Id;
667 12070 statement.Initialize( _configScope );
668  
669   // Build ISql (analyse sql statement)
670 12070 ProcessSqlStatement( statement );
671   //config, sqlMapName, sqlMap, xmlNode, statement);
672  
673   // Build MappedStatement
674 12070 mappedStatement = new MappedStatement( _configScope.SqlMapper, statement);
675  
676 12070 _configScope.SqlMapper.AddMappedStatement(mappedStatement.Name, mappedStatement);
677   }
678   #endregion
679  
680   #region Select tag
681 1870 Select select = null;
682 1870 serializer = new XmlSerializer(typeof(Select));
683 1870 foreach (XmlNode xmlNode in _configScope.SqlMapDocument.SelectNodes("/sqlMap/statements/select"))
684   {
685 9350 _configScope.ErrorContext.MoreInfo = "loading select tag";
686 9350 _configScope.NodeContext = xmlNode; // A select node
687  
688 9350 MappedStatement mappedStatement = null;
689  
690 9350 select = (Select) serializer.Deserialize(new XmlNodeReader(xmlNode));
691 9350 select.CacheModelName = ApplyNamespace( select.CacheModelName );
692 9350 select.ParameterMapName = ApplyNamespace( select.ParameterMapName );
693 9350 select.ResultMapName = ApplyNamespace( select.ResultMapName );
694  
695 9350 if (_configScope.UseStatementNamespaces == true)
696   {
697 0 select.Id = ApplyNamespace(select.Id);
698   }
699 9350 _configScope.ErrorContext.ObjectId = select.Id;
700  
701 9350 select.Initialize( _configScope );
702  
703 9350 if (select.Generate != null)
704   {
705 340 GenerateCommandText(_configScope.SqlMapper, select);
706   }
707   else
708   {
709   // Build ISql (analyse sql statement)
710 9010 ProcessSqlStatement( select);
711   //config, sqlMapName, sqlMap, xmlNode, select);
712   }
713  
714   // Build MappedStatement
715 9350 mappedStatement = new SelectMappedStatement( _configScope.SqlMapper, select);
716  
717 9350 _configScope.SqlMapper.AddMappedStatement(mappedStatement.Name, mappedStatement);
718   }
719   #endregion
720  
721   #region Insert tag
722 1870 Insert insert = null;
723 1870 serializer = new XmlSerializer(typeof(Insert));
724 1870 foreach (XmlNode xmlNode in _configScope.SqlMapDocument.SelectNodes("/sqlMap/statements/insert"))
725   {
726 2040 _configScope.ErrorContext.MoreInfo = "loading insert tag";
727 2040 _configScope.NodeContext = xmlNode; // A insert tag
728  
729 2040 MappedStatement mappedStatement = null;
730  
731 2040 insert = (Insert) serializer.Deserialize(new XmlNodeReader(xmlNode));
732 2040 insert.CacheModelName = ApplyNamespace( insert.CacheModelName );
733 2040 insert.ParameterMapName = ApplyNamespace( insert.ParameterMapName );
734 2040 insert.ResultMapName = ApplyNamespace( insert.ResultMapName );
735  
736 2040 if (_configScope.UseStatementNamespaces == true)
737   {
738 0 insert.Id = ApplyNamespace(insert.Id);
739   }
740 2040 _configScope.ErrorContext.ObjectId = insert.Id;
741 2040 insert.Initialize( _configScope );
742  
743   // Build ISql (analyse sql command text)
744 2040 if (insert.Generate != null)
745   {
746 170 GenerateCommandText(_configScope.SqlMapper, insert);
747   }
748   else
749   {
750 1870 ProcessSqlStatement( insert);
751   //config, sqlMapName, sqlMap, xmlNode, insert);
752   }
753  
754   // Build MappedStatement
755 2040 mappedStatement = new InsertMappedStatement( _configScope.SqlMapper, insert);
756  
757 2040 _configScope.SqlMapper.AddMappedStatement(mappedStatement.Name, mappedStatement);
758  
759   #region statement SelectKey
760   // Set sql statement SelectKey
761 2040 if (insert.SelectKey != null)
762   {
763 850 insert.SelectKey.Initialize( _configScope );
764 850 insert.SelectKey.Id = insert.Id + DOT + "SelectKey";
765 850 string commandText = xmlNode.SelectSingleNode("selectKey").FirstChild.InnerText.Replace('\n', ' ').Replace('\r', ' ').Replace('\t', ' ').Trim();
766 850 commandText = Resources.ParsePropertyTokens(commandText, _configScope.Properties);
767 850 StaticSql sql = new StaticSql(insert.SelectKey);
768 850 IDalSession session = new SqlMapSession( _configScope.SqlMapper.DataSource );
769 850 sql.BuildPreparedStatement( session, commandText );
770 850 insert.SelectKey.Sql = sql;
771  
772   // Build MappedStatement
773 850 mappedStatement = new MappedStatement( _configScope.SqlMapper, insert.SelectKey);
774  
775 850 _configScope.SqlMapper.AddMappedStatement(mappedStatement.Name, mappedStatement);
776   }
777   #endregion
778   }
779   #endregion
780  
781   #region Update tag
782 1870 Update update = null;
783 1870 serializer = new XmlSerializer(typeof(Update));
784 1870 foreach (XmlNode xmlNode in _configScope.SqlMapDocument.SelectNodes("/sqlMap/statements/update"))
785   {
786 850 _configScope.ErrorContext.MoreInfo = "loading update tag";
787 850 _configScope.NodeContext = xmlNode; // A update tag
788  
789 850 MappedStatement mappedStatement = null;
790  
791 850 update = (Update) serializer.Deserialize(new XmlNodeReader(xmlNode));
792 850 update.CacheModelName = ApplyNamespace( update.CacheModelName );
793 850 update.ParameterMapName = ApplyNamespace( update.ParameterMapName );
794 850 update.ResultMapName = ApplyNamespace( update.ResultMapName );
795  
796 850 if (_configScope.UseStatementNamespaces == true)
797   {
798 0 update.Id = ApplyNamespace(update.Id);
799   }
800 850 _configScope.ErrorContext.ObjectId = update.Id;
801 850 update.Initialize( _configScope );
802  
803   // Build ISql (analyse sql statement)
804 850 if (update.Generate != null)
805   {
806 170 GenerateCommandText(_configScope.SqlMapper, update);
807   }
808   else
809   {
810   // Build ISql (analyse sql statement)
811 680 ProcessSqlStatement(update);
812   //config, sqlMapName, sqlMap, xmlNode, update);
813   }
814  
815   // Build MappedStatement
816 850 mappedStatement = new UpdateMappedStatement( _configScope.SqlMapper, update);
817  
818 850 _configScope.SqlMapper.AddMappedStatement(mappedStatement.Name, mappedStatement);
819   }
820   #endregion
821  
822   #region Delete tag
823 1870 Delete delete = null;
824 1870 serializer = new XmlSerializer(typeof(Delete));
825 1870 foreach (XmlNode xmlNode in _configScope.SqlMapDocument.SelectNodes("/sqlMap/statements/delete"))
826   {
827 680 _configScope.ErrorContext.MoreInfo = "loading delete tag";
828 680 _configScope.NodeContext = xmlNode; // A delete tag
829 680 MappedStatement mappedStatement = null;
830  
831 680 delete = (Delete) serializer.Deserialize(new XmlNodeReader(xmlNode));
832 680 delete.CacheModelName = ApplyNamespace( delete.CacheModelName );
833 680 delete.ParameterMapName = ApplyNamespace( delete.ParameterMapName );
834 680 delete.ResultMapName = ApplyNamespace( delete.ResultMapName );
835  
836 680 if (_configScope.UseStatementNamespaces == true)
837   {
838 0 delete.Id = ApplyNamespace(delete.Id);
839   }
840 680 _configScope.ErrorContext.ObjectId = delete.Id;
841 680 delete.Initialize( _configScope );
842  
843   // Build ISql (analyse sql statement)
844 680 if (delete.Generate != null)
845   {
846 170 GenerateCommandText(_configScope.SqlMapper, delete);
847   }
848   else
849   {
850   // Build ISql (analyse sql statement)
851 510 ProcessSqlStatement(delete);
852   //config, sqlMapName, sqlMap, xmlNode, delete);
853   }
854  
855   // Build MappedStatement
856 680 mappedStatement = new DeleteMappedStatement( _configScope.SqlMapper, delete);
857  
858 680 _configScope.SqlMapper.AddMappedStatement(mappedStatement.Name, mappedStatement);
859   }
860   #endregion
861  
862   #region Procedure tag
863 1870 Procedure procedure = null;
864 1870 serializer = new XmlSerializer(typeof(Procedure));
865 1870 foreach (XmlNode xmlNode in _configScope.SqlMapDocument.SelectNodes("/sqlMap/statements/procedure"))
866   {
867 680 _configScope.ErrorContext.MoreInfo = "loading procedure tag";
868 680 _configScope.NodeContext = xmlNode; // A procedure tag
869  
870 680 MappedStatement mappedStatement = null;
871  
872 680 procedure = (Procedure)serializer.Deserialize(new XmlNodeReader(xmlNode));
873 680 procedure.CacheModelName = ApplyNamespace( procedure.CacheModelName );
874 680 procedure.ParameterMapName = ApplyNamespace( procedure.ParameterMapName );
875 680 procedure.ResultMapName = ApplyNamespace( procedure.ResultMapName );
876  
877 680 if (_configScope.UseStatementNamespaces == true)
878   {
879 0 procedure.Id = ApplyNamespace(procedure.Id);
880   }
881 680 _configScope.ErrorContext.ObjectId = procedure.Id;
882 680 procedure.Initialize( _configScope );
883  
884   // Build ISql (analyse sql command text)
885 680 ProcessSqlStatement( procedure );
886   //config, sqlMapName, sqlMap, xmlNode, procedure);
887  
888   // Build MappedStatement
889 680 mappedStatement = new MappedStatement( _configScope.SqlMapper, procedure);
890  
891 680 _configScope.SqlMapper.AddMappedStatement(mappedStatement.Name, mappedStatement);
892   }
893   #endregion
894  
895   #endregion
896  
897   #region Load CacheModels
898  
899 1870 if (_configScope.IsCacheModelsEnabled == true)
900   {
901 1870 CacheModel cacheModel = null;
902 1870 serializer = new XmlSerializer(typeof(CacheModel));
903 1870 foreach (XmlNode xmlNode in _configScope.SqlMapDocument.SelectNodes("/sqlMap/cacheModels/cacheModel"))
904   {
905 170 cacheModel = (CacheModel) serializer.Deserialize(new XmlNodeReader(xmlNode));
906 170 cacheModel.Id = ApplyNamespace( cacheModel.Id );
907  
908   // Attach ExecuteEventHandler
909 170 foreach(XmlNode flushOn in xmlNode.SelectNodes("flushOnExecute"))
910   {
911 340 string statementName = flushOn.Attributes["statement"].Value;
912 340 if (_configScope.UseStatementNamespaces == true)
913   {
914 0 statementName = _configScope.SqlMapNamespace + DOT + statementName;
915   }
916  
917 340 MappedStatement mappedStatement = _configScope.SqlMapper.GetMappedStatement(statementName);
918  
919 340 cacheModel.RegisterTriggerStatement(mappedStatement);
920   }
921  
922   // Get Properties
923 170 foreach(XmlNode propertie in xmlNode.SelectNodes("property"))
924   {
925 170 string name = propertie.Attributes["name"].Value;
926 170 string value = propertie.Attributes["value"].Value;
927  
928 170 cacheModel.AddPropertie(name, value);
929   }
930  
931 170 cacheModel.Initialize();
932  
933 170 _configScope.SqlMapper.AddCache( cacheModel );
934   }
935   }
936  
937   #endregion
938  
939 1870 _configScope.ErrorContext.Reset();
940   }
941  
942  
943   /// <summary>
944   /// Process the Sql Statement
945   /// </summary>
946   /// <param name="statement"></param>
947 24820 private void ProcessSqlStatement( IStatement statement )
948   {
949 24820 bool isDynamic = false;
950 24820 XmlNode commandTextNode = _configScope.NodeContext;
951 24820 DynamicSql dynamic = new DynamicSql(_configScope.TypeHandlerFactory, statement, _configScope.DataSource.Provider.UsePositionalParameters );
952 24820 StringBuilder sqlBuffer = new StringBuilder();
953  
954 24820 _configScope.ErrorContext.MoreInfo = "process the Sql statement";
955  
956   // Resolve "extend" attribute on Statement
957 24820 if (statement.ExtendSatement.Length >0)
958   {
959   // Find 'super' statement
960 510 XmlNode supperStatementNode = _configScope.SqlMapDocument.SelectSingleNode("/sqlMap/statements/child::*[@id='"+statement.ExtendSatement+"']");
961 510 if (supperStatementNode!=null)
962   {
963 510 commandTextNode.InnerXml = supperStatementNode.InnerXml + commandTextNode.InnerXml;
964   }
965   else
966   {
967 0 throw new ConfigurationException("Unable to find extend statement named '"+statement.ExtendSatement+"' on statement '"+statement.Id+"'.'");
968   }
969   }
970  
971 24820 _configScope.ErrorContext.MoreInfo = "parse dynamic tags on sql statement";
972  
973 24820 isDynamic = ParseDynamicTags( commandTextNode, dynamic, sqlBuffer, isDynamic, false);
974  
975 24820 if (isDynamic)
976   {
977 4590 statement.Sql = dynamic;
978   }
979   else
980   {
981 20230 string sqlText = sqlBuffer.ToString();
982 20230 ApplyInlineParemeterMap( statement, sqlText);
983   }
984   }
985  
986  
987   /// <summary>
988   /// Parse dynamic tags
989   /// </summary>
990   /// <param name="commandTextNode"></param>
991   /// <param name="dynamic"></param>
992   /// <param name="sqlBuffer"></param>
993   /// <param name="isDynamic"></param>
994   /// <param name="postParseRequired"></param>
995   /// <returns></returns>
996 35530 private bool ParseDynamicTags( XmlNode commandTextNode, IDynamicParent dynamic,
997   StringBuilder sqlBuffer, bool isDynamic, bool postParseRequired)
998   {
999 35530 XmlNodeList children = commandTextNode.ChildNodes;
1000 80920 for (int i = 0; i < children.Count; i++)
1001   {
1002 45390 XmlNode child = children[i];
1003 45390 if ( (child.NodeType == XmlNodeType.CDATA) || (child.NodeType == XmlNodeType.Text) )
1004   {
1005 33660 string data = child.InnerText.Replace('\n', ' ').Replace('\r', ' ').Replace('\t', ' ').Trim(); //??
1006  
1007 33660 data = Resources.ParsePropertyTokens(data, _configScope.Properties);
1008  
1009 33660 SqlText sqlText = null;
1010 33660 if ( postParseRequired == true )
1011   {
1012 1360 sqlText = new SqlText();
1013 1360 sqlText.Text = data.ToString();
1014   }
1015   else
1016   {
1017 32300 sqlText = _paramParser.ParseInlineParameterMap(_configScope.TypeHandlerFactory, null, data );
1018   }
1019  
1020 33660 dynamic.AddChild(sqlText);
1021 33660 sqlBuffer.Append(data);
1022   }
1023   else
1024   {
1025 11730 string nodeName = child.Name;
1026 11730 XmlSerializer serializer = SerializerFactory.GetSerializer(nodeName);
1027  
1028 11730 if (serializer != null)
1029   {
1030 10710 isDynamic = true;
1031 10710 SqlTag tag = null;
1032  
1033 10710 tag = (SqlTag) serializer.Deserialize(new XmlNodeReader(child));
1034  
1035 10710 dynamic.AddChild(tag);
1036  
1037 10710 if (child.HasChildNodes == true)
1038   {
1039 10710 isDynamic = ParseDynamicTags( child, tag, sqlBuffer, isDynamic, tag.Handler.IsPostParseRequired );
1040   }
1041   }
1042   }
1043   }
1044  
1045 35530 return isDynamic;
1046   }
1047  
1048  
1049   #region Inline Parameter parsing
1050  
1051   /// <summary>
1052   /// Apply inline paremeterMap
1053   /// </summary>
1054   /// <param name="statement"></param>
1055   /// <param name="sqlStatement"></param>
1056 20230 private void ApplyInlineParemeterMap( IStatement statement, string sqlStatement)
1057   {
1058 20230 string newSql = sqlStatement;
1059  
1060 20230 _configScope.ErrorContext.MoreInfo = "apply inline parameterMap";
1061  
1062   // Check the inline parameter
1063 20230 if (statement.ParameterMap == null)
1064   {
1065   // Build a Parametermap with the inline parameters.
1066   // if they exist. Then delete inline infos from sqltext.
1067  
1068 17510 SqlText sqlText = _paramParser.ParseInlineParameterMap(_configScope.TypeHandlerFactory, statement, newSql );
1069  
1070 17510 if (sqlText.Parameters.Length > 0)
1071   {
1072 13430 ParameterMap map = new ParameterMap(_configScope.DataSource.Provider.UsePositionalParameters);
1073 13430 map.Id = statement.Id + "-InLineParameterMap";
1074 13430 statement.ParameterMap = map;
1075  
1076 34340 for(int index=0;index<sqlText.Parameters.Length;index++)
1077   {
1078 20910 map.AddParameterProperty( sqlText.Parameters[index] );
1079   }
1080   }
1081 17510 newSql = sqlText.Text;
1082   }
1083  
1084 20230 ISql sql = null;
1085  
1086 20230 if (SimpleDynamicSql.IsSimpleDynamicSql(newSql))
1087   {
1088 850 sql = new SimpleDynamicSql(_configScope.TypeHandlerFactory, newSql, statement);
1089   }
1090   else
1091   {
1092 19380 if (statement is Procedure)
1093   {
1094 680 sql = new ProcedureSql(newSql, statement);
1095   // Could not call BuildPreparedStatement for procedure because when NUnit Test
1096   // the database is not here (but in theory procedure must be prepared like statement)
1097   // It's even better as we can then switch DataSource.
1098   }
1099 18700 else if (statement is Statement)
1100   {
1101 18700 sql = new StaticSql(statement);
1102 18700 IDalSession session = new SqlMapSession(_configScope.SqlMapper.DataSource);
1103  
1104 18700 ((StaticSql)sql).BuildPreparedStatement( session, newSql );
1105   }
1106   }
1107 20230 statement.Sql = sql;
1108   }
1109  
1110   #endregion
1111  
1112  
1113   /// <summary>
1114   /// Initialize the list of variables defined in the
1115   /// properties file.
1116   /// </summary>
1117 170 private void ParseGlobalProperties()
1118   {
1119 170 XmlNode nodeProperties = _configScope.NodeContext.SelectSingleNode("properties");
1120 170 _configScope.ErrorContext.Activity = "loading global properties";
1121  
1122 170 if (nodeProperties != null)
1123   {
1124   // JIRA-38 Fix
1125   // <properties> element's InnerXml is currently an empty string anyway
1126   // since <settings> are in properties file
1127   //_configScope.ErrorContext.Resource = nodeProperties.InnerXml.ToString();
1128 170 _configScope.ErrorContext.Resource = nodeProperties.OuterXml.ToString();
1129  
1130   // Load the file defined by the resource attribute
1131 170 XmlDocument propertiesConfig = Resources.GetAsXmlDocument(nodeProperties);
1132  
1133 170 foreach (XmlNode node in propertiesConfig.SelectNodes("/settings/add"))
1134   {
1135 2210 _configScope.Properties[node.Attributes["key"].Value] = node.Attributes["value"].Value;
1136   }
1137   }
1138  
1139 170 _configScope.ErrorContext.Reset();;
1140   }
1141  
1142  
1143  
1144   /// <summary>
1145   /// Generate the command text for CRUD operation
1146   /// </summary>
1147   /// <param name="sqlMap"></param>
1148   /// <param name="statement"></param>
1149 850 private void GenerateCommandText(SqlMapper sqlMap, IStatement statement)
1150   {
1151 850 string generatedSQL = string.Empty;
1152  
1153   //------ Build SQL CommandText
1154 850 generatedSQL = SqlGenerator.BuildQuery(statement);
1155  
1156 850 ISql sql = new StaticSql(statement);
1157 850 IDalSession session = new SqlMapSession(sqlMap.DataSource);
1158  
1159 850 ((StaticSql)sql).BuildPreparedStatement( session, generatedSQL );
1160 850 statement.Sql = sql;
1161   }
1162  
1163  
1164   /// <summary>
1165   /// Build a ParameterMap
1166   /// </summary>
1167 3400 private void BuildParameterMap()
1168   {
1169 3400 ParameterMap parameterMap = null;
1170 3400 XmlNode parameterMapNode = _configScope.NodeContext;
1171  
1172 3400 XmlSerializer serializer = new XmlSerializer(typeof(ParameterMap));
1173  
1174 3400 _configScope.ErrorContext.MoreInfo = "build ParameterMap";
1175  
1176   // Get the parameterMap id
1177 3400 string id = ApplyNamespace( ((XmlAttribute)parameterMapNode.Attributes.GetNamedItem("id")).Value );
1178 3400 _configScope.ErrorContext.ObjectId = id;
1179  
1180   // Did we already process it ?
1181 3400 if (_configScope.SqlMapper.ParameterMaps.Contains( id ) == false)
1182   {
1183 3400 parameterMap = (ParameterMap) serializer.Deserialize(new XmlNodeReader(parameterMapNode));
1184  
1185 3400 _configScope.ErrorContext.MoreInfo = "Initialize ParameterMap";
1186 3400 _configScope.NodeContext = parameterMapNode;
1187 3400 parameterMap.Initialize( _configScope );
1188  
1189 3400 parameterMap.Id = ApplyNamespace( parameterMap.Id );
1190 3400 string attributeExtendMap = parameterMap.ExtendMap;
1191 3400 parameterMap.ExtendMap = ApplyNamespace( parameterMap.ExtendMap );
1192  
1193 3400 if (parameterMap.ExtendMap.Length >0)
1194   {
1195 510 ParameterMap superMap = null;
1196   // Did we already build Extend ParameterMap ?
1197 510 if (_configScope.SqlMapper.ParameterMaps.Contains( parameterMap.ExtendMap ) == false)
1198   {
1199 0 XmlNode superNode = _configScope.SqlMapConfigDocument.SelectSingleNode("/sqlMap/parameterMaps/parameterMap[@id='"+ attributeExtendMap +"']");
1200  
1201 0 if (superNode != null)
1202   {
1203   _configScope.ErrorContext.MoreInfo = "Build parent ParameterMap";
1204   _configScope.NodeContext = superNode;
1205   BuildParameterMap();
1206   superMap = _configScope.SqlMapper.GetParameterMap( parameterMap.ExtendMap );
1207   }
1208   else
1209   {
1210   throw new ConfigurationException("In mapping file '"+ _configScope.SqlMapNamespace +"' the parameterMap '"+parameterMap.Id+"' can not resolve extends attribute '"+parameterMap.ExtendMap+"'");
1211   }
1212   }
1213   else
1214   {
1215 510 superMap = _configScope.SqlMapper.GetParameterMap( parameterMap.ExtendMap );
1216   }
1217   // Add extends property
1218 510 int index = 0;
1219  
1220 510 foreach(string propertyName in superMap.GetPropertyNameArray())
1221   {
1222 2380 parameterMap.InsertParameterProperty( index, superMap.GetProperty(propertyName) );
1223 2380 index++;
1224   }
1225   }
1226 3400 _configScope.SqlMapper.AddParameterMap( parameterMap );
1227   }
1228   }
1229  
1230  
1231   /// <summary>
1232   /// Build a ResultMap
1233   /// </summary>
1234 5100 private void BuildResultMap()
1235   {
1236 5100 ResultMap resultMap = null;
1237 5100 XmlNode resultMapNode = _configScope.NodeContext;
1238  
1239 5100 XmlSerializer serializer = new XmlSerializer(typeof(ResultMap));
1240  
1241 5100 _configScope.ErrorContext.MoreInfo = "build ResultMap";
1242  
1243 5100 string id = ApplyNamespace( ((XmlAttribute)resultMapNode.Attributes.GetNamedItem("id")).Value );
1244 5100 _configScope.ErrorContext.ObjectId = id;
1245  
1246   // Did we alredy process it
1247 5100 if (_configScope.SqlMapper.ResultMaps.Contains( id ) == false)
1248   {
1249 4930 resultMap = (ResultMap) serializer.Deserialize(new XmlNodeReader(resultMapNode));
1250  
1251 4930 resultMap.SqlMapNameSpace = _configScope.SqlMapNamespace;
1252  
1253 4930 _configScope.ErrorContext.MoreInfo = "initialize ResultMap";
1254 4930 resultMap.Initialize( _configScope );
1255  
1256 4930 resultMap.Id = ApplyNamespace( resultMap.Id );
1257 4930 string attributeExtendMap = resultMap.ExtendMap;
1258 4930 resultMap.ExtendMap = ApplyNamespace( resultMap.ExtendMap );
1259  
1260 4930 if (resultMap.ExtendMap.Length >0)
1261   {
1262 1020 ResultMap superMap = null;
1263   // Did we already build Extend ResultMap?
1264 1020 if (_configScope.SqlMapper.ResultMaps.Contains( resultMap.ExtendMap ) == false)
1265   {
1266 170 XmlNode superNode = _configScope.SqlMapDocument.SelectSingleNode("/sqlMap/resultMaps/resultMap[@id='"+ attributeExtendMap +"']");
1267  
1268 170 if (superNode != null)
1269   {
1270 170 _configScope.ErrorContext.MoreInfo = "Build parent ResultMap";
1271 170 _configScope.NodeContext = superNode;
1272 170 BuildResultMap();
1273 170 superMap = _configScope.SqlMapper.GetResultMap( resultMap.ExtendMap );
1274   }
1275   else
1276   {
1277 0 throw new ConfigurationException("In mapping file '"+_configScope.SqlMapNamespace+"' the resultMap '"+resultMap.Id+"' can not resolve extends attribute '"+resultMap.ExtendMap+"'" );
1278   }
1279   }
1280   else
1281   {
1282 850 superMap = _configScope.SqlMapper.GetResultMap( resultMap.ExtendMap );
1283   }
1284  
1285   // Add parent property
1286 1020 foreach(DictionaryEntry dicoEntry in superMap.ColumnsToPropertiesMap)
1287   {
1288 6800 ResultProperty property = (ResultProperty)dicoEntry.Value;
1289 6800 resultMap.AddResultPropery(property);
1290   }
1291   }
1292 4930 _configScope.SqlMapper.AddResultMap( resultMap );
1293   }
1294   }
1295  
1296  
1297   /// <summary>
1298   /// Register under Statement Name or Fully Qualified Statement Name
1299   /// </summary>
1300   /// <param name="id">An Identity</param>
1301   /// <returns>The new Identity</returns>
1302 102340 private string ApplyNamespace(string id)
1303   {
1304 102340 string newId = id;
1305 102340 string currentNamespace = _configScope.SqlMapNamespace;
1306  
1307 102340 if (currentNamespace != null && currentNamespace.Length > 0
1308   && id != null && id.Length>0 && id.IndexOf(".") < 0)
1309   {
1310 31280 newId = currentNamespace + DOT + id;
1311   }
1312 102340 return newId;
1313   }
1314  
1315  
1316  
1317   /// <summary>
1318   /// Gets a resource stream.
1319   /// </summary>
1320   /// <param name="schemaResourceKey">The schema resource key.</param>
1321   /// <returns>A resource stream.</returns>
1322 170 public Stream GetStream( string schemaResourceKey )
1323   {
1324 170 return Assembly.GetExecutingAssembly().GetManifestResourceStream("IBatisNet.DataMapper." + schemaResourceKey);
1325   }
1326  
1327  
1328   // private String ParsePropertyTokens(string str)
1329   // {
1330   // const string OPEN = "${";
1331   // const string CLOSE = "}";
1332   //
1333   //
1334   // string newString = str;
1335   // if (str != null && props != null) {
1336   // int start = newString.indexOf(OPEN);
1337   // int end = newString.indexOf(CLOSE);
1338   //
1339   // while (start > -1 && end > start) {
1340   // String prepend = newString.substring(0, start);
1341   // String append = newString.substring(end + CLOSE.length());
1342   // String propName = newString.substring(start + OPEN.length(), end);
1343   // String propValue = props.getProperty(propName);
1344   // if (propValue == null) {
1345   // newString = prepend + propName + append;
1346   // } else {
1347   // newString = prepend + propValue + append;
1348   // }
1349   // start = newString.indexOf(OPEN);
1350   // end = newString.indexOf(CLOSE);
1351   // }
1352   // }
1353   // return newString;
1354   // }
1355  
1356   #endregion
1357   }
1358   }
1359