001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 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, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.parser; 018 019import static org.apache.juneau.commons.utils.AssertionUtils.*; 020import static org.apache.juneau.commons.utils.IoUtils.*; 021import static org.apache.juneau.commons.utils.Utils.*; 022 023import java.lang.annotation.*; 024import java.nio.charset.*; 025import java.util.*; 026 027import org.apache.juneau.*; 028import org.apache.juneau.commons.collections.*; 029import org.apache.juneau.commons.function.*; 030import org.apache.juneau.commons.reflect.*; 031 032/** 033 * Subclass of {@link Parser} for characters-based parsers. 034 * 035 * <h5 class='topic'>Description</h5> 036 * <p> 037 * This class is typically the parent class of all character-based parsers. 038 * It has 1 abstract method to implement on the session object... 039 * <ul> 040 * <li><c>parse(ParserSession, ClassMeta)</c> 041 * </ul> 042 * 043 * <h5 class='section'>Notes:</h5><ul> 044 * <li class='note'>This class is thread safe and reusable. 045 * </ul> 046 * 047 * <h5 class='section'>See Also:</h5><ul> 048 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/SerializersAndParsers">Serializers and Parsers</a> 049 * </ul> 050 */ 051public class ReaderParser extends Parser { 052 053 /** 054 * Builder class. 055 */ 056 public static class Builder extends Parser.Builder { 057 058 private Charset fileCharset; 059 private Charset streamCharset; 060 061 /** 062 * Constructor, default settings. 063 */ 064 protected Builder() { 065 fileCharset = env("ReaderParser.fileCharset").map(x -> Charset.forName(x)).orElse(Charset.defaultCharset()); 066 streamCharset = env("ReaderParser.streamCharset", UTF8); 067 } 068 069 /** 070 * Copy constructor. 071 * 072 * @param copyFrom The builder to copy from. 073 * <br>Cannot be <jk>null</jk>. 074 */ 075 protected Builder(Builder copyFrom) { 076 super(assertArgNotNull("copyFrom", copyFrom)); 077 fileCharset = copyFrom.fileCharset; 078 streamCharset = copyFrom.streamCharset; 079 } 080 081 /** 082 * Copy constructor. 083 * 084 * @param copyFrom The bean to copy from. 085 * <br>Cannot be <jk>null</jk>. 086 */ 087 protected Builder(ReaderParser copyFrom) { 088 super(assertArgNotNull("copyFrom", copyFrom)); 089 fileCharset = copyFrom.fileCharset; 090 streamCharset = copyFrom.streamCharset; 091 } 092 093 @Override /* Overridden from Builder */ 094 public Builder annotations(Annotation...values) { 095 super.annotations(values); 096 return this; 097 } 098 099 @Override /* Overridden from Builder */ 100 public Builder apply(AnnotationWorkList work) { 101 super.apply(work); 102 return this; 103 } 104 105 @Override /* Overridden from Builder */ 106 public Builder applyAnnotations(Class<?>...from) { 107 super.applyAnnotations(from); 108 return this; 109 } 110 111 @Override /* Overridden from Builder */ 112 public Builder applyAnnotations(Object...from) { 113 super.applyAnnotations(from); 114 return this; 115 } 116 117 @Override /* Overridden from Builder */ 118 public Builder autoCloseStreams() { 119 super.autoCloseStreams(); 120 return this; 121 } 122 123 @Override /* Overridden from Builder */ 124 public Builder autoCloseStreams(boolean value) { 125 super.autoCloseStreams(value); 126 return this; 127 } 128 129 @Override /* Overridden from Builder */ 130 public Builder beanClassVisibility(Visibility value) { 131 super.beanClassVisibility(value); 132 return this; 133 } 134 135 @Override /* Overridden from Builder */ 136 public Builder beanConstructorVisibility(Visibility value) { 137 super.beanConstructorVisibility(value); 138 return this; 139 } 140 141 @Override /* Overridden from Builder */ 142 public Builder beanContext(BeanContext value) { 143 super.beanContext(value); 144 return this; 145 } 146 147 @Override /* Overridden from Builder */ 148 public Builder beanContext(BeanContext.Builder value) { 149 super.beanContext(value); 150 return this; 151 } 152 153 @Override /* Overridden from Builder */ 154 public Builder beanDictionary(java.lang.Class<?>...values) { 155 super.beanDictionary(values); 156 return this; 157 } 158 159 @Override /* Overridden from Builder */ 160 public Builder beanFieldVisibility(Visibility value) { 161 super.beanFieldVisibility(value); 162 return this; 163 } 164 165 @Override /* Overridden from Builder */ 166 public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) { 167 super.beanInterceptor(on, value); 168 return this; 169 } 170 171 @Override /* Overridden from Builder */ 172 public Builder beanMapPutReturnsOldValue() { 173 super.beanMapPutReturnsOldValue(); 174 return this; 175 } 176 177 @Override /* Overridden from Builder */ 178 public Builder beanMethodVisibility(Visibility value) { 179 super.beanMethodVisibility(value); 180 return this; 181 } 182 183 @Override /* Overridden from Builder */ 184 public Builder beanProperties(Class<?> beanClass, String properties) { 185 super.beanProperties(beanClass, properties); 186 return this; 187 } 188 189 @Override /* Overridden from Builder */ 190 public Builder beanProperties(Map<String,Object> values) { 191 super.beanProperties(values); 192 return this; 193 } 194 195 @Override /* Overridden from Builder */ 196 public Builder beanProperties(String beanClassName, String properties) { 197 super.beanProperties(beanClassName, properties); 198 return this; 199 } 200 201 @Override /* Overridden from Builder */ 202 public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) { 203 super.beanPropertiesExcludes(beanClass, properties); 204 return this; 205 } 206 207 @Override /* Overridden from Builder */ 208 public Builder beanPropertiesExcludes(Map<String,Object> values) { 209 super.beanPropertiesExcludes(values); 210 return this; 211 } 212 213 @Override /* Overridden from Builder */ 214 public Builder beanPropertiesExcludes(String beanClassName, String properties) { 215 super.beanPropertiesExcludes(beanClassName, properties); 216 return this; 217 } 218 219 @Override /* Overridden from Builder */ 220 public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) { 221 super.beanPropertiesReadOnly(beanClass, properties); 222 return this; 223 } 224 225 @Override /* Overridden from Builder */ 226 public Builder beanPropertiesReadOnly(Map<String,Object> values) { 227 super.beanPropertiesReadOnly(values); 228 return this; 229 } 230 231 @Override /* Overridden from Builder */ 232 public Builder beanPropertiesReadOnly(String beanClassName, String properties) { 233 super.beanPropertiesReadOnly(beanClassName, properties); 234 return this; 235 } 236 237 @Override /* Overridden from Builder */ 238 public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) { 239 super.beanPropertiesWriteOnly(beanClass, properties); 240 return this; 241 } 242 243 @Override /* Overridden from Builder */ 244 public Builder beanPropertiesWriteOnly(Map<String,Object> values) { 245 super.beanPropertiesWriteOnly(values); 246 return this; 247 } 248 249 @Override /* Overridden from Builder */ 250 public Builder beanPropertiesWriteOnly(String beanClassName, String properties) { 251 super.beanPropertiesWriteOnly(beanClassName, properties); 252 return this; 253 } 254 255 @Override /* Overridden from Builder */ 256 public Builder beansRequireDefaultConstructor() { 257 super.beansRequireDefaultConstructor(); 258 return this; 259 } 260 261 @Override /* Overridden from Builder */ 262 public Builder beansRequireSerializable() { 263 super.beansRequireSerializable(); 264 return this; 265 } 266 267 @Override /* Overridden from Builder */ 268 public Builder beansRequireSettersForGetters() { 269 super.beansRequireSettersForGetters(); 270 return this; 271 } 272 273 @Override /* Overridden from Context.Builder */ 274 public ReaderParser build() { 275 return build(ReaderParser.class); 276 } 277 278 @Override /* Overridden from Builder */ 279 public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) { 280 super.cache(value); 281 return this; 282 } 283 284 @Override /* Overridden from Builder */ 285 public Builder consumes(String value) { 286 super.consumes(value); 287 return this; 288 } 289 290 @Override /* Overridden from Context.Builder */ 291 public Builder copy() { 292 return new Builder(this); 293 } 294 295 @Override /* Overridden from Builder */ 296 public Builder debug() { 297 super.debug(); 298 return this; 299 } 300 301 @Override /* Overridden from Builder */ 302 public Builder debug(boolean value) { 303 super.debug(value); 304 return this; 305 } 306 307 @Override /* Overridden from Builder */ 308 public Builder debugOutputLines(int value) { 309 super.debugOutputLines(value); 310 return this; 311 } 312 313 @Override /* Overridden from Builder */ 314 public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) { 315 super.dictionaryOn(on, values); 316 return this; 317 } 318 319 @Override /* Overridden from Builder */ 320 public Builder disableBeansRequireSomeProperties() { 321 super.disableBeansRequireSomeProperties(); 322 return this; 323 } 324 325 @Override /* Overridden from Builder */ 326 public Builder disableIgnoreMissingSetters() { 327 super.disableIgnoreMissingSetters(); 328 return this; 329 } 330 331 @Override /* Overridden from Builder */ 332 public Builder disableIgnoreTransientFields() { 333 super.disableIgnoreTransientFields(); 334 return this; 335 } 336 337 @Override /* Overridden from Builder */ 338 public Builder disableIgnoreUnknownNullBeanProperties() { 339 super.disableIgnoreUnknownNullBeanProperties(); 340 return this; 341 } 342 343 @Override /* Overridden from Builder */ 344 public Builder disableInterfaceProxies() { 345 super.disableInterfaceProxies(); 346 return this; 347 } 348 349 @Override /* Overridden from Builder */ 350 public <T> Builder example(Class<T> pojoClass, String json) { 351 super.example(pojoClass, json); 352 return this; 353 } 354 355 @Override /* Overridden from Builder */ 356 public <T> Builder example(Class<T> pojoClass, T o) { 357 super.example(pojoClass, o); 358 return this; 359 } 360 361 /** 362 * File charset. 363 * 364 * <p> 365 * The character set to use for reading <c>Files</c> from the file system. 366 * 367 * <p> 368 * Used when passing in files to {@link Parser#parse(Object, Class)}. 369 * 370 * <h5 class='section'>Example:</h5> 371 * <p class='bjava'> 372 * <jc>// Create a parser that reads UTF-8 files.</jc> 373 * ReaderParser <jv>parser</jv> = JsonParser 374 * .<jsm>create</jsm>() 375 * .fileCharset(<js>"UTF-8"</js>) 376 * .build(); 377 * 378 * <jc>// Use it to read a UTF-8 encoded file.</jc> 379 * MyBean <jv>myBean</jv> = <jv>parser</jv>.parse(<jk>new</jk> File(<js>"MyBean.txt"</js>), MyBean.<jk>class</jk>); 380 * </p> 381 * 382 * @param value 383 * The new value for this property. 384 * <br>The default value is <js>"DEFAULT"</js> which causes the system default to be used. 385 * <br>Can be <jk>null</jk> (defaults to system default). 386 * @return This object. 387 */ 388 public Builder fileCharset(Charset value) { 389 fileCharset = value; 390 return this; 391 } 392 393 @Override /* Overridden from Builder */ 394 public Builder findFluentSetters() { 395 super.findFluentSetters(); 396 return this; 397 } 398 399 @Override /* Overridden from Builder */ 400 public Builder findFluentSetters(Class<?> on) { 401 super.findFluentSetters(on); 402 return this; 403 } 404 405 @Override /* Overridden from Context.Builder */ 406 public HashKey hashKey() { 407 // @formatter:off 408 return HashKey.of( 409 super.hashKey(), 410 fileCharset, 411 streamCharset 412 ); 413 // @formatter:on 414 } 415 416 @Override /* Overridden from Builder */ 417 public Builder ignoreInvocationExceptionsOnGetters() { 418 super.ignoreInvocationExceptionsOnGetters(); 419 return this; 420 } 421 422 @Override /* Overridden from Builder */ 423 public Builder ignoreInvocationExceptionsOnSetters() { 424 super.ignoreInvocationExceptionsOnSetters(); 425 return this; 426 } 427 428 @Override /* Overridden from Builder */ 429 public Builder ignoreUnknownBeanProperties() { 430 super.ignoreUnknownBeanProperties(); 431 return this; 432 } 433 434 @Override /* Overridden from Builder */ 435 public Builder ignoreUnknownEnumValues() { 436 super.ignoreUnknownEnumValues(); 437 return this; 438 } 439 440 @Override /* Overridden from Builder */ 441 public Builder impl(Context value) { 442 super.impl(value); 443 return this; 444 } 445 446 @Override /* Overridden from Builder */ 447 public Builder implClass(Class<?> interfaceClass, Class<?> implClass) { 448 super.implClass(interfaceClass, implClass); 449 return this; 450 } 451 452 @Override /* Overridden from Builder */ 453 public Builder implClasses(Map<Class<?>,Class<?>> values) { 454 super.implClasses(values); 455 return this; 456 } 457 458 @Override /* Overridden from Builder */ 459 public Builder interfaceClass(Class<?> on, Class<?> value) { 460 super.interfaceClass(on, value); 461 return this; 462 } 463 464 @Override /* Overridden from Builder */ 465 public Builder interfaces(java.lang.Class<?>...value) { 466 super.interfaces(value); 467 return this; 468 } 469 470 @Override /* Overridden from Builder */ 471 public Builder listener(Class<? extends org.apache.juneau.parser.ParserListener> value) { 472 super.listener(value); 473 return this; 474 } 475 476 @Override /* Overridden from Builder */ 477 public Builder locale(Locale value) { 478 super.locale(value); 479 return this; 480 } 481 482 @Override /* Overridden from Builder */ 483 public Builder mediaType(MediaType value) { 484 super.mediaType(value); 485 return this; 486 } 487 488 @Override /* Overridden from Builder */ 489 public Builder notBeanClasses(java.lang.Class<?>...values) { 490 super.notBeanClasses(values); 491 return this; 492 } 493 494 @Override /* Overridden from Builder */ 495 public Builder notBeanPackages(String...values) { 496 super.notBeanPackages(values); 497 return this; 498 } 499 500 @Override /* Overridden from Builder */ 501 public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) { 502 super.propertyNamer(on, value); 503 return this; 504 } 505 506 @Override /* Overridden from Builder */ 507 public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) { 508 super.propertyNamer(value); 509 return this; 510 } 511 512 @Override /* Overridden from Builder */ 513 public Builder sortProperties() { 514 super.sortProperties(); 515 return this; 516 } 517 518 @Override /* Overridden from Builder */ 519 public Builder sortProperties(java.lang.Class<?>...on) { 520 super.sortProperties(on); 521 return this; 522 } 523 524 @Override /* Overridden from Builder */ 525 public Builder stopClass(Class<?> on, Class<?> value) { 526 super.stopClass(on, value); 527 return this; 528 } 529 530 /** 531 * Input stream charset. 532 * 533 * <p> 534 * The character set to use for converting <c>InputStreams</c> and byte arrays to readers. 535 * 536 * <p> 537 * Used when passing in input streams and byte arrays to {@link Parser#parse(Object, Class)}. 538 * 539 * <h5 class='section'>Example:</h5> 540 * <p class='bjava'> 541 * <jc>// Create a parser that reads UTF-8 files.</jc> 542 * ReaderParser <jv>parser</jv> = JsonParser 543 * .<jsm>create</jsm>() 544 * .streamCharset(Charset.<jsm>forName</jsm>(<js>"UTF-8"</js>)) 545 * .build(); 546 * 547 * <jc>// Use it to read a UTF-8 encoded input stream.</jc> 548 * MyBean <jv>myBean</jv> = <jv>parser</jv>.parse(<jk>new</jk> FileInputStream(<js>"MyBean.txt"</js>), MyBean.<jk>class</jk>); 549 * </p> 550 * 551 * @param value 552 * The new value for this property. 553 * <br>The default value is <js>"UTF-8"</js>. 554 * <br>Can be <jk>null</jk> (defaults to UTF-8). 555 * @return This object. 556 */ 557 public Builder streamCharset(Charset value) { 558 streamCharset = value; 559 return this; 560 } 561 562 @Override /* Overridden from Builder */ 563 public Builder strict() { 564 super.strict(); 565 return this; 566 } 567 568 @Override /* Overridden from Builder */ 569 public Builder strict(boolean value) { 570 super.strict(value); 571 return this; 572 } 573 574 @Override /* Overridden from Builder */ 575 public <T,S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) { 576 super.swap(normalClass, swappedClass, swapFunction); 577 return this; 578 } 579 580 @Override /* Overridden from Builder */ 581 public <T,S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) { 582 super.swap(normalClass, swappedClass, swapFunction, unswapFunction); 583 return this; 584 } 585 586 @Override /* Overridden from Builder */ 587 public Builder swaps(Class<?>...values) { 588 super.swaps(values); 589 return this; 590 } 591 592 @Override /* Overridden from Builder */ 593 public Builder swaps(Object...values) { 594 super.swaps(values); 595 return this; 596 } 597 598 @Override /* Overridden from Builder */ 599 public Builder timeZone(TimeZone value) { 600 super.timeZone(value); 601 return this; 602 } 603 604 @Override /* Overridden from Builder */ 605 public Builder trimStrings() { 606 super.trimStrings(); 607 return this; 608 } 609 610 @Override /* Overridden from Builder */ 611 public Builder trimStrings(boolean value) { 612 super.trimStrings(value); 613 return this; 614 } 615 616 @Override /* Overridden from Builder */ 617 public Builder type(Class<? extends org.apache.juneau.Context> value) { 618 super.type(value); 619 return this; 620 } 621 622 @Override /* Overridden from Builder */ 623 public Builder typeName(Class<?> on, String value) { 624 super.typeName(on, value); 625 return this; 626 } 627 628 @Override /* Overridden from Builder */ 629 public Builder typePropertyName(Class<?> on, String value) { 630 super.typePropertyName(on, value); 631 return this; 632 } 633 634 @Override /* Overridden from Builder */ 635 public Builder typePropertyName(String value) { 636 super.typePropertyName(value); 637 return this; 638 } 639 640 @Override /* Overridden from Builder */ 641 public Builder unbuffered() { 642 super.unbuffered(); 643 return this; 644 } 645 646 @Override /* Overridden from Builder */ 647 public Builder unbuffered(boolean value) { 648 super.unbuffered(value); 649 return this; 650 } 651 652 @Override /* Overridden from Builder */ 653 public Builder useEnumNames() { 654 super.useEnumNames(); 655 return this; 656 } 657 658 @Override /* Overridden from Builder */ 659 public Builder useJavaBeanIntrospector() { 660 super.useJavaBeanIntrospector(); 661 return this; 662 } 663 } 664 665 /** 666 * Creates a new builder for this object. 667 * 668 * @return A new builder. 669 */ 670 public static Builder create() { 671 return new Builder(); 672 } 673 674 private final Charset fileCharset; 675 private final Charset streamCharset; 676 677 /** 678 * Constructor. 679 * 680 * @param builder The builder for this object. 681 */ 682 protected ReaderParser(Builder builder) { 683 super(builder); 684 fileCharset = builder.fileCharset; 685 streamCharset = builder.streamCharset; 686 } 687 688 @Override /* Overridden from Context */ 689 public ReaderParserSession.Builder createSession() { 690 return ReaderParserSession.create(this); 691 } 692 693 @Override /* Overridden from Context */ 694 public ReaderParserSession getSession() { return createSession().build(); } 695 696 @Override /* Overridden from Parser */ 697 public final boolean isReaderParser() { return true; } 698 699 /** 700 * File charset. 701 * 702 * @see Builder#fileCharset(Charset) 703 * @return 704 * The character set to use for reading <c>Files</c> from the file system. 705 */ 706 protected final Charset getFileCharset() { return fileCharset; } 707 708 /** 709 * Input stream charset. 710 * 711 * @see Builder#streamCharset(Charset) 712 * @return 713 * The character set to use for converting <c>InputStreams</c> and byte arrays to readers. 714 */ 715 protected final Charset getStreamCharset() { return streamCharset; } 716 717 @Override /* Overridden from Parser */ 718 protected FluentMap<String,Object> properties() { 719 return super.properties() 720 .a("fileCharset", fileCharset) 721 .a("streamCharset", streamCharset); 722 } 723}