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