adjust version
[mcs.git] / tools / mconfig / Mono.MonoConfig / DefaultConfigFileNodeHandler.cs
blob0bc3a6e1e3e8830b480c135cdddd87fd303bf347
1 //
2 // Authors:
3 // Marek Habersack (mhabersack@novell.com)
4 //
5 // (C) 2007 Novell, Inc
6 //
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 using System;
29 using System.Collections.Generic;
30 using System.IO;
31 using System.Text;
32 using System.Xml;
33 using System.Xml.XPath;
35 namespace Mono.MonoConfig
37 class DefaultConfigFile
39 string name;
40 string fileName;
41 FeatureTarget target;
42 Section sections;
44 public string Name {
45 get { return name; }
48 public string FileName {
49 get {
50 if (!String.IsNullOrEmpty (fileName))
51 return fileName;
52 return Name;
56 public FeatureTarget Target {
57 get { return target; }
60 public Section Sections {
61 get { return sections; }
64 public DefaultConfigFile (string name, string fileName, FeatureTarget target, Section sections)
66 this.name = name;
67 this.fileName = fileName;
68 this.target = target;
69 this.sections = sections;
73 public delegate void OverwriteFileEventHandler (object sender, OverwriteFileEventArgs e);
75 public sealed class OverwriteFileEventArgs : System.EventArgs
77 string name;
78 string path;
79 FeatureTarget target;
80 bool overwrite;
82 public string Name {
83 get { return name; }
86 public string Path {
87 get { return path; }
90 public FeatureTarget Target {
91 get { return target; }
94 public bool Overwrite {
95 get { return overwrite; }
96 set { overwrite = value; }
99 public OverwriteFileEventArgs (string name, string path, FeatureTarget target, bool overwrite)
101 this.name = name;
102 this.path = path;
103 this.target = target;
104 this.overwrite = overwrite;
108 public class DefaultConfigFileNodeHandler : IDocumentNodeHandler, IDefaultConfigFileContainer, IStorageConsumer
110 string name;
111 string fileName;
112 FeatureTarget target;
113 Section sections;
114 Dictionary <string, DefaultConfigFile> storage;
116 public event OverwriteFileEventHandler OverwriteFile;
118 public void ReadConfiguration (XPathNavigator nav)
120 name = Helpers.GetRequiredNonEmptyAttribute (nav, "name");
121 target = Helpers.ConvertEnum <FeatureTarget> (Helpers.GetRequiredNonEmptyAttribute (nav, "target"), "target");
122 fileName = Helpers.GetOptionalAttribute (nav, "fileName");
124 if (String.IsNullOrEmpty (fileName))
125 fileName = name;
127 sections = new Section ();
128 Helpers.BuildSectionTree (nav.Select ("./section[string-length (@name) > 0]"), sections);
131 public void StoreConfiguration ()
133 AssertStorage ();
135 DefaultConfigFile dcf = new DefaultConfigFile (name, fileName, target, sections);
136 if (storage.ContainsKey (name))
137 storage [name] = dcf;
138 else
139 storage.Add (name, dcf);
141 name = null;
142 fileName = null;
143 sections = null;
146 public void SetStorage (object storage)
148 this.storage = storage as Dictionary <string, DefaultConfigFile>;
149 if (this.storage == null)
150 throw new ApplicationException ("Invalid storage type");
153 public ICollection <string> DefaultConfigFiles {
154 get {
155 AssertStorage ();
157 if (storage.Count == 0)
158 return null;
160 List <string> ret = new List <string>(storage.Count);
161 DefaultConfigFile dcf;
163 foreach (KeyValuePair <string, DefaultConfigFile> kvp in storage) {
164 dcf = kvp.Value;
165 ret.Add (String.Format ("{0} (Target: {1}; Output file: {2})",
166 kvp.Key, dcf.Target, dcf.FileName));
169 return ret;
173 public bool HasDefaultConfigFile (string name, FeatureTarget target)
175 AssertStorage ();
177 if (storage.ContainsKey (name)) {
178 DefaultConfigFile dcf = storage [name];
179 if (dcf == null)
180 return false;
182 if (target != FeatureTarget.Any && dcf.Target != target)
183 return false;
185 return true;
188 return false;
191 public void WriteDefaultConfigFile (string name, FeatureTarget target, string path, IDefaultContainer[] defaults)
193 AssertStorage ();
195 DefaultConfigFile dcf;
196 if (!storage.ContainsKey (name) || (dcf = storage [name]) == null)
197 throw new ApplicationException (
198 String.Format ("Definition of the '{0}' default config file not found.", name));
200 if (target != FeatureTarget.Any && dcf.Target != target)
201 throw new ApplicationException (
202 String.Format ("Config file '{0}' can be generated only for the '{1}' target",
203 name, target));
205 string targetFile = Path.Combine (path, dcf.FileName);
206 if (File.Exists (targetFile)) {
207 OverwriteFileEventArgs args = new OverwriteFileEventArgs (
208 dcf.FileName,
209 path,
210 target,
211 true
214 OnOverwriteFile (args);
215 if (!args.Overwrite)
216 return;
219 try {
220 if (!Directory.Exists (path))
221 Directory.CreateDirectory (path);
222 } catch (Exception ex) {
223 throw new ApplicationException (
224 String.Format ("Could not create directory '{0}'", path),
225 ex);
228 XmlDocument doc = new XmlDocument ();
229 PopulateDocument (name, target, doc, dcf, defaults);
230 Helpers.SaveXml (doc, targetFile);
233 void OnOverwriteFile (OverwriteFileEventArgs args)
235 if (OverwriteFile == null)
236 return;
238 OverwriteFile (this, args);
241 void PopulateDocument (string name, FeatureTarget target, XmlDocument doc, DefaultConfigFile dcf,
242 IDefaultContainer[] defaults)
244 List <Section> children = dcf.Sections != null ? dcf.Sections.Children : null;
245 if (children == null || children.Count == 0)
246 return;
248 PopulateDocument (name, target, doc, doc, defaults, children);
251 void PopulateDocument (string name, FeatureTarget target, XmlDocument doc, XmlNode parent,
252 IDefaultContainer[] defaults, List <Section> children)
254 if (defaults == null || defaults.Length == 0)
255 return;
257 XmlNode node;
258 XmlDocument tmp;
260 foreach (Section s in children) {
261 tmp = Helpers.FindDefault (defaults, s.DefaultBlockName, target);
262 if (tmp == null)
263 continue;
265 node = doc.ImportNode (tmp.DocumentElement.FirstChild, true);
266 try {
267 PopulateDocument (name, target, doc, node, defaults, s.Children);
268 } catch (Exception ex) {
269 throw new ApplicationException (
270 String.Format ("Error building default config file '{0}'", name),
271 ex);
274 parent.AppendChild (node);
278 void AssertStorage ()
280 if (storage == null)
281 throw new ApplicationException ("No storage attached");