001/* 002 * ============================================================================ 003 * Copyright © 2002-2026 by Thomas Thrien. 004 * All Rights Reserved. 005 * ============================================================================ 006 * Licensed to the public under the agreements of the GNU Lesser General Public 007 * License, version 3.0 (the "License"). You may obtain a copy of the License at 008 * 009 * http://www.gnu.org/licenses/lgpl.html 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 014 * License for the specific language governing permissions and limitations 015 * under the License. 016 */ 017 018package org.tquadrat.foundation.jsonbuilder; 019 020import static org.apiguardian.api.API.Status.STABLE; 021import static org.tquadrat.foundation.jsonbuilder.JSONLiteral.FALSE; 022import static org.tquadrat.foundation.jsonbuilder.JSONLiteral.NULL; 023import static org.tquadrat.foundation.jsonbuilder.JSONLiteral.TRUE; 024import static org.tquadrat.foundation.lang.Objects.mapFromNull; 025import static org.tquadrat.foundation.lang.Objects.requireNonNullArgument; 026 027import java.math.BigDecimal; 028import java.math.BigInteger; 029import java.util.Collection; 030import java.util.Formatter; 031import java.util.function.Function; 032import java.util.function.Supplier; 033 034import org.apiguardian.api.API; 035import org.tquadrat.foundation.annotation.ClassVersion; 036import org.tquadrat.foundation.jsonbuilder.internal.JSONArrayImpl; 037import org.tquadrat.foundation.jsonbuilder.internal.JSONBuilderImpl; 038import org.tquadrat.foundation.jsonbuilder.internal.JSONObjectImpl; 039import org.tquadrat.foundation.lang.value.Dimension; 040import org.tquadrat.foundation.lang.value.DimensionedValue; 041 042/** 043 * <p>{@summary This sealed interface is the main API for the Foundation JSON 044 * Builder Library.}</p> 045 * <p>{@link #getInstance()} returns an instance of an implementation for the 046 * interface.</p> 047 * <p>Basically, the instances of {@code JSONBuilder} are stateless, and 048 * therefore they can be treated as thread-safe. Only the 049 * {@linkplain #getIndentation() indentation} 050 * that is used for pretty-printing the resulting JSON values may cause issues 051 * when different threads are using different values.</p> 052 * <p>The different implementations of 053 * {@link JSONValue} 054 * – particularly 055 * {@link JSONObject} 056 * and 057 * {@link JSONArray} 058 * are <i>not</i> thread-safe.</p> 059 * 060 * @extauthor Thomas Thrien - thomas.thrien@tquadrat.org 061 * @version $Id: JSONBuilder.java 1258 2026-06-04 18:33:06Z tquadrat $ 062 * @since 0.25.0 063 * 064 * @UMLGraph.link 065 */ 066@ClassVersion( sourceVersion = "$Id: JSONBuilder.java 1258 2026-06-04 18:33:06Z tquadrat $" ) 067@API( status = STABLE, since = "0.25.0" ) 068public sealed interface JSONBuilder 069 permits JSONBuilderImpl 070{ 071 /*-----------*\ 072 ====** Constants **======================================================== 073 \*-----------*/ 074 /** 075 * The indentation that is used when a 076 * {@link JSONValue} 077 * is formatted: {@value}. 078 * 079 * @see JSONValue#formatTo(Formatter,int,int,int) 080 */ 081 public static final int DEFAULT_INDENTATION = 2; 082 083 /** 084 * The name of the JSON String that holds the unit for the dimension from 085 * a 086 * {@link DimensionedValue}: 087 * {@value}. 088 * 089 * @see #valueOf(DimensionedValue,Dimension) 090 */ 091 public static final String JSONField_Unit = "Unit"; 092 093 /** 094 * The name of the JSON Number that holds the value from a 095 * {@link DimensionedValue}: 096 * {@value}. 097 * 098 * @see #valueOf(DimensionedValue,Dimension) 099 */ 100 public static final String JSONField_Value = "Value"; 101 102 /*---------*\ 103 ====** Methods **========================================================== 104 \*---------*/ 105 /** 106 * <p>{@summary Returns a deep copy of the given JSON array.}</p> 107 * 108 * @param source The array to copy. 109 * @return The deep copy. 110 */ 111 public default JSONArray copyArray( final JSONArray source ) 112 { 113 final var retValue = new JSONArrayImpl( (JSONArrayImpl) requireNonNullArgument( source, "source" ) ); 114 115 //---* Done *---------------------------------------------------------- 116 return retValue; 117 } // copyArray() 118 119 /** 120 * <p>{@summary Returns a deep copy of the given JSON object.}</p> 121 * 122 * @param source The object to copy. 123 * @return The deep copy. 124 */ 125 public default JSONObject copyObject( final JSONObject source ) 126 { 127 final var retValue = new JSONObjectImpl( (JSONObjectImpl) requireNonNullArgument( source, "source" ) ); 128 129 //---* Done *---------------------------------------------------------- 130 return retValue; 131 } // copyObject() 132 133 /** 134 * <p>{@summary Returns a new empty instance of 135 * {@link JSONArray}.}</p> 136 * 137 * @return The new array. 138 */ 139 public JSONArray createArray(); 140 141 /** 142 * <p>{@summary Returns a new instance of 143 * {@link JSONArray} 144 * with the given number of elements, all set to 145 * {@link JSONLiteral#NULL}.}</p> 146 * 147 * @param elementCount The number of elements for the new array. 148 * @return The new array. 149 */ 150 public default JSONArray createArray( final int elementCount ) 151 { 152 final var retValue = createArray(); 153 for( var i = 0; i < elementCount; ++i ) retValue.add( NULL ); 154 155 //---* Done *---------------------------------------------------------- 156 return retValue; 157 } // createArray() 158 159 /** 160 * <p>{@summary Returns a new instance of 161 * {@link JSONArray} 162 * that is populated with the values from the given array.}</p> 163 * 164 * @param values The values. 165 * @return The new array. 166 */ 167 public default JSONArray createArray( final BigDecimal [] values ) 168 { 169 final var retValue = createArray(); 170 for( final var value : requireNonNullArgument( values, "values" ) ) 171 { 172 retValue.add( mapFromNull( valueOf( value ), NULL ) ); 173 } 174 175 //---* Done *---------------------------------------------------------- 176 return retValue; 177 } // createArray() 178 179 /** 180 * <p>{@summary Returns a new instance of 181 * {@link JSONArray} 182 * that is populated with the values from the given array.}</p> 183 * 184 * @param values The values. 185 * @return The new array. 186 */ 187 public default JSONArray createArray( final BigInteger [] values ) 188 { 189 final var retValue = createArray(); 190 for( final var value : requireNonNullArgument( values, "values" ) ) 191 { 192 retValue.add( mapFromNull( valueOf( value ), NULL ) ); 193 } 194 195 //---* Done *---------------------------------------------------------- 196 return retValue; 197 } // createArray() 198 199 /** 200 * <p>{@summary Returns a new instance of 201 * {@link JSONArray} 202 * that is populated with the values from the given array.}</p> 203 * 204 * @param values The values. 205 * @return The new array. 206 */ 207 public default JSONArray createArray( final double [] values ) 208 { 209 final var retValue = createArray(); 210 for( final var value : requireNonNullArgument( values, "values" ) ) 211 { 212 retValue.add( valueOf( value ) ); 213 } 214 215 //---* Done *---------------------------------------------------------- 216 return retValue; 217 } // createArray() 218 219 /** 220 * <p>{@summary Returns a new instance of 221 * {@link JSONArray} 222 * that is populated with the values from the given array.}</p> 223 * 224 * @param values The values. 225 * @return The new array. 226 */ 227 public default JSONArray createArray( final Double [] values ) 228 { 229 final var retValue = createArray(); 230 for( final var value : requireNonNullArgument( values, "values" ) ) 231 { 232 retValue.add( mapFromNull( valueOf( value ), NULL ) ); 233 } 234 235 //---* Done *---------------------------------------------------------- 236 return retValue; 237 } // createArray() 238 239 /** 240 * <p>{@summary Returns a new instance of 241 * {@link JSONArray} 242 * that is populated with the values from the given array.}</p> 243 * 244 * @param values The values. 245 * @return The new array. 246 */ 247 public default JSONArray createArray( final float [] values ) 248 { 249 final var retValue = createArray(); 250 for( final var value : requireNonNullArgument( values, "values" ) ) 251 { 252 retValue.add( valueOf( value ) ); 253 } 254 255 //---* Done *---------------------------------------------------------- 256 return retValue; 257 } // createArray() 258 259 /** 260 * <p>{@summary Returns a new instance of 261 * {@link JSONArray} 262 * that is populated with the values from the given array.}</p> 263 * 264 * @param values The values. 265 * @return The new array. 266 */ 267 public default JSONArray createArray( final Float [] values ) 268 { 269 final var retValue = createArray(); 270 for( final var value : requireNonNullArgument( values, "values" ) ) 271 { 272 retValue.add( mapFromNull( valueOf( value ), NULL ) ); 273 } 274 275 //---* Done *---------------------------------------------------------- 276 return retValue; 277 } // createArray() 278 279 /** 280 * <p>{@summary Returns a new instance of 281 * {@link JSONArray} 282 * that is populated with the values from the given array.}</p> 283 * 284 * @param values The values. 285 * @return The new array. 286 */ 287 public default JSONArray createArray( final int [] values ) 288 { 289 final var retValue = createArray(); 290 for( final var value : requireNonNullArgument( values, "values" ) ) 291 { 292 retValue.add( valueOf( value ) ); 293 } 294 295 //---* Done *---------------------------------------------------------- 296 return retValue; 297 } // createArray() 298 299 /** 300 * <p>{@summary Returns a new instance of 301 * {@link JSONArray} 302 * that is populated with the values from the given array.}</p> 303 * 304 * @param values The values. 305 * @return The new array. 306 */ 307 public default JSONArray createArray( final Integer [] values ) 308 { 309 final var retValue = createArray(); 310 for( final var value : requireNonNullArgument( values, "values" ) ) 311 { 312 retValue.add( mapFromNull( valueOf( value ), NULL ) ); 313 } 314 315 //---* Done *---------------------------------------------------------- 316 return retValue; 317 } // createArray() 318 319 /** 320 * <p>{@summary Returns a new instance of 321 * {@link JSONArray} 322 * that is populated with the values from the given array.}</p> 323 * 324 * @param values The values. 325 * @return The new array. 326 */ 327 public default JSONArray createArray( final JSONValue [] values ) 328 { 329 final var retValue = createArray(); 330 for( final var value : requireNonNullArgument( values, "values" ) ) 331 { 332 retValue.add( mapFromNull( value, NULL ) ); 333 } 334 335 //---* Done *---------------------------------------------------------- 336 return retValue; 337 } // createArray() 338 339 /** 340 * <p>{@summary Returns a new instance of 341 * {@link JSONArray} 342 * that is populated with the values from the given array.}</p> 343 * 344 * @param values The values. 345 * @return The new array. 346 */ 347 public default JSONArray createArray( final long [] values ) 348 { 349 final var retValue = createArray(); 350 for( final var value : requireNonNullArgument( values, "values" ) ) 351 { 352 retValue.add( valueOf( value ) ); 353 } 354 355 //---* Done *---------------------------------------------------------- 356 return retValue; 357 } // createArray() 358 359 /** 360 * <p>{@summary Returns a new instance of 361 * {@link JSONArray} 362 * that is populated with the values from the given array.}</p> 363 * 364 * @param values The values. 365 * @return The new array. 366 */ 367 public default JSONArray createArray( final Long [] values ) 368 { 369 final var retValue = createArray(); 370 for( final var value : requireNonNullArgument( values, "values" ) ) 371 { 372 retValue.add( mapFromNull( valueOf( value ), NULL ) ); 373 } 374 375 //---* Done *---------------------------------------------------------- 376 return retValue; 377 } // createArray() 378 379 /** 380 * <p>{@summary Returns a new instance of 381 * {@link JSONArray} 382 * that is populated with the return value from the given 383 * {@link Supplier Supplier<JSONValue []>}.}</p> 384 * 385 * @param supplier The supplier for the array. 386 * @return The new array. 387 */ 388 public default JSONArray createArray( final Supplier<JSONValue []> supplier ) 389 { 390 final var retValue = createArray(); 391 for( final var value : requireNonNullArgument( supplier, "supplier" ).get() ) 392 { 393 retValue.add( mapFromNull( value, NULL ) ); 394 } 395 396 //---* Done *---------------------------------------------------------- 397 return retValue; 398 } // createArray() 399 400 /** 401 * <p>{@summary Returns a new instance of 402 * {@link JSONArray} 403 * that is populated with the values from the given array.}</p> 404 * 405 * @param values The values. 406 * @return The new array. 407 */ 408 public default JSONArray createArray( final String... values ) 409 { 410 final var retValue = createArray(); 411 for( final var value : requireNonNullArgument( values, "values" ) ) 412 { 413 retValue.add( mapFromNull( valueOf( value ), NULL ) ); 414 } 415 416 //---* Done *---------------------------------------------------------- 417 return retValue; 418 } // createArray() 419 420 /** 421 * <p>{@summary Returns a new empty instance of 422 * {@link JSONObject}.}</p> 423 * 424 * @return The new object. 425 */ 426 public JSONObject createObject(); 427 428 /** 429 * <p>{@summary Returns a new instance of 430 * {@link JSONObject} 431 * that is populated with the values returned by the given 432 * {@link Function}.}</p> 433 * <p>The function's argument is the name of the new member, provided by 434 * the {@code names} argument to this method.</p> 435 * 436 * @param names The member names for the new object. 437 * @param provider The function that returns the value for the member 438 * with the given name. 439 * @return The new object. 440 */ 441 public default JSONObject createObject( final Collection<String> names, final Function<String,JSONValue> provider ) 442 { 443 requireNonNullArgument( provider, "provider" ); 444 final var retValue = createObject(); 445 for( final var name : requireNonNullArgument( names, "names" ) ) 446 { 447 retValue.set( name, provider.apply( name ) ); 448 } 449 450 //---* Done *---------------------------------------------------------- 451 return retValue; 452 } // createObject() 453 454 /** 455 * <p>{@summary Returns the indentation that is used when a 456 * {@link JSONValue} 457 * is formatted.} If not set explicitly through a call to 458 * {@link #setIndentation(int)}, 459 * the default value 460 * ({@value DEFAULT_INDENTATION}) 461 * will be returned.</p> 462 * 463 * @return The indentation. 464 * 465 * @see #DEFAULT_INDENTATION 466 * @see JSONValue#formatTo(Formatter,int,int,int) 467 */ 468 public int getIndentation(); 469 470 /** 471 * <p>{@summary Sets the indentation that is used when a 472 * {@link JSONValue} 473 * is formatted for pretty-printing.} 474 * 475 * @param value The indentation. 476 * 477 * @see JSONValue#formatTo(Formatter,int,int,int) 478 */ 479 public void setIndentation( final int value ); 480 481 /** 482 * <p>{@summary Creates an instance of {@code JSONBuilder}.}</p> 483 * <p>Each call to this method will return a new instance of 484 * {@code JSONBuilder}.</p> 485 * 486 * @return A new instance of {@code JSONBuilder}. 487 */ 488 public static JSONBuilder getInstance() { return new JSONBuilderImpl(); } 489 490 /** 491 * Returns a 492 * {@link JSONValue} 493 * instance that represents the given 494 * {@link BigDecimal} 495 * value. 496 * 497 * @param value The value. 498 * @return The JSON value that represents the given value. 499 */ 500 public JSONNumber valueOf( final BigDecimal value ); 501 502 /** 503 * Returns a 504 * {@link JSONValue} 505 * instance that represents the given 506 * {@link BigInteger} 507 * value. 508 * 509 * @param value The value 510 * @return The JSON value that represents the given value. 511 */ 512 public JSONNumber valueOf( final BigInteger value ); 513 514 /** 515 * Returns a 516 * {@link JSONValue} 517 * instance that represents the given {@code boolean} value. 518 * 519 * @param value The value 520 * @return The JSON value that represents the given value. 521 */ 522 public default JSONLiteral valueOf( final boolean value ) 523 { 524 final var retValue = value ? TRUE : FALSE; 525 526 //---* Done *---------------------------------------------------------- 527 return retValue; 528 } // valueOf() 529 530 /** 531 * <p>{@summary Returns a 532 * {@link JSONValue} 533 * instance (more precisely, an instance of 534 * {@link JSONObject}) 535 * that represents the given 536 * {@link DimensionedValue} 537 * instance.}</p> 538 * <p>The member names are 539 * {@value #JSONField_Unit} 540 * for the dimension, and 541 * {@value #JSONField_Value} 542 * for the numerical value.</p> 543 * 544 * @param <T> The type of the dimension for the value. 545 * @param value The value. 546 * @param targetUnit The dimension for the output. 547 * @return The resulting JSON object. 548 */ 549 public default <T extends Dimension> JSONObject valueOf( final DimensionedValue<T> value, final T targetUnit ) 550 { 551 final var retValue = createObject(); 552 retValue.set( JSONField_Unit, requireNonNullArgument( targetUnit, "targetUnit" ).unitSymbolForPrinting() ); 553 retValue.set( JSONField_Value, requireNonNullArgument( value, "value" ).convert( targetUnit ) ); 554 555 //---* Done *---------------------------------------------------------- 556 return retValue; 557 } // valueOf() 558 559 /** 560 * Returns a 561 * {@link JSONValue} 562 * instance that represents the given {@code double} value. 563 * 564 * @param value The value 565 * @return The JSON value that represents the given value. 566 */ 567 public JSONNumber valueOf( final double value ); 568 569 /** 570 * Returns a 571 * {@link JSONValue} 572 * instance that represents the given 573 * {@link Double} 574 * value. 575 * 576 * @param value The value 577 * @return The JSON value that represents the given value. 578 */ 579 public JSONNumber valueOf( final Double value ); 580 581 /** 582 * Returns a 583 * {@link JSONValue} 584 * instance that represents the given {@code float} value. 585 * 586 * @param value The value 587 * @return The JSON value that represents the given value. 588 */ 589 public JSONNumber valueOf( final float value ); 590 591 /** 592 * Returns a 593 * {@link JSONValue} 594 * instance that represents the given 595 * {@link Float} 596 * value. 597 * 598 * @param value The value 599 * @return The JSON value that represents the given value. 600 */ 601 public JSONNumber valueOf( final Float value ); 602 603 /** 604 * Returns a 605 * {@link JSONValue} 606 * instance that represents the given {@code int} value. 607 * 608 * @param value The value 609 * @return The JSON value that represents the given value. 610 */ 611 public JSONNumber valueOf( final int value ); 612 613 /** 614 * Returns a 615 * {@link JSONValue} 616 * instance that represents the given 617 * {@link Integer} 618 * value. 619 * 620 * @param value The value 621 * @return The JSON value that represents the given value. 622 */ 623 public JSONNumber valueOf( final Integer value ); 624 625 /** 626 * Returns a 627 * {@link JSONValue} 628 * instance that represents the given {@code long} value. 629 * 630 * @param value The value 631 * @return The JSON value that represents the given value. 632 */ 633 public JSONNumber valueOf( final long value ); 634 635 /** 636 * Returns a 637 * {@link JSONValue} 638 * instance that represents the given 639 * {@link Long} 640 * value. 641 * 642 * @param value The value 643 * @return The JSON value that represents the given value. 644 */ 645 public JSONNumber valueOf( final Long value ); 646 647 /** 648 * Returns a 649 * {@link JSONValue} 650 * instance that represents the given 651 * {@link String} 652 * value. 653 * 654 * @param value The value 655 * @return The JSON value that represents the given value. 656 */ 657 public JSONString valueOf( final String value ); 658 659 /** 660 * Returns a 661 * {@link JSONValue} 662 * instance that represents the {@null} value. 663 * 664 * @return The JSON value that represents {@null}. 665 */ 666 public default JSONLiteral valueOfNull() { return NULL; } 667} 668// interface JSONBuilder 669 670/* 671 * End of File 672 */