/// <summary> /// Builds the condition parameter. /// </summary> /// <param name="reportCondition">The report condition.</param> /// <param name="queryCondition">The query condition.</param> /// <param name="context"></param> internal static void BuildConditionParameter([NotNull] ReportCondition reportCondition, QueryCondition queryCondition, FromEntityContext context) { if (reportCondition == null) { throw new ArgumentNullException(nameof(reportCondition)); } ActivityArgument activityArgument; // Get the column expression for the analysable field. If this is a referenced column then use it's referenced column's expression. ReportExpression reportExpression = reportCondition.ConditionExpression; if (reportExpression != null && reportExpression.Is <ColumnReferenceExpression>()) { reportExpression = reportCondition.ConditionExpression.As <ColumnReferenceExpression>() .ExpressionReferencesColumn.ColumnExpression; } if (reportCondition.ConditionParameter?.ParamTypeAndDefault != null) { activityArgument = reportCondition.ConditionParameter.ParamTypeAndDefault; } else if (reportExpression?.ReportExpressionResultType != null) { activityArgument = reportCondition.ConditionExpression.ReportExpressionResultType; } else { EventLog.Application.WriteWarning(context.DebugInfo + "condition parameter could not be processed"); return; } List <TypedValue> typedValues = TypedValueHelper.TypedValueFromEntity(activityArgument); foreach (TypedValue typedValue in typedValues) { queryCondition.Arguments.Add(typedValue); } }
/// <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 expression. /// </summary> /// <param name="reportExpression">The report expression.</param> /// <param name="context">The context.</param> /// <returns>ScalarExpression.</returns> internal static ScalarExpression BuildExpression(ReportExpression reportExpression, FromEntityContext context) { if (reportExpression == null) { EventLog.Application.WriteWarning(context.DebugInfo + "reportExpression was null"); return(null); } // Verify that there is a valid node - prior to converting expressions (invalid nodes may be only partially loaded) // Update the reference table for expressions of interest ignoring anything that is a column expression long nodeId = 0; NodeExpression nodeExpression = reportExpression.As <NodeExpression>( ); if (nodeExpression != null) { nodeId = nodeExpression.SourceNode.Id; // Check that we have a valid node for it if (!context.ReportNodeToEntityMap.ContainsKey(nodeId)) { EventLog.Application.WriteWarning(context.DebugInfo + "expression node could not be found"); return(null); } } // Convert specific expression types ScalarExpression scalarExpression; if (context.InstanceExpressionMap.TryGetValue(reportExpression.Id, out scalarExpression)) { return(scalarExpression); } if (reportExpression.Is <Model.IdExpression>()) { scalarExpression = BuildIdExpression(reportExpression.As <Model.IdExpression>()); } else if (reportExpression.Is <Model.ResourceExpression>()) { scalarExpression = BuildResourceExpression(reportExpression.As <Model.ResourceExpression>(), context); } else if (reportExpression.Is <Model.FieldExpression>()) { scalarExpression = BuildFieldExpression(reportExpression.As <Model.FieldExpression>(), context); } else if (reportExpression.Is <Model.ScriptExpression>()) { scalarExpression = BuildScriptExpression(reportExpression.As <Model.ScriptExpression>()); } else if (reportExpression.Is <Model.AggregateExpression>()) { return(BuildAggregateExpression(reportExpression.As <Model.AggregateExpression>(), context)); } else if (reportExpression.Is <Model.ColumnReferenceExpression>()) { return(BuildColumnReferenceExpression(reportExpression.As <ColumnReferenceExpression>(), context)); } else if (reportExpression.Is <Model.StructureViewExpression>()) { return(BuildStructureViewExpression(reportExpression.As <Model.StructureViewExpression>(), context)); } // Final book keeping if (scalarExpression != null) { if (nodeExpression != null) { Guid key = Guid.NewGuid( ); context.ReportExpressionMap[key] = nodeId; scalarExpression.ExpressionId = key; scalarExpression.EntityId = nodeExpression.Id; } context.InstanceExpressionMap[reportExpression.Id] = scalarExpression; } ApplyExpressionClustering(scalarExpression, reportExpression, context); return(scalarExpression); }