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.collections.JsonMap.*; 016import static org.apache.juneau.common.internal.StringUtils.*; 017import static org.apache.juneau.internal.CollectionUtils.*; 018 019import java.io.*; 020import java.lang.annotation.*; 021import java.lang.reflect.*; 022import java.nio.charset.*; 023import java.util.*; 024 025import org.apache.juneau.*; 026import org.apache.juneau.collections.*; 027import org.apache.juneau.html.*; 028import org.apache.juneau.internal.*; 029import org.apache.juneau.json.*; 030import org.apache.juneau.msgpack.*; 031import org.apache.juneau.objecttools.*; 032import org.apache.juneau.swap.*; 033import org.apache.juneau.swaps.*; 034import org.apache.juneau.uon.*; 035import org.apache.juneau.utils.*; 036import org.apache.juneau.xml.*; 037 038/** 039 * Parent class for all Juneau parsers. 040 * 041 * <h5 class='topic'>Valid data conversions</h5> 042 * <p> 043 * Parsers can parse any parsable POJO types, as specified in the <a class="doclink" href="../../../../index.html#jm.PojoCategories">POJO Categories</a>. 044 * 045 * <p> 046 * Some examples of conversions are shown below... 047 * </p> 048 * <table class='styled'> 049 * <tr> 050 * <th>Data type</th> 051 * <th>Class type</th> 052 * <th>JSON example</th> 053 * <th>XML example</th> 054 * <th>Class examples</th> 055 * </tr> 056 * <tr> 057 * <td>object</td> 058 * <td>Maps, Java beans</td> 059 * <td class='code'>{name:<js>'John Smith'</js>,age:21}</td> 060 * <td class='code'><xt><object> 061 * <name</xt> <xa>type</xa>=<xs>'string'</xs><xt>></xt>John Smith<xt></name> 062 * <age</xt> <xa>type</xa>=<xs>'number'</xs><xt>></xt>21<xt></age> 063 * </object></xt></td> 064 * <td class='code'>HashMap, TreeMap<String,Integer></td> 065 * </tr> 066 * <tr> 067 * <td>array</td> 068 * <td>Collections, Java arrays</td> 069 * <td class='code'>[1,2,3]</td> 070 * <td class='code'><xt><array> 071 * <number></xt>1<xt></number> 072 * <number></xt>2<xt></number> 073 * <number></xt>3<xt></number> 074 * </array></xt></td> 075 * <td class='code'>List<Integer>, <jk>int</jk>[], Float[], Set<Person></td> 076 * </tr> 077 * <tr> 078 * <td>number</td> 079 * <td>Numbers</td> 080 * <td class='code'>123</td> 081 * <td class='code'><xt><number></xt>123<xt></number></xt></td> 082 * <td class='code'>Integer, Long, Float, <jk>int</jk></td> 083 * </tr> 084 * <tr> 085 * <td>boolean</td> 086 * <td>Booleans</td> 087 * <td class='code'><jk>true</jk></td> 088 * <td class='code'><xt><boolean></xt>true<xt></boolean></xt></td> 089 * <td class='code'>Boolean</td> 090 * </tr> 091 * <tr> 092 * <td>string</td> 093 * <td>CharSequences</td> 094 * <td class='code'><js>'foobar'</js></td> 095 * <td class='code'><xt><string></xt>foobar<xt></string></xt></td> 096 * <td class='code'>String, StringBuilder</td> 097 * </tr> 098 * </table> 099 * 100 * <p> 101 * In addition, any class types with {@link ObjectSwap ObjectSwaps} associated with them on the registered 102 * bean context can also be passed in. 103 * 104 * <p> 105 * For example, if the {@link TemporalCalendarSwap} transform is used to generalize {@code Calendar} objects to {@code String} 106 * objects. 107 * When registered with this parser, you can construct {@code Calendar} objects from {@code Strings} using the 108 * following syntax... 109 * <p class='bjava'> 110 * Calendar <jv>calendar</jv> = <jv>parser</jv>.parse(<js>"'Sun Mar 03 04:05:06 EST 2001'"</js>, GregorianCalendar.<jk>class</jk>); 111 * </p> 112 * 113 * <p> 114 * If <code>Object.<jk>class</jk></code> is specified as the target type, then the parser automatically determines the 115 * data types and generates the following object types... 116 * <table class='styled'> 117 * <tr><th>JSON type</th><th>Class type</th></tr> 118 * <tr><td>object</td><td>{@link JsonMap}</td></tr> 119 * <tr><td>array</td><td>{@link JsonList}</td></tr> 120 * <tr><td>number</td><td>{@link Number}<br>(depending on length and format, could be {@link Integer}, 121 * {@link Double}, {@link Float}, etc...)</td></tr> 122 * <tr><td>boolean</td><td>{@link Boolean}</td></tr> 123 * <tr><td>string</td><td>{@link String}</td></tr> 124 * </table> 125 * 126 * <h5 class='section'>Notes:</h5><ul> 127 * <li class='note'>This class is thread safe and reusable. 128 * </ul> 129 * 130 * <h5 class='section'>See Also:</h5><ul> 131 * <li class='link'><a class="doclink" href="../../../../index.html#jm.SerializersAndParsers">Serializers and Parsers</a> 132 133 * </ul> 134 */ 135public class Parser extends BeanContextable { 136 137 //------------------------------------------------------------------------------------------------------------------- 138 // Static 139 //------------------------------------------------------------------------------------------------------------------- 140 141 /** 142 * Creates a new builder for this object. 143 * 144 * @return A new builder. 145 */ 146 public static Builder create() { 147 return new Builder(); 148 } 149 150 //------------------------------------------------------------------------------------------------------------------- 151 // Static 152 //------------------------------------------------------------------------------------------------------------------- 153 154 /** 155 * Represents no Parser. 156 */ 157 public static abstract class Null extends Parser { 158 private Null(Builder builder) { 159 super(builder); 160 } 161 } 162 163 /** 164 * Instantiates a builder of the specified parser class. 165 * 166 * <p> 167 * Looks for a public static method called <c>create</c> that returns an object that can be passed into a public 168 * or protected constructor of the class. 169 * 170 * @param c The builder to create. 171 * @return A new builder. 172 */ 173 public static Builder createParserBuilder(Class<? extends Parser> c) { 174 return (Builder)Context.createBuilder(c); 175 } 176 177 //------------------------------------------------------------------------------------------------------------------- 178 // Builder 179 //------------------------------------------------------------------------------------------------------------------- 180 181 /** 182 * Builder class. 183 */ 184 @FluentSetters 185 public static class Builder extends BeanContextable.Builder { 186 187 boolean autoCloseStreams, strict, trimStrings, unbuffered; 188 String consumes; 189 int debugOutputLines; 190 Class<? extends ParserListener> listener; 191 192 /** 193 * Constructor, default settings. 194 */ 195 protected Builder() { 196 super(); 197 autoCloseStreams = env("Parser.autoCloseStreams", false); 198 strict = env("Parser.strict", false); 199 trimStrings = env("Parser.trimStrings", false); 200 unbuffered = env("Parser.unbuffered", false); 201 debugOutputLines = env("Parser.debugOutputLines", 5); 202 listener = null; 203 consumes = null; 204 } 205 206 /** 207 * Copy constructor. 208 * 209 * @param copyFrom The bean to copy from. 210 */ 211 protected Builder(Parser copyFrom) { 212 super(copyFrom); 213 autoCloseStreams = copyFrom.autoCloseStreams; 214 strict = copyFrom.strict; 215 trimStrings = copyFrom.trimStrings; 216 unbuffered = copyFrom.unbuffered; 217 debugOutputLines = copyFrom.debugOutputLines; 218 listener = copyFrom.listener; 219 consumes = copyFrom.consumes; 220 } 221 222 /** 223 * Copy constructor. 224 * 225 * @param copyFrom The builder to copy from. 226 */ 227 protected Builder(Builder copyFrom) { 228 super(copyFrom); 229 autoCloseStreams = copyFrom.autoCloseStreams; 230 strict = copyFrom.strict; 231 trimStrings = copyFrom.trimStrings; 232 unbuffered = copyFrom.unbuffered; 233 debugOutputLines = copyFrom.debugOutputLines; 234 listener = copyFrom.listener; 235 consumes = copyFrom.consumes; 236 } 237 238 @Override /* Context.Builder */ 239 public Builder copy() { 240 return new Builder(this); 241 } 242 243 @Override /* Context.Builder */ 244 public Parser build() { 245 return build(Parser.class); 246 } 247 248 @Override /* Context.Builder */ 249 public HashKey hashKey() { 250 return HashKey.of( 251 super.hashKey(), 252 autoCloseStreams, 253 strict, 254 trimStrings, 255 unbuffered, 256 debugOutputLines, 257 listener, 258 consumes 259 ); 260 } 261 262 //----------------------------------------------------------------------------------------------------------------- 263 // Properties 264 //----------------------------------------------------------------------------------------------------------------- 265 266 /** 267 * Specifies the media type that this parser consumes. 268 * 269 * @param value The value for this setting. 270 * @return This object. 271 */ 272 @FluentSetter 273 public Builder consumes(String value) { 274 this.consumes = value; 275 return this; 276 } 277 278 /** 279 * Returns the current value for the 'consumes' property. 280 * 281 * @return The current value for the 'consumes' property. 282 */ 283 public String getConsumes() { 284 return consumes; 285 } 286 287 /** 288 * Auto-close streams. 289 * 290 * <p> 291 * When enabled, <l>InputStreams</l> and <l>Readers</l> passed into parsers will be closed 292 * after parsing is complete. 293 * 294 * <h5 class='section'>Example:</h5> 295 * <p class='bjava'> 296 * <jc>// Create a parser using strict mode.</jc> 297 * ReaderParser <jv>parser</jv> = JsonParser 298 * .<jsm>create</jsm>() 299 * .autoCloseStreams() 300 * .build(); 301 * 302 * Reader <jv>myReader</jv> = <jk>new</jk> FileReader(<js>"/tmp/myfile.json"</js>); 303 * MyBean <jv>myBean</jv> = <jv>parser</jv>.parse(<jv>myReader</jv>, MyBean.<jk>class</jk>); 304 * 305 * <jsm>assertTrue</jsm>(<jv>myReader</jv>.isClosed()); 306 * </p> 307 * 308 * @return This object. 309 */ 310 @FluentSetter 311 public Builder autoCloseStreams() { 312 return autoCloseStreams(true); 313 } 314 315 /** 316 * Same as {@link #autoCloseStreams()} but allows you to explicitly specify the value. 317 * 318 * @param value The value for this setting. 319 * @return This object. 320 */ 321 @FluentSetter 322 public Builder autoCloseStreams(boolean value) { 323 autoCloseStreams = value; 324 return this; 325 } 326 327 /** 328 * Debug output lines. 329 * 330 * <p> 331 * When parse errors occur, this specifies the number of lines of input before and after the 332 * error location to be printed as part of the exception message. 333 * 334 * <h5 class='section'>Example:</h5> 335 * <p class='bjava'> 336 * <jc>// Create a parser whose exceptions print out 100 lines before and after the parse error location.</jc> 337 * ReaderParser <jv>parser</jv> = JsonParser 338 * .<jsm>create</jsm>() 339 * .debug() <jc>// Enable debug mode to capture Reader contents as strings.</jc> 340 * .debugOuputLines(100) 341 * .build(); 342 * 343 * Reader <jv>myReader</jv> = <jk>new</jk> FileReader(<js>"/tmp/mybadfile.json"</js>); 344 * <jk>try</jk> { 345 * <jv>parser</jv>.parse(<jv>myReader</jv>, Object.<jk>class</jk>); 346 * } <jk>catch</jk> (ParseException <jv>e</jv>) { 347 * System.<jsf>err</jsf>.println(<jv>e</jv>.getMessage()); <jc>// Will display 200 lines of the output.</jc> 348 * } 349 * </p> 350 * 351 * @param value 352 * The new value for this property. 353 * <br>The default value is <c>5</c>. 354 * @return This object. 355 */ 356 @FluentSetter 357 public Builder debugOutputLines(int value) { 358 debugOutputLines = value; 359 return this; 360 } 361 362 /** 363 * Parser listener. 364 * 365 * <p> 366 * Class used to listen for errors and warnings that occur during parsing. 367 * 368 * <h5 class='section'>Example:</h5> 369 * <p class='bjava'> 370 * <jc>// Define our parser listener.</jc> 371 * <jc>// Simply captures all unknown bean property events.</jc> 372 * <jk>public class</jk> MyParserListener <jk>extends</jk> ParserListener { 373 * 374 * <jc>// A simple property to store our events.</jc> 375 * <jk>public</jk> List<String> <jf>events</jf> = <jk>new</jk> LinkedList<>(); 376 * 377 * <ja>@Override</ja> 378 * <jk>public</jk> <T> <jk>void</jk> onUnknownBeanProperty(ParserSession <jv>session</jv>, String <jv>propertyName</jv>, Class<T> <jv>beanClass</jv>, T <jv>bean</jv>) { 379 * Position <jv>position</jv> = <jv>parser</jv>.getPosition(); 380 * <jf>events</jf>.add(<jv>propertyName</jv> + <js>","</js> + <jv>position</jv>.getLine() + <js>","</js> + <jv>position</jv>.getColumn()); 381 * } 382 * } 383 * 384 * <jc>// Create a parser using our listener.</jc> 385 * ReaderParser <jv>parser</jv> = JsonParser 386 * .<jsm>create</jsm>() 387 * .listener(MyParserListener.<jk>class</jk>) 388 * .build(); 389 * 390 * <jc>// Create a session object.</jc> 391 * <jc>// Needed because listeners are created per-session.</jc> 392 * <jk>try</jk> (ReaderParserSession <jv>session</jv> = <jv>parser</jv>.createSession()) { 393 * 394 * <jc>// Parse some JSON object.</jc> 395 * MyBean <jv>myBean</jv> = <jv>session</jv>.parse(<js>"{...}"</js>, MyBean.<jk>class</jk>); 396 * 397 * <jc>// Get the listener.</jc> 398 * MyParserListener <jv>listener</jv> = <jv>session</jv>.getListener(MyParserListener.<jk>class</jk>); 399 * 400 * <jc>// Dump the results to the console.</jc> 401 * Json5.<jsf>DEFAULT</jsf>.println(<jv>listener</jv>.<jf>events</jf>); 402 * } 403 * </p> 404 * 405 * @param value The new value for this property. 406 * @return This object. 407 */ 408 @FluentSetter 409 public Builder listener(Class<? extends ParserListener> value) { 410 listener = value; 411 return this; 412 } 413 414 /** 415 * Strict mode. 416 * 417 * <p> 418 * When enabled, strict mode for the parser is enabled. 419 * 420 * <p> 421 * Strict mode can mean different things for different parsers. 422 * 423 * <table class='styled'> 424 * <tr><th>Parser class</th><th>Strict behavior</th></tr> 425 * <tr> 426 * <td>All reader-based parsers</td> 427 * <td> 428 * When enabled, throws {@link ParseException ParseExceptions} on malformed charset input. 429 * Otherwise, malformed input is ignored. 430 * </td> 431 * </tr> 432 * <tr> 433 * <td>{@link JsonParser}</td> 434 * <td> 435 * When enabled, throws exceptions on the following invalid JSON syntax: 436 * <ul> 437 * <li>Unquoted attributes. 438 * <li>Missing attribute values. 439 * <li>Concatenated strings. 440 * <li>Javascript comments. 441 * <li>Numbers and booleans when Strings are expected. 442 * <li>Numbers valid in Java but not JSON (e.g. octal notation, etc...) 443 * </ul> 444 * </td> 445 * </tr> 446 * </table> 447 * 448 * <h5 class='section'>Example:</h5> 449 * <p class='bjava'> 450 * <jc>// Create a parser using strict mode.</jc> 451 * ReaderParser <jv>parser</jv> = JsonParser 452 * .<jsm>create</jsm>() 453 * .strict() 454 * .build(); 455 * 456 * <jc>// Use it.</jc> 457 * <jk>try</jk> { 458 * String <jv>json</jv> = <js>"{unquotedAttr:'value'}"</js>; 459 * <jv>parser</jv>.parse(<jv>json</jv>, MyBean.<jk>class</jk>); 460 * } <jk>catch</jk> (ParseException <jv>e</jv>) { 461 * <jsm>assertTrue</jsm>(<jv>e</jv>.getMessage().contains(<js>"Unquoted attribute detected."</js>); 462 * } 463 * </p> 464 * 465 * @return This object. 466 */ 467 @FluentSetter 468 public Builder strict() { 469 return strict(true); 470 } 471 472 /** 473 * Same as {@link #strict()} but allows you to explicitly specify the value. 474 * 475 * @param value The value for this setting. 476 * @return This object. 477 */ 478 @FluentSetter 479 public Builder strict(boolean value) { 480 strict = value; 481 return this; 482 } 483 484 /** 485 * Trim parsed strings. 486 * 487 * <p> 488 * When enabled, string values will be trimmed of whitespace using {@link String#trim()} before being added to 489 * the POJO. 490 * 491 * <h5 class='section'>Example:</h5> 492 * <p class='bjava'> 493 * <jc>// Create a parser with trim-strings enabled.</jc> 494 * ReaderParser <jv>parser</jv> = JsonParser 495 * .<jsm>create</jsm>() 496 * .trimStrings() 497 * .build(); 498 * 499 * <jc>// Use it.</jc> 500 * String <jv>json</jv> = <js>"{' foo ':' bar '}"</js>; 501 * Map<String,String> <jv>myMap</jv> = <jv>parser</jv>.parse(<jv>json</jv>, HashMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>); 502 * 503 * <jc>// Make sure strings are parsed.</jc> 504 * <jsm>assertEquals</jsm>(<js>"bar"</js>, <jv>myMap</jv>.get(<js>"foo"</js>)); 505 * </p> 506 * 507 * @return This object. 508 */ 509 @FluentSetter 510 public Builder trimStrings() { 511 return trimStrings(true); 512 } 513 514 /** 515 * Same as {@link #trimStrings()} but allows you to explicitly specify the value. 516 * 517 * @param value The value for this setting. 518 * @return This object. 519 */ 520 @FluentSetter 521 public Builder trimStrings(boolean value) { 522 trimStrings = value; 523 return this; 524 } 525 526 /** 527 * Unbuffered. 528 * 529 * <p> 530 * When enabled, don't use internal buffering during parsing. 531 * 532 * <p> 533 * This is useful in cases when you want to parse the same input stream or reader multiple times 534 * because it may contain multiple independent POJOs to parse. 535 * <br>Buffering would cause the parser to read past the current POJO in the stream. 536 * 537 * <h5 class='section'>Example:</h5> 538 * <p class='bjava'> 539 * <jc>// Create a parser using strict mode.</jc> 540 * ReaderParser <jv>parser</jv> = JsonParser. 541 * .<jsm>create</jsm>() 542 * .unbuffered(<jk>true</jk>) 543 * .build(); 544 * 545 * <jc>// If you're calling parse on the same input multiple times, use a session instead of the parser directly.</jc> 546 * <jc>// It's more efficient because we don't need to recalc the session settings again. </jc> 547 * ReaderParserSession <jv>session</jv> = <jv>parser</jv>.createSession(); 548 * 549 * <jc>// Read input with multiple POJOs</jc> 550 * Reader <jv>json</jv> = <jk>new</jk> StringReader(<js>"{foo:'bar'}{foo:'baz'}"</js>); 551 * MyBean <jv>myBean1</jv> = <jv>session</jv>.parse(<jv>json</jv>, MyBean.<jk>class</jk>); 552 * MyBean <jv>myBean2</jv> = <jv>session</jv>.parse(<jv>json</jv>, MyBean.<jk>class</jk>); 553 * </p> 554 * 555 * <h5 class='section'>Notes:</h5><ul> 556 * <li class='note'> 557 * This only allows for multi-input streams for the following parsers: 558 * <ul> 559 * <li class='jc'>{@link JsonParser} 560 * <li class='jc'>{@link UonParser} 561 * </ul> 562 * It has no effect on the following parsers: 563 * <ul> 564 * <li class='jc'>{@link MsgPackParser} - It already doesn't use buffering. 565 * <li class='jc'>{@link XmlParser}, {@link HtmlParser} - These use StAX which doesn't allow for more than one root element anyway. 566 * <li>RDF parsers - These read everything into an internal model before any parsing begins. 567 * </ul> 568 * </ul> 569 * 570 * @return This object. 571 */ 572 @FluentSetter 573 public Builder unbuffered() { 574 return unbuffered(true); 575 } 576 577 /** 578 * Same as {@link #unbuffered()} but allows you to explicitly specify the value. 579 * 580 * @param value The value for this setting. 581 * @return This object. 582 */ 583 @FluentSetter 584 public Builder unbuffered(boolean value) { 585 unbuffered = value; 586 return this; 587 } 588 589 // <FluentSetters> 590 591 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 592 public Builder annotations(Annotation...values) { 593 super.annotations(values); 594 return this; 595 } 596 597 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 598 public Builder apply(AnnotationWorkList work) { 599 super.apply(work); 600 return this; 601 } 602 603 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 604 public Builder applyAnnotations(java.lang.Class<?>...fromClasses) { 605 super.applyAnnotations(fromClasses); 606 return this; 607 } 608 609 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 610 public Builder applyAnnotations(Method...fromMethods) { 611 super.applyAnnotations(fromMethods); 612 return this; 613 } 614 615 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 616 public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) { 617 super.cache(value); 618 return this; 619 } 620 621 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 622 public Builder debug() { 623 super.debug(); 624 return this; 625 } 626 627 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 628 public Builder debug(boolean value) { 629 super.debug(value); 630 return this; 631 } 632 633 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 634 public Builder impl(Context value) { 635 super.impl(value); 636 return this; 637 } 638 639 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 640 public Builder type(Class<? extends org.apache.juneau.Context> value) { 641 super.type(value); 642 return this; 643 } 644 645 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 646 public Builder beanClassVisibility(Visibility value) { 647 super.beanClassVisibility(value); 648 return this; 649 } 650 651 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 652 public Builder beanConstructorVisibility(Visibility value) { 653 super.beanConstructorVisibility(value); 654 return this; 655 } 656 657 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 658 public Builder beanContext(BeanContext value) { 659 super.beanContext(value); 660 return this; 661 } 662 663 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 664 public Builder beanContext(BeanContext.Builder value) { 665 super.beanContext(value); 666 return this; 667 } 668 669 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 670 public Builder beanDictionary(java.lang.Class<?>...values) { 671 super.beanDictionary(values); 672 return this; 673 } 674 675 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 676 public Builder beanFieldVisibility(Visibility value) { 677 super.beanFieldVisibility(value); 678 return this; 679 } 680 681 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 682 public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) { 683 super.beanInterceptor(on, value); 684 return this; 685 } 686 687 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 688 public Builder beanMapPutReturnsOldValue() { 689 super.beanMapPutReturnsOldValue(); 690 return this; 691 } 692 693 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 694 public Builder beanMethodVisibility(Visibility value) { 695 super.beanMethodVisibility(value); 696 return this; 697 } 698 699 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 700 public Builder beanProperties(Map<String,Object> values) { 701 super.beanProperties(values); 702 return this; 703 } 704 705 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 706 public Builder beanProperties(Class<?> beanClass, String properties) { 707 super.beanProperties(beanClass, properties); 708 return this; 709 } 710 711 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 712 public Builder beanProperties(String beanClassName, String properties) { 713 super.beanProperties(beanClassName, properties); 714 return this; 715 } 716 717 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 718 public Builder beanPropertiesExcludes(Map<String,Object> values) { 719 super.beanPropertiesExcludes(values); 720 return this; 721 } 722 723 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 724 public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) { 725 super.beanPropertiesExcludes(beanClass, properties); 726 return this; 727 } 728 729 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 730 public Builder beanPropertiesExcludes(String beanClassName, String properties) { 731 super.beanPropertiesExcludes(beanClassName, properties); 732 return this; 733 } 734 735 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 736 public Builder beanPropertiesReadOnly(Map<String,Object> values) { 737 super.beanPropertiesReadOnly(values); 738 return this; 739 } 740 741 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 742 public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) { 743 super.beanPropertiesReadOnly(beanClass, properties); 744 return this; 745 } 746 747 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 748 public Builder beanPropertiesReadOnly(String beanClassName, String properties) { 749 super.beanPropertiesReadOnly(beanClassName, properties); 750 return this; 751 } 752 753 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 754 public Builder beanPropertiesWriteOnly(Map<String,Object> values) { 755 super.beanPropertiesWriteOnly(values); 756 return this; 757 } 758 759 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 760 public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) { 761 super.beanPropertiesWriteOnly(beanClass, properties); 762 return this; 763 } 764 765 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 766 public Builder beanPropertiesWriteOnly(String beanClassName, String properties) { 767 super.beanPropertiesWriteOnly(beanClassName, properties); 768 return this; 769 } 770 771 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 772 public Builder beansRequireDefaultConstructor() { 773 super.beansRequireDefaultConstructor(); 774 return this; 775 } 776 777 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 778 public Builder beansRequireSerializable() { 779 super.beansRequireSerializable(); 780 return this; 781 } 782 783 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 784 public Builder beansRequireSettersForGetters() { 785 super.beansRequireSettersForGetters(); 786 return this; 787 } 788 789 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 790 public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) { 791 super.dictionaryOn(on, values); 792 return this; 793 } 794 795 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 796 public Builder disableBeansRequireSomeProperties() { 797 super.disableBeansRequireSomeProperties(); 798 return this; 799 } 800 801 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 802 public Builder disableIgnoreMissingSetters() { 803 super.disableIgnoreMissingSetters(); 804 return this; 805 } 806 807 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 808 public Builder disableIgnoreTransientFields() { 809 super.disableIgnoreTransientFields(); 810 return this; 811 } 812 813 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 814 public Builder disableIgnoreUnknownNullBeanProperties() { 815 super.disableIgnoreUnknownNullBeanProperties(); 816 return this; 817 } 818 819 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 820 public Builder disableInterfaceProxies() { 821 super.disableInterfaceProxies(); 822 return this; 823 } 824 825 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 826 public <T> Builder example(Class<T> pojoClass, T o) { 827 super.example(pojoClass, o); 828 return this; 829 } 830 831 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 832 public <T> Builder example(Class<T> pojoClass, String json) { 833 super.example(pojoClass, json); 834 return this; 835 } 836 837 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 838 public Builder findFluentSetters() { 839 super.findFluentSetters(); 840 return this; 841 } 842 843 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 844 public Builder findFluentSetters(Class<?> on) { 845 super.findFluentSetters(on); 846 return this; 847 } 848 849 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 850 public Builder ignoreInvocationExceptionsOnGetters() { 851 super.ignoreInvocationExceptionsOnGetters(); 852 return this; 853 } 854 855 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 856 public Builder ignoreInvocationExceptionsOnSetters() { 857 super.ignoreInvocationExceptionsOnSetters(); 858 return this; 859 } 860 861 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 862 public Builder ignoreUnknownBeanProperties() { 863 super.ignoreUnknownBeanProperties(); 864 return this; 865 } 866 867 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 868 public Builder ignoreUnknownEnumValues() { 869 super.ignoreUnknownEnumValues(); 870 return this; 871 } 872 873 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 874 public Builder implClass(Class<?> interfaceClass, Class<?> implClass) { 875 super.implClass(interfaceClass, implClass); 876 return this; 877 } 878 879 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 880 public Builder implClasses(Map<Class<?>,Class<?>> values) { 881 super.implClasses(values); 882 return this; 883 } 884 885 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 886 public Builder interfaceClass(Class<?> on, Class<?> value) { 887 super.interfaceClass(on, value); 888 return this; 889 } 890 891 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 892 public Builder interfaces(java.lang.Class<?>...value) { 893 super.interfaces(value); 894 return this; 895 } 896 897 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 898 public Builder locale(Locale value) { 899 super.locale(value); 900 return this; 901 } 902 903 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 904 public Builder mediaType(MediaType value) { 905 super.mediaType(value); 906 return this; 907 } 908 909 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 910 public Builder notBeanClasses(java.lang.Class<?>...values) { 911 super.notBeanClasses(values); 912 return this; 913 } 914 915 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 916 public Builder notBeanPackages(String...values) { 917 super.notBeanPackages(values); 918 return this; 919 } 920 921 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 922 public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) { 923 super.propertyNamer(value); 924 return this; 925 } 926 927 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 928 public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) { 929 super.propertyNamer(on, value); 930 return this; 931 } 932 933 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 934 public Builder sortProperties() { 935 super.sortProperties(); 936 return this; 937 } 938 939 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 940 public Builder sortProperties(java.lang.Class<?>...on) { 941 super.sortProperties(on); 942 return this; 943 } 944 945 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 946 public Builder stopClass(Class<?> on, Class<?> value) { 947 super.stopClass(on, value); 948 return this; 949 } 950 951 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 952 public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) { 953 super.swap(normalClass, swappedClass, swapFunction); 954 return this; 955 } 956 957 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 958 public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) { 959 super.swap(normalClass, swappedClass, swapFunction, unswapFunction); 960 return this; 961 } 962 963 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 964 public Builder swaps(java.lang.Class<?>...values) { 965 super.swaps(values); 966 return this; 967 } 968 969 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 970 public Builder timeZone(TimeZone value) { 971 super.timeZone(value); 972 return this; 973 } 974 975 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 976 public Builder typeName(Class<?> on, String value) { 977 super.typeName(on, value); 978 return this; 979 } 980 981 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 982 public Builder typePropertyName(String value) { 983 super.typePropertyName(value); 984 return this; 985 } 986 987 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 988 public Builder typePropertyName(Class<?> on, String value) { 989 super.typePropertyName(on, value); 990 return this; 991 } 992 993 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 994 public Builder useEnumNames() { 995 super.useEnumNames(); 996 return this; 997 } 998 999 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1000 public Builder useJavaBeanIntrospector() { 1001 super.useJavaBeanIntrospector(); 1002 return this; 1003 } 1004 1005 // </FluentSetters> 1006 } 1007 //------------------------------------------------------------------------------------------------------------------- 1008 // Instance 1009 //------------------------------------------------------------------------------------------------------------------- 1010 1011 final boolean trimStrings, strict, autoCloseStreams, unbuffered; 1012 final int debugOutputLines; 1013 final String consumes; 1014 final Class<? extends ParserListener> listener; 1015 1016 /** General parser properties currently set on this parser. */ 1017 private final MediaType[] consumesArray; 1018 1019 /** 1020 * Constructor. 1021 * 1022 * @param builder The builder this object. 1023 */ 1024 protected Parser(Builder builder) { 1025 super(builder); 1026 1027 consumes = builder.consumes; 1028 trimStrings = builder.trimStrings; 1029 strict = builder.strict; 1030 autoCloseStreams = builder.autoCloseStreams; 1031 debugOutputLines = builder.debugOutputLines; 1032 unbuffered = builder.unbuffered; 1033 listener = builder.listener; 1034 1035 String[] _consumes = split(consumes != null ? consumes : ""); 1036 this.consumesArray = new MediaType[_consumes.length]; 1037 for (int i = 0; i < _consumes.length; i++) { 1038 this.consumesArray[i] = MediaType.of(_consumes[i]); 1039 } 1040 } 1041 1042 @Override /* Context */ 1043 public Builder copy() { 1044 return new Builder(this); 1045 } 1046 1047 //----------------------------------------------------------------------------------------------------------------- 1048 // Abstract methods 1049 //----------------------------------------------------------------------------------------------------------------- 1050 1051 /** 1052 * Returns <jk>true</jk> if this parser subclasses from {@link ReaderParser}. 1053 * 1054 * @return <jk>true</jk> if this parser subclasses from {@link ReaderParser}. 1055 */ 1056 public boolean isReaderParser() { 1057 return true; 1058 } 1059 1060 //----------------------------------------------------------------------------------------------------------------- 1061 // Other methods 1062 //----------------------------------------------------------------------------------------------------------------- 1063 1064 /** 1065 * Parses input into the specified object type. 1066 * 1067 * <p> 1068 * The type can be a simple type (e.g. beans, strings, numbers) or parameterized type (collections/maps). 1069 * 1070 * <h5 class='section'>Examples:</h5> 1071 * <p class='bjava'> 1072 * ReaderParser <jv>parser</jv> = JsonParser.<jsf>DEFAULT</jsf>; 1073 * 1074 * <jc>// Parse into a linked-list of strings.</jc> 1075 * List <jv>list1</jv> = <jv>parser</jv>.parse(<jv>json</jv>, LinkedList.<jk>class</jk>, String.<jk>class</jk>); 1076 * 1077 * <jc>// Parse into a linked-list of beans.</jc> 1078 * List <jv>list2</jv> = <jv>parser</jv>.parse(<jv>json</jv>, LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>); 1079 * 1080 * <jc>// Parse into a linked-list of linked-lists of strings.</jc> 1081 * List <jv>list3</jv> = <jv>parser</jv>.parse(<jv>json</jv>, LinkedList.<jk>class</jk>, LinkedList.<jk>class</jk>, String.<jk>class</jk>); 1082 * 1083 * <jc>// Parse into a map of string keys/values.</jc> 1084 * Map <jv>map1</jv> = <jv>parser</jv>.parse(<jv>json</jv>, TreeMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>); 1085 * 1086 * <jc>// Parse into a map containing string keys and values of lists containing beans.</jc> 1087 * Map <jv>map2</jv> = <jv>parser</jv>.parse(<jv>json</jv>, TreeMap.<jk>class</jk>, String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>); 1088 * </p> 1089 * 1090 * <p> 1091 * <c>Collection</c> classes are assumed to be followed by zero or one objects indicating the element type. 1092 * 1093 * <p> 1094 * <c>Map</c> classes are assumed to be followed by zero or two meta objects indicating the key and value types. 1095 * 1096 * <p> 1097 * The array can be arbitrarily long to indicate arbitrarily complex data structures. 1098 * 1099 * <h5 class='section'>Notes:</h5><ul> 1100 * <li class='note'> 1101 * Use the {@link #parse(Object, Class)} method instead if you don't need a parameterized map/collection. 1102 * </ul> 1103 * 1104 * @param <T> The class type of the object to create. 1105 * @param input 1106 * The input. 1107 * <br>Character-based parsers can handle the following input class types: 1108 * <ul> 1109 * <li><jk>null</jk> 1110 * <li>{@link Reader} 1111 * <li>{@link CharSequence} 1112 * <li>{@link InputStream} containing UTF-8 encoded text (or charset defined by 1113 * {@link ReaderParser.Builder#streamCharset(Charset)} property value). 1114 * <li><code><jk>byte</jk>[]</code> containing UTF-8 encoded text (or charset defined by 1115 * {@link ReaderParser.Builder#streamCharset(Charset)} property value). 1116 * <li>{@link File} containing system encoded text (or charset defined by 1117 * {@link ReaderParser.Builder#fileCharset(Charset)} property value). 1118 * </ul> 1119 * <br>Stream-based parsers can handle the following input class types: 1120 * <ul> 1121 * <li><jk>null</jk> 1122 * <li>{@link InputStream} 1123 * <li><code><jk>byte</jk>[]</code> 1124 * <li>{@link File} 1125 * <li>{@link CharSequence} containing encoded bytes according to the {@link InputStreamParser.Builder#binaryFormat(BinaryFormat)} setting. 1126 * </ul> 1127 * @param type 1128 * The object type to create. 1129 * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} 1130 * @param args 1131 * The type arguments of the class if it's a collection or map. 1132 * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} 1133 * <br>Ignored if the main type is not a map or collection. 1134 * @return The parsed object. 1135 * @throws ParseException Malformed input encountered. 1136 * @throws IOException Thrown by underlying stream. 1137 * @see BeanSession#getClassMeta(Type,Type...) for argument syntax for maps and collections. 1138 */ 1139 public final <T> T parse(Object input, Type type, Type...args) throws ParseException, IOException { 1140 return getSession().parse(input, type, args); 1141 } 1142 1143 /** 1144 * Same as {@link #parse(Object, Type, Type...)} but since it's a {@link String} input doesn't throw an {@link IOException}. 1145 * 1146 * @param <T> The class type of the object being created. 1147 * @param input 1148 * The input. 1149 * See {@link #parse(Object, Type, Type...)} for details. 1150 * @param type 1151 * The object type to create. 1152 * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} 1153 * @param args 1154 * The type arguments of the class if it's a collection or map. 1155 * <br>Can be any of the following: {@link ClassMeta}, {@link Class}, {@link ParameterizedType}, {@link GenericArrayType} 1156 * <br>Ignored if the main type is not a map or collection. 1157 * @return The parsed object. 1158 * @throws ParseException Malformed input encountered. 1159 */ 1160 public final <T> T parse(String input, Type type, Type...args) throws ParseException { 1161 return getSession().parse(input, type, args); 1162 } 1163 1164 /** 1165 * Same as {@link #parse(Object, Type, Type...)} except optimized for a non-parameterized class. 1166 * 1167 * <p> 1168 * This is the preferred parse method for simple types since you don't need to cast the results. 1169 * 1170 * <h5 class='section'>Examples:</h5> 1171 * <p class='bjava'> 1172 * ReaderParser <jv>parser</jv> = JsonParser.<jsf>DEFAULT</jsf>; 1173 * 1174 * <jc>// Parse into a string.</jc> 1175 * String <jv>string</jv> = <jv>parser</jv>.parse(<jv>json</jv>, String.<jk>class</jk>); 1176 * 1177 * <jc>// Parse into a bean.</jc> 1178 * MyBean <jv>bean</jv> = <jv>parser</jv>.parse(<jv>json</jv>, MyBean.<jk>class</jk>); 1179 * 1180 * <jc>// Parse into a bean array.</jc> 1181 * MyBean[] <jv>beanArray</jv> = <jv>parser</jv>.parse(<jv>json</jv>, MyBean[].<jk>class</jk>); 1182 * 1183 * <jc>// Parse into a linked-list of objects.</jc> 1184 * List <jv>list</jv> = <jv>parser</jv>.parse(<jv>json</jv>, LinkedList.<jk>class</jk>); 1185 * 1186 * <jc>// Parse into a map of object keys/values.</jc> 1187 * Map <jv>map</jv> = <jv>parser</jv>.parse(<jv>json</jv>, TreeMap.<jk>class</jk>); 1188 * </p> 1189 * 1190 * @param <T> The class type of the object being created. 1191 * @param input 1192 * The input. 1193 * See {@link #parse(Object, Type, Type...)} for details. 1194 * @param type The object type to create. 1195 * @return The parsed object. 1196 * @throws ParseException Malformed input encountered. 1197 * @throws IOException Thrown by the underlying stream. 1198 */ 1199 public final <T> T parse(Object input, Class<T> type) throws ParseException, IOException { 1200 return getSession().parse(input, type); 1201 } 1202 1203 /** 1204 * Same as {@link #parse(Object, Class)} but since it's a {@link String} input doesn't throw an {@link IOException}. 1205 * 1206 * @param <T> The class type of the object being created. 1207 * @param input 1208 * The input. 1209 * See {@link #parse(Object, Type, Type...)} for details. 1210 * @param type The object type to create. 1211 * @return The parsed object. 1212 * @throws ParseException Malformed input encountered. 1213 */ 1214 public final <T> T parse(String input, Class<T> type) throws ParseException { 1215 return getSession().parse(input, type); 1216 } 1217 1218 /** 1219 * Same as {@link #parse(Object, Type, Type...)} except the type has already been converted into a {@link ClassMeta} 1220 * object. 1221 * 1222 * <p> 1223 * This is mostly an internal method used by the framework. 1224 * 1225 * @param <T> The class type of the object being created. 1226 * @param input 1227 * The input. 1228 * See {@link #parse(Object, Type, Type...)} for details. 1229 * @param type The object type to create. 1230 * @return The parsed object. 1231 * @throws ParseException Malformed input encountered. 1232 * @throws IOException Thrown by the underlying stream. 1233 */ 1234 public final <T> T parse(Object input, ClassMeta<T> type) throws ParseException, IOException { 1235 return getSession().parse(input, type); 1236 } 1237 1238 /** 1239 * Same as {@link #parse(Object, ClassMeta)} but since it's a {@link String} input doesn't throw an {@link IOException}. 1240 * 1241 * @param <T> The class type of the object being created. 1242 * @param input 1243 * The input. 1244 * See {@link #parse(Object, Type, Type...)} for details. 1245 * @param type The object type to create. 1246 * @return The parsed object. 1247 * @throws ParseException Malformed input encountered. 1248 */ 1249 public final <T> T parse(String input, ClassMeta<T> type) throws ParseException { 1250 return getSession().parse(input, type); 1251 } 1252 1253 @Override /* Context */ 1254 public ParserSession.Builder createSession() { 1255 return ParserSession.create(this); 1256 } 1257 1258 @Override /* Context */ 1259 public ParserSession getSession() { 1260 return createSession().build(); 1261 } 1262 1263 /** 1264 * Workhorse method. 1265 * 1266 * <p> 1267 * Subclasses are expected to either implement this method or {@link ParserSession#doParse(ParserPipe, ClassMeta)}. 1268 * 1269 * @param session The current session. 1270 * @param pipe Where to get the input from. 1271 * @param type 1272 * The class type of the object to create. 1273 * If <jk>null</jk> or <code>Object.<jk>class</jk></code>, object type is based on what's being parsed. 1274 * For example, when parsing JSON text, it may return a <c>String</c>, <c>Number</c>, 1275 * <c>JsonMap</c>, etc... 1276 * @param <T> The class type of the object to create. 1277 * @return The parsed object. 1278 * @throws IOException Thrown by underlying stream. 1279 * @throws ParseException Malformed input encountered. 1280 * @throws ExecutableException Exception occurred on invoked constructor/method/field. 1281 */ 1282 public <T> T doParse(ParserSession session, ParserPipe pipe, ClassMeta<T> type) throws IOException, ParseException { 1283 throw new UnsupportedOperationException(); 1284 } 1285 1286 //----------------------------------------------------------------------------------------------------------------- 1287 // Optional methods 1288 //----------------------------------------------------------------------------------------------------------------- 1289 1290 /** 1291 * Parses the contents of the specified reader and loads the results into the specified map. 1292 * 1293 * <p> 1294 * Reader must contain something that serializes to a map (such as text containing a JSON object). 1295 * 1296 * <p> 1297 * Used in the following locations: 1298 * <ul class='spaced-list'> 1299 * <li> 1300 * The various character-based constructors in {@link JsonMap} (e.g. 1301 * {@link JsonMap#JsonMap(CharSequence,Parser)}). 1302 * </ul> 1303 * 1304 * @param <K> The key class type. 1305 * @param <V> The value class type. 1306 * @param input The input. See {@link #parse(Object, ClassMeta)} for supported input types. 1307 * @param m The map being loaded. 1308 * @param keyType The class type of the keys, or <jk>null</jk> to default to <code>String.<jk>class</jk></code>. 1309 * @param valueType The class type of the values, or <jk>null</jk> to default to whatever is being parsed. 1310 * @return The same map that was passed in to allow this method to be chained. 1311 * @throws ParseException Malformed input encountered. 1312 * @throws UnsupportedOperationException If not implemented. 1313 */ 1314 public final <K,V> Map<K,V> parseIntoMap(Object input, Map<K,V> m, Type keyType, Type valueType) throws ParseException { 1315 return getSession().parseIntoMap(input, m, keyType, valueType); 1316 } 1317 1318 /** 1319 * Parses the contents of the specified reader and loads the results into the specified collection. 1320 * 1321 * <p> 1322 * Used in the following locations: 1323 * <ul class='spaced-list'> 1324 * <li> 1325 * The various character-based constructors in {@link JsonList} (e.g. 1326 * {@link JsonList#JsonList(CharSequence,Parser)}. 1327 * </ul> 1328 * 1329 * @param <E> The element class type. 1330 * @param input The input. See {@link #parse(Object, ClassMeta)} for supported input types. 1331 * @param c The collection being loaded. 1332 * @param elementType The class type of the elements, or <jk>null</jk> to default to whatever is being parsed. 1333 * @return The same collection that was passed in to allow this method to be chained. 1334 * @throws ParseException Malformed input encountered. 1335 * @throws UnsupportedOperationException If not implemented. 1336 */ 1337 public final <E> Collection<E> parseIntoCollection(Object input, Collection<E> c, Type elementType) throws ParseException { 1338 return getSession().parseIntoCollection(input, c, elementType); 1339 } 1340 1341 /** 1342 * Parses the specified array input with each entry in the object defined by the {@code argTypes} 1343 * argument. 1344 * 1345 * <p> 1346 * Used for converting arrays (e.g. <js>"[arg1,arg2,...]"</js>) into an {@code Object[]} that can be passed 1347 * to the {@code Method.invoke(target, args)} method. 1348 * 1349 * <p> 1350 * Used in the following locations: 1351 * <ul class='spaced-list'> 1352 * <li> 1353 * Used to parse argument strings in the {@link ObjectIntrospector#invokeMethod(Method, Reader)} method. 1354 * </ul> 1355 * 1356 * @param input The input. Subclasses can support different input types. 1357 * @param argTypes Specifies the type of objects to create for each entry in the array. 1358 * @return An array of parsed objects. 1359 * @throws ParseException Malformed input encountered. 1360 */ 1361 public final Object[] parseArgs(Object input, Type[] argTypes) throws ParseException { 1362 if (argTypes == null || argTypes.length == 0) 1363 return new Object[0]; 1364 return getSession().parseArgs(input, argTypes); 1365 } 1366 1367 1368 //----------------------------------------------------------------------------------------------------------------- 1369 // Other methods 1370 //----------------------------------------------------------------------------------------------------------------- 1371 1372 /** 1373 * Returns the media types handled based on the values passed to the <c>consumes</c> constructor parameter. 1374 * 1375 * @return The list of media types. Never <jk>null</jk>. 1376 */ 1377 public final List<MediaType> getMediaTypes() { 1378 return ulist(consumesArray); 1379 } 1380 1381 /** 1382 * Returns the first media type handled based on the values passed to the <c>consumes</c> constructor parameter. 1383 * 1384 * @return The media type. 1385 */ 1386 public final MediaType getPrimaryMediaType() { 1387 return consumesArray == null || consumesArray.length == 0 ? null : consumesArray[0]; 1388 } 1389 1390 /** 1391 * Returns <jk>true</jk> if this parser can handle the specified content type. 1392 * 1393 * @param contentType The content type to test. 1394 * @return <jk>true</jk> if this parser can handle the specified content type. 1395 */ 1396 public boolean canHandle(String contentType) { 1397 if (contentType != null) 1398 for (MediaType mt : getMediaTypes()) 1399 if (contentType.equals(mt.toString())) 1400 return true; 1401 return false; 1402 } 1403 1404 //----------------------------------------------------------------------------------------------------------------- 1405 // Properties 1406 //----------------------------------------------------------------------------------------------------------------- 1407 1408 /** 1409 * Auto-close streams. 1410 * 1411 * @see Parser.Builder#autoCloseStreams() 1412 * @return 1413 * <jk>true</jk> if <l>InputStreams</l> and <l>Readers</l> passed into parsers will be closed 1414 * after parsing is complete. 1415 */ 1416 protected final boolean isAutoCloseStreams() { 1417 return autoCloseStreams; 1418 } 1419 1420 /** 1421 * Debug output lines. 1422 * 1423 * @see Parser.Builder#debugOutputLines(int) 1424 * @return 1425 * The number of lines of input before and after the error location to be printed as part of the exception message. 1426 */ 1427 protected final int getDebugOutputLines() { 1428 return debugOutputLines; 1429 } 1430 1431 /** 1432 * Parser listener. 1433 * 1434 * @see Parser.Builder#listener(Class) 1435 * @return 1436 * Class used to listen for errors and warnings that occur during parsing. 1437 */ 1438 protected final Class<? extends ParserListener> getListener() { 1439 return listener; 1440 } 1441 1442 /** 1443 * Strict mode. 1444 * 1445 * @see Parser.Builder#strict() 1446 * @return 1447 * <jk>true</jk> if strict mode for the parser is enabled. 1448 */ 1449 protected final boolean isStrict() { 1450 return strict; 1451 } 1452 1453 /** 1454 * Trim parsed strings. 1455 * 1456 * @see Parser.Builder#trimStrings() 1457 * @return 1458 * <jk>true</jk> if string values will be trimmed of whitespace using {@link String#trim()} before being added to 1459 * the POJO. 1460 */ 1461 protected final boolean isTrimStrings() { 1462 return trimStrings; 1463 } 1464 1465 /** 1466 * Unbuffered. 1467 * 1468 * @see Parser.Builder#unbuffered() 1469 * @return 1470 * <jk>true</jk> if parsers don't use internal buffering during parsing. 1471 */ 1472 protected final boolean isUnbuffered() { 1473 return unbuffered; 1474 } 1475 1476 //----------------------------------------------------------------------------------------------------------------- 1477 // Other methods 1478 //----------------------------------------------------------------------------------------------------------------- 1479 1480 @Override /* Context */ 1481 protected JsonMap properties() { 1482 return filteredMap() 1483 .append("autoCloseStreams", autoCloseStreams) 1484 .append("debugOutputLines", debugOutputLines) 1485 .append("listener", listener) 1486 .append("strict", strict) 1487 .append("trimStrings", trimStrings) 1488 .append("unbuffered", unbuffered); 1489 } 1490}