Exemplo n.º 1
0
        private void SetParentClass(IMochaStore library, Guid sourceInstanceID, Guid parentClassID)
        {
            MochaRelationship relHasSuperClass = new MochaRelationship();

            relHasSuperClass.SourceInstanceID = sourceInstanceID;
            relHasSuperClass.DestinationInstanceIDs.Add(parentClassID);
            relHasSuperClass.RelationshipInstanceID = global::Mocha.Core.KnownRelationshipGuids.Instance__for__Class;
            library.Relationships.Add(relHasSuperClass);

            MochaRelationship relHasSubClass = new MochaRelationship();

            relHasSubClass.SourceInstanceID = parentClassID;
            relHasSubClass.DestinationInstanceIDs.Add(sourceInstanceID);
            relHasSubClass.RelationshipInstanceID = global::Mocha.Core.KnownRelationshipGuids.Class__has__Instance;
            library.Relationships.Add(relHasSubClass);
        }
Exemplo n.º 2
0
        private void SetClass(IMochaStore library, Guid id)
        {
            MochaRelationship relClass__has__Instance = new MochaRelationship();

            relClass__has__Instance.SourceInstanceID       = global::Mocha.Core.KnownInstanceGuids.Classes.Class;
            relClass__has__Instance.RelationshipInstanceID = global::Mocha.Core.KnownRelationshipGuids.Class__has__Instance;
            relClass__has__Instance.DestinationInstanceIDs.Add(id);
            library.Relationships.Add(relClass__has__Instance);

            MochaRelationship relInstance__for__Class = new MochaRelationship();

            relInstance__for__Class.SourceInstanceID       = id;
            relInstance__for__Class.RelationshipInstanceID = global::Mocha.Core.KnownRelationshipGuids.Instance__for__Class;
            relInstance__for__Class.DestinationInstanceIDs.Add(global::Mocha.Core.KnownInstanceGuids.Classes.Class);
            library.Relationships.Add(relInstance__for__Class);
        }
Exemplo n.º 3
0
        private void SetOwner(IMochaStore library, Guid instanceId, Guid ownerId)
        {
            MochaRelationship relClass__has__Instance = new MochaRelationship();

            relClass__has__Instance.SourceInstanceID       = instanceId;
            relClass__has__Instance.RelationshipInstanceID = global::Mocha.Core.KnownRelationshipGuids.Class__has_owner__User;
            relClass__has__Instance.DestinationInstanceIDs.Add(ownerId);
            library.Relationships.Add(relClass__has__Instance);

            MochaRelationship relInstance__for__Class = new MochaRelationship();

            relInstance__for__Class.SourceInstanceID       = ownerId;
            relInstance__for__Class.RelationshipInstanceID = global::Mocha.Core.KnownRelationshipGuids.User__owner_for__Class;
            relInstance__for__Class.DestinationInstanceIDs.Add(instanceId);
            library.Relationships.Add(relInstance__for__Class);
        }
Exemplo n.º 4
0
        private void SetSource(IMochaStore library, Guid instanceId, Guid sourceTypeId)
        {
            MochaRelationship relClass__has__Instance = new MochaRelationship();

            relClass__has__Instance.SourceInstanceID       = instanceId;
            relClass__has__Instance.RelationshipInstanceID = global::Mocha.Core.KnownRelationshipGuids.Class__has__Object_Source;
            relClass__has__Instance.DestinationInstanceIDs.Add(sourceTypeId);
            library.Relationships.Add(relClass__has__Instance);

            MochaRelationship relInstance__for__Class = new MochaRelationship();

            relInstance__for__Class.SourceInstanceID       = sourceTypeId;
            relInstance__for__Class.RelationshipInstanceID = global::Mocha.Core.KnownRelationshipGuids.Object_Source__for__Class;
            relInstance__for__Class.DestinationInstanceIDs.Add(instanceId);
            library.Relationships.Add(relInstance__for__Class);
        }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        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
        }