3 // Marek Habersack (mhabersack@novell.com)
5 // (C) 2007 Novell, Inc
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
29 using System
.Collections
.Generic
;
33 using System
.Xml
.XPath
;
35 namespace Mono
.MonoConfig
37 class DefaultConfigFile
48 public string FileName
{
50 if (!String
.IsNullOrEmpty (fileName
))
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
)
67 this.fileName
= fileName
;
69 this.sections
= sections
;
73 public delegate void OverwriteFileEventHandler (object sender
, OverwriteFileEventArgs e
);
75 public sealed class OverwriteFileEventArgs
: System
.EventArgs
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
)
103 this.target
= target
;
104 this.overwrite
= overwrite
;
108 public class DefaultConfigFileNodeHandler
: IDocumentNodeHandler
, IDefaultConfigFileContainer
, IStorageConsumer
112 FeatureTarget target
;
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
))
127 sections
= new Section ();
128 Helpers
.BuildSectionTree (nav
.Select ("./section[string-length (@name) > 0]"), sections
);
131 public void StoreConfiguration ()
135 DefaultConfigFile dcf
= new DefaultConfigFile (name
, fileName
, target
, sections
);
136 if (storage
.ContainsKey (name
))
137 storage
[name
] = dcf
;
139 storage
.Add (name
, dcf
);
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
{
157 if (storage
.Count
== 0)
160 List
<string> ret
= new List
<string>(storage
.Count
);
161 DefaultConfigFile dcf
;
163 foreach (KeyValuePair
<string, DefaultConfigFile
> kvp
in storage
) {
165 ret
.Add (String
.Format ("{0} (Target: {1}; Output file: {2})",
166 kvp
.Key
, dcf
.Target
, dcf
.FileName
));
173 public bool HasDefaultConfigFile (string name
, FeatureTarget target
)
177 if (storage
.ContainsKey (name
)) {
178 DefaultConfigFile dcf
= storage
[name
];
182 if (target
!= FeatureTarget
.Any
&& dcf
.Target
!= target
)
191 public void WriteDefaultConfigFile (string name
, FeatureTarget target
, string path
, IDefaultContainer
[] defaults
)
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",
205 string targetFile
= Path
.Combine (path
, dcf
.FileName
);
206 if (File
.Exists (targetFile
)) {
207 OverwriteFileEventArgs args
= new OverwriteFileEventArgs (
214 OnOverwriteFile (args
);
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
),
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)
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)
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)
260 foreach (Section s
in children
) {
261 tmp
= Helpers
.FindDefault (defaults
, s
.DefaultBlockName
, target
);
265 node
= doc
.ImportNode (tmp
.DocumentElement
.FirstChild
, true);
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
),
274 parent
.AppendChild (node
);
278 void AssertStorage ()
281 throw new ApplicationException ("No storage attached");