LCOV - code coverage report
Current view: top level - io/source - io_export_diagram_traversal.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.63.2_covts Lines: 14.5 % 152 22
Test Date: 2025-05-01 10:10:14 Functions: 28.6 % 7 2

            Line data    Source code
       1              : /* File: io_export_diagram_traversal.c; Copyright and License: see below */
       2              : 
       3              : #include "io_export_diagram_traversal.h"
       4              : #include "u8/u8_trace.h"
       5              : #include "entity/data_diagram.h"
       6              : #include "entity/data_classifier.h"
       7              : #include <stdint.h>
       8              : #include <stdio.h>
       9              : #include <stdlib.h>
      10              : 
      11            2 : void io_export_diagram_traversal_init( io_export_diagram_traversal_t *this_,
      12              :                                        data_database_reader_t *db_reader,
      13              :                                        data_visible_set_t *input_data,
      14              :                                        data_stat_t *io_export_stat,
      15              :                                        io_element_writer_t *out_element_writer )
      16              : {
      17            2 :     U8_TRACE_BEGIN();
      18            2 :     assert( NULL != db_reader );
      19            2 :     assert( NULL != input_data );
      20            2 :     assert( NULL != io_export_stat );
      21            2 :     assert( NULL != out_element_writer );
      22              : 
      23            2 :     (*this_).db_reader = db_reader;
      24            2 :     (*this_).input_data = input_data;
      25            2 :     data_rules_init ( &((*this_).filter_rules) );
      26            2 :     (*this_).export_stat = io_export_stat;
      27            2 :     (*this_).element_writer = out_element_writer;
      28              : 
      29            2 :     U8_TRACE_END();
      30            2 : }
      31              : 
      32            2 : void io_export_diagram_traversal_destroy( io_export_diagram_traversal_t *this_ )
      33              : {
      34            2 :     U8_TRACE_BEGIN();
      35              : 
      36            2 :     data_rules_destroy ( &((*this_).filter_rules) );
      37            2 :     (*this_).input_data = NULL;
      38            2 :     (*this_).db_reader = NULL;
      39            2 :     (*this_).export_stat = NULL;
      40            2 :     (*this_).element_writer = NULL;
      41              : 
      42            2 :     U8_TRACE_END();
      43            2 : }
      44              : 
      45            0 : u8_error_t io_export_diagram_traversal_begin_and_walk_diagram ( io_export_diagram_traversal_t *this_,
      46              :                                                                 data_id_t diagram_id,
      47              :                                                                 const char *diagram_file_base_name )
      48              : {
      49            0 :     U8_TRACE_BEGIN();
      50            0 :     assert( data_id_is_valid( &diagram_id ) );
      51            0 :     assert( data_id_get_table( &diagram_id ) == DATA_TABLE_DIAGRAM );
      52            0 :     u8_error_t write_err = U8_ERROR_NONE;
      53              : 
      54              :     /* load data to be drawn */
      55            0 :     data_visible_set_init( (*this_).input_data );
      56              :     const u8_error_t d_err
      57            0 :         = data_visible_set_load( (*this_).input_data, data_id_get_row_id( &diagram_id ), (*this_).db_reader );
      58            0 :     if( d_err != U8_ERROR_NONE )
      59              :     {
      60            0 :         write_err = -1;
      61            0 :         assert(false);
      62              :     }
      63              :     else
      64              :     {
      65            0 :         assert( data_visible_set_is_valid ( (*this_).input_data ) );
      66              : 
      67              :         /* write diagram */
      68            0 :         const data_diagram_t *diag_ptr = data_visible_set_get_diagram_const( (*this_).input_data );
      69            0 :         assert( diag_ptr != NULL );
      70            0 :         assert( data_diagram_is_valid( diag_ptr ) );
      71            0 :         U8_TRACE_INFO_INT("printing diagram with id",data_diagram_get_row_id(diag_ptr));
      72              : 
      73              :         /* load parent diagram if there is one */
      74            0 :         data_diagram_init_empty( &((*this_).temp_parent_diag) );
      75            0 :         const data_row_t parent_id = data_diagram_get_parent_row_id( diag_ptr );
      76            0 :         if ( DATA_ROW_VOID != parent_id )
      77              :         {
      78              :             const u8_error_t d_err2
      79            0 :                 = data_database_reader_get_diagram_by_id( (*this_).db_reader, parent_id, &((*this_).temp_parent_diag) );
      80            0 :             if( d_err2 != U8_ERROR_NONE )
      81              :             {
      82            0 :                 write_err = -1;
      83            0 :                 assert(false);
      84              :             }
      85              :         }
      86              : 
      87            0 :         write_err |= io_element_writer_start_diagram( (*this_).element_writer, diag_ptr );
      88            0 :         write_err |= io_element_writer_assemble_diagram( (*this_).element_writer,
      89            0 :                                                          &((*this_).temp_parent_diag),
      90              :                                                          diag_ptr,
      91              :                                                          diagram_file_base_name
      92              :                                                        );
      93              : 
      94            0 :         data_diagram_destroy( &((*this_).temp_parent_diag) );
      95              : 
      96              :         /* write all classifiers */
      97            0 :         write_err |= io_export_diagram_traversal_private_iterate_diagram_classifiers( this_, (*this_).input_data );
      98              :     }
      99              : 
     100            0 :     data_visible_set_destroy( (*this_).input_data );
     101              : 
     102            0 :     U8_TRACE_END_ERR( write_err );
     103            0 :     return write_err;
     104              : }
     105              : 
     106            0 : u8_error_t io_export_diagram_traversal_end_diagram ( io_export_diagram_traversal_t *this_, data_id_t diagram_id )
     107              : {
     108            0 :     U8_TRACE_BEGIN();
     109            0 :     assert( data_id_is_valid( &diagram_id ) );
     110            0 :     assert( data_id_get_table( &diagram_id ) == DATA_TABLE_DIAGRAM );
     111            0 :     u8_error_t write_err = U8_ERROR_NONE;
     112              : 
     113              :     /* load diagram only to be drawn */
     114            0 :     data_diagram_t *const diagram_ptr = data_visible_set_get_diagram_ptr ( (*this_).input_data );
     115              :     const u8_error_t d_err
     116            0 :         = data_database_reader_get_diagram_by_id( (*this_).db_reader, data_id_get_row_id( &diagram_id ), diagram_ptr );
     117            0 :     if( d_err != U8_ERROR_NONE )
     118              :     {
     119            0 :         write_err = -1;
     120            0 :         assert(false);
     121              :     }
     122              :     else
     123              :     {
     124            0 :         assert( data_diagram_is_valid( diagram_ptr ) );
     125              : 
     126              :         /* write footer */
     127            0 :         write_err |= io_element_writer_end_diagram( (*this_).element_writer, diagram_ptr );
     128              : 
     129            0 :         data_diagram_destroy( diagram_ptr );
     130              :     }
     131            0 :     U8_TRACE_END_ERR( write_err );
     132            0 :     return write_err;
     133              : }
     134              : 
     135            0 : u8_error_t io_export_diagram_traversal_private_iterate_diagram_classifiers ( io_export_diagram_traversal_t *this_,
     136              :                                                                              const data_visible_set_t *diagram_data )
     137              : {
     138            0 :     U8_TRACE_BEGIN();
     139            0 :     assert( diagram_data != NULL );
     140            0 :     assert( data_visible_set_is_valid( diagram_data ) );
     141            0 :     u8_error_t write_err = U8_ERROR_NONE;
     142              : 
     143              :     /* iterate over all classifiers */
     144              :     uint32_t count;
     145            0 :     count = data_visible_set_get_visible_classifier_count ( diagram_data );
     146            0 :     for ( uint32_t index = 0; index < count; index ++ )
     147              :     {
     148              :         /* get classifier */
     149              :         const data_visible_classifier_t *const visible_classifier
     150            0 :             = data_visible_set_get_visible_classifier_const ( diagram_data, index );
     151            0 :         if (( visible_classifier != NULL ) && ( data_visible_classifier_is_valid( visible_classifier ) ))
     152            0 :         {
     153              :             const data_classifier_t *classifier
     154            0 :                 = data_visible_classifier_get_classifier_const( visible_classifier );
     155            0 :             const data_id_t classifier_id = data_classifier_get_data_id( classifier );
     156            0 :             U8_TRACE_INFO_INT( "printing classifier with id", data_id_get_row_id( &classifier_id ) );
     157              : 
     158              :             /* start+assemble classifier */
     159            0 :             write_err |= io_element_writer_start_classifier( (*this_).element_writer,
     160              :                                                              DATA_CLASSIFIER_TYPE_VOID,  /* no host */
     161              :                                                              classifier
     162              :                                                            );
     163              : 
     164            0 :             write_err |= io_element_writer_assemble_classifier( (*this_).element_writer,
     165              :                                                                 DATA_CLASSIFIER_TYPE_VOID,   /* no host */
     166              :                                                                 classifier
     167              :                                                               );
     168              : 
     169              :             /* print all features of the classifier */
     170            0 :             write_err |= io_export_diagram_traversal_private_iterate_classifier_features( this_,
     171              :                                                                                           diagram_data,
     172              :                                                                                           classifier_id
     173              :                                                                                         );
     174              : 
     175              :             /* end classifier */
     176            0 :             write_err |= io_element_writer_end_classifier( (*this_).element_writer,
     177              :                                                            DATA_CLASSIFIER_TYPE_VOID,  /* no host */
     178              :                                                            classifier
     179              :                                                          );
     180              : 
     181              :             /* print all relationships starting from classifier_id */
     182            0 :             write_err |= io_export_diagram_traversal_private_iterate_classifier_relationships( this_,
     183              :                                                                                                diagram_data,
     184              :                                                                                                classifier_id
     185              :                                                                                              );
     186              : 
     187              :             const data_diagramelement_t *diagele
     188            0 :                 = data_visible_classifier_get_diagramelement_const( visible_classifier );
     189            0 :             const data_id_t diagele_id = data_diagramelement_get_data_id( diagele );
     190            0 :             const data_diagram_t *const diagram_ptr = data_visible_set_get_diagram_ptr ( (*this_).input_data );
     191            0 :             const data_row_t focused_feature_id = data_diagramelement_get_focused_feature_row_id( diagele );
     192            0 :             const data_feature_t *const focused_f_or_null
     193              :                 = ( focused_feature_id == DATA_ROW_VOID )
     194              :                 ? NULL
     195            0 :                 : data_visible_set_get_feature_by_id_const( diagram_data, focused_feature_id );
     196              : 
     197            0 :             U8_TRACE_INFO_INT( "printing diagramelement with id", data_id_get_row_id( &diagele_id ) );
     198              : 
     199              :             /* start+assemble+end diagramelement */
     200            0 :             write_err |= io_element_writer_start_diagramelement( (*this_).element_writer,
     201              :                                                                  diagram_ptr,
     202              :                                                                  diagele
     203              :                                                                );
     204            0 :             write_err |= io_element_writer_assemble_diagramelement( (*this_).element_writer,
     205              :                                                                     diagram_ptr,
     206              :                                                                     diagele,
     207              :                                                                     classifier,
     208              :                                                                     focused_f_or_null
     209              :                                                                   );
     210            0 :             write_err |= io_element_writer_end_diagramelement( (*this_).element_writer,
     211              :                                                                diagram_ptr,
     212              :                                                                diagele
     213              :                                                              );
     214              :         }
     215              :         else
     216              :         {
     217            0 :             assert( false );
     218              :         }
     219              :     }
     220              : 
     221            0 :     U8_TRACE_END_ERR( write_err );
     222            0 :     return write_err;
     223              : }
     224              : 
     225            0 : u8_error_t io_export_diagram_traversal_private_iterate_classifier_features ( io_export_diagram_traversal_t *this_,
     226              :                                                                              const data_visible_set_t *diagram_data,
     227              :                                                                              data_id_t classifier_id )
     228              : {
     229            0 :     U8_TRACE_BEGIN();
     230            0 :     assert( diagram_data != NULL );
     231            0 :     assert( data_visible_set_is_valid( diagram_data ) );
     232            0 :     assert( DATA_TABLE_CLASSIFIER == data_id_get_table( &classifier_id ) );
     233            0 :     assert( DATA_ROW_VOID != data_id_get_row_id( &classifier_id) );
     234            0 :     u8_error_t write_err = U8_ERROR_NONE;
     235              : 
     236              :     /* iterate over all features */
     237              :     uint32_t count;
     238            0 :     count = data_visible_set_get_feature_count ( diagram_data );
     239            0 :     for ( uint32_t index = 0; index < count; index ++ )
     240              :     {
     241              :         /* get feature */
     242              :         const data_feature_t *feature;
     243            0 :         feature = data_visible_set_get_feature_const ( diagram_data, index );
     244            0 :         if (( feature != NULL ) && ( data_feature_is_valid( feature ) ))
     245            0 :         {
     246            0 :             const data_id_t f_classifier_id = data_feature_get_classifier_data_id( feature );
     247            0 :             if ( data_id_equals( &classifier_id, &f_classifier_id ) )
     248              :             {
     249            0 :                 const bool is_visible = data_rules_diagram_shows_feature ( &((*this_).filter_rules),
     250              :                                                                            diagram_data,
     251              :                                                                            data_feature_get_row_id( feature )
     252              :                                                                          );
     253            0 :                 const bool is_lifeline
     254            0 :                     =( DATA_FEATURE_TYPE_LIFELINE == data_feature_get_main_type( feature ) );
     255              : 
     256            0 :                 if ( is_visible && ( ! is_lifeline ) )
     257              :                 {
     258              :                     const data_classifier_t *const parent_classifier
     259            0 :                         = data_visible_set_get_classifier_by_id_const( diagram_data, data_id_get_row_id( &classifier_id ));
     260            0 :                     if ( parent_classifier != NULL )
     261              :                     {
     262            0 :                         write_err |= io_element_writer_start_feature( (*this_).element_writer,
     263              :                                                                       data_classifier_get_main_type( parent_classifier ),
     264              :                                                                       feature
     265              :                                                                     );
     266            0 :                         write_err |= io_element_writer_assemble_feature( (*this_).element_writer,
     267              :                                                                          parent_classifier,
     268              :                                                                          feature
     269              :                                                                        );
     270            0 :                         write_err |= io_element_writer_end_feature( (*this_).element_writer,
     271              :                                                                     data_classifier_get_main_type( parent_classifier ),
     272              :                                                                     feature
     273              :                                                                   );
     274              :                     }
     275              :                     else
     276              :                     {
     277            0 :                         assert ( false );  /* is_visible should not be true if parent_classifier == NULL */
     278              :                     }
     279              :                 }
     280              :                 else
     281              :                 {
     282              :                     /* do not export invisible features or lifelines */
     283              :                 }
     284              :             }
     285              :         }
     286              :         else
     287              :         {
     288            0 :             assert( false );
     289              :         }
     290              :     }
     291              : 
     292            0 :     U8_TRACE_END_ERR( write_err );
     293            0 :     return write_err;
     294              : }
     295              : 
     296            0 : u8_error_t io_export_diagram_traversal_private_iterate_classifier_relationships ( io_export_diagram_traversal_t *this_,
     297              :                                                                                   const data_visible_set_t *diagram_data,
     298              :                                                                                   data_id_t from_classifier_id )
     299              : {
     300            0 :     U8_TRACE_BEGIN();
     301            0 :     assert( diagram_data != NULL );
     302            0 :     assert( data_visible_set_is_valid( diagram_data ) );
     303            0 :     assert( DATA_TABLE_CLASSIFIER == data_id_get_table( &from_classifier_id ) );
     304            0 :     assert( DATA_ROW_VOID != data_id_get_row_id( &from_classifier_id) );
     305            0 :     u8_error_t write_err = U8_ERROR_NONE;
     306              : 
     307              :     /* iterate over all relationships */
     308              :     uint32_t count;
     309            0 :     count = data_visible_set_get_relationship_count ( diagram_data );
     310            0 :     for ( uint32_t index = 0; index < count; index ++ )
     311              :     {
     312              :         /* get relationship */
     313              :         const data_relationship_t *relation;
     314            0 :         relation = data_visible_set_get_relationship_const ( diagram_data, index );
     315            0 :         if (( relation != NULL ) && ( data_relationship_is_valid( relation ) ))
     316            0 :         {
     317            0 :             const data_id_t r_from_classifier_id = data_relationship_get_from_classifier_data_id( relation );
     318            0 :             if ( data_id_equals( &from_classifier_id, &r_from_classifier_id ) )
     319              :             {
     320            0 :                 const data_id_t relation_id = data_relationship_get_data_id( relation );
     321            0 :                 const bool is_visible = data_rules_diagram_shows_relationship ( &((*this_).filter_rules),
     322              :                                                                                 diagram_data,
     323              :                                                                                 data_id_get_row_id( &relation_id )
     324              :                                                                               );
     325              : 
     326            0 :                 if ( is_visible /* no filter for duplicates */ )
     327              :                 {
     328            0 :                     const data_row_t to_classifier_id = data_relationship_get_to_classifier_row_id( relation );
     329              :                     const data_classifier_t *const dest_classifier
     330            0 :                         = data_visible_set_get_classifier_by_id_const ( diagram_data, to_classifier_id );
     331            0 :                     if ( dest_classifier != NULL )
     332              :                     {
     333              :                         /* destination classifier found, print the relation */
     334            0 :                         write_err |= io_element_writer_start_relationship( (*this_).element_writer,
     335              :                                                                            DATA_CLASSIFIER_TYPE_VOID,
     336              :                                                                            relation
     337              :                                                                          );
     338            0 :                         write_err |= io_element_writer_assemble_relationship( (*this_).element_writer,
     339              :                                                                               NULL,
     340              :                                                                               relation,
     341              :                                                                               NULL,
     342              :                                                                               NULL,
     343              :                                                                               dest_classifier,
     344              :                                                                               NULL
     345              :                                                                             );
     346            0 :                         write_err |= io_element_writer_end_relationship( (*this_).element_writer,
     347              :                                                                          DATA_CLASSIFIER_TYPE_VOID,
     348              :                                                                          relation
     349              :                                                                        );
     350              :                     }
     351              :                     else
     352              :                     {
     353            0 :                         assert ( false );  /* is_visible should not be true if dest_classifier == NULL */
     354              :                     }
     355              :                 }
     356              :             }
     357              :         }
     358              :         else
     359              :         {
     360            0 :             assert( false );
     361              :         }
     362              :     }
     363              : 
     364            0 :     U8_TRACE_END_ERR( write_err );
     365            0 :     return write_err;
     366              : }
     367              : 
     368              : 
     369              : /*
     370              : Copyright 2016-2025 Andreas Warnke
     371              : 
     372              : Licensed under the Apache License, Version 2.0 (the "License");
     373              : you may not use this file except in compliance with the License.
     374              : You may obtain a copy of the License at
     375              : 
     376              :     http://www.apache.org/licenses/LICENSE-2.0
     377              : 
     378              : Unless required by applicable law or agreed to in writing, software
     379              : distributed under the License is distributed on an "AS IS" BASIS,
     380              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     381              : See the License for the specific language governing permissions and
     382              : limitations under the License.
     383              : */
        

Generated by: LCOV version 2.0-1