Line data Source code
1 : /* File: json_element_writer.inl; Copyright and License: see below */
2 :
3 : #include <json/json_element_writer.h>
4 : #include "json/json_constants.h"
5 : #include "meta/meta_info.h"
6 : #include "meta/meta_version.h"
7 : #include "u8/u8_trace.h"
8 : #include "u8/u8_log.h"
9 : #include <assert.h>
10 :
11 : #define io_element_writer_impl_t json_element_writer_t
12 : /*!
13 : * \brief A struct of function pointers which is the interface of an io_element_writer
14 : *
15 : * To avoid typecasts, this struct provides function pointers with the exact right signatures
16 : * provided via io_element_writer_impl_t
17 : */
18 : struct json_element_writer_io_element_writer_if_struct {
19 : #include "io_element_writer_if.inl"
20 : };
21 : #undef io_element_writer_impl_t
22 :
23 : /* the vmt implementing the interface */
24 : static const struct json_element_writer_io_element_writer_if_struct json_element_writer_private_io_element_writer_if
25 : = {
26 : .write_header = &json_element_writer_write_header,
27 : .start_main = &json_element_writer_start_main,
28 : .can_classifier_nest_classifier = &json_element_writer_can_classifier_nest_classifier,
29 : .can_classifier_nest_relationship = &json_element_writer_can_classifier_nest_relationship,
30 : .start_classifier = &json_element_writer_start_classifier,
31 : .assemble_classifier = &json_element_writer_assemble_classifier,
32 : .end_classifier = &json_element_writer_end_classifier,
33 : .start_feature = &json_element_writer_start_feature,
34 : .assemble_feature = &json_element_writer_assemble_feature,
35 : .end_feature = &json_element_writer_end_feature,
36 : .start_relationship = &json_element_writer_start_relationship,
37 : .assemble_relationship = &json_element_writer_assemble_relationship,
38 : .end_relationship = &json_element_writer_end_relationship,
39 : .start_diagram = &json_element_writer_start_diagram,
40 : .assemble_diagram = &json_element_writer_assemble_diagram,
41 : .descend_diagram = &json_element_writer_descend_diagram,
42 : .end_diagram = &json_element_writer_end_diagram_fake,
43 : .start_diagramelement = &json_element_writer_start_diagramelement,
44 : .assemble_diagramelement = &json_element_writer_assemble_diagramelement,
45 : .end_diagramelement = &json_element_writer_end_diagramelement,
46 : .end_main = &json_element_writer_end_main,
47 : .write_footer = &json_element_writer_write_footer
48 : };
49 :
50 2 : void json_element_writer_init( json_element_writer_t *this_,
51 : data_stat_t *io_export_stat,
52 : universal_output_stream_t *output)
53 : {
54 2 : U8_TRACE_BEGIN();
55 2 : assert( io_export_stat != NULL );
56 2 : assert( output != NULL );
57 :
58 2 : io_element_writer_private_init( &((*this_).element_writer),
59 : (io_element_writer_if_t*) &json_element_writer_private_io_element_writer_if,
60 : this_
61 : );
62 :
63 2 : json_writer_init( &((*this_).json_writer), output );
64 :
65 2 : json_type_name_map_init( &((*this_).type_map) );
66 :
67 2 : (*this_).in_outer_array = false;
68 2 : (*this_).is_outer_first = false;
69 2 : (*this_).in_inner_array = false;
70 2 : (*this_).is_inner_first = false;
71 :
72 2 : (*this_).mode = JSON_WRITER_PASS_NODES;
73 2 : (*this_).export_stat = io_export_stat;
74 :
75 2 : U8_TRACE_END();
76 2 : }
77 :
78 2 : void json_element_writer_destroy( json_element_writer_t *this_ )
79 : {
80 2 : U8_TRACE_BEGIN();
81 :
82 2 : json_type_name_map_destroy( &((*this_).type_map) );
83 :
84 2 : json_writer_destroy( &((*this_).json_writer) );
85 :
86 2 : io_element_writer_private_destroy( &((*this_).element_writer) );
87 2 : (*this_).export_stat = NULL;
88 :
89 2 : U8_TRACE_END();
90 2 : }
91 :
92 4 : io_element_writer_t * json_element_writer_get_element_writer( json_element_writer_t *this_ )
93 : {
94 4 : U8_TRACE_BEGIN();
95 :
96 4 : io_element_writer_t * base = &((*this_).element_writer);
97 :
98 4 : U8_TRACE_END();
99 4 : return base;
100 : }
101 :
102 6 : void json_element_writer_set_mode( json_element_writer_t *this_, json_writer_pass_t mode )
103 : {
104 6 : U8_TRACE_BEGIN();
105 :
106 6 : (*this_).mode = mode;
107 :
108 6 : U8_TRACE_END();
109 6 : }
110 :
111 2 : u8_error_t json_element_writer_write_header( json_element_writer_t *this_, const char *document_title )
112 : {
113 2 : U8_TRACE_BEGIN();
114 2 : assert( document_title != NULL );
115 2 : assert( (*this_).in_outer_array == false );
116 2 : assert( (*this_).in_inner_array == false );
117 2 : u8_error_t out_err = U8_ERROR_NONE;
118 :
119 2 : out_err |= json_writer_write_plain( &((*this_).json_writer),
120 : JSON_CONSTANTS_BEGIN_OBJECT_NL
121 : JSON_CONSTANTS_TAB
122 : JSON_CONSTANTS_QUOTE
123 : JSON_CONSTANTS_KEY_HEAD
124 : JSON_CONSTANTS_QUOTE
125 : JSON_CONSTANTS_DEF
126 : JSON_CONSTANTS_BEGIN_OBJECT_NL
127 : );
128 :
129 2 : out_err |= json_writer_write_member_string( &((*this_).json_writer), 2, "encoding", "utf-8", true );
130 : /* hexadecimal escapes are complex: */
131 : /* a single 6-byte sequence can only encode a codepoint of the the basic multilingual plane, */
132 : /* two of these 6-byte sequences may form a surrogate pair */
133 2 : out_err |= json_writer_write_member_string( &((*this_).json_writer), 2, "structure_format", "rfc-8259 w/o hexadecimal escapes", true );
134 2 : out_err |= json_writer_write_member_string( &((*this_).json_writer), 2, "format", "cfu-json", true );
135 : #ifdef JSON_CONSTANTS_NEW_KEYS
136 : out_err |= json_writer_write_member_int( &((*this_).json_writer), 2, "major_version", 2, true );
137 : out_err |= json_writer_write_member_int( &((*this_).json_writer), 2, "minor_version", 0, true );
138 : #else
139 : /* version 1.1 stores stereotypes for diagrams and relationships */
140 2 : out_err |= json_writer_write_member_int( &((*this_).json_writer), 2, "major_version", 1, true );
141 2 : out_err |= json_writer_write_member_int( &((*this_).json_writer), 2, "minor_version", 3, true );
142 : #endif
143 2 : out_err |= json_writer_write_member_string( &((*this_).json_writer), 2, "generator_name", META_INFO_PROGRAM_ID_STR, true );
144 2 : out_err |= json_writer_write_member_string( &((*this_).json_writer), 2, "generator_version", META_VERSION_STR, false );
145 :
146 2 : out_err |= json_writer_write_plain( &((*this_).json_writer),
147 : JSON_CONSTANTS_TAB
148 : JSON_CONSTANTS_END_OBJECT
149 : JSON_CONSTANTS_NL
150 : );
151 :
152 :
153 2 : if ( out_err != 0 )
154 : {
155 0 : U8_LOG_ERROR( "output buffer exceeded." );
156 : }
157 :
158 2 : U8_TRACE_END_ERR(out_err);
159 2 : return out_err;
160 : }
161 :
162 6 : u8_error_t json_element_writer_start_main( json_element_writer_t *this_, const char *document_title )
163 : {
164 6 : U8_TRACE_BEGIN();
165 6 : assert( document_title != NULL );
166 6 : assert( (*this_).in_outer_array == false );
167 6 : assert( (*this_).in_inner_array == false );
168 6 : u8_error_t out_err = U8_ERROR_NONE;
169 :
170 6 : out_err |= json_writer_write_plain( &((*this_).json_writer),
171 : JSON_CONSTANTS_TAB
172 : JSON_CONSTANTS_NEXT_NL
173 : JSON_CONSTANTS_TAB
174 : JSON_CONSTANTS_QUOTE
175 : );
176 :
177 :
178 6 : switch( (*this_).mode )
179 : {
180 2 : case JSON_WRITER_PASS_VIEWS:
181 : {
182 2 : out_err |= json_writer_write_plain( &((*this_).json_writer), JSON_CONSTANTS_KEY_VIEWS );
183 : }
184 2 : break;
185 :
186 2 : case JSON_WRITER_PASS_NODES:
187 : {
188 2 : out_err |= json_writer_write_plain( &((*this_).json_writer), JSON_CONSTANTS_KEY_NODES );
189 : }
190 2 : break;
191 :
192 2 : case JSON_WRITER_PASS_EDGES:
193 : {
194 2 : out_err |= json_writer_write_plain( &((*this_).json_writer), JSON_CONSTANTS_KEY_EDGES );
195 : }
196 2 : break;
197 :
198 0 : default:
199 : {
200 0 : assert( false );
201 : }
202 : break;
203 : }
204 :
205 6 : out_err |= json_writer_write_plain( &((*this_).json_writer),
206 : JSON_CONSTANTS_QUOTE
207 : JSON_CONSTANTS_DEF_NL
208 : JSON_CONSTANTS_TAB
209 : JSON_CONSTANTS_BEGIN_ARRAY
210 : );
211 :
212 6 : if ( out_err != 0 )
213 : {
214 0 : U8_LOG_ERROR( "output buffer exceeded." );
215 : }
216 :
217 6 : (*this_).in_outer_array = true;
218 6 : (*this_).is_outer_first = true;
219 :
220 6 : U8_TRACE_END_ERR(out_err);
221 6 : return out_err;
222 : }
223 :
224 0 : bool json_element_writer_can_classifier_nest_classifier( json_element_writer_t *this_,
225 : data_classifier_type_t host_type,
226 : data_classifier_type_t child_type )
227 : {
228 0 : U8_TRACE_BEGIN();
229 0 : const bool can_nest = false;
230 0 : U8_TRACE_END();
231 0 : return can_nest;
232 : }
233 :
234 0 : bool json_element_writer_can_classifier_nest_relationship( json_element_writer_t *this_,
235 : data_classifier_type_t host_type,
236 : data_relationship_type_t child_type )
237 : {
238 0 : U8_TRACE_BEGIN();
239 0 : const bool can_nest = true;
240 0 : U8_TRACE_END();
241 0 : return can_nest;
242 : }
243 :
244 0 : u8_error_t json_element_writer_start_classifier( json_element_writer_t *this_,
245 : data_classifier_type_t host_type,
246 : const data_classifier_t *classifier_ptr )
247 : {
248 0 : U8_TRACE_BEGIN();
249 0 : assert( classifier_ptr != NULL );
250 0 : u8_error_t out_err = U8_ERROR_NONE;
251 :
252 0 : if ( (*this_).mode == JSON_WRITER_PASS_NODES )
253 : {
254 : /* separate objects in array if not first */
255 0 : if ( (*this_).is_outer_first )
256 : {
257 0 : (*this_).is_outer_first = false;
258 0 : out_err |= json_writer_write_plain( &((*this_).json_writer), JSON_CONSTANTS_NL );
259 : }
260 : else
261 : {
262 0 : out_err |= json_writer_write_plain( &((*this_).json_writer), JSON_CONSTANTS_NEXT_NL );
263 : }
264 :
265 : /* begin classifier */
266 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
267 : JSON_CONSTANTS_TAB
268 : JSON_CONSTANTS_TAB
269 : JSON_CONSTANTS_BEGIN_OBJECT
270 : JSON_CONSTANTS_NL
271 : JSON_CONSTANTS_TAB
272 : JSON_CONSTANTS_TAB
273 : JSON_CONSTANTS_TAB
274 : JSON_CONSTANTS_QUOTE
275 : JSON_CONSTANTS_KEY_CLASSIFIER
276 : JSON_CONSTANTS_QUOTE
277 : JSON_CONSTANTS_DEF
278 : JSON_CONSTANTS_BEGIN_OBJECT_NL );
279 : }
280 :
281 0 : U8_TRACE_END_ERR(out_err);
282 0 : return out_err;
283 : }
284 :
285 0 : u8_error_t json_element_writer_assemble_classifier( json_element_writer_t *this_,
286 : data_classifier_type_t host_type,
287 : const data_classifier_t *classifier_ptr )
288 : {
289 0 : U8_TRACE_BEGIN();
290 0 : assert( classifier_ptr != NULL );
291 0 : u8_error_t out_err = U8_ERROR_NONE;
292 :
293 0 : if ( (*this_).mode == JSON_WRITER_PASS_NODES )
294 : {
295 0 : assert( (*this_).in_outer_array == true );
296 0 : assert( (*this_).in_inner_array == false );
297 :
298 : /* id */
299 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
300 : 4,
301 : JSON_CONSTANTS_KEY_CLASSIFIER_ID,
302 0 : data_classifier_get_row_id( classifier_ptr ),
303 : true
304 : );
305 :
306 : /* type */
307 : const char *const type_name
308 0 : = json_type_name_map_get_classifier_type( &((*this_).type_map),
309 : data_classifier_get_main_type( classifier_ptr )
310 : );
311 0 : out_err |= json_writer_write_member_enum( &((*this_).json_writer),
312 : 4,
313 : JSON_CONSTANTS_KEY_TYPE_NAME,
314 : type_name,
315 : #ifdef JSON_CONSTANTS_NEW_KEYS
316 : JSON_CONSTANTS_KEY_TYPE_ID,
317 : #else
318 : JSON_CONSTANTS_KEY_CLASSIFIER_MAIN_TYPE,
319 : #endif
320 0 : data_classifier_get_main_type( classifier_ptr ),
321 : true
322 : );
323 :
324 : /* stereotype */
325 0 : if ( data_classifier_has_stereotype( classifier_ptr ) )
326 : {
327 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
328 : 4,
329 : JSON_CONSTANTS_KEY_CLASSIFIER_STEREOTYPE,
330 0 : data_classifier_get_stereotype_const( classifier_ptr ),
331 : true
332 : );
333 : }
334 :
335 : /* name */
336 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
337 : 4,
338 : JSON_CONSTANTS_KEY_CLASSIFIER_NAME,
339 0 : data_classifier_get_name_const( classifier_ptr ),
340 : true
341 : );
342 :
343 : /* description */
344 0 : out_err |= json_writer_write_member_string_array( &((*this_).json_writer) ,
345 : 4,
346 : JSON_CONSTANTS_KEY_CLASSIFIER_DESCRIPTION,
347 0 : data_classifier_get_description_const( classifier_ptr ),
348 : true
349 : );
350 :
351 : /* x_order */
352 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
353 : 4,
354 : JSON_CONSTANTS_KEY_CLASSIFIER_X_ORDER,
355 0 : data_classifier_get_x_order( classifier_ptr ),
356 : true
357 : );
358 :
359 : /* y_order */
360 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
361 : 4,
362 : JSON_CONSTANTS_KEY_CLASSIFIER_Y_ORDER,
363 0 : data_classifier_get_y_order( classifier_ptr ),
364 : true
365 : );
366 :
367 : /* list_order */
368 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
369 : 4,
370 : #ifdef JSON_CONSTANTS_NEW_KEYS
371 : JSON_CONSTANTS_KEY_ORDER,
372 : #else
373 : JSON_CONSTANTS_KEY_CLASSIFIER_LIST_ORDER,
374 : #endif
375 0 : data_classifier_get_list_order( classifier_ptr ),
376 : true
377 : );
378 :
379 : /* uuid */
380 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
381 : 4,
382 : JSON_CONSTANTS_KEY_UUID,
383 0 : data_classifier_get_uuid_const( classifier_ptr ),
384 : true
385 : );
386 :
387 : /* array of features */
388 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
389 : JSON_CONSTANTS_TAB
390 : JSON_CONSTANTS_TAB
391 : JSON_CONSTANTS_TAB
392 : JSON_CONSTANTS_TAB
393 : JSON_CONSTANTS_QUOTE
394 : JSON_CONSTANTS_KEY_CLASSIFIER_FEATURES
395 : JSON_CONSTANTS_QUOTE
396 : JSON_CONSTANTS_DEF_NL
397 : JSON_CONSTANTS_TAB
398 : JSON_CONSTANTS_TAB
399 : JSON_CONSTANTS_TAB
400 : JSON_CONSTANTS_TAB
401 : JSON_CONSTANTS_BEGIN_ARRAY
402 : );
403 :
404 0 : (*this_).in_inner_array = true;
405 0 : (*this_).is_inner_first = true;
406 :
407 : /* update export statistics */
408 0 : data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_CLASSIFIER, DATA_STAT_SERIES_EXPORTED );
409 : }
410 :
411 0 : U8_TRACE_END_ERR(out_err);
412 0 : return out_err;
413 : }
414 :
415 0 : u8_error_t json_element_writer_end_classifier( json_element_writer_t *this_,
416 : data_classifier_type_t host_type,
417 : const data_classifier_t *classifier_ptr )
418 : {
419 0 : U8_TRACE_BEGIN();
420 0 : assert( classifier_ptr != NULL );
421 0 : u8_error_t out_err = U8_ERROR_NONE;
422 :
423 0 : if ( (*this_).mode == JSON_WRITER_PASS_NODES )
424 : {
425 0 : assert( (*this_).in_outer_array == true );
426 0 : assert( (*this_).in_inner_array == true );
427 0 : (*this_).in_inner_array = false;
428 0 : (*this_).is_inner_first = false;
429 :
430 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
431 : JSON_CONSTANTS_NL
432 : );
433 :
434 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
435 : JSON_CONSTANTS_TAB
436 : JSON_CONSTANTS_TAB
437 : JSON_CONSTANTS_TAB
438 : JSON_CONSTANTS_TAB
439 : JSON_CONSTANTS_END_ARRAY
440 : JSON_CONSTANTS_NL
441 : );
442 :
443 : /* end classifier */
444 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
445 : JSON_CONSTANTS_TAB
446 : JSON_CONSTANTS_TAB
447 : JSON_CONSTANTS_TAB
448 : JSON_CONSTANTS_END_OBJECT_NL
449 : JSON_CONSTANTS_TAB
450 : JSON_CONSTANTS_TAB
451 : JSON_CONSTANTS_END_OBJECT
452 : );
453 :
454 0 : if ( out_err != 0 )
455 : {
456 0 : U8_LOG_ERROR( "output buffer exceeded." );
457 : }
458 : }
459 :
460 0 : U8_TRACE_END_ERR(out_err);
461 0 : return out_err;
462 : }
463 :
464 0 : u8_error_t json_element_writer_start_feature( json_element_writer_t *this_,
465 : data_classifier_type_t parent_type,
466 : const data_feature_t *feature_ptr )
467 : {
468 0 : U8_TRACE_BEGIN();
469 0 : assert( feature_ptr != NULL );
470 0 : u8_error_t out_err = U8_ERROR_NONE;
471 :
472 0 : if ( (*this_).mode == JSON_WRITER_PASS_NODES )
473 : {
474 : /* separate objects in array if not first */
475 0 : if ( (*this_).is_inner_first )
476 : {
477 0 : (*this_).is_inner_first = false;
478 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
479 : JSON_CONSTANTS_NL
480 : );
481 : }
482 : else
483 : {
484 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
485 : JSON_CONSTANTS_NEXT_NL
486 : );
487 : }
488 :
489 : /* begin feature */
490 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
491 : JSON_CONSTANTS_TAB
492 : JSON_CONSTANTS_TAB
493 : JSON_CONSTANTS_TAB
494 : JSON_CONSTANTS_TAB
495 : JSON_CONSTANTS_TAB
496 : JSON_CONSTANTS_BEGIN_OBJECT_NL
497 : );
498 : }
499 :
500 0 : U8_TRACE_END_ERR(out_err);
501 0 : return out_err;
502 : }
503 :
504 0 : u8_error_t json_element_writer_assemble_feature( json_element_writer_t *this_,
505 : const data_classifier_t *parent,
506 : const data_feature_t *feature_ptr )
507 : {
508 0 : U8_TRACE_BEGIN();
509 0 : assert( feature_ptr != NULL );
510 0 : assert( parent != NULL );
511 0 : u8_error_t out_err = U8_ERROR_NONE;
512 :
513 0 : if ( (*this_).mode == JSON_WRITER_PASS_NODES )
514 : {
515 0 : assert( (*this_).in_outer_array == true );
516 0 : assert( (*this_).in_inner_array == true );
517 :
518 : /* id */
519 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
520 : 6,
521 : JSON_CONSTANTS_KEY_FEATURE_ID,
522 0 : data_feature_get_row_id( feature_ptr ),
523 : true
524 : );
525 :
526 : /* type */
527 : const char *const type_name
528 0 : = json_type_name_map_get_feature_type( &((*this_).type_map),
529 : data_feature_get_main_type( feature_ptr )
530 : );
531 0 : out_err |= json_writer_write_member_enum( &((*this_).json_writer),
532 : 6,
533 : JSON_CONSTANTS_KEY_TYPE_NAME,
534 : type_name,
535 : #ifdef JSON_CONSTANTS_NEW_KEYS
536 : JSON_CONSTANTS_KEY_TYPE_ID,
537 : #else
538 : JSON_CONSTANTS_KEY_FEATURE_MAIN_TYPE,
539 : #endif
540 0 : data_feature_get_main_type( feature_ptr ),
541 : true
542 : );
543 :
544 : /* key */
545 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
546 : 6,
547 : JSON_CONSTANTS_KEY_FEATURE_KEY,
548 0 : data_feature_get_key_const( feature_ptr ),
549 : true
550 : );
551 :
552 : /* value */
553 0 : if ( data_feature_has_value( feature_ptr ) )
554 : {
555 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
556 : 6,
557 : JSON_CONSTANTS_KEY_FEATURE_VALUE,
558 0 : data_feature_get_value_const( feature_ptr ),
559 : true
560 : );
561 : }
562 :
563 : /* description */
564 0 : out_err |= json_writer_write_member_string_array( &((*this_).json_writer) ,
565 : 6,
566 : JSON_CONSTANTS_KEY_FEATURE_DESCRIPTION,
567 0 : data_feature_get_description_const( feature_ptr ),
568 : true
569 : );
570 :
571 : /* list_order */
572 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
573 : 6,
574 : #ifdef JSON_CONSTANTS_NEW_KEYS
575 : JSON_CONSTANTS_KEY_ORDER,
576 : #else
577 : JSON_CONSTANTS_KEY_FEATURE_LIST_ORDER,
578 : #endif
579 0 : data_feature_get_list_order( feature_ptr ),
580 : true
581 : );
582 :
583 : /* uuid */
584 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
585 : 6,
586 : JSON_CONSTANTS_KEY_UUID,
587 0 : data_feature_get_uuid_const( feature_ptr ),
588 : false /* LAST, no NEXT */
589 : );
590 :
591 : /* update export statistics */
592 0 : const data_feature_type_t feat_type = data_feature_get_main_type( feature_ptr );
593 0 : const data_stat_table_t feat_or_lifeline
594 0 : = ( feat_type == DATA_FEATURE_TYPE_LIFELINE ) ? DATA_STAT_TABLE_LIFELINE : DATA_STAT_TABLE_FEATURE;
595 0 : data_stat_inc_count ( (*this_).export_stat, feat_or_lifeline, DATA_STAT_SERIES_EXPORTED );
596 : }
597 :
598 0 : U8_TRACE_END_ERR(out_err);
599 0 : return out_err;
600 : }
601 :
602 0 : u8_error_t json_element_writer_end_feature( json_element_writer_t *this_,
603 : data_classifier_type_t parent_type,
604 : const data_feature_t *feature_ptr )
605 : {
606 0 : U8_TRACE_BEGIN();
607 0 : assert( feature_ptr != NULL );
608 0 : u8_error_t out_err = U8_ERROR_NONE;
609 :
610 0 : if ( (*this_).mode == JSON_WRITER_PASS_NODES )
611 : {
612 : /* end feature */
613 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
614 : JSON_CONSTANTS_TAB
615 : JSON_CONSTANTS_TAB
616 : JSON_CONSTANTS_TAB
617 : JSON_CONSTANTS_TAB
618 : JSON_CONSTANTS_TAB
619 : JSON_CONSTANTS_END_OBJECT
620 : );
621 :
622 0 : if ( out_err != 0 )
623 : {
624 0 : U8_LOG_ERROR( "output buffer exceeded." );
625 : }
626 : }
627 :
628 0 : U8_TRACE_END_ERR(out_err);
629 0 : return out_err;
630 : }
631 :
632 0 : u8_error_t json_element_writer_start_relationship( json_element_writer_t *this_,
633 : data_classifier_type_t host_type,
634 : const data_relationship_t *relation_ptr )
635 : {
636 0 : U8_TRACE_BEGIN();
637 0 : assert( relation_ptr != NULL );
638 0 : u8_error_t out_err = U8_ERROR_NONE;
639 :
640 0 : if ( (*this_).mode == JSON_WRITER_PASS_EDGES )
641 : {
642 : /* separate objects if not first */
643 0 : if ( (*this_).is_outer_first )
644 : {
645 0 : (*this_).is_outer_first = false;
646 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
647 : JSON_CONSTANTS_NL
648 : );
649 : }
650 : else
651 : {
652 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
653 : JSON_CONSTANTS_NEXT_NL
654 : );
655 : }
656 :
657 : /* begin relationship */
658 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
659 : JSON_CONSTANTS_TAB
660 : JSON_CONSTANTS_TAB
661 : JSON_CONSTANTS_BEGIN_OBJECT
662 : JSON_CONSTANTS_NL
663 : JSON_CONSTANTS_TAB
664 : JSON_CONSTANTS_TAB
665 : JSON_CONSTANTS_TAB
666 : JSON_CONSTANTS_QUOTE
667 : JSON_CONSTANTS_KEY_RELATIONSHIP
668 : JSON_CONSTANTS_QUOTE
669 : JSON_CONSTANTS_DEF
670 : JSON_CONSTANTS_BEGIN_OBJECT_NL
671 : );
672 : }
673 :
674 0 : U8_TRACE_END_ERR(out_err);
675 0 : return out_err;
676 : }
677 :
678 0 : u8_error_t json_element_writer_assemble_relationship( json_element_writer_t *this_,
679 : const data_classifier_t *host,
680 : const data_relationship_t *relation_ptr,
681 : const data_classifier_t *from_c,
682 : const data_feature_t *from_f,
683 : const data_classifier_t *to_c,
684 : const data_feature_t *to_f )
685 : {
686 0 : U8_TRACE_BEGIN();
687 0 : assert( relation_ptr != NULL );
688 0 : u8_error_t out_err = U8_ERROR_NONE;
689 :
690 0 : if ( (*this_).mode == JSON_WRITER_PASS_EDGES )
691 : {
692 0 : assert( from_c != NULL );
693 0 : assert( to_c != NULL );
694 0 : assert( (*this_).in_outer_array == true );
695 0 : assert( (*this_).in_inner_array == false );
696 :
697 0 : const bool from_f_valid = ( from_f == NULL ) ? false : data_feature_is_valid( from_f );
698 0 : const bool from_c_valid = ( from_c == NULL ) ? false : data_classifier_is_valid( from_c );
699 0 : const bool to_f_valid = ( to_f == NULL ) ? false : data_feature_is_valid( to_f );
700 0 : const bool to_c_valid = ( to_c == NULL ) ? false : data_classifier_is_valid( to_c );
701 :
702 : /* id */
703 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
704 : 4,
705 : JSON_CONSTANTS_KEY_RELATIONSHIP_ID,
706 0 : data_relationship_get_row_id( relation_ptr ),
707 : true
708 : );
709 :
710 : /* type */
711 : const char *const type_name
712 0 : = json_type_name_map_get_relationship_type( &((*this_).type_map),
713 : data_relationship_get_main_type( relation_ptr )
714 : );
715 0 : out_err |= json_writer_write_member_enum( &((*this_).json_writer),
716 : 4,
717 : JSON_CONSTANTS_KEY_TYPE_NAME,
718 : type_name,
719 : #ifdef JSON_CONSTANTS_NEW_KEYS
720 : JSON_CONSTANTS_KEY_TYPE_ID,
721 : #else
722 : JSON_CONSTANTS_KEY_RELATIONSHIP_MAIN_TYPE,
723 : #endif
724 0 : data_relationship_get_main_type( relation_ptr ),
725 : true
726 : );
727 :
728 : /* stereotype */
729 0 : if ( data_relationship_has_stereotype( relation_ptr ) )
730 : {
731 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
732 : 4,
733 : JSON_CONSTANTS_KEY_RELATIONSHIP_STEREOTYPE,
734 0 : data_relationship_get_stereotype_const( relation_ptr ),
735 : true
736 : );
737 : }
738 :
739 : /* name */
740 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
741 : 4,
742 : JSON_CONSTANTS_KEY_RELATIONSHIP_NAME,
743 0 : data_relationship_get_name_const( relation_ptr ),
744 : true
745 : );
746 :
747 : /* description */
748 0 : out_err |= json_writer_write_member_string_array( &((*this_).json_writer) ,
749 : 4,
750 : JSON_CONSTANTS_KEY_RELATIONSHIP_DESCRIPTION,
751 0 : data_relationship_get_description_const( relation_ptr ),
752 : true
753 : );
754 :
755 : /* list_order */
756 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
757 : 4,
758 : #ifdef JSON_CONSTANTS_NEW_KEYS
759 : JSON_CONSTANTS_KEY_ORDER,
760 : #else
761 : JSON_CONSTANTS_KEY_RELATIONSHIP_LIST_ORDER,
762 : #endif
763 0 : data_relationship_get_list_order( relation_ptr ),
764 : true
765 : );
766 :
767 : /* from_classifier_name */
768 0 : const char *const from_c_name = from_c_valid ? data_classifier_get_name_const( from_c ) : "";
769 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
770 : JSON_CONSTANTS_TAB
771 : JSON_CONSTANTS_TAB
772 : JSON_CONSTANTS_TAB
773 : JSON_CONSTANTS_TAB
774 : JSON_CONSTANTS_QUOTE
775 : #ifdef JSON_CONSTANTS_NEW_KEYS
776 : JSON_CONSTANTS_KEY_RELATIONSHIP_FROM_NODE_NAME
777 : #else
778 : JSON_CONSTANTS_KEY_RELATIONSHIP_FROM_CLASSIFIER_NAME
779 : #endif
780 : JSON_CONSTANTS_QUOTE
781 : JSON_CONSTANTS_DEF
782 : JSON_CONSTANTS_QUOTE
783 : );
784 0 : out_err |= json_writer_write_string_enc( &((*this_).json_writer), from_c_name );
785 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
786 : JSON_CONSTANTS_QUOTE
787 : JSON_CONSTANTS_NEXT_NL
788 : );
789 :
790 : /* from_feature_key */
791 0 : if ( from_f_valid )
792 : {
793 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
794 : JSON_CONSTANTS_TAB
795 : JSON_CONSTANTS_TAB
796 : JSON_CONSTANTS_TAB
797 : JSON_CONSTANTS_TAB
798 : JSON_CONSTANTS_QUOTE
799 : #ifdef JSON_CONSTANTS_NEW_KEYS
800 : JSON_CONSTANTS_KEY_RELATIONSHIP_FROM_PORT_NAME
801 : #else
802 : JSON_CONSTANTS_KEY_RELATIONSHIP_FROM_FEATURE_KEY
803 : #endif
804 : JSON_CONSTANTS_QUOTE
805 : JSON_CONSTANTS_DEF
806 : JSON_CONSTANTS_QUOTE
807 : );
808 0 : out_err |= json_writer_write_string_enc( &((*this_).json_writer),
809 0 : data_feature_get_key_const( from_f )
810 : );
811 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
812 : JSON_CONSTANTS_QUOTE
813 : JSON_CONSTANTS_NEXT_NL
814 : );
815 : }
816 :
817 : /* from node ref_uuid */
818 0 : const char *const from_node_ref
819 : = ( from_f_valid )
820 0 : ? data_feature_get_uuid_const( from_f )
821 0 : : ( from_c_valid )
822 0 : ? data_classifier_get_uuid_const( from_c )
823 : : "";
824 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
825 : 4,
826 : #ifdef JSON_CONSTANTS_NEW_KEYS
827 : JSON_CONSTANTS_KEY_RELATIONSHIP_FROM_NODE_UUID,
828 : #else
829 : JSON_CONSTANTS_KEY_RELATIONSHIP_FROM_NODE,
830 : #endif
831 : from_node_ref,
832 : true
833 : );
834 :
835 : /* to_classifier_name */
836 0 : const char *const to_c_name = to_c_valid ? data_classifier_get_name_const( to_c ) : "";
837 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
838 : JSON_CONSTANTS_TAB
839 : JSON_CONSTANTS_TAB
840 : JSON_CONSTANTS_TAB
841 : JSON_CONSTANTS_TAB
842 : JSON_CONSTANTS_QUOTE
843 : #ifdef JSON_CONSTANTS_NEW_KEYS
844 : JSON_CONSTANTS_KEY_RELATIONSHIP_TO_NODE_NAME
845 : #else
846 : JSON_CONSTANTS_KEY_RELATIONSHIP_TO_CLASSIFIER_NAME
847 : #endif
848 : JSON_CONSTANTS_QUOTE
849 : JSON_CONSTANTS_DEF
850 : JSON_CONSTANTS_QUOTE
851 : );
852 0 : out_err |= json_writer_write_string_enc( &((*this_).json_writer), to_c_name );
853 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
854 : JSON_CONSTANTS_QUOTE
855 : JSON_CONSTANTS_NEXT_NL
856 : );
857 :
858 : /* to_feature_key */
859 0 : if ( to_f_valid )
860 : {
861 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
862 : JSON_CONSTANTS_TAB
863 : JSON_CONSTANTS_TAB
864 : JSON_CONSTANTS_TAB
865 : JSON_CONSTANTS_TAB
866 : JSON_CONSTANTS_QUOTE
867 : #ifdef JSON_CONSTANTS_NEW_KEYS
868 : JSON_CONSTANTS_KEY_RELATIONSHIP_TO_PORT_NAME
869 : #else
870 : JSON_CONSTANTS_KEY_RELATIONSHIP_TO_FEATURE_KEY
871 : #endif
872 : JSON_CONSTANTS_QUOTE
873 : JSON_CONSTANTS_DEF
874 : JSON_CONSTANTS_QUOTE
875 : );
876 0 : out_err |= json_writer_write_string_enc( &((*this_).json_writer),
877 0 : data_feature_get_key_const( to_f )
878 : );
879 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
880 : JSON_CONSTANTS_QUOTE
881 : JSON_CONSTANTS_NEXT_NL
882 : );
883 : }
884 :
885 : /* to node ref_uuid */
886 0 : const char *const to_node_ref
887 : = ( to_f_valid )
888 0 : ? data_feature_get_uuid_const( to_f )
889 0 : : ( to_c_valid )
890 0 : ? data_classifier_get_uuid_const( to_c )
891 : : "";
892 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
893 : 4,
894 : #ifdef JSON_CONSTANTS_NEW_KEYS
895 : JSON_CONSTANTS_KEY_RELATIONSHIP_TO_NODE_UUID,
896 : #else
897 : JSON_CONSTANTS_KEY_RELATIONSHIP_TO_NODE,
898 : #endif
899 : to_node_ref,
900 : true
901 : );
902 :
903 : /* uuid */
904 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
905 : 4,
906 : JSON_CONSTANTS_KEY_UUID,
907 0 : data_relationship_get_uuid_const( relation_ptr ),
908 : false /* LAST, no NEXT */
909 : );
910 :
911 : /* update export statistics */
912 0 : data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_EXPORTED );
913 : }
914 :
915 0 : U8_TRACE_END_ERR(out_err);
916 0 : return out_err;
917 : }
918 :
919 0 : u8_error_t json_element_writer_end_relationship( json_element_writer_t *this_,
920 : data_classifier_type_t host_type,
921 : const data_relationship_t *relation_ptr )
922 : {
923 0 : U8_TRACE_BEGIN();
924 0 : assert( relation_ptr != NULL );
925 0 : u8_error_t out_err = U8_ERROR_NONE;
926 :
927 0 : if ( (*this_).mode == JSON_WRITER_PASS_EDGES )
928 : {
929 : /* end relationship */
930 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
931 : JSON_CONSTANTS_TAB
932 : JSON_CONSTANTS_TAB
933 : JSON_CONSTANTS_TAB
934 : JSON_CONSTANTS_END_OBJECT_NL
935 : JSON_CONSTANTS_TAB
936 : JSON_CONSTANTS_TAB
937 : JSON_CONSTANTS_END_OBJECT
938 : );
939 :
940 0 : if ( out_err != 0 )
941 : {
942 0 : U8_LOG_ERROR( "output buffer exceeded." );
943 : }
944 : }
945 :
946 0 : U8_TRACE_END_ERR(out_err);
947 0 : return out_err;
948 : }
949 :
950 0 : u8_error_t json_element_writer_start_diagram( json_element_writer_t *this_, const data_diagram_t *diag_ptr )
951 : {
952 0 : U8_TRACE_BEGIN();
953 0 : assert( diag_ptr != NULL );
954 0 : u8_error_t out_err = U8_ERROR_NONE;
955 :
956 0 : if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
957 : {
958 : /* separate objects if not first */
959 0 : if ( (*this_).is_outer_first )
960 : {
961 0 : (*this_).is_outer_first = false;
962 0 : out_err |= json_writer_write_plain( &((*this_).json_writer), JSON_CONSTANTS_NL );
963 : }
964 : else
965 : {
966 : /* print diagram end here because the official end requires hierarcical diagram containments */
967 0 : out_err |= json_element_writer_private_end_diagram( this_ );
968 :
969 0 : out_err |= json_writer_write_plain( &((*this_).json_writer), JSON_CONSTANTS_NEXT_NL );
970 : }
971 :
972 0 : assert( (*this_).in_outer_array == true );
973 0 : assert( (*this_).in_inner_array == false );
974 :
975 : /* begin diagram */
976 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
977 : JSON_CONSTANTS_TAB
978 : JSON_CONSTANTS_TAB
979 : JSON_CONSTANTS_BEGIN_OBJECT
980 : JSON_CONSTANTS_NL
981 : JSON_CONSTANTS_TAB
982 : JSON_CONSTANTS_TAB
983 : JSON_CONSTANTS_TAB
984 : JSON_CONSTANTS_QUOTE
985 : JSON_CONSTANTS_KEY_DIAGRAM
986 : JSON_CONSTANTS_QUOTE
987 : JSON_CONSTANTS_DEF
988 : JSON_CONSTANTS_BEGIN_OBJECT_NL
989 : );
990 : }
991 :
992 0 : U8_TRACE_END_ERR(out_err);
993 0 : return out_err;
994 : }
995 :
996 0 : u8_error_t json_element_writer_assemble_diagram( json_element_writer_t *this_,
997 : const data_diagram_t *parent,
998 : const data_diagram_t *diag_ptr,
999 : const char *diagram_file_base_name )
1000 : {
1001 0 : U8_TRACE_BEGIN();
1002 0 : assert( diag_ptr != NULL );
1003 0 : assert( diagram_file_base_name != NULL );
1004 0 : u8_error_t out_err = U8_ERROR_NONE;
1005 :
1006 0 : if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
1007 : {
1008 : /* id */
1009 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
1010 : 4,
1011 : JSON_CONSTANTS_KEY_DIAGRAM_ID,
1012 0 : data_diagram_get_row_id( diag_ptr ),
1013 : true
1014 : );
1015 :
1016 : /* diagram type */
1017 : const char *const type_name
1018 0 : = json_type_name_map_get_diagram_type( &((*this_).type_map),
1019 : data_diagram_get_diagram_type( diag_ptr )
1020 : );
1021 0 : out_err |= json_writer_write_member_enum( &((*this_).json_writer),
1022 : 4,
1023 : JSON_CONSTANTS_KEY_TYPE_NAME,
1024 : type_name,
1025 : #ifdef JSON_CONSTANTS_NEW_KEYS
1026 : JSON_CONSTANTS_KEY_TYPE_ID,
1027 : #else
1028 : JSON_CONSTANTS_KEY_DIAGRAM_DIAGRAM_TYPE,
1029 : #endif
1030 0 : data_diagram_get_diagram_type( diag_ptr ),
1031 : true
1032 : );
1033 :
1034 : /* stereotype */
1035 0 : if ( data_diagram_has_stereotype( diag_ptr ) )
1036 : {
1037 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1038 : 4,
1039 : JSON_CONSTANTS_KEY_DIAGRAM_STEREOTYPE,
1040 0 : data_diagram_get_stereotype_const( diag_ptr ),
1041 : true
1042 : );
1043 : }
1044 :
1045 : /* name */
1046 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1047 : 4,
1048 : JSON_CONSTANTS_KEY_DIAGRAM_NAME,
1049 0 : data_diagram_get_name_const( diag_ptr ),
1050 : true
1051 : );
1052 :
1053 : /* description */
1054 0 : out_err |= json_writer_write_member_string_array( &((*this_).json_writer) ,
1055 : 4,
1056 : JSON_CONSTANTS_KEY_DIAGRAM_DESCRIPTION,
1057 0 : data_diagram_get_description_const( diag_ptr ),
1058 : true
1059 : );
1060 :
1061 : /* list_order */
1062 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
1063 : 4,
1064 : #ifdef JSON_CONSTANTS_NEW_KEYS
1065 : JSON_CONSTANTS_KEY_ORDER,
1066 : #else
1067 : JSON_CONSTANTS_KEY_DIAGRAM_LIST_ORDER,
1068 : #endif
1069 0 : data_diagram_get_list_order( diag_ptr ),
1070 : true
1071 : );
1072 :
1073 : /* display_tags (flag names) + display_flags */
1074 0 : if ( data_diagram_get_display_flags( diag_ptr ) != DATA_DIAGRAM_FLAG_NONE )
1075 : {
1076 : const char *const tag_names
1077 0 : = json_type_name_map_get_diagram_tags( &((*this_).type_map),
1078 : data_diagram_get_display_flags( diag_ptr )
1079 : );
1080 :
1081 0 : out_err |= json_writer_write_member_enum( &((*this_).json_writer),
1082 : 4,
1083 : JSON_CONSTANTS_KEY_DIAGRAM_DISPLAY_FLAG_NAMES,
1084 : tag_names,
1085 : JSON_CONSTANTS_KEY_DIAGRAM_DISPLAY_FLAGS,
1086 0 : data_diagram_get_display_flags( diag_ptr ),
1087 : true
1088 : );
1089 : }
1090 :
1091 0 : const bool parent_valid = ( parent == NULL ) ? false : data_diagram_is_valid( parent );
1092 :
1093 : /* parent_name */
1094 0 : if( parent_valid )
1095 : {
1096 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1097 : 4,
1098 : JSON_CONSTANTS_KEY_DIAGRAM_PARENT_NAME,
1099 0 : data_diagram_get_name_const( parent ),
1100 : true
1101 : );
1102 : }
1103 :
1104 : /* parent uuid */
1105 0 : if ( parent_valid )
1106 : {
1107 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1108 : 4,
1109 : JSON_CONSTANTS_KEY_DIAGRAM_PARENT,
1110 0 : data_diagram_get_uuid_const( parent ),
1111 : true
1112 : );
1113 : }
1114 :
1115 : /* uuid */
1116 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1117 : 4,
1118 : JSON_CONSTANTS_KEY_UUID,
1119 0 : data_diagram_get_uuid_const( diag_ptr ),
1120 : true /* NEXT, not LAST */
1121 : );
1122 :
1123 : /* array of features */
1124 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1125 : JSON_CONSTANTS_TAB
1126 : JSON_CONSTANTS_TAB
1127 : JSON_CONSTANTS_TAB
1128 : JSON_CONSTANTS_TAB
1129 : JSON_CONSTANTS_QUOTE
1130 : #ifdef JSON_CONSTANTS_NEW_KEYS
1131 : JSON_CONSTANTS_KEY_DIAGRAM_ELEMENT_LIST
1132 : #else
1133 : JSON_CONSTANTS_KEY_DIAGRAM_ELEMENTS
1134 : #endif
1135 : JSON_CONSTANTS_QUOTE
1136 : JSON_CONSTANTS_DEF_NL
1137 : JSON_CONSTANTS_TAB
1138 : JSON_CONSTANTS_TAB
1139 : JSON_CONSTANTS_TAB
1140 : JSON_CONSTANTS_TAB
1141 : JSON_CONSTANTS_BEGIN_ARRAY
1142 : );
1143 :
1144 0 : (*this_).in_inner_array = true;
1145 0 : (*this_).is_inner_first = true;
1146 :
1147 : /* update export statistics */
1148 0 : data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_EXPORTED );
1149 : }
1150 :
1151 0 : U8_TRACE_END_ERR(out_err);
1152 0 : return out_err;
1153 : }
1154 :
1155 0 : u8_error_t json_element_writer_descend_diagram( json_element_writer_t *this_, const data_diagram_t *diag_ptr )
1156 : {
1157 0 : U8_TRACE_BEGIN();
1158 0 : assert( diag_ptr != NULL );
1159 0 : u8_error_t out_err = U8_ERROR_NONE;
1160 :
1161 0 : U8_TRACE_END_ERR(out_err);
1162 0 : return out_err;
1163 : }
1164 :
1165 0 : u8_error_t json_element_writer_end_diagram_fake( json_element_writer_t *this_, const data_diagram_t *diag_ptr )
1166 : {
1167 0 : U8_TRACE_BEGIN();
1168 0 : assert( diag_ptr != NULL );
1169 0 : u8_error_t out_err = U8_ERROR_NONE;
1170 :
1171 : /* The JSON export does not encapsulate one diagram into another. */
1172 : /* Therefore, diagrams are ended already when the next starts. */
1173 :
1174 0 : U8_TRACE_END_ERR(out_err);
1175 0 : return out_err;
1176 : }
1177 :
1178 0 : u8_error_t json_element_writer_private_end_diagram( json_element_writer_t *this_ )
1179 : {
1180 0 : U8_TRACE_BEGIN();
1181 0 : u8_error_t out_err = U8_ERROR_NONE;
1182 :
1183 0 : if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
1184 : {
1185 0 : (*this_).in_inner_array = false;
1186 0 : (*this_).is_inner_first = false;
1187 :
1188 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1189 : JSON_CONSTANTS_NL
1190 : );
1191 :
1192 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1193 : JSON_CONSTANTS_TAB
1194 : JSON_CONSTANTS_TAB
1195 : JSON_CONSTANTS_TAB
1196 : JSON_CONSTANTS_TAB
1197 : JSON_CONSTANTS_END_ARRAY
1198 : JSON_CONSTANTS_NL
1199 : );
1200 :
1201 : /* end diagram */
1202 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1203 : JSON_CONSTANTS_TAB
1204 : JSON_CONSTANTS_TAB
1205 : JSON_CONSTANTS_TAB
1206 : JSON_CONSTANTS_END_OBJECT_NL
1207 : JSON_CONSTANTS_TAB
1208 : JSON_CONSTANTS_TAB
1209 : JSON_CONSTANTS_END_OBJECT
1210 : );
1211 : }
1212 :
1213 0 : U8_TRACE_END_ERR(out_err);
1214 0 : return out_err;
1215 : }
1216 :
1217 0 : u8_error_t json_element_writer_start_diagramelement( json_element_writer_t *this_,
1218 : const data_diagram_t *parent,
1219 : const data_diagramelement_t *diagramelement_ptr )
1220 : {
1221 0 : U8_TRACE_BEGIN();
1222 0 : assert( diagramelement_ptr != NULL );
1223 0 : assert( parent != NULL );
1224 0 : u8_error_t out_err = U8_ERROR_NONE;
1225 :
1226 0 : if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
1227 : {
1228 : /* separate objects in array if not first */
1229 0 : if ( (*this_).is_inner_first )
1230 : {
1231 0 : (*this_).is_inner_first = false;
1232 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1233 : JSON_CONSTANTS_NL
1234 : );
1235 : }
1236 : else
1237 : {
1238 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1239 : JSON_CONSTANTS_NEXT_NL
1240 : );
1241 : }
1242 :
1243 : /* begin diagramelement */
1244 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1245 : JSON_CONSTANTS_TAB
1246 : JSON_CONSTANTS_TAB
1247 : JSON_CONSTANTS_TAB
1248 : JSON_CONSTANTS_TAB
1249 : JSON_CONSTANTS_TAB
1250 : JSON_CONSTANTS_BEGIN_OBJECT_NL
1251 : );
1252 :
1253 0 : if ( out_err != 0 )
1254 : {
1255 0 : U8_LOG_ERROR( "output buffer exceeded." );
1256 : }
1257 : }
1258 :
1259 0 : U8_TRACE_END_ERR(out_err);
1260 0 : return out_err;
1261 : }
1262 :
1263 0 : u8_error_t json_element_writer_assemble_diagramelement( json_element_writer_t *this_,
1264 : const data_diagram_t *parent,
1265 : const data_diagramelement_t *diagramelement_ptr,
1266 : const data_classifier_t *occurrence,
1267 : const data_feature_t *feat_occur )
1268 : {
1269 0 : U8_TRACE_BEGIN();
1270 0 : assert( parent != NULL );
1271 0 : assert( diagramelement_ptr != NULL );
1272 0 : assert( occurrence != NULL );
1273 : /* feat_occur may be NULL */
1274 0 : u8_error_t out_err = U8_ERROR_NONE;
1275 :
1276 0 : if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
1277 : {
1278 0 : assert( (*this_).in_outer_array == true );
1279 0 : assert( (*this_).in_inner_array == true );
1280 :
1281 : /* id */
1282 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
1283 : 6,
1284 : JSON_CONSTANTS_KEY_DIAGRAMELEMENT_ID,
1285 0 : data_diagramelement_get_row_id( diagramelement_ptr ),
1286 : true
1287 : );
1288 :
1289 : /* classifier_name */
1290 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1291 : 6,
1292 : #ifdef JSON_CONSTANTS_NEW_KEYS
1293 : JSON_CONSTANTS_KEY_DIAGRAMELEMENT_NODE_NAME,
1294 : #else
1295 : JSON_CONSTANTS_KEY_DIAGRAMELEMENT_CLASSIFIER_NAME,
1296 : #endif
1297 0 : data_classifier_get_name_const( occurrence ),
1298 : true
1299 : );
1300 :
1301 : /* focused_feature_name */
1302 : /* note that focused features are always lifelines and these never have names */
1303 :
1304 : /* ref_uuid */
1305 0 : const bool feat_valid = ( feat_occur == NULL ) ? false : data_feature_is_valid( feat_occur );
1306 0 : const bool clas_valid = data_classifier_is_valid( occurrence );
1307 0 : const char *const node_ref
1308 : = ( feat_valid )
1309 0 : ? data_feature_get_uuid_const( feat_occur )
1310 0 : : ( clas_valid )
1311 0 : ? data_classifier_get_uuid_const( occurrence )
1312 : : "";
1313 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1314 : 6,
1315 : JSON_CONSTANTS_KEY_DIAGRAMELEMENT_NODE,
1316 : node_ref,
1317 : true
1318 : );
1319 :
1320 : /* display_tags (flag names) + display_flags */
1321 0 : if ( data_diagramelement_get_display_flags( diagramelement_ptr ) != DATA_DIAGRAMELEMENT_FLAG_NONE )
1322 : {
1323 : const char *const tag_names
1324 0 : = json_type_name_map_get_diagramelement_tags( &((*this_).type_map),
1325 : data_diagramelement_get_display_flags( diagramelement_ptr )
1326 : );
1327 0 : out_err |= json_writer_write_member_enum( &((*this_).json_writer),
1328 : 6,
1329 : JSON_CONSTANTS_KEY_DIAGRAMELEMENT_DISPLAY_FLAG_NAMES,
1330 : tag_names,
1331 : JSON_CONSTANTS_KEY_DIAGRAMELEMENT_DISPLAY_FLAGS,
1332 0 : data_diagramelement_get_display_flags( diagramelement_ptr ),
1333 : true
1334 : );
1335 : }
1336 :
1337 : /* uuid */
1338 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1339 : 6,
1340 : JSON_CONSTANTS_KEY_UUID,
1341 0 : data_diagramelement_get_uuid_const( diagramelement_ptr ),
1342 : false /* LAST, no NEXT */
1343 : );
1344 :
1345 : /* update export statistics */
1346 0 : data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_EXPORTED );
1347 : }
1348 :
1349 0 : U8_TRACE_END_ERR(out_err);
1350 0 : return out_err;
1351 : }
1352 :
1353 0 : u8_error_t json_element_writer_end_diagramelement( json_element_writer_t *this_,
1354 : const data_diagram_t *parent,
1355 : const data_diagramelement_t *diagramelement_ptr )
1356 : {
1357 0 : U8_TRACE_BEGIN();
1358 0 : assert( diagramelement_ptr != NULL );
1359 0 : assert( parent != NULL );
1360 0 : u8_error_t out_err = U8_ERROR_NONE;
1361 :
1362 0 : if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
1363 : {
1364 : /* end diagramelement */
1365 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1366 : JSON_CONSTANTS_TAB
1367 : JSON_CONSTANTS_TAB
1368 : JSON_CONSTANTS_TAB
1369 : JSON_CONSTANTS_TAB
1370 : JSON_CONSTANTS_TAB
1371 : JSON_CONSTANTS_END_OBJECT
1372 : );
1373 :
1374 0 : if ( out_err != 0 )
1375 : {
1376 0 : U8_LOG_ERROR( "output buffer exceeded." );
1377 : }
1378 : }
1379 :
1380 0 : U8_TRACE_END_ERR(out_err);
1381 0 : return out_err;
1382 : }
1383 :
1384 6 : u8_error_t json_element_writer_end_main( json_element_writer_t *this_ )
1385 : {
1386 6 : U8_TRACE_BEGIN();
1387 6 : u8_error_t out_err = U8_ERROR_NONE;
1388 :
1389 : /* print diagram end here because the official end requires hierarcical diagram containments */
1390 6 : if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
1391 : {
1392 2 : if ( ! (*this_).is_outer_first )
1393 : {
1394 0 : out_err |= json_element_writer_private_end_diagram( this_ );
1395 : }
1396 : }
1397 :
1398 6 : assert( (*this_).in_outer_array == true );
1399 6 : assert( (*this_).in_inner_array == false );
1400 6 : (*this_).in_outer_array = false;
1401 6 : (*this_).is_outer_first = false;
1402 :
1403 6 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1404 : JSON_CONSTANTS_NL
1405 : JSON_CONSTANTS_TAB
1406 : JSON_CONSTANTS_END_ARRAY
1407 : JSON_CONSTANTS_NL
1408 : );
1409 :
1410 6 : if ( out_err != 0 )
1411 : {
1412 0 : U8_LOG_ERROR( "output buffer exceeded." );
1413 : }
1414 :
1415 6 : U8_TRACE_END_ERR(out_err);
1416 6 : return out_err;
1417 : }
1418 :
1419 2 : u8_error_t json_element_writer_write_footer( json_element_writer_t *this_ )
1420 : {
1421 2 : U8_TRACE_BEGIN();
1422 2 : assert( (*this_).in_outer_array == false );
1423 2 : assert( (*this_).in_inner_array == false );
1424 2 : u8_error_t out_err = U8_ERROR_NONE;
1425 :
1426 2 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1427 : JSON_CONSTANTS_END_OBJECT_NL
1428 : );
1429 :
1430 2 : if ( out_err != 0 )
1431 : {
1432 0 : U8_LOG_ERROR( "output buffer exceeded." );
1433 : }
1434 :
1435 2 : U8_TRACE_END_ERR(out_err);
1436 2 : return out_err;
1437 : }
1438 :
1439 :
1440 : /*
1441 : Copyright 2016-2026 Andreas Warnke
1442 :
1443 : Licensed under the Apache License, Version 2.0 (the "License");
1444 : you may not use this file except in compliance with the License.
1445 : You may obtain a copy of the License at
1446 :
1447 : http://www.apache.org/licenses/LICENSE-2.0
1448 :
1449 : Unless required by applicable law or agreed to in writing, software
1450 : distributed under the License is distributed on an "AS IS" BASIS,
1451 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1452 : See the License for the specific language governing permissions and
1453 : limitations under the License.
1454 : */
|