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 || attValue == null) { return(null); } MochaAttributeValue item = new MochaAttributeValue(); item.AttributeInstanceID = new Guid(attInstanceID.Value); item.Value = attValue.Value; return(item); }
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 = instance.Index.Value; instance.AttributeValues.Add(mav); }
private MochaInstance LoadInstance(IMochaStore library, MarkupTagElement tag) { if (tag == null) { return(null); } if (tag.FullName != "instance") { return(null); } MarkupAttribute attID = tag.Attributes["id"]; if (attID == null) { 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"]; Guid instanceId = new Guid(attID.Value); MochaInstance inst = library.Instances[instanceId]; if (inst == null) { inst = new MochaInstance(); inst.ID = instanceId; } 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 { Console.Error.WriteLine("bad guid for classInstanceId: {0}", attClassInstanceId.Value); } } if (attSuperClassId != null) { if (Guid.TryParse(attSuperClassId.Value, out Guid 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 { Console.Error.WriteLine("bad guid for superClassId: {0}", attSuperClassId.Value); } } 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) { 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"]; if (attRelationshipInstanceId == null) { continue; } if (String.IsNullOrEmpty(attRelationshipInstanceId.Value)) { Console.Error.WriteLine("relationshipInstanceId not specified for relationship"); continue; } MochaRelationship rel = new MochaRelationship(); rel.SourceInstanceID = inst.ID; if (Guid.TryParse(attRelationshipInstanceId.Value, out Guid id)) { rel.RelationshipInstanceID = id; } else { Console.Error.WriteLine("bad guid for relationship: relationshipInstanceId='{0}'", attRelationshipInstanceId.Value); } MarkupTagElement tagTargetInstances = tagRelationship.Elements["targetInstances"] as MarkupTagElement; if (tagTargetInstances != null) { for (int j = 0; j < tagTargetInstances.Elements.Count; j++) { MarkupTagElement tagInstanceReference = tagTargetInstances.Elements[j] as MarkupTagElement; if (tagInstanceReference == null) { continue; } if (tagInstanceReference.FullName != "instanceReference") { continue; } MarkupAttribute attInstanceId = tagInstanceReference.Attributes["instanceId"]; if (attInstanceId == null) { continue; } if (Guid.TryParse(attInstanceId.Value, out Guid instId)) { rel.DestinationInstanceIDs.Add(instId); } else { Console.Error.WriteLine("bad guid for instanceReference: instanceId='{0}'", attInstanceId.Value); } } } library.Relationships.Add(rel); } } 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) { continue; } MarkupTagElement tagTranslationValues = (tagTranslation.Elements["translationValues"] as MarkupTagElement); if (tagTranslationValues == null) { 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 = new Guid(attRelationshipId.Value); 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.Translatable_Text_Constant__has__Translatable_Text_Constant_Value; for (int j = 0; j < tagTranslationValues.Elements.Count; j++) { MarkupTagElement tagTranslationValue = (tagTranslationValues.Elements[j] as MarkupTagElement); if (tagTranslationValue == null) { continue; } if (tagTranslationValue.FullName != "translationValue") { continue; } MarkupAttribute attLanguageInstanceID = tagTranslationValue.Attributes["languageInstanceId"]; MarkupAttribute attValue = tagTranslationValue.Attributes["value"]; if (attLanguageInstanceID == null || attValue == null) { continue; } // create a new TTCValue instance MochaInstance instTranslationValue = new MochaInstance(); instTranslationValue.ID = Guid.NewGuid(); SetParentClass(library, instTranslationValue.ID, global::Mocha.Core.KnownInstanceGuids.Classes.TranslatableTextConstantValue); // 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.Translatable_Text_Constant_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); } } return(inst); }
protected override void AfterLoadInternal(Stack <ObjectModel> objectModels) { base.AfterLoadInternal(objectModels); if (objectModels.Count < 2) { throw new ObjectModelNotSupportedException("must have a FileSystemObjectModel and a MochaClassLibraryObjectModel in the stack"); } FileSystemObjectModel fsom = (objectModels.Pop() as FileSystemObjectModel); if (fsom == null) { throw new ObjectModelNotSupportedException(); } ObjectModel om = objectModels.Pop(); MochaSnapshotObjectModel mcx = (om as MochaSnapshotObjectModel); MochaClassLibraryObjectModel mcl = (om as MochaClassLibraryObjectModel); if (mcl == null && mcx == null) { throw new ObjectModelNotSupportedException(); } List <Guid> _instanceGuids = new List <Guid>(); List <string> _stringTable = new List <string>(); LIBRARY_INFO[] library_info = null; // COMMON TABLES #region Guid Table { File fGlobalIdentifiers = fsom.FindFile("GlobalIdentifiers"); using (MemoryAccessor ma = new MemoryAccessor(fGlobalIdentifiers.GetData())) { int instanceCount = ma.Reader.ReadInt32(); for (int i = 0; i < instanceCount; i++) { _instanceGuids.Add(ma.Reader.ReadGuid()); } } } #endregion #region String Table { File f = fsom.FindFile("StringTable"); using (MemoryAccessor ma = new MemoryAccessor(f.GetData())) { int stringTableCount = ma.Reader.ReadInt32(); for (int i = 0; i < stringTableCount; i++) { string value = ma.Reader.ReadNullTerminatedString(); _stringTable.Add(value); } } } #endregion // MCL-SPECIFIC #region Libraries File fLibraries = fsom.FindFile("Libraries"); if (mcl != null && fLibraries != null) { using (MemoryAccessor ma = new MemoryAccessor(fLibraries.GetData())) { int libraryCount = ma.Reader.ReadInt32(); library_info = new LIBRARY_INFO[libraryCount]; for (int i = 0; i < libraryCount; i++) { MochaLibrary library = new MochaLibrary(); library.ID = ma.Reader.ReadGuid(); library_info[i].instanceCount = ma.Reader.ReadInt32(); // library_info[i].attributeValueCount = ma.Reader.ReadInt32(); library_info[i].relationshipCount = ma.Reader.ReadInt32(); mcl.Libraries.Add(library); } } } else { Console.Error.WriteLine("mocha: mcl: error: ignoring 'Libraries' section found in non-mcl file"); } #endregion INSTANCE_INFO[] instance_info = null; #region Instances File fInstances = fsom.FindFile("Instances"); if (mcl != null && fInstances != null) { using (MemoryAccessor ma = new MemoryAccessor(fInstances.GetData())) { for (int i = 0; i < mcl.Libraries.Count; i++) { int instanceCount = ma.Reader.ReadInt32(); instance_info = new INSTANCE_INFO[instanceCount]; for (int j = 0; j < instanceCount; j++) { instance_info[j].instanceIndex = ma.Reader.ReadInt32(); instance_info[j].attributeValueCount = ma.Reader.ReadInt32(); MochaInstanceFlags flags = (MochaInstanceFlags)ma.Reader.ReadInt32(); int?index = null; if ((flags & MochaInstanceFlags.HasIndex) == MochaInstanceFlags.HasIndex) { index = ma.Reader.ReadInt32(); } MochaInstance inst = new MochaInstance(); inst.ID = _instanceGuids[instance_info[j].instanceIndex]; inst.Index = index; mcl.Libraries[i].Instances.Add(inst); } } } } else { Console.Error.WriteLine("mocha: mcl: error: ignoring 'Instances' section found in non-mcl file"); } #endregion #region Attributes File fAttributes = fsom.FindFile("Attributes"); if (mcl != null && fAttributes != null) { using (MemoryAccessor ma = new MemoryAccessor(fAttributes.GetData())) { for (int i = 0; i < mcl.Libraries.Count; i++) { for (int j = 0; j < mcl.Libraries[i].Instances.Count; j++) { for (int k = 0; k < instance_info[j].attributeValueCount; k++) { int attributeInstanceIndex = ma.Reader.ReadInt32(); MochaAttributeValue val = new MochaAttributeValue(); val.AttributeInstanceID = _instanceGuids[attributeInstanceIndex]; MochaAttributeType attributeType = (MochaAttributeType)ma.Reader.ReadInt32(); switch (attributeType) { case MochaAttributeType.None: break; case MochaAttributeType.Text: { int stringTableIndex = ma.Reader.ReadInt32(); string value = _stringTable[stringTableIndex]; val.Value = value; break; } case MochaAttributeType.Boolean: { bool value = ma.Reader.ReadBoolean(); val.Value = value; break; } case MochaAttributeType.Date: { DateTime value = ma.Reader.ReadDateTime(); val.Value = value; break; } case MochaAttributeType.Unknown: { break; } } mcl.Libraries[i].Instances[j].AttributeValues.Add(val); } } } } } else { Console.Error.WriteLine("mocha: mcl: error: ignoring 'Attributes' section found in non-mcl file"); } #endregion #region Relationships File fRelationships = fsom.FindFile("Relationships"); if (mcl != null && fRelationships != null) { using (MemoryAccessor ma = new MemoryAccessor(fRelationships.GetData())) { for (int i = 0; i < mcl.Libraries.Count; i++) { for (int j = 0; j < library_info[i].relationshipCount; j++) { int relationshipIndex = ma.Reader.ReadInt32(); int sourceInstanceIndex = ma.Reader.ReadInt32(); MochaRelationship rel = new MochaRelationship(); rel.RelationshipInstanceID = _instanceGuids[relationshipIndex]; rel.SourceInstanceID = _instanceGuids[sourceInstanceIndex]; int targetInstanceCount = ma.Reader.ReadInt32(); for (int k = 0; k < targetInstanceCount; k++) { int instanceIndex = ma.Reader.ReadInt32(); rel.DestinationInstanceIDs.Add(_instanceGuids[instanceIndex]); } mcl.Libraries[i].Relationships.Add(rel); } } } } else { Console.Error.WriteLine("mocha: mcl: error: ignoring 'Relationships' section found in non-mcl file"); } #endregion #region Tenants File fTenants = fsom.FindFile("Tenants"); if (mcl != null && fTenants != null) { using (MemoryAccessor ma = new MemoryAccessor(fTenants.GetData())) { int tenantCount = ma.Reader.ReadInt32(); for (int i = 0; i < tenantCount; i++) { int instanceIndex = ma.Reader.ReadInt32(); Guid instanceGuid = _instanceGuids[instanceIndex]; int tenantNameIndex = ma.Reader.ReadInt32(); string tenantName = _stringTable[tenantNameIndex]; MochaTenant tenant = new MochaTenant(); tenant.ID = instanceGuid; tenant.Name = tenantName; int libraryReferenceCount = ma.Reader.ReadInt32(); for (int j = 0; j < libraryReferenceCount; j++) { int libraryIndex = ma.Reader.ReadInt32(); Guid libraryID = _instanceGuids[libraryIndex]; tenant.LibraryReferences.Add(new MochaLibraryReference(libraryID)); } int instanceCount = ma.Reader.ReadInt32(); for (int j = 0; j < instanceCount; j++) { int instanceIndex2 = ma.Reader.ReadInt32(); MochaInstance inst = new MochaInstance(); inst.ID = _instanceGuids[instanceIndex2]; tenant.Instances.Add(inst); } int relationshipCount = ma.Reader.ReadInt32(); for (int j = 0; j < relationshipCount; j++) { int sourceInex = ma.Reader.ReadInt32(); Guid ssource = _instanceGuids[sourceInex]; int relationshipInex = ma.Reader.ReadInt32(); Guid relati = _instanceGuids[relationshipInex]; MochaRelationship rel = new MochaRelationship(); rel.SourceInstanceID = ssource; rel.RelationshipInstanceID = relati; int count = ma.Reader.ReadInt32(); for (int k = 0; k < count; k++) { int targetIndex = ma.Reader.ReadInt32(); Guid targ = _instanceGuids[targetIndex]; rel.DestinationInstanceIDs.Add(targ); } tenant.Relationships.Add(rel); } mcl.Tenants.Add(tenant); } ma.Close(); fTenants.SetData(ma.ToArray()); } } else { Console.Error.WriteLine("mocha: mcl: error: ignoring 'Tenants' section found in non-mcl file"); } #endregion #region Journal // journal is present in MCX / MCD (application, data files) // is an opcode based format // eg. 0x01 = create instance, 0x02 = delete instance // 0x04 = set attribute value, 0x05 = delete attribute value // 0x08 = create relationship, 0x09 = remove relationship File fJournal = fsom.FindFile("Journal"); if (mcx != null && fJournal != null) { using (MemoryAccessor ma = new MemoryAccessor(fJournal.GetData())) { MochaSnapshotTransaction currentTransaction = null; while (!ma.Reader.EndOfStream) { MochaOpcode opcode = (MochaOpcode)ma.Reader.ReadByte(); switch (opcode) { case MochaOpcode.BeginTransaction: { currentTransaction = new MochaSnapshotTransaction(); currentTransaction.TenantName = _stringTable[ma.Reader.ReadInt32()]; break; } case MochaOpcode.EndTransaction: { mcx.Transactions.Add(currentTransaction); currentTransaction = null; break; } case MochaOpcode.CreateInstance: { DateTime effectiveDate = ma.Reader.ReadDateTime(); int guidIndex = ma.Reader.ReadInt32(); int classGuidIndex = ma.Reader.ReadInt32(); MochaSnapshotCreateInstanceTransactionOperation op = new MochaSnapshotCreateInstanceTransactionOperation(); op.GlobalIdentifier = _instanceGuids[guidIndex]; op.ClassGlobalIdentifier = _instanceGuids[classGuidIndex]; op.EffectiveDate = effectiveDate; currentTransaction.Operations.Add(op); break; } case MochaOpcode.CreateRelationship: case MochaOpcode.RemoveRelationship: { DateTime effectiveDate = ma.Reader.ReadDateTime(); int sourceInstanceIndex = ma.Reader.ReadInt32(); int relationshipIndex = ma.Reader.ReadInt32(); int targetInstanceCount = ma.Reader.ReadInt32(); MochaSnapshotAssociateRelationshipTransactionOperation rel = new MochaSnapshotAssociateRelationshipTransactionOperation(); rel.RelationshipInstanceID = _instanceGuids[relationshipIndex]; rel.SourceInstanceID = _instanceGuids[sourceInstanceIndex]; rel.EffectiveDate = effectiveDate; for (int k = 0; k < targetInstanceCount; k++) { int instanceIndex = ma.Reader.ReadInt32(); rel.TargetInstanceIDs.Add(_instanceGuids[instanceIndex]); } if (opcode == MochaOpcode.RemoveRelationship) { rel.Remove = true; } currentTransaction.Operations.Add(rel); break; } case MochaOpcode.AssignAttribute: { DateTime effectiveDate = ma.Reader.ReadDateTime(); int instanceIndex = ma.Reader.ReadInt32(); Guid instanceID = _instanceGuids[instanceIndex]; int attributeIndex = ma.Reader.ReadInt32(); Guid attributeInstanceID = _instanceGuids[attributeIndex]; object value = ReadMochaValue(ma.Reader, _stringTable); MochaSnapshotAssignAttributeTransactionOperation mav = new MochaSnapshotAssignAttributeTransactionOperation(); mav.SourceInstanceID = instanceID; mav.AttributeInstanceID = attributeInstanceID; mav.EffectiveDate = effectiveDate; mav.Value = value; currentTransaction.Operations.Add(mav); break; } } } } } else { Console.Error.WriteLine("mocha: mcl: error: ignoring 'Journal' section found in non-mcx file"); } #endregion }