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( 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 0 : const bool is_lifeline = ( DATA_FEATURE_TYPE_LIFELINE == data_feature_get_main_type( feature_ptr ) );
513 :
514 0 : if ( (*this_).mode == JSON_WRITER_PASS_NODES )
515 : {
516 0 : assert( (*this_).in_outer_array == true );
517 0 : assert( (*this_).in_inner_array == true );
518 :
519 : /* id */
520 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
521 : 6,
522 : JSON_CONSTANTS_KEY_FEATURE_ID,
523 0 : data_feature_get_row( feature_ptr ),
524 : true
525 : );
526 :
527 : /* type */
528 : const char *const type_name
529 0 : = json_type_name_map_get_feature_type( &((*this_).type_map),
530 : data_feature_get_main_type( feature_ptr )
531 : );
532 0 : out_err |= json_writer_write_member_enum( &((*this_).json_writer),
533 : 6,
534 : JSON_CONSTANTS_KEY_TYPE_NAME,
535 : type_name,
536 : #ifdef JSON_CONSTANTS_NEW_KEYS
537 : JSON_CONSTANTS_KEY_TYPE_ID,
538 : #else
539 : JSON_CONSTANTS_KEY_FEATURE_MAIN_TYPE,
540 : #endif
541 0 : data_feature_get_main_type( feature_ptr ),
542 : true
543 : );
544 :
545 0 : if (( ! is_lifeline )||( 0 != utf8string_get_length( data_feature_get_key_const( feature_ptr ) ) ))
546 : {
547 : /* key */
548 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
549 : 6,
550 : JSON_CONSTANTS_KEY_FEATURE_KEY,
551 0 : data_feature_get_key_const( feature_ptr ),
552 : true
553 : );
554 : }
555 :
556 : /* value */
557 0 : if ( data_feature_has_value( feature_ptr ) )
558 : {
559 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
560 : 6,
561 : JSON_CONSTANTS_KEY_FEATURE_VALUE,
562 0 : data_feature_get_value_const( feature_ptr ),
563 : true
564 : );
565 : }
566 :
567 0 : if (( ! is_lifeline )||( 0 != utf8string_get_length( data_feature_get_description_const( feature_ptr ) ) ))
568 : {
569 : /* description */
570 0 : out_err |= json_writer_write_member_string_array( &((*this_).json_writer) ,
571 : 6,
572 : JSON_CONSTANTS_KEY_FEATURE_DESCRIPTION,
573 0 : data_feature_get_description_const( feature_ptr ),
574 : true
575 : );
576 : }
577 :
578 0 : if (( ! is_lifeline )||( 0 != data_feature_get_list_order( feature_ptr ) ))
579 : {
580 : /* list_order */
581 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
582 : 6,
583 : #ifdef JSON_CONSTANTS_NEW_KEYS
584 : JSON_CONSTANTS_KEY_ORDER,
585 : #else
586 : JSON_CONSTANTS_KEY_FEATURE_LIST_ORDER,
587 : #endif
588 0 : data_feature_get_list_order( feature_ptr ),
589 : true
590 : );
591 : }
592 :
593 : /* uuid */
594 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
595 : 6,
596 : JSON_CONSTANTS_KEY_UUID,
597 0 : data_feature_get_uuid_const( feature_ptr ),
598 : false /* LAST, no NEXT */
599 : );
600 :
601 : /* update export statistics */
602 0 : const data_feature_type_t feat_type = data_feature_get_main_type( feature_ptr );
603 0 : const data_stat_table_t feat_or_lifeline
604 0 : = ( feat_type == DATA_FEATURE_TYPE_LIFELINE ) ? DATA_STAT_TABLE_LIFELINE : DATA_STAT_TABLE_FEATURE;
605 0 : data_stat_inc_count ( (*this_).export_stat, feat_or_lifeline, DATA_STAT_SERIES_EXPORTED );
606 : }
607 :
608 0 : U8_TRACE_END_ERR(out_err);
609 0 : return out_err;
610 : }
611 :
612 0 : u8_error_t json_element_writer_end_feature( json_element_writer_t *this_,
613 : data_classifier_type_t parent_type,
614 : const data_feature_t *feature_ptr )
615 : {
616 0 : U8_TRACE_BEGIN();
617 0 : assert( feature_ptr != NULL );
618 0 : u8_error_t out_err = U8_ERROR_NONE;
619 :
620 0 : if ( (*this_).mode == JSON_WRITER_PASS_NODES )
621 : {
622 : /* end feature */
623 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
624 : JSON_CONSTANTS_TAB
625 : JSON_CONSTANTS_TAB
626 : JSON_CONSTANTS_TAB
627 : JSON_CONSTANTS_TAB
628 : JSON_CONSTANTS_TAB
629 : JSON_CONSTANTS_END_OBJECT
630 : );
631 :
632 0 : if ( out_err != 0 )
633 : {
634 0 : U8_LOG_ERROR( "output buffer exceeded." );
635 : }
636 : }
637 :
638 0 : U8_TRACE_END_ERR(out_err);
639 0 : return out_err;
640 : }
641 :
642 0 : u8_error_t json_element_writer_start_relationship( json_element_writer_t *this_,
643 : data_classifier_type_t host_type,
644 : const data_relationship_t *relation_ptr )
645 : {
646 0 : U8_TRACE_BEGIN();
647 0 : assert( relation_ptr != NULL );
648 0 : u8_error_t out_err = U8_ERROR_NONE;
649 :
650 0 : if ( (*this_).mode == JSON_WRITER_PASS_EDGES )
651 : {
652 : /* separate objects if not first */
653 0 : if ( (*this_).is_outer_first )
654 : {
655 0 : (*this_).is_outer_first = false;
656 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
657 : JSON_CONSTANTS_NL
658 : );
659 : }
660 : else
661 : {
662 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
663 : JSON_CONSTANTS_NEXT_NL
664 : );
665 : }
666 :
667 : /* begin relationship */
668 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
669 : JSON_CONSTANTS_TAB
670 : JSON_CONSTANTS_TAB
671 : JSON_CONSTANTS_BEGIN_OBJECT
672 : JSON_CONSTANTS_NL
673 : JSON_CONSTANTS_TAB
674 : JSON_CONSTANTS_TAB
675 : JSON_CONSTANTS_TAB
676 : JSON_CONSTANTS_QUOTE
677 : JSON_CONSTANTS_KEY_RELATIONSHIP
678 : JSON_CONSTANTS_QUOTE
679 : JSON_CONSTANTS_DEF
680 : JSON_CONSTANTS_BEGIN_OBJECT_NL
681 : );
682 : }
683 :
684 0 : U8_TRACE_END_ERR(out_err);
685 0 : return out_err;
686 : }
687 :
688 0 : u8_error_t json_element_writer_assemble_relationship( json_element_writer_t *this_,
689 : const data_classifier_t *host,
690 : const data_relationship_t *relation_ptr,
691 : const data_classifier_t *from_c,
692 : const data_feature_t *from_f,
693 : const data_classifier_t *to_c,
694 : const data_feature_t *to_f )
695 : {
696 0 : U8_TRACE_BEGIN();
697 0 : assert( relation_ptr != NULL );
698 0 : u8_error_t out_err = U8_ERROR_NONE;
699 :
700 0 : if ( (*this_).mode == JSON_WRITER_PASS_EDGES )
701 : {
702 0 : assert( from_c != NULL );
703 0 : assert( to_c != NULL );
704 0 : assert( (*this_).in_outer_array == true );
705 0 : assert( (*this_).in_inner_array == false );
706 :
707 0 : const bool from_f_valid = ( from_f == NULL ) ? false : data_feature_is_valid( from_f );
708 0 : const bool from_c_valid = ( from_c == NULL ) ? false : data_classifier_is_valid( from_c );
709 0 : const bool to_f_valid = ( to_f == NULL ) ? false : data_feature_is_valid( to_f );
710 0 : const bool to_c_valid = ( to_c == NULL ) ? false : data_classifier_is_valid( to_c );
711 :
712 : /* id */
713 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
714 : 4,
715 : JSON_CONSTANTS_KEY_RELATIONSHIP_ID,
716 0 : data_relationship_get_row( relation_ptr ),
717 : true
718 : );
719 :
720 : /* type */
721 : const char *const type_name
722 0 : = json_type_name_map_get_relationship_type( &((*this_).type_map),
723 : data_relationship_get_main_type( relation_ptr )
724 : );
725 0 : out_err |= json_writer_write_member_enum( &((*this_).json_writer),
726 : 4,
727 : JSON_CONSTANTS_KEY_TYPE_NAME,
728 : type_name,
729 : #ifdef JSON_CONSTANTS_NEW_KEYS
730 : JSON_CONSTANTS_KEY_TYPE_ID,
731 : #else
732 : JSON_CONSTANTS_KEY_RELATIONSHIP_MAIN_TYPE,
733 : #endif
734 0 : data_relationship_get_main_type( relation_ptr ),
735 : true
736 : );
737 :
738 : /* stereotype */
739 0 : if ( data_relationship_has_stereotype( relation_ptr ) )
740 : {
741 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
742 : 4,
743 : JSON_CONSTANTS_KEY_RELATIONSHIP_STEREOTYPE,
744 0 : data_relationship_get_stereotype_const( relation_ptr ),
745 : true
746 : );
747 : }
748 :
749 : /* name */
750 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
751 : 4,
752 : JSON_CONSTANTS_KEY_RELATIONSHIP_NAME,
753 0 : data_relationship_get_name_const( relation_ptr ),
754 : true
755 : );
756 :
757 : /* description */
758 0 : out_err |= json_writer_write_member_string_array( &((*this_).json_writer) ,
759 : 4,
760 : JSON_CONSTANTS_KEY_RELATIONSHIP_DESCRIPTION,
761 0 : data_relationship_get_description_const( relation_ptr ),
762 : true
763 : );
764 :
765 : /* list_order */
766 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
767 : 4,
768 : #ifdef JSON_CONSTANTS_NEW_KEYS
769 : JSON_CONSTANTS_KEY_ORDER,
770 : #else
771 : JSON_CONSTANTS_KEY_RELATIONSHIP_LIST_ORDER,
772 : #endif
773 0 : data_relationship_get_list_order( relation_ptr ),
774 : true
775 : );
776 :
777 : /* from_classifier_name */
778 0 : const char *const from_c_name = from_c_valid ? data_classifier_get_name_const( from_c ) : "";
779 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
780 : JSON_CONSTANTS_TAB
781 : JSON_CONSTANTS_TAB
782 : JSON_CONSTANTS_TAB
783 : JSON_CONSTANTS_TAB
784 : JSON_CONSTANTS_QUOTE
785 : #ifdef JSON_CONSTANTS_NEW_KEYS
786 : JSON_CONSTANTS_KEY_RELATIONSHIP_FROM_NODE_NAME
787 : #else
788 : JSON_CONSTANTS_KEY_RELATIONSHIP_FROM_CLASSIFIER_NAME
789 : #endif
790 : JSON_CONSTANTS_QUOTE
791 : JSON_CONSTANTS_DEF
792 : JSON_CONSTANTS_QUOTE
793 : );
794 0 : out_err |= json_writer_write_string_enc( &((*this_).json_writer), from_c_name );
795 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
796 : JSON_CONSTANTS_QUOTE
797 : JSON_CONSTANTS_NEXT_NL
798 : );
799 :
800 : /* from_feature_key */
801 0 : if ( from_f_valid )
802 : {
803 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
804 : JSON_CONSTANTS_TAB
805 : JSON_CONSTANTS_TAB
806 : JSON_CONSTANTS_TAB
807 : JSON_CONSTANTS_TAB
808 : JSON_CONSTANTS_QUOTE
809 : #ifdef JSON_CONSTANTS_NEW_KEYS
810 : JSON_CONSTANTS_KEY_RELATIONSHIP_FROM_PORT_NAME
811 : #else
812 : JSON_CONSTANTS_KEY_RELATIONSHIP_FROM_FEATURE_KEY
813 : #endif
814 : JSON_CONSTANTS_QUOTE
815 : JSON_CONSTANTS_DEF
816 : JSON_CONSTANTS_QUOTE
817 : );
818 0 : out_err |= json_writer_write_string_enc( &((*this_).json_writer),
819 0 : data_feature_get_key_const( from_f )
820 : );
821 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
822 : JSON_CONSTANTS_QUOTE
823 : JSON_CONSTANTS_NEXT_NL
824 : );
825 : }
826 :
827 : /* from node ref_uuid */
828 0 : const char *const from_node_ref
829 : = ( from_f_valid )
830 0 : ? data_feature_get_uuid_const( from_f )
831 0 : : ( from_c_valid )
832 0 : ? data_classifier_get_uuid_const( from_c )
833 : : "";
834 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
835 : 4,
836 : #ifdef JSON_CONSTANTS_NEW_KEYS
837 : JSON_CONSTANTS_KEY_RELATIONSHIP_FROM_NODE_UUID,
838 : #else
839 : JSON_CONSTANTS_KEY_RELATIONSHIP_FROM_NODE,
840 : #endif
841 : from_node_ref,
842 : true
843 : );
844 :
845 : /* to_classifier_name */
846 0 : const char *const to_c_name = to_c_valid ? data_classifier_get_name_const( to_c ) : "";
847 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
848 : JSON_CONSTANTS_TAB
849 : JSON_CONSTANTS_TAB
850 : JSON_CONSTANTS_TAB
851 : JSON_CONSTANTS_TAB
852 : JSON_CONSTANTS_QUOTE
853 : #ifdef JSON_CONSTANTS_NEW_KEYS
854 : JSON_CONSTANTS_KEY_RELATIONSHIP_TO_NODE_NAME
855 : #else
856 : JSON_CONSTANTS_KEY_RELATIONSHIP_TO_CLASSIFIER_NAME
857 : #endif
858 : JSON_CONSTANTS_QUOTE
859 : JSON_CONSTANTS_DEF
860 : JSON_CONSTANTS_QUOTE
861 : );
862 0 : out_err |= json_writer_write_string_enc( &((*this_).json_writer), to_c_name );
863 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
864 : JSON_CONSTANTS_QUOTE
865 : JSON_CONSTANTS_NEXT_NL
866 : );
867 :
868 : /* to_feature_key */
869 0 : if ( to_f_valid )
870 : {
871 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
872 : JSON_CONSTANTS_TAB
873 : JSON_CONSTANTS_TAB
874 : JSON_CONSTANTS_TAB
875 : JSON_CONSTANTS_TAB
876 : JSON_CONSTANTS_QUOTE
877 : #ifdef JSON_CONSTANTS_NEW_KEYS
878 : JSON_CONSTANTS_KEY_RELATIONSHIP_TO_PORT_NAME
879 : #else
880 : JSON_CONSTANTS_KEY_RELATIONSHIP_TO_FEATURE_KEY
881 : #endif
882 : JSON_CONSTANTS_QUOTE
883 : JSON_CONSTANTS_DEF
884 : JSON_CONSTANTS_QUOTE
885 : );
886 0 : out_err |= json_writer_write_string_enc( &((*this_).json_writer),
887 0 : data_feature_get_key_const( to_f )
888 : );
889 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
890 : JSON_CONSTANTS_QUOTE
891 : JSON_CONSTANTS_NEXT_NL
892 : );
893 : }
894 :
895 : /* to node ref_uuid */
896 0 : const char *const to_node_ref
897 : = ( to_f_valid )
898 0 : ? data_feature_get_uuid_const( to_f )
899 0 : : ( to_c_valid )
900 0 : ? data_classifier_get_uuid_const( to_c )
901 : : "";
902 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
903 : 4,
904 : #ifdef JSON_CONSTANTS_NEW_KEYS
905 : JSON_CONSTANTS_KEY_RELATIONSHIP_TO_NODE_UUID,
906 : #else
907 : JSON_CONSTANTS_KEY_RELATIONSHIP_TO_NODE,
908 : #endif
909 : to_node_ref,
910 : true
911 : );
912 :
913 : /* uuid */
914 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
915 : 4,
916 : JSON_CONSTANTS_KEY_UUID,
917 0 : data_relationship_get_uuid_const( relation_ptr ),
918 : false /* LAST, no NEXT */
919 : );
920 :
921 : /* update export statistics */
922 0 : data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_EXPORTED );
923 : }
924 :
925 0 : U8_TRACE_END_ERR(out_err);
926 0 : return out_err;
927 : }
928 :
929 0 : u8_error_t json_element_writer_end_relationship( json_element_writer_t *this_,
930 : data_classifier_type_t host_type,
931 : const data_relationship_t *relation_ptr )
932 : {
933 0 : U8_TRACE_BEGIN();
934 0 : assert( relation_ptr != NULL );
935 0 : u8_error_t out_err = U8_ERROR_NONE;
936 :
937 0 : if ( (*this_).mode == JSON_WRITER_PASS_EDGES )
938 : {
939 : /* end relationship */
940 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
941 : JSON_CONSTANTS_TAB
942 : JSON_CONSTANTS_TAB
943 : JSON_CONSTANTS_TAB
944 : JSON_CONSTANTS_END_OBJECT_NL
945 : JSON_CONSTANTS_TAB
946 : JSON_CONSTANTS_TAB
947 : JSON_CONSTANTS_END_OBJECT
948 : );
949 :
950 0 : if ( out_err != 0 )
951 : {
952 0 : U8_LOG_ERROR( "output buffer exceeded." );
953 : }
954 : }
955 :
956 0 : U8_TRACE_END_ERR(out_err);
957 0 : return out_err;
958 : }
959 :
960 0 : u8_error_t json_element_writer_start_diagram( json_element_writer_t *this_, const data_diagram_t *diag_ptr )
961 : {
962 0 : U8_TRACE_BEGIN();
963 0 : assert( diag_ptr != NULL );
964 0 : u8_error_t out_err = U8_ERROR_NONE;
965 :
966 0 : if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
967 : {
968 : /* separate objects if not first */
969 0 : if ( (*this_).is_outer_first )
970 : {
971 0 : (*this_).is_outer_first = false;
972 0 : out_err |= json_writer_write_plain( &((*this_).json_writer), JSON_CONSTANTS_NL );
973 : }
974 : else
975 : {
976 : /* print diagram end here because the official end requires hierarcical diagram containments */
977 0 : out_err |= json_element_writer_private_end_diagram( this_ );
978 :
979 0 : out_err |= json_writer_write_plain( &((*this_).json_writer), JSON_CONSTANTS_NEXT_NL );
980 : }
981 :
982 0 : assert( (*this_).in_outer_array == true );
983 0 : assert( (*this_).in_inner_array == false );
984 :
985 : /* begin diagram */
986 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
987 : JSON_CONSTANTS_TAB
988 : JSON_CONSTANTS_TAB
989 : JSON_CONSTANTS_BEGIN_OBJECT
990 : JSON_CONSTANTS_NL
991 : JSON_CONSTANTS_TAB
992 : JSON_CONSTANTS_TAB
993 : JSON_CONSTANTS_TAB
994 : JSON_CONSTANTS_QUOTE
995 : JSON_CONSTANTS_KEY_DIAGRAM
996 : JSON_CONSTANTS_QUOTE
997 : JSON_CONSTANTS_DEF
998 : JSON_CONSTANTS_BEGIN_OBJECT_NL
999 : );
1000 : }
1001 :
1002 0 : U8_TRACE_END_ERR(out_err);
1003 0 : return out_err;
1004 : }
1005 :
1006 0 : u8_error_t json_element_writer_assemble_diagram( json_element_writer_t *this_,
1007 : const data_diagram_t *parent,
1008 : const data_diagram_t *diag_ptr,
1009 : const char *diagram_file_base_name )
1010 : {
1011 0 : U8_TRACE_BEGIN();
1012 0 : assert( diag_ptr != NULL );
1013 0 : assert( diagram_file_base_name != NULL );
1014 0 : u8_error_t out_err = U8_ERROR_NONE;
1015 :
1016 0 : if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
1017 : {
1018 : /* id */
1019 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
1020 : 4,
1021 : JSON_CONSTANTS_KEY_DIAGRAM_ID,
1022 0 : data_diagram_get_row( diag_ptr ),
1023 : true
1024 : );
1025 :
1026 : /* diagram type */
1027 : const char *const type_name
1028 0 : = json_type_name_map_get_diagram_type( &((*this_).type_map),
1029 : data_diagram_get_diagram_type( diag_ptr )
1030 : );
1031 0 : out_err |= json_writer_write_member_enum( &((*this_).json_writer),
1032 : 4,
1033 : JSON_CONSTANTS_KEY_TYPE_NAME,
1034 : type_name,
1035 : #ifdef JSON_CONSTANTS_NEW_KEYS
1036 : JSON_CONSTANTS_KEY_TYPE_ID,
1037 : #else
1038 : JSON_CONSTANTS_KEY_DIAGRAM_DIAGRAM_TYPE,
1039 : #endif
1040 0 : data_diagram_get_diagram_type( diag_ptr ),
1041 : true
1042 : );
1043 :
1044 : /* stereotype */
1045 0 : if ( data_diagram_has_stereotype( diag_ptr ) )
1046 : {
1047 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1048 : 4,
1049 : JSON_CONSTANTS_KEY_DIAGRAM_STEREOTYPE,
1050 0 : data_diagram_get_stereotype_const( diag_ptr ),
1051 : true
1052 : );
1053 : }
1054 :
1055 : /* name */
1056 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1057 : 4,
1058 : JSON_CONSTANTS_KEY_DIAGRAM_NAME,
1059 0 : data_diagram_get_name_const( diag_ptr ),
1060 : true
1061 : );
1062 :
1063 : /* description */
1064 0 : out_err |= json_writer_write_member_string_array( &((*this_).json_writer) ,
1065 : 4,
1066 : JSON_CONSTANTS_KEY_DIAGRAM_DESCRIPTION,
1067 0 : data_diagram_get_description_const( diag_ptr ),
1068 : true
1069 : );
1070 :
1071 : /* list_order */
1072 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
1073 : 4,
1074 : #ifdef JSON_CONSTANTS_NEW_KEYS
1075 : JSON_CONSTANTS_KEY_ORDER,
1076 : #else
1077 : JSON_CONSTANTS_KEY_DIAGRAM_LIST_ORDER,
1078 : #endif
1079 0 : data_diagram_get_list_order( diag_ptr ),
1080 : true
1081 : );
1082 :
1083 : /* display_tags (flag names) + display_flags */
1084 0 : if ( data_diagram_get_display_flags( diag_ptr ) != DATA_DIAGRAM_FLAG_NONE )
1085 : {
1086 : const char *const tag_names
1087 0 : = json_type_name_map_get_diagram_tags( &((*this_).type_map),
1088 : data_diagram_get_display_flags( diag_ptr )
1089 : );
1090 :
1091 0 : out_err |= json_writer_write_member_enum( &((*this_).json_writer),
1092 : 4,
1093 : JSON_CONSTANTS_KEY_DIAGRAM_DISPLAY_FLAG_NAMES,
1094 : tag_names,
1095 : JSON_CONSTANTS_KEY_DIAGRAM_DISPLAY_FLAGS,
1096 0 : data_diagram_get_display_flags( diag_ptr ),
1097 : true
1098 : );
1099 : }
1100 :
1101 0 : const bool parent_valid = ( parent == NULL ) ? false : data_diagram_is_valid( parent );
1102 :
1103 : /* parent_name */
1104 0 : if( parent_valid )
1105 : {
1106 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1107 : 4,
1108 : JSON_CONSTANTS_KEY_DIAGRAM_PARENT_NAME,
1109 0 : data_diagram_get_name_const( parent ),
1110 : true
1111 : );
1112 : }
1113 :
1114 : /* parent uuid */
1115 0 : if ( parent_valid )
1116 : {
1117 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1118 : 4,
1119 : JSON_CONSTANTS_KEY_DIAGRAM_PARENT,
1120 0 : data_diagram_get_uuid_const( parent ),
1121 : true
1122 : );
1123 : }
1124 :
1125 : /* uuid */
1126 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1127 : 4,
1128 : JSON_CONSTANTS_KEY_UUID,
1129 0 : data_diagram_get_uuid_const( diag_ptr ),
1130 : true /* NEXT, not LAST */
1131 : );
1132 :
1133 : /* array of features */
1134 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1135 : JSON_CONSTANTS_TAB
1136 : JSON_CONSTANTS_TAB
1137 : JSON_CONSTANTS_TAB
1138 : JSON_CONSTANTS_TAB
1139 : JSON_CONSTANTS_QUOTE
1140 : #ifdef JSON_CONSTANTS_NEW_KEYS
1141 : JSON_CONSTANTS_KEY_DIAGRAM_ELEMENT_LIST
1142 : #else
1143 : JSON_CONSTANTS_KEY_DIAGRAM_ELEMENTS
1144 : #endif
1145 : JSON_CONSTANTS_QUOTE
1146 : JSON_CONSTANTS_DEF_NL
1147 : JSON_CONSTANTS_TAB
1148 : JSON_CONSTANTS_TAB
1149 : JSON_CONSTANTS_TAB
1150 : JSON_CONSTANTS_TAB
1151 : JSON_CONSTANTS_BEGIN_ARRAY
1152 : );
1153 :
1154 0 : (*this_).in_inner_array = true;
1155 0 : (*this_).is_inner_first = true;
1156 :
1157 : /* update export statistics */
1158 0 : data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_EXPORTED );
1159 : }
1160 :
1161 0 : U8_TRACE_END_ERR(out_err);
1162 0 : return out_err;
1163 : }
1164 :
1165 0 : u8_error_t json_element_writer_descend_diagram( 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 0 : U8_TRACE_END_ERR(out_err);
1172 0 : return out_err;
1173 : }
1174 :
1175 0 : u8_error_t json_element_writer_end_diagram_fake( json_element_writer_t *this_, const data_diagram_t *diag_ptr )
1176 : {
1177 0 : U8_TRACE_BEGIN();
1178 0 : assert( diag_ptr != NULL );
1179 0 : u8_error_t out_err = U8_ERROR_NONE;
1180 :
1181 : /* The JSON export does not encapsulate one diagram into another. */
1182 : /* Therefore, diagrams are ended already when the next starts. */
1183 :
1184 0 : U8_TRACE_END_ERR(out_err);
1185 0 : return out_err;
1186 : }
1187 :
1188 0 : u8_error_t json_element_writer_private_end_diagram( json_element_writer_t *this_ )
1189 : {
1190 0 : U8_TRACE_BEGIN();
1191 0 : u8_error_t out_err = U8_ERROR_NONE;
1192 :
1193 0 : if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
1194 : {
1195 0 : (*this_).in_inner_array = false;
1196 0 : (*this_).is_inner_first = false;
1197 :
1198 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1199 : JSON_CONSTANTS_NL
1200 : );
1201 :
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_TAB
1207 : JSON_CONSTANTS_END_ARRAY
1208 : JSON_CONSTANTS_NL
1209 : );
1210 :
1211 : /* end diagram */
1212 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1213 : JSON_CONSTANTS_TAB
1214 : JSON_CONSTANTS_TAB
1215 : JSON_CONSTANTS_TAB
1216 : JSON_CONSTANTS_END_OBJECT_NL
1217 : JSON_CONSTANTS_TAB
1218 : JSON_CONSTANTS_TAB
1219 : JSON_CONSTANTS_END_OBJECT
1220 : );
1221 : }
1222 :
1223 0 : U8_TRACE_END_ERR(out_err);
1224 0 : return out_err;
1225 : }
1226 :
1227 0 : u8_error_t json_element_writer_start_diagramelement( json_element_writer_t *this_,
1228 : const data_diagram_t *parent,
1229 : const data_diagramelement_t *diagramelement_ptr )
1230 : {
1231 0 : U8_TRACE_BEGIN();
1232 0 : assert( diagramelement_ptr != NULL );
1233 0 : assert( parent != NULL );
1234 0 : u8_error_t out_err = U8_ERROR_NONE;
1235 :
1236 0 : if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
1237 : {
1238 : /* separate objects in array if not first */
1239 0 : if ( (*this_).is_inner_first )
1240 : {
1241 0 : (*this_).is_inner_first = false;
1242 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1243 : JSON_CONSTANTS_NL
1244 : );
1245 : }
1246 : else
1247 : {
1248 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1249 : JSON_CONSTANTS_NEXT_NL
1250 : );
1251 : }
1252 :
1253 : /* begin diagramelement */
1254 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1255 : JSON_CONSTANTS_TAB
1256 : JSON_CONSTANTS_TAB
1257 : JSON_CONSTANTS_TAB
1258 : JSON_CONSTANTS_TAB
1259 : JSON_CONSTANTS_TAB
1260 : JSON_CONSTANTS_BEGIN_OBJECT_NL
1261 : );
1262 :
1263 0 : if ( out_err != 0 )
1264 : {
1265 0 : U8_LOG_ERROR( "output buffer exceeded." );
1266 : }
1267 : }
1268 :
1269 0 : U8_TRACE_END_ERR(out_err);
1270 0 : return out_err;
1271 : }
1272 :
1273 0 : u8_error_t json_element_writer_assemble_diagramelement( json_element_writer_t *this_,
1274 : const data_diagram_t *parent,
1275 : const data_diagramelement_t *diagramelement_ptr,
1276 : const data_classifier_t *occurrence,
1277 : const data_feature_t *feat_occur )
1278 : {
1279 0 : U8_TRACE_BEGIN();
1280 0 : assert( parent != NULL );
1281 0 : assert( diagramelement_ptr != NULL );
1282 0 : assert( occurrence != NULL );
1283 : /* feat_occur may be NULL */
1284 0 : u8_error_t out_err = U8_ERROR_NONE;
1285 :
1286 0 : if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
1287 : {
1288 0 : assert( (*this_).in_outer_array == true );
1289 0 : assert( (*this_).in_inner_array == true );
1290 :
1291 : /* id */
1292 0 : out_err |= json_writer_write_member_int( &((*this_).json_writer),
1293 : 6,
1294 : JSON_CONSTANTS_KEY_DIAGRAMELEMENT_ID,
1295 0 : data_diagramelement_get_row( diagramelement_ptr ),
1296 : true
1297 : );
1298 :
1299 : /* classifier_name */
1300 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1301 : 6,
1302 : #ifdef JSON_CONSTANTS_NEW_KEYS
1303 : JSON_CONSTANTS_KEY_DIAGRAMELEMENT_NODE_NAME,
1304 : #else
1305 : JSON_CONSTANTS_KEY_DIAGRAMELEMENT_CLASSIFIER_NAME,
1306 : #endif
1307 0 : data_classifier_get_name_const( occurrence ),
1308 : true
1309 : );
1310 :
1311 : /* focused_feature_name */
1312 : /* note that focused features are always lifelines and these never have names */
1313 :
1314 : /* ref_uuid */
1315 0 : const bool feat_valid = ( feat_occur == NULL ) ? false : data_feature_is_valid( feat_occur );
1316 0 : const bool clas_valid = data_classifier_is_valid( occurrence );
1317 0 : const char *const node_ref
1318 : = ( feat_valid )
1319 0 : ? data_feature_get_uuid_const( feat_occur )
1320 0 : : ( clas_valid )
1321 0 : ? data_classifier_get_uuid_const( occurrence )
1322 : : "";
1323 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1324 : 6,
1325 : JSON_CONSTANTS_KEY_DIAGRAMELEMENT_NODE,
1326 : node_ref,
1327 : true
1328 : );
1329 :
1330 : /* display_tags (flag names) + display_flags */
1331 0 : if ( data_diagramelement_get_display_flags( diagramelement_ptr ) != DATA_DIAGRAMELEMENT_FLAG_NONE )
1332 : {
1333 : const char *const tag_names
1334 0 : = json_type_name_map_get_diagramelement_tags( &((*this_).type_map),
1335 : data_diagramelement_get_display_flags( diagramelement_ptr )
1336 : );
1337 0 : out_err |= json_writer_write_member_enum( &((*this_).json_writer),
1338 : 6,
1339 : JSON_CONSTANTS_KEY_DIAGRAMELEMENT_DISPLAY_FLAG_NAMES,
1340 : tag_names,
1341 : JSON_CONSTANTS_KEY_DIAGRAMELEMENT_DISPLAY_FLAGS,
1342 0 : data_diagramelement_get_display_flags( diagramelement_ptr ),
1343 : true
1344 : );
1345 : }
1346 :
1347 : /* uuid */
1348 0 : out_err |= json_writer_write_member_string( &((*this_).json_writer),
1349 : 6,
1350 : JSON_CONSTANTS_KEY_UUID,
1351 0 : data_diagramelement_get_uuid_const( diagramelement_ptr ),
1352 : false /* LAST, no NEXT */
1353 : );
1354 :
1355 : /* update export statistics */
1356 0 : data_stat_inc_count ( (*this_).export_stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_EXPORTED );
1357 : }
1358 :
1359 0 : U8_TRACE_END_ERR(out_err);
1360 0 : return out_err;
1361 : }
1362 :
1363 0 : u8_error_t json_element_writer_end_diagramelement( json_element_writer_t *this_,
1364 : const data_diagram_t *parent,
1365 : const data_diagramelement_t *diagramelement_ptr )
1366 : {
1367 0 : U8_TRACE_BEGIN();
1368 0 : assert( diagramelement_ptr != NULL );
1369 0 : assert( parent != NULL );
1370 0 : u8_error_t out_err = U8_ERROR_NONE;
1371 :
1372 0 : if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
1373 : {
1374 : /* end diagramelement */
1375 0 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1376 : JSON_CONSTANTS_TAB
1377 : JSON_CONSTANTS_TAB
1378 : JSON_CONSTANTS_TAB
1379 : JSON_CONSTANTS_TAB
1380 : JSON_CONSTANTS_TAB
1381 : JSON_CONSTANTS_END_OBJECT
1382 : );
1383 :
1384 0 : if ( out_err != 0 )
1385 : {
1386 0 : U8_LOG_ERROR( "output buffer exceeded." );
1387 : }
1388 : }
1389 :
1390 0 : U8_TRACE_END_ERR(out_err);
1391 0 : return out_err;
1392 : }
1393 :
1394 6 : u8_error_t json_element_writer_end_main( json_element_writer_t *this_ )
1395 : {
1396 6 : U8_TRACE_BEGIN();
1397 6 : u8_error_t out_err = U8_ERROR_NONE;
1398 :
1399 : /* print diagram end here because the official end requires hierarcical diagram containments */
1400 6 : if ( (*this_).mode == JSON_WRITER_PASS_VIEWS )
1401 : {
1402 2 : if ( ! (*this_).is_outer_first )
1403 : {
1404 0 : out_err |= json_element_writer_private_end_diagram( this_ );
1405 : }
1406 : }
1407 :
1408 6 : assert( (*this_).in_outer_array == true );
1409 6 : assert( (*this_).in_inner_array == false );
1410 6 : (*this_).in_outer_array = false;
1411 6 : (*this_).is_outer_first = false;
1412 :
1413 6 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1414 : JSON_CONSTANTS_NL
1415 : JSON_CONSTANTS_TAB
1416 : JSON_CONSTANTS_END_ARRAY
1417 : JSON_CONSTANTS_NL
1418 : );
1419 :
1420 6 : if ( out_err != 0 )
1421 : {
1422 0 : U8_LOG_ERROR( "output buffer exceeded." );
1423 : }
1424 :
1425 6 : U8_TRACE_END_ERR(out_err);
1426 6 : return out_err;
1427 : }
1428 :
1429 2 : u8_error_t json_element_writer_write_footer( json_element_writer_t *this_ )
1430 : {
1431 2 : U8_TRACE_BEGIN();
1432 2 : assert( (*this_).in_outer_array == false );
1433 2 : assert( (*this_).in_inner_array == false );
1434 2 : u8_error_t out_err = U8_ERROR_NONE;
1435 :
1436 2 : out_err |= json_writer_write_plain( &((*this_).json_writer),
1437 : JSON_CONSTANTS_END_OBJECT_NL
1438 : );
1439 :
1440 2 : if ( out_err != 0 )
1441 : {
1442 0 : U8_LOG_ERROR( "output buffer exceeded." );
1443 : }
1444 :
1445 2 : U8_TRACE_END_ERR(out_err);
1446 2 : return out_err;
1447 : }
1448 :
1449 :
1450 : /*
1451 : Copyright 2016-2026 Andreas Warnke
1452 :
1453 : Licensed under the Apache License, Version 2.0 (the "License");
1454 : you may not use this file except in compliance with the License.
1455 : You may obtain a copy of the License at
1456 :
1457 : http://www.apache.org/licenses/LICENSE-2.0
1458 :
1459 : Unless required by applicable law or agreed to in writing, software
1460 : distributed under the License is distributed on an "AS IS" BASIS,
1461 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1462 : See the License for the specific language governing permissions and
1463 : limitations under the License.
1464 : */
|