1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.ActiveRecord
.Framework
.Config
18 using System
.Collections
;
19 using System
.Collections
.Specialized
;
20 using System
.Configuration
;
25 /// Source of configuration based on Xml
26 /// source like files, streams or readers.
28 public class XmlConfigurationSource
: InPlaceConfigurationSource
31 /// Initializes a new instance of the <see cref="XmlConfigurationSource"/> class.
33 protected XmlConfigurationSource()
38 /// Initializes a new instance of the <see cref="XmlConfigurationSource"/> class.
40 /// <param name="xmlFileName">Name of the XML file.</param>
41 public XmlConfigurationSource(String xmlFileName
)
43 XmlDocument doc
= new XmlDocument();
44 doc
.Load(xmlFileName
);
45 PopulateSource(doc
.DocumentElement
);
49 /// Initializes a new instance of the <see cref="XmlConfigurationSource"/> class.
51 /// <param name="stream">The stream.</param>
52 public XmlConfigurationSource(Stream stream
)
54 XmlDocument doc
= new XmlDocument();
56 PopulateSource(doc
.DocumentElement
);
60 /// Initializes a new instance of the <see cref="XmlConfigurationSource"/> class.
62 /// <param name="reader">The reader.</param>
63 public XmlConfigurationSource(TextReader reader
)
65 XmlDocument doc
= new XmlDocument();
67 PopulateSource(doc
.DocumentElement
);
71 /// Populate this instance with values from the given XML node
73 protected void PopulateSource(XmlNode section
)
75 XmlAttribute isWebAtt
= section
.Attributes
["isWeb"];
76 XmlAttribute threadInfoAtt
= section
.Attributes
["threadinfotype"];
77 XmlAttribute isDebug
= section
.Attributes
["isDebug"];
78 XmlAttribute lazyByDefault
= section
.Attributes
["default-lazy"];
79 XmlAttribute pluralize
= section
.Attributes
["pluralizeTableNames"];
80 XmlAttribute verifyModelsAgainstDBSchemaAtt
= section
.Attributes
["verifyModelsAgainstDBSchema"];
82 SetUpThreadInfoType(isWebAtt
!= null && "true" == isWebAtt
.Value
,
83 threadInfoAtt
!= null ? threadInfoAtt
.Value
: String
.Empty
);
85 XmlAttribute sessionfactoryholdertypeAtt
=
86 section
.Attributes
["sessionfactoryholdertype"];
88 SetUpSessionFactoryHolderType(sessionfactoryholdertypeAtt
!= null
90 sessionfactoryholdertypeAtt
.Value
93 XmlAttribute namingStrategyTypeAtt
= section
.Attributes
["namingstrategytype"];
95 SetUpNamingStrategyType(namingStrategyTypeAtt
!= null ? namingStrategyTypeAtt
.Value
: String
.Empty
);
97 SetDebugFlag(ConvertBool(isDebug
));
99 SetIsLazyByDefault(ConvertBool(lazyByDefault
));
101 SetPluralizeTableNames(ConvertBool(pluralize
));
103 SetVerifyModelsAgainstDBSchema(verifyModelsAgainstDBSchemaAtt
!= null && verifyModelsAgainstDBSchemaAtt
.Value
== "true");
105 PopulateConfigNodes(section
);
108 private void PopulateConfigNodes(XmlNode section
)
110 const string Config_Node_Name
= "config";
112 foreach(XmlNode node
in section
.ChildNodes
)
114 if (node
.NodeType
!= XmlNodeType
.Element
) continue;
116 if (!Config_Node_Name
.Equals(node
.Name
))
118 String message
= String
.Format("Unexpected node. Expect '{0}' found '{1}'",
119 Config_Node_Name
, node
.Name
);
121 throw new ConfigurationErrorsException(message
);
124 Type targetType
= typeof(ActiveRecordBase
);
126 if (node
.Attributes
.Count
!= 0)
128 XmlAttribute typeNameAtt
= node
.Attributes
["type"];
130 if (typeNameAtt
== null)
132 String message
= String
.Format("Invalid attribute at node '{0}'. " +
133 "The only supported attribute is 'type'", Config_Node_Name
);
135 throw new ConfigurationErrorsException(message
);
138 String typeName
= typeNameAtt
.Value
;
140 targetType
= Type
.GetType(typeName
, false, false);
142 if (targetType
== null)
144 String message
= String
.Format("Could not obtain type from name '{0}'", typeName
);
146 throw new ConfigurationErrorsException(message
);
150 Add(targetType
, BuildProperties(node
));
155 /// Builds the configuration properties.
157 /// <param name="node">The node.</param>
158 /// <returns></returns>
159 protected IDictionary
BuildProperties(XmlNode node
)
161 HybridDictionary dict
= new HybridDictionary();
163 foreach(XmlNode addNode
in node
.SelectNodes("add"))
165 XmlAttribute keyAtt
= addNode
.Attributes
["key"];
166 XmlAttribute valueAtt
= addNode
.Attributes
["value"];
168 if (keyAtt
== null || valueAtt
== null)
170 String message
= String
.Format("For each 'add' element you must specify 'key' and 'value' attributes");
172 throw new ConfigurationErrorsException(message
);
174 string value = valueAtt
.Value
;
176 dict
.Add(keyAtt
.Value
, value);
182 private static bool ConvertBool(XmlNode boolAttrib
)
184 return boolAttrib
!= null && "true".Equals(boolAttrib
.Value
, StringComparison
.OrdinalIgnoreCase
);