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.internal; 019 020import org.apiguardian.api.API; 021import org.tquadrat.foundation.annotation.ClassVersion; 022import org.tquadrat.foundation.jsonbuilder.JSONArray; 023import org.tquadrat.foundation.jsonbuilder.JSONBuilder; 024import org.tquadrat.foundation.jsonbuilder.JSONObject; 025import org.tquadrat.foundation.jsonbuilder.JSONValue; 026import org.tquadrat.foundation.lang.value.Dimension; 027import org.tquadrat.foundation.lang.value.DimensionedValue; 028 029import java.io.IOException; 030import java.io.UncheckedIOException; 031import java.math.BigDecimal; 032import java.math.BigInteger; 033import java.util.ArrayList; 034import java.util.Formatter; 035import java.util.Iterator; 036import java.util.List; 037import java.util.StringJoiner; 038 039import static java.lang.Integer.max; 040import static org.apiguardian.api.API.Status.INTERNAL; 041import static org.tquadrat.foundation.jsonbuilder.JSONLiteral.NULL; 042import static org.tquadrat.foundation.lang.CommonConstants.EMPTY_STRING; 043import static org.tquadrat.foundation.lang.Objects.hash; 044import static org.tquadrat.foundation.lang.Objects.requireNonNullArgument; 045 046/** 047 * <p>{@summary The implementation for the interface 048 * {@link JSONArray}.}</p> 049 * 050 * @extauthor Thomas Thrien - thomas.thrien@tquadrat.org 051 * @version $Id: JSONArrayImpl.java 1195 2026-04-15 21:33:40Z tquadrat $ 052 * @since 0.25.0 053 * 054 * @UMLGraph.link 055 */ 056@ClassVersion( sourceVersion = "$Id: JSONArrayImpl.java 1195 2026-04-15 21:33:40Z tquadrat $" ) 057@API( status = INTERNAL, since = "0.25.0" ) 058public final class JSONArrayImpl implements JSONArray 059{ 060 /*------------*\ 061 ====** Attributes **======================================================= 062 \*------------*/ 063 /** 064 * The reference to the 065 * {@link JSONBuilder} 066 * that was used to create this {@code JSONObject}, and that is used to 067 * create the members. 068 */ 069 private final JSONBuilderImpl m_Builder; 070 071 /** 072 * The elements for this {@code JSONArray} instance. 073 */ 074 private final List<JSONValue> m_Elements = new ArrayList<>(); 075 076 /*--------------*\ 077 ====** Constructors **===================================================== 078 \*--------------*/ 079 /** 080 * Creates a new instance of {@code JSONArrayImpl}. 081 * 082 * @param builder The reference to the 083 * {@link JSONBuilder}. 084 */ 085 public JSONArrayImpl( final JSONBuilderImpl builder ) 086 { 087 m_Builder = requireNonNullArgument( builder, "builder" ); 088 } // JSONArrayImpl() 089 090 /** 091 * <p>{summary Creates a new instance of {@code JSONArrayImpl} from the 092 * given other array.}</p> 093 * <p>The new array is a deep copy of the given instance.</p> 094 * 095 * @param other The other JSON array. 096 */ 097 public JSONArrayImpl( final JSONArrayImpl other ) 098 { 099 m_Builder = requireNonNullArgument( other, "other" ).m_Builder; 100 for( final var element : other.m_Elements ) 101 { 102 m_Elements.add( switch( element ) 103 { 104 case null -> NULL; 105 case JSONArrayImpl array -> new JSONArrayImpl( array ); 106 case JSONObjectImpl object -> new JSONObjectImpl( object ); 107 default -> element; 108 }); 109 } 110 } // JSONArrayImpl() 111 112 /*---------*\ 113 ====** Methods **========================================================== 114 \*---------*/ 115 /** 116 * {@inheritDoc} 117 */ 118 @Override 119 public final void add( final BigDecimal value ) { add( m_Builder.valueOf( value ) ); } 120 121 /** 122 * {@inheritDoc} 123 */ 124 @Override 125 public final void add( final BigInteger value ) { add( m_Builder.valueOf( value ) ); } 126 127 /** 128 * {@inheritDoc} 129 */ 130 @Override 131 public final <T extends Dimension> void add( final DimensionedValue<T> value, final T targetUnit ) 132 { 133 add( m_Builder.valueOf( value, targetUnit ) ); 134 } // add() 135 136 /** 137 * {@inheritDoc} 138 */ 139 @Override 140 public final void add( final double value ) { add( m_Builder.valueOf( value ) ); } 141 142 /** 143 * {@inheritDoc} 144 */ 145 @Override 146 public final void add( final Double value ) { add( m_Builder.valueOf( value ) ); } 147 148 /** 149 * {@inheritDoc} 150 */ 151 @Override 152 public final void add( final float value ) { add( m_Builder.valueOf( value ) ); } 153 154 /** 155 * {@inheritDoc} 156 */ 157 @Override 158 public final void add( final Float value ) { add( m_Builder.valueOf( value ) ); } 159 160 /** 161 * {@inheritDoc} 162 */ 163 @Override 164 public final void add( final int value ) { add( m_Builder.valueOf( value ) ); } 165 166 /** 167 * {@inheritDoc} 168 */ 169 @Override 170 public final void add( final Integer value ) { add( m_Builder.valueOf( value ) ); } 171 172 /** 173 * {@inheritDoc} 174 */ 175 @Override 176 public final void add( final JSONValue value ) 177 { 178 m_Elements.add( requireNonNullArgument( value, "value" ) ); 179 } // add() 180 181 /** 182 * {@inheritDoc} 183 */ 184 @Override 185 public final void add( final long value ) { add( m_Builder.valueOf( value ) ); } 186 187 /** 188 * {@inheritDoc} 189 */ 190 @Override 191 public final void add( final Long value ) { add( m_Builder.valueOf( value ) ); } 192 193 /** 194 * {@inheritDoc} 195 */ 196 @Override 197 public final void add( final String value ) { add( m_Builder.valueOf( value ) ); } 198 199 /** 200 * {@inheritDoc} 201 */ 202 @Override 203 public final void add( final int index, final BigDecimal value ) throws IndexOutOfBoundsException 204 { 205 add( index, m_Builder.valueOf( value ) ); 206 } // add() 207 208 /** 209 * {@inheritDoc} 210 */ 211 @Override 212 public final void add( final int index, final BigInteger value ) throws IndexOutOfBoundsException 213 { 214 add( index, m_Builder.valueOf( value ) ); 215 } // add() 216 217 /** 218 * {@inheritDoc} 219 */ 220 @Override 221 public final <T extends Dimension> void add( final int index, final DimensionedValue<T> value, final T targetUnit ) throws IndexOutOfBoundsException 222 { 223 add( index, m_Builder.valueOf( value, targetUnit ) ); 224 } // add() 225 226 /** 227 * {@inheritDoc} 228 */ 229 @Override 230 public final void add( final int index, final double value ) throws IndexOutOfBoundsException 231 { 232 add( index, m_Builder.valueOf( value ) ); 233 } // add() 234 235 /** 236 * {@inheritDoc} 237 */ 238 @Override 239 public final void add( final int index, final Double value ) throws IndexOutOfBoundsException 240 { 241 add( index, m_Builder.valueOf( value ) ); 242 } // add() 243 244 /** 245 * {@inheritDoc} 246 */ 247 @Override 248 public final void add( final int index, final float value ) throws IndexOutOfBoundsException 249 { 250 add( index, m_Builder.valueOf( value ) ); 251 } // add() 252 253 /** 254 * {@inheritDoc} 255 */ 256 @Override 257 public final void add( final int index, final Float value ) throws IndexOutOfBoundsException 258 { 259 add( index, m_Builder.valueOf( value ) ); 260 } // add() 261 262 /** 263 * {@inheritDoc} 264 */ 265 @Override 266 public final void add( final int index, final int value ) throws IndexOutOfBoundsException 267 { 268 add( index, m_Builder.valueOf( value ) ); 269 } // add() 270 271 /** 272 * {@inheritDoc} 273 */ 274 @Override 275 public final void add( final int index, final Integer value ) throws IndexOutOfBoundsException 276 { 277 add( index, m_Builder.valueOf( value ) ); 278 } // add() 279 280 /** 281 * {@inheritDoc} 282 */ 283 @Override 284 public final void add( final int index, final JSONValue value ) throws IndexOutOfBoundsException 285 { 286 m_Elements.add( index, requireNonNullArgument( value, "value" ) ); 287 } // add() 288 289 /** 290 * {@inheritDoc} 291 */ 292 @Override 293 public final void add( final int index, final long value ) throws IndexOutOfBoundsException 294 { 295 add( index, m_Builder.valueOf( value ) ); 296 } // add() 297 298 /** 299 * {@inheritDoc} 300 */ 301 @Override 302 public final void add( final int index, final Long value ) throws IndexOutOfBoundsException 303 { 304 add( index, m_Builder.valueOf( value ) ); 305 } // add() 306 307 /** 308 * {@inheritDoc} 309 */ 310 @Override 311 public final void add( final int index, final String value ) throws IndexOutOfBoundsException 312 { 313 add( index, m_Builder.valueOf( value ) ); 314 } // add() 315 316 /** 317 * {@inheritDoc} 318 */ 319 @Override 320 public final boolean addAll( final JSONArray array ) 321 { 322 final var retValue = m_Elements.addAll( ((JSONArrayImpl) requireNonNullArgument( array, "array" )).m_Elements ); 323 324 //---* Done *---------------------------------------------------------- 325 return retValue; 326 } // addAll() 327 328 /** 329 * {@inheritDoc} 330 */ 331 @Override 332 public final JSONArray addArray() 333 { 334 final var retValue = m_Builder.createArray(); 335 add( retValue ); 336 337 //---* Done *---------------------------------------------------------- 338 return retValue; 339 } // addArray() 340 341 /** 342 * {@inheritDoc} 343 */ 344 @Override 345 public JSONArray addArray( final int index ) throws IndexOutOfBoundsException 346 { 347 final var retValue = m_Builder.createArray(); 348 add( index, retValue ); 349 350 //---* Done *---------------------------------------------------------- 351 return retValue; 352 } // addArray() 353 354 /** 355 * {@inheritDoc} 356 */ 357 @Override 358 public JSONObject addObject() 359 { 360 final var retValue = m_Builder.createObject(); 361 add( retValue ); 362 363 //---* Done *---------------------------------------------------------- 364 return retValue; 365 } // addObject() 366 367 /** 368 * {@inheritDoc} 369 */ 370 @Override 371 public JSONObject addObject( final int index ) throws IndexOutOfBoundsException 372 { 373 final var retValue = m_Builder.createObject(); 374 add( index, retValue ); 375 376 //---* Done *---------------------------------------------------------- 377 return retValue; 378 } // addObject() 379 380 /** 381 * {@inheritDoc} 382 */ 383 @Override 384 public final boolean equals( final Object o ) 385 { 386 var retValue = this == o; 387 if( !retValue && o instanceof final JSONArrayImpl other ) 388 { 389 retValue = m_Builder.equals( other.m_Builder ) 390 && m_Elements.equals( other.m_Elements ); 391 } 392 393 //---* Done *---------------------------------------------------------- 394 return retValue; 395 } // equals() 396 397 /** 398 * {@inheritDoc} 399 */ 400 @Override 401 public void formatTo( final Formatter formatter, final int flags, final int width, final int precision ) 402 { 403 final var indentation1 = "\n" + (width <= 0 ? EMPTY_STRING : " ".repeat( width )); 404 final var newWidth = max( 0, width ) + m_Builder.getIndentation(); 405 final var indentation2 = "\n" + " ".repeat( newWidth ); 406 final var appendable = formatter.out(); 407 try 408 { 409 switch( m_Elements.size() ) 410 { 411 case 0 -> appendable.append( "[]" ); 412 case 1 -> 413 { 414 appendable.append( "[" ); 415 final var element = m_Elements.getFirst(); 416 element.formatTo( formatter, flags, newWidth, precision ); 417 appendable.append( "]" ); 418 } 419 default -> 420 { 421 var isFirst = true; 422 appendable.append( "[" ); 423 for( final var element : m_Elements ) 424 { 425 if( isFirst ) 426 { 427 isFirst = false; 428 } 429 else 430 { 431 appendable.append( ',' ); 432 } 433 appendable.append( indentation2 ); 434 element.formatTo( formatter, flags, newWidth, precision ); 435 } 436 appendable.append( indentation1 ) 437 .append( "]" ); 438 } 439 } 440 } 441 catch( final IOException e ) 442 { 443 throw new UncheckedIOException( e.getMessage(), e ); 444 } 445 } // formatTo() 446 447 /** 448 * {@inheritDoc} 449 */ 450 @Override 451 public final JSONValue get( final int index ) throws IndexOutOfBoundsException 452 { 453 return m_Elements.get( index ); 454 } // get() 455 456 /** 457 * {@inheritDoc} 458 */ 459 @Override 460 public final int hashCode() { return hash( m_Builder, m_Elements ); } 461 462 /** 463 * {@inheritDoc} 464 */ 465 @Override 466 public final boolean isEmpty() { return m_Elements.isEmpty(); } 467 468 /** 469 * {@inheritDoc} 470 */ 471 @Override 472 public final Iterator<JSONValue> iterator() { return m_Elements.listIterator(); } 473 474 /** 475 * {@inheritDoc} 476 */ 477 @Override 478 public final void remove( final int index ) throws IndexOutOfBoundsException 479 { 480 m_Elements.remove( index ); 481 } // remove() 482 483 /** 484 * {@inheritDoc} 485 */ 486 @Override 487 public final void remove( final JSONValue element ) throws IndexOutOfBoundsException 488 { 489 m_Elements.remove( requireNonNullArgument( element, "element" ) ); 490 } // remove() 491 492 /** 493 * {@inheritDoc} 494 */ 495 @Override 496 public final void set( final int index, final BigDecimal value ) throws IndexOutOfBoundsException 497 { 498 set( index, m_Builder.valueOf( value ) ); 499 } // set() 500 501 /** 502 * {@inheritDoc} 503 */ 504 @Override 505 public void set( final int index, final BigInteger value ) throws IndexOutOfBoundsException 506 { 507 set( index, m_Builder.valueOf( value ) ); 508 } // set() 509 510 /** 511 * {@inheritDoc} 512 */ 513 @Override 514 public <T extends Dimension> void set( final int index, final DimensionedValue<T> value, final T targetUnit ) throws IndexOutOfBoundsException 515 { 516 set( index, m_Builder.valueOf( value, targetUnit ) ); 517 } // set() 518 519 /** 520 * {@inheritDoc} 521 */ 522 @Override 523 public void set( final int index, final double value ) throws IndexOutOfBoundsException 524 { 525 set( index, m_Builder.valueOf( value ) ); 526 } // set() 527 528 /** 529 * {@inheritDoc} 530 */ 531 @Override 532 public void set( final int index, final Double value ) throws IndexOutOfBoundsException 533 { 534 set( index, m_Builder.valueOf( value ) ); 535 } // set() 536 537 /** 538 * {@inheritDoc} 539 */ 540 @Override 541 public void set( final int index, final float value ) throws IndexOutOfBoundsException 542 { 543 set( index, m_Builder.valueOf( value ) ); 544 } // set() 545 546 /** 547 * {@inheritDoc} 548 */ 549 @Override 550 public void set( final int index, final Float value ) throws IndexOutOfBoundsException 551 { 552 set( index, m_Builder.valueOf( value ) ); 553 } // set() 554 555 /** 556 * {@inheritDoc} 557 */ 558 @Override 559 public void set( final int index, final int value ) throws IndexOutOfBoundsException 560 { 561 set( index, m_Builder.valueOf( value ) ); 562 } // set() 563 564 /** 565 * {@inheritDoc} 566 */ 567 @Override 568 public void set( final int index, final Integer value ) throws IndexOutOfBoundsException 569 { 570 set( index, m_Builder.valueOf( value ) ); 571 } // set() 572 573 /** 574 * {@inheritDoc} 575 */ 576 @Override 577 public final void set( final int index, final JSONValue value ) throws IndexOutOfBoundsException 578 { 579 m_Elements.set( index, requireNonNullArgument( value, "value" ) ); 580 } // set() 581 582 /** 583 * {@inheritDoc} 584 */ 585 @Override 586 public void set( final int index, final long value ) throws IndexOutOfBoundsException 587 { 588 set( index, m_Builder.valueOf( value ) ); 589 } // set() 590 591 /** 592 * {@inheritDoc} 593 */ 594 @Override 595 public void set( final int index, final Long value ) throws IndexOutOfBoundsException 596 { 597 set( index, m_Builder.valueOf( value ) ); 598 } // set() 599 600 /** 601 * {@inheritDoc} 602 */ 603 @Override 604 public void set( final int index, final String value ) throws IndexOutOfBoundsException 605 { 606 set( index, m_Builder.valueOf( value ) ); 607 } // set() 608 609 /** 610 * {@inheritDoc} 611 */ 612 @Override 613 public final JSONArray setArray( final int index ) throws IndexOutOfBoundsException 614 { 615 final var retValue = m_Builder.createArray(); 616 set( index, retValue ); 617 618 //---* Done *---------------------------------------------------------- 619 return retValue; 620 } // setArray() 621 622 /** 623 * {@inheritDoc} 624 */ 625 @Override 626 public final JSONObject setObject( final int index ) throws IndexOutOfBoundsException 627 { 628 final var retValue = m_Builder.createObject(); 629 set( index, retValue ); 630 631 //---* Done *---------------------------------------------------------- 632 return retValue; 633 } // setObject() 634 635 /** 636 * {@inheritDoc} 637 */ 638 @Override 639 public final int size() { return m_Elements.size(); } 640 641 /** 642 * {@inheritDoc} 643 */ 644 @Override 645 public final String toString() 646 { 647 final var buffer = new StringJoiner( ",", "[", "]" ); 648 for( final var element : m_Elements ) 649 { 650 buffer.add( element.toString() ); 651 } 652 final var retValue = buffer.toString(); 653 654 //---* Done *---------------------------------------------------------- 655 return retValue; 656 } // toString() 657} 658// class JSONArrayImpl 659 660/* 661 * End of File 662 */