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