001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau; 014 015import static org.apache.juneau.BeanTraverseContext.*; 016 017import java.lang.annotation.*; 018import java.lang.reflect.*; 019import java.util.*; 020 021import org.apache.juneau.http.*; 022import org.apache.juneau.internal.*; 023import org.apache.juneau.reflect.*; 024import org.apache.juneau.svl.*; 025 026/** 027 * Builder class for building instances of bean traversals. 028 */ 029public class BeanTraverseBuilder extends BeanContextBuilder { 030 031 /** 032 * Constructor, default settings. 033 */ 034 public BeanTraverseBuilder() { 035 super(); 036 } 037 038 /** 039 * Constructor. 040 * 041 * @param ps The initial configuration settings for this builder. 042 */ 043 public BeanTraverseBuilder(PropertyStore ps) { 044 super(ps); 045 } 046 047 //----------------------------------------------------------------------------------------------------------------- 048 // Properties 049 //----------------------------------------------------------------------------------------------------------------- 050 051 /** 052 * <i><l>BeanTraverse</l> configuration property: </i> Automatically detect POJO recursions. 053 * 054 * <div class='warn'> 055 * <b>Deprecated</b> - Use {@link #detectRecursions()} 056 * </div> 057 */ 058 @SuppressWarnings("javadoc") 059 @FluentSetter 060 @Deprecated 061 public BeanTraverseBuilder detectRecursions(boolean value) { 062 return set(BEANTRAVERSE_detectRecursions, value); 063 } 064 065 /** 066 * <i><l>BeanTraverse</l> configuration property: </i> Automatically detect POJO recursions. 067 * 068 * <p> 069 * When enabled, specifies that recursions should be checked for during traversal. 070 * 071 * <p> 072 * Recursions can occur when traversing models that aren't true trees but rather contain loops. 073 * <br>In general, unchecked recursions cause stack-overflow-errors. 074 * <br>These show up as {@link BeanRecursionException BeanRecursionException} with the message <js>"Depth too deep. Stack overflow occurred."</js>. 075 * 076 * <ul class='notes'> 077 * <li> 078 * Checking for recursion can cause a small performance penalty. 079 * </ul> 080 * 081 * <h5 class='section'>Example:</h5> 082 * <p class='bcode w800'> 083 * <jc>// Create a serializer that automatically checks for recursions.</jc> 084 * WriterSerializer s = JsonSerializer 085 * .<jsm>create</jsm>() 086 * .detectRecursions() 087 * .build(); 088 * 089 * <jc>// Create a POJO model with a recursive loop.</jc> 090 * <jk>public class</jk> A { 091 * <jk>public</jk> Object <jf>f</jf>; 092 * } 093 * A a = <jk>new</jk> A(); 094 * a.<jf>f</jf> = a; 095 * 096 * <jc>// Throws a SerializeException and not a StackOverflowError</jc> 097 * String json = s.serialize(a); 098 * </p> 099 * 100 * <ul class='seealso'> 101 * <li class='jf'>{@link BeanTraverseContext#BEANTRAVERSE_detectRecursions} 102 * </ul> 103 * 104 * @return This object (for method chaining). 105 */ 106 @FluentSetter 107 public BeanTraverseBuilder detectRecursions() { 108 return set(BEANTRAVERSE_detectRecursions, true); 109 } 110 111 /** 112 * <i><l>BeanTraverse</l> configuration property: </i> Ignore recursion errors. 113 * 114 * <div class='warn'> 115 * <b>Deprecated</b> - Use {@link #ignoreRecursions()} 116 * </div> 117 */ 118 @SuppressWarnings("javadoc") 119 @FluentSetter 120 @Deprecated 121 public BeanTraverseBuilder ignoreRecursions(boolean value) { 122 return set(BEANTRAVERSE_ignoreRecursions, value); 123 } 124 125 /** 126 * <i><l>BeanTraverse</l> configuration property: </i> Ignore recursion errors. 127 * 128 * <p> 129 * When enabled, when we encounter the same object when traversing a tree, we set the value to <jk>null</jk>. 130 * 131 * <p> 132 * For example, if a model contains the links A->B->C->A, then the JSON generated will look like 133 * the following when <jsf>BEANTRAVERSE_ignoreRecursions</jsf> is <jk>true</jk>... 134 * 135 * <p class='bcode w800'> 136 * {A:{B:{C:<jk>null</jk>}}} 137 * </p> 138 * 139 * <ul class='notes'> 140 * <li> 141 * Checking for recursion can cause a small performance penalty. 142 * </ul> 143 * 144 * <h5 class='section'>Example:</h5> 145 * <p class='bcode w800'> 146 * <jc>// Create a serializer ignores recursions.</jc> 147 * WriterSerializer s = JsonSerializer 148 * .<jsm>create</jsm>() 149 * .ignoreRecursions() 150 * .build(); 151 * 152 * <jc>// Create a POJO model with a recursive loop.</jc> 153 * <jk>public class</jk> A { 154 * <jk>public</jk> Object <jf>f</jf>; 155 * } 156 * A a = <jk>new</jk> A(); 157 * a.<jf>f</jf> = a; 158 * 159 * <jc>// Produces "{f:null}"</jc> 160 * String json = s.serialize(a); 161 * </p> 162 * 163 * <ul class='seealso'> 164 * <li class='jf'>{@link BeanTraverseContext#BEANTRAVERSE_ignoreRecursions} 165 * </ul> 166 * 167 * @return This object (for method chaining). 168 */ 169 @FluentSetter 170 public BeanTraverseBuilder ignoreRecursions() { 171 return set(BEANTRAVERSE_ignoreRecursions, true); 172 } 173 174 /** 175 * <i><l>BeanTraverse</l> configuration property: </i> Initial depth. 176 * 177 * <p> 178 * The initial indentation level at the root. 179 * 180 * <p> 181 * Useful when constructing document fragments that need to be indented at a certain level when whitespace is enabled. 182 * 183 * <h5 class='section'>Example:</h5> 184 * <p class='bcode w800'> 185 * <jc>// Create a serializer with whitespace enabled and an initial depth of 2.</jc> 186 * WriterSerializer s = JsonSerializer 187 * .<jsm>create</jsm>() 188 * .ws() 189 * .initialDepth(2) 190 * .build(); 191 * 192 * <jc>// Produces "\t\t{\n\t\t\t'foo':'bar'\n\t\t}\n"</jc> 193 * String json = s.serialize(<jk>new</jk> MyBean()); 194 * </p> 195 * 196 * <ul class='seealso'> 197 * <li class='jf'>{@link BeanTraverseContext#BEANTRAVERSE_initialDepth} 198 * </ul> 199 * 200 * @param value 201 * The new value for this property. 202 * <br>The default is <c>0</c>. 203 * @return This object (for method chaining). 204 */ 205 @FluentSetter 206 public BeanTraverseBuilder initialDepth(int value) { 207 return set(BEANTRAVERSE_initialDepth, value); 208 } 209 210 /** 211 * <i><l>BeanTraverse</l> configuration property: </i> Max traversal depth. 212 * 213 * <p> 214 * When enabled, abort traversal if specified depth is reached in the POJO tree. 215 * 216 * <p> 217 * If this depth is exceeded, an exception is thrown. 218 * 219 * <p> 220 * This prevents stack overflows from occurring when trying to traverse models with recursive references. 221 * 222 * <h5 class='section'>Example:</h5> 223 * <p class='bcode w800'> 224 * <jc>// Create a serializer that throws an exception if the depth reaches greater than 20.</jc> 225 * WriterSerializer s = JsonSerializer 226 * .<jsm>create</jsm>() 227 * .maxDepth(20) 228 * .build(); 229 * </p> 230 * 231 * <ul class='seealso'> 232 * <li class='jf'>{@link BeanTraverseContext#BEANTRAVERSE_maxDepth} 233 * </ul> 234 * 235 * @param value 236 * The new value for this property. 237 * <br>The default is <c>100</c>. 238 * @return This object (for method chaining). 239 */ 240 @FluentSetter 241 public BeanTraverseBuilder maxDepth(int value) { 242 return set(BEANTRAVERSE_maxDepth, value); 243 } 244 245 // <FluentSetters> 246 247 @Override /* GENERATED - ContextBuilder */ 248 public BeanTraverseBuilder add(Map<String,Object> properties) { 249 super.add(properties); 250 return this; 251 } 252 253 @Override /* GENERATED - ContextBuilder */ 254 public BeanTraverseBuilder addTo(String name, Object value) { 255 super.addTo(name, value); 256 return this; 257 } 258 259 @Override /* GENERATED - ContextBuilder */ 260 public BeanTraverseBuilder appendTo(String name, Object value) { 261 super.appendTo(name, value); 262 return this; 263 } 264 265 @Override /* GENERATED - ContextBuilder */ 266 public BeanTraverseBuilder apply(PropertyStore copyFrom) { 267 super.apply(copyFrom); 268 return this; 269 } 270 271 @Override /* GENERATED - ContextBuilder */ 272 public BeanTraverseBuilder applyAnnotations(java.lang.Class<?>...fromClasses) { 273 super.applyAnnotations(fromClasses); 274 return this; 275 } 276 277 @Override /* GENERATED - ContextBuilder */ 278 public BeanTraverseBuilder applyAnnotations(Method...fromMethods) { 279 super.applyAnnotations(fromMethods); 280 return this; 281 } 282 283 @Override /* GENERATED - ContextBuilder */ 284 public BeanTraverseBuilder applyAnnotations(AnnotationList al, VarResolverSession r) { 285 super.applyAnnotations(al, r); 286 return this; 287 } 288 289 @Override /* GENERATED - ContextBuilder */ 290 public BeanTraverseBuilder debug() { 291 super.debug(); 292 return this; 293 } 294 295 @Override /* GENERATED - ContextBuilder */ 296 public BeanTraverseBuilder locale(Locale value) { 297 super.locale(value); 298 return this; 299 } 300 301 @Override /* GENERATED - ContextBuilder */ 302 public BeanTraverseBuilder mediaType(MediaType value) { 303 super.mediaType(value); 304 return this; 305 } 306 307 @Override /* GENERATED - ContextBuilder */ 308 public BeanTraverseBuilder prependTo(String name, Object value) { 309 super.prependTo(name, value); 310 return this; 311 } 312 313 @Override /* GENERATED - ContextBuilder */ 314 public BeanTraverseBuilder putAllTo(String name, Object value) { 315 super.putAllTo(name, value); 316 return this; 317 } 318 319 @Override /* GENERATED - ContextBuilder */ 320 public BeanTraverseBuilder putTo(String name, String key, Object value) { 321 super.putTo(name, key, value); 322 return this; 323 } 324 325 @Override /* GENERATED - ContextBuilder */ 326 public BeanTraverseBuilder removeFrom(String name, Object value) { 327 super.removeFrom(name, value); 328 return this; 329 } 330 331 @Override /* GENERATED - ContextBuilder */ 332 public BeanTraverseBuilder set(Map<String,Object> properties) { 333 super.set(properties); 334 return this; 335 } 336 337 @Override /* GENERATED - ContextBuilder */ 338 public BeanTraverseBuilder set(String name, Object value) { 339 super.set(name, value); 340 return this; 341 } 342 343 @Override /* GENERATED - ContextBuilder */ 344 public BeanTraverseBuilder timeZone(TimeZone value) { 345 super.timeZone(value); 346 return this; 347 } 348 349 @Override /* GENERATED - BeanContextBuilder */ 350 public BeanTraverseBuilder annotations(Annotation...values) { 351 super.annotations(values); 352 return this; 353 } 354 355 @Override /* GENERATED - BeanContextBuilder */ 356 public BeanTraverseBuilder beanClassVisibility(Visibility value) { 357 super.beanClassVisibility(value); 358 return this; 359 } 360 361 @Override /* GENERATED - BeanContextBuilder */ 362 public BeanTraverseBuilder beanConstructorVisibility(Visibility value) { 363 super.beanConstructorVisibility(value); 364 return this; 365 } 366 367 @Override /* GENERATED - BeanContextBuilder */ 368 public BeanTraverseBuilder beanFieldVisibility(Visibility value) { 369 super.beanFieldVisibility(value); 370 return this; 371 } 372 373 @Override /* GENERATED - BeanContextBuilder */ 374 public BeanTraverseBuilder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.transform.BeanInterceptor<?>> value) { 375 super.beanInterceptor(on, value); 376 return this; 377 } 378 379 @Override /* GENERATED - BeanContextBuilder */ 380 public BeanTraverseBuilder beanMapPutReturnsOldValue() { 381 super.beanMapPutReturnsOldValue(); 382 return this; 383 } 384 385 @Override /* GENERATED - BeanContextBuilder */ 386 public BeanTraverseBuilder beanMethodVisibility(Visibility value) { 387 super.beanMethodVisibility(value); 388 return this; 389 } 390 391 @Override /* GENERATED - BeanContextBuilder */ 392 public BeanTraverseBuilder beansDontRequireSomeProperties() { 393 super.beansDontRequireSomeProperties(); 394 return this; 395 } 396 397 @Override /* GENERATED - BeanContextBuilder */ 398 public BeanTraverseBuilder beansRequireDefaultConstructor() { 399 super.beansRequireDefaultConstructor(); 400 return this; 401 } 402 403 @Override /* GENERATED - BeanContextBuilder */ 404 public BeanTraverseBuilder beansRequireSerializable() { 405 super.beansRequireSerializable(); 406 return this; 407 } 408 409 @Override /* GENERATED - BeanContextBuilder */ 410 public BeanTraverseBuilder beansRequireSettersForGetters() { 411 super.beansRequireSettersForGetters(); 412 return this; 413 } 414 415 @Override /* GENERATED - BeanContextBuilder */ 416 public BeanTraverseBuilder bpi(Map<String,Object> values) { 417 super.bpi(values); 418 return this; 419 } 420 421 @Override /* GENERATED - BeanContextBuilder */ 422 public BeanTraverseBuilder bpi(Class<?> beanClass, String properties) { 423 super.bpi(beanClass, properties); 424 return this; 425 } 426 427 @Override /* GENERATED - BeanContextBuilder */ 428 public BeanTraverseBuilder bpi(String beanClassName, String properties) { 429 super.bpi(beanClassName, properties); 430 return this; 431 } 432 433 @Override /* GENERATED - BeanContextBuilder */ 434 public BeanTraverseBuilder bpro(Map<String,Object> values) { 435 super.bpro(values); 436 return this; 437 } 438 439 @Override /* GENERATED - BeanContextBuilder */ 440 public BeanTraverseBuilder bpro(Class<?> beanClass, String properties) { 441 super.bpro(beanClass, properties); 442 return this; 443 } 444 445 @Override /* GENERATED - BeanContextBuilder */ 446 public BeanTraverseBuilder bpro(String beanClassName, String properties) { 447 super.bpro(beanClassName, properties); 448 return this; 449 } 450 451 @Override /* GENERATED - BeanContextBuilder */ 452 public BeanTraverseBuilder bpwo(Map<String,Object> values) { 453 super.bpwo(values); 454 return this; 455 } 456 457 @Override /* GENERATED - BeanContextBuilder */ 458 public BeanTraverseBuilder bpwo(Class<?> beanClass, String properties) { 459 super.bpwo(beanClass, properties); 460 return this; 461 } 462 463 @Override /* GENERATED - BeanContextBuilder */ 464 public BeanTraverseBuilder bpwo(String beanClassName, String properties) { 465 super.bpwo(beanClassName, properties); 466 return this; 467 } 468 469 @Override /* GENERATED - BeanContextBuilder */ 470 public BeanTraverseBuilder bpx(Map<String,Object> values) { 471 super.bpx(values); 472 return this; 473 } 474 475 @Override /* GENERATED - BeanContextBuilder */ 476 public BeanTraverseBuilder bpx(Class<?> beanClass, String properties) { 477 super.bpx(beanClass, properties); 478 return this; 479 } 480 481 @Override /* GENERATED - BeanContextBuilder */ 482 public BeanTraverseBuilder bpx(String beanClassName, String properties) { 483 super.bpx(beanClassName, properties); 484 return this; 485 } 486 487 @Override /* GENERATED - BeanContextBuilder */ 488 public BeanTraverseBuilder dictionary(Object...values) { 489 super.dictionary(values); 490 return this; 491 } 492 493 @Override /* GENERATED - BeanContextBuilder */ 494 public BeanTraverseBuilder dictionaryOn(Class<?> on, java.lang.Class<?>...values) { 495 super.dictionaryOn(on, values); 496 return this; 497 } 498 499 @Override /* GENERATED - BeanContextBuilder */ 500 public BeanTraverseBuilder dontIgnorePropertiesWithoutSetters() { 501 super.dontIgnorePropertiesWithoutSetters(); 502 return this; 503 } 504 505 @Override /* GENERATED - BeanContextBuilder */ 506 public BeanTraverseBuilder dontIgnoreTransientFields() { 507 super.dontIgnoreTransientFields(); 508 return this; 509 } 510 511 @Override /* GENERATED - BeanContextBuilder */ 512 public BeanTraverseBuilder dontIgnoreUnknownNullBeanProperties() { 513 super.dontIgnoreUnknownNullBeanProperties(); 514 return this; 515 } 516 517 @Override /* GENERATED - BeanContextBuilder */ 518 public BeanTraverseBuilder dontUseInterfaceProxies() { 519 super.dontUseInterfaceProxies(); 520 return this; 521 } 522 523 @Override /* GENERATED - BeanContextBuilder */ 524 public <T> BeanTraverseBuilder example(Class<T> pojoClass, T o) { 525 super.example(pojoClass, o); 526 return this; 527 } 528 529 @Override /* GENERATED - BeanContextBuilder */ 530 public <T> BeanTraverseBuilder exampleJson(Class<T> pojoClass, String json) { 531 super.exampleJson(pojoClass, json); 532 return this; 533 } 534 535 @Override /* GENERATED - BeanContextBuilder */ 536 public BeanTraverseBuilder fluentSetters() { 537 super.fluentSetters(); 538 return this; 539 } 540 541 @Override /* GENERATED - BeanContextBuilder */ 542 public BeanTraverseBuilder fluentSetters(Class<?> on) { 543 super.fluentSetters(on); 544 return this; 545 } 546 547 @Override /* GENERATED - BeanContextBuilder */ 548 public BeanTraverseBuilder ignoreInvocationExceptionsOnGetters() { 549 super.ignoreInvocationExceptionsOnGetters(); 550 return this; 551 } 552 553 @Override /* GENERATED - BeanContextBuilder */ 554 public BeanTraverseBuilder ignoreInvocationExceptionsOnSetters() { 555 super.ignoreInvocationExceptionsOnSetters(); 556 return this; 557 } 558 559 @Override /* GENERATED - BeanContextBuilder */ 560 public BeanTraverseBuilder ignoreUnknownBeanProperties() { 561 super.ignoreUnknownBeanProperties(); 562 return this; 563 } 564 565 @Override /* GENERATED - BeanContextBuilder */ 566 public BeanTraverseBuilder implClass(Class<?> interfaceClass, Class<?> implClass) { 567 super.implClass(interfaceClass, implClass); 568 return this; 569 } 570 571 @Override /* GENERATED - BeanContextBuilder */ 572 public BeanTraverseBuilder implClasses(Map<Class<?>,Class<?>> values) { 573 super.implClasses(values); 574 return this; 575 } 576 577 @Override /* GENERATED - BeanContextBuilder */ 578 public BeanTraverseBuilder interfaceClass(Class<?> on, Class<?> value) { 579 super.interfaceClass(on, value); 580 return this; 581 } 582 583 @Override /* GENERATED - BeanContextBuilder */ 584 public BeanTraverseBuilder interfaces(java.lang.Class<?>...value) { 585 super.interfaces(value); 586 return this; 587 } 588 589 @Override /* GENERATED - BeanContextBuilder */ 590 public BeanTraverseBuilder notBeanClasses(Object...values) { 591 super.notBeanClasses(values); 592 return this; 593 } 594 595 @Override /* GENERATED - BeanContextBuilder */ 596 public BeanTraverseBuilder notBeanPackages(Object...values) { 597 super.notBeanPackages(values); 598 return this; 599 } 600 601 @Override /* GENERATED - BeanContextBuilder */ 602 public BeanTraverseBuilder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) { 603 super.propertyNamer(value); 604 return this; 605 } 606 607 @Override /* GENERATED - BeanContextBuilder */ 608 public BeanTraverseBuilder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) { 609 super.propertyNamer(on, value); 610 return this; 611 } 612 613 @Override /* GENERATED - BeanContextBuilder */ 614 public BeanTraverseBuilder sortProperties() { 615 super.sortProperties(); 616 return this; 617 } 618 619 @Override /* GENERATED - BeanContextBuilder */ 620 public BeanTraverseBuilder sortProperties(java.lang.Class<?>...on) { 621 super.sortProperties(on); 622 return this; 623 } 624 625 @Override /* GENERATED - BeanContextBuilder */ 626 public BeanTraverseBuilder stopClass(Class<?> on, Class<?> value) { 627 super.stopClass(on, value); 628 return this; 629 } 630 631 @Override /* GENERATED - BeanContextBuilder */ 632 public BeanTraverseBuilder swaps(Object...values) { 633 super.swaps(values); 634 return this; 635 } 636 637 @Override /* GENERATED - BeanContextBuilder */ 638 public BeanTraverseBuilder typeName(Class<?> on, String value) { 639 super.typeName(on, value); 640 return this; 641 } 642 643 @Override /* GENERATED - BeanContextBuilder */ 644 public BeanTraverseBuilder typePropertyName(String value) { 645 super.typePropertyName(value); 646 return this; 647 } 648 649 @Override /* GENERATED - BeanContextBuilder */ 650 public BeanTraverseBuilder typePropertyName(Class<?> on, String value) { 651 super.typePropertyName(on, value); 652 return this; 653 } 654 655 @Override /* GENERATED - BeanContextBuilder */ 656 public BeanTraverseBuilder useEnumNames() { 657 super.useEnumNames(); 658 return this; 659 } 660 661 @Override /* GENERATED - BeanContextBuilder */ 662 public BeanTraverseBuilder useJavaBeanIntrospector() { 663 super.useJavaBeanIntrospector(); 664 return this; 665 } 666 667 // </FluentSetters> 668 669 @Override /* Context */ 670 public BeanTraverseContext build() { 671 return null; 672 } 673}