Line data Source code
1 : /* File: io_export_set_traversal.c; Copyright and License: see below */
2 :
3 : #include "io_export_set_traversal.h"
4 :
5 : #include "json/json_element_reader.h"
6 : #include "utf8stringbuf/utf8string.h"
7 : #include "u8stream/universal_memory_output_stream.h"
8 : #include "u8/u8_trace.h"
9 : #include <assert.h>
10 : #include <gtk/gtk.h>
11 : #include <stdbool.h>
12 :
13 0 : void io_export_set_traversal_init ( io_export_set_traversal_t *this_,
14 : data_database_reader_t *db_reader,
15 : data_stat_t *io_export_stat,
16 : io_element_writer_t *out_element_writer )
17 : {
18 0 : U8_TRACE_BEGIN();
19 0 : assert( NULL != db_reader );
20 0 : assert( NULL != io_export_stat );
21 0 : assert( NULL != out_element_writer );
22 :
23 0 : (*this_).db_reader = db_reader;
24 0 : (*this_).export_stat = io_export_stat;
25 0 : (*this_).element_writer = out_element_writer;
26 :
27 0 : U8_TRACE_END();
28 0 : }
29 :
30 0 : void io_export_set_traversal_destroy ( io_export_set_traversal_t *this_ )
31 : {
32 0 : U8_TRACE_BEGIN();
33 :
34 0 : (*this_).db_reader = NULL;
35 0 : (*this_).export_stat = NULL;
36 0 : (*this_).element_writer = NULL;
37 :
38 0 : U8_TRACE_END();
39 0 : }
40 :
41 0 : u8_error_t io_export_set_traversal_export_set( io_export_set_traversal_t *this_,
42 : const data_small_set_t *set_to_be_exported )
43 : {
44 0 : U8_TRACE_BEGIN();
45 0 : assert( NULL != set_to_be_exported );
46 :
47 0 : u8_error_t serialize_error = U8_ERROR_NONE;
48 :
49 0 : const char *const document_title = "";
50 0 : serialize_error |= io_element_writer_start_main( (*this_).element_writer, document_title );
51 :
52 : /* first pass: serialize the diagram(s) if there is one/some */
53 0 : for ( int index = 0; index < data_small_set_get_count( set_to_be_exported ); index ++ )
54 : {
55 : data_id_t current_id;
56 0 : current_id = data_small_set_get_id( set_to_be_exported, index );
57 0 : switch ( data_id_get_table( ¤t_id ) )
58 : {
59 0 : case DATA_TABLE_DIAGRAM:
60 : {
61 0 : serialize_error |= io_export_set_traversal_private_export_diagram( this_, current_id );
62 : }
63 0 : break;
64 :
65 0 : case DATA_TABLE_DIAGRAMELEMENT:
66 : {
67 0 : serialize_error |= io_export_set_traversal_private_export_diagramelement( this_, current_id );
68 : }
69 0 : break;
70 :
71 0 : case DATA_TABLE_CLASSIFIER:
72 : {
73 0 : serialize_error |= io_export_set_traversal_private_export_classifier( this_, current_id );
74 : }
75 0 : break;
76 :
77 0 : case DATA_TABLE_FEATURE:
78 : {
79 0 : serialize_error |= io_export_set_traversal_private_export_feature( this_, current_id );
80 : }
81 0 : break;
82 :
83 0 : case DATA_TABLE_RELATIONSHIP:
84 : {
85 0 : serialize_error |= io_export_set_traversal_private_export_relationship( this_, current_id );
86 : }
87 0 : break;
88 :
89 0 : default:
90 0 : break;
91 : }
92 : }
93 :
94 0 : serialize_error |= io_element_writer_end_main( (*this_).element_writer );
95 :
96 0 : U8_TRACE_END_ERR(serialize_error);
97 0 : return serialize_error;
98 : }
99 :
100 0 : u8_error_t io_export_set_traversal_private_export_diagram( io_export_set_traversal_t *this_, data_id_t id )
101 : {
102 0 : U8_TRACE_BEGIN();
103 0 : assert( data_id_is_valid( &id ) );
104 0 : assert( DATA_TABLE_DIAGRAM == data_id_get_table( &id ) );
105 0 : u8_error_t serialize_error = U8_ERROR_NONE;
106 : u8_error_t read_error;
107 :
108 : data_diagram_t out_diagram;
109 0 : read_error = data_database_reader_get_diagram_by_id ( (*this_).db_reader,
110 : data_id_get_row_id( &id ),
111 : &out_diagram
112 : );
113 :
114 0 : if ( read_error == U8_ERROR_NONE )
115 : {
116 : /* write diagram */
117 0 : const char *const diagram_file_base_name = "";
118 0 : serialize_error |= io_element_writer_start_diagram( (*this_).element_writer, &out_diagram );
119 0 : serialize_error |= io_element_writer_assemble_diagram( (*this_).element_writer,
120 : NULL, /* parent, currently not needed here */
121 : &out_diagram,
122 : diagram_file_base_name
123 : );
124 0 : serialize_error |= io_element_writer_end_diagram( (*this_).element_writer, &out_diagram );
125 : }
126 : else
127 : {
128 : /* program internal error */
129 0 : U8_LOG_ERROR( "io_export_set_traversal_export_set could not read all data of the set." );
130 0 : data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_ERROR );
131 : }
132 :
133 0 : U8_TRACE_END_ERR(serialize_error);
134 0 : return serialize_error;
135 : }
136 :
137 0 : u8_error_t io_export_set_traversal_private_export_diagramelement( io_export_set_traversal_t *this_, data_id_t id )
138 : {
139 0 : U8_TRACE_BEGIN();
140 0 : assert( data_id_is_valid( &id ) );
141 0 : assert( DATA_TABLE_DIAGRAMELEMENT == data_id_get_table( &id ) );
142 0 : u8_error_t serialize_error = U8_ERROR_NONE;
143 : u8_error_t read_error;
144 :
145 : data_classifier_t out_classifier;
146 : data_diagramelement_t out_diagramelement;
147 : /* data_diagram_t out_diagram; */
148 :
149 0 : read_error = data_database_reader_get_diagramelement_by_id( (*this_).db_reader,
150 : data_id_get_row_id( &id ),
151 : &out_diagramelement
152 : );
153 :
154 0 : if ( read_error == U8_ERROR_NONE )
155 : {
156 : /* get classifier */
157 0 : const data_row_id_t classifier_id = data_diagramelement_get_classifier_row_id( &out_diagramelement );
158 0 : read_error = data_database_reader_get_classifier_by_id( (*this_).db_reader,
159 : classifier_id,
160 : &out_classifier
161 : );
162 :
163 : /* get focused_feature */
164 : /*
165 : assert ( IO_EXPORT_SET_TRAVERSAL_MAX_FEATURES >= 1 );
166 : const data_row_id_t focused_feature_id = data_diagramelement_get_focused_feature_row_id( &out_diagramelement );
167 : if ( DATA_ROW_ID_VOID == focused_feature_id )
168 : {
169 : data_feature_init_empty( &((*this_).temp_features[0]) );
170 : }
171 : else
172 : {
173 : read_error |= data_database_reader_get_feature_by_id ( (*this_).db_reader,
174 : focused_feature_id,
175 : &((*this_).temp_features[0])
176 : );
177 : }
178 : */
179 :
180 : /* get diagram */
181 : /*
182 : const data_row_id_t diag_id = data_diagramelement_get_diagram_row_id( &out_diagramelement );
183 : read_error |= data_database_reader_get_diagram_by_id ( (*this_).db_reader,
184 : diag_id,
185 : &out_diagram
186 : );
187 : */
188 :
189 0 : if ( read_error == U8_ERROR_NONE )
190 : {
191 : /* intentionally not supported: diagramelements */
192 0 : U8_TRACE_INFO( "io_export_set_traversal_export_set does not copy single diagramelements, only referenced classifiers." );
193 : /*
194 : serialize_error |= io_element_writer_start_diagramelement( (*this_).element_writer,
195 : &out_diagram,
196 : &out_diagramelement
197 : );
198 :
199 : serialize_error |= io_element_writer_assemble_diagramelement( (*this_).element_writer,
200 : &out_diagram,
201 : &out_diagramelement,
202 : &out_classifier,
203 : &((*this_).temp_features[0]
204 : );
205 :
206 : serialize_error |= io_element_writer_end_diagramelement( (*this_).element_writer,
207 : &out_diagram,
208 : &out_diagramelement
209 : );
210 : */
211 : }
212 :
213 : uint32_t feature_count;
214 0 : read_error = data_database_reader_get_features_by_classifier_id( (*this_).db_reader,
215 : classifier_id,
216 : IO_EXPORT_SET_TRAVERSAL_MAX_FEATURES,
217 0 : &((*this_).temp_features),
218 : &feature_count
219 : );
220 :
221 0 : if ( read_error == U8_ERROR_NONE )
222 : {
223 : /* write classifier */
224 0 : serialize_error |= io_element_writer_start_classifier( (*this_).element_writer,
225 : DATA_CLASSIFIER_TYPE_VOID, /* host_type */
226 : &out_classifier
227 : );
228 0 : serialize_error |= io_element_writer_assemble_classifier( (*this_).element_writer,
229 : DATA_CLASSIFIER_TYPE_VOID, /* host_type */
230 : &out_classifier
231 : );
232 :
233 : /* write classifier-features */
234 0 : for ( uint32_t index = 0; index < feature_count; index ++ )
235 : {
236 0 : const data_classifier_type_t parent_type = data_classifier_get_main_type( &out_classifier );
237 0 : const data_feature_t *const feature_ptr = &(((*this_).temp_features)[index]);
238 0 : serialize_error |= io_element_writer_start_feature( (*this_).element_writer,
239 : parent_type,
240 : feature_ptr
241 : );
242 :
243 0 : serialize_error |= io_element_writer_assemble_feature( (*this_).element_writer,
244 : &out_classifier,
245 : feature_ptr
246 : );
247 :
248 0 : serialize_error |= io_element_writer_end_feature( (*this_).element_writer,
249 : parent_type,
250 : feature_ptr
251 : );
252 : }
253 :
254 0 : serialize_error |= io_element_writer_end_classifier( (*this_).element_writer,
255 : DATA_CLASSIFIER_TYPE_VOID, /* host_type */
256 : &out_classifier
257 : );
258 : }
259 : else
260 : {
261 : /* program internal error */
262 0 : U8_LOG_ERROR( "io_export_set_traversal_export_set could not read referenced data of the set." );
263 0 : data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_CLASSIFIER, DATA_STAT_SERIES_ERROR );
264 : }
265 : }
266 : else
267 : {
268 : /* program internal error */
269 0 : U8_LOG_ERROR( "io_export_set_traversal_export_set could not read all data of the set." );
270 0 : data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_CLASSIFIER, DATA_STAT_SERIES_ERROR );
271 : }
272 :
273 0 : U8_TRACE_END_ERR(serialize_error);
274 0 : return serialize_error;
275 : }
276 :
277 0 : u8_error_t io_export_set_traversal_private_export_classifier( io_export_set_traversal_t *this_, data_id_t id )
278 : {
279 0 : U8_TRACE_BEGIN();
280 0 : assert( data_id_is_valid( &id ) );
281 0 : assert( DATA_TABLE_CLASSIFIER == data_id_get_table( &id ) );
282 0 : u8_error_t serialize_error = U8_ERROR_NONE;
283 : u8_error_t read_error;
284 :
285 : data_classifier_t out_classifier;
286 0 : read_error = data_database_reader_get_classifier_by_id( (*this_).db_reader,
287 : data_id_get_row_id( &id ),
288 : &out_classifier
289 : );
290 :
291 : uint32_t feature_count;
292 0 : read_error = data_database_reader_get_features_by_classifier_id( (*this_).db_reader,
293 : data_id_get_row_id( &id ),
294 : IO_EXPORT_SET_TRAVERSAL_MAX_FEATURES,
295 0 : &((*this_).temp_features),
296 : &feature_count
297 : );
298 :
299 0 : if ( read_error == U8_ERROR_NONE )
300 : {
301 : /* write classifier */
302 0 : serialize_error |= io_element_writer_start_classifier( (*this_).element_writer,
303 : DATA_CLASSIFIER_TYPE_VOID, /* host_type */
304 : &out_classifier
305 : );
306 0 : serialize_error |= io_element_writer_assemble_classifier( (*this_).element_writer,
307 : DATA_CLASSIFIER_TYPE_VOID, /* host_type */
308 : &out_classifier
309 : );
310 :
311 : /* write classifier-features */
312 0 : for ( uint32_t index = 0; index < feature_count; index ++ )
313 : {
314 0 : const data_classifier_type_t parent_type = data_classifier_get_main_type( &out_classifier );
315 0 : const data_feature_t *const feature_ptr = &(((*this_).temp_features)[index]);
316 0 : serialize_error |= io_element_writer_start_feature( (*this_).element_writer,
317 : parent_type,
318 : feature_ptr
319 : );
320 :
321 0 : serialize_error |= io_element_writer_assemble_feature( (*this_).element_writer,
322 : &out_classifier,
323 : feature_ptr
324 : );
325 :
326 0 : serialize_error |= io_element_writer_end_feature( (*this_).element_writer,
327 : parent_type,
328 : feature_ptr
329 : );
330 : }
331 :
332 0 : serialize_error |= io_element_writer_end_classifier( (*this_).element_writer,
333 : DATA_CLASSIFIER_TYPE_VOID, /* host_type */
334 : &out_classifier
335 : );
336 : }
337 : else
338 : {
339 : /* program internal error */
340 0 : U8_LOG_ERROR( "io_export_set_traversal_export_set could not read all data of the set." );
341 0 : data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_CLASSIFIER, DATA_STAT_SERIES_ERROR );
342 : }
343 :
344 0 : U8_TRACE_END_ERR(serialize_error);
345 0 : return serialize_error;
346 : }
347 :
348 0 : u8_error_t io_export_set_traversal_private_export_feature( io_export_set_traversal_t *this_, data_id_t id )
349 : {
350 0 : U8_TRACE_BEGIN();
351 0 : assert( data_id_is_valid( &id ) );
352 0 : assert( DATA_TABLE_FEATURE == data_id_get_table( &id ) );
353 0 : u8_error_t serialize_error = U8_ERROR_NONE;
354 : u8_error_t read_error;
355 :
356 : data_feature_t out_feature;
357 0 : read_error = data_database_reader_get_feature_by_id ( (*this_).db_reader,
358 : data_id_get_row_id( &id ),
359 : &out_feature
360 : );
361 :
362 0 : if ( read_error == U8_ERROR_NONE )
363 : {
364 0 : const data_feature_type_t feat_type = data_feature_get_main_type( &out_feature );
365 0 : const data_stat_table_t feat_or_lifeline
366 0 : = ( feat_type == DATA_FEATURE_TYPE_LIFELINE ) ? DATA_STAT_TABLE_LIFELINE : DATA_STAT_TABLE_FEATURE;
367 :
368 : /* intentionally not supported */
369 0 : U8_TRACE_INFO( "io_export_set_traversal_export_set does not copy single features, only complete classifiers." );
370 0 : data_stat_inc_count ( (*this_).export_stat, feat_or_lifeline, DATA_STAT_SERIES_IGNORED );
371 : }
372 : else
373 : {
374 : /* program internal error */
375 0 : U8_LOG_ERROR( "io_export_set_traversal_export_set could not read all data of the set." );
376 0 : data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_FEATURE, DATA_STAT_SERIES_ERROR );
377 : }
378 :
379 0 : U8_TRACE_END_ERR(serialize_error);
380 0 : return serialize_error;
381 : }
382 :
383 0 : u8_error_t io_export_set_traversal_private_export_relationship( io_export_set_traversal_t *this_, data_id_t id )
384 : {
385 0 : U8_TRACE_BEGIN();
386 0 : assert( data_id_is_valid( &id ) );
387 0 : assert( DATA_TABLE_RELATIONSHIP == data_id_get_table( &id ) );
388 0 : u8_error_t serialize_error = U8_ERROR_NONE;
389 : u8_error_t read_error;
390 :
391 : data_relationship_t out_relation;
392 0 : read_error = data_database_reader_get_relationship_by_id ( (*this_).db_reader,
393 : data_id_get_row_id( &id ),
394 : &out_relation
395 : );
396 :
397 0 : if ( read_error == U8_ERROR_NONE )
398 : {
399 : data_classifier_t from_classifier;
400 : data_classifier_t to_classifier;
401 : assert ( IO_EXPORT_SET_TRAVERSAL_MAX_FEATURES >= 2 );
402 :
403 : /* get source */
404 0 : read_error |= data_database_reader_get_classifier_by_id ( (*this_).db_reader,
405 : data_relationship_get_from_classifier_row_id( &out_relation ),
406 : &from_classifier
407 : );
408 0 : if ( DATA_ROW_ID_VOID == data_relationship_get_from_feature_row_id( &out_relation ) )
409 : {
410 0 : data_feature_init_empty( &((*this_).temp_features[0]) );
411 : }
412 : else
413 : {
414 0 : read_error |= data_database_reader_get_feature_by_id ( (*this_).db_reader,
415 : data_relationship_get_from_feature_row_id( &out_relation ),
416 : &((*this_).temp_features[0])
417 : );
418 : }
419 :
420 : /* get destination */
421 0 : read_error |= data_database_reader_get_classifier_by_id ( (*this_).db_reader,
422 : data_relationship_get_to_classifier_row_id( &out_relation ),
423 : &to_classifier
424 : );
425 0 : if ( DATA_ROW_ID_VOID == data_relationship_get_to_feature_row_id( &out_relation ) )
426 : {
427 0 : data_feature_init_empty( &((*this_).temp_features[1]) );
428 : }
429 : else
430 : {
431 0 : read_error |= data_database_reader_get_feature_by_id ( (*this_).db_reader,
432 : data_relationship_get_to_feature_row_id( &out_relation ),
433 : &((*this_).temp_features[1])
434 : );
435 : }
436 :
437 : /* serialize */
438 0 : if ( read_error == U8_ERROR_NONE )
439 : {
440 : /* write relationship */
441 0 : serialize_error |= io_element_writer_start_relationship( (*this_).element_writer,
442 : DATA_CLASSIFIER_TYPE_VOID, /* host_type */
443 : &out_relation
444 : );
445 0 : serialize_error |= io_element_writer_assemble_relationship( (*this_).element_writer,
446 : NULL, /* host */
447 : &out_relation,
448 : &from_classifier,
449 0 : &((*this_).temp_features[0]),
450 : &to_classifier,
451 0 : &((*this_).temp_features[1])
452 : );
453 0 : serialize_error |= io_element_writer_end_relationship( (*this_).element_writer,
454 : DATA_CLASSIFIER_TYPE_VOID, /* host_type */
455 : &out_relation
456 : );
457 : }
458 : else
459 : {
460 : /* program internal error */
461 0 : U8_LOG_ERROR( "io_export_set_traversal_export_set could not read referenced data of the set." );
462 0 : data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_ERROR );
463 : }
464 : }
465 : else
466 : {
467 : /* program internal error */
468 0 : U8_LOG_ERROR( "io_export_set_traversal_export_set could not read all data of the set." );
469 0 : data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_ERROR );
470 : }
471 :
472 0 : U8_TRACE_END_ERR(serialize_error);
473 0 : return serialize_error;
474 : }
475 :
476 :
477 : /*
478 : Copyright 2016-2024 Andreas Warnke
479 :
480 : Licensed under the Apache License, Version 2.0 (the "License");
481 : you may not use this file except in compliance with the License.
482 : You may obtain a copy of the License at
483 :
484 : http://www.apache.org/licenses/LICENSE-2.0
485 :
486 : Unless required by applicable law or agreed to in writing, software
487 : distributed under the License is distributed on an "AS IS" BASIS,
488 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
489 : See the License for the specific language governing permissions and
490 : limitations under the License.
491 : */
|