📄 addin.cs
字号:
fieldInfo.SetValue(customizer, Convert.ChangeType(Enum.Parse(fieldInfo.FieldType, node.Value), fieldInfo.FieldType));
} else {
PathAttribute pathAttribute = (PathAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(PathAttribute));
if (pathAttribute != null) {
fieldInfo.SetValue(customizer, fileUtilityService.GetDirectoryNameWithSeparator(Path.GetDirectoryName(fileName)) + Convert.ChangeType(node.Value, fieldInfo.FieldType).ToString());
} else {
fieldInfo.SetValue(customizer, Convert.ChangeType(node.Value, fieldInfo.FieldType));
}
}
}
}
// process XmlMemberAttributeAttribute attributes
XmlMemberArrayAttribute codonArrayAttribute = (XmlMemberArrayAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(XmlMemberArrayAttribute));
if (codonArrayAttribute != null) {
// get value from xml file
XmlNode node = codonNode.SelectSingleNode("@" + codonArrayAttribute.Name);
// check if its required
if (node == null && codonArrayAttribute.IsRequired) {
throw new ApplicationException(String.Format("{0} is a required attribute.", codonArrayAttribute.Name));
}
if (node != null) {
string[] attrArray = node.Value.Split(codonArrayAttribute.Separator);
// TODO : convert array types (currently only string arrays are supported)
fieldInfo.SetValue(customizer, attrArray);
}
}
}
currentType = currentType.BaseType;
}
}
ICondition GetCondition(XmlElement el)
{
ConditionCollection conditions = new ConditionCollection();
foreach (XmlElement child in el.ChildNodes) {
conditions.Add(GetCondition(child));
}
switch (el.Name) {
case "Condition":
if (conditions.Count > 0) {
throw new AddInTreeFormatException("Condition node childs found. (doesn't make sense)");
}
ICondition c = AddInTreeSingleton.AddInTree.ConditionFactory.CreateCondition(this, el);
AutoInitializeAttributes(c, el);
return c;
case "And":
if (conditions.Count <= 1) {
throw new AddInTreeFormatException("And node with none or only one child found.");
}
return new AndCondition(conditions);
case "Or":
if (conditions.Count <= 1) {
throw new AddInTreeFormatException("Or node with none or only one child found.");
}
return new OrCondition(conditions);
case "Not":
if (conditions.Count > 1) {
throw new AddInTreeFormatException("Not node with more than one child found");
}
if (conditions.Count == 0) {
throw new AddInTreeFormatException("Not node without child found.");
}
return new NegatedCondition(conditions);
}
throw new AddInTreeFormatException("node " + el.Name + " not valid in expression.");
}
ICondition BuildComplexCondition(XmlElement el)
{
if (el["Or"] != null) {
return GetCondition(el["Or"]);
}
if (el["And"] != null) {
return GetCondition(el["And"]);
}
if (el["Not"] != null) {
return GetCondition(el["Not"]);
}
if (el["Condition"] != null) {
return GetCondition(el["Condition"]);
}
return null;
}
void AddCodonsToExtension(Extension e, XmlElement el, ConditionCollection conditions)
{
foreach (object o in el.ChildNodes) {
if (!(o is XmlElement)) {
continue;
}
XmlElement curEl = (XmlElement)o;
switch (curEl.Name) {
case "And": // these nodes are silently ignored.
case "Or":
case "Not":
case "Condition":
break;
case "Conditional":
ICondition condition = null;
// construct condition
if (curEl.Attributes.Count == 0 || (curEl.Attributes.Count == 1 && curEl.Attributes["action"] != null)) {
condition = BuildComplexCondition(curEl);
// set condition action manually
if (curEl.Attributes["action"] != null) {
condition.Action = (ConditionFailedAction)Enum.Parse(typeof(ConditionFailedAction), curEl.Attributes["action"].InnerText);
}
if (condition == null) {
throw new AddInTreeFormatException("empty conditional, but no condition definition found.");
}
} else {
condition = AddInTreeSingleton.AddInTree.ConditionFactory.CreateCondition(this, curEl);
AutoInitializeAttributes(condition, curEl);
}
// put the condition at the end of the condition 'stack'
conditions.Add(condition);
// traverse the subtree
AddCodonsToExtension(e, curEl, conditions);
// now we are back to the old level, remove the condition
// that was applied to the subtree.
conditions.RemoveAt(conditions.Count - 1);
break;
default:
ICodon codon = AddInTreeSingleton.AddInTree.CodonFactory.CreateCodon(this, curEl);
AutoInitializeAttributes(codon, curEl);
// Ensure that the codon is inserted after the codon which is defined
// before in the add-in definition.
// The codons get topologically sorted and if I don't set the InsertAfter they may
// change it's sorting order.
e.Conditions[codon.ID] = new ConditionCollection(conditions);
if (codon.InsertAfter == null && codon.InsertBefore == null && e.CodonCollection.Count > 0) {
codon.InsertAfter = new string[] { ((ICodon)e.CodonCollection[e.CodonCollection.Count - 1]).ID };
}
e.CodonCollection.Add(codon);
if (curEl.ChildNodes.Count > 0) {
Extension newExtension = new Extension(e.Path + '/' + codon.ID);
AddCodonsToExtension(newExtension, curEl, conditions);
extensions.Add(newExtension);
}
break;
}
}
}
/// <summary>
/// Creates an object which is related to this Add-In.
/// </summary>
/// <exception cref="TypeNotFoundException">
/// If className could not be created.
/// </exception>
public object CreateObject(string className)
{
object newInstance;
foreach (DictionaryEntry library in runtimeLibraries) {
newInstance = ((Assembly)library.Value).CreateInstance(className);
if (newInstance != null) {
return newInstance;
}
}
newInstance = Assembly.GetExecutingAssembly().CreateInstance(className);
if (newInstance == null) {
foreach (Assembly assembly in runtimeLibraries.Values) {
newInstance = assembly.CreateInstance(className);
if (newInstance != null) {
break;
}
}
if (newInstance == null) {
newInstance = Assembly.GetCallingAssembly().CreateInstance(className);
}
}
if (newInstance == null) {
MessageBox.Show("Type not found: " + className + ". Please check : " + fileName, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1);
}
return newInstance;
}
/// <summary>
/// Definies an extension point (path in the tree) with its codons.
/// </summary>
public class Extension
{
string path;
ArrayList codonCollection = new ArrayList();
Hashtable conditions = new Hashtable();
/// <summary>
/// returns the path in which the underlying codons are inserted
/// </summary>
public string Path {
get {
return path;
}
set {
path = value;
}
}
/// <summary>
/// returns a Hashtable with all conditions defined in this extension.
/// where the key is the codon ID and the value is a <code>ConditionCollection</code>
/// containing all conditions.
/// </summary>
public Hashtable Conditions {
get {
return conditions;
}
}
/// <summary>
/// returns a ArrayList with all the codons defined in this extension.
/// </summary>
public ArrayList CodonCollection {
get {
return codonCollection;
}
set {
codonCollection = value;
}
}
/// <summary>
/// Constructs a new instance.
/// </summary>
public Extension(string path)
{
this.path = path;
}
/// <summary>
/// Returns a string representation of a Extension.
/// </summary>
public override string ToString()
{
return "[Extension: Path = " + path + ", codonCollection.Count = " + codonCollection.Count + "]";
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -