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.67.0_covts Lines: 14.4 % 153 22
Test Date: 2025-11-06 17:22:08 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              :         /* write end of diagram-contents, prepare to descend to children  */
     100            0 :         write_err |= io_element_writer_descend_diagram( (*this_).element_writer, diag_ptr );
     101              :     }
     102              : 
     103            0 :     data_visible_set_destroy( (*this_).input_data );
     104              : 
     105            0 :     U8_TRACE_END_ERR( write_err );
     106            0 :     return write_err;
     107              : }
     108              : 
     109            0 : u8_error_t io_export_diagram_traversal_end_diagram ( io_export_diagram_traversal_t *this_, data_id_t diagram_id )
     110              : {
     111            0 :     U8_TRACE_BEGIN();
     112            0 :     assert( data_id_is_valid( &diagram_id ) );
     113            0 :     assert( data_id_get_table( &diagram_id ) == DATA_TABLE_DIAGRAM );
     114            0 :     u8_error_t write_err = U8_ERROR_NONE;
     115              : 
     116              :     /* load diagram only to be drawn */
     117            0 :     data_diagram_t *const diagram_ptr = data_visible_set_get_diagram_ptr ( (*this_).input_data );
     118              :     const u8_error_t d_err
     119            0 :         = data_database_reader_get_diagram_by_id( (*this_).db_reader, data_id_get_row_id( &diagram_id ), diagram_ptr );
     120            0 :     if( d_err != U8_ERROR_NONE )
     121              :     {
     122            0 :         write_err = -1;
     123            0 :         assert(false);
     124              :     }
     125              :     else
     126              :     {
     127            0 :         assert( data_diagram_is_valid( diagram_ptr ) );
     128              : 
     129              :         /* write footer */
     130            0 :         write_err |= io_element_writer_end_diagram( (*this_).element_writer, diagram_ptr );
     131              : 
     132            0 :         data_diagram_destroy( diagram_ptr );
     133              :     }
     134            0 :     U8_TRACE_END_ERR( write_err );
     135            0 :     return write_err;
     136              : }
     137              : 
     138            0 : u8_error_t io_export_diagram_traversal_private_iterate_diagram_classifiers ( io_export_diagram_traversal_t *this_,
     139              :                                                                              const data_visible_set_t *diagram_data )
     140              : {
     141            0 :     U8_TRACE_BEGIN();
     142            0 :     assert( diagram_data != NULL );
     143            0 :     assert( data_visible_set_is_valid( diagram_data ) );
     144            0 :     u8_error_t write_err = U8_ERROR_NONE;
     145              : 
     146              :     /* iterate over all classifiers */
     147              :     uint32_t count;
     148            0 :     count = data_visible_set_get_visible_classifier_count ( diagram_data );
     149            0 :     for ( uint32_t index = 0; index < count; index ++ )
     150              :     {
     151              :         /* get classifier */
     152              :         const data_visible_classifier_t *const visible_classifier
     153            0 :             = data_visible_set_get_visible_classifier_const ( diagram_data, index );
     154            0 :         if (( visible_classifier != NULL ) && ( data_visible_classifier_is_valid( visible_classifier ) ))
     155            0 :         {
     156              :             const data_classifier_t *classifier
     157            0 :                 = data_visible_classifier_get_classifier_const( visible_classifier );
     158            0 :             const data_id_t classifier_id = data_classifier_get_data_id( classifier );
     159            0 :             U8_TRACE_INFO_INT( "printing classifier with id", data_id_get_row_id( &classifier_id ) );
     160              : 
     161              :             /* start+assemble classifier */
     162            0 :             write_err |= io_element_writer_start_classifier( (*this_).element_writer,
     163              :                                                              DATA_CLASSIFIER_TYPE_VOID,  /* no host */
     164              :                                                              classifier
     165              :                                                            );
     166              : 
     167            0 :             write_err |= io_element_writer_assemble_classifier( (*this_).element_writer,
     168              :                                                                 DATA_CLASSIFIER_TYPE_VOID,   /* no host */
     169              :                                                                 classifier
     170              :                                                               );
     171              : 
     172              :             /* print all features of the classifier */
     173            0 :             write_err |= io_export_diagram_traversal_private_iterate_classifier_features( this_,
     174              :                                                                                           diagram_data,
     175              :                                                                                           classifier_id
     176              :                                                                                         );
     177              : 
     178              :             /* end classifier */
     179            0 :             write_err |= io_element_writer_end_classifier( (*this_).element_writer,
     180              :                                                            DATA_CLASSIFIER_TYPE_VOID,  /* no host */
     181              :                                                            classifier
     182              :                                                          );
     183              : 
     184              :             /* print all relationships starting from classifier_id */
     185            0 :             write_err |= io_export_diagram_traversal_private_iterate_classifier_relationships( this_,
     186              :                                                                                                diagram_data,
     187              :                                                                                                classifier_id
     188              :                                                                                              );
     189              : 
     190              :             const data_diagramelement_t *diagele
     191            0 :                 = data_visible_classifier_get_diagramelement_const( visible_classifier );
     192            0 :             const data_id_t diagele_id = data_diagramelement_get_data_id( diagele );
     193            0 :             const data_diagram_t *const diagram_ptr = data_visible_set_get_diagram_ptr ( (*this_).input_data );
     194            0 :             const data_row_t focused_feature_id = data_diagramelement_get_focused_feature_row_id( diagele );
     195            0 :             const data_feature_t *const focused_f_or_null
     196              :                 = ( focused_feature_id == DATA_ROW_VOID )
     197              :                 ? NULL
     198            0 :                 : data_visible_set_get_feature_by_id_const( diagram_data, focused_feature_id );
     199              : 
     200            0 :             U8_TRACE_INFO_INT( "printing diagramelement with id", data_id_get_row_id( &diagele_id ) );
     201              : 
     202              :             /* start+assemble+end diagramelement */
     203            0 :             write_err |= io_element_writer_start_diagramelement( (*this_).element_writer,
     204              :                                                                  diagram_ptr,
     205              :                                                                  diagele
     206              :                                                                );
     207            0 :             write_err |= io_element_writer_assemble_diagramelement( (*this_).element_writer,
     208              :                                                                     diagram_ptr,
     209              :                                                                     diagele,
     210              :                                                                     classifier,
     211              :                                                                     focused_f_or_null
     212              :                                                                   );
     213            0 :             write_err |= io_element_writer_end_diagramelement( (*this_).element_writer,
     214              :                                                                diagram_ptr,
     215              :                                                                diagele
     216              :                                                              );
     217              :         }
     218              :         else
     219              :         {
     220            0 :             assert( false );
     221              :         }
     222              :     }
     223              : 
     224            0 :     U8_TRACE_END_ERR( write_err );
     225            0 :     return write_err;
     226              : }
     227              : 
     228            0 : u8_error_t io_export_diagram_traversal_private_iterate_classifier_features ( io_export_diagram_traversal_t *this_,
     229              :                                                                              const data_visible_set_t *diagram_data,
     230              :                                                                              data_id_t classifier_id )
     231              : {
     232            0 :     U8_TRACE_BEGIN();
     233            0 :     assert( diagram_data != NULL );
     234            0 :     assert( data_visible_set_is_valid( diagram_data ) );
     235            0 :     assert( DATA_TABLE_CLASSIFIER == data_id_get_table( &classifier_id ) );
     236            0 :     assert( DATA_ROW_VOID != data_id_get_row_id( &classifier_id) );
     237            0 :     u8_error_t write_err = U8_ERROR_NONE;
     238              : 
     239              :     /* iterate over all features */
     240              :     uint32_t count;
     241            0 :     count = data_visible_set_get_feature_count ( diagram_data );
     242            0 :     for ( uint32_t index = 0; index < count; index ++ )
     243              :     {
     244              :         /* get feature */
     245              :         const data_feature_t *feature;
     246            0 :         feature = data_visible_set_get_feature_const ( diagram_data, index );
     247            0 :         if (( feature != NULL ) && ( data_feature_is_valid( feature ) ))
     248            0 :         {
     249            0 :             const data_id_t f_classifier_id = data_feature_get_classifier_data_id( feature );
     250            0 :             if ( data_id_equals( &classifier_id, &f_classifier_id ) )
     251              :             {
     252            0 :                 const bool is_visible = data_rules_diagram_shows_feature ( &((*this_).filter_rules),
     253              :                                                                            diagram_data,
     254              :                                                                            data_feature_get_row_id( feature )
     255              :                                                                          );
     256            0 :                 const bool is_lifeline
     257            0 :                     =( DATA_FEATURE_TYPE_LIFELINE == data_feature_get_main_type( feature ) );
     258              : 
     259            0 :                 if ( is_visible && ( ! is_lifeline ) )
     260              :                 {
     261              :                     const data_classifier_t *const parent_classifier
     262            0 :                         = data_visible_set_get_classifier_by_id_const( diagram_data, data_id_get_row_id( &classifier_id ));
     263            0 :                     if ( parent_classifier != NULL )
     264              :                     {
     265            0 :                         write_err |= io_element_writer_start_feature( (*this_).element_writer,
     266              :                                                                       data_classifier_get_main_type( parent_classifier ),
     267              :                                                                       feature
     268              :                                                                     );
     269            0 :                         write_err |= io_element_writer_assemble_feature( (*this_).element_writer,
     270              :                                                                          parent_classifier,
     271              :                                                                          feature
     272              :                                                                        );
     273            0 :                         write_err |= io_element_writer_end_feature( (*this_).element_writer,
     274              :                                                                     data_classifier_get_main_type( parent_classifier ),
     275              :                                                                     feature
     276              :                                                                   );
     277              :                     }
     278              :                     else
     279              :                     {
     280            0 :                         assert ( false );  /* is_visible should not be true if parent_classifier == NULL */
     281              :                     }
     282              :                 }
     283              :                 else
     284              :                 {
     285              :                     /* do not export invisible features or lifelines */
     286              :                 }
     287              :             }
     288              :         }
     289              :         else
     290              :         {
     291            0 :             assert( false );
     292              :         }
     293              :     }
     294              : 
     295            0 :     U8_TRACE_END_ERR( write_err );
     296            0 :     return write_err;
     297              : }
     298              : 
     299            0 : u8_error_t io_export_diagram_traversal_private_iterate_classifier_relationships ( io_export_diagram_traversal_t *this_,
     300              :                                                                                   const data_visible_set_t *diagram_data,
     301              :                                                                                   data_id_t from_classifier_id )
     302              : {
     303            0 :     U8_TRACE_BEGIN();
     304            0 :     assert( diagram_data != NULL );
     305            0 :     assert( data_visible_set_is_valid( diagram_data ) );
     306            0 :     assert( DATA_TABLE_CLASSIFIER == data_id_get_table( &from_classifier_id ) );
     307            0 :     assert( DATA_ROW_VOID != data_id_get_row_id( &from_classifier_id) );
     308            0 :     u8_error_t write_err = U8_ERROR_NONE;
     309              : 
     310              :     /* iterate over all relationships */
     311              :     uint32_t count;
     312            0 :     count = data_visible_set_get_relationship_count ( diagram_data );
     313            0 :     for ( uint32_t index = 0; index < count; index ++ )
     314              :     {
     315              :         /* get relationship */
     316              :         const data_relationship_t *relation;
     317            0 :         relation = data_visible_set_get_relationship_const ( diagram_data, index );
     318            0 :         if (( relation != NULL ) && ( data_relationship_is_valid( relation ) ))
     319            0 :         {
     320            0 :             const data_id_t r_from_classifier_id = data_relationship_get_from_classifier_data_id( relation );
     321            0 :             if ( data_id_equals( &from_classifier_id, &r_from_classifier_id ) )
     322              :             {
     323            0 :                 const data_id_t relation_id = data_relationship_get_data_id( relation );
     324            0 :                 const bool is_visible = data_rules_diagram_shows_relationship ( &((*this_).filter_rules),
     325              :                                                                                 diagram_data,
     326              :                                                                                 data_id_get_row_id( &relation_id )
     327              :                                                                               );
     328              : 
     329            0 :                 if ( is_visible /* no filter for duplicates */ )
     330              :                 {
     331            0 :                     const data_row_t to_classifier_id = data_relationship_get_to_classifier_row_id( relation );
     332              :                     const data_classifier_t *const dest_classifier
     333            0 :                         = data_visible_set_get_classifier_by_id_const ( diagram_data, to_classifier_id );
     334            0 :                     if ( dest_classifier != NULL )
     335              :                     {
     336              :                         /* destination classifier found, print the relation */
     337            0 :                         write_err |= io_element_writer_start_relationship( (*this_).element_writer,
     338              :                                                                            DATA_CLASSIFIER_TYPE_VOID,
     339              :                                                                            relation
     340              :                                                                          );
     341            0 :                         write_err |= io_element_writer_assemble_relationship( (*this_).element_writer,
     342              :                                                                               NULL,
     343              :                                                                               relation,
     344              :                                                                               NULL,
     345              :                                                                               NULL,
     346              :                                                                               dest_classifier,
     347              :                                                                               NULL
     348              :                                                                             );
     349            0 :                         write_err |= io_element_writer_end_relationship( (*this_).element_writer,
     350              :                                                                          DATA_CLASSIFIER_TYPE_VOID,
     351              :                                                                          relation
     352              :                                                                        );
     353              :                     }
     354              :                     else
     355              :                     {
     356            0 :                         assert ( false );  /* is_visible should not be true if dest_classifier == NULL */
     357              :                     }
     358              :                 }
     359              :             }
     360              :         }
     361              :         else
     362              :         {
     363            0 :             assert( false );
     364              :         }
     365              :     }
     366              : 
     367            0 :     U8_TRACE_END_ERR( write_err );
     368            0 :     return write_err;
     369              : }
     370              : 
     371              : 
     372              : /*
     373              : Copyright 2016-2025 Andreas Warnke
     374              : 
     375              : Licensed under the Apache License, Version 2.0 (the "License");
     376              : you may not use this file except in compliance with the License.
     377              : You may obtain a copy of the License at
     378              : 
     379              :     http://www.apache.org/licenses/LICENSE-2.0
     380              : 
     381              : Unless required by applicable law or agreed to in writing, software
     382              : distributed under the License is distributed on an "AS IS" BASIS,
     383              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     384              : See the License for the specific language governing permissions and
     385              : limitations under the License.
     386              : */
        

Generated by: LCOV version 2.0-1