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
50 // The attributes of the <preserve> element in a .compiled file are described in
52 // http://msdn.microsoft.com/msdnmag/issues/07/01/cuttingedge/default.aspx?loc=&fig=true#fig4
54 // and a sample file is shown in
56 // http://msdn.microsoft.com/msdnmag/issues/07/01/cuttingedge/default.aspx?loc=&fig=true#fig3
58 class PreservationFile
65 BuildResultTypeCode _resultType = BuildResultTypeCode.Unknown;
67 List <string> _filedeps;
69 public string Assembly {
70 get { return _assembly; }
71 set { _assembly = value; }
74 public string FilePath {
75 get { return _filePath; }
76 set { _filePath = value; }
79 public Int32 FileHash {
80 get { return _fileHash; }
81 set { _fileHash = value; }
85 get { return _flags; }
86 set { _flags = value; }
91 set { _hash = value; }
94 public BuildResultTypeCode ResultType {
95 get { return _resultType; }
96 set { _resultType = value; }
99 public string VirtualPath {
100 get { return _virtualPath; }
101 set { _virtualPath = value; }
104 public List <string> FileDeps {
105 get { return _filedeps; }
106 set { _filedeps = value; }
109 public PreservationFile ()
113 public PreservationFile (string filePath)
115 this._filePath = filePath;
121 if (_filePath == null)
122 throw new InvalidOperationException ("File path is not defined");
126 public void Parse (string filePath)
128 if (filePath == null)
129 throw new ArgumentNullException ("File path is required", "filePath");
131 XmlDocument doc = new XmlDocument ();
134 XmlNode root = doc.DocumentElement;
135 if (root.Name != "preserve")
136 throw new InvalidOperationException ("Invalid assembly mapping file format");
137 ParseRecursively (root);
140 void ParseRecursively (XmlNode root)
142 _assembly = GetNonEmptyRequiredAttribute (root, "assembly");
144 // The rest of the values is optional for us and since we don't use them
145 // at all (at least for now) we also ignore all the integer parsing errors
147 _virtualPath = GetNonEmptyOptionalAttribute (root, "virtualPath");
148 _fileHash = GetNonEmptyOptionalAttributeInt32 (root, "filehash");
149 _hash = GetNonEmptyOptionalAttributeInt32 (root, "hash");
150 _flags = GetNonEmptyOptionalAttributeInt32 (root, "flags");
151 _resultType = (BuildResultTypeCode) GetNonEmptyOptionalAttributeInt32 (root, "resultType");
153 foreach (XmlNode child in root.ChildNodes) {
154 if (child.NodeType != XmlNodeType.Element)
156 if (child.Name != "filedeps")
158 ReadFileDeps (child);
160 } catch (Exception) {
164 void ReadFileDeps (XmlNode node)
167 if (_filedeps == null)
168 _filedeps = new List <string> ();
169 foreach (XmlNode child in node.ChildNodes) {
170 if (child.NodeType != XmlNodeType.Element)
172 if (child.Name != "filedep")
174 tmp = GetNonEmptyRequiredAttribute (child, "name");
181 if (_filePath == null)
182 throw new InvalidOperationException ("File path is not defined");
186 public void Save (string filePath)
188 if (filePath == null)
189 throw new ArgumentNullException ("File path is required", "filePath");
191 XmlWriterSettings xmlSettings = new XmlWriterSettings ();
192 xmlSettings.Indent = false;
193 xmlSettings.OmitXmlDeclaration = false;
194 xmlSettings.NewLineOnAttributes = false;
196 using (XmlWriter xml = XmlWriter.Create (filePath, xmlSettings)) {
197 xml.WriteStartElement ("preserve");
198 xml.WriteAttributeString ("assembly", _assembly);
199 if (!String.IsNullOrEmpty (_virtualPath))
200 xml.WriteAttributeString ("virtualPath", _virtualPath);
202 xml.WriteAttributeString ("filehash", _fileHash.ToString ());
204 xml.WriteAttributeString ("flags", _flags.ToString ());
206 xml.WriteAttributeString ("hash", _hash.ToString ());
207 if (_resultType != BuildResultTypeCode.Unknown)
208 xml.WriteAttributeString ("resultType", ((int)_resultType).ToString ());
209 if (_filedeps != null && _filedeps.Count > 0) {
210 xml.WriteStartElement ("filedeps");
211 foreach (string s in _filedeps) {
212 xml.WriteStartElement ("filedep");
213 xml.WriteAttributeString ("name", s);
214 xml.WriteEndElement ();
216 xml.WriteEndElement ();
218 xml.WriteEndElement ();
222 string GetNonEmptyOptionalAttribute (XmlNode n, string name)
224 return System.Web.Configuration.HandlersUtil.ExtractAttributeValue (name, n, true);
227 Int32 GetNonEmptyOptionalAttributeInt32 (XmlNode n, string name)
229 string tmp = GetNonEmptyOptionalAttribute (n, name);
231 return Int32.Parse (tmp);
235 string GetNonEmptyRequiredAttribute (XmlNode n, string name)
237 return System.Web.Configuration.HandlersUtil.ExtractAttributeValue (name, n, false, false);