Clover.NET coverage report - Coverage

Coverage timestamp: viernes, 12 de agosto de 2005 12:53:38 PM

File Stats: LOC: 308   Methods: 9
NCLOC: 153 Classes: 1
 
Source File Conditionals Statements Methods TOTAL
Model\XmlModel\XmlClassMap.cs 95,8 % 100,0 % 100,0 % 99,0 %
coverage coverage
1   #region Copyright
2   /*
3   ShowX. Maps business objects into presentation layer.
4   Copyright (C) 2005 Jesus Diaz.
5  
6   This library is free software; you can redistribute it and/or
7   modify it under the terms of the GNU Lesser General Public
8   License as published by the Free Software Foundation; either
9   version 2.1 of the License, or (at your option) any later version.
10  
11   This library is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15  
16   You should have received a copy of the GNU Lesser General Public
17   License along with this library; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19  
20   For project details see: http://showx.sourceforge.net
21   */
22   #endregion
23  
24   using System;
25   using System.Xml;
26   using System.Collections;
27   using System.Reflection;
28   using log4net;
29  
30   namespace ShowX.Model.XmlModel
31   {
32   /// <summary>
33   /// XmlClassMap store relevant information loaded from XML mapping files.
34   /// </summary>
35   public class XmlClassMap
36   {
37   private static readonly ILog log = LogManager.GetLogger(
38   typeof(XmlClassMap));
39  
40   /// <summary>
41   /// Type represented by this mapping class.
42   /// </summary>
43   Type mappedType;
44  
45   /// <summary>
46   /// Object Handler type for this mapping class.
47   /// </summary>
48   Type handlerType;
49  
50   /// <summary>
51   /// Property that represent the identifier of this type.
52   /// </summary>
53   XmlIdentifierMap pkProperty;
54  
55   /// <summary>
56   /// Store information about ShowX mapped properties for this type. The
57   /// property name is used as the hash key, and the value is an instance of
58   /// the XMLPropertyMap class.
59   /// </summary>
60   Hashtable propertyMappingInfo;
61  
62   // Store information about ShowX mapped properties for this type. An arrayList
63   // is used here too keep track of the relative order of properties.
64   ArrayList propertyMappingList;
65  
66   /// <summary>
67   /// Store information about the ShowX views defined over this type.
68   /// </summary>
69   XmlViewCollection viewCollection;
70  
71   /// <summary>
72   /// Path to embedded resource class-mapping.xsd, used to validate class
73   /// mapping files.
74   /// </summary>
75   protected static string classMappingSchemeEmbeddedPath =
76   "ShowX.Model.XmlModel.Schema.class-mapping.xsd";
77  
78   /// <summary>
79   /// Validate a given XmlNode over the format defined for a XML mapping file.
80   /// </summary>
81   /// <param name="section">XmlNode to validate.</param>
82   /// <returns>True if validation is sucessful, false otherwise.</returns>
83 32 protected static bool validate(XmlNode section)
84   {
85 32 return new XmlFileValidator()
86   .Validate(section,classMappingSchemeEmbeddedPath);
87   }
88  
89   /// <summary>
90   /// Load a certain type, from a configuration file. The format allows to
91   /// specify an assembly and a type, for example: "Core.Business.Entity,Core".
92   /// </summary>
93   /// <param name="typename">Text that represents the typename and, optionally,
94   /// the assemble</param>
95   /// <returns></returns>
96 30 protected Type LoadType(string typename)
97   {
98 30 typename = typename.Replace(" ","");
99 30 string[] split = typename.Split(new char[]{','});
100  
101 30 Assembly asm = (split.Length == 2)
102   ? Assembly.LoadWithPartialName (split[1])
103   : this.mappedType.UnderlyingSystemType.Assembly;
104  
105 30 if(asm == null) {
106  
107 1 string errorMsg = string.Format(
108   "Unable to load assembly for type '{0}'.",typename);
109  
110 1 log.Fatal(errorMsg);
111 1 throw new ModelException(errorMsg);
112   }
113  
114 29 return asm.GetType(split[0],false);
115   }
116  
117   /// <summary>
118   /// Constructor.
119   /// </summary>
120   /// <param name="t">Type to map.</param>
121   /// <param name="mapping">Mapping document, containing mapping info for
122   /// type t.</param>
123 35 public XmlClassMap(Type t, XmlDocument mapping)
124   {
125 35 mappedType = t;
126 35 propertyMappingInfo = new Hashtable();
127 35 propertyMappingList = new ArrayList();
128  
129 35 if (mapping == null) {
130  
131 1 log.Fatal("Detected a null Xml mapping document.");
132 1 throw new ModelException("Xml mapping document cannot be null");
133   }
134  
135 34 if (mappedType == null) {
136  
137 1 log.Fatal("Detected a null type.");
138 1 throw new ModelException("Mapped type cannot be null.");
139   }
140  
141 33 XmlNode rootTag = mapping
142   .SelectSingleNode("//" + XmlMappingFileConst.rootTag);
143  
144 33 if (rootTag == null) {
145  
146 1 string errorMsg = string.Format(
147   "Mapping settings does not contains the '{0}' tag",
148   XmlMappingFileConst.rootTag);
149  
150 1 log.Fatal(errorMsg);
151 1 throw new ModelException(errorMsg);
152   }
153  
154 32 if (!validate(rootTag)) {
155  
156 1 string errorMsg = string.Format(
157   "Error validating class mapping file for type '{0}'.",t);
158  
159 1 log.Fatal(errorMsg);
160 1 throw new ModelException(errorMsg);
161   }
162  
163 31 string mappedClassNameValue = rootTag
164   .Attributes[XmlMappingFileConst.propertyMappingNameAttr].Value;
165  
166 31 if (t.FullName != mappedClassNameValue) {
167  
168 1 string errorMsg = string.Format(
169   "Attempt to load type '{0}' from type '{1}' mapping file.",
170   t,mappedClassNameValue);
171  
172 1 log.Fatal(errorMsg);
173 1 throw new ModelException(errorMsg);
174   }
175  
176  
177 30 string mappedObjectHandlerValue = rootTag
178   .Attributes[XmlMappingFileConst.propertyMappingHandlerClassAttr].Value;
179  
180 30 this.handlerType = LoadType(mappedObjectHandlerValue);
181  
182 29 if (handlerType == null) {
183  
184 1 string errorMsg = string.Format(
185   "Unable to load handler class '{0}' for type '{1}'.",
186   mappedObjectHandlerValue,mappedClassNameValue);
187  
188 1 log.Fatal(errorMsg);
189 1 throw new ModelException(errorMsg);
190   }
191  
192  
193 28 foreach (XmlNode node in rootTag.SelectSingleNode("//" +
194   XmlMappingFileConst.propertyMappingTag).ChildNodes) {
195  
196 147 if (node.Name == XmlMappingFileConst.idTag) {
197   //Reading primary key property mapping
198  
199 28 this.pkProperty = new XmlIdentifierMap(t,node);
200   }
201 119 else if (node.Name == XmlMappingFileConst.propertyTag) {
202   //Reading a property
203  
204 100 string propertyName = node.Attributes
205   [XmlMappingFileConst.propertyMappingNameAttr].Value;
206  
207 100 XmlPropertyMap pm = new XmlPropertyMap(t,node);
208  
209 100 propertyMappingInfo[propertyName] = pm;
210 100 propertyMappingList.Add(pm.PropertyInfo);
211   }
212 19 else if (node.Name == XmlMappingFileConst.fkPropertyTag) {
213   //Reading foreign key properties
214  
215 8 string propertyName = node.Attributes
216   [XmlMappingFileConst.propertyMappingNameAttr].Value;
217  
218 8 XmlForeignIdentifierMap fk = new XmlForeignIdentifierMap(t,node);
219  
220 8 propertyMappingInfo[propertyName] = fk;
221 8 propertyMappingList.Add(fk.PropertyInfo);
222   }
223 11 else if (node.Name == XmlMappingFileConst.collectionPropertyTag) {
224   //Reading collection property
225  
226 10 string propertyName = node.Attributes
227   [XmlMappingFileConst.propertyMappingNameAttr].Value;
228  
229 10 XmlCollectionMap cm = new XmlCollectionMap(t,node);
230  
231 10 propertyMappingInfo[propertyName] = cm;
232 10 propertyMappingList.Add(cm.PropertyInfo);
233   }
234 1 else if (node.Name == XmlMappingFileConst.xpercentPropertyTag) {
235  
236 1 string propertyName = node.Attributes
237   [XmlMappingFileConst.propertyMappingNameAttr].Value;
238  
239 1 XmlXPercentMap cm = new XmlXPercentMap(t,node);
240  
241 1 propertyMappingInfo[propertyName] = cm;
242 1 propertyMappingList.Add(cm.PropertyInfo);
243  
244   }
245   }
246  
247 28 XmlNode viewTag = mapping
248   .SelectSingleNode("//" + XmlMappingFileConst.viewsTag);
249  
250 28 viewCollection = (viewTag == null)
251   ? new XmlViewCollection()
252   : new XmlViewCollection(viewTag);
253   }
254  
255   /// <summary>
256   /// Expose the mapped type stored by this XmlClassMap instance.
257   /// </summary>
258   public Type MappedType
259   {
260 1 get { return mappedType; }
261   }
262  
263   /// <summary>
264   /// Expose the handler type associated to the mapped type stored by this
265   /// XmlClassMap instance.
266   /// </summary>
267   public Type HandlerType
268   {
269 144 get { return handlerType; }
270   }
271  
272   /// <summary>
273   /// Store the property maps for the mapped type stored by this XmlClassMap
274   /// instance.
275   /// </summary>
276   public Hashtable PropertyMaps
277   {
278 2153 get { return this.propertyMappingInfo; }
279   }
280  
281   /// <summary>
282   /// Store the properties for the mapped type stored by this XmlClassMap
283   /// instance.
284   /// </summary>
285   public ArrayList PropertyList
286   {
287 61 get { return this.propertyMappingList; }
288   }
289  
290   /// <summary>
291   /// Store the identifier map for the mapped type stored by this XmlClassMap
292   /// instance.
293   /// </summary>
294   public XmlPropertyMap IdentifierMap
295   {
296 2945 get { return this.pkProperty; }
297   }
298  
299   /// <summary>
300   /// Allow read-only access to the view collection object for this class
301   /// mapping.
302   /// </summary>
303   public IViewCollection Views
304   {
305 36 get { return this.viewCollection; }
306   }
307   }
308   }