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.parser; 014 015import static org.apache.juneau.internal.CollectionUtils.*; 016import static org.apache.juneau.parser.Parser.*; 017 018import java.util.*; 019 020import org.apache.juneau.*; 021import org.apache.juneau.http.*; 022import org.apache.juneau.internal.*; 023 024/** 025 * Builder class for creating instances of {@link ParserGroup}. 026 */ 027public class ParserGroupBuilder extends BeanContextBuilder { 028 029 private final List<Object> parsers; 030 031 /** 032 * Create an empty parser group builder. 033 */ 034 public ParserGroupBuilder() { 035 this.parsers = new ArrayList<>(); 036 } 037 038 /** 039 * Clone an existing parser group builder. 040 * 041 * @param copyFrom The parser group that we're copying settings and parsers from. 042 */ 043 public ParserGroupBuilder(ParserGroup copyFrom) { 044 super(copyFrom.getPropertyStore()); 045 this.parsers = new ArrayList<>(); 046 addReverse(parsers, copyFrom.getParsers()); 047 } 048 049 /** 050 * Registers the specified parsers with this group. 051 * 052 * @param p The parsers to append to this group. 053 * @return This object (for method chaining). 054 */ 055 public ParserGroupBuilder append(Class<?>...p) { 056 addReverse(parsers, p); 057 return this; 058 } 059 060 /** 061 * Registers the specified parsers with this group. 062 * 063 * <p> 064 * When passing in pre-instantiated parsers to this group, applying properties and transforms to the group 065 * do not affect them. 066 * 067 * @param p The parsers to append to this group. 068 * @return This object (for method chaining). 069 */ 070 public ParserGroupBuilder append(Parser...p) { 071 addReverse(parsers, p); 072 return this; 073 } 074 075 /** 076 * Registers the specified parsers with this group. 077 * 078 * <p> 079 * Objects can either be instances of parsers or parser classes. 080 * 081 * @param p The parsers to append to this group. 082 * @return This object (for method chaining). 083 */ 084 public ParserGroupBuilder append(List<Object> p) { 085 addReverse(parsers, p); 086 return this; 087 } 088 089 /** 090 * Registers the specified parsers with this group. 091 * 092 * <p> 093 * Objects can either be instances of parsers or parser classes. 094 * 095 * @param p The parsers to append to this group. 096 * @return This object (for method chaining). 097 */ 098 public ParserGroupBuilder append(Object...p) { 099 addReverse(parsers, p); 100 return this; 101 } 102 103 /** 104 * Creates a new {@link ParserGroup} object using a snapshot of the settings defined in this builder. 105 * 106 * <p> 107 * This method can be called multiple times to produce multiple parser groups. 108 * 109 * @return A new {@link ParserGroup} object. 110 */ 111 @Override /* Context */ 112 @SuppressWarnings("unchecked") 113 public ParserGroup build() { 114 List<Parser> l = new ArrayList<>(); 115 for (Object p : parsers) { 116 Class<? extends Parser> c = null; 117 PropertyStore ps = getPropertyStore(); 118 if (p instanceof Class) { 119 c = (Class<? extends Parser>)p; 120 l.add(ContextCache.INSTANCE.create(c, ps)); 121 } else { 122 l.add((Parser)p); 123 } 124 } 125 return new ParserGroup(getPropertyStore(), ArrayUtils.toReverseArray(Parser.class, l)); 126 } 127 128 129 //-------------------------------------------------------------------------------- 130 // Properties 131 //-------------------------------------------------------------------------------- 132 133 /** 134 * Configuration property: Auto-close streams. 135 * 136 * <p> 137 * If <jk>true</jk>, <l>InputStreams</l> and <l>Readers</l> passed into parsers will be closed 138 * after parsing is complete. 139 * 140 * <h5 class='section'>See Also:</h5> 141 * <ul> 142 * <li class='jf'>{@link Parser#PARSER_autoCloseStreams} 143 * </ul> 144 * 145 * @param value 146 * The new value for this property. 147 * <br>The default value is <jk>false</jk>. 148 * @return This object (for method chaining). 149 */ 150 public ParserGroupBuilder autoCloseStreams(boolean value) { 151 return set(PARSER_autoCloseStreams, value); 152 } 153 154 /** 155 * Configuration property: Auto-close streams. 156 * <p> 157 * Shortcut for calling <code>autoCloseStreams(<jk>true</jk>)</code>. 158 * 159 * <h5 class='section'>See Also:</h5> 160 * <ul> 161 * <li class='jf'>{@link Parser#PARSER_autoCloseStreams} 162 * </ul> 163 * 164 * @return This object (for method chaining). 165 */ 166 public ParserGroupBuilder autoCloseStreams() { 167 return set(PARSER_autoCloseStreams, true); 168 } 169 170 /** 171 * Configuration property: File charset. 172 * 173 * <p> 174 * The character set to use for reading <code>Files</code> from the file system. 175 * 176 * <h5 class='section'>See Also:</h5> 177 * <ul> 178 * <li class='jf'>{@link Parser#PARSER_fileCharset} 179 * </ul> 180 * 181 * @param value 182 * The new value for this property. 183 * <br>The default value is <js>"DEFAULT"</js> which causes the system default to be used. 184 * @return This object (for method chaining). 185 */ 186 public ParserGroupBuilder fileCharset(String value) { 187 return set(PARSER_fileCharset, value); 188 } 189 190 /** 191 * Configuration property: Input stream charset. 192 * 193 * <p> 194 * The character set to use for converting <code>InputStreams</code> and byte arrays to readers. 195 * 196 * <h5 class='section'>See Also:</h5> 197 * <ul> 198 * <li class='jf'>{@link Parser#PARSER_inputStreamCharset} 199 * </ul> 200 * 201 * @param value 202 * The new value for this property. 203 * <br>The default value is <js>"UTF-8"</js>. 204 * @return This object (for method chaining). 205 */ 206 public ParserGroupBuilder inputStreamCharset(String value) { 207 return set(PARSER_inputStreamCharset, value); 208 } 209 210 /** 211 * Configuration property: Parser listener. 212 * 213 * <p> 214 * Class used to listen for errors and warnings that occur during parsing. 215 * 216 * <h5 class='section'>See Also:</h5> 217 * <ul> 218 * <li class='jf'>{@link Parser#PARSER_listener} 219 * </ul> 220 * 221 * @param value The new value for this property. 222 * @return This object (for method chaining). 223 */ 224 public ParserGroupBuilder listener(Class<? extends ParserListener> value) { 225 return set(PARSER_listener, value); 226 } 227 228 /** 229 * Configuration property: Strict mode. 230 * 231 * <p> 232 * If <jk>true</jk>, strict mode for the parsers are enabled. 233 * 234 * <h5 class='section'>See Also:</h5> 235 * <ul> 236 * <li class='jf'>{@link Parser#PARSER_strict} 237 * </ul> 238 * 239 * @param value 240 * The new value for this property. 241 * <br>The default value is <jk>false</jk>. 242 * @return This object (for method chaining). 243 */ 244 public ParserGroupBuilder strict(boolean value) { 245 return set(PARSER_strict, value); 246 } 247 248 /** 249 * Configuration property: Strict mode. 250 * 251 * <p> 252 * Shortcut for calling <code>strict(<jk>true</jk>)</code>. 253 * 254 * <h5 class='section'>See Also:</h5> 255 * <ul> 256 * <li class='jf'>{@link Parser#PARSER_strict} 257 * </ul> 258 * 259 * @return This object (for method chaining). 260 */ 261 public ParserGroupBuilder strict() { 262 return set(PARSER_strict, true); 263 } 264 265 /** 266 * Configuration property: Trim parsed strings. 267 * 268 * <p> 269 * If <jk>true</jk>, string values will be trimmed of whitespace using {@link String#trim()} before being added to 270 * the POJO. 271 * 272 * <h5 class='section'>See Also:</h5> 273 * <ul> 274 * <li class='jf'>{@link Parser#PARSER_trimStrings} 275 * </ul> 276 * 277 * @param value 278 * The new value for this property. 279 * <br>The default value is <jk>false</jk>. 280 * @return This object (for method chaining). 281 */ 282 public ParserGroupBuilder trimStrings(boolean value) { 283 return set(PARSER_trimStrings, value); 284 } 285 286 /** 287 * Configuration property: Trim parsed strings. 288 * 289 * <p> 290 * Shortcut for calling <code>trimStrings(<jk>true</jk>)</code>. 291 * 292 * <h5 class='section'>See Also:</h5> 293 * <ul> 294 * <li class='jf'>{@link Parser#PARSER_trimStrings} 295 * </ul> 296 * 297 * @return This object (for method chaining). 298 */ 299 public ParserGroupBuilder trimStrings() { 300 return set(PARSER_trimStrings, true); 301 } 302 303 /** 304 * Configuration property: Unbuffered. 305 * 306 * <p> 307 * If <jk>true</jk>, don't use internal buffering during parsing. 308 * 309 * <h5 class='section'>See Also:</h5> 310 * <ul> 311 * <li class='jf'>{@link Parser#PARSER_unbuffered} 312 * </ul> 313 * 314 * @param value 315 * The new value for this property. 316 * <br>The default value is <jk>false</jk>. 317 * @return This object (for method chaining). 318 */ 319 public ParserGroupBuilder unbuffered(boolean value) { 320 return set(PARSER_unbuffered, value); 321 } 322 323 /** 324 * Configuration property: Unbuffered. 325 * 326 * <p> 327 * Shortcut for calling <code>unbuffered(<jk>true</jk>)</code>. 328 * 329 * <h5 class='section'>See Also:</h5> 330 * <ul> 331 * <li class='jf'>{@link Parser#PARSER_unbuffered} 332 * </ul> 333 * 334 * @return This object (for method chaining). 335 */ 336 public ParserGroupBuilder unbuffered() { 337 return set(PARSER_unbuffered, true); 338 } 339 340 @Override /* BeanContextBuilder */ 341 public ParserGroupBuilder beansRequireDefaultConstructor(boolean value) { 342 super.beansRequireDefaultConstructor(value); 343 return this; 344 } 345 346 @Override /* BeanContextBuilder */ 347 public ParserGroupBuilder beansRequireDefaultConstructor() { 348 super.beansRequireDefaultConstructor(); 349 return this; 350 } 351 352 @Override /* BeanContextBuilder */ 353 public ParserGroupBuilder beansRequireSerializable(boolean value) { 354 super.beansRequireSerializable(value); 355 return this; 356 } 357 358 @Override /* BeanContextBuilder */ 359 public ParserGroupBuilder beansRequireSerializable() { 360 super.beansRequireSerializable(); 361 return this; 362 } 363 364 @Override /* BeanContextBuilder */ 365 public ParserGroupBuilder beansRequireSettersForGetters(boolean value) { 366 super.beansRequireSettersForGetters(value); 367 return this; 368 } 369 370 @Override /* BeanContextBuilder */ 371 public ParserGroupBuilder beansRequireSettersForGetters() { 372 super.beansRequireSettersForGetters(); 373 return this; 374 } 375 376 @Override /* BeanContextBuilder */ 377 public ParserGroupBuilder beansRequireSomeProperties(boolean value) { 378 super.beansRequireSomeProperties(value); 379 return this; 380 } 381 382 @Override /* BeanContextBuilder */ 383 public ParserGroupBuilder beanMapPutReturnsOldValue(boolean value) { 384 super.beanMapPutReturnsOldValue(value); 385 return this; 386 } 387 388 @Override /* BeanContextBuilder */ 389 public ParserGroupBuilder beanMapPutReturnsOldValue() { 390 super.beanMapPutReturnsOldValue(); 391 return this; 392 } 393 394 @Override /* BeanContextBuilder */ 395 public ParserGroupBuilder beanConstructorVisibility(Visibility value) { 396 super.beanConstructorVisibility(value); 397 return this; 398 } 399 400 @Override /* BeanContextBuilder */ 401 public ParserGroupBuilder beanClassVisibility(Visibility value) { 402 super.beanClassVisibility(value); 403 return this; 404 } 405 406 @Override /* BeanContextBuilder */ 407 public ParserGroupBuilder beanFieldVisibility(Visibility value) { 408 super.beanFieldVisibility(value); 409 return this; 410 } 411 412 @Override /* BeanContextBuilder */ 413 public ParserGroupBuilder beanMethodVisibility(Visibility value) { 414 super.beanMethodVisibility(value); 415 return this; 416 } 417 418 @Override /* BeanContextBuilder */ 419 public ParserGroupBuilder useJavaBeanIntrospector(boolean value) { 420 super.useJavaBeanIntrospector(value); 421 return this; 422 } 423 424 @Override /* BeanContextBuilder */ 425 public ParserGroupBuilder useJavaBeanIntrospector() { 426 super.useJavaBeanIntrospector(); 427 return this; 428 } 429 430 @Override /* BeanContextBuilder */ 431 public ParserGroupBuilder useInterfaceProxies(boolean value) { 432 super.useInterfaceProxies(value); 433 return this; 434 } 435 436 @Override /* BeanContextBuilder */ 437 public ParserGroupBuilder ignoreUnknownBeanProperties(boolean value) { 438 super.ignoreUnknownBeanProperties(value); 439 return this; 440 } 441 442 @Override /* BeanContextBuilder */ 443 public ParserGroupBuilder ignoreUnknownBeanProperties() { 444 super.ignoreUnknownBeanProperties(); 445 return this; 446 } 447 448 @Override /* BeanContextBuilder */ 449 public ParserGroupBuilder ignoreUnknownNullBeanProperties(boolean value) { 450 super.ignoreUnknownNullBeanProperties(value); 451 return this; 452 } 453 454 @Override /* BeanContextBuilder */ 455 public ParserGroupBuilder ignorePropertiesWithoutSetters(boolean value) { 456 super.ignorePropertiesWithoutSetters(value); 457 return this; 458 } 459 460 @Override /* BeanContextBuilder */ 461 public ParserGroupBuilder ignoreInvocationExceptionsOnGetters(boolean value) { 462 super.ignoreInvocationExceptionsOnGetters(value); 463 return this; 464 } 465 466 @Override /* BeanContextBuilder */ 467 public ParserGroupBuilder ignoreInvocationExceptionsOnGetters() { 468 super.ignoreInvocationExceptionsOnGetters(); 469 return this; 470 } 471 472 @Override /* BeanContextBuilder */ 473 public ParserGroupBuilder ignoreInvocationExceptionsOnSetters(boolean value) { 474 super.ignoreInvocationExceptionsOnSetters(value); 475 return this; 476 } 477 478 @Override /* BeanContextBuilder */ 479 public ParserGroupBuilder ignoreInvocationExceptionsOnSetters() { 480 super.ignoreInvocationExceptionsOnSetters(); 481 return this; 482 } 483 484 @Override /* BeanContextBuilder */ 485 public ParserGroupBuilder sortProperties(boolean value) { 486 super.sortProperties(value); 487 return this; 488 } 489 490 @Override /* BeanContextBuilder */ 491 public ParserGroupBuilder sortProperties() { 492 super.sortProperties(); 493 return this; 494 } 495 496 @Override /* BeanContextBuilder */ 497 public ParserGroupBuilder notBeanPackages(Object...values) { 498 super.notBeanPackages(values); 499 return this; 500 } 501 502 @Override /* BeanContextBuilder */ 503 public ParserGroupBuilder notBeanPackages(String...values) { 504 super.notBeanPackages(values); 505 return this; 506 } 507 508 @Override /* BeanContextBuilder */ 509 public ParserGroupBuilder notBeanPackages(boolean append, Object...values) { 510 super.notBeanPackages(append, values); 511 return this; 512 } 513 514 @Override /* BeanContextBuilder */ 515 public ParserGroupBuilder notBeanPackagesRemove(Object...values) { 516 super.notBeanPackagesRemove(values); 517 return this; 518 } 519 520 @Override /* BeanContextBuilder */ 521 public ParserGroupBuilder notBeanClasses(Object...values) { 522 super.notBeanClasses(values); 523 return this; 524 } 525 526 @Override /* BeanContextBuilder */ 527 public ParserGroupBuilder notBeanClasses(Class<?>...values) { 528 super.notBeanClasses(values); 529 return this; 530 } 531 532 @Override /* BeanContextBuilder */ 533 public ParserGroupBuilder notBeanClasses(boolean append, Object...values) { 534 super.notBeanClasses(append, values); 535 return this; 536 } 537 538 @Override /* BeanContextBuilder */ 539 public ParserGroupBuilder notBeanClassesRemove(Object...values) { 540 super.notBeanClassesRemove(values); 541 return this; 542 } 543 544 @Override /* BeanContextBuilder */ 545 public ParserGroupBuilder beanFilters(Object...values) { 546 super.beanFilters(values); 547 return this; 548 } 549 550 @Override /* BeanContextBuilder */ 551 public ParserGroupBuilder beanFilters(Class<?>...values) { 552 super.beanFilters(values); 553 return this; 554 } 555 556 @Override /* BeanContextBuilder */ 557 public ParserGroupBuilder beanFilters(boolean append, Object...values) { 558 super.beanFilters(append, values); 559 return this; 560 } 561 562 @Override /* BeanContextBuilder */ 563 public ParserGroupBuilder beanFiltersRemove(Object...values) { 564 super.beanFiltersRemove(values); 565 return this; 566 } 567 568 @Override /* BeanContextBuilder */ 569 public ParserGroupBuilder pojoSwaps(Object...values) { 570 super.pojoSwaps(values); 571 return this; 572 } 573 574 @Override /* BeanContextBuilder */ 575 public ParserGroupBuilder pojoSwaps(Class<?>...values) { 576 super.pojoSwaps(values); 577 return this; 578 } 579 580 @Override /* BeanContextBuilder */ 581 public ParserGroupBuilder pojoSwaps(boolean append, Object...values) { 582 super.pojoSwaps(append, values); 583 return this; 584 } 585 586 @Override /* BeanContextBuilder */ 587 public ParserGroupBuilder pojoSwapsRemove(Object...values) { 588 super.pojoSwapsRemove(values); 589 return this; 590 } 591 592 @Override /* BeanContextBuilder */ 593 public ParserGroupBuilder implClasses(Map<String,Class<?>> values) { 594 super.implClasses(values); 595 return this; 596 } 597 598 @Override /* BeanContextBuilder */ 599 public <T> ParserGroupBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) { 600 super.implClass(interfaceClass, implClass); 601 return this; 602 } 603 604 @Override /* BeanContextBuilder */ 605 public ParserGroupBuilder beanDictionary(Object...values) { 606 super.beanDictionary(values); 607 return this; 608 } 609 610 @Override /* BeanContextBuilder */ 611 public ParserGroupBuilder beanDictionary(Class<?>...values) { 612 super.beanDictionary(values); 613 return this; 614 } 615 616 @Override /* BeanContextBuilder */ 617 public ParserGroupBuilder beanDictionary(boolean append, Object...values) { 618 super.beanDictionary(append, values); 619 return this; 620 } 621 622 @Override /* BeanContextBuilder */ 623 public ParserGroupBuilder beanDictionaryRemove(Object...values) { 624 super.beanDictionaryRemove(values); 625 return this; 626 } 627 628 @Override /* BeanContextBuilder */ 629 public ParserGroupBuilder beanTypePropertyName(String value) { 630 super.beanTypePropertyName(value); 631 return this; 632 } 633 634 @Override /* BeanContextBuilder */ 635 public ParserGroupBuilder locale(Locale value) { 636 super.locale(value); 637 return this; 638 } 639 640 @Override /* BeanContextBuilder */ 641 public ParserGroupBuilder timeZone(TimeZone value) { 642 super.timeZone(value); 643 return this; 644 } 645 646 @Override /* BeanContextBuilder */ 647 public ParserGroupBuilder mediaType(MediaType value) { 648 super.mediaType(value); 649 return this; 650 } 651 652 @Override /* BeanContextBuilder */ 653 public ParserGroupBuilder debug() { 654 super.debug(); 655 return this; 656 } 657 658 @Override /* ContextBuilder */ 659 public ParserGroupBuilder set(String name, Object value) { 660 super.set(name, value); 661 return this; 662 } 663 664 @Override /* ContextBuilder */ 665 public ParserGroupBuilder set(boolean append, String name, Object value) { 666 super.set(append, name, value); 667 return this; 668 } 669 670 @Override /* ContextBuilder */ 671 public ParserGroupBuilder set(Map<String,Object> properties) { 672 super.set(properties); 673 return this; 674 } 675 676 @Override /* ContextBuilder */ 677 public ParserGroupBuilder add(Map<String,Object> properties) { 678 super.add(properties); 679 return this; 680 } 681 682 @Override /* ContextBuilder */ 683 public ParserGroupBuilder addTo(String name, Object value) { 684 super.addTo(name, value); 685 return this; 686 } 687 688 @Override /* ContextBuilder */ 689 public ParserGroupBuilder addTo(String name, String key, Object value) { 690 super.addTo(name, key, value); 691 return this; 692 } 693 694 @Override /* ContextBuilder */ 695 public ParserGroupBuilder removeFrom(String name, Object value) { 696 super.removeFrom(name, value); 697 return this; 698 } 699 700 @Override /* ContextBuilder */ 701 public ParserGroupBuilder apply(PropertyStore copyFrom) { 702 super.apply(copyFrom); 703 return this; 704 } 705}