# # # custom_report_util.cfv # Utilities to create custom reports and report elements # # override_common_default_report_parameters() # override_common_default_report_element_parameters() # # set_number_of_rows_in_custom_table() # handle_pivot_table_in_custom_table() # # add_predefined_columns_in_custom_table() # add_single_column_in_custom_table() # # handle_sort_by_in_custom_table() # # set_graph_value_in_custom_table() # handle_graphs_in_custom_table() # # # # # override_common_default_report_parameters() # # # subroutine(override_common_default_report_parameters( node custom_report, node report), ( # This overrides/adds all report parameters which are # defined in custom report, except the report_elements node. node item; string item_name; foreach item custom_report ( item_name = node_name(item); # Don't allow report_elements because report_elements are covered separately if (item_name ne "report_elements") then ( if (num_subnodes(item) > 0) then ( # This item has subnodes, recursively call the subroutine # Set subnode in report @report{item_name} = ""; override_common_default_report_parameters(item, report{item_name}); ) else ( # This item has no more subitems, set the value in report @report{item_name} = @item; ); ); ); )); # # # # override_common_default_report_element_parameters() # # # subroutine(override_common_default_report_element_parameters( node custom_report_element, node report_element), ( # This overrides default parameters in report elements regardless of its type. debug_message("\n#### override_common_default_report_element_parameters() \n"); node n = new_node(); @n{"show_header_bar"} = ""; @n{"header"} = ""; @n{"footer"} = ""; @n{"omit_parenthesized_items"} = ""; @n{"use_overview_for_totals"} = ""; @n{"table_filter_expression"} = ""; @n{"show_graphs"} = ""; @n{"show_table"} = ""; @n{"sort_by"} = ""; @n{"sort_direction"} = ""; @n{"show_remainder_row"} = ""; @n{"show_remainder_row"} = ""; @n{"show_min_row"} = ""; @n{"show_max_row"} = ""; @n{"show_totals_row"} = ""; node item; string item_name; foreach item n ( item_name = node_name(item); # debug_message("\n#### item_name: " . item_name . "\n"); if (custom_report_element?{item_name}) then ( # Override default value # debug_message("#### item_name exists in custom_report_element with value: " . @custom_report_element{item_name} . "\n"); @report_element{item_name} = @custom_report_element{item_name}; ); ); if (?(custom_report_element . ".date_filter.df")) then ( @report_element{"date_filter"}{"df"} = @custom_report_element{"date_filter"}{"df"}; ); if (?(custom_report_element . ".filter.expression")) then ( @report_element{"filter"}{"expression"} = @custom_report_element{"filter"}{"expression"}; ) else if (custom_report_element?{"filter"}) then ( @report_element{"filter"}{"expression"} = @custom_report_element{"filter"}; ); )); # # # # # set_number_of_rows_in_custom_table() # # # # subroutine(set_number_of_rows_in_custom_table( node custom_report_element, node report_element), ( # debug_message("\n#### set_number_of_rows_in_custom_table() \n"); # debug_message("#### custom_report_element:\n" . node_as_string(custom_report_element) . "\n"); # debug_message("#### report_element:\n" . node_as_string(report_element) . "\n"); int number_of_rows; if (custom_report_element?{"number_of_rows"}) then ( number_of_rows = @custom_report_element{"number_of_rows"}; ) else if (custom_report_element?{"ending_row"}) then ( # version 7 definition for number_of_rows number_of_rows = @custom_report_element{"ending_row"}; ) else if (node_name(report_element) eq "day_of_week") then ( number_of_rows = 7; ) else if (node_name(report_element) eq "hour_of_day") then ( number_of_rows = 24; ) else ( number_of_rows = 10; ); # debug_message("#### number_of_rows: " . number_of_rows . "\n"); # # Set actual general report element parameters # @report_element{"number_of_rows"} = number_of_rows; )); # # # # # handle_pivot_table_in_custom_table() # # # # subroutine(handle_pivot_table_in_custom_table( node report_fields, node description, node report_element), ( # # Set defaults # string pivot_table_report_field_name; int number_of_rows = 10; string sort_by; string sort_direction = "descending"; bool show_averages_row = false; bool show_min_row = false; bool show_max_row = false; bool show_totals_row = true; node pivot_table_source; # # Check for pivot table description # if (?(description . ".pivot_table.show_pivot_table") and @(description . ".pivot_table.show_pivot_table")) then ( # # Handle pivot table # pivot_table_source = description{"pivot_table"}; if (pivot_table_source?{"report_field"}) then ( pivot_table_report_field_name = @pivot_table_source{"report_field"}; ); if (pivot_table_source?{"number_of_rows"}) then ( number_of_rows = @pivot_table_source{"number_of_rows"}; ); if (pivot_table_source?{"sort_by"}) then ( sort_by = @pivot_table_source{"sort_by"}; ); if (pivot_table_source?{"sort_direction"}) then ( sort_direction = @pivot_table_source{"sort_direction"}; ); if (pivot_table_source?{"show_averages_row"}) then ( show_averages_row = @pivot_table_source{"show_averages_row"}; ); if (pivot_table_source?{"show_min_row"}) then ( show_min_row = @pivot_table_source{"show_min_row"}; ); if (pivot_table_source?{"show_max_row"}) then ( show_max_row = @pivot_table_source{"show_max_row"}; ); if (pivot_table_source?{"show_totals_row"}) then ( show_totals_row = @pivot_table_source{"show_totals_row"}; ); ) else if (description?{"subtable"}) then ( pivot_table_source = description{"subtable"}; # # Handle version 7 pivot table # # In case of a version 7 pivot table there must be a second column in the columns node. # Get the name of this column and save it in pivot_table_report_field_name, then remove the specific # column from the report element description if (description?{"columns"}) then ( node columns = description{"columns"}; if (num_subnodes(columns) >= 2) then ( node drill_down_column = subnode_by_number(columns, 1); # The second column if (drill_down_column?{"field_name"}) then ( pivot_table_report_field_name = @drill_down_column{"field_name"}; # delete this field from the description now because its not anymore # specified in columns in version 8 delete_node(drill_down_column); ); ); ); if (pivot_table_source?{"ending_row"}) then ( number_of_rows = @pivot_table_source{"ending_row"}; ); if (pivot_table_source?{"show_averages_row"}) then ( show_averages_row = @pivot_table_source{"show_averages_row"}; ); ); # # Add pivot table to report element # if ((pivot_table_report_field_name ne "") and report_fields?{pivot_table_report_field_name}) then ( # # Add pivot table properties # @report_element{"pivot_table"} = ""; node pivot_table = report_element{"pivot_table"}; @pivot_table{"show_pivot_table"} = true; @pivot_table{"report_field"} = pivot_table_report_field_name; @pivot_table{"number_of_rows"} = number_of_rows; @pivot_table{"sort_by"} = sort_by; @pivot_table{"sort_direction"} = sort_direction; @pivot_table{"show_averages_row"} = show_averages_row; @pivot_table{"show_min_row"} = show_min_row; @pivot_table{"show_max_row"} = show_max_row; @pivot_table{"show_totals_row"} = show_totals_row; ); )); # # # # # # # # # Columns handling # # # # # # # # # # # # add_predefined_columns_in_custom_table() # # # # subroutine(add_predefined_columns_in_custom_table( node profile, string report_name, node report_fields, node numerical_report_fields, string main_numerical_field_name, node description, node report_element, string report_element_type), ( node columns_source = description{"columns"}; int number_of_text_columns = 0; int number_of_numerical_columns = 0; node column; string report_field_name; string main_report_field_name; bool show_column; bool show_percent_column; bool show_bar_column; bool show_graph; string description_graph_field = if (description?{"graph_field"}) then (@description{"graph_field"}) else (""); string error_msg; foreach column columns_source ( if (column?{"report_field"}) then ( # Version 8 definition report_field_name = @column{"report_field"}; ) else if (column?{"field_name"}) then ( # Version 7 definition report_field_name = @column{"field_name"}; ) else ( # No report field name, reset it to "" report_field_name = ""; ); # Only add the column if it actually exists if (report_field_name ne "") then ( # Check if this is a non-existing version 7 date_time field #* DISABLED BECAUSE WE ADDED A DATE_TIME REPORT_FIELD FOR BACKWARD COMPATIBILITY, so we don't convert date_time! if (!report_fields?{report_field_name} and (report_field_name eq "date_time")) then ( # Convert date_time to day, month or year if one of these report fields exist if (report_fields?{"day"}) then ( report_field_name = "day"; ) else if (report_fields?{"month"}) then ( report_field_name = "month"; ) else if (report_fields?{"year"}) then ( report_field_name = "year"; ); ); *# # Finally add the report field if it exists if (report_fields?{report_field_name}) then ( if (!numerical_report_fields?{report_field_name}) then ( # # Add non-numerical column # show_column = true; if (column?{"show_column"}) then ( show_column = @column{"show_column"}; ) else if (column?{"visible"}) then ( # Handle version 7 style show_column = @column{"visible"}; ); # # Add the column to the report element # report_element . ".columns." . report_field_name . ".report_field" = report_field_name; report_element . ".columns." . report_field_name . ".show_column" = show_column; if (main_report_field_name eq "") then ( # This must be the first column, respectively the main report field for tables main_report_field_name = report_field_name; ); number_of_text_columns++; ) else ( # # Add numerical column # show_column = true; show_percent_column = false; show_bar_column = false; show_graph = false; if (column?{"show_column"}) then ( show_column = @column{"show_column"}; ) else if (column?{"show_number_column"}) then ( # Handle version 7 style show_column = @column{"show_number_column"}; ); if (column?{"show_percent_column"}) then ( show_percent_column = @column{"show_percent_column"}; ); if (column?{"show_bar_column"}) then ( show_bar_column = @column{"show_bar_column"}; ); if (column?{"show_graph"}) then ( show_graph = @column{"show_graph"}; ) else if (description_graph_field eq report_field_name) then ( show_graph = true; ); # # Add the column to the report element # report_element . ".columns." . report_field_name . ".report_field" = report_field_name; report_element . ".columns." . report_field_name . ".show_column" = show_column; report_element . ".columns." . report_field_name . ".show_percent_column" = show_percent_column; report_element . ".columns." . report_field_name . ".show_bar_column" = show_bar_column; report_element . ".columns." . report_field_name . ".show_graph" = show_graph; number_of_numerical_columns++; ); ); ); ); if (number_of_text_columns > 0) then ( # # Add numerical columns if there aren't any yet # if ((number_of_numerical_columns == 0) and (report_element_type eq "table")) then ( # # There are no numerical columns defined or found, so we add all numerical columns # if no field associations list exists or we add all fields defined of the field associations list. # This is limited to report elements of type "table" because other report element type has no main_report_field_name. # node report_field_item; string db_field_associations_path = profile . '.create_profile_wizard_options.database_field_associations.' . main_report_field_name; bool is_defined_db_field_associations = ?(db_field_associations_path); foreach report_field_item numerical_report_fields ( report_field_name = node_name(report_field_item); # If this field is in the field associations list for the main report field, # or if there is no field associations list, include it in the table. if (!is_defined_db_field_associations or ?(db_field_associations_path . "." . report_field_name)) then ( # If graph_field is specified in the description, and it's this field, show a graph show_graph = if (description?{"graph_field"} and (@description{"graph_field"} eq report_field_name)) then (true) else (false); report_element . ".columns." . report_field_name . ".report_field" = report_field_name; report_element . ".columns." . report_field_name . ".show_column" = true; report_element . ".columns." . report_field_name . ".show_percent_column" = false; report_element . ".columns." . report_field_name . ".show_bar_column" = false; report_element . ".columns." . report_field_name . ".show_graph" = show_graph; ); ); ); # # Set main report field if it is not yet set # if ((report_element_type eq "table") and (@report_element{"report_field"} eq "")) then ( @report_element{"report_field"} = main_report_field_name; ); ) else ( # No non-numerical column found, throw an error error_msg = "Could not find non-numerical column in log format report description \"" . report_name . "\". "; error_msg .= "Error occured in profile setup add_predefined_columns_in_custom_table()"; error(error_msg); ); )); # # # # # add_single_column_in_custom_table() # # # # subroutine(add_single_column_in_custom_table( string report_name, node report_fields, node numerical_report_fields, node description, node report_element, string report_element_type), ( # No columns exist in the report element description, just add one non-numerical column string main_report_field_name; bool is_error = false; if (description?{"database_field_name"}) then ( main_report_field_name = @description{"database_field_name"}; ) else if (report_fields?{report_name}) then ( main_report_field_name = report_name; ) else if (report_element_type ne 'table') then ( if (report_element_type eq 'log_detail') then ( # 2008-03-31 - GMF - if it's custom log_detail, use the first report field as the main one main_report_field_name = node_name(subnode_by_number(report_fields, 0)); ) ) else ( # 2012-11-13 - GMF - If no main field is specified, could be log detail (cisco_waas_tcp_proxy); use the first report field # is_error = true; main_report_field_name = node_name(subnode_by_number(report_fields, 0)); ); # set_report_element_variable(profile, report_element, "report_field", main_report_field_name); # add_nonnumerical_column_to_table(profile, report_element, main_report_field_name, main_report_field_name); if ((main_report_field_name ne "") and report_fields?{main_report_field_name} and !numerical_report_fields?{main_report_field_name}) then ( report_element . ".columns." . main_report_field_name . ".report_field" = main_report_field_name; report_element . ".columns." . main_report_field_name . ".show_column" = true; if (report_element_type eq "table") then ( # Set the report_field just in case that it isn't set yet @report_element{"report_field"} = main_report_field_name; ); ) else ( is_error = true; ); if (is_error) then ( string error_msg = "Could not find main_report_field_name in log format report description \"" . report_name . "\". "; error_msg .= "Error occured in profile setup add_single_column_in_custom_table()"; error(error_msg); ); )); # # # # # handle_sort_by_in_custom_table() # # # # subroutine(handle_sort_by_in_custom_table( node numerical_report_fields, string main_numerical_field_name, node report_element, string report_element_type), ( if (report_element_type ne "log_detail") then ( # Sort by sort_by or the main sort field, or by the first numerical field if the main field isn't in this table string sort_by = @report_element{"sort_by"}; node columns = report_element{"columns"}; if (sort_by eq "" or !columns?{sort_by}) then ( # No sort_by defined or the sort_by field does not exist in columns # Reset sort_by sort_by = ""; if (columns?{main_numerical_field_name}) then ( # Sort by main_numerical_field_name sort_by = main_numerical_field_name; ) else ( # Sort by first numerical field node column; string report_field_name; foreach column columns ( report_field_name = @column{"report_field"}; if (numerical_report_fields?{report_field_name}) then ( sort_by = report_field_name; last; ); ); ); # Set sort_by @report_element{"sort_by"} = sort_by; ); ); )); # # # # # set_graph_value_in_custom_table() # # # # subroutine(set_graph_value_in_custom_table( node graphs_description, node default_graph_object, node report_element_graphs, string option_name), ( string option_value; # 2010-02-23 - GMF - changed "option_name" to option_name. It can't be in quotes, or it looks only literally for a node named "option_name" instead of # e.g., a node named "pie_3d". if (graphs_description?{option_name}) then ( # Version 8+ definition option_value = @graphs_description{option_name}; ) else if (?(graphs_description . ".bar_line_graph." . option_name)) then ( # Version 7 bar line graph definition option_value = @(graphs_description . ".bar_line_graph." . option_name); ) else if (?(graphs_description . ".pie_chart." . option_name)) then ( # Version 7 bar pie chart definition option_value = @(graphs_description . ".pie_chart." . option_name); ); # Use the default value if no option_value exists in the graphs_description if (option_value eq "") then ( option_value = @default_graph_object{option_name}; ); @report_element_graphs{option_name} = option_value; )); # # # # # handle_graphs_in_custom_table # # # # subroutine(handle_graphs_in_custom_table( node database_fields, node report_fields, node description, node report_element, string report_element_type), ( debug_message("\n#### handle_graphs_in_custom_table() START \n"); if (report_element_type ne "log_detail") then ( node default_graphs = "default_graphs"; string graph_type; bool is_chrono_graph_support = false; # # Check if the main report field supports chronological graphs # if (report_element_type eq "table") then ( string report_field_name = @report_element{"report_field"}; if (report_fields?{report_field_name}) then ( node report_field = report_fields{report_field_name}; string database_field_name = @report_field{"database_field"}; if (?(database_fields . "." . database_field_name . ".category")) then ( string category = @(database_fields . "." . database_field_name . ".category"); if (category eq "date_time" or category eq "day_of_week" or category eq "hour_of_day") then ( is_chrono_graph_support = true; ); ); ); ); # # Get graphs description, if any # node graphs_description; if (description?{"graphs"}) then ( graphs_description = description{"graphs"}; ) else ( # No graphs node exists in report element description, use empty node delete_node("v.temp_graphs_description"); v.temp_graphs_description = ""; graphs_description = "v.temp_graphs_description"; ); # # Get graph_type # if (graphs_description?{"graph_type"} and (@graphs_description{"graph_type"} eq "bar" or @graphs_description{"graph_type"} eq "line" or @graphs_description{"graph_type"} eq "pie")) then ( # Use pre-defined graph type graph_type = @graphs_description{"graph_type"}; ) else if (!is_chrono_graph_support) then ( # Use default graph_type graph_type = @default_graphs{"graph_type"}; ) else ( # Use default chrono graph_type graph_type = @default_graphs{"chrono_graph_type"}; ); # # Check if we show a chrono graph # bool show_chrono_graph = false; if (is_chrono_graph_support and (graph_type ne "pie")) then ( show_chrono_graph = if (graphs_description?{"show_chrono_graph"}) then (@graphs_description{"show_chrono_graph"}) else (true); ); # # Get default graph object # node default_graph_object; if (graph_type ne "pie") then ( if (!show_chrono_graph) then ( default_graph_object = default_graphs{"bar_line_graph"}; ) else ( default_graph_object = default_graphs{"chrono_bar_line_graph"}; ); ) else ( default_graph_object = default_graphs{"pie_chart"}; ); # # # Set the graph values in report element # # @report_element{"graphs"}= ""; node report_element_graphs = report_element{"graphs"}; @report_element_graphs{"graph_type"} = graph_type; set_graph_value_in_custom_table(graphs_description, default_graph_object, report_element_graphs, "y_axis_height"); set_graph_value_in_custom_table(graphs_description, default_graph_object, report_element_graphs, "x_axis_length"); set_graph_value_in_custom_table(graphs_description, default_graph_object, report_element_graphs, "sort_all_descending"); if (!show_chrono_graph) then ( set_graph_value_in_custom_table(graphs_description, default_graph_object, report_element_graphs, "max_variables"); set_graph_value_in_custom_table(graphs_description, default_graph_object, report_element_graphs, "show_remainder"); set_graph_value_in_custom_table(graphs_description, default_graph_object, report_element_graphs, "show_legend"); set_graph_value_in_custom_table(graphs_description, default_graph_object, report_element_graphs, "max_legend_rows"); if (graph_type eq "pie") then ( set_graph_value_in_custom_table(graphs_description, default_graph_object, report_element_graphs, "show_3d"); ); ) else ( # This is a chrono graph @report_element_graphs{"show_chrono_graph"} = true; ); ); debug_message("\n#### handle_graphs_in_custom_table() END \n\n"); ));