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.html; 018 019import static org.apache.juneau.commons.utils.AssertionUtils.*; 020 021import java.lang.annotation.*; 022import java.nio.charset.*; 023import java.util.*; 024import java.util.concurrent.*; 025 026import org.apache.juneau.*; 027import org.apache.juneau.commons.collections.*; 028import org.apache.juneau.commons.function.*; 029import org.apache.juneau.commons.reflect.*; 030import org.apache.juneau.xml.*; 031 032/** 033 * Parses text generated by the {@link HtmlSerializer} class back into a POJO model. 034 * 035 * <h5 class='topic'>Media types</h5> 036 * 037 * Handles <c>Content-Type</c> types: <bc>text/html</bc> 038 * 039 * <h5 class='topic'>Description</h5> 040 * 041 * See the {@link HtmlSerializer} class for a description of the HTML generated. 042 * <p> 043 * This class is used primarily for automated testing of the {@link HtmlSerializer} class. 044 * 045 * <h5 class='section'>Notes:</h5><ul> 046 * <li class='note'>This class is thread safe and reusable. 047 * </ul> 048 * 049 * <h5 class='section'>See Also:</h5><ul> 050 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/HtmlBasics">HTML Basics</a> 051 052 * </ul> 053 */ 054public class HtmlParser extends XmlParser implements HtmlMetaProvider { 055 /** 056 * Builder class. 057 */ 058 public static class Builder extends XmlParser.Builder { 059 060 private static final Cache<HashKey,HtmlParser> CACHE = Cache.of(HashKey.class, HtmlParser.class).build(); 061 062 /** 063 * Constructor, default settings. 064 */ 065 protected Builder() { 066 consumes("text/html,text/html+stripped"); 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 } 078 079 /** 080 * Copy constructor. 081 * 082 * @param copyFrom The bean to copy from. 083 * <br>Cannot be <jk>null</jk>. 084 */ 085 protected Builder(HtmlParser copyFrom) { 086 super(assertArgNotNull("copyFrom", copyFrom)); 087 } 088 089 @Override /* Overridden from Builder */ 090 public Builder annotations(Annotation...values) { 091 super.annotations(values); 092 return this; 093 } 094 095 @Override /* Overridden from Builder */ 096 public Builder apply(AnnotationWorkList work) { 097 super.apply(work); 098 return this; 099 } 100 101 @Override /* Overridden from Builder */ 102 public Builder applyAnnotations(Class<?>...from) { 103 super.applyAnnotations(from); 104 return this; 105 } 106 107 @Override /* Overridden from Builder */ 108 public Builder applyAnnotations(Object...from) { 109 super.applyAnnotations(from); 110 return this; 111 } 112 113 @Override /* Overridden from Builder */ 114 public Builder autoCloseStreams() { 115 super.autoCloseStreams(); 116 return this; 117 } 118 119 @Override /* Overridden from Builder */ 120 public Builder autoCloseStreams(boolean value) { 121 super.autoCloseStreams(value); 122 return this; 123 } 124 125 @Override /* Overridden from Builder */ 126 public Builder beanClassVisibility(Visibility value) { 127 super.beanClassVisibility(value); 128 return this; 129 } 130 131 @Override /* Overridden from Builder */ 132 public Builder beanConstructorVisibility(Visibility value) { 133 super.beanConstructorVisibility(value); 134 return this; 135 } 136 137 @Override /* Overridden from Builder */ 138 public Builder beanContext(BeanContext value) { 139 super.beanContext(value); 140 return this; 141 } 142 143 @Override /* Overridden from Builder */ 144 public Builder beanContext(BeanContext.Builder value) { 145 super.beanContext(value); 146 return this; 147 } 148 149 @Override /* Overridden from Builder */ 150 public Builder beanDictionary(java.lang.Class<?>...values) { 151 super.beanDictionary(values); 152 return this; 153 } 154 155 @Override /* Overridden from Builder */ 156 public Builder beanFieldVisibility(Visibility value) { 157 super.beanFieldVisibility(value); 158 return this; 159 } 160 161 @Override /* Overridden from Builder */ 162 public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) { 163 super.beanInterceptor(on, value); 164 return this; 165 } 166 167 @Override /* Overridden from Builder */ 168 public Builder beanMapPutReturnsOldValue() { 169 super.beanMapPutReturnsOldValue(); 170 return this; 171 } 172 173 @Override /* Overridden from Builder */ 174 public Builder beanMethodVisibility(Visibility value) { 175 super.beanMethodVisibility(value); 176 return this; 177 } 178 179 @Override /* Overridden from Builder */ 180 public Builder beanProperties(Class<?> beanClass, String properties) { 181 super.beanProperties(beanClass, properties); 182 return this; 183 } 184 185 @Override /* Overridden from Builder */ 186 public Builder beanProperties(Map<String,Object> values) { 187 super.beanProperties(values); 188 return this; 189 } 190 191 @Override /* Overridden from Builder */ 192 public Builder beanProperties(String beanClassName, String properties) { 193 super.beanProperties(beanClassName, properties); 194 return this; 195 } 196 197 @Override /* Overridden from Builder */ 198 public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) { 199 super.beanPropertiesExcludes(beanClass, properties); 200 return this; 201 } 202 203 @Override /* Overridden from Builder */ 204 public Builder beanPropertiesExcludes(Map<String,Object> values) { 205 super.beanPropertiesExcludes(values); 206 return this; 207 } 208 209 @Override /* Overridden from Builder */ 210 public Builder beanPropertiesExcludes(String beanClassName, String properties) { 211 super.beanPropertiesExcludes(beanClassName, properties); 212 return this; 213 } 214 215 @Override /* Overridden from Builder */ 216 public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) { 217 super.beanPropertiesReadOnly(beanClass, properties); 218 return this; 219 } 220 221 @Override /* Overridden from Builder */ 222 public Builder beanPropertiesReadOnly(Map<String,Object> values) { 223 super.beanPropertiesReadOnly(values); 224 return this; 225 } 226 227 @Override /* Overridden from Builder */ 228 public Builder beanPropertiesReadOnly(String beanClassName, String properties) { 229 super.beanPropertiesReadOnly(beanClassName, properties); 230 return this; 231 } 232 233 @Override /* Overridden from Builder */ 234 public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) { 235 super.beanPropertiesWriteOnly(beanClass, properties); 236 return this; 237 } 238 239 @Override /* Overridden from Builder */ 240 public Builder beanPropertiesWriteOnly(Map<String,Object> values) { 241 super.beanPropertiesWriteOnly(values); 242 return this; 243 } 244 245 @Override /* Overridden from Builder */ 246 public Builder beanPropertiesWriteOnly(String beanClassName, String properties) { 247 super.beanPropertiesWriteOnly(beanClassName, properties); 248 return this; 249 } 250 251 @Override /* Overridden from Builder */ 252 public Builder beansRequireDefaultConstructor() { 253 super.beansRequireDefaultConstructor(); 254 return this; 255 } 256 257 @Override /* Overridden from Builder */ 258 public Builder beansRequireSerializable() { 259 super.beansRequireSerializable(); 260 return this; 261 } 262 263 @Override /* Overridden from Builder */ 264 public Builder beansRequireSettersForGetters() { 265 super.beansRequireSettersForGetters(); 266 return this; 267 } 268 269 @Override /* Overridden from Context.Builder */ 270 public HtmlParser build() { 271 return cache(CACHE).build(HtmlParser.class); 272 } 273 274 @Override /* Overridden from Builder */ 275 public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) { 276 super.cache(value); 277 return this; 278 } 279 280 @Override /* Overridden from Builder */ 281 public Builder consumes(String value) { 282 super.consumes(value); 283 return this; 284 } 285 286 @Override /* Overridden from Context.Builder */ 287 public Builder copy() { 288 return new Builder(this); 289 } 290 291 @Override /* Overridden from Builder */ 292 public Builder debug() { 293 super.debug(); 294 return this; 295 } 296 297 @Override /* Overridden from Builder */ 298 public Builder debug(boolean value) { 299 super.debug(value); 300 return this; 301 } 302 303 @Override /* Overridden from Builder */ 304 public Builder debugOutputLines(int value) { 305 super.debugOutputLines(value); 306 return this; 307 } 308 309 @Override /* Overridden from Builder */ 310 public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) { 311 super.dictionaryOn(on, values); 312 return this; 313 } 314 315 @Override /* Overridden from Builder */ 316 public Builder disableBeansRequireSomeProperties() { 317 super.disableBeansRequireSomeProperties(); 318 return this; 319 } 320 321 @Override /* Overridden from Builder */ 322 public Builder disableIgnoreMissingSetters() { 323 super.disableIgnoreMissingSetters(); 324 return this; 325 } 326 327 @Override /* Overridden from Builder */ 328 public Builder disableIgnoreTransientFields() { 329 super.disableIgnoreTransientFields(); 330 return this; 331 } 332 333 @Override /* Overridden from Builder */ 334 public Builder disableIgnoreUnknownNullBeanProperties() { 335 super.disableIgnoreUnknownNullBeanProperties(); 336 return this; 337 } 338 339 @Override /* Overridden from Builder */ 340 public Builder disableInterfaceProxies() { 341 super.disableInterfaceProxies(); 342 return this; 343 } 344 345 @Override /* Overridden from Builder */ 346 public Builder eventAllocator(Class<? extends javax.xml.stream.util.XMLEventAllocator> value) { 347 super.eventAllocator(value); 348 return this; 349 } 350 351 @Override /* Overridden from Builder */ 352 public <T> Builder example(Class<T> pojoClass, String json) { 353 super.example(pojoClass, json); 354 return this; 355 } 356 357 @Override /* Overridden from Builder */ 358 public <T> Builder example(Class<T> pojoClass, T o) { 359 super.example(pojoClass, o); 360 return this; 361 } 362 363 @Override /* Overridden from Builder */ 364 public Builder fileCharset(Charset value) { 365 super.fileCharset(value); 366 return this; 367 } 368 369 @Override /* Overridden from Builder */ 370 public Builder findFluentSetters() { 371 super.findFluentSetters(); 372 return this; 373 } 374 375 @Override /* Overridden from Builder */ 376 public Builder findFluentSetters(Class<?> on) { 377 super.findFluentSetters(on); 378 return this; 379 } 380 381 @Override /* Overridden from Context.Builder */ 382 public HashKey hashKey() { 383 return super.hashKey(); 384 } 385 386 @Override /* Overridden from Builder */ 387 public Builder ignoreInvocationExceptionsOnGetters() { 388 super.ignoreInvocationExceptionsOnGetters(); 389 return this; 390 } 391 392 @Override /* Overridden from Builder */ 393 public Builder ignoreInvocationExceptionsOnSetters() { 394 super.ignoreInvocationExceptionsOnSetters(); 395 return this; 396 } 397 398 @Override /* Overridden from Builder */ 399 public Builder ignoreUnknownBeanProperties() { 400 super.ignoreUnknownBeanProperties(); 401 return this; 402 } 403 404 @Override /* Overridden from Builder */ 405 public Builder ignoreUnknownEnumValues() { 406 super.ignoreUnknownEnumValues(); 407 return this; 408 } 409 410 @Override /* Overridden from Builder */ 411 public Builder impl(Context value) { 412 super.impl(value); 413 return this; 414 } 415 416 @Override /* Overridden from Builder */ 417 public Builder implClass(Class<?> interfaceClass, Class<?> implClass) { 418 super.implClass(interfaceClass, implClass); 419 return this; 420 } 421 422 @Override /* Overridden from Builder */ 423 public Builder implClasses(Map<Class<?>,Class<?>> values) { 424 super.implClasses(values); 425 return this; 426 } 427 428 @Override /* Overridden from Builder */ 429 public Builder interfaceClass(Class<?> on, Class<?> value) { 430 super.interfaceClass(on, value); 431 return this; 432 } 433 434 @Override /* Overridden from Builder */ 435 public Builder interfaces(java.lang.Class<?>...value) { 436 super.interfaces(value); 437 return this; 438 } 439 440 @Override /* Overridden from Builder */ 441 public Builder listener(Class<? extends org.apache.juneau.parser.ParserListener> value) { 442 super.listener(value); 443 return this; 444 } 445 446 @Override /* Overridden from Builder */ 447 public Builder locale(Locale value) { 448 super.locale(value); 449 return this; 450 } 451 452 @Override /* Overridden from Builder */ 453 public Builder mediaType(MediaType value) { 454 super.mediaType(value); 455 return this; 456 } 457 458 @Override /* Overridden from Builder */ 459 public Builder notBeanClasses(java.lang.Class<?>...values) { 460 super.notBeanClasses(values); 461 return this; 462 } 463 464 @Override /* Overridden from Builder */ 465 public Builder notBeanPackages(String...values) { 466 super.notBeanPackages(values); 467 return this; 468 } 469 470 @Override /* Overridden from Builder */ 471 public Builder preserveRootElement() { 472 super.preserveRootElement(); 473 return this; 474 } 475 476 @Override /* Overridden from Builder */ 477 public Builder preserveRootElement(boolean value) { 478 super.preserveRootElement(value); 479 return this; 480 } 481 482 @Override /* Overridden from Builder */ 483 public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) { 484 super.propertyNamer(on, value); 485 return this; 486 } 487 488 @Override /* Overridden from Builder */ 489 public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) { 490 super.propertyNamer(value); 491 return this; 492 } 493 494 @Override /* Overridden from Builder */ 495 public Builder reporter(Class<? extends javax.xml.stream.XMLReporter> value) { 496 super.reporter(value); 497 return this; 498 } 499 500 @Override /* Overridden from Builder */ 501 public Builder resolver(Class<? extends javax.xml.stream.XMLResolver> value) { 502 super.resolver(value); 503 return this; 504 } 505 506 @Override /* Overridden from Builder */ 507 public Builder sortProperties() { 508 super.sortProperties(); 509 return this; 510 } 511 512 @Override /* Overridden from Builder */ 513 public Builder sortProperties(java.lang.Class<?>...on) { 514 super.sortProperties(on); 515 return this; 516 } 517 518 @Override /* Overridden from Builder */ 519 public Builder stopClass(Class<?> on, Class<?> value) { 520 super.stopClass(on, value); 521 return this; 522 } 523 524 @Override /* Overridden from Builder */ 525 public Builder streamCharset(Charset value) { 526 super.streamCharset(value); 527 return this; 528 } 529 530 @Override /* Overridden from Builder */ 531 public Builder strict() { 532 super.strict(); 533 return this; 534 } 535 536 @Override /* Overridden from Builder */ 537 public Builder strict(boolean value) { 538 super.strict(value); 539 return this; 540 } 541 542 @Override /* Overridden from Builder */ 543 public <T,S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) { 544 super.swap(normalClass, swappedClass, swapFunction); 545 return this; 546 } 547 548 @Override /* Overridden from Builder */ 549 public <T,S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) { 550 super.swap(normalClass, swappedClass, swapFunction, unswapFunction); 551 return this; 552 } 553 554 @Override /* Overridden from Builder */ 555 public Builder swaps(Class<?>...values) { 556 super.swaps(values); 557 return this; 558 } 559 560 @Override /* Overridden from Builder */ 561 public Builder swaps(Object...values) { 562 super.swaps(values); 563 return this; 564 } 565 566 @Override /* Overridden from Builder */ 567 public Builder timeZone(TimeZone value) { 568 super.timeZone(value); 569 return this; 570 } 571 572 @Override /* Overridden from Builder */ 573 public Builder trimStrings() { 574 super.trimStrings(); 575 return this; 576 } 577 578 @Override /* Overridden from Builder */ 579 public Builder trimStrings(boolean value) { 580 super.trimStrings(value); 581 return this; 582 } 583 584 @Override /* Overridden from Builder */ 585 public Builder type(Class<? extends org.apache.juneau.Context> value) { 586 super.type(value); 587 return this; 588 } 589 590 @Override /* Overridden from Builder */ 591 public Builder typeName(Class<?> on, String value) { 592 super.typeName(on, value); 593 return this; 594 } 595 596 @Override /* Overridden from Builder */ 597 public Builder typePropertyName(Class<?> on, String value) { 598 super.typePropertyName(on, value); 599 return this; 600 } 601 602 @Override /* Overridden from Builder */ 603 public Builder typePropertyName(String value) { 604 super.typePropertyName(value); 605 return this; 606 } 607 608 @Override /* Overridden from Builder */ 609 public Builder unbuffered() { 610 super.unbuffered(); 611 return this; 612 } 613 614 @Override /* Overridden from Builder */ 615 public Builder unbuffered(boolean value) { 616 super.unbuffered(value); 617 return this; 618 } 619 620 @Override /* Overridden from Builder */ 621 public Builder useEnumNames() { 622 super.useEnumNames(); 623 return this; 624 } 625 626 @Override /* Overridden from Builder */ 627 public Builder useJavaBeanIntrospector() { 628 super.useJavaBeanIntrospector(); 629 return this; 630 } 631 632 @Override /* Overridden from Builder */ 633 public Builder validating() { 634 super.validating(); 635 return this; 636 } 637 638 @Override /* Overridden from Builder */ 639 public Builder validating(boolean value) { 640 super.validating(value); 641 return this; 642 } 643 } 644 645 /** Default parser, all default settings.*/ 646 public static final HtmlParser DEFAULT = new HtmlParser(create()); 647 648 /** 649 * Creates a new builder for this object. 650 * 651 * @return A new builder. 652 */ 653 public static Builder create() { 654 return new Builder(); 655 } 656 657 private final Map<ClassMeta<?>,HtmlClassMeta> htmlClassMetas = new ConcurrentHashMap<>(); 658 private final Map<BeanPropertyMeta,HtmlBeanPropertyMeta> htmlBeanPropertyMetas = new ConcurrentHashMap<>(); 659 660 /** 661 * Constructor. 662 * 663 * @param builder The builder for this object. 664 */ 665 public HtmlParser(Builder builder) { 666 super(builder); 667 } 668 669 @Override /* Overridden from Context */ 670 public Builder copy() { 671 return new Builder(this); 672 } 673 674 @Override /* Overridden from Context */ 675 public HtmlParserSession.Builder createSession() { 676 return HtmlParserSession.create(this); 677 } 678 679 @Override /* Overridden from HtmlMetaProvider */ 680 public HtmlBeanPropertyMeta getHtmlBeanPropertyMeta(BeanPropertyMeta bpm) { 681 if (bpm == null) 682 return HtmlBeanPropertyMeta.DEFAULT; 683 HtmlBeanPropertyMeta m = htmlBeanPropertyMetas.get(bpm); 684 if (m == null) { 685 m = new HtmlBeanPropertyMeta(bpm.getDelegateFor(), this.getAnnotationProvider(), this); 686 htmlBeanPropertyMetas.put(bpm, m); 687 } 688 return m; 689 } 690 691 @Override /* Overridden from HtmlMetaProvider */ 692 public HtmlClassMeta getHtmlClassMeta(ClassMeta<?> cm) { 693 HtmlClassMeta m = htmlClassMetas.get(cm); 694 if (m == null) { 695 m = new HtmlClassMeta(cm, this); 696 htmlClassMetas.put(cm, m); 697 } 698 return m; 699 } 700 701 @Override /* Overridden from Context */ 702 public HtmlParserSession getSession() { return createSession().build(); } 703}