2 // System.Web.Compilation.AppCodeCompiler: A compiler for the App_Code folder
5 // Marek Habersack (grendello@gmail.com)
7 // (C) 2006 Marek Habersack
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Collections.Generic;
36 namespace System.Web.Compilation
38 enum BuildResultTypeCode
46 // The attributes of the <preserve> element in a .compiled file are described in
48 // http://msdn.microsoft.com/msdnmag/issues/07/01/cuttingedge/default.aspx?loc=&fig=true#fig4
50 // and a sample file is shown in
52 // http://msdn.microsoft.com/msdnmag/issues/07/01/cuttingedge/default.aspx?loc=&fig=true#fig3
54 internal class PreservationFile
61 BuildResultTypeCode _resultType = BuildResultTypeCode.Unknown;
63 List <string> _filedeps;
65 public string Assembly {
66 get { return _assembly; }
67 set { _assembly = value; }
70 public string FilePath {
71 get { return _filePath; }
72 set { _filePath = value; }
75 public Int32 FileHash {
76 get { return _fileHash; }
77 set { _fileHash = value; }
81 get { return _flags; }
82 set { _flags = value; }
87 set { _hash = value; }
90 public BuildResultTypeCode ResultType {
91 get { return _resultType; }
92 set { _resultType = value; }
95 public string VirtualPath {
96 get { return _virtualPath; }
97 set { _virtualPath = value; }
100 public List <string> FileDeps {
101 get { return _filedeps; }
102 set { _filedeps = value; }
105 public PreservationFile ()
109 public PreservationFile (string filePath)
111 this._filePath = filePath;
117 if (_filePath == null)
118 throw new InvalidOperationException ("File path is not defined");
122 public void Parse (string filePath)
124 if (filePath == null)
125 throw new ArgumentNullException ("File path is required", "filePath");
127 XmlDocument doc = new XmlDocument ();
130 XmlNode root = doc.DocumentElement;
131 if (root.Name != "preserve")
132 throw new InvalidOperationException ("Invalid assembly mapping file format");
133 ParseRecursively (root);
136 void ParseRecursively (XmlNode root)
138 _assembly = GetNonEmptyRequiredAttribute (root, "assembly");
140 // The rest of the values is optional for us and since we don't use them
141 // at all (at least for now) we also ignore all the integer parsing errors
143 _virtualPath = GetNonEmptyOptionalAttribute (root, "virtualPath");
144 _fileHash = GetNonEmptyOptionalAttributeInt32 (root, "filehash");
145 _hash = GetNonEmptyOptionalAttributeInt32 (root, "hash");
146 _flags = GetNonEmptyOptionalAttributeInt32 (root, "flags");
147 _resultType = (BuildResultTypeCode) GetNonEmptyOptionalAttributeInt32 (root, "resultType");
149 foreach (XmlNode child in root.ChildNodes) {
150 if (child.NodeType != XmlNodeType.Element)
152 if (child.Name != "filedeps")
154 ReadFileDeps (child);
156 } catch (Exception) {
160 void ReadFileDeps (XmlNode node)
163 if (_filedeps == null)
164 _filedeps = new List <string> ();
165 foreach (XmlNode child in node.ChildNodes) {
166 if (child.NodeType != XmlNodeType.Element)
168 if (child.Name != "filedep")
170 tmp = GetNonEmptyRequiredAttribute (child, "name");
177 if (_filePath == null)
178 throw new InvalidOperationException ("File path is not defined");
182 public void Save (string filePath)
184 if (filePath == null)
185 throw new ArgumentNullException ("File path is required", "filePath");
187 XmlWriterSettings xmlSettings = new XmlWriterSettings ();
188 xmlSettings.Indent = false;
189 xmlSettings.OmitXmlDeclaration = false;
190 xmlSettings.NewLineOnAttributes = false;
192 using (XmlWriter xml = XmlWriter.Create (filePath, xmlSettings)) {
193 xml.WriteStartElement ("preserve");
194 xml.WriteAttributeString ("assembly", _assembly);
195 if (!String.IsNullOrEmpty (_virtualPath))
196 xml.WriteAttributeString ("virtualPath", _virtualPath);
198 xml.WriteAttributeString ("filehash", _fileHash.ToString ());
200 xml.WriteAttributeString ("flags", _flags.ToString ());
202 xml.WriteAttributeString ("hash", _hash.ToString ());
203 if (_resultType != BuildResultTypeCode.Unknown)
204 xml.WriteAttributeString ("resultType", ((int)_resultType).ToString ());
205 if (_filedeps != null && _filedeps.Count > 0) {
206 xml.WriteStartElement ("filedeps");
207 foreach (string s in _filedeps) {
208 xml.WriteStartElement ("filedep");
209 xml.WriteAttributeString ("name", s);
210 xml.WriteEndElement ();
212 xml.WriteEndElement ();
214 xml.WriteEndElement ();
218 string GetNonEmptyOptionalAttribute (XmlNode n, string name)
220 return System.Web.Configuration.HandlersUtil.ExtractAttributeValue (name, n, true);
223 Int32 GetNonEmptyOptionalAttributeInt32 (XmlNode n, string name)
225 string tmp = GetNonEmptyOptionalAttribute (n, name);
227 return Int32.Parse (tmp);
231 string GetNonEmptyRequiredAttribute (XmlNode n, string name)
233 return System.Web.Configuration.HandlersUtil.ExtractAttributeValue (name, n, false, false);