///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
// Pair for the auto-generated RegistryData.cs, provides the helper ctors and methods.
using System;
using System.Collection.Generic;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Xml.Schema;
using JetBrains.Annotations;
namespace JetBrains.Build.InstallationData
{
public partial class InstallationDataXml
{
#region Init
public InstallationDataXml([NotNull] RegistryXml registry, [NotNull] params FolderXml[] folders)
{
if(registry == null)
throw new ArgumentNullException("registry");
if(folders == null)
throw new ArgumentNullException("folders");
Registry = registry;
Files = folders;
}
public InstallationDataXml()
: this(new RegistryXml(), new FolderXml[] {})
{
}
public InstallationDataXml(RegistryXml registry)
: this(registry, new FolderXml[] {})
{
}
public InstallationDataXml(FolderXml folderxml)
: this(new RegistryXml(), folderxml)
{
}
#endregion
#region Attributes
///
/// Gets the XSD for the Registry Data XML files.
///
public static XmlSchema RegistryDataXmlSchema
{
get
{
using(Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("JetBrains.Build.RegistryData.RegistryData.xsd"))
return XmlSchema.Read(stream, null);
}
}
#endregion
#region Operations
public void AssertValid()
{
if(Registry == null)
throw new InvalidOperationException(string.Format("The Registry must not be Null."));
Registry.AssertValid();
if(Files == null)
throw new InvalidOperationException(string.Format("The Files collection must not be Null."));
var hashFolderIds = new Dictionary();
foreach(FolderXml folderxml in Files)
{
folderxml.AssertValid();
if(hashFolderIds.ContainsKey(folderxml.Id))
throw new InvalidOperationException(string.Format("Duplicate folder ID “{0}”.", folderxml.Id));
hashFolderIds.Add(folderxml.Id, true);
}
}
///
/// Makes sure all of the collections are non-Null (but may be empty).
///
public void EnsureNotNull()
{
if(Registry == null)
Registry = new RegistryXml();
Registry.EnsureNotNull();
if(Files == null)
Files = new FolderXml[] {};
}
///
/// Merges the installation data into the host's, and destroys the former.
/// All of the collections are guaranteed to be non-Null
///
public void MergeWith(InstallationDataXml addon)
{
EnsureNotNull();
Registry.MergeWith(addon.Registry);
// Merge files
var files = new List(Files);
files.AddRange(addon.Files);
Files = files.ToArray();
}
///
/// Checks for duplicate keys and values, removes, if any.
///
public void RemoveDuplicates()
{
EnsureNotNull();
if(Registry != null)
Registry.RemoveDuplicates();
// Remove file duplicates (from the target point of view)
var hashFiles = new Dictionary();
foreach(FolderXml folder in Files)
{
if(folder.Files == null)
continue;
foreach(FileXml file in folder.Files)
{
string sFileId = folder.TargetRoot + ":" + folder.TargetDir.Trim() + ":" + file.TargetName;
if(hashFiles.ContainsKey(sFileId))
continue;
hashFiles.Add(sFileId, true);
}
}
}
#endregion
}
public partial class RegistryXml
{
#region Init
///
/// The default ctor, leaves the collections empty.
///
public RegistryXml()
: this(new RegistryKeyXml[] {}, new RegistryValueXml[] {})
{
}
///
/// Creates a object and fills it with data.
///
/// Keys.
/// Values.
public RegistryXml([NotNull] ICollection keys, [NotNull] ICollection values)
{
if(keys == null)
throw new ArgumentNullException("keys");
if(values == null)
throw new ArgumentNullException("values");
Key = new RegistryKeyXml[keys.Count];
keys.CopyTo(Key, 0);
Value = new RegistryValueXml[values.Count];
values.CopyTo(Value, 0);
}
#endregion
#region Operations
public void AssertValid()
{
if(Key == null)
throw new InvalidOperationException(string.Format("The keys collection must not be Null."));
foreach(RegistryKeyXml keyxml in Key)
keyxml.AssertValid();
if(Value == null)
throw new InvalidOperationException(string.Format("The values collection must not be Null."));
foreach(RegistryValueXml valuexml in Value)
valuexml.AssertValid();
// Note: the macros collection is fake and should not be validated.
}
///
/// Makes sure all of the collections are non-Null (but may be empty).
///
public void EnsureNotNull()
{
if(Key == null)
Key = new RegistryKeyXml[] {};
if(Value == null)
Value = new RegistryValueXml[] {};
}
///
/// Merges the keys and values into the host's, and destroys the former.
/// The or colections may be Null on either parameter, but on return they're guaranteed to be non-Null in this object.
///
public void MergeWith([NotNull] RegistryXml addon)
{
if(addon == null)
throw new ArgumentNullException("addon");
var keys = new List(Key ?? new RegistryKeyXml[] {});
var values = new List(Value ?? new RegistryValueXml[] {});
foreach(RegistryKeyXml key in addon.Key ?? new RegistryKeyXml[] {})
keys.Add(key);
foreach(RegistryValueXml value in addon.Value ?? new RegistryValueXml[] {})
values.Add(value);
addon.Key = new RegistryKeyXml[] {};
addon.Value = new RegistryValueXml[] {};
Key = keys.ToArray();
Value = values.ToArray();
}
///
/// Checks for duplicate keys and values, removes, if any.
///
public void RemoveDuplicates()
{
IList keysOld = Key ?? new RegistryKeyXml[] {};
IList valuesOld = Value ?? new RegistryValueXml[] {};
var keysNew = new List(keysOld.Count);
var valuesNew = new List(valuesOld.Count);
var hashKeys = new HashSet();
var hashValues = new HashSet();
foreach(RegistryKeyXml keyxml in keysOld)
{
if(hashKeys.Contains(keyxml))
continue;
keysNew.Add(keyxml);
hashKeys.Add(keyxml);
}
foreach(RegistryValueXml valuexml in valuesOld)
{
if(hashValues.Contains(valuexml))
continue;
valuesNew.Add(valuexml);
hashValues.Add(valuexml);
}
Key = keysNew.ToArray();
Value = valuesNew.ToArray();
}
///
/// Wraps into the installation data object.
///
///
public InstallationDataXml ToInstallationData()
{
return new InstallationDataXml(this);
}
#endregion
}
public partial class RegistryKeyXml : IEquatable
{
#region Init
public RegistryKeyXml()
{
}
///
/// Creates a object.
///
/// Hive.
/// Path to the key under the hive.
public RegistryKeyXml(RegistryHiveXml hive, [NotNull] string key)
{
if(key == null)
throw new ArgumentNullException("key");
Hive = hive;
Key = key;
}
#endregion
#region Operations
///
/// Creates a new Registry Value that derives its Hive and Key path from the current Registry key.
///
/// Name of the value.
/// Value of the value, must be either a or an .
/// The new registry value.
public RegistryValueXml CreateValue([NotNull] string name, [NotNull] object value)
{
return new RegistryValueXml(Hive, Key, name, value);
}
///
/// Creates a new array consisting of only this object.
///
public RegistryKeyXml[] ToArray()
{
return new[] {this};
}
#endregion
#region Overrides
public override bool Equals(object obj)
{
if(this == obj)
return true;
return Equals(obj as RegistryKeyXml);
}
#pragma warning disable RedundantOverridenMember
public override int GetHashCode()
{
return base.GetHashCode();
}
#pragma warning restore RedundantOverridenMember
///
///Returns a that represents the current .
///
///
///
///A that represents the current .
///
///2
public override string ToString()
{
return string.Format("", Hive, Key);
}
#endregion
#region IEquatable Members
public bool Equals(RegistryKeyXml registryKeyXml)
{
if(registryKeyXml == null)
return false;
if(!base.Equals(registryKeyXml))
return false;
return true;
}
#endregion
}
public partial class RegistryBaseXml : IEquatable
{
#region Operations
public virtual void AssertValid()
{
if(string.IsNullOrEmpty(Key))
throw new InvalidOperationException(string.Format("The key must not be empty."));
if(Key.IndexOf("/") >= 0)
throw new InvalidOperationException(string.Format("The slashes in the key must be reverse."));
}
#endregion
#region Overrides
public override bool Equals(object obj)
{
if(this == obj)
return true;
return Equals(obj as RegistryBaseXml);
}
public override int GetHashCode()
{
return hiveField.GetHashCode() + 29 * (keyField != null ? keyField.GetHashCode() : 0);
}
#endregion
#region IEquatable Members
public bool Equals(RegistryBaseXml registryBaseXml)
{
if(registryBaseXml == null)
return false;
return Equals(hiveField, registryBaseXml.hiveField) && Equals(keyField, registryBaseXml.keyField);
}
#endregion
}
public partial class FileXml
{
#region Init
public FileXml(string name)
: this(name, name)
{
}
public FileXml(string sSourceName, string sTargetName)
{
SourceName = sSourceName;
TargetName = sTargetName;
}
#endregion
#region Operations
public void AssertValid()
{
if(string.IsNullOrEmpty(SourceName))
throw new InvalidOperationException(string.Format("The source name must be specified."));
if(TargetName == null) // Target name is allowed to be empty
throw new InvalidOperationException(string.Format("The target name must not be Null."));
}
#endregion
}
public partial class FolderXml
{
#region Operations
public void AssertValid()
{
Normalize();
if((Files == null) || (Files.Length == 0))
throw new InvalidOperationException(string.Format("The files collection of the folder must not be empty."));
if(string.IsNullOrEmpty(Id))
throw new InvalidOperationException(string.Format("The ID of a folder must not be empty."));
if(string.IsNullOrEmpty(MsiComponentGuid))
throw new InvalidOperationException(string.Format("The GUID must be specified."));
foreach(FileXml filexml in Files)
filexml.AssertValid();
}
public void Normalize()
{
TargetDir = TargetDir.Trim().Trim('/', '\\').Replace('/', '\\').Trim();
SourceDir = SourceDir.Trim().Trim('/', '\\').Replace('/', '\\').Trim();
}
public InstallationDataXml ToInstallationData()
{
return new InstallationDataXml(this);
}
#endregion
}
public partial class MacroXml
{
}
public partial class RegistryValueXml : IEquatable
{
#region Init
///
/// Creates a object.
///
/// Hive.
/// Path to the key under the hive.
/// Name of the value.
/// Value of the value, must be either a or an .
public RegistryValueXml(RegistryHiveXml hive, [NotNull] string key, [NotNull] string name, [NotNull] object value)
{
if(key == null)
throw new ArgumentNullException("key");
if(name == null)
throw new ArgumentNullException("name");
if(value == null)
throw new ArgumentNullException("value");
Hive = hive;
Key = key;
Name = name;
if(value is string)
{
Type = RegistryValueTypeXml.String;
Value = (string)value;
}
else if(value is int)
{
Type = RegistryValueTypeXml.Dword;
Value = value.ToString();
}
else
throw new InvalidOperationException(string.Format("The value type “{0}” is not supported.", value.GetType().AssemblyQualifiedName));
}
#endregion
#region Operations
///
/// Creates a new array consisting of only this object.
///
public RegistryValueXml[] ToArray()
{
return new[] {this};
}
///
/// Creates a new Registry with just this value.
///
public RegistryXml ToRegistry()
{
return new RegistryXml(new RegistryKeyXml[] {}, new[] {this});
}
#endregion
#region Overrides
public override void AssertValid()
{
base.AssertValid();
if(Name == null)
throw new InvalidOperationException(string.Format("The Name must not be Null, but it can be empty for the default value of the key."));
}
public override bool Equals(object obj)
{
if(this == obj)
return true;
return Equals(obj as RegistryValueXml);
}
public override int GetHashCode()
{
int result = base.GetHashCode();
result = 29 * result + (nameField != null ? nameField.GetHashCode() : 0);
result = 29 * result + (valueField != null ? valueField.GetHashCode() : 0);
result = 29 * result + typeField.GetHashCode();
return result;
}
///
///Returns a that represents the current .
///
///
///
///A that represents the current .
///
///2
public override string ToString()
{
return string.Format("", Hive, Key, Name, Value);
}
#endregion
#region IEquatable Members
public bool Equals(RegistryValueXml registryValueXml)
{
if(registryValueXml == null)
return false;
if(!base.Equals(registryValueXml))
return false;
if(!Equals(nameField, registryValueXml.nameField))
return false;
if(!Equals(valueField, registryValueXml.valueField))
return false;
if(!Equals(typeField, registryValueXml.typeField))
return false;
return true;
}
#endregion
}
}