/// <summary> /// Builds the resource expression. /// </summary> /// <param name="resourceExpression">The resource expression.</param> /// <returns>ResourceExpression.</returns> /// <param name="context"></param> private static ResourceExpression BuildResourceExpression(Model.ResourceExpression resourceExpression, FromEntityContext context) { //resourceExpression entity node's followRelationship must not be null RelationshipReportNode relationshipReportNode = resourceExpression.SourceNode.As <RelationshipReportNode>(); if (relationshipReportNode != null) { if (relationshipReportNode.FollowRelationship == null) { EventLog.Application.WriteWarning(context.DebugInfo + "relationshipReportNode.FollowRelationship was null"); return(null); } } //resourceExpression sourceNode is null means that the source entity is removed if (resourceExpression.SourceNode == null) { EventLog.Application.WriteWarning(context.DebugInfo + "resourceExpression.SourceNode was null"); return(null); } long targetTypeId = 0; TypedArgument ta = resourceExpression.ReportExpressionResultType.As <TypedArgument>(); if (ta != null && ta.ConformsToType != null) { targetTypeId = ta.ConformsToType.Id; } DatabaseType castType = null; if (ta != null && ta.Name != null) { if (ta.Name == "ChoiceRelationship") { castType = new ChoiceRelationshipType(); } else { castType = new InlineRelationshipType(); } } return(new ResourceExpression { FieldId = new EntityRef("core:name"), SourceNodeEntityId = resourceExpression.SourceNode.Id, TargetTypeId = targetTypeId, CastType = castType }); }
/// <summary> /// To check column is valid, /// if field or relationship is removed from object. /// </summary> /// <param name="expression">report column expression</param> /// <remarks> /// the report column expression must be exists, when field is removed from node object, /// the column expression will be deleted, on this case, it is not valid column /// the the column expression is resourceexpression, check the relationship exists or not /// if the relationship is removed, the followRelationship property will be null, current /// column is invalid column /// </remarks> /// <returns></returns> internal static bool IsValidExpression(ReportExpression expression) { if (expression == null) { return(false); } bool isValid = true; //resourceExpression reportnode's followRelationship must not be null Model.ResourceExpression resourceExpression = expression.As <Model.ResourceExpression>(); if (resourceExpression != null) { RelationshipReportNode relationshipReportNode = resourceExpression.SourceNode.As <RelationshipReportNode>(); if (relationshipReportNode != null) { if (relationshipReportNode.FollowRelationship == null) { isValid = false; } } } //if aggregated grouped expression is resourceExpression reportnode's followRelationship must not be null Model.AggregateExpression aggregateExpression = expression.As <Model.AggregateExpression>(); if (aggregateExpression != null) { if (!IsValidExpression(aggregateExpression.AggregatedExpression)) { isValid = false; } } return(isValid); }
/// <summary> /// Populates the analyser type for column. /// </summary> /// <param name="report">The report.</param> /// <param name="entityType">The resource type returned if the analyser refers to a resource expression.</param> /// <param name="reportExpression">The report expression.</param> /// <param name="reportAnalyserColumn">The report analyser column.</param> private static void PopulateAnalyserTypeForColumn(Report report, EntityType entityType, ReportExpression reportExpression, ReportAnalyserColumn reportAnalyserColumn) { reportAnalyserColumn.AnalyserType = reportAnalyserColumn.Type.GetDisplayName(); if (reportExpression.Is <StructureViewExpression>()) { reportAnalyserColumn.AnalyserType = StructureLevelsType.DisplayName; reportAnalyserColumn.DefaultOperator = Structured.ConditionType.AnyBelowStructureLevel; var expression = reportExpression.As <StructureViewExpression>(); var resReportNode = expression.StructureViewExpressionSourceNode.As <ResourceReportNode>(); var eType = resReportNode.ResourceReportNodeType; reportAnalyserColumn.TypeId = eType.Id; return; } if (!reportExpression.Is <NodeExpression>()) { return; } NodeExpression nodeExpression = reportExpression.As <NodeExpression>(); if (!nodeExpression.SourceNode.Is <ResourceReportNode>()) { return; } bool isNameColumnForType = false; if (reportExpression.Is <FieldExpression>()) { var fieldExpression = reportExpression.As <FieldExpression>(); if (fieldExpression.FieldExpressionField.Alias != "core:name") { return; } long sourceId = fieldExpression.SourceNode != null ? fieldExpression.SourceNode.Id : 0; long rootId = report.RootNode != null ? report.RootNode.Id : 0; isNameColumnForType = (sourceId == rootId) && (sourceId != 0); } reportAnalyserColumn.IsNameColumnForType = isNameColumnForType; ResourceReportNode resourceReportNode = nodeExpression.SourceNode.As <ResourceReportNode>( ); RelationshipReportNode relationshipReportNode = nodeExpression.SourceNode.As <RelationshipReportNode>( ); if (entityType == null) { // Need to be able accept entityType as an argument, e.g. if it is from a script column // But also need to be able to read it from the node, e.g. if it is the root name column. Messed up. entityType = resourceReportNode.ResourceReportNodeType; if (entityType == null) { return; } } ResourceExpression resourceExpression = reportExpression.As <ResourceExpression>(); // Handle "Type" types //if the resource type is "Type", add current parent node type and descendant types' id as filtered entity ids (bug 24859) //Update: only the forward relationship is "isOfType", the "type" list will be restricted. (bug 27862) if (entityType.Alias == "core:type" && relationshipReportNode?.FollowRelationship?.Alias == "core:isOfType" ) { AggregateReportNode parentAggregatedNode = resourceReportNode.ParentAggregatedNode; ReportNode parentReportNode = parentAggregatedNode != null ? parentAggregatedNode.GroupedNode : resourceReportNode.ParentReportNode; ResourceReportNode parentResourceReportNode = parentReportNode != null?parentReportNode.As <ResourceReportNode>() : null; if (parentResourceReportNode != null && parentResourceReportNode.ResourceReportNodeType != null) { reportAnalyserColumn.FilteredEntityIds = PerTenantEntityTypeCache.Instance.GetDescendantsAndSelf( parentResourceReportNode.ResourceReportNodeType.Id).ToArray(); } } // Handle "User" and "Person" types if (PerTenantEntityTypeCache.Instance.IsDerivedFrom(entityType.Id, "core:person") || PerTenantEntityTypeCache.Instance.IsDerivedFrom(entityType.Id, "core:userAccount")) { // If this is a relationship or calc then make it as a user inline relationship otherwise a simple user string. reportAnalyserColumn.AnalyserType = nodeExpression.SourceNode.Is <FieldExpression>( ) ? "UserString" : "UserInlineRelationship"; return; } // Treat the root 'Name' column like a lookup, so we get the 'Any Of', 'Any Except' options. if (isNameColumnForType) { reportAnalyserColumn.AnalyserType = "InlineRelationship"; reportAnalyserColumn.TypeId = entityType.Id; } }
/// <summary> /// Builds the relationship report node. /// </summary> /// <param name="reportNode">The report node.</param> /// <param name="context">The context.</param> /// <returns>RelatedResource.</returns> private static RelatedResource BuildRelationshipReportNode(RelationshipReportNode reportNode, FromEntityContext context) { RelatedResource relatedResource = new RelatedResource { ResourceMustExist = reportNode.TargetMustExist ?? false, ResourceNeedNotExist = reportNode.TargetNeedNotExist ?? false, ParentNeedNotExist = reportNode.ParentNeedNotExist ?? false, ExactType = reportNode.ExactType ?? false }; if (reportNode.ResourceReportNodeType != null) { relatedResource.EntityTypeId = reportNode.ResourceReportNodeType.Id; } if (reportNode.FollowInReverse ?? false) { relatedResource.RelationshipDirection = RelationshipDirection.Reverse; } else { relatedResource.RelationshipDirection = RelationshipDirection.Forward; } if (reportNode.FollowRecursive == true) { if (reportNode.IncludeSelfInRecursive == true) { relatedResource.Recursive = RecursionMode.RecursiveWithSelf; } else { relatedResource.Recursive = RecursionMode.Recursive; } } else { relatedResource.Recursive = RecursionMode.None; } Guid nodeId; if (!context.ReportNodeMap.TryGetValue(reportNode.Id, out nodeId)) { nodeId = Guid.NewGuid(); context.ReportNodeMap[reportNode.Id] = nodeId; } relatedResource.NodeId = nodeId; relatedResource.EntityId = reportNode.Id; if (reportNode.FollowRelationship != null) { relatedResource.RelationshipTypeId = reportNode.FollowRelationship.Id; } else { context.ReportInvalidNodes [reportNode.Id] = reportNode.ResourceReportNodeType != null?Model.Entity.GetName(reportNode.ResourceReportNodeType.Id) : ""; EventLog.Application.WriteWarning(context.DebugInfo + "reportNode.FollowRelationship was null"); return(null); } return(relatedResource); }