Пример #1
0
        public static void LoadStream(this Oms oms, System.IO.Stream stream)
        {
            MochaClassLibraryObjectModel mcl = new MochaClassLibraryObjectModel();

            Document.Load(mcl, mcldf, new StreamAccessor(stream));

            oms.LoadObjectModel(mcl);
        }
Пример #2
0
        public static void LoadFile(this Oms oms, string file)
        {
            MochaClassLibraryObjectModel mcl = new MochaClassLibraryObjectModel();

            Document.Load(mcl, mcldf, new FileAccessor(file, false, false, true));

            oms.LoadObjectModel(mcl);
        }
Пример #3
0
        public static void Initialize(this Oms oms, Accessor accessor)
        {
            MochaClassLibraryObjectModel mcl = new MochaClassLibraryObjectModel();

            Document.Load(mcl, mcldf, accessor);

            oms.Initialize(mcl);
        }
Пример #4
0
        protected override void BeforeSaveInternal(Stack <ObjectModel> objectModels)
        {
            base.BeforeSaveInternal(objectModels);

            MochaClassLibraryObjectModel mcl = (objectModels.Pop() as MochaClassLibraryObjectModel);
            MarkupObjectModel            mom = new MarkupObjectModel();

            objectModels.Push(mom);
        }
Пример #5
0
        public static void Initialize(this Oms oms, string[] path)
        {
            string[] files = path;

            MochaClassLibraryObjectModel mcl = new MochaClassLibraryObjectModel();

            for (int i = 0; i < files.Length; i++)
            {
                MochaClassLibraryObjectModel mcl1 = new MochaClassLibraryObjectModel();
                Document.Load(mcl1, mcldf, new FileAccessor(files[i], false, false, true));
                mcl1.CopyTo(mcl);
            }

            oms.Initialize(mcl);
        }
Пример #6
0
        private static void Initialize(this Oms oms, MochaClassLibraryObjectModel mcl)
        {
            oms.BeginTransaction();

            for (int i = 0; i < mcl.Libraries.Count; i++)
            {
                for (int j = 0; j < mcl.Libraries[i].Instances.Count; j++)
                {
                    oms.CreateInstance(mcl.Libraries[i].Instances[j].ID, Guid.Empty);
                }
            }

            oms.CommitTransaction();

            oms.BeginTransaction();
            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 < mcl.Libraries[i].Instances[j].AttributeValues.Count; k++)
                    {
                        oms.SetAttributeValue(oms.GetInstance(mcl.Libraries[i].Instances[j].ID), oms.GetInstance(mcl.Libraries[i].Instances[j].AttributeValues[k].AttributeInstanceID), mcl.Libraries[i].Instances[j].AttributeValues[k].Value);
                    }
                }
                for (int j = 0; j < mcl.Libraries[i].Relationships.Count; j++)
                {
                    Guid[] ids = new Guid[mcl.Libraries[i].Relationships[j].DestinationInstanceIDs.Count];
                    for (int k = 0; k < mcl.Libraries[i].Relationships[j].DestinationInstanceIDs.Count; k++)
                    {
                        ids[k] = mcl.Libraries[i].Relationships[j].DestinationInstanceIDs[k];
                    }
                    oms.CreateRelationship(oms.GetInstance(mcl.Libraries[i].Relationships[j].SourceInstanceID), oms.GetInstance(mcl.Libraries[i].Relationships[j].RelationshipInstanceID), GuidsToInstances(oms, ids));
                }
            }
            oms.CommitTransaction();

            oms.BeginTransaction();


            // create the Class::Instance.has parent Class relationship
            oms.CreateRelationship(oms.GetInstance(KnownInstanceGuids.Classes.Class), oms.GetInstance(KnownRelationshipGuids.Class__has__Instance), oms.GetInstance(KnownInstanceGuids.Classes.Class));
            oms.CreateRelationship(oms.GetInstance(KnownInstanceGuids.Classes.Class), oms.GetInstance(KnownRelationshipGuids.Instance__for__Class), oms.GetInstance(KnownInstanceGuids.Classes.Class));

            oms.CommitTransaction();
        }
Пример #7
0
        private static void LoadObjectModel(this Oms oms, MochaClassLibraryObjectModel mcl)
        {
            foreach (MochaTenant tenant in mcl.Tenants)
            {
                oms.DefaultTenant = oms.GetTenant(tenant.Name);
                if (oms.DefaultTenant.IsEmpty)
                {
                    throw new InvalidOperationException("attempted to load snapshot for nonexistent tenant");
                }

                oms.BeginTransaction();
                for (int j = 0; j < tenant.Instances.Count; j++)
                {
                    oms.CreateInstance(tenant.Instances[j].ID, Guid.Empty);
                }
                oms.CommitTransaction();
            }
        }
Пример #8
0
        public static void Main(string[] args)
        {
            List <string> listFileNames = new List <string>();

            string outputFileName = "output.mcx";
            bool   foundFileName  = false;

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i].StartsWith("/") && !foundFileName)
                {
                    if (args[i].StartsWith("/out:"))
                    {
                        outputFileName = args[i].Substring(5);
                    }
                }
                else
                {
                    // is file name
                    foundFileName = true;

                    listFileNames.Add(args[i]);
                }
            }

            MochaClassLibraryObjectModel mcl = new MochaClassLibraryObjectModel();
            MochaBinaryDataFormat        mcx = new MochaBinaryDataFormat();
            MochaXMLDataFormat           xml = new MochaXMLDataFormat();

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            int totalInstances = 0, totalRelationships = 0;

            for (int i = 0; i < listFileNames.Count; i++)
            {
                Console.Error.WriteLine("reading {0}", listFileNames[i]);

                MochaClassLibraryObjectModel mcl1 = new MochaClassLibraryObjectModel();
                FileAccessor fain = new FileAccessor(listFileNames[i]);
                Document.Load(mcl1, xml, fain);

                for (int j = 0; j < mcl1.Libraries.Count; j++)
                {
                    mcl.Libraries.Merge(mcl1.Libraries[j]);
                    totalInstances     += mcl1.Libraries[j].Instances.Count;
                    totalRelationships += mcl1.Libraries[j].Relationships.Count;
                }
                for (int j = 0; j < mcl1.Tenants.Count; j++)
                {
                    Console.Error.WriteLine("registered tenant {0}", mcl1.Tenants[j].Name);
                    mcl.Tenants.Merge(mcl1.Tenants[j]);
                }
            }

            Console.Error.WriteLine("wrote {0} libraries with {1} instances and {2} relationships total", mcl.Libraries.Count, totalInstances, totalRelationships);

            string outputDir = System.IO.Path.GetDirectoryName(outputFileName);

            if (!System.IO.Directory.Exists(outputDir))
            {
                System.IO.Directory.CreateDirectory(outputDir);
            }

            FileAccessor faout = new FileAccessor(outputFileName, true, true);

            Document.Save(mcl, mcx, faout);
        }
Пример #9
0
        protected override void AfterLoadInternal(Stack <ObjectModel> 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 <MarkupTagElement>())
                {
                    if (tagTenant == null)
                    {
                        continue;
                    }
                    if (tagTenant.FullName != "tenant")
                    {
                        continue;
                    }

                    MarkupAttribute attTenantID   = tagTenant.Attributes["id"];
                    MarkupAttribute attTenantName = tagTenant.Attributes["name"];

                    if (attTenantID == null || attTenantName == null)
                    {
                        continue;
                    }

                    MochaTenant tenant = new MochaTenant();
                    tenant.ID   = new Guid(attTenantID.Value);
                    tenant.Name = attTenantName.Value;

                    MarkupTagElement tagLibraryReferences = tagTenant.Elements["libraryReferences"] as MarkupTagElement;
                    if (tagLibraryReferences != null)
                    {
                        foreach (MarkupTagElement tagLibraryReference in tagLibraryReferences.Elements.OfType <MarkupTagElement>())
                        {
                            MarkupAttribute attLibraryId = tagLibraryReference.Attributes["libraryId"];
                            if (attLibraryId == null)
                            {
                                continue;
                            }

                            tenant.LibraryReferences.Add(new MochaLibraryReference(new Guid(attLibraryId.Value)));
                        }
                    }
                    MarkupTagElement tagInstances = tagTenant.Elements["instances"] as MarkupTagElement;
                    if (tagInstances != null)
                    {
                        foreach (MarkupTagElement tagInstance in tagInstances.Elements.OfType <MarkupTagElement>())
                        {
                            MochaInstance inst = LoadInstance(tenant, tagInstance);
                            tenant.Instances.Add(inst);
                        }
                    }

                    mcl.Tenants.Add(tenant);
                }
            }
        }
Пример #10
0
        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 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);
        }
Пример #11
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
        }
Пример #12
0
        protected override void BeforeSaveInternal(Stack <ObjectModel> objectModels)
        {
            base.BeforeSaveInternal(objectModels);

            FileNameSize = 32;

            ObjectModel om = objectModels.Pop();
            MochaClassLibraryObjectModel mcl = (om as MochaClassLibraryObjectModel);
            MochaSnapshotObjectModel     mcx = (om as MochaSnapshotObjectModel);

            if (mcl == null && mcx == null)
            {
                throw new ObjectModelNotSupportedException();
            }

            FileSystemObjectModel fsom = new FileSystemObjectModel();

            List <Guid>   _instanceIndices = new List <Guid>();
            List <string> _stringTable     = new List <string>();

            if (mcl != null)
            {
                #region Libraries
                {
                    File           f  = fsom.AddFile("Libraries");
                    MemoryAccessor ma = new MemoryAccessor();
                    ma.Writer.WriteInt32(mcl.Libraries.Count);
                    for (int i = 0; i < mcl.Libraries.Count; i++)
                    {
                        ma.Writer.WriteGuid(mcl.Libraries[i].ID);
                        ma.Writer.WriteInt32(mcl.Libraries[i].Instances.Count);
                        ma.Writer.WriteInt32(mcl.Libraries[i].Relationships.Count);
                    }
                    ma.Close();
                    f.SetData(ma.ToArray());
                }
                #endregion
                #region Instances
                {
                    File           f  = fsom.AddFile("Instances");
                    MemoryAccessor ma = new MemoryAccessor();
                    for (int i = 0; i < mcl.Libraries.Count; i++)
                    {
                        ma.Writer.WriteInt32(mcl.Libraries[i].Instances.Count);
                        for (int j = 0; j < mcl.Libraries[i].Instances.Count; j++)
                        {
                            ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, mcl.Libraries[i].Instances[j].ID));
                            ma.Writer.WriteInt32(mcl.Libraries[i].Instances[j].AttributeValues.Count);

                            MochaInstanceFlags flags = MochaInstanceFlags.None;
                            if (mcl.Libraries[i].Instances[j].Index != null)
                            {
                                flags |= MochaInstanceFlags.HasIndex;
                            }
                            ma.Writer.WriteInt32((int)flags);

                            if ((flags & MochaInstanceFlags.HasIndex) == MochaInstanceFlags.HasIndex)
                            {
                                ma.Writer.WriteInt32(mcl.Libraries[i].Instances[j].Index.Value);
                            }
                        }
                    }
                    ma.Close();
                    f.SetData(ma.ToArray());
                }
                #endregion
                #region Attributes
                {
                    File           f  = fsom.AddFile("Attributes");
                    MemoryAccessor ma = new MemoryAccessor();

                    for (int i = 0; i < mcl.Libraries.Count; i++)
                    {
                        /*
                         * writer.WriteInt32(mcl.Libraries[i].Metadata.Count);
                         * for (int j = 0; j < mcl.Libraries[i].Metadata.Count; j++)
                         * {
                         *      writer.WriteNullTerminatedString(mcl.Libraries[i].Metadata[j].Name);
                         *      writer.WriteNullTerminatedString(mcl.Libraries[i].Metadata[j].Value);
                         * }
                         */
                        for (int j = 0; j < mcl.Libraries[i].Instances.Count; j++)
                        {
                            for (int k = 0; k < mcl.Libraries[i].Instances[j].AttributeValues.Count; k++)
                            {
                                ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, mcl.Libraries[i].Instances[j].AttributeValues[k].AttributeInstanceID));

                                if (mcl.Libraries[i].Instances[j].AttributeValues[k].Value == null)
                                {
                                    ma.Writer.WriteInt32((int)MochaAttributeType.None);
                                }
                                else if (mcl.Libraries[i].Instances[j].AttributeValues[k].Value is string)
                                {
                                    ma.Writer.WriteInt32((int)MochaAttributeType.Text);
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <string>(_stringTable, mcl.Libraries[i].Instances[j].AttributeValues[k].Value as string));
                                }
                                else
                                {
                                    ma.Writer.WriteInt32((int)MochaAttributeType.Unknown);
                                    ma.Writer.WriteObject(mcl.Libraries[i].Instances[j].AttributeValues[k].Value);
                                }
                            }
                        }
                    }

                    ma.Close();
                    f.SetData(ma.ToArray());
                }
                #endregion
                #region Relationships
                {
                    File           f  = fsom.AddFile("Relationships");
                    MemoryAccessor ma = new MemoryAccessor();
                    for (int i = 0; i < mcl.Libraries.Count; i++)
                    {
                        for (int j = 0; j < mcl.Libraries[i].Relationships.Count; j++)
                        {
                            ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, mcl.Libraries[i].Relationships[j].RelationshipInstanceID));
                            ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, mcl.Libraries[i].Relationships[j].SourceInstanceID));

                            ma.Writer.WriteInt32(mcl.Libraries[i].Relationships[j].DestinationInstanceIDs.Count);
                            for (int k = 0; k < mcl.Libraries[i].Relationships[j].DestinationInstanceIDs.Count; k++)
                            {
                                ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, mcl.Libraries[i].Relationships[j].DestinationInstanceIDs[k]));
                            }
                        }
                    }
                    ma.Close();
                    f.SetData(ma.ToArray());
                }
                #endregion

                #region Tenants
                {
                    if (mcl.Tenants.Count > 0)
                    {
                        File           f  = fsom.AddFile("Tenants");
                        MemoryAccessor ma = new MemoryAccessor();
                        ma.Writer.WriteInt32(mcl.Tenants.Count);
                        foreach (MochaTenant tenant in mcl.Tenants)
                        {
                            ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.ID));
                            ma.Writer.WriteInt32(AddOrUpdateLookupTable <string>(_stringTable, tenant.Name));

                            ma.Writer.WriteInt32(tenant.LibraryReferences.Count);
                            for (int i = 0; i < tenant.LibraryReferences.Count; i++)
                            {
                                ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.LibraryReferences[i].LibraryID));
                            }

                            ma.Writer.WriteInt32(tenant.Instances.Count);
                            for (int i = 0; i < tenant.Instances.Count; i++)
                            {
                                ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.Instances[i].ID));
                            }
                            ma.Writer.WriteInt32(tenant.Relationships.Count);
                            for (int i = 0; i < tenant.Relationships.Count; i++)
                            {
                                ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.Relationships[i].SourceInstanceID));
                                ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.Relationships[i].RelationshipInstanceID));
                                ma.Writer.WriteInt32(tenant.Relationships[i].DestinationInstanceIDs.Count);
                                for (int j = 0; j < tenant.Relationships[i].DestinationInstanceIDs.Count; j++)
                                {
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, tenant.Relationships[i].DestinationInstanceIDs[j]));
                                }
                            }
                        }
                        ma.Close();
                        f.SetData(ma.ToArray());
                    }
                }
                #endregion
            }
            else if (mcx != null)
            {
                #region Journal
                {
                    if (mcx.Transactions.Count > 0)
                    {
                        File           f  = fsom.AddFile("Journal");
                        MemoryAccessor ma = new MemoryAccessor();
                        foreach (MochaSnapshotTransaction t in mcx.Transactions)
                        {
                            ma.Writer.WriteByte((byte)MochaOpcode.BeginTransaction);
                            ma.Writer.WriteInt32(AddOrUpdateLookupTable <string>(_stringTable, t.TenantName));
                            foreach (MochaSnapshotTransactionOperation op in t.Operations)
                            {
                                if (op is MochaSnapshotCreateInstanceTransactionOperation ci)
                                {
                                    ma.Writer.WriteByte((byte)MochaOpcode.CreateInstance);
                                    ma.Writer.WriteDateTime(ci.EffectiveDate);
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, ci.GlobalIdentifier));
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, ci.ClassGlobalIdentifier));
                                }
                                else if (op is MochaSnapshotAssignAttributeTransactionOperation aa)
                                {
                                    ma.Writer.WriteByte((byte)MochaOpcode.AssignAttribute);
                                    ma.Writer.WriteDateTime(aa.EffectiveDate);
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, aa.SourceInstanceID));
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, aa.AttributeInstanceID));
                                    WriteMochaValue(ma.Writer, aa.Value, _stringTable);
                                }
                                else if (op is MochaSnapshotAssociateRelationshipTransactionOperation ar)
                                {
                                    ma.Writer.WriteByte((byte)MochaOpcode.CreateRelationship);
                                    ma.Writer.WriteDateTime(ar.EffectiveDate);
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, ar.SourceInstanceID));
                                    ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, ar.RelationshipInstanceID));
                                    ma.Writer.WriteInt32(ar.TargetInstanceIDs.Count);
                                    foreach (Guid id in ar.TargetInstanceIDs)
                                    {
                                        ma.Writer.WriteInt32(AddOrUpdateLookupTable <Guid>(_instanceIndices, id));
                                    }
                                }
                            }
                            ma.Writer.WriteByte((byte)MochaOpcode.EndTransaction);
                        }
                        ma.Close();
                        f.SetData(ma.ToArray());
                    }
                }
                #endregion
            }
            #region Guid Table
            {
                File           f  = fsom.AddFile("GlobalIdentifiers");
                MemoryAccessor ma = new MemoryAccessor();
                ma.Writer.WriteInt32(_instanceIndices.Count);
                foreach (Guid id in _instanceIndices)
                {
                    ma.Writer.WriteGuid(id);
                }
                ma.Close();
                f.SetData(ma.ToArray());
            }
            #endregion
            #region String Table
            {
                File           f  = fsom.AddFile("StringTable");
                MemoryAccessor ma = new MemoryAccessor();
                ma.Writer.WriteInt32(_stringTable.Count);
                foreach (string id in _stringTable)
                {
                    ma.Writer.WriteNullTerminatedString(id);
                }
                ma.Close();
                f.SetData(ma.ToArray());
            }
            #endregion

            objectModels.Push(fsom);
        }