// // MochaXMLDataFormat.cs // // Author: // Michael Becker // // Copyright (c) 2020 Mike Becker's Software // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . using System; using System.Collections.Generic; using System.Linq; using MBS.Framework; using Mocha.Core; using UniversalEditor.DataFormats.Markup.XML; using UniversalEditor.ObjectModels.Markup; using UniversalEditor.Plugins.Mocha.ObjectModels.MochaClassLibrary; namespace UniversalEditor.Plugins.Mocha.DataFormats.MochaXML { public class MochaXMLDataFormat : XMLDataFormat { public MochaXMLDataFormat() { /* this.Settings.Entities.Add("IDC_Class", KnownInstanceGuids.Classes.Class.ToString("B")); this.Settings.Entities.Add("IDC_Attribute", "{F9CD7751-EF62-4F7C-8A28-EBE90B8F46AA}"); this.Settings.Entities.Add("IDC_BooleanAttribute", "{EA830448-A403-4ED9-A3D3-048D5D5C3A03}"); this.Settings.Entities.Add("IDC_NumericAttribute", "{9DE86AF1-EFD6-4B71-9DCC-202F247C94CB}"); this.Settings.Entities.Add("IDC_TextAttribute", "{C2F36542-60C3-4B9E-9A96-CA9B309C43AF}"); this.Settings.Entities.Add("IDC_DateAttribute", "{0B7B1812-DFB4-4F25-BF6D-CEB0E1DF8744}"); this.Settings.Entities.Add("IDC_Relationship", "{9B0A80F9-C325-4D36-997C-FB4106204648}"); this.Settings.Entities.Add("IDC_Instance", "{263C4882-945F-4DE9-AED8-E0D6516D4903}"); this.Settings.Entities.Add("IDC_InstanceSet", KnownInstanceGuids.Classes.InstanceSet.ToString("B")); this.Settings.Entities.Add("IDC_InstanceDefinition", "{ee26f146-0b89-4cfe-a1af-ae6ac3533eae}"); this.Settings.Entities.Add("IDC_String", ""); this.Settings.Entities.Add("IDC_Module", ""); this.Settings.Entities.Add("IDC_Translation", "{04A53CC8-3206-4A97-99C5-464DB8CAA6E6}"); this.Settings.Entities.Add("IDC_TranslationValue", "{6D38E757-EC18-43AD-9C35-D15BB446C0E1}"); this.Settings.Entities.Add("IDC_Enumeration", ""); this.Settings.Entities.Add("IDC_StringComponent", "{F9E2B671-13F5-4172-A568-725ACD8BBFAB}"); this.Settings.Entities.Add("IDC_ExtractSingleInstanceStringComponent", "{FCECCE4E-8D05-485A-AE34-B1B45E766661}"); this.Settings.Entities.Add("IDC_InstanceAttributeStringComponent", "{623565D5-5AEE-49ED-A5A9-0CFE670507BC}"); this.Settings.Entities.Add("IDC_User", "{9C6871C1-9A7F-4A3A-900E-69D1D9E24486}"); this.Settings.Entities.Add("IDC_Report", KnownInstanceGuids.Classes.Report.ToString("B")); this.Settings.Entities.Add("IDC_ReportColumn", KnownInstanceGuids.Classes.ReportColumn.ToString("B")); this.Settings.Entities.Add("IDC_Page", "{D9626359-48E3-4840-A089-CD8DA6731690}"); this.Settings.Entities.Add("IDC_HeadingPageComponent", "{FD86551E-E4CE-4B8B-95CB-BEC1E6A0EE2B}"); this.Settings.Entities.Add("IDC_Element", KnownInstanceGuids.Classes.Element.ToString("B")); this.Settings.Entities.Add("IDC_ElementContent", KnownInstanceGuids.Classes.ElementContent.ToString("B")); this.Settings.Entities.Add("IDC_ElementContentDisplayOption", " "); this.Settings.Entities.Add("IDC_Event", KnownInstanceGuids.Classes.Event.ToString("B")); this.Settings.Entities.Add("IDC_WorkData", KnownInstanceGuids.Classes.WorkData.ToString("B")); this.Settings.Entities.Add("IDC_WorkSet", KnownInstanceGuids.Classes.WorkSet.ToString("B")); this.Settings.Entities.Add("IDC_AccessModifier", ""); this.Settings.Entities.Add("IDC_Method", KnownInstanceGuids.Classes.Method.ToString("B")); this.Settings.Entities.Add("IDC_CalculateDateMethod", KnownInstanceGuids.Classes.CalculateDateMethod.ToString("B")); this.Settings.Entities.Add("IDC_BuildAttributeMethod", KnownInstanceGuids.Classes.BuildAttributeMethod.ToString("B")); this.Settings.Entities.Add("IDC_GetAttributeMethod", KnownInstanceGuids.Classes.GetAttributeMethod.ToString("B")); this.Settings.Entities.Add("IDC_SelectFromInstanceSetMethod", KnownInstanceGuids.Classes.SelectFromInstanceSetMethod.ToString("B")); this.Settings.Entities.Add("IDC_GetReferencedAttributeMethod", KnownInstanceGuids.Classes.GetReferencedAttributeMethod.ToString("B")); this.Settings.Entities.Add("IDC_InstanceOpMethod", KnownInstanceGuids.Classes.InstanceOpMethod.ToString("B")); this.Settings.Entities.Add("IDC_GetSpecifiedInstancesMethod", KnownInstanceGuids.Classes.GetSpecificInstancesMethod.ToString("B")); this.Settings.Entities.Add("IDC_GetReferencedInstanceSetMethod", KnownInstanceGuids.Classes.GetReferencedInstanceSetMethod.ToString("B")); this.Settings.Entities.Add("IDC_EvaluateBooleanExpressionMethod", ""); this.Settings.Entities.Add("IDC_GetRelationshipMethod", "{d53c9232-89ef-4cca-8520-261da6787450}"); this.Settings.Entities.Add("IDC_ConditionalSelectAttributeMethod", KnownInstanceGuids.Classes.ConditionalSelectAttributeMethod.ToString("B")); this.Settings.Entities.Add("IDC_GetInstanceSetBySystemRoutineMethod", KnownInstanceGuids.Classes.GetInstanceSetBySystemRoutineMethod.ToString("B")); this.Settings.Entities.Add("IDC_ConditionalMethodCase", KnownInstanceGuids.Classes.ConditionalMethodCase.ToString("B")); this.Settings.Entities.Add("IDC_Executable", KnownInstanceGuids.Classes.Executable.ToString("B")); this.Settings.Entities.Add("IDC_Parameter", global::Mocha.Core.KnownInstanceGuids.Classes.Parameter.ToString("B")); this.Settings.Entities.Add("IDC_ReportObject", global::Mocha.Core.KnownInstanceGuids.Classes.ReportObject.ToString("B")); this.Settings.Entities.Add("IDC_Validation", KnownInstanceGuids.Classes.Validation.ToString("B")); this.Settings.Entities.Add("IDC_ValidationClassification", KnownInstanceGuids.Classes.ValidationClassification.ToString("B")); this.Settings.Entities.Add("IDC_MethodBinding", "{CB36098E-B9BF-4D22-87FA-4186EC632C89}"); this.Settings.Entities.Add("IDC_ParameterAssignment", ""); this.Settings.Entities.Add("IDC_ReturnAttributeMethodBinding", "{30FB6BA6-2BBB-41D2-B91A-709C00A07790}"); this.Settings.Entities.Add("IDC_ReturnInstanceSetMethodBinding", "{AADC20F9-7559-429B-AEF0-97E059295C76}"); this.Settings.Entities.Add("IDC_PageComponent_TabContainerPageComponent", ""); this.Settings.Entities.Add("IDC_DetailPageComponent", ""); // FIXME: these should be `Report Field`.has source Method `GA - Get Attribute Method...` or `GSI - Get Specific Instance`... etc. this.Settings.Entities.Add("IDC_ReportField", "{655A04D9-FE35-4F89-9AAB-B8FA34989D03}"); this.Settings.Entities.Add("IDC_AttributeReportField", "{C06E0461-A956-4599-9708-012C8FE04D94}"); this.Settings.Entities.Add("IDC_RelationshipReportField", "{FC4E3BB5-1EA7-44FF-B828-2EA54CDD4ABB}"); this.Settings.Entities.Add("IDC_StandardReport", "{FDF4A498-DE83-417D-BA01-707372125C8D}"); this.Settings.Entities.Add("IDC_Tenant", "{703F9D65-C584-4D9F-A656-D0E3C247FF1F}"); this.Settings.Entities.Add("IDC_AuditLine", ""); this.Settings.Entities.Add("IDC_Dashboard", KnownInstanceGuids.Classes.Dashboard.ToString("B")); this.Settings.Entities.Add("IDC_DashboardContent", KnownInstanceGuids.Classes.DashboardContent.ToString("B")); this.Settings.Entities.Add("IDC_Theme", KnownInstanceGuids.Classes.Theme.ToString("B")); */ this.Settings.Entities.Add("IDA_Name", "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}"); this.Settings.Entities.Add("IDA_Abstract", "{A1C0255D-3E8D-47D7-A186-1C93C93D4667}"); this.Settings.Entities.Add("IDA_Value", "{041DD7FD-2D9C-412B-8B9D-D7125C166FE0}"); this.Settings.Entities.Add("IDA_DateAndTime", "{ea71cc92-a5e9-49c1-b487-8ad178b557d2}"); this.Settings.Entities.Add("IDA_Order", "{49423f66-8837-430d-8cac-7892ebdcb1fe}"); this.Settings.Entities.Add("IDA_Abbreviation", "{7ee78e44-e894-41a0-996b-d0f33c76e23b}"); this.Settings.Entities.Add("IDA_StartDate", "{F23CD242-64DB-4115-AB57-E9C70B0A38DC}"); this.Settings.Entities.Add("IDA_EndDate", "{B3AED59A-1977-4CE4-A2F9-891A1CACDEB8}"); this.Settings.Entities.Add("IDA_Static", "{9A3A0719-64C2-484F-A55E-22CD4597D9FD}"); this.Settings.Entities.Add("IDA_Verb", "{61345a5d-3397-4a96-8797-8863f03a476c}"); this.Settings.Entities.Add("IDA_Final", "{4028ec9a-7d7b-4bfb-8883-e450e797ca0e}"); this.Settings.Entities.Add("IDA_Required", KnownAttributeGuids.Boolean.Required.ToString("B")); this.Settings.Entities.Add("IDA_Null", KnownAttributeGuids.Boolean.Null.ToString("B")); this.Settings.Entities.Add("IDA_Visible", KnownAttributeGuids.Boolean.Visible.ToString("B")); this.Settings.Entities.Add("IDA_UseAnyCondition", KnownAttributeGuids.Boolean.UseAnyCondition.ToString("B")); this.Settings.Entities.Add("IDA_ValidateOnlyOnSubmit", KnownAttributeGuids.Boolean.ValidateOnlyOnSubmit.ToString("B")); // class GUID loader // first load top-level properties Type[] types = typeof(KnownInstanceGuids).Assembly.GetTypes(); foreach (Type t in types) { object[] attrs = t.GetCustomAttributes(typeof(ExportEntitiesAttribute), false); if (attrs.Length > 0) { ExportEntitiesAttribute attr = (ExportEntitiesAttribute)attrs[0]; if (attr.Prefix != null || attr.Suffix != null) { InitGuids(t, attr.Prefix, attr.Suffix, false); } } } // InitGuids(typeof(KnownInstanceGuids.Classes), "IDC"); // InitGuids(typeof(KnownInstanceGuids.MethodClasses), "IDC"); // InitGuids(typeof(KnownRelationshipGuids), "IDR", false); this.Settings.Entities.Add("IDI_Module_MochaBaseSystem", "{3ffd3a31-208c-49c9-905d-2a69362902ca}"); this.Settings.Entities.Add("IDI_Language_English", "{68BB6038-A4B5-4EE1-AAE9-326494942062}"); this.Settings.Entities.Add("IDI_Language_Spanish", "{6dc357cb-37c3-43ed-ae13-6259fb109213}"); this.Settings.Entities.Add("IDI_Language_French", "{6bf0cf09-87c9-4e21-b360-7eb5a1c279de}"); this.Settings.Entities.Add("IDI_Language_German", "{c7c1d740-0d3c-493f-ab0b-fe1b42546d0a}"); this.Settings.Entities.Add("IDI_Language_Italian", "{cf165170-0680-4a41-8f88-88f34b2b1986}"); this.Settings.Entities.Add("IDI_Language_Chinese", "{6f908a9b-7464-4a16-aed9-7eccb8d39032}"); this.Settings.Entities.Add("IDI_Language_Japanese", "{1e16de9d-0e49-4a79-b690-4905c46a94cc}"); this.Settings.Entities.Add("IDI_Language_Korean", "{d03a795e-906b-49ee-87ea-c1bef4b8ee9a}"); } private void InitGuids(Type type, string prefix, string suffix, bool nested) { Console.Error.WriteLine("debug: loading type {0}", type); System.Reflection.PropertyInfo[] pis = type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); foreach (System.Reflection.PropertyInfo pi in pis) { if (pi.PropertyType == typeof(Guid)) { Guid value = (Guid)pi.GetValue(null, null); string name = String.Format("{0}{1}{2}", prefix, pi.Name, suffix); Console.Error.WriteLine("debug: mapped entity &{0}; to {1}", name, value.ToString("B")); this.Settings.Entities.Add(name, value.ToString("B")); } } if (nested) { Type[] subtypes = type.GetNestedTypes(); foreach (Type subtype in subtypes) { InitGuids(subtype, prefix, suffix, nested); } } } protected override void BeforeLoadInternal(Stack objectModels) { base.BeforeLoadInternal(objectModels); objectModels.Push(new MarkupObjectModel() { Accessor = this.Accessor }); } protected override void AfterLoadInternal(Stack objectModels) { base.AfterLoadInternal(objectModels); MarkupObjectModel mom = (objectModels.Pop() as MarkupObjectModel); MochaClassLibraryObjectModel mcl = (objectModels.Pop() as MochaClassLibraryObjectModel); MarkupTagElement tagMocha = (mom.Elements["mocha"] as MarkupTagElement); if (tagMocha == null) throw new InvalidDataFormatException("file does not contain top-level 'mocha' tag"); MarkupTagElement tagLibraries = (tagMocha.Elements["libraries"] as MarkupTagElement); if (tagLibraries != null) { for (int i = 0; i < tagLibraries.Elements.Count; i++) { MochaLibrary library = LoadLibrary(mcl, tagLibraries.Elements[i] as MarkupTagElement); if (library == null) continue; mcl.Libraries.Merge(library); } } MarkupTagElement tagTenants = (tagMocha.Elements["tenants"] as MarkupTagElement); if (tagTenants != null) { foreach (MarkupTagElement tagTenant in tagTenants.Elements.OfType()) { if (tagTenant == null) continue; if (tagTenant.FullName != "tenant") continue; MarkupAttribute attTenantID = tagTenant.Attributes["id"]; MarkupAttribute attTenantName = tagTenant.Attributes["name"]; if (attTenantID == null) continue; Guid id = new Guid(attTenantID.Value); MochaTenant tenant = mcl.Tenants[id]; if (tenant == null) { tenant = new MochaTenant(); tenant.ID = id; mcl.Tenants.Add(tenant); } if (tenant.Name == null && attTenantName != null) { tenant.Name = attTenantName.Value; } MarkupTagElement tagLibraryReferences = tagTenant.Elements["libraryReferences"] as MarkupTagElement; if (tagLibraryReferences != null) { foreach (MarkupTagElement tagLibraryReference in tagLibraryReferences.Elements.OfType()) { MarkupAttribute attLibraryId = tagLibraryReference.Attributes["libraryId"]; if (attLibraryId == null) continue; tenant.LibraryReferences.Add(new Guid(attLibraryId.Value)); } } MarkupTagElement tagInstances = tagTenant.Elements["instances"] as MarkupTagElement; if (tagInstances != null) { foreach (MarkupTagElement tagInstance in tagInstances.Elements.OfType()) { MochaInstance inst = LoadInstance(tenant, tagInstance); tenant.Instances.Add(inst); } } } } } private MochaInstance ZqCompileMethod(IMochaStore library, MarkupTagElement tag) { MochaInstance inst = null; MarkupAttribute attID = tag.Attributes["id"]; if (attID == null) return null; Guid id = new Guid(attID.Value); Console.Error.WriteLine("zq: compiling method {0}", id); MarkupAttribute attType = tag.Attributes["type"]; MarkupAttribute attName = tag.Attributes["name"]; MarkupAttribute attVerb = tag.Attributes["verb"]; if (attName == null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "Missing 'name' attribute for method definition", "MCX0101", tag.ParentObjectModel.Accessor.GetFileName(), tag.Definition.LineNumber, tag.Definition.ColumnNumber, "Method Compiler"); } if (attVerb == null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "Missing 'verb' attribute for method definition", "MCX0101", tag.ParentObjectModel.Accessor.GetFileName(), tag.Definition.LineNumber, tag.Definition.ColumnNumber, "Method Compiler"); } if (attType != null) { switch (attType.Value) { case "getAttribute": { inst = ZqCreateInstance(library, id, global::Mocha.Core.KnownInstanceGuids.MethodClasses.GetAttributeMethod); break; } case "getInstanceSetBySystemRoutine": { inst = ZqCreateInstance(library, id, global::Mocha.Core.KnownInstanceGuids.MethodClasses.GetInstanceSetBySystemRoutineMethod); break; } case "conditionalSelectAttribute": { inst = ZqCreateInstance(library, id, global::Mocha.Core.KnownInstanceGuids.MethodClasses.ConditionalSelectAttributeMethod); if (!(tag.Elements["cases"] is MarkupTagElement tagCases)) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "Missing 'cases' element for SAC - Conditional Select Attribute Method", "MCX0101", tag.ParentObjectModel.Accessor.GetFileName(), tag.Definition.LineNumber, tag.Definition.ColumnNumber, "Method Compiler"); } else { foreach (MarkupElement elCase in tagCases.Elements) { MarkupTagElement tagCase = (elCase as MarkupTagElement); if (tagCase == null) continue; if (tagCase.FullName != "case") continue; Guid caseId; MarkupAttribute attCaseId = tagCase.Attributes["id"]; if (attCaseId != null) { caseId = Guid.Parse(attCaseId.Value); } MochaInstance instCase = ZqCreateInstance(library, caseId, KnownInstanceGuids.Classes.ConditionalEvaluationCase); MarkupAttribute attUseAnyCondition = tagCase.Attributes["useAnyCondition"]; bool useAnyCondition = false; if (attUseAnyCondition != null) { useAnyCondition = Boolean.Parse(attUseAnyCondition.Value); } MarkupAttribute attReturnAttributeMethodBindingId = tagCase.Attributes["returnAttributeMethodBindingId"]; MarkupTagElement tagTrueConditions = tagCase.Elements["trueConditions"] as MarkupTagElement; MarkupTagElement tagFalseConditions = tagCase.Elements["falseConditions"] as MarkupTagElement; ZqAssignAttribute(instCase, KnownAttributeGuids.Boolean.UseAnyCondition, useAnyCondition); if (attReturnAttributeMethodBindingId != null) { Guid returnAttributeMethodId = Guid.Parse(attReturnAttributeMethodBindingId.Value); ZqAssignRelationship(library, instCase.ID, KnownRelationshipGuids.Conditional_Method_Case__has_return_attribute__Method_Binding, new Guid[] { returnAttributeMethodId }); } List listTrueConditionsGuids = new List(); List listFalseConditionsGuids = new List(); if (tagTrueConditions != null) { for (int j = 0; j < tagTrueConditions.Elements.Count; j++) { MarkupTagElement tagInstanceReference = tagTrueConditions.Elements[j] as MarkupTagElement; if (tagInstanceReference == null) continue; if (tagInstanceReference.FullName != "instanceReference") continue; MarkupAttribute attInstanceId = tagInstanceReference.Attributes["instanceId"]; if (attInstanceId == null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "instance ID not specified for relationship target instance", "MCX0107", tag.ParentObjectModel.Accessor.GetFileName(), tagInstanceReference.Definition.LineNumber, tagInstanceReference.Definition.ColumnNumber); continue; } if (Guid.TryParse(attInstanceId.Value, out Guid instId)) { listTrueConditionsGuids.Add(instId); } } } if (tagFalseConditions != null) { for (int j = 0; j < tagFalseConditions.Elements.Count; j++) { MarkupTagElement tagInstanceReference = tagFalseConditions.Elements[j] as MarkupTagElement; if (tagInstanceReference == null) continue; if (tagInstanceReference.FullName != "instanceReference") continue; MarkupAttribute attInstanceId = tagInstanceReference.Attributes["instanceId"]; if (attInstanceId == null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "instance ID not specified for relationship target instance", "MCX0107", tag.ParentObjectModel.Accessor.GetFileName(), tagInstanceReference.Definition.LineNumber, tagInstanceReference.Definition.ColumnNumber); continue; } if (Guid.TryParse(attInstanceId.Value, out Guid instId)) { listFalseConditionsGuids.Add(instId); } } } ZqAssignRelationship(library, instCase.ID, KnownRelationshipGuids.Conditional_Method_Case__has_true_condition__Method_Binding, listTrueConditionsGuids.ToArray()); ZqAssignRelationship(library, instCase.ID, KnownRelationshipGuids.Conditional_Method_Case__has_false_condition__Method_Binding, listFalseConditionsGuids.ToArray()); ZqAssignRelationship(library, inst.ID, KnownRelationshipGuids.Conditional_Method__has__Conditional_Method_Case, new Guid[] { instCase.ID }); ZqAssignRelationship(library, instCase.ID, KnownRelationshipGuids.Conditional_Method_Case__for__Conditional_Method, new Guid[] { inst.ID }); } } break; } default: { Console.Error.WriteLine("unknown ZQ method type {0}; ignoring", attType.Value); break; } } if (inst != null) { if (attName != null) { ZqAssignAttribute(inst, global::Mocha.Core.KnownAttributeGuids.Text.Name, attName.Value); } if (attVerb != null) { ZqAssignAttribute(inst, global::Mocha.Core.KnownAttributeGuids.Text.Verb, attVerb.Value); } SetupInstanceWithXML(library, inst, tag); } } return inst; } private void ZqAssignAttribute(MochaInstance inst, Guid attributeInstanceId, object value) { inst.AttributeValues.Add(new MochaAttributeValue() { AttributeInstanceID = attributeInstanceId, Value = value }); } private MochaInstance ZqCompileRelationship(IMochaStore library, MarkupTagElement tag) { MarkupAttribute attID = tag.Attributes["id"]; Guid instanceId = new Guid(attID.Value); Console.Error.WriteLine("zq: compiling relationship {0}", instanceId); MochaInstance inst = ZqCreateInstance(library, instanceId); MarkupAttribute attSourceClassId = tag.Attributes["sourceClassId"]; MarkupAttribute attType = tag.Attributes["type"]; MarkupAttribute attDestinationClassId = tag.Attributes["destinationClassId"]; MarkupAttribute attSiblingRelationshipId = tag.Attributes["siblingRelationshipId"]; MarkupAttribute attSingular = tag.Attributes["singular"]; bool singular = false; if (attSingular != null) { if (!Boolean.TryParse(attSingular.Value, out singular)) { return null; } ZqAssignAttribute(inst, global::Mocha.Core.KnownAttributeGuids.Boolean.Singular, singular); } if (attType != null) { ZqAssignAttribute(inst, global::Mocha.Core.KnownAttributeGuids.Text.RelationshipType, attType.Value); } Guid sourceClassId, destinationClassId, siblingRelationshipId; if (attSourceClassId != null) { if (Guid.TryParse(attSourceClassId.Value, out sourceClassId)) { ZqAssignRelationship(library, instanceId, global::Mocha.Core.KnownRelationshipGuids.Relationship__has_source__Class, new Guid[] { sourceClassId }); } else { } } if (attDestinationClassId != null) { if (Guid.TryParse(attDestinationClassId.Value, out destinationClassId)) { ZqAssignRelationship(library, instanceId, global::Mocha.Core.KnownRelationshipGuids.Relationship__has_destination__Class, new Guid[] { destinationClassId }); } else { } } if (attSiblingRelationshipId != null) { if (Guid.TryParse(attSiblingRelationshipId.Value, out siblingRelationshipId)) { ZqAssignRelationship(library, instanceId, global::Mocha.Core.KnownRelationshipGuids.Relationship__has_sibling__Relationship, new Guid[] { siblingRelationshipId }); } else { } } library.Relationships.Add(new MochaRelationship() { SourceInstanceID = sourceClassId, RelationshipInstanceID = KnownRelationshipGuids.Class__has__Relationship, DestinationInstanceIDs = new List(new Guid[] { inst.ID }) }); SetParentClass(library, instanceId, global::Mocha.Core.KnownInstanceGuids.Classes.Relationship); return inst; } private MochaInstance ZqCompileClass(IMochaStore library, MarkupTagElement tag) { MarkupAttribute attID = tag.Attributes["id"]; Guid instanceId = new Guid(attID.Value); Console.Error.WriteLine("zq: compiling class {0}", instanceId); MochaInstance inst = ZqCreateInstance(library, instanceId); MarkupTagElement tagMethods = tag.Elements["methods"] as MarkupTagElement; if (tagMethods != null) { foreach (MarkupElement elMethod in tagMethods.Elements) { MochaInstance instMethod = ZqCompileMethod(library, elMethod as MarkupTagElement); if (instMethod != null) { ZqAssignRelationship(library, inst.ID, global::Mocha.Core.KnownRelationshipGuids.Class__has__Method, new Guid[] { instMethod.ID }); ZqAssignRelationship(library, instMethod.ID, global::Mocha.Core.KnownRelationshipGuids.Method__for__Class, new Guid[] { inst.ID }); } } } SetParentClass(library, instanceId, global::Mocha.Core.KnownInstanceGuids.Classes.Class); MarkupAttribute attSuperClassId = tag.Attributes["superClassId"]; if (attSuperClassId != null) { if (Guid.TryParse(tag.Attributes["superClassId"].Value, out Guid superClassId)) { SetSuperClass(library, instanceId, superClassId); } } else { SetSuperClass(library, instanceId, global::Mocha.Core.KnownInstanceGuids.Classes.Class); } SetOwner(library, inst.ID, global::Mocha.Core.KnownInstanceGuids.Users.XQEnvironments); SetSource(library, inst.ID, library.DefaultObjectSourceID); // global::Mocha.Core.KnownInstanceGuids.ObjectSources.System); SetupInstanceWithXML(library, inst, tag); return inst; } private MochaInstance ZqCreateInstance(IMochaStore library, Guid instanceId, Guid classInstanceId = default(Guid)) { MochaInstance inst = library.Instances[instanceId]; if (inst == null) { inst = new MochaInstance(); inst.ID = instanceId; library.Instances.Add(inst); } if (classInstanceId != default(Guid)) { SetParentClass(library, instanceId, classInstanceId); } return inst; } private MochaLibrary LoadLibrary(MochaClassLibraryObjectModel parent, MarkupTagElement tag) { if (tag == null) return null; if (tag.FullName != "library") return null; MarkupAttribute attGuid = tag.Attributes["id"]; if (attGuid == null) return null; Guid id = new Guid(attGuid.Value); MochaLibrary library = parent.Libraries[id]; if (library == null) { library = new MochaLibrary(); library.ID = id; } MarkupAttribute attDefaultObjectSourceId = tag.Attributes["defaultObjectSourceId"]; if (attDefaultObjectSourceId != null) { library.DefaultObjectSourceID = new Guid(attDefaultObjectSourceId.Value); } else { library.DefaultObjectSourceID = global::Mocha.Core.KnownInstanceGuids.ObjectSources.System; } MarkupTagElement tagMetadata = tag.Elements["metadata"] as MarkupTagElement; if (tagMetadata != null) { for (int i = 0; i < tagMetadata.Elements.Count; i++) { MarkupTagElement tagMetadataItem = tagMetadata.Elements[i] as MarkupTagElement; if (tagMetadataItem == null) continue; library.Metadata.Add(new MochaLibraryMetadata(tagMetadataItem.Name, tagMetadataItem.Value)); } } MarkupTagElement tagLibraryReferences = tag.Elements["libraryReferences"] as MarkupTagElement; if (tagLibraryReferences != null) { foreach (MarkupTagElement tagLibraryReference in tagLibraryReferences.Elements.OfType()) { MarkupAttribute attLibraryId = tagLibraryReference.Attributes["libraryId"]; if (attLibraryId == null) continue; library.LibraryReferences.Add(new Guid(attLibraryId.Value)); } } MarkupTagElement tagInstances = tag.Elements["instances"] as MarkupTagElement; if (tagInstances != null) { for (int i = 0; i < tagInstances.Elements.Count; i++) { MochaInstance inst = LoadInstance(library, tagInstances.Elements[i] as MarkupTagElement); if (inst == null) continue; library.Instances.Add(inst); } } return library; } private MochaInstance LoadInstance(IMochaStore library, MarkupTagElement tag) { if (tag == null) return null; MarkupAttribute attID = tag.Attributes["id"]; string strInstanceId = attID?.Value; if (strInstanceId == null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "Missing GUID for instance declaration", "MCX0101", tag.ParentObjectModel.Accessor.GetFileName(), tag.Definition.LineNumber, tag.Definition.ColumnNumber, "Instance Loader"); return null; } Guid instanceId; if (!Guid.TryParse(strInstanceId, out instanceId)) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, String.Format("Invalid GUID for instance declaration '{0}'", strInstanceId), "MCX0101", tag.ParentObjectModel.Accessor.GetFileName(), tag.Definition.LineNumber, tag.Definition.ColumnNumber, "Instance Loader"); return null; } MochaInstance inst = library.Instances[instanceId]; if (tag.FullName == "class") { inst = ZqCompileClass(library, tag); return inst; } else if (tag.FullName == "method") { inst = ZqCompileMethod(library, tag); return inst; } else if (tag.FullName == "relationship") { inst = ZqCompileRelationship(library, tag); return inst; } else if (tag.FullName == "instanceSet") { inst = ZqCompileInstanceSet(library, tag); return inst; } if (inst == null) { inst = new MochaInstance(); inst.ID = instanceId; } if (tag.FullName != "instance") { Console.Error.WriteLine("unhandled preprocess instance tag type '{0}'", tag.FullName); return null; } MarkupAttribute attIndex = tag.Attributes["index"]; int? index = null; if (attIndex != null) { if (Int32.TryParse(attIndex.Value, out int index2)) index = index2; } MarkupAttribute attClassInstanceId = tag.Attributes["classInstanceId"]; MarkupAttribute attSuperClassId = tag.Attributes["superClassId"]; inst.Index = index; if (inst.Index != null) { SetIndex(library, inst); } if (attClassInstanceId != null) { if (Guid.TryParse(attClassInstanceId.Value, out Guid classInstanceId)) { SetParentClass(library, inst.ID, classInstanceId); } else { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, String.Format("Bad GUID for classInstanceId: {0}", attClassInstanceId.Value), "MCX0102", tag.ParentObjectModel.Accessor.GetFileName(), attClassInstanceId.Definition.LineNumber, attClassInstanceId.Definition.ColumnNumber); } } if (attSuperClassId != null) { if (Guid.TryParse(attSuperClassId.Value, out Guid superClassId)) { Console.Error.WriteLine("creating class {0} inherits {1}", instanceId, superClassId); SetClass(library, inst.ID); SetOwner(library, inst.ID, global::Mocha.Core.KnownInstanceGuids.Users.XQEnvironments); SetSource(library, inst.ID, library.DefaultObjectSourceID); // global::Mocha.Core.KnownInstanceGuids.ObjectSources.System); SetSuperClass(library, inst.ID, superClassId); } else { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, String.Format("Bad GUID for superClassId '{0}'", attSuperClassId.Value), "MCX0902", tag.ParentObjectModel.Accessor.GetFileName(), attSuperClassId.Definition.LineNumber, attSuperClassId.Definition.ColumnNumber); } } if (attClassInstanceId == null && attSuperClassId == null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Warning, String.Format("neither classInstanceId nor superClassId specified for instance: {0}", inst.ID), "MCX0302", tag.ParentObjectModel.Accessor.GetFileName(), tag.Definition.LineNumber, tag.Definition.ColumnNumber); } SetupInstanceWithXML(library, inst, tag); return inst; } private MochaInstance ZqCompileInstanceSet(IMochaStore library, MarkupTagElement tag) { MarkupAttribute attID = tag.Attributes["id"]; Guid instanceId = new Guid(attID.Value); MochaInstance instSet = ZqCreateInstance(library, instanceId, KnownInstanceGuids.Classes.InstanceSet); MarkupTagElement tagInstances = (tag.Elements["instances"] as MarkupTagElement); if (tagInstances != null) { MochaRelationship relInstanceSetHasInstance = new MochaRelationship() { SourceInstanceID = instSet.ID, RelationshipInstanceID = KnownRelationshipGuids.Instance_Set__has__Instance }; foreach (MarkupElement el in tagInstances.Elements) { MarkupTagElement tag1 = (el as MarkupTagElement); if (tag1 == null) continue; if (tag1.FullName != "instanceReference") continue; MarkupAttribute attInstRefId = tag1.Attributes["instanceId"]; if (attInstRefId == null) continue; if (Guid.TryParse(attInstRefId.Value, out Guid instRefId)) { relInstanceSetHasInstance.DestinationInstanceIDs.Add(instRefId); } } library.Relationships.Add(relInstanceSetHasInstance); } return instSet; } public bool WriteDebugInfo { get; set; } = true; private void SetupInstanceWithXML(IMochaStore library, MochaInstance inst, MarkupTagElement tag) { if (WriteDebugInfo) { SetupInstanceWithXML__DebugInfo(library, inst, tag); } MarkupTagElement tagAttributeValues = tag.Elements["attributeValues"] as MarkupTagElement; if (tagAttributeValues != null) { for (int i = 0; i < tagAttributeValues.Elements.Count; i++) { MochaAttributeValue attv = LoadAttributeValue(tagAttributeValues.Elements[i] as MarkupTagElement); if (attv == null) continue; inst.AttributeValues.Add(attv); } } MarkupTagElement tagRelationships = tag.Elements["relationships"] as MarkupTagElement; if (tagRelationships != null && tagRelationships.Elements.Count > 0) { for (int i = 0; i < tagRelationships.Elements.Count; i++) { MarkupTagElement tagRelationship = tagRelationships.Elements[i] as MarkupTagElement; if (tagRelationship == null) continue; if (tagRelationship.FullName != "relationship") continue; MarkupAttribute attRelationshipInstanceId = tagRelationship.Attributes["relationshipInstanceId"]; string relationshipInstanceId = attRelationshipInstanceId?.Value; if (String.IsNullOrEmpty(relationshipInstanceId)) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "relationshipInstanceId not specified for relationship", "MCX0902", tagRelationship.ParentObjectModel.Accessor.GetFileName(), tagRelationship.Definition.LineNumber, tagRelationship.Definition.ColumnNumber); continue; } MochaRelationship rel = new MochaRelationship(); rel.SourceInstanceID = inst.ID; if (Guid.TryParse(attRelationshipInstanceId.Value, out Guid id)) { rel.RelationshipInstanceID = id; } else { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, String.Format("invalid GUID for relationship with instanceID '{0}'", attRelationshipInstanceId.Value), "MCX0903", tagRelationship.ParentObjectModel.Accessor.GetFileName(), tagRelationship.Definition.LineNumber, tagRelationship.Definition.ColumnNumber); } MarkupTagElement tagTargetInstances = tagRelationship.Elements["targetInstances"] as MarkupTagElement; if (tagTargetInstances != null) { MarkupTagElement[] tagTargetInstancesElems = tagTargetInstances.GetElementsByTagName("instanceReference"); if (tagTargetInstancesElems.Length == 0) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Warning, "empty targetInstances for relationship", "MCX0901", tag.ParentObjectModel.Accessor.GetFileName(), tagTargetInstances.Definition.LineNumber, tagTargetInstances.Definition.ColumnNumber); } for (int j = 0; j < tagTargetInstancesElems.Length; j++) { MarkupTagElement tagInstanceReference = tagTargetInstancesElems[j] as MarkupTagElement; if (tagInstanceReference == null) continue; if (tagInstanceReference.FullName != "instanceReference") continue; MarkupAttribute attInstanceId = tagInstanceReference.Attributes["instanceId"]; if (attInstanceId == null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "instance ID not specified for relationship target instance", "MCX0107", tag.ParentObjectModel.Accessor.GetFileName(), tagInstanceReference.Definition.LineNumber, tagInstanceReference.Definition.ColumnNumber); continue; } global::Mocha.Core.RelationshipKey thisRelKey = new global::Mocha.Core.RelationshipKey(rel.RelationshipInstanceID, global::Mocha.Core.KnownRelationshipGuids.Relationship__has_sibling__Relationship); MochaRelationship siblingRelationship = library.Relationships[thisRelKey]; // FindRelationship(library, thisRelKey); // FIXME: in order to link sibling relationships, we must be able to read all referenced libraries in at once // this might be a job for the compiler... if (Guid.TryParse(attInstanceId.Value, out Guid instId)) { if (siblingRelationship != null) { global::Mocha.Core.RelationshipKey keysib = new global::Mocha.Core.RelationshipKey(instId, siblingRelationship.DestinationInstanceIDs[0]); MochaRelationship relsib = library.Relationships[keysib]; if (relsib == null) { relsib = new MochaRelationship(); relsib.SourceInstanceID = keysib.SourceInstanceID; relsib.RelationshipInstanceID = keysib.RelationshipID; relsib.DestinationInstanceIDs.Add(inst.ID); library.Relationships.Add(relsib); ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Message, String.Format("sibling relationship found empty {0} : {1}", siblingRelationship.SourceInstanceID, siblingRelationship.DestinationInstanceIDs[0]), "MCX0712", tagInstanceReference.ParentObjectModel.Accessor.GetFileName(), tagInstanceReference.Definition.LineNumber, tagInstanceReference.Definition.ColumnNumber); } else { Console.Error.WriteLine("sibling relationship found with targets {0} : {1} ", siblingRelationship.SourceInstanceID, siblingRelationship.DestinationInstanceIDs[0]); } } else { Console.Error.WriteLine("no sibling relationship found for relationship {0}", rel.RelationshipInstanceID.ToString("B")); } rel.DestinationInstanceIDs.Add(instId); } else { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, String.Format("Bad GUID for instanceReference: {0}", attInstanceId.Value), "MCX0102", tag.ParentObjectModel.Accessor.GetFileName(), attInstanceId.Definition.LineNumber, attInstanceId.Definition.ColumnNumber); } } } else { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Warning, "missing targetInstances for relationship", "MCX0903", tagRelationship.ParentObjectModel.Accessor.GetFileName(), tagRelationship.Definition.LineNumber, tagRelationship.Definition.ColumnNumber); } library.Relationships.Add(rel); } } else if (tagRelationships != null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Warning, "no 'relationship' tags specified in 'relationships' element", "MCX0909", tagRelationships.ParentObjectModel.Accessor.GetFileName(), tagRelationships.Definition.LineNumber, tagRelationships.Definition.ColumnNumber); } SetupInstanceWithXML__Translations(library, tag, inst); SetupInstanceWithXML__IntegrationIDs(library, tag, inst); if (tagAttributeValues == null && tagRelationships == null && (tag.Elements["translations"] as MarkupTagElement) == null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Warning, String.Format("no attributes, relationships, or translations specified for instance '{0}'", inst.ID), "MCX0301", tag.ParentObjectModel.Accessor.GetFileName(), tag.Definition.LineNumber, tag.Definition.ColumnNumber); } } private void SetupInstanceWithXML__DebugInfo(IMochaStore library, MochaInstance inst, MarkupTagElement tag) { Guid guidDebugDefinition = Guid.NewGuid(); MochaInstance instDebugDefinition = ZqCreateInstance(library, guidDebugDefinition, KnownInstanceGuids.Classes.InstanceDefinition); ZqAssignAttribute(instDebugDefinition, KnownAttributeGuids.Text.DebugDefinitionFileName, tag.ParentObjectModel.Accessor.GetFileName()); ZqAssignAttribute(instDebugDefinition, KnownAttributeGuids.Numeric.DebugDefinitionLineNumber, tag.Definition.LineNumber); ZqAssignAttribute(instDebugDefinition, KnownAttributeGuids.Numeric.DebugDefinitionColumnNumber, tag.Definition.ColumnNumber); ZqAssignRelationship(library, inst.ID, KnownRelationshipGuids.Instance__has__Instance_Definition, new Guid[] { instDebugDefinition.ID }); } private void SetupInstanceWithXML__Translations(IMochaStore library, MarkupTagElement tag, MochaInstance inst) { MarkupTagElement tagTranslations = tag.Elements["translations"] as MarkupTagElement; if (tagTranslations != null) { for (int i = 0; i < tagTranslations.Elements.Count; i++) { MarkupTagElement tagTranslation = (tagTranslations.Elements[i] as MarkupTagElement); if (tagTranslation == null) continue; if (tagTranslation.FullName != "translation") continue; MarkupAttribute attRelationshipId = tagTranslation.Attributes["relationshipInstanceId"]; if (attRelationshipId == null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "missing 'relationshipInstanceId' attribute for 'translation' element", "MCX0701", tagTranslation.ParentObjectModel.Accessor.GetFileName(), tagTranslation.Definition.LineNumber, tagTranslation.Definition.ColumnNumber); continue; } MarkupTagElement tagTranslationValues = (tagTranslation.Elements["translationValues"] as MarkupTagElement); if (tagTranslationValues == null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "missing 'translationValues' subelement for 'translation' element", "MCX0702", tagTranslation.ParentObjectModel.Accessor.GetFileName(), tagTranslation.Definition.LineNumber, tagTranslation.Definition.ColumnNumber); continue; } Guid relationshipInstanceId; if (!Guid.TryParse(attRelationshipId.Value, out relationshipInstanceId)) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "invalid 'relationshipInstanceId' attribute for 'translation' element", "MCX0703", tagTranslation.ParentObjectModel.Accessor.GetFileName(), attRelationshipId.Definition.LineNumber, attRelationshipId.Definition.ColumnNumber); continue; } MochaInstance instTTC = new MochaInstance(); instTTC.ID = Guid.NewGuid(); SetParentClass(library, instTTC.ID, global::Mocha.Core.KnownInstanceGuids.Classes.Translation); MochaRelationship relInstance__has__Translatable_Text_Constant = new MochaRelationship(); relInstance__has__Translatable_Text_Constant.SourceInstanceID = inst.ID; relInstance__has__Translatable_Text_Constant.RelationshipInstanceID = relationshipInstanceId; relInstance__has__Translatable_Text_Constant.DestinationInstanceIDs.Add(instTTC.ID); library.Relationships.Add(relInstance__has__Translatable_Text_Constant); MochaRelationship relTranslatable_Text_Constant__has__Translatable_Text_Constant_Value = new MochaRelationship(); relTranslatable_Text_Constant__has__Translatable_Text_Constant_Value.SourceInstanceID = instTTC.ID; relTranslatable_Text_Constant__has__Translatable_Text_Constant_Value.RelationshipInstanceID = global::Mocha.Core.KnownRelationshipGuids.Translation__has__Translation_Value; if (tagTranslationValues.Elements.Count == 0) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Warning, "no translation values defined for translation element", "MCX0702", tagTranslationValues.ParentObjectModel.Accessor.GetFileName(), tagTranslationValues.Definition.LineNumber, tagTranslationValues.Definition.ColumnNumber); } for (int j = 0; j < tagTranslationValues.Elements.Count; j++) { MarkupTagElement tagTranslationValue = (tagTranslationValues.Elements[j] as MarkupTagElement); if (tagTranslationValue?.FullName != "translationValue") { continue; } MarkupAttribute attLanguageInstanceID = tagTranslationValue.Attributes["languageInstanceId"]; MarkupAttribute attValue = tagTranslationValue.Attributes["value"]; if (attLanguageInstanceID == null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "missing 'languageInstanceId' attribute for translation value", "MCX0702", tagTranslationValue.ParentObjectModel.Accessor.GetFileName(), tagTranslationValue.Definition.LineNumber, tagTranslationValue.Definition.ColumnNumber); continue; } if (attValue == null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "missing 'value' attribute for translation value", "MCX0702", tagTranslationValue.ParentObjectModel.Accessor.GetFileName(), tagTranslationValue.Definition.LineNumber, tagTranslationValue.Definition.ColumnNumber); continue; } Guid languageInstanceId; if (!Guid.TryParse(attLanguageInstanceID?.Value, out languageInstanceId)) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "invalid language instance ID for translation value", "MCX0705", tagTranslationValue.ParentObjectModel.Accessor.GetFileName(), tagTranslationValue.Definition.LineNumber, tagTranslationValue.Definition.ColumnNumber); continue; } // create a new TTCValue instance MochaInstance instTranslationValue = new MochaInstance(); instTranslationValue.ID = Guid.NewGuid(); SetParentClass(library, instTranslationValue.ID, global::Mocha.Core.KnownInstanceGuids.Classes.TranslationValue); // associate the TTCValue with the Language MochaRelationship relTranslatable_Text_Constant_Value__has__Language = new MochaRelationship(); relTranslatable_Text_Constant_Value__has__Language.SourceInstanceID = instTranslationValue.ID; relTranslatable_Text_Constant_Value__has__Language.RelationshipInstanceID = global::Mocha.Core.KnownRelationshipGuids.Translation_Value__has__Language; relTranslatable_Text_Constant_Value__has__Language.DestinationInstanceIDs.Add(new Guid(attLanguageInstanceID.Value)); library.Relationships.Add(relTranslatable_Text_Constant_Value__has__Language); // set the Value attribute of the TTCValue MochaAttributeValue mavValue = new MochaAttributeValue(); mavValue.AttributeInstanceID = global::Mocha.Core.KnownAttributeGuids.Text.Value; mavValue.Value = attValue.Value; instTranslationValue.AttributeValues.Add(mavValue); // add the TTCValue to the instance list library.Instances.Add(instTranslationValue); // add the TTCValue to the TTC.has TTC Value relationship relTranslatable_Text_Constant__has__Translatable_Text_Constant_Value.DestinationInstanceIDs.Add(instTranslationValue.ID); } library.Relationships.Add(relTranslatable_Text_Constant__has__Translatable_Text_Constant_Value); library.Instances.Add(instTTC); } } } private void SetupInstanceWithXML__IntegrationIDs(IMochaStore library, MarkupTagElement tag, MochaInstance inst) { MarkupTagElement tagIntegrationIDs = (tag.Elements["integrationIds"] as MarkupTagElement); if (tagIntegrationIDs != null) { IEnumerable tagIntegrationIDsElems = tagIntegrationIDs.Elements.OfType(); if (!tagIntegrationIDsElems.Any()) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Warning, String.Format("no 'integrationId' elements specified in 'integrationIds' for instance '{0}'", inst.ID.ToString("B")), "MCX0706", tagIntegrationIDs.ParentObjectModel.Accessor.GetFileName(), tagIntegrationIDs.Definition.LineNumber, tagIntegrationIDs.Definition.ColumnNumber); } else { foreach (MarkupTagElement tagIntegrationID in tagIntegrationIDsElems) { Guid id, typeId; MarkupAttribute attValue = tagIntegrationID.Attributes["value"]; if (attValue == null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "no 'value' attribute specified for integrationId", "MCX0713", tagIntegrationID.ParentObjectModel.Accessor.GetFileName(), tagIntegrationID.Definition.LineNumber, tagIntegrationID.Definition.ColumnNumber); continue; } MarkupAttribute attIntegrationIDTypeID = tagIntegrationID.Attributes["typeId"]; if (!Guid.TryParse(attIntegrationIDTypeID?.Value, out typeId)) { if (attIntegrationIDTypeID != null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, String.Format("bad GUID '{0}' for integrationId 'typeId' attribute", attIntegrationIDTypeID.Value), "MCX0712", tag.ParentObjectModel.Accessor.GetFileName(), attIntegrationIDTypeID.Definition.LineNumber, attIntegrationIDTypeID.Definition.ColumnNumber); continue; } typeId = Guid.NewGuid(); } MarkupAttribute attIntegrationIDID = tagIntegrationID.Attributes["id"]; if (!Guid.TryParse(attIntegrationIDID?.Value, out id)) { if (attIntegrationIDID != null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Warning, String.Format("bad GUID '{0}' for integrationId 'id' attribute", attIntegrationIDID.Value), "MCX0712", tag.ParentObjectModel.Accessor.GetFileName(), attIntegrationIDID.Definition.LineNumber, attIntegrationIDID.Definition.ColumnNumber); } id = Guid.NewGuid(); } MochaInstance instIntegrationID = ZqCreateInstance(library, id, global::Mocha.Core.KnownInstanceGuids.Classes.IntegrationID); ZqAssignAttribute(instIntegrationID, global::Mocha.Core.KnownAttributeGuids.Text.Value, attValue?.Value); ZqAssignRelationship(library, id, global::Mocha.Core.KnownRelationshipGuids.Integration_ID__has__Integration_ID_Usage, new Guid[] { typeId }); ZqAssignRelationship(library, typeId, global::Mocha.Core.KnownRelationshipGuids.Integration_ID_Usage__for__Integration_ID, new Guid[] { id }); MarkupAttribute attSingular = tagIntegrationID.Attributes["singular"]; if (attSingular != null) { ZqAssignAttribute(instIntegrationID, global::Mocha.Core.KnownAttributeGuids.Text.Value, Boolean.Parse(attSingular?.Value)); } } } } } private void SetIndex(IMochaStore library, MochaInstance instance) { if (instance.Index == null) return; MochaAttributeValue mav = new MochaAttributeValue(); mav.AttributeInstanceID = global::Mocha.Core.KnownAttributeGuids.Numeric.Index; mav.Value = (decimal) instance.Index.Value; instance.AttributeValues.Add(mav); } private void SetSource(IMochaStore library, Guid instanceId, Guid sourceTypeId) { ZqAssignRelationship(library, instanceId, global::Mocha.Core.KnownRelationshipGuids.Class__has__Object_Source, new Guid[] { sourceTypeId }); ZqAssignRelationship(library, sourceTypeId, global::Mocha.Core.KnownRelationshipGuids.Object_Source__for__Class, new Guid[] { instanceId }); } private void SetOwner(IMochaStore library, Guid instanceId, Guid ownerId) { ZqAssignRelationship(library, instanceId, global::Mocha.Core.KnownRelationshipGuids.Class__has_owner__User, new Guid[] { ownerId }); ZqAssignRelationship(library, ownerId, global::Mocha.Core.KnownRelationshipGuids.User__owner_for__Class, new Guid[] { instanceId }); } private void SetClass(IMochaStore library, Guid id) { SetParentClass(library, id, global::Mocha.Core.KnownInstanceGuids.Classes.Class); } private void SetSuperClass(IMochaStore library, Guid sourceInstanceID, Guid parentClassID) { ZqAssignRelationship(library, sourceInstanceID, global::Mocha.Core.KnownRelationshipGuids.Class__has_super__Class, new Guid[] { parentClassID }); ZqAssignRelationship(library, parentClassID, global::Mocha.Core.KnownRelationshipGuids.Class__has_sub__Class, new Guid[] { sourceInstanceID }); } private void SetParentClass(IMochaStore library, Guid sourceInstanceID, Guid parentClassID) { ZqAssignRelationship(library, sourceInstanceID, global::Mocha.Core.KnownRelationshipGuids.Instance__for__Class, new Guid[] { parentClassID }); ZqAssignRelationship(library, parentClassID, global::Mocha.Core.KnownRelationshipGuids.Class__has__Instance, new Guid[] { sourceInstanceID }); } private void ZqAssignRelationship(IMochaStore library, Guid sourceInstanceID, Guid relationshipInstanceID, Guid[] destinationInstanceIds) { MochaRelationship rel = new MochaRelationship(); rel.SourceInstanceID = sourceInstanceID; for (int i = 0; i < destinationInstanceIds.Length; i++) { rel.DestinationInstanceIDs.Add(destinationInstanceIds[i]); } if (!library.Instances.Contains(relationshipInstanceID)) { // FIXME: this doesn't work because we don't know exactly what libraries we've referenced // Console.Error.WriteLine("zq: assignRelationship: relationship not found {0}", relationshipInstanceID.ToString("B")); } rel.RelationshipInstanceID = relationshipInstanceID; library.Relationships.Add(rel); } private MochaAttributeValue LoadAttributeValue(MarkupTagElement tag) { if (tag == null) return null; if (tag.FullName != "attributeValue") return null; MarkupAttribute attInstanceID = tag.Attributes["attributeInstanceId"]; MarkupAttribute attValue = tag.Attributes["value"]; if (attInstanceID == null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "attributeInstanceId not specified for attributeValue", "MCX0302", tag.ParentObjectModel.Accessor.GetFileName(), tag.Definition.LineNumber, tag.Definition.ColumnNumber); return null; } Guid instanceId; if (!Guid.TryParse(attInstanceID.Value, out instanceId)) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, String.Format("invalid GUID for attributeInstanceId: '{0}'", attInstanceID.Value), "MCX0302", tag.ParentObjectModel.Accessor.GetFileName(), tag.Definition.LineNumber, tag.Definition.ColumnNumber); return null; } if (attValue == null) { ConsoleExtensions.LogMSBuildMessage(MessageSeverity.Error, "value not specified for attributeValue", "MCX0303", tag.ParentObjectModel.Accessor.GetFileName(), tag.Definition.LineNumber, tag.Definition.ColumnNumber); return null; } MochaAttributeValue item = new MochaAttributeValue(); item.AttributeInstanceID = instanceId; item.Value = attValue.Value; return item; } protected override void BeforeSaveInternal(Stack objectModels) { base.BeforeSaveInternal(objectModels); MochaClassLibraryObjectModel mcl = (objectModels.Pop() as MochaClassLibraryObjectModel); MarkupObjectModel mom = new MarkupObjectModel(); objectModels.Push(mom); } } }