Exemple #1
0
        /// <summary>
        /// Create a 3-level nested projection object
        /// </summary>
        /// <param name="corpus"></param>
        /// <returns></returns>
        private CdmProjection CreateNestedProjection(CdmCorpusDefinition corpus)
        {
            CdmProjection projection3 = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef);
            {
                projection3.Source = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, "TestSource", simpleNameRef: true);
            }
            CdmEntityReference inlineProjectionEntityRef3 = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            inlineProjectionEntityRef3.ExplicitReference = projection3;

            CdmProjection projection2 = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef);
            {
                projection2.Source = inlineProjectionEntityRef3;
            }
            CdmEntityReference inlineProjectionEntityRef2 = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            inlineProjectionEntityRef2.ExplicitReference = projection2;

            CdmProjection projection1 = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef);

            {
                projection1.Source = inlineProjectionEntityRef2;
            }

            return(projection1);
        }
        public async Task TestEntityProjUsingObjectModel()
        {
            CdmCorpusDefinition corpus = ProjectionTestUtils.GetLocalCorpus(testsSubpath, "TestEntityProjUsingObjectModel");

            corpus.Storage.Mount("local", new LocalAdapter(TestHelper.GetActualOutputFolderPath(testsSubpath, "TestEntityProjUsingObjectModel")));
            CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local");

            // Create an entity
            CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot);

            // Create a projection
            CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot);

            // Create an ArrayExpansion operation
            CdmOperationArrayExpansion arrayExpansionOp = corpus.MakeObject <CdmOperationArrayExpansion>(CdmObjectType.OperationArrayExpansionDef);

            arrayExpansionOp.StartOrdinal = 1;
            arrayExpansionOp.EndOrdinal   = 2;
            projection.Operations.Add(arrayExpansionOp);

            // Create an entity reference to hold this projection
            CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef.ExplicitReference = projection;

            // Create another projection that does a rename so that we can see the expanded attributes in the final resolved entity
            CdmProjection projection2 = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef);

            projection2.Source = projectionEntityRef;

            // Create a RenameAttributes operation
            CdmOperationRenameAttributes renameAttrsOp = corpus.MakeObject <CdmOperationRenameAttributes>(CdmObjectType.OperationRenameAttributesDef);

            renameAttrsOp.RenameFormat = "{m}{o}";
            projection2.Operations.Add(renameAttrsOp);

            // Create an entity reference to hold this projection
            CdmEntityReference projectionEntityRef2 = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef2.ExplicitReference = projection2;

            // Set the entity's ExtendEntity to be the projection
            entity.ExtendsEntity = projectionEntityRef2;

            // Resolve the entity
            CdmEntityDefinition resolvedEntity = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", null, localRoot);

            // Verify correctness of the resolved attributes after running the projections
            // Original set of attributes: ["id", "name", "value", "date"]
            // Expand 1...2, renameFormat = {m}{o}
            Assert.AreEqual(8, resolvedEntity.Attributes.Count);
            Assert.AreEqual("id1", (resolvedEntity.Attributes[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name1", (resolvedEntity.Attributes[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value1", (resolvedEntity.Attributes[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date1", (resolvedEntity.Attributes[3] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("id2", (resolvedEntity.Attributes[4] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name2", (resolvedEntity.Attributes[5] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value2", (resolvedEntity.Attributes[6] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date2", (resolvedEntity.Attributes[7] as CdmTypeAttributeDefinition).Name);
        }
Exemple #3
0
        /// <summary>
        /// Create a simple projection object
        /// </summary>
        /// <param name="projectionSourceName"></param>
        /// <returns></returns>
        public CdmProjection CreateProjection(string projectionSourceName)
        {
            CdmProjection projection = Corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef);

            projection.Source = Corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, projectionSourceName, simpleNameRef: true);

            return(projection);
        }
Exemple #4
0
        /// <summary>
        /// Create an inline entity reference for a projection
        /// </summary>
        /// <param name="projectionSourceName"></param>
        /// <returns></returns>
        public CdmEntityReference CreateProjectionInlineEntityReference(CdmProjection projection)
        {
            CdmEntityReference projectionInlineEntityRef = Corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionInlineEntityRef.ExplicitReference = projection;

            return(projectionInlineEntityRef);
        }
        public async Task TestNestedProjUsingObjectModel()
        {
            CdmCorpusDefinition corpus = TestHelper.GetLocalCorpus(testsSubpath, "TestNestedProjUsingObjectModel");

            corpus.Storage.Mount("local", new LocalAdapter(TestHelper.GetActualOutputFolderPath(testsSubpath, "TestNestedProjUsingObjectModel")));
            CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local");

            // Create an entity
            CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot);

            // Create a projection
            CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot);

            // Create an ExcludeAttributes operation
            CdmOperationExcludeAttributes excludeAttrsOp = corpus.MakeObject <CdmOperationExcludeAttributes>(CdmObjectType.OperationExcludeAttributesDef);

            excludeAttrsOp.ExcludeAttributes.Add("id");
            excludeAttrsOp.ExcludeAttributes.Add("date");
            projection.Operations.Add(excludeAttrsOp);

            // Create an entity reference to hold this projection
            CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef.ExplicitReference = projection;

            // Create another projection that uses the previous projection as its source
            CdmProjection projection2 = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef);

            projection2.Source = projectionEntityRef;

            // Create an ExcludeAttributes operation
            CdmOperationExcludeAttributes excludeAttrsOp2 = corpus.MakeObject <CdmOperationExcludeAttributes>(CdmObjectType.OperationExcludeAttributesDef);

            excludeAttrsOp2.ExcludeAttributes.Add("value");
            projection2.Operations.Add(excludeAttrsOp2);

            // Create an entity reference to hold this projection
            CdmEntityReference projectionEntityRef2 = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef2.ExplicitReference = projection2;

            // Create an entity attribute that contains this projection and add this to the entity
            CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute");

            entityAttribute.Entity = projectionEntityRef2;
            entity.Attributes.Add(entityAttribute);

            // Resolve the entity
            CdmEntityDefinition resolvedEntity = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", null, localRoot);

            // Verify correctness of the resolved attributes after running the ExcludeAttributes operations
            // Original set of attributes: ["id", "name", "value", "date"]
            // Excluded attributes: ["id", "date"], ["value"]
            Assert.AreEqual(1, resolvedEntity.Attributes.Count);
            Assert.AreEqual("name", (resolvedEntity.Attributes[0] as CdmTypeAttributeDefinition).Name);
        }
Exemple #6
0
        /// <summary>
        /// Create a simple projection object
        /// </summary>
        /// <param name="corpus"></param>
        /// <returns></returns>
        private CdmProjection CreateProjection(CdmCorpusDefinition corpus)
        {
            CdmProjection projection = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef);

            {
                projection.Source = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, "TestSource", simpleNameRef: true);
            }

            return(projection);
        }
Exemple #7
0
        /// <summary>
        /// Applies the arrayExpansion operation to the entity attribute provided.
        /// It also takes care of applying a renameAttributes operation and optionally applying a addCountAttribute operation.
        /// </summary>
        /// <param name="entityAttr"></param>
        /// <param name="startOrdinal"></param>
        /// <param name="endOrdinal"></param>
        /// <param name="renameFormat"></param>
        /// <param name="countAttName"></param>
        static void ApplyArrayExpansion(CdmEntityAttributeDefinition entityAttr, int startOrdinal, int endOrdinal, string renameFormat, string countAttName)
        {
            var           ctx        = entityAttr.Ctx;
            CdmProjection projection = new CdmProjection(ctx)
            {
                Source          = entityAttr.Entity,
                RunSequentially = true,
                // Link for the Condition property documentation.
                // https://docs.microsoft.com/en-us/common-data-model/sdk/convert-logical-entities-resolved-entities#condition
                Condition = "!normalized"
            };

            entityAttr.Entity = new CdmEntityReference(ctx, projection, false);

            // Link for the ArrayExpansion operation documentation.
            // https://docs.microsoft.com/en-us/common-data-model/sdk/projections/arrayexpansion
            var arrExpansionOperation = new CdmOperationArrayExpansion(ctx)
            {
                StartOrdinal = startOrdinal,
                EndOrdinal   = endOrdinal
            };

            projection.Operations.Add(arrExpansionOperation);

            // Link for the RenameAttributes operation documentation.
            // https://docs.microsoft.com/en-us/common-data-model/sdk/projections/renameattributes
            // Doing an ArrayExpansion without a RenameAttributes afterwards will result in the expanded attributes being merged in the final resolved entity.
            // This is because ArrayExpansion does not rename the attributes it expands by default. The expanded attributes end up with the same name and gets merged.
            // Example: We expand A to A[1], A[2], A[3], but A[1], A[2], A[3] are still named "A".
            var renameAttrsOperation = new CdmOperationRenameAttributes(ctx)
            {
                RenameFormat = renameFormat
            };

            projection.Operations.Add(renameAttrsOperation);

            if (countAttName != null)
            {
                var countAttribute = new CdmTypeAttributeDefinition(ctx, countAttName)
                {
                    DataType = new CdmDataTypeReference(ctx, "integer", true)
                };

                // Link for the AddCountAttribute operation documentation.
                // https://docs.microsoft.com/en-us/common-data-model/sdk/projections/addcountattribute
                // It is recommended, but not mandated, to be used with the ArrayExpansion operation to provide an ArrayExpansion a count attribute that
                // represents the total number of expanded elements. AddCountAttribute can also be used by itself.
                var addCountAttrOperation = new CdmOperationAddCountAttribute(ctx)
                {
                    CountAttribute = countAttribute
                };
                projection.Operations.Add(addCountAttrOperation);
            }
        }
Exemple #8
0
        /// <summary>
        /// Create a Combine Attribute Operation
        /// </summary>
        /// <returns></returns>
        public CdmOperationCombineAttributes CreateOperationCombineAttributes(CdmProjection projection, List <string> selectedAttributes, CdmTypeAttributeDefinition mergeIntoAttribute)
        {
            // CombineAttributes Operation
            CdmOperationCombineAttributes combineAttributesOp = new CdmOperationCombineAttributes(Corpus.Ctx)
            {
                Select    = selectedAttributes,
                MergeInto = mergeIntoAttribute
            };

            projection.Operations.Add(combineAttributesOp);

            return(combineAttributesOp);
        }
Exemple #9
0
        public async Task TestEAProjOM()
        {
            string className = "ProjectionIncludeTest";
            string testName  = "TestEAProjOM";

            string entityName_RGB = "RGB";
            List <TypeAttributeParam> attributeParams_RGB = new List <TypeAttributeParam>();
            {
                attributeParams_RGB.Add(new TypeAttributeParam("Red", "string", "hasA"));
                attributeParams_RGB.Add(new TypeAttributeParam("Green", "string", "hasA"));
                attributeParams_RGB.Add(new TypeAttributeParam("Blue", "string", "hasA"));
                attributeParams_RGB.Add(new TypeAttributeParam("IsGrayscale", "boolean", "hasA"));
            }

            string entityName_Color = "Color";
            List <TypeAttributeParam> attributeParams_Color = new List <TypeAttributeParam>();
            {
                attributeParams_Color.Add(new TypeAttributeParam("ColorName", "string", "identifiedBy"));
            }

            List <string> includeAttributeNames = new List <string>()
            {
                "Red",
                "Green",
                "Blue"
            };

            using (ProjectionOMTestUtil util = new ProjectionOMTestUtil(className, testName))
            {
                CdmEntityDefinition entity_RGB = util.CreateBasicEntity(entityName_RGB, attributeParams_RGB);
                util.ValidateBasicEntity(entity_RGB, entityName_RGB, attributeParams_RGB);

                CdmEntityDefinition entity_Color = util.CreateBasicEntity(entityName_Color, attributeParams_Color);
                util.ValidateBasicEntity(entity_Color, entityName_Color, attributeParams_Color);

                CdmProjection projection_RGBColor = util.CreateProjection(entity_RGB.EntityName);
                CdmOperationIncludeAttributes operation_IncludeAttributes  = util.CreateOperationInputAttributes(projection_RGBColor, includeAttributeNames);
                CdmEntityReference            projectionEntityRef_RGBColor = util.CreateProjectionInlineEntityReference(projection_RGBColor);

                CdmEntityAttributeDefinition entityAttribute_RGBColor = util.CreateEntityAttribute("RGBColor", projectionEntityRef_RGBColor);
                entity_Color.Attributes.Add(entityAttribute_RGBColor);

                foreach (List <string> resOpts in resOptsCombinations)
                {
                    await util.GetAndValidateResolvedEntity(entity_Color, resOpts);
                }

                await util.DefaultManifest.SaveAsAsync(util.ManifestDocName, saveReferenced : true);
            }
        }
Exemple #10
0
        /// <summary>
        /// Creates a projection
        /// </summary>
        public static CdmProjection CreateProjection(CdmCorpusDefinition corpus, CdmFolderDefinition localRoot)
        {
            // Create an entity reference to use as the source of the projection
            CdmEntityReference projectionSource = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionSource.ExplicitReference = CreateSourceEntity(corpus, localRoot);

            // Create the projection
            CdmProjection projection = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef);

            projection.Source = projectionSource;

            return(projection);
        }
        /// <summary>
        /// Applies the arrayExpansion operation to the entity attribute provided.
        /// It also takes care of applying a renameAttributes operation and optionally applying a addCountAttribute operation.
        /// </summary>
        /// <param name="entityAttr"></param>
        /// <param name="startOrdinal"></param>
        /// <param name="endOrdinal"></param>
        /// <param name="renameFormat"></param>
        /// <param name="countAttName"></param>
        static void ApplyArrayExpansion(CdmEntityAttributeDefinition entityAttr, int startOrdinal, int endOrdinal, string renameFormat, string countAttName)
        {
            var           ctx        = entityAttr.Ctx;
            CdmProjection projection = new CdmProjection(ctx)
            {
                Source          = entityAttr.Entity,
                RunSequentially = true,
                // Link for the Condition property documentation.
                // https://docs.microsoft.com/en-us/common-data-model/sdk/convert-logical-entities-resolved-entities#condition
                Condition = "!normalized"
            };

            entityAttr.Entity = new CdmEntityReference(ctx, projection, false);

            // Link for the ArrayExpansion operation documentation.
            // https://docs.microsoft.com/en-us/common-data-model/sdk/projections/arrayexpansion
            var arrExpansionOperation = new CdmOperationArrayExpansion(ctx)
            {
                StartOrdinal = startOrdinal,
                EndOrdinal   = endOrdinal
            };

            projection.Operations.Add(arrExpansionOperation);

            // Link for the RenameAttributes operation documentation.
            // https://docs.microsoft.com/en-us/common-data-model/sdk/projections/renameattributes
            var renameAttrsOperation = new CdmOperationRenameAttributes(ctx)
            {
                RenameFormat = renameFormat
            };

            projection.Operations.Add(renameAttrsOperation);

            if (countAttName != null)
            {
                var countAttribute = new CdmTypeAttributeDefinition(ctx, countAttName)
                {
                    DataType = new CdmDataTypeReference(ctx, "integer", true)
                };

                // Link for the AddCountAttribute operation documentation.
                // https://docs.microsoft.com/en-us/common-data-model/sdk/projections/addcountattribute
                var addCountAttrOperation = new CdmOperationAddCountAttribute(ctx)
                {
                    CountAttribute = countAttribute
                };
                projection.Operations.Add(addCountAttrOperation);
            }
        }
Exemple #12
0
        /// <summary>
        /// Create an Input Attribute Operation
        /// </summary>
        /// <returns></returns>
        public CdmOperationIncludeAttributes CreateOperationInputAttributes(CdmProjection projection, List <string> includeAttributes)
        {
            // IncludeAttributes Operation
            CdmOperationIncludeAttributes includeAttributesOp = new CdmOperationIncludeAttributes(Corpus.Ctx)
            {
                IncludeAttributes = new List <string>()
            };

            foreach (string includeAttribute in includeAttributes)
            {
                includeAttributesOp.IncludeAttributes.Add(includeAttribute);
            }

            projection.Operations.Add(includeAttributesOp);

            return(includeAttributesOp);
        }
        /// <summary>
        /// Applies the replaceAsForeignKey and addAttributeGroup operations to the entity attribute provided.
        /// </summary>
        /// <param name="entityAttr"></param>
        /// <param name="fkAttrName"></param>
        /// <param name="attrGroupName"></param>
        static void ApplyDefaultBehavior(CdmEntityAttributeDefinition entityAttr, string fkAttrName, string attrGroupName)
        {
            var           ctx        = entityAttr.Ctx;
            CdmProjection projection = new CdmProjection(ctx)
            {
                // Link for the Source property documentation.
                // https://docs.microsoft.com/en-us/common-data-model/sdk/convert-logical-entities-resolved-entities#source
                Source = entityAttr.Entity,
                // Link for the RunSequentially property documentation.
                // https://docs.microsoft.com/en-us/common-data-model/sdk/convert-logical-entities-resolved-entities#run-sequentially
                RunSequentially = true
            };

            entityAttr.Entity = new CdmEntityReference(ctx, projection, false);

            if (fkAttrName != null)
            {
                var foreignKeyAttr = new CdmTypeAttributeDefinition(ctx, fkAttrName)
                {
                    DataType = new CdmDataTypeReference(ctx, "entityId", true)
                };

                // Link for the ReplaceAsForeignKey operation documentation.
                // https://docs.microsoft.com/en-us/common-data-model/sdk/projections/replaceasforeignkey
                var replaceAsFKOperation = new CdmOperationReplaceAsForeignKey(ctx)
                {
                    Condition   = "referenceOnly",
                    Reference   = "addressLine",
                    ReplaceWith = foreignKeyAttr
                };
                projection.Operations.Add(replaceAsFKOperation);
            }

            if (attrGroupName != null)
            {
                // Link for the AddAttributeGroup operation documentation.
                // https://docs.microsoft.com/en-us/common-data-model/sdk/projections/addattributegroup
                var addAttrGroupOperation = new CdmOperationAddAttributeGroup(ctx)
                {
                    Condition          = "structured",
                    AttributeGroupName = attrGroupName
                };
                projection.Operations.Add(addAttrGroupOperation);
            }
        }
Exemple #14
0
        public async Task TestEntityAttributeProjUsingObjectModel()
        {
            CdmCorpusDefinition corpus = ProjectionTestUtils.GetLocalCorpus(testsSubpath, "TestEntityAttributeProjUsingObjectModel");

            corpus.Storage.Mount("local", new LocalAdapter(TestHelper.GetActualOutputFolderPath(testsSubpath, "TestEntityAttributeProjUsingObjectModel")));
            CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local");

            // Create an entity
            CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot);

            // Create a projection
            CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot);

            // Create an AddTypeAttribute operation
            CdmOperationAddTypeAttribute addTypeAttrOp = corpus.MakeObject <CdmOperationAddTypeAttribute>(CdmObjectType.OperationAddTypeAttributeDef);

            addTypeAttrOp.TypeAttribute          = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, "testType");
            addTypeAttrOp.TypeAttribute.DataType = corpus.MakeRef <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "entityName", true);
            projection.Operations.Add(addTypeAttrOp);

            // Create an entity reference to hold this projection
            CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef.ExplicitReference = projection;

            // Create an entity attribute that contains this projection and add this to the entity
            CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute");

            entityAttribute.Entity = projectionEntityRef;
            entity.Attributes.Add(entityAttribute);

            // Resolve the entity
            CdmEntityDefinition resolvedEntity = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", null, localRoot);

            // Verify correctness of the resolved attributes after running the AddTypeAttribute operation
            // Original set of attributes: ["id", "name", "value", "date"]
            // Type attribute: "testType"
            Assert.AreEqual(5, resolvedEntity.Attributes.Count);
            Assert.AreEqual("id", (resolvedEntity.Attributes[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name", (resolvedEntity.Attributes[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value", (resolvedEntity.Attributes[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date", (resolvedEntity.Attributes[3] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("testType", (resolvedEntity.Attributes[4] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("is.linkedEntity.name", resolvedEntity.Attributes[4].AppliedTraits[4].NamedReference);
        }
Exemple #15
0
        public void TestEntityAttributeSource()
        {
            CdmCorpusDefinition corpus = new CdmCorpusDefinition();
            int errorCount             = 0;

            corpus.SetEventCallback(new EventCallback()
            {
                Invoke = (level, message) =>
                {
                    errorCount++;
                }
            }, CdmStatusLevel.Error);
            CdmProjection projection       = new CdmProjection(corpus.Ctx);
            CdmEntityAttributeDefinition _ = new CdmEntityAttributeDefinition(corpus.Ctx, "attribute")
            {
                Entity = new CdmEntityReference(corpus.Ctx, projection, false)
            };

            // First case, a projection without source.
            projection.Validate();
            Assert.AreEqual(1, errorCount);
            errorCount = 0;

            // Second case, a projection with a nested projection.
            CdmProjection innerProjection = new CdmProjection(corpus.Ctx);

            projection.Source = new CdmEntityReference(corpus.Ctx, innerProjection, false);
            projection.Validate();
            innerProjection.Validate();
            Assert.AreEqual(1, errorCount);
            errorCount = 0;

            // Third case, a projection with an explicit entity definition.
            innerProjection.Source = new CdmEntityReference(corpus.Ctx, new CdmEntityDefinition(corpus.Ctx, "Entity"), false);
            projection.Validate();
            innerProjection.Validate();
            Assert.AreEqual(0, errorCount);

            // Third case, a projection with a named reference.
            innerProjection.Source = new CdmEntityReference(corpus.Ctx, "Entity", false);
            projection.Validate();
            innerProjection.Validate();
            Assert.AreEqual(0, errorCount);
        }
        public async Task TestEntityAttributeProjUsingObjectModel()
        {
            string testName               = "TestEntityAttributeProjUsingObjectModel";
            CdmCorpusDefinition corpus    = ProjectionTestUtils.GetCorpus(testName, testsSubpath);
            CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local");

            // Create an entity
            CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot);

            // Create a projection
            CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot);

            // Create an AddAttributeGroup operation
            CdmOperationAddAttributeGroup addAttGroupOp = corpus.MakeObject <CdmOperationAddAttributeGroup>(CdmObjectType.OperationAddAttributeGroupDef);

            addAttGroupOp.AttributeGroupName = "PersonAttributeGroup";
            projection.Operations.Add(addAttGroupOp);

            // Create an entity reference to hold this projection
            CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef.ExplicitReference = projection;

            // Create an entity attribute that contains this projection and add this to the entity
            CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute");

            entityAttribute.Entity = projectionEntityRef;
            entity.Attributes.Add(entityAttribute);

            // Resolve the entity.
            CdmEntityDefinition resolvedEntity = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", null, localRoot);

            // Verify correctness of the resolved attributes after running the AddAttributeGroup operation
            // Original set of attributes: ["id", "name", "value", "date"]
            CdmAttributeGroupDefinition attGroupDefinition = this.ValidateAttributeGroup(resolvedEntity.Attributes, "PersonAttributeGroup");

            Assert.AreEqual(4, attGroupDefinition.Members.Count);
            Assert.AreEqual("id", (attGroupDefinition.Members[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name", (attGroupDefinition.Members[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value", (attGroupDefinition.Members[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date", (attGroupDefinition.Members[3] as CdmTypeAttributeDefinition).Name);
        }
Exemple #17
0
        public async Task TestEntityProjUsingObjectModel()
        {
            CdmCorpusDefinition corpus = TestHelper.GetLocalCorpus(testsSubpath, "TestEntityProjUsingObjectModel");

            corpus.Storage.Mount("local", new LocalAdapter(TestHelper.GetActualOutputFolderPath(testsSubpath, "TestEntityProjUsingObjectModel")));
            CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local");

            // Create an entity
            CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot);

            // Create a projection
            CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot);

            // Create an ExcludeAttributes operation
            CdmOperationExcludeAttributes excludeAttrsOp = corpus.MakeObject <CdmOperationExcludeAttributes>(CdmObjectType.OperationExcludeAttributesDef);

            excludeAttrsOp.ExcludeAttributes = new List <string>()
            {
                "name", "value"
            };
            projection.Operations.Add(excludeAttrsOp);

            // Create an entity reference to hold this projection
            CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef.ExplicitReference = projection;

            // Set the entity's ExtendEntity to be the projection
            entity.ExtendsEntity = projectionEntityRef;

            // Resolve the entity
            CdmEntityDefinition resolvedEntity = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", null, localRoot);

            // Verify correctness of the resolved attributes after running the ExcludeAttributes operation
            // Original set of attributes: ["id", "name", "value", "date"]
            // Excluded attributes: ["name", "value"]
            Assert.AreEqual(2, resolvedEntity.Attributes.Count);
            Assert.AreEqual("id", (resolvedEntity.Attributes[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date", (resolvedEntity.Attributes[1] as CdmTypeAttributeDefinition).Name);
        }
        public static Projection ToData(CdmProjection instance, ResolveOptions resOpt, CopyOptions options)
        {
            if (instance == null)
            {
                return(null);
            }

            dynamic source = null;

            if (instance.Source != null && instance.Source.GetType() == typeof(string))
            {
                source = instance.Source;
            }
            else if (instance.Source != null && !string.IsNullOrWhiteSpace(instance.Source.NamedReference) && instance.Source.ExplicitReference == null)
            {
                source = instance.Source.NamedReference;
            }
            else if (instance.Source != null && instance.Source.GetType() == typeof(CdmEntityReference))
            {
                source = EntityReferencePersistence.ToData(instance.Source, resOpt, options);
            }

            List <OperationBase> operations = null;

            if (instance.Operations != null && instance.Operations.Count > 0)
            {
                operations = new List <OperationBase>();
                foreach (CdmOperationBase operation in instance.Operations)
                {
                    switch (operation.ObjectType)
                    {
                    case CdmObjectType.OperationAddCountAttributeDef:
                        OperationAddCountAttribute addCountAttributeOp = OperationAddCountAttributePersistence.ToData(operation as CdmOperationAddCountAttribute, resOpt, options);
                        operations.Add(addCountAttributeOp);
                        break;

                    case CdmObjectType.OperationAddSupportingAttributeDef:
                        OperationAddSupportingAttribute addSupportingAttributeOp = OperationAddSupportingAttributePersistence.ToData(operation as CdmOperationAddSupportingAttribute, resOpt, options);
                        operations.Add(addSupportingAttributeOp);
                        break;

                    case CdmObjectType.OperationAddTypeAttributeDef:
                        OperationAddTypeAttribute addTypeAttributeOp = OperationAddTypeAttributePersistence.ToData(operation as CdmOperationAddTypeAttribute, resOpt, options);
                        operations.Add(addTypeAttributeOp);
                        break;

                    case CdmObjectType.OperationExcludeAttributesDef:
                        OperationExcludeAttributes excludeAttributesOp = OperationExcludeAttributesPersistence.ToData(operation as CdmOperationExcludeAttributes, resOpt, options);
                        operations.Add(excludeAttributesOp);
                        break;

                    case CdmObjectType.OperationArrayExpansionDef:
                        OperationArrayExpansion arrayExpansionOp = OperationArrayExpansionPersistence.ToData(operation as CdmOperationArrayExpansion, resOpt, options);
                        operations.Add(arrayExpansionOp);
                        break;

                    case CdmObjectType.OperationCombineAttributesDef:
                        OperationCombineAttributes combineAttributesOp = OperationCombineAttributesPersistence.ToData(operation as CdmOperationCombineAttributes, resOpt, options);
                        operations.Add(combineAttributesOp);
                        break;

                    case CdmObjectType.OperationRenameAttributesDef:
                        OperationRenameAttributes renameAttributesOp = OperationRenameAttributesPersistence.ToData(operation as CdmOperationRenameAttributes, resOpt, options);
                        operations.Add(renameAttributesOp);
                        break;

                    case CdmObjectType.OperationReplaceAsForeignKeyDef:
                        OperationReplaceAsForeignKey replaceAsForeignKeyOp = OperationReplaceAsForeignKeyPersistence.ToData(operation as CdmOperationReplaceAsForeignKey, resOpt, options);
                        operations.Add(replaceAsForeignKeyOp);
                        break;

                    case CdmObjectType.OperationIncludeAttributesDef:
                        OperationIncludeAttributes includeAttributesOp = OperationIncludeAttributesPersistence.ToData(operation as CdmOperationIncludeAttributes, resOpt, options);
                        operations.Add(includeAttributesOp);
                        break;

                    case CdmObjectType.OperationAddAttributeGroupDef:
                        OperationAddAttributeGroup addAttributeGroupOp = OperationAddAttributeGroupPersistence.ToData(operation as CdmOperationAddAttributeGroup, resOpt, options);
                        operations.Add(addAttributeGroupOp);
                        break;

                    default:
                        OperationBase baseOp = new OperationBase();
                        baseOp.Type = OperationTypeConvertor.OperationTypeToString(CdmOperationType.Error);
                        operations.Add(baseOp);
                        break;
                    }
                }
            }

            return(new Projection
            {
                Explanation = instance.Explanation,
                Source = source,
                Operations = operations,
                Condition = instance.Condition,
                RunSequentially = instance.RunSequentially
            });
        }
Exemple #19
0
        public async Task TestConditionalProjUsingObjectModel()
        {
            CdmCorpusDefinition corpus = ProjectionTestUtils.GetLocalCorpus(testsSubpath, "TestConditionalProjUsingObjectModel");

            corpus.Storage.Mount("local", new LocalAdapter(TestHelper.GetActualOutputFolderPath(testsSubpath, "TestConditionalProjUsingObjectModel")));
            CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local");

            // Create an entity
            CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot);

            // Create a projection with a condition that states the operation should only execute when the resolution directive is 'referenceOnly'
            CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot);

            projection.Condition = "referenceOnly==true";

            // Create an AddTypeAttribute operation
            CdmOperationAddTypeAttribute addTypeAttrOp = corpus.MakeObject <CdmOperationAddTypeAttribute>(CdmObjectType.OperationAddTypeAttributeDef);

            addTypeAttrOp.TypeAttribute          = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, "testType");
            addTypeAttrOp.TypeAttribute.DataType = corpus.MakeRef <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "entityName", true);
            projection.Operations.Add(addTypeAttrOp);

            // Create an entity reference to hold this projection
            CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef.ExplicitReference = projection;

            // Create an entity attribute that contains this projection and add this to the entity
            CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute");

            entityAttribute.Entity = projectionEntityRef;
            entity.Attributes.Add(entityAttribute);

            // Create resolution options with the 'referenceOnly' directive
            ResolveOptions resOpt = new ResolveOptions(entity.InDocument);

            resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> {
                "referenceOnly"
            });

            // Resolve the entity with 'referenceOnly'
            CdmEntityDefinition resolvedEntityWithReferenceOnly = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot);

            // Verify correctness of the resolved attributes after running the AddTypeAttribute operation
            // Original set of attributes: ["id", "name", "value", "date"]
            // Type attribute: "testType"
            Assert.AreEqual(5, resolvedEntityWithReferenceOnly.Attributes.Count);
            Assert.AreEqual("id", (resolvedEntityWithReferenceOnly.Attributes[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name", (resolvedEntityWithReferenceOnly.Attributes[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value", (resolvedEntityWithReferenceOnly.Attributes[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date", (resolvedEntityWithReferenceOnly.Attributes[3] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("testType", (resolvedEntityWithReferenceOnly.Attributes[4] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("is.linkedEntity.name", resolvedEntityWithReferenceOnly.Attributes[4].AppliedTraits[4].NamedReference);

            // Now resolve the entity with the 'structured' directive
            resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> {
                "structured"
            });
            CdmEntityDefinition resolvedEntityWithStructured = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot);

            // Verify correctness of the resolved attributes after running the AddTypeAttribute operation
            // Original set of attributes: ["id", "name", "value", "date"]
            // No Type attribute added, condition was false
            Assert.AreEqual(4, resolvedEntityWithStructured.Attributes.Count);
            Assert.AreEqual("id", (resolvedEntityWithStructured.Attributes[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name", (resolvedEntityWithStructured.Attributes[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value", (resolvedEntityWithStructured.Attributes[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date", (resolvedEntityWithStructured.Attributes[3] as CdmTypeAttributeDefinition).Name);
        }
Exemple #20
0
        /// <summary>
        /// Create a projection object with operations
        /// </summary>
        /// <param name="corpus"></param>
        /// <returns></returns>
        private CdmProjection CreateProjectionWithOperationCollection(CdmCorpusDefinition corpus, CdmObject owner)
        {
            CdmProjection projection = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef);

            {
                projection.Source = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, "TestSource", simpleNameRef: true);
            }

            {
                // AddCountAttribute Operation
                CdmOperationAddCountAttribute addCountAttributeOp = new CdmOperationAddCountAttribute(corpus.Ctx)
                {
                    CountAttribute = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef)
                };
                projection.Operations.Add(addCountAttributeOp);

                // AddSupportingAttribute Operation
                CdmOperationAddSupportingAttribute addSupportingAttributesOp = new CdmOperationAddSupportingAttribute(corpus.Ctx)
                {
                    SupportingAttribute = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef)
                };
                projection.Operations.Add(addSupportingAttributesOp);

                // AddTypeAttribute Operation
                CdmOperationAddTypeAttribute addTypeAttributeOp = new CdmOperationAddTypeAttribute(corpus.Ctx)
                {
                    TypeAttribute = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef)
                };
                projection.Operations.Add(addTypeAttributeOp);

                // ExcludeAttributes Operation
                CdmOperationExcludeAttributes excludeAttributesOp = new CdmOperationExcludeAttributes(corpus.Ctx)
                {
                    ExcludeAttributes = new List <string>()
                };
                excludeAttributesOp.ExcludeAttributes.Add("testAttribute1");
                projection.Operations.Add(excludeAttributesOp);

                // ArrayExpansion Operation
                CdmOperationArrayExpansion arrayExpansionOp = new CdmOperationArrayExpansion(corpus.Ctx)
                {
                    StartOrdinal = 0,
                    EndOrdinal   = 1
                };
                projection.Operations.Add(arrayExpansionOp);

                // CombineAttributes Operation
                CdmOperationCombineAttributes combineAttributesOp = new CdmOperationCombineAttributes(corpus.Ctx)
                {
                    Take      = new List <string>(),
                    MergeInto = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef)
                };
                combineAttributesOp.Take.Add("testAttribute1");
                projection.Operations.Add(combineAttributesOp);

                // RenameAttributes Operation
                CdmOperationRenameAttributes renameAttributesOp = new CdmOperationRenameAttributes(corpus.Ctx)
                {
                    RenameFormat = "{m}"
                };
                projection.Operations.Add(renameAttributesOp);

                // ReplaceAsForeignKey Operation
                CdmOperationReplaceAsForeignKey replaceAsForeignKeyOp = new CdmOperationReplaceAsForeignKey(corpus.Ctx)
                {
                    Reference   = "testAttribute1",
                    ReplaceWith = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, "testForeignKey", simpleNameRef: false)
                };
                projection.Operations.Add(replaceAsForeignKeyOp);

                // IncludeAttributes Operation
                CdmOperationIncludeAttributes includeAttributesOp = new CdmOperationIncludeAttributes(corpus.Ctx)
                {
                    IncludeAttributes = new List <string>()
                };
                includeAttributesOp.IncludeAttributes.Add("testAttribute1");
                projection.Operations.Add(includeAttributesOp);
            }

            return(projection);
        }
Exemple #21
0
        public async Task TestConditionalProjUsingObjectModel()
        {
            string testName               = nameof(TestConditionalProjUsingObjectModel);
            CdmCorpusDefinition corpus    = TestHelper.GetLocalCorpus(testsSubpath, testName);
            CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local");

            corpus.Storage.Mount("traitGroup", new LocalAdapter(traitGroupFilePath));

            // Create an entity.
            CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot);

            entity.InDocument.Imports.Add("traitGroup:/TraitGroup.cdm.json");

            // Create a projection with a condition that states the operation should only execute when the resolution directive is 'structured'.
            CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot);

            projection.Condition       = "structured==true";
            projection.RunSequentially = true;

            // Create an AlterTraits operation
            CdmOperationAlterTraits alterTraitsOp_1 = corpus.MakeObject <CdmOperationAlterTraits>(CdmObjectType.OperationAlterTraitsDef);

            alterTraitsOp_1.TraitsToAdd = new CdmCollection <CdmTraitReferenceBase>(corpus.Ctx, alterTraitsOp_1, CdmObjectType.TraitRef);
            alterTraitsOp_1.TraitsToAdd.Add(corpus.MakeRef <CdmTraitReference>(CdmObjectType.TraitRef, "means.TraitG100", true));
            alterTraitsOp_1.TraitsToAdd.Add(corpus.MakeRef <CdmTraitGroupReference>(CdmObjectType.TraitGroupRef, "JobTitleBase", true));
            alterTraitsOp_1.TraitsToRemove = new CdmCollection <CdmTraitReferenceBase>(corpus.Ctx, alterTraitsOp_1, CdmObjectType.TraitRef);
            alterTraitsOp_1.TraitsToRemove.Add(corpus.MakeRef <CdmTraitReference>(CdmObjectType.TraitRef, "means.TraitG300", true));
            projection.Operations.Add(alterTraitsOp_1);

            CdmOperationAlterTraits alterTraitsOp_2 = corpus.MakeObject <CdmOperationAlterTraits>(CdmObjectType.OperationAlterTraitsDef);
            var traitG4 = corpus.MakeRef <CdmTraitReference>(CdmObjectType.TraitRef, "means.TraitG4", true);

            traitG4.Arguments.Add("precision", "5");
            traitG4.Arguments.Add("scale", "15");
            alterTraitsOp_2.TraitsToAdd = new CdmCollection <CdmTraitReferenceBase>(corpus.Ctx, alterTraitsOp_2, CdmObjectType.TraitRef);
            alterTraitsOp_2.TraitsToAdd.Add(traitG4);
            alterTraitsOp_2.ApplyTo = new List <string>()
            {
                "name"
            };
            projection.Operations.Add(alterTraitsOp_2);

            // Create an entity reference to hold this projection.
            CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef.ExplicitReference = projection;

            // Create an entity attribute that contains this projection and add this to the entity.
            CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute");

            entityAttribute.Entity = projectionEntityRef;
            entity.Attributes.Add(entityAttribute);

            // Create resolution options with the 'referenceOnly' directive.
            ResolveOptions resOpt = new ResolveOptions(entity.InDocument)
            {
                Directives = new AttributeResolutionDirectiveSet(new HashSet <string> {
                    "referenceOnly"
                })
            };
            CdmEntityDefinition resolvedEntityWithReferenceOnly = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot);

            // Original set of attributes: ["name", "age", "address", "phoneNumber", "email"]
            // Condition not met, no traits are added
            Assert.AreEqual(4, resolvedEntityWithReferenceOnly.Attributes.Count);
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithReferenceOnly.Attributes[0], "id", doesNotExist: true);
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithReferenceOnly.Attributes[1], "name", doesNotExist: true);
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithReferenceOnly.Attributes[2], "value", doesNotExist: true);
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithReferenceOnly.Attributes[3], "date", doesNotExist: true);

            CdmEntityDefinition resolvedEntityWithStructured = await ProjectionTestUtils.GetResolvedEntity(corpus, entity, new List <string> {
                "structured"
            });

            // Original set of attributes: ["name", "age", "address", "phoneNumber", "email"]
            // Condition met, new traits are added
            Assert.AreEqual(4, resolvedEntityWithStructured.Attributes.Count);
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithStructured.Attributes[0], "id");
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithStructured.Attributes[1], "name", true);
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithStructured.Attributes[2], "value");
            ValidateTrait((CdmTypeAttributeDefinition)resolvedEntityWithStructured.Attributes[3], "date");
        }
        public static CdmEntityAttributeDefinition FromData(CdmCorpusContext ctx, JToken obj)
        {
            var entityAttribute = ctx.Corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, (string)obj["name"]);

            entityAttribute.Description = Utils.PropertyFromDataToString(obj["description"]);
            entityAttribute.DisplayName = Utils.PropertyFromDataToString(obj["displayName"]);
            entityAttribute.Explanation = Utils.PropertyFromDataToString(obj["explanation"]);

            if (obj["cardinality"] != null)
            {
                string minCardinality = null;
                if (obj["cardinality"]["minimum"] != null)
                {
                    minCardinality = (string)obj["cardinality"]["minimum"];
                }

                string maxCardinality = null;
                if (obj["cardinality"]["maximum"] != null)
                {
                    maxCardinality = (string)obj["cardinality"]["maximum"];
                }

                if (string.IsNullOrWhiteSpace(minCardinality) || string.IsNullOrWhiteSpace(maxCardinality))
                {
                    Logger.Error(nameof(EntityAttributePersistence), ctx, $"Both minimum and maximum are required for the Cardinality property.", nameof(FromData));
                }

                if (!CardinalitySettings.IsMinimumValid(minCardinality))
                {
                    Logger.Error(nameof(EntityAttributePersistence), ctx, $"Invalid minimum cardinality {minCardinality}.", nameof(FromData));
                }

                if (!CardinalitySettings.IsMaximumValid(maxCardinality))
                {
                    Logger.Error(nameof(EntityAttributePersistence), ctx, $"Invalid maximum cardinality {maxCardinality}.", nameof(FromData));
                }

                if (!string.IsNullOrWhiteSpace(minCardinality) &&
                    !string.IsNullOrWhiteSpace(maxCardinality) &&
                    CardinalitySettings.IsMinimumValid(minCardinality) &&
                    CardinalitySettings.IsMinimumValid(maxCardinality))
                {
                    entityAttribute.Cardinality = new CardinalitySettings(entityAttribute)
                    {
                        Minimum = minCardinality,
                        Maximum = maxCardinality
                    };
                }
            }

            entityAttribute.IsPolymorphicSource = (bool?)obj["isPolymorphicSource"];

            bool isProjection = obj["entity"] != null &&
                                !(obj["entity"] is JValue) &&
                                obj["entity"]["source"] != null;

            if (isProjection)
            {
                CdmProjection projection = ProjectionPersistence.FromData(ctx, obj["entity"]);
                projection.Owner = entityAttribute;

                CdmEntityReference inlineEntityRef = ctx.Corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);
                inlineEntityRef.ExplicitReference = projection;
                entityAttribute.Entity            = inlineEntityRef;
            }
            else
            {
                entityAttribute.Entity = EntityReferencePersistence.FromData(ctx, obj["entity"]);
            }

            entityAttribute.Purpose = PurposeReferencePersistence.FromData(ctx, obj["purpose"]);
            Utils.AddListToCdmCollection(entityAttribute.AppliedTraits, Utils.CreateTraitReferenceList(ctx, obj["appliedTraits"]));
            // ignore resolution guidance if the entity is a projection
            if (obj["resolutionGuidance"] != null && isProjection)
            {
                Logger.Error(nameof(EntityAttributePersistence), ctx, $"The EntityAttribute {entityAttribute.Name} is projection based. Resolution guidance is not supported with a projection.");
            }
            else
            {
                entityAttribute.ResolutionGuidance = AttributeResolutionGuidancePersistence.FromData(ctx, obj["resolutionGuidance"]);
            }
            return(entityAttribute);
        }
        public async Task TestConditionalProjUsingObjectModel()
        {
            string testName               = nameof(TestConditionalProjUsingObjectModel);
            CdmCorpusDefinition corpus    = TestHelper.GetLocalCorpus(testsSubpath, testName);
            CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local");

            // Create an entity.
            CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot);

            // Create a projection with a condition that states the operation should only execute when the resolution directive is 'structured'.
            CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot);

            projection.Condition = "structured==true";

            // Create an AddArtifactAttribute operation
            CdmOperationAddArtifactAttribute addArtifactAttributeOp = corpus.MakeObject <CdmOperationAddArtifactAttribute>(CdmObjectType.OperationAddArtifactAttributeDef);

            addArtifactAttributeOp.NewAttribute = corpus.MakeObject <CdmTypeAttributeDefinition>(CdmObjectType.TypeAttributeDef, "newName");
            ((CdmTypeAttributeDefinition)addArtifactAttributeOp.NewAttribute).DataType = corpus.MakeRef <CdmDataTypeReference>(CdmObjectType.DataTypeRef, "string", true);
            projection.Operations.Add(addArtifactAttributeOp);

            // Create an entity reference to hold this projection.
            CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef.ExplicitReference = projection;

            // Create an entity attribute that contains this projection and add this to the entity.
            CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute");

            entityAttribute.Entity = projectionEntityRef;
            entity.Attributes.Add(entityAttribute);

            // Create resolution options with the 'referenceOnly' directive.
            ResolveOptions resOpt = new ResolveOptions(entity.InDocument)
            {
                Directives = new AttributeResolutionDirectiveSet(new HashSet <string> {
                    "referenceOnly"
                })
            };

            // Resolve the entity with 'referenceOnly'
            CdmEntityDefinition resolvedEntityWithReferenceOnly = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot);

            // Original set of attributes: ["id", "name", "value", "date"]
            // Condition not met, keep attributes in flat list
            Assert.AreEqual(4, resolvedEntityWithReferenceOnly.Attributes.Count);
            Assert.AreEqual("id", (resolvedEntityWithReferenceOnly.Attributes[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name", (resolvedEntityWithReferenceOnly.Attributes[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value", (resolvedEntityWithReferenceOnly.Attributes[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date", (resolvedEntityWithReferenceOnly.Attributes[3] as CdmTypeAttributeDefinition).Name);

            // Now resolve the entity with the 'structured' directive
            resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> {
                "structured"
            });
            CdmEntityDefinition resolvedEntityWithStructured = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot);

            // Original set of attributes: ["id", "name", "value", "date"]
            // Condition met, keep attributes in flat list and add the new attribute "newName" all attributes at the end
            Assert.AreEqual(5, resolvedEntityWithStructured.Attributes.Count);
            Assert.AreEqual("id", (resolvedEntityWithStructured.Attributes[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name", (resolvedEntityWithStructured.Attributes[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value", (resolvedEntityWithStructured.Attributes[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date", (resolvedEntityWithStructured.Attributes[3] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("newName", (resolvedEntityWithStructured.Attributes[4] as CdmTypeAttributeDefinition).Name);
        }
        public async Task TestConditionalProjUsingObjectModel()
        {
            CdmCorpusDefinition corpus = ProjectionTestUtils.GetLocalCorpus(testsSubpath, "TestConditionalProjUsingObjectModel");

            corpus.Storage.Mount("local", new LocalAdapter(TestHelper.GetActualOutputFolderPath(testsSubpath, "TestConditionalProjUsingObjectModel")));
            CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local");

            // Create an entity
            CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot);

            // Create a projection with a condition that states the operation should only execute when the resolution directive is 'referenceOnly'
            CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot);

            projection.Condition = "referenceOnly==true";

            // Create an ArrayExpansion operation
            CdmOperationArrayExpansion arrayExpansionOp = corpus.MakeObject <CdmOperationArrayExpansion>(CdmObjectType.OperationArrayExpansionDef);

            arrayExpansionOp.StartOrdinal = 1;
            arrayExpansionOp.EndOrdinal   = 2;
            projection.Operations.Add(arrayExpansionOp);

            // Create an entity reference to hold this projection
            CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef.ExplicitReference = projection;

            // Create another projection that does a rename so that we can see the expanded attributes in the final resolved entity
            CdmProjection projection2 = corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef);

            projection2.Source = projectionEntityRef;

            // Create a RenameAttributes operation
            CdmOperationRenameAttributes renameAttrsOp = corpus.MakeObject <CdmOperationRenameAttributes>(CdmObjectType.OperationRenameAttributesDef);

            renameAttrsOp.RenameFormat = "{m}{o}";
            projection2.Operations.Add(renameAttrsOp);

            // Create an entity reference to hold this projection
            CdmEntityReference projectionEntityRef2 = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef2.ExplicitReference = projection2;

            // Create an entity attribute that contains this projection and add this to the entity
            CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute");

            entityAttribute.Entity = projectionEntityRef2;
            entity.Attributes.Add(entityAttribute);

            // Create resolution options with the 'referenceOnly' directive
            ResolveOptions resOpt = new ResolveOptions(entity.InDocument);

            resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> {
                "referenceOnly"
            });

            // Resolve the entity with 'referenceOnly'
            CdmEntityDefinition resolvedEntityWithReferenceOnly = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot);

            // Verify correctness of the resolved attributes after running the projections
            // Original set of attributes: ["id", "name", "value", "date"]
            // Expand 1...2, renameFormat = {m}{o}
            Assert.AreEqual(8, resolvedEntityWithReferenceOnly.Attributes.Count);
            Assert.AreEqual("id1", (resolvedEntityWithReferenceOnly.Attributes[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name1", (resolvedEntityWithReferenceOnly.Attributes[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value1", (resolvedEntityWithReferenceOnly.Attributes[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date1", (resolvedEntityWithReferenceOnly.Attributes[3] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("id2", (resolvedEntityWithReferenceOnly.Attributes[4] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name2", (resolvedEntityWithReferenceOnly.Attributes[5] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value2", (resolvedEntityWithReferenceOnly.Attributes[6] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date2", (resolvedEntityWithReferenceOnly.Attributes[7] as CdmTypeAttributeDefinition).Name);

            // Now resolve the entity with the default directives
            resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> {
            });
            CdmEntityDefinition resolvedEntityWithStructured = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot);

            // Verify correctness of the resolved attributes after running the projections
            // Original set of attributes: ["id", "name", "value", "date"]
            // Expand 1...2, renameFormat = {m}{o}
            Assert.AreEqual(4, resolvedEntityWithStructured.Attributes.Count);
            Assert.AreEqual("id", (resolvedEntityWithStructured.Attributes[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name", (resolvedEntityWithStructured.Attributes[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value", (resolvedEntityWithStructured.Attributes[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date", (resolvedEntityWithStructured.Attributes[3] as CdmTypeAttributeDefinition).Name);
        }
        public static CdmProjection FromData(CdmCorpusContext ctx, JToken obj)
        {
            if (obj == null)
            {
                return(null);
            }

            CdmProjection projection = ctx.Corpus.MakeObject <CdmProjection>(CdmObjectType.ProjectionDef);

            CdmEntityReference source = EntityReferencePersistence.FromData(ctx, obj["source"]);

            if (obj["explanation"] != null)
            {
                projection.Explanation = (string)obj["explanation"];
            }

            projection.Condition       = obj["condition"]?.ToString();
            projection.RunSequentially = (bool?)obj["runSequentially"];

            if (obj["operations"] != null)
            {
                List <JObject> operationJsons = obj["operations"]?.ToObject <List <JObject> >();
                foreach (JObject operationJson in operationJsons)
                {
                    string type = (string)operationJson["$type"];
                    switch (type)
                    {
                    case "addCountAttribute":
                        CdmOperationAddCountAttribute addCountAttributeOp = OperationAddCountAttributePersistence.FromData(ctx, operationJson);
                        projection.Operations.Add(addCountAttributeOp);
                        break;

                    case "addSupportingAttribute":
                        CdmOperationAddSupportingAttribute addSupportingAttributeOp = OperationAddSupportingAttributePersistence.FromData(ctx, operationJson);
                        projection.Operations.Add(addSupportingAttributeOp);
                        break;

                    case "addTypeAttribute":
                        CdmOperationAddTypeAttribute addTypeAttributeOp = OperationAddTypeAttributePersistence.FromData(ctx, operationJson);
                        projection.Operations.Add(addTypeAttributeOp);
                        break;

                    case "excludeAttributes":
                        CdmOperationExcludeAttributes excludeAttributesOp = OperationExcludeAttributesPersistence.FromData(ctx, operationJson);
                        projection.Operations.Add(excludeAttributesOp);
                        break;

                    case "arrayExpansion":
                        CdmOperationArrayExpansion arrayExpansionOp = OperationArrayExpansionPersistence.FromData(ctx, operationJson);
                        projection.Operations.Add(arrayExpansionOp);
                        break;

                    case "combineAttributes":
                        CdmOperationCombineAttributes combineAttributesOp = OperationCombineAttributesPersistence.FromData(ctx, operationJson);
                        projection.Operations.Add(combineAttributesOp);
                        break;

                    case "renameAttributes":
                        CdmOperationRenameAttributes renameAttributesOp = OperationRenameAttributesPersistence.FromData(ctx, operationJson);
                        projection.Operations.Add(renameAttributesOp);
                        break;

                    case "replaceAsForeignKey":
                        CdmOperationReplaceAsForeignKey replaceAsForeignKeyOp = OperationReplaceAsForeignKeyPersistence.FromData(ctx, operationJson);
                        projection.Operations.Add(replaceAsForeignKeyOp);
                        break;

                    case "includeAttributes":
                        CdmOperationIncludeAttributes includeAttributesOp = OperationIncludeAttributesPersistence.FromData(ctx, operationJson);
                        projection.Operations.Add(includeAttributesOp);
                        break;

                    case "addAttributeGroup":
                        CdmOperationAddAttributeGroup addAttributeGroupOp = OperationAddAttributeGroupPersistence.FromData(ctx, operationJson);
                        projection.Operations.Add(addAttributeGroupOp);
                        break;

                    default:
                        Logger.Error(nameof(ProjectionPersistence), ctx, $"Invalid operation type '{type}'.", nameof(FromData));
                        break;
                    }
                }
            }

            projection.Source = source;

            return(projection);
        }
Exemple #26
0
        public async Task TestEAProjOM()
        {
            string className = "ProjectionCombineTest";
            string testName  = "TestEAProjOM";

            string entityName_Email = "Email";
            List <TypeAttributeParam> attributeParams_Email = new List <TypeAttributeParam>();
            {
                attributeParams_Email.Add(new TypeAttributeParam("EmailID", "string", "identifiedBy"));
                attributeParams_Email.Add(new TypeAttributeParam("Address", "string", "hasA"));
                attributeParams_Email.Add(new TypeAttributeParam("IsPrimary", "boolean", "hasA"));
            }

            string entityName_Phone = "Phone";
            List <TypeAttributeParam> attributeParams_Phone = new List <TypeAttributeParam>();
            {
                attributeParams_Phone.Add(new TypeAttributeParam("PhoneID", "string", "identifiedBy"));
                attributeParams_Phone.Add(new TypeAttributeParam("Number", "string", "hasA"));
                attributeParams_Phone.Add(new TypeAttributeParam("IsPrimary", "boolean", "hasA"));
            }

            string entityName_Social = "Social";
            List <TypeAttributeParam> attributeParams_Social = new List <TypeAttributeParam>();
            {
                attributeParams_Social.Add(new TypeAttributeParam("SocialID", "string", "identifiedBy"));
                attributeParams_Social.Add(new TypeAttributeParam("Account", "string", "hasA"));
                attributeParams_Social.Add(new TypeAttributeParam("IsPrimary", "boolean", "hasA"));
            }

            string entityName_Customer = "Customer";
            List <TypeAttributeParam> attributeParams_Customer = new List <TypeAttributeParam>();
            {
                attributeParams_Customer.Add(new TypeAttributeParam("CustomerName", "string", "hasA"));
            }

            List <string> selectedAttributes = new List <string>()
            {
                "EmailID",
                "PhoneID",
                "SocialID"
            };

            using (ProjectionOMTestUtil util = new ProjectionOMTestUtil(className, testName))
            {
                CdmEntityDefinition entity_Email = util.CreateBasicEntity(entityName_Email, attributeParams_Email);
                util.ValidateBasicEntity(entity_Email, entityName_Email, attributeParams_Email);

                CdmEntityDefinition entity_Phone = util.CreateBasicEntity(entityName_Phone, attributeParams_Phone);
                util.ValidateBasicEntity(entity_Phone, entityName_Phone, attributeParams_Phone);

                CdmEntityDefinition entity_Social = util.CreateBasicEntity(entityName_Social, attributeParams_Social);
                util.ValidateBasicEntity(entity_Social, entityName_Social, attributeParams_Social);

                CdmEntityDefinition entity_Customer = util.CreateBasicEntity(entityName_Customer, attributeParams_Customer);
                util.ValidateBasicEntity(entity_Customer, entityName_Customer, attributeParams_Customer);

                CdmProjection projection_Customer = util.CreateProjection(entity_Customer.EntityName);
                CdmTypeAttributeDefinition    typeAttribute_MergeInto      = util.CreateTypeAttribute("MergeInto", "string", "hasA");
                CdmOperationCombineAttributes operation_CombineAttributes  = util.CreateOperationCombineAttributes(projection_Customer, selectedAttributes, typeAttribute_MergeInto);
                CdmEntityReference            projectionEntityRef_Customer = util.CreateProjectionInlineEntityReference(projection_Customer);

                CdmEntityAttributeDefinition entityAttribute_ContactAt = util.CreateEntityAttribute("ContactAt", projectionEntityRef_Customer);
                entity_Customer.Attributes.Add(entityAttribute_ContactAt);

                foreach (List <string> resOpts in resOptsCombinations)
                {
                    await util.GetAndValidateResolvedEntity(entity_Customer, resOpts);
                }

                await util.DefaultManifest.SaveAsAsync(util.ManifestDocName, saveReferenced : true);
            }
        }
        public async Task TestConditionalProjUsingObjectModel()
        {
            string testName               = "TestConditionalProjUsingObjectModel";
            CdmCorpusDefinition corpus    = ProjectionTestUtils.GetCorpus(testName, testsSubpath);
            CdmFolderDefinition localRoot = corpus.Storage.FetchRootFolder("local");

            // Create an entity.
            CdmEntityDefinition entity = ProjectionTestUtils.CreateEntity(corpus, localRoot);

            // Create a projection with a condition that states the operation should only execute when the resolution directive is 'structured'.
            CdmProjection projection = ProjectionTestUtils.CreateProjection(corpus, localRoot);

            projection.Condition = "structured==true";

            // Create an AddAttributeGroup operation
            CdmOperationAddAttributeGroup addAttGroupOp = corpus.MakeObject <CdmOperationAddAttributeGroup>(CdmObjectType.OperationAddAttributeGroupDef);

            addAttGroupOp.AttributeGroupName = "PersonAttributeGroup";
            projection.Operations.Add(addAttGroupOp);

            // Create an entity reference to hold this projection.
            CdmEntityReference projectionEntityRef = corpus.MakeObject <CdmEntityReference>(CdmObjectType.EntityRef, null);

            projectionEntityRef.ExplicitReference = projection;

            // Create an entity attribute that contains this projection and add this to the entity.
            CdmEntityAttributeDefinition entityAttribute = corpus.MakeObject <CdmEntityAttributeDefinition>(CdmObjectType.EntityAttributeDef, "TestEntityAttribute");

            entityAttribute.Entity = projectionEntityRef;
            entity.Attributes.Add(entityAttribute);

            // Create resolution options with the 'referenceOnly' directive.
            ResolveOptions resOpt = new ResolveOptions(entity.InDocument)
            {
                Directives = new AttributeResolutionDirectiveSet(new HashSet <string> {
                    "referenceOnly"
                })
            };

            // Resolve the entity with 'referenceOnly'
            CdmEntityDefinition resolvedEntityWithReferenceOnly = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot);

            // Verify correctness of the resolved attributes after running the AddAttributeGroup operation
            // Original set of attributes: ["id", "name", "value", "date"]
            // Condition not met, keep attributes in flat list
            Assert.AreEqual(4, resolvedEntityWithReferenceOnly.Attributes.Count);
            Assert.AreEqual("id", (resolvedEntityWithReferenceOnly.Attributes[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name", (resolvedEntityWithReferenceOnly.Attributes[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value", (resolvedEntityWithReferenceOnly.Attributes[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date", (resolvedEntityWithReferenceOnly.Attributes[3] as CdmTypeAttributeDefinition).Name);

            // Now resolve the entity with the 'structured' directive
            resOpt.Directives = new AttributeResolutionDirectiveSet(new HashSet <string> {
                "structured"
            });
            CdmEntityDefinition resolvedEntityWithStructured = await entity.CreateResolvedEntityAsync($"Resolved_{entity.EntityName}.cdm.json", resOpt, localRoot);

            // Verify correctness of the resolved attributes after running the AddAttributeGroup operation
            // Original set of attributes: ["id", "name", "value", "date"]
            // Condition met, put all attributes in an attribute group
            CdmAttributeGroupDefinition attGroupDefinition = this.ValidateAttributeGroup(resolvedEntityWithStructured.Attributes, "PersonAttributeGroup");

            Assert.AreEqual(4, attGroupDefinition.Members.Count);
            Assert.AreEqual("id", (attGroupDefinition.Members[0] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("name", (attGroupDefinition.Members[1] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("value", (attGroupDefinition.Members[2] as CdmTypeAttributeDefinition).Name);
            Assert.AreEqual("date", (attGroupDefinition.Members[3] as CdmTypeAttributeDefinition).Name);
        }