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.html; 014 015import static org.apache.juneau.collections.JsonMap.*; 016import java.lang.annotation.*; 017import java.lang.reflect.*; 018import java.nio.charset.*; 019import java.util.*; 020import java.util.concurrent.*; 021 022import org.apache.juneau.*; 023import org.apache.juneau.collections.*; 024import org.apache.juneau.html.annotation.*; 025import org.apache.juneau.internal.*; 026import org.apache.juneau.serializer.*; 027import org.apache.juneau.utils.*; 028import org.apache.juneau.xml.*; 029 030/** 031 * Serializes POJO models to HTML. 032 * 033 * <h5 class='topic'>Media types</h5> 034 * <p> 035 * Handles <c>Accept</c> types: <bc>text/html</bc> 036 * <p> 037 * Produces <c>Content-Type</c> types: <bc>text/html</bc> 038 * 039 * <h5 class='topic'>Description</h5> 040 * <p> 041 * The conversion is as follows... 042 * <ul class='spaced-list'> 043 * <li> 044 * {@link Map Maps} (e.g. {@link HashMap}, {@link TreeMap}) and beans are converted to HTML tables with 045 * 'key' and 'value' columns. 046 * <li> 047 * {@link Collection Collections} (e.g. {@link HashSet}, {@link LinkedList}) and Java arrays are converted 048 * to HTML ordered lists. 049 * <li> 050 * {@code Collections} of {@code Maps} and beans are converted to HTML tables with keys as headers. 051 * <li> 052 * Everything else is converted to text. 053 * </ul> 054 * 055 * <p> 056 * This serializer provides several serialization options. Typically, one of the predefined <jsf>DEFAULT</jsf> 057 * serializers will be sufficient. 058 * However, custom serializers can be constructed to fine-tune behavior. 059 * 060 * <p> 061 * The {@link HtmlLink} annotation can be used on beans to add hyperlinks to the output. 062 * 063 * <h5 class='topic'>Behavior-specific subclasses</h5> 064 * <p> 065 * The following direct subclasses are provided for convenience: 066 * <ul class='spaced-list'> 067 * <li> 068 * {@link Sq} - Default serializer, single quotes. 069 * <li> 070 * {@link SqReadable} - Default serializer, single quotes, whitespace added. 071 * </ul> 072 * 073 * <h5 class='section'>Example:</h5> 074 * <p class='bjava'> 075 * <jc>// Use one of the default serializers to serialize a POJO</jc> 076 * String <jv>html</jv> = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(<jv>someObject</jv>); 077 * 078 * <jc>// Create a custom serializer that doesn't use whitespace and newlines</jc> 079 * HtmlSerializer <jv>serializer</jv> = HtmlSerializer.<jsm>create</jsm>().ws().build(); 080 * 081 * <jc>// Same as above, except uses cloning</jc> 082 * HtmlSerializer <jv>serializer</jv> = HtmlSerializer.<jsf>DEFAULT</jsf>.copy().ws().build(); 083 * 084 * <jc>// Serialize POJOs to HTML</jc> 085 * 086 * <jc>// Produces: </jc> 087 * <jc>// <ul><li>1<li>2<li>3</ul></jc> 088 * List <jv>list</jv> = JsonList.<jsm>of</jsm>(1, 2, 3); 089 * String <jv>html</jv> = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(<jv>list</jv>); 090 * 091 * <jc>// Produces: </jc> 092 * <jc>// <table> </jc> 093 * <jc>// <tr><th>firstName</th><th>lastName</th></tr> </jc> 094 * <jc>// <tr><td>Bob</td><td>Costas</td></tr> </jc> 095 * <jc>// <tr><td>Billy</td><td>TheKid</td></tr> </jc> 096 * <jc>// <tr><td>Barney</td><td>Miller</td></tr> </jc> 097 * <jc>// </table> </jc> 098 * <jv>html</jv> = JsonList.<jsm>of</jsm>( 099 * JsonMap.<jsm>ofJson</jsm>(<js>"{firstName:'Bob',lastName:'Costas'}"</js>), 100 * JsonMap.<jsm>ofJson</jsm>(<js>"{firstName:'Billy',lastName:'TheKid'}"</js>), 101 * JsonMap.<jsm>ofJson</jsm>(<js>"{firstName:'Barney',lastName:'Miller'}"</js>) 102 * ); 103 * String <jv>html</jv> = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(<jv>list</jv>); 104 * 105 * <jc>// Produces: </jc> 106 * <jc>// <table> </jc> 107 * <jc>// <tr><th>key</th><th>value</th></tr> </jc> 108 * <jc>// <tr><td>foo</td><td>bar</td></tr> </jc> 109 * <jc>// <tr><td>baz</td><td>123</td></tr> </jc> 110 * <jc>// </table> </jc> 111 * Map <jv>map</jv> = JsonMap.<jsm>ofJson</jsm>(<js>"{foo:'bar',baz:123}"</js>); 112 * String <jv>html</jv> = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(<jv>map</jv>); 113 * 114 * <jc>// HTML elements can be nested arbitrarily deep</jc> 115 * <jc>// Produces: </jc> 116 * <jc>// <table> </jc> 117 * <jc>// <tr><th>key</th><th>value</th></tr> </jc> 118 * <jc>// <tr><td>foo</td><td>bar</td></tr> </jc> 119 * <jc>// <tr><td>baz</td><td>123</td></tr> </jc> 120 * <jc>// <tr><td>someNumbers</td><td><ul><li>1<li>2<li>3</ul></td></tr> </jc> 121 * <jc>// <tr><td>someSubMap</td><td> </jc> 122 * <jc>// <table> </jc> 123 * <jc>// <tr><th>key</th><th>value</th></tr> </jc> 124 * <jc>// <tr><td>a</td><td>b</td></tr> </jc> 125 * <jc>// </table> </jc> 126 * <jc>// </td></tr> </jc> 127 * <jc>// </table> </jc> 128 * Map <jv>map</jv> = JsonMap.<jsm>ofJson</jsm>(<js>"{foo:'bar',baz:123}"</js>); 129 * <jv>map</jv>.put(<js>"someNumbers"</js>, JsonList.<jsm>of</jsm>(1, 2, 3)); 130 * <jv>map</jv>.put(<js>"someSubMap"</js>, JsonMap.<jsm>ofJson</jsm>(<js>"{a:'b'}"</js>)); 131 * String <jv>html</jv> = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(<jv>map</jv>); 132 * </p> 133 * 134 * <h5 class='section'>Notes:</h5><ul> 135 * <li class='note'>This class is thread safe and reusable. 136 * </ul> 137 * 138 * <h5 class='section'>See Also:</h5><ul> 139 * <li class='link'><a class="doclink" href="../../../../index.html#jm.HtmlDetails">HTML Details</a> 140 141 * </ul> 142 */ 143public class HtmlSerializer extends XmlSerializer implements HtmlMetaProvider { 144 145 //------------------------------------------------------------------------------------------------------------------- 146 // Static 147 //------------------------------------------------------------------------------------------------------------------- 148 149 /** Default serializer, all default settings. */ 150 public static final HtmlSerializer DEFAULT = new HtmlSerializer(create()); 151 152 /** Default serializer, single quotes. */ 153 public static final HtmlSerializer DEFAULT_SQ = new HtmlSerializer.Sq(create()); 154 155 /** Default serializer, single quotes, whitespace added. */ 156 public static final HtmlSerializer DEFAULT_SQ_READABLE = new HtmlSerializer.SqReadable(create()); 157 158 /** 159 * Creates a new builder for this object. 160 * 161 * @return A new builder. 162 */ 163 public static Builder create() { 164 return new Builder(); 165 } 166 167 //------------------------------------------------------------------------------------------------------------------- 168 // Static subclasses 169 //------------------------------------------------------------------------------------------------------------------- 170 171 /** Default serializer, single quotes. */ 172 public static class Sq extends HtmlSerializer { 173 174 /** 175 * Constructor. 176 * 177 * @param builder The builder for this object. 178 */ 179 public Sq(Builder builder) { 180 super(builder.quoteChar('\'')); 181 } 182 } 183 184 /** Default serializer, single quotes, whitespace added. */ 185 public static class SqReadable extends HtmlSerializer { 186 187 /** 188 * Constructor. 189 * 190 * @param builder The builder for this object. 191 */ 192 public SqReadable(Builder builder) { 193 super(builder.quoteChar('\'').useWhitespace()); 194 } 195 } 196 197 //------------------------------------------------------------------------------------------------------------------- 198 // Instance 199 //------------------------------------------------------------------------------------------------------------------- 200 201 /** 202 * Builder class. 203 */ 204 @FluentSetters 205 public static class Builder extends XmlSerializer.Builder { 206 207 private static final Cache<HashKey,HtmlSerializer> CACHE = Cache.of(HashKey.class, HtmlSerializer.class).build(); 208 209 boolean addBeanTypesHtml, addKeyValueTableHeaders, disableDetectLabelParameters, disableDetectLinksInStrings; 210 String labelParameter; 211 AnchorText uriAnchorText; 212 213 /** 214 * Constructor, default settings. 215 */ 216 protected Builder() { 217 super(); 218 produces("text/html"); 219 addBeanTypesHtml = env("HtmlSerializer.addBeanTypesHtml", false); 220 addKeyValueTableHeaders = env("HtmlSerializer.addKeyValueTableHeaders", false); 221 disableDetectLabelParameters = env("HtmlSerializer.disableDetectLabelParameters", false); 222 disableDetectLinksInStrings = env("HtmlSerializer.disableDetectLinksInStrings", false); 223 uriAnchorText = env("HtmlSerializer.uriAnchorText", AnchorText.TO_STRING); 224 labelParameter = env("HtmlSerializer.labelParameter", "label"); 225 } 226 227 /** 228 * Copy constructor. 229 * 230 * @param copyFrom The bean to copy from. 231 */ 232 protected Builder(HtmlSerializer copyFrom) { 233 super(copyFrom); 234 addBeanTypesHtml = copyFrom.addBeanTypesHtml; 235 addKeyValueTableHeaders = copyFrom.addKeyValueTableHeaders; 236 disableDetectLabelParameters = ! copyFrom.detectLabelParameters; 237 disableDetectLinksInStrings = ! copyFrom.detectLinksInStrings; 238 labelParameter = copyFrom.labelParameter; 239 uriAnchorText = copyFrom.uriAnchorText; 240 } 241 242 /** 243 * Copy constructor. 244 * 245 * @param copyFrom The builder to copy from. 246 */ 247 protected Builder(Builder copyFrom) { 248 super(copyFrom); 249 addBeanTypesHtml = copyFrom.addBeanTypesHtml; 250 addKeyValueTableHeaders = copyFrom.addKeyValueTableHeaders; 251 disableDetectLabelParameters = copyFrom.disableDetectLabelParameters; 252 disableDetectLinksInStrings = copyFrom.disableDetectLinksInStrings; 253 labelParameter = copyFrom.labelParameter; 254 uriAnchorText = copyFrom.uriAnchorText; 255 } 256 257 @Override /* Context.Builder */ 258 public Builder copy() { 259 return new Builder(this); 260 } 261 262 @Override /* Context.Builder */ 263 public HtmlSerializer build() { 264 return cache(CACHE).build(HtmlSerializer.class); 265 } 266 267 @Override /* Context.Builder */ 268 public HashKey hashKey() { 269 return HashKey.of( 270 super.hashKey(), 271 addBeanTypesHtml, 272 addKeyValueTableHeaders, 273 disableDetectLabelParameters, 274 disableDetectLinksInStrings, 275 labelParameter, 276 uriAnchorText 277 ); 278 } 279 280 //----------------------------------------------------------------------------------------------------------------- 281 // Properties 282 //----------------------------------------------------------------------------------------------------------------- 283 284 /** 285 * Add <js>"_type"</js> properties when needed. 286 * 287 * <p> 288 * If <jk>true</jk>, then <js>"_type"</js> properties will be added to beans if their type cannot be inferred 289 * through reflection. 290 * 291 * <p> 292 * When present, this value overrides the {@link org.apache.juneau.serializer.Serializer.Builder#addBeanTypes()} setting and is 293 * provided to customize the behavior of specific serializers in a {@link SerializerSet}. 294 * 295 * @return This object. 296 */ 297 @FluentSetter 298 public Builder addBeanTypesHtml() { 299 return addBeanTypesHtml(true); 300 } 301 302 /** 303 * Same as {@link #addBeanTypesHtml()} but allows you to explicitly specify the value. 304 * 305 * @param value The value for this setting. 306 * @return This object. 307 */ 308 @FluentSetter 309 public Builder addBeanTypesHtml(boolean value) { 310 addBeanTypesHtml = value; 311 return this; 312 } 313 314 /** 315 * <i><l>HtmlSerializer</l> configuration property: </i> Add key/value headers on bean/map tables. 316 * 317 * <p> 318 * When enabled, <bc>key</bc> and <bc>value</bc> column headers are added to tables. 319 * 320 * <h5 class='section'>Example:</h5> 321 * <p class='bjson'> 322 * <jc>// Our bean class.</jc> 323 * <jk>public class</jk> MyBean { 324 * <jk>public</jk> String <jf>f1</jf> = <js>"foo"</js>; 325 * <jk>public</jk> String <jf>f2</jf> = <js>"bar"</js>; 326 * } 327 * 328 * <jc>// Serializer without headers.</jc> 329 * WriterSerializer <jv>serializer1</jv> = HtmlSerializer.<jsf>DEFAULT</jsf>; 330 * 331 * <jc>// Serializer with headers.</jc> 332 * WriterSerializer <jv>serializer2</jv> = HtmlSerializer 333 * .<jsm>create</jsm>() 334 * .addKeyValueTableHeaders() 335 * .build(); 336 * 337 * String <jv>withoutHeaders</jv> = <jv>serializer1</jv>.serialize(<jk>new</jk> MyBean()); 338 * String <jv>withHeaders</jv> = <jv>serializer2</jv>.serialize(<jk>new</jk> MyBean()); 339 * </p> 340 * 341 * <p> 342 * The following shows the difference between the two generated outputs: 343 * 344 * <table class='styled'> 345 * <tr> 346 * <th><c>withoutHeaders</c></th> 347 * <th><c>withHeaders</c></th> 348 * </tr> 349 * <tr> 350 * <td> 351 * <table class='unstyled'> 352 * <tr><td>f1</td><td>foo</td></tr> 353 * <tr><td>f2</td><td>bar</td></tr> 354 * </table> 355 * </td> 356 * <td> 357 * <table class='unstyled'> 358 * <tr><th>key</th><th>value</th></tr> 359 * <tr><td>f1</td><td>foo</td></tr> 360 * <tr><td>f2</td><td>bar</td></tr> 361 * </table> 362 * </td> 363 * </tr> 364 * </table> 365 * 366 * @return This object. 367 */ 368 @FluentSetter 369 public Builder addKeyValueTableHeaders() { 370 return addKeyValueTableHeaders(true); 371 } 372 373 /** 374 * Same as {@link #addKeyValueTableHeaders()} but allows you to explicitly specify the value. 375 * 376 * @param value The value for this setting. 377 * @return This object. 378 */ 379 @FluentSetter 380 public Builder addKeyValueTableHeaders(boolean value) { 381 addKeyValueTableHeaders = value; 382 return this; 383 } 384 385 /** 386 * <i><l>HtmlSerializer</l> configuration property: </i> Don't look for URLs in {@link String Strings}. 387 * 388 * <p> 389 * Disables the feature where if a string looks like a URL (i.e. starts with <js>"http://"</js> or <js>"https://"</js>, then treat it like a URL 390 * and make it into a hyperlink based on the rules specified by {@link Builder#uriAnchorText(AnchorText)}. 391 * 392 * <h5 class='section'>Example:</h5> 393 * <p class='bjson'> 394 * <jc>// Our bean class with a property containing what looks like a URL.</jc> 395 * <jk>public class</jk> MyBean { 396 * <jk>public</jk> String <jf>f1</jf> = <js>"http://www.apache.org"</js>; 397 * } 398 * 399 * <jc>// Serializer with link detection.</jc> 400 * WriterSerializer <jv>serializer1</jv> = HtmlSerializer 401 * .<jsm>create</jsm>() 402 * .addKeyValueTableHeaders() 403 * .build(); 404 * 405 * <jc>// Serializer without link detection.</jc> 406 * WriterSerializer <jv>serializer2</jv> = HtmlSerializer 407 * .<jsm>create</jsm>() 408 * .addKeyValueTableHeaders() 409 * .disableDetectLinksInStrings() 410 * .build(); 411 * 412 * String <jv>withLinks</jv> = <jv>serializer1</jv>.serialize(<jk>new</jk> MyBean()); 413 * String <jv>withoutLinks</jv> = <jv>serializer2</jv>.serialize(<jk>new</jk> MyBean()); 414 * </p> 415 * 416 * <p> 417 * The following shows the difference between the two generated outputs: 418 * 419 * <table class='styled'> 420 * <tr> 421 * <th><c>withLinks</c></th> 422 * <th><c>withoutLinks</c></th> 423 * </tr> 424 * <tr> 425 * <td> 426 * <table class='unstyled'> 427 * <tr><th>key</th><th>value</th></tr> 428 * <tr><td>f1</td><td><a href='http://www.apache.org'>http://www.apache.org</a></td></tr> 429 * </table> 430 * </td> 431 * <td> 432 * <table class='unstyled'> 433 * <tr><th>key</th><th>value</th></tr> 434 * <tr><td>f1</td><td>http://www.apache.org</td></tr> 435 * </table> 436 * </td> 437 * </tr> 438 * </table> 439 * 440 * @return This object. 441 */ 442 @FluentSetter 443 public Builder disableDetectLinksInStrings() { 444 return disableDetectLinksInStrings(true); 445 } 446 447 /** 448 * Same as {@link #disableDetectLinksInStrings()} but allows you to explicitly specify the value. 449 * 450 * @param value The value for this setting. 451 * @return This object. 452 */ 453 @FluentSetter 454 public Builder disableDetectLinksInStrings(boolean value) { 455 disableDetectLinksInStrings = value; 456 return this; 457 } 458 459 /** 460 * <i><l>HtmlSerializer</l> configuration property: </i> Link label parameter name. 461 * 462 * <p> 463 * The parameter name to look for when resolving link labels}. 464 * 465 * @param value 466 * The new value for this property. 467 * <br>The default is <js>"label"</js>. 468 * @return This object. 469 */ 470 @FluentSetter 471 public Builder labelParameter(String value) { 472 labelParameter = value; 473 return this; 474 } 475 476 /** 477 * <i><l>HtmlSerializer</l> configuration property: </i> Dont look for link labels in URIs. 478 * 479 * <p> 480 * Disables the feature where if the URL has a label parameter (e.g. <js>"?label=foobar"</js>), then use that as the anchor text of the link. 481 * 482 * <p> 483 * The parameter name can be changed via the {@link #labelParameter(String)} property. 484 * 485 * <h5 class='section'>Example:</h5> 486 * <p class='bjson'> 487 * <jc>// Our bean class with a property containing what looks like a URL.</jc> 488 * <jk>public class</jk> MyBean { 489 * <jk>public</jk> URI <jf>f1</jf> = URI.<jsm>create</jsm>(<js>"http://www.apache.org?label=Apache%20Foundation"</js>); 490 * } 491 * 492 * <jc>// Serializer with label detection.</jc> 493 * WriterSerializer <jv>serializer1</jv> = HtmlSerializer 494 * .<jsm>create</jsm>() 495 * .addKeyValueTableHeaders() 496 * .build(); 497 * 498 * <jc>// Serializer without label detection.</jc> 499 * WriterSerializer <jv>serializer2</jv> = HtmlSerializer 500 * .<jsm>create</jsm>() 501 * .addKeyValueTableHeaders() 502 * .disableDetectLabelParameters() 503 * .build(); 504 * 505 * String <jv>withLabels</jv> = <jv>serializer1</jv>.serialize(<jk>new</jk> MyBean()); 506 * String <jv>withoutLabels</jv> = <jv>serializer2</jv>.serialize(<jk>new</jk> MyBean()); 507 * </p> 508 * 509 * <p> 510 * The following shows the difference between the two generated outputs. 511 * <br>Note that they're both hyperlinks, but the anchor text differs: 512 * 513 * <table class='styled'> 514 * <tr> 515 * <th><c>withLabels</c></th> 516 * <th><c>withoutLabels</c></th> 517 * </tr> 518 * <tr> 519 * <td> 520 * <table class='unstyled'> 521 * <tr><th>key</th><th>value</th></tr> 522 * <tr><td>f1</td><td><a href='http://www.apache.org?label=Apache%20Foundation'>Apache Foundation</a></td></tr> 523 * </table> 524 * </td> 525 * <td> 526 * <table class='unstyled'> 527 * <tr><th>key</th><th>value</th></tr> 528 * <tr><td>f1</td><td><a href='http://www.apache.org?label=Apache%20Foundation'>http://www.apache.org?label=Apache%20Foundation</a></td></tr> 529 * </table> 530 * </td> 531 * </tr> 532 * </table> 533 * 534 * @return This object. 535 */ 536 @FluentSetter 537 public Builder disableDetectLabelParameters() { 538 return disableDetectLabelParameters(true); 539 } 540 541 /** 542 * Same as {@link #disableDetectLabelParameters()} but allows you to explicitly specify the value. 543 * 544 * @param value The value for this setting. 545 * @return This object. 546 */ 547 @FluentSetter 548 public Builder disableDetectLabelParameters(boolean value) { 549 disableDetectLabelParameters = value; 550 return this; 551 } 552 553 /** 554 * <i><l>HtmlSerializer</l> configuration property: </i> Anchor text source. 555 * 556 * <p> 557 * When creating anchor tags (e.g. <code><xt><a</xt> <xa>href</xa>=<xs>'...'</xs> 558 * <xt>></xt>text<xt></a></xt></code>) in HTML, this setting defines what to set the inner text to. 559 * 560 * <p> 561 * The possible values are: 562 * <ul> 563 * <li class='jc'>{@link AnchorText} 564 * <ul> 565 * <li class='jf'>{@link AnchorText#TO_STRING TO_STRING} (default) - Set to whatever is returned by {@link #toString()} on the object. 566 * <br> 567 * <h5 class='section'>Example:</h5> 568 * <p class='bjson'> 569 * <jc>// Our bean class with a URI property.</jc> 570 * <jk>public class</jk> MyBean { 571 * <jk>public</jk> URI <jf>f1</jf> = URI.<jsm>create</jsm>(<js>"http://www.apache.org?foo=bar#myAnchor"</js>); 572 * } 573 * 574 * <jc>// Serializer with TO_STRING anchor text.</jc> 575 * WriterSerializer <jv>serializer1</jv> = HtmlSerializer.<jsm>create</jsm>().anchorText(<jsf>TO_STRING</jsf>).build(); 576 * 577 * <jc>// Produces: <a href='http://www.apache.org?foo=bar#myAnchor'>http://www.apache.org?foo=bar#myAnchor</a></jc> 578 * String <jv>html</jv> = <jv>serializer1</jv>.serialize(<jk>new</jk> MyBean()); 579 * </p> 580 * <li class='jf'>{@link AnchorText#PROPERTY_NAME PROPERTY_NAME} - Set to the bean property name. 581 * <br> 582 * <h5 class='section'>Example:</h5> 583 * <p class='bjson'> 584 * <jc>// Our bean class with a URI property.</jc> 585 * <jk>public class</jk> MyBean { 586 * <jk>public</jk> URI <jf>f1</jf> = URI.<jsm>create</jsm>(<js>"http://www.apache.org?foo=bar#myAnchor"</js>); 587 * } 588 * 589 * <jc>// Serializer with PROPERTY_NAME anchor text.</jc> 590 * WriterSerializer <jv>serializer1</jv> = HtmlSerializer.<jsm>create</jsm>().anchorText(<jsf>PROPERTY_NAME</jsf>).build(); 591 * 592 * <jc>// Produces: <a href='http://www.apache.org?foo=bar#myAnchor'>f1</a></jc> 593 * String <jv>html</jv> = <jv>serializer1</jv>.serialize(<jk>new</jk> MyBean()); 594 * </p> 595 * <li class='jf'>{@link AnchorText#URI URI} - Set to the URI value. 596 * <br> 597 * <h5 class='section'>Example:</h5> 598 * <p class='bjson'> 599 * <jc>// Our bean class with a URI property.</jc> 600 * <jk>public class</jk> MyBean { 601 * <jk>public</jk> URI <jf>f1</jf> = URI.<jsm>create</jsm>(<js>"http://www.apache.org?foo=bar#myAnchor"</js>); 602 * } 603 * 604 * <jc>// Serializer with URI anchor text.</jc> 605 * WriterSerializer <jv>serializer1</jv> = HtmlSerializer.<jsm>create</jsm>().anchorText(<jsf>URI</jsf>).build(); 606 * 607 * <jc>// Produces: <a href='http://www.apache.org?foo=bar#myAnchor'>http://www.apache.org?foo=bar</a></jc> 608 * String <jv>html</jv> = <jv>serializer1</jv>.serialize(<jk>new</jk> MyBean()); 609 * </p> 610 * <li class='jf'>{@link AnchorText#LAST_TOKEN LAST_TOKEN} - Set to the last token of the URI value. 611 * <br> 612 * <h5 class='section'>Example:</h5> 613 * <p class='bjson'> 614 * <jc>// Our bean class with a URI property.</jc> 615 * <jk>public class</jk> MyBean { 616 * <jk>public</jk> URI <jf>f1</jf> = URI.<jsm>create</jsm>(<js>"http://www.apache.org/foo/bar?baz=qux#myAnchor"</js>); 617 * } 618 * 619 * <jc>// Serializer with LAST_TOKEN anchor text.</jc> 620 * WriterSerializer <jv>serializer1</jv> = HtmlSerializer.<jsm>create</jsm>().anchorText(<jsf>LAST_TOKEN</jsf>).build(); 621 * 622 * <jc>// Produces: <a href='http://www.apache.org/foo/bar?baz=qux#myAnchor'>bar</a></jc> 623 * String <jv>html</jv> = <jv>serializer1</jv>.serialize(<jk>new</jk> MyBean()); 624 * </p> 625 * <li class='jf'>{@link AnchorText#URI_ANCHOR URI_ANCHOR} - Set to the anchor of the URL. 626 * <br> 627 * <h5 class='section'>Example:</h5> 628 * <p class='bjson'> 629 * <jc>// Our bean class with a URI property.</jc> 630 * <jk>public class</jk> MyBean { 631 * <jk>public</jk> URI <jf>f1</jf> = URI.<jsm>create</jsm>(<js>"http://www.apache.org/foo/bar?baz=qux#myAnchor"</js>); 632 * } 633 * 634 * <jc>// Serializer with URI_ANCHOR anchor text.</jc> 635 * WriterSerializer <jv>serializer1</jv> = HtmlSerializer.<jsm>create</jsm>().anchorText(<jsf>URI_ANCHOR</jsf>).build(); 636 * 637 * <jc>// Produces: <a href='http://www.apache.org/foo/bar?baz=qux#myAnchor'>myAnchor</a></jc> 638 * String <jv>html</jv> = <jv>serializer1</jv>.serialize(<jk>new</jk> MyBean()); 639 * </p> 640 * <li class='jf'>{@link AnchorText#CONTEXT_RELATIVE CONTEXT_RELATIVE} - Same as {@link AnchorText#TO_STRING TO_STRING} but assumes it's a context-relative path. 641 * <br> 642 * <h5 class='section'>Example:</h5> 643 * <p class='bjson'> 644 * <jc>// Our bean class with a URI property.</jc> 645 * <jk>public class</jk> MyBean { 646 * <jk>public</jk> URI <jf>f1</jf> = URI.<jsm>create</jsm>(<js>"bar/baz"</js>); 647 * } 648 * 649 * <jc>// Serializer with CONTEXT_RELATIVE anchor text.</jc> 650 * WriterSerializer <jv>serializer1</jv> = HtmlSerializer 651 * .<jsm>create</jsm>() 652 * .anchorText(<jsf>CONTEXT_RELATIVE</jsf>) 653 * .uriResolution(<jsf>ROOT_RELATIVE</jsf>) 654 * .uriRelativity(<jsf>RESOURCE</jsf>) 655 * .uriContext(<js>"{authority:'http://localhost:10000',contextRoot:'/myContext',servletPath:'/myServlet',pathInfo:'/foo'}"</js>) 656 * .build(); 657 * 658 * <jc>// Produces: <a href='/myContext/myServlet/bar/baz'>myServlet/bar/baz</a></jc> 659 * String <jv>html</jv> = <jv>serializer1</jv>.serialize(<jk>new</jk> MyBean()); 660 * </p> 661 * <li class='jf'>{@link AnchorText#SERVLET_RELATIVE SERVLET_RELATIVE} - Same as {@link AnchorText#TO_STRING TO_STRING} but assumes it's a servlet-relative path. 662 * <br> 663 * <h5 class='section'>Example:</h5> 664 * <p class='bjson'> 665 * <jc>// Our bean class with a URI property.</jc> 666 * <jk>public class</jk> MyBean { 667 * <jk>public</jk> URI <jf>f1</jf> = URI.<jsm>create</jsm>(<js>"bar/baz"</js>); 668 * } 669 * 670 * <jc>// Serializer with SERVLET_RELATIVE anchor text.</jc> 671 * WriterSerializer <jv>serializer1</jv> = HtmlSerializer 672 * .<jsm>create</jsm>() 673 * .anchorText(<jsf>SERVLET_RELATIVE</jsf>) 674 * .uriResolution(<jsf>ROOT_RELATIVE</jsf>) 675 * .uriRelativity(<jsf>RESOURCE</jsf>) 676 * .uriContext(<js>"{authority:'http://localhost:10000',contextRoot:'/myContext',servletPath:'/myServlet',pathInfo:'/foo'}"</js>) 677 * .build(); 678 * 679 * <jc>// Produces: <a href='/myContext/myServlet/bar/baz'>bar/baz</a></jc> 680 * String <jv>html</jv> = <jv>serializer1</jv>.serialize(<jk>new</jk> MyBean()); 681 * </p> 682 * <li class='jf'>{@link AnchorText#PATH_RELATIVE PATH_RELATIVE} - Same as {@link AnchorText#TO_STRING TO_STRING} but assumes it's a path-relative path. 683 * <br> 684 * <h5 class='section'>Example:</h5> 685 * <p class='bjson'> 686 * <jc>// Our bean class with a URI property.</jc> 687 * <jk>public class</jk> MyBean { 688 * <jk>public</jk> URI <jf>f1</jf> = URI.<jsm>create</jsm>(<js>"bar/baz"</js>); 689 * } 690 * 691 * <jc>// Serializer with PATH_RELATIVE anchor text.</jc> 692 * WriterSerializer <jv>serializer1</jv> = HtmlSerializer 693 * .<jsm>create</jsm>() 694 * .anchorText(<jsf>PATH_RELATIVE</jsf>) 695 * .uriResolution(<jsf>ROOT_RELATIVE</jsf>) 696 * .uriRelativity(<jsf>PATH_INFO</jsf>) 697 * .uriContext(<js>"{authority:'http://localhost:10000',contextRoot:'/myContext',servletPath:'/myServlet',pathInfo:'/foo'}"</js>) 698 * .build(); 699 * 700 * <jc>// Produces: <a href='/myContext/myServlet/foo/bar/baz'>bar/baz</a></jc> 701 * String <jv>html</jv> = <jv>serializer1</jv>.serialize(<jk>new</jk> MyBean()); 702 * </p> 703 * </ul> 704 * </ul> 705 * 706 * @param value 707 * The new value for this property. 708 * <br>The default is {@link AnchorText#TO_STRING}. 709 * @return This object. 710 */ 711 @FluentSetter 712 public Builder uriAnchorText(AnchorText value) { 713 uriAnchorText = value; 714 return this; 715 } 716 717 // <FluentSetters> 718 719 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 720 public Builder annotations(Annotation...values) { 721 super.annotations(values); 722 return this; 723 } 724 725 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 726 public Builder apply(AnnotationWorkList work) { 727 super.apply(work); 728 return this; 729 } 730 731 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 732 public Builder applyAnnotations(java.lang.Class<?>...fromClasses) { 733 super.applyAnnotations(fromClasses); 734 return this; 735 } 736 737 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 738 public Builder applyAnnotations(Method...fromMethods) { 739 super.applyAnnotations(fromMethods); 740 return this; 741 } 742 743 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 744 public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) { 745 super.cache(value); 746 return this; 747 } 748 749 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 750 public Builder debug() { 751 super.debug(); 752 return this; 753 } 754 755 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 756 public Builder debug(boolean value) { 757 super.debug(value); 758 return this; 759 } 760 761 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 762 public Builder impl(Context value) { 763 super.impl(value); 764 return this; 765 } 766 767 @Override /* GENERATED - org.apache.juneau.Context.Builder */ 768 public Builder type(Class<? extends org.apache.juneau.Context> value) { 769 super.type(value); 770 return this; 771 } 772 773 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 774 public Builder beanClassVisibility(Visibility value) { 775 super.beanClassVisibility(value); 776 return this; 777 } 778 779 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 780 public Builder beanConstructorVisibility(Visibility value) { 781 super.beanConstructorVisibility(value); 782 return this; 783 } 784 785 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 786 public Builder beanContext(BeanContext value) { 787 super.beanContext(value); 788 return this; 789 } 790 791 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 792 public Builder beanContext(BeanContext.Builder value) { 793 super.beanContext(value); 794 return this; 795 } 796 797 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 798 public Builder beanDictionary(java.lang.Class<?>...values) { 799 super.beanDictionary(values); 800 return this; 801 } 802 803 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 804 public Builder beanFieldVisibility(Visibility value) { 805 super.beanFieldVisibility(value); 806 return this; 807 } 808 809 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 810 public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) { 811 super.beanInterceptor(on, value); 812 return this; 813 } 814 815 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 816 public Builder beanMapPutReturnsOldValue() { 817 super.beanMapPutReturnsOldValue(); 818 return this; 819 } 820 821 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 822 public Builder beanMethodVisibility(Visibility value) { 823 super.beanMethodVisibility(value); 824 return this; 825 } 826 827 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 828 public Builder beanProperties(Map<String,Object> values) { 829 super.beanProperties(values); 830 return this; 831 } 832 833 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 834 public Builder beanProperties(Class<?> beanClass, String properties) { 835 super.beanProperties(beanClass, properties); 836 return this; 837 } 838 839 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 840 public Builder beanProperties(String beanClassName, String properties) { 841 super.beanProperties(beanClassName, properties); 842 return this; 843 } 844 845 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 846 public Builder beanPropertiesExcludes(Map<String,Object> values) { 847 super.beanPropertiesExcludes(values); 848 return this; 849 } 850 851 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 852 public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) { 853 super.beanPropertiesExcludes(beanClass, properties); 854 return this; 855 } 856 857 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 858 public Builder beanPropertiesExcludes(String beanClassName, String properties) { 859 super.beanPropertiesExcludes(beanClassName, properties); 860 return this; 861 } 862 863 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 864 public Builder beanPropertiesReadOnly(Map<String,Object> values) { 865 super.beanPropertiesReadOnly(values); 866 return this; 867 } 868 869 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 870 public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) { 871 super.beanPropertiesReadOnly(beanClass, properties); 872 return this; 873 } 874 875 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 876 public Builder beanPropertiesReadOnly(String beanClassName, String properties) { 877 super.beanPropertiesReadOnly(beanClassName, properties); 878 return this; 879 } 880 881 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 882 public Builder beanPropertiesWriteOnly(Map<String,Object> values) { 883 super.beanPropertiesWriteOnly(values); 884 return this; 885 } 886 887 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 888 public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) { 889 super.beanPropertiesWriteOnly(beanClass, properties); 890 return this; 891 } 892 893 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 894 public Builder beanPropertiesWriteOnly(String beanClassName, String properties) { 895 super.beanPropertiesWriteOnly(beanClassName, properties); 896 return this; 897 } 898 899 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 900 public Builder beansRequireDefaultConstructor() { 901 super.beansRequireDefaultConstructor(); 902 return this; 903 } 904 905 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 906 public Builder beansRequireSerializable() { 907 super.beansRequireSerializable(); 908 return this; 909 } 910 911 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 912 public Builder beansRequireSettersForGetters() { 913 super.beansRequireSettersForGetters(); 914 return this; 915 } 916 917 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 918 public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) { 919 super.dictionaryOn(on, values); 920 return this; 921 } 922 923 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 924 public Builder disableBeansRequireSomeProperties() { 925 super.disableBeansRequireSomeProperties(); 926 return this; 927 } 928 929 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 930 public Builder disableIgnoreMissingSetters() { 931 super.disableIgnoreMissingSetters(); 932 return this; 933 } 934 935 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 936 public Builder disableIgnoreTransientFields() { 937 super.disableIgnoreTransientFields(); 938 return this; 939 } 940 941 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 942 public Builder disableIgnoreUnknownNullBeanProperties() { 943 super.disableIgnoreUnknownNullBeanProperties(); 944 return this; 945 } 946 947 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 948 public Builder disableInterfaceProxies() { 949 super.disableInterfaceProxies(); 950 return this; 951 } 952 953 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 954 public <T> Builder example(Class<T> pojoClass, T o) { 955 super.example(pojoClass, o); 956 return this; 957 } 958 959 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 960 public <T> Builder example(Class<T> pojoClass, String json) { 961 super.example(pojoClass, json); 962 return this; 963 } 964 965 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 966 public Builder findFluentSetters() { 967 super.findFluentSetters(); 968 return this; 969 } 970 971 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 972 public Builder findFluentSetters(Class<?> on) { 973 super.findFluentSetters(on); 974 return this; 975 } 976 977 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 978 public Builder ignoreInvocationExceptionsOnGetters() { 979 super.ignoreInvocationExceptionsOnGetters(); 980 return this; 981 } 982 983 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 984 public Builder ignoreInvocationExceptionsOnSetters() { 985 super.ignoreInvocationExceptionsOnSetters(); 986 return this; 987 } 988 989 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 990 public Builder ignoreUnknownBeanProperties() { 991 super.ignoreUnknownBeanProperties(); 992 return this; 993 } 994 995 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 996 public Builder ignoreUnknownEnumValues() { 997 super.ignoreUnknownEnumValues(); 998 return this; 999 } 1000 1001 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1002 public Builder implClass(Class<?> interfaceClass, Class<?> implClass) { 1003 super.implClass(interfaceClass, implClass); 1004 return this; 1005 } 1006 1007 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1008 public Builder implClasses(Map<Class<?>,Class<?>> values) { 1009 super.implClasses(values); 1010 return this; 1011 } 1012 1013 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1014 public Builder interfaceClass(Class<?> on, Class<?> value) { 1015 super.interfaceClass(on, value); 1016 return this; 1017 } 1018 1019 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1020 public Builder interfaces(java.lang.Class<?>...value) { 1021 super.interfaces(value); 1022 return this; 1023 } 1024 1025 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1026 public Builder locale(Locale value) { 1027 super.locale(value); 1028 return this; 1029 } 1030 1031 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1032 public Builder mediaType(MediaType value) { 1033 super.mediaType(value); 1034 return this; 1035 } 1036 1037 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1038 public Builder notBeanClasses(java.lang.Class<?>...values) { 1039 super.notBeanClasses(values); 1040 return this; 1041 } 1042 1043 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1044 public Builder notBeanPackages(String...values) { 1045 super.notBeanPackages(values); 1046 return this; 1047 } 1048 1049 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1050 public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) { 1051 super.propertyNamer(value); 1052 return this; 1053 } 1054 1055 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1056 public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) { 1057 super.propertyNamer(on, value); 1058 return this; 1059 } 1060 1061 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1062 public Builder sortProperties() { 1063 super.sortProperties(); 1064 return this; 1065 } 1066 1067 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1068 public Builder sortProperties(java.lang.Class<?>...on) { 1069 super.sortProperties(on); 1070 return this; 1071 } 1072 1073 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1074 public Builder stopClass(Class<?> on, Class<?> value) { 1075 super.stopClass(on, value); 1076 return this; 1077 } 1078 1079 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1080 public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) { 1081 super.swap(normalClass, swappedClass, swapFunction); 1082 return this; 1083 } 1084 1085 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1086 public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) { 1087 super.swap(normalClass, swappedClass, swapFunction, unswapFunction); 1088 return this; 1089 } 1090 1091 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1092 public Builder swaps(java.lang.Class<?>...values) { 1093 super.swaps(values); 1094 return this; 1095 } 1096 1097 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1098 public Builder timeZone(TimeZone value) { 1099 super.timeZone(value); 1100 return this; 1101 } 1102 1103 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1104 public Builder typeName(Class<?> on, String value) { 1105 super.typeName(on, value); 1106 return this; 1107 } 1108 1109 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1110 public Builder typePropertyName(String value) { 1111 super.typePropertyName(value); 1112 return this; 1113 } 1114 1115 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1116 public Builder typePropertyName(Class<?> on, String value) { 1117 super.typePropertyName(on, value); 1118 return this; 1119 } 1120 1121 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1122 public Builder useEnumNames() { 1123 super.useEnumNames(); 1124 return this; 1125 } 1126 1127 @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ 1128 public Builder useJavaBeanIntrospector() { 1129 super.useJavaBeanIntrospector(); 1130 return this; 1131 } 1132 1133 @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ 1134 public Builder detectRecursions() { 1135 super.detectRecursions(); 1136 return this; 1137 } 1138 1139 @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ 1140 public Builder detectRecursions(boolean value) { 1141 super.detectRecursions(value); 1142 return this; 1143 } 1144 1145 @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ 1146 public Builder ignoreRecursions() { 1147 super.ignoreRecursions(); 1148 return this; 1149 } 1150 1151 @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ 1152 public Builder ignoreRecursions(boolean value) { 1153 super.ignoreRecursions(value); 1154 return this; 1155 } 1156 1157 @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ 1158 public Builder initialDepth(int value) { 1159 super.initialDepth(value); 1160 return this; 1161 } 1162 1163 @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ 1164 public Builder maxDepth(int value) { 1165 super.maxDepth(value); 1166 return this; 1167 } 1168 1169 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1170 public Builder accept(String value) { 1171 super.accept(value); 1172 return this; 1173 } 1174 1175 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1176 public Builder addBeanTypes() { 1177 super.addBeanTypes(); 1178 return this; 1179 } 1180 1181 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1182 public Builder addBeanTypes(boolean value) { 1183 super.addBeanTypes(value); 1184 return this; 1185 } 1186 1187 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1188 public Builder addRootType() { 1189 super.addRootType(); 1190 return this; 1191 } 1192 1193 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1194 public Builder addRootType(boolean value) { 1195 super.addRootType(value); 1196 return this; 1197 } 1198 1199 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1200 public Builder keepNullProperties() { 1201 super.keepNullProperties(); 1202 return this; 1203 } 1204 1205 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1206 public Builder keepNullProperties(boolean value) { 1207 super.keepNullProperties(value); 1208 return this; 1209 } 1210 1211 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1212 public Builder listener(Class<? extends org.apache.juneau.serializer.SerializerListener> value) { 1213 super.listener(value); 1214 return this; 1215 } 1216 1217 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1218 public Builder produces(String value) { 1219 super.produces(value); 1220 return this; 1221 } 1222 1223 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1224 public Builder sortCollections() { 1225 super.sortCollections(); 1226 return this; 1227 } 1228 1229 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1230 public Builder sortCollections(boolean value) { 1231 super.sortCollections(value); 1232 return this; 1233 } 1234 1235 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1236 public Builder sortMaps() { 1237 super.sortMaps(); 1238 return this; 1239 } 1240 1241 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1242 public Builder sortMaps(boolean value) { 1243 super.sortMaps(value); 1244 return this; 1245 } 1246 1247 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1248 public Builder trimEmptyCollections() { 1249 super.trimEmptyCollections(); 1250 return this; 1251 } 1252 1253 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1254 public Builder trimEmptyCollections(boolean value) { 1255 super.trimEmptyCollections(value); 1256 return this; 1257 } 1258 1259 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1260 public Builder trimEmptyMaps() { 1261 super.trimEmptyMaps(); 1262 return this; 1263 } 1264 1265 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1266 public Builder trimEmptyMaps(boolean value) { 1267 super.trimEmptyMaps(value); 1268 return this; 1269 } 1270 1271 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1272 public Builder trimStrings() { 1273 super.trimStrings(); 1274 return this; 1275 } 1276 1277 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1278 public Builder trimStrings(boolean value) { 1279 super.trimStrings(value); 1280 return this; 1281 } 1282 1283 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1284 public Builder uriContext(UriContext value) { 1285 super.uriContext(value); 1286 return this; 1287 } 1288 1289 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1290 public Builder uriRelativity(UriRelativity value) { 1291 super.uriRelativity(value); 1292 return this; 1293 } 1294 1295 @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ 1296 public Builder uriResolution(UriResolution value) { 1297 super.uriResolution(value); 1298 return this; 1299 } 1300 1301 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1302 public Builder fileCharset(Charset value) { 1303 super.fileCharset(value); 1304 return this; 1305 } 1306 1307 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1308 public Builder maxIndent(int value) { 1309 super.maxIndent(value); 1310 return this; 1311 } 1312 1313 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1314 public Builder quoteChar(char value) { 1315 super.quoteChar(value); 1316 return this; 1317 } 1318 1319 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1320 public Builder quoteCharOverride(char value) { 1321 super.quoteCharOverride(value); 1322 return this; 1323 } 1324 1325 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1326 public Builder sq() { 1327 super.sq(); 1328 return this; 1329 } 1330 1331 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1332 public Builder streamCharset(Charset value) { 1333 super.streamCharset(value); 1334 return this; 1335 } 1336 1337 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1338 public Builder useWhitespace() { 1339 super.useWhitespace(); 1340 return this; 1341 } 1342 1343 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1344 public Builder useWhitespace(boolean value) { 1345 super.useWhitespace(value); 1346 return this; 1347 } 1348 1349 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ 1350 public Builder ws() { 1351 super.ws(); 1352 return this; 1353 } 1354 1355 @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ 1356 public Builder addBeanTypesXml() { 1357 super.addBeanTypesXml(); 1358 return this; 1359 } 1360 1361 @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ 1362 public Builder addBeanTypesXml(boolean value) { 1363 super.addBeanTypesXml(value); 1364 return this; 1365 } 1366 1367 @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ 1368 public Builder addNamespaceUrisToRoot() { 1369 super.addNamespaceUrisToRoot(); 1370 return this; 1371 } 1372 1373 @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ 1374 public Builder addNamespaceUrisToRoot(boolean value) { 1375 super.addNamespaceUrisToRoot(value); 1376 return this; 1377 } 1378 1379 @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ 1380 public Builder defaultNamespace(Namespace value) { 1381 super.defaultNamespace(value); 1382 return this; 1383 } 1384 1385 @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ 1386 public Builder disableAutoDetectNamespaces() { 1387 super.disableAutoDetectNamespaces(); 1388 return this; 1389 } 1390 1391 @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ 1392 public Builder disableAutoDetectNamespaces(boolean value) { 1393 super.disableAutoDetectNamespaces(value); 1394 return this; 1395 } 1396 1397 @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ 1398 public Builder enableNamespaces() { 1399 super.enableNamespaces(); 1400 return this; 1401 } 1402 1403 @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ 1404 public Builder enableNamespaces(boolean value) { 1405 super.enableNamespaces(value); 1406 return this; 1407 } 1408 1409 @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ 1410 public Builder namespaces(Namespace...values) { 1411 super.namespaces(values); 1412 return this; 1413 } 1414 1415 @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ 1416 public Builder ns() { 1417 super.ns(); 1418 return this; 1419 } 1420 1421 // </FluentSetters> 1422 } 1423 1424 //------------------------------------------------------------------------------------------------------------------- 1425 // Instance 1426 //------------------------------------------------------------------------------------------------------------------- 1427 1428 final AnchorText uriAnchorText; 1429 final boolean 1430 detectLabelParameters, 1431 detectLinksInStrings, 1432 addKeyValueTableHeaders, 1433 addBeanTypesHtml; 1434 final String labelParameter; 1435 1436 private final Map<ClassMeta<?>,HtmlClassMeta> htmlClassMetas = new ConcurrentHashMap<>(); 1437 private final Map<BeanPropertyMeta,HtmlBeanPropertyMeta> htmlBeanPropertyMetas = new ConcurrentHashMap<>(); 1438 1439 private volatile HtmlSchemaSerializer schemaSerializer; 1440 1441 /** 1442 * Constructor. 1443 * 1444 * @param builder The builder for this object. 1445 */ 1446 public HtmlSerializer(Builder builder) { 1447 super(builder); 1448 detectLabelParameters = ! builder.disableDetectLabelParameters; 1449 detectLinksInStrings = ! builder.disableDetectLinksInStrings; 1450 addKeyValueTableHeaders = builder.addKeyValueTableHeaders; 1451 labelParameter = builder.labelParameter; 1452 uriAnchorText = builder.uriAnchorText; 1453 addBeanTypesHtml = builder.addBeanTypesHtml; 1454 } 1455 1456 @Override /* Context */ 1457 public Builder copy() { 1458 return new Builder(this); 1459 } 1460 1461 @Override /* Context */ 1462 public HtmlSerializerSession.Builder createSession() { 1463 return HtmlSerializerSession.create(this); 1464 } 1465 1466 @Override /* Context */ 1467 public HtmlSerializerSession getSession() { 1468 return createSession().build(); 1469 } 1470 1471 /** 1472 * Returns the schema serializer. 1473 * 1474 * @return The schema serializer. 1475 */ 1476 public HtmlSerializer getSchemaSerializer() { 1477 if (schemaSerializer == null) 1478 schemaSerializer = HtmlSchemaSerializer.create().beanContext(getBeanContext()).build(); 1479 return schemaSerializer; 1480 } 1481 1482 //----------------------------------------------------------------------------------------------------------------- 1483 // Extended metadata 1484 //----------------------------------------------------------------------------------------------------------------- 1485 1486 @Override /* HtmlMetaProvider */ 1487 public HtmlClassMeta getHtmlClassMeta(ClassMeta<?> cm) { 1488 HtmlClassMeta m = htmlClassMetas.get(cm); 1489 if (m == null) { 1490 m = new HtmlClassMeta(cm, this); 1491 htmlClassMetas.put(cm, m); 1492 } 1493 return m; 1494 } 1495 1496 @Override /* HtmlMetaProvider */ 1497 public HtmlBeanPropertyMeta getHtmlBeanPropertyMeta(BeanPropertyMeta bpm) { 1498 if (bpm == null) 1499 return HtmlBeanPropertyMeta.DEFAULT; 1500 HtmlBeanPropertyMeta m = htmlBeanPropertyMetas.get(bpm); 1501 if (m == null) { 1502 m = new HtmlBeanPropertyMeta(bpm.getDelegateFor(), this); 1503 htmlBeanPropertyMetas.put(bpm, m); 1504 } 1505 return m; 1506 } 1507 1508 //----------------------------------------------------------------------------------------------------------------- 1509 // Properties 1510 //----------------------------------------------------------------------------------------------------------------- 1511 1512 /** 1513 * Add <js>"_type"</js> properties when needed. 1514 * 1515 * @see Builder#addBeanTypesHtml() 1516 * @return 1517 * <jk>true</jk> if <js>"_type"</js> properties will be added to beans if their type cannot be inferred 1518 * through reflection. 1519 */ 1520 @Override 1521 protected final boolean isAddBeanTypes() { 1522 return addBeanTypesHtml || super.isAddBeanTypes(); 1523 } 1524 1525 /** 1526 * Add key/value headers on bean/map tables. 1527 * 1528 * @see Builder#addKeyValueTableHeaders() 1529 * @return 1530 * <jk>true</jk> if <bc>key</bc> and <bc>value</bc> column headers are added to tables. 1531 */ 1532 protected final boolean isAddKeyValueTableHeaders() { 1533 return addKeyValueTableHeaders; 1534 } 1535 1536 /** 1537 * Look for link labels in URIs. 1538 * 1539 * @see Builder#disableDetectLabelParameters() 1540 * @return 1541 * <jk>true</jk> if we should look for URL label parameters (e.g. <js>"?label=foobar"</js>). 1542 */ 1543 protected final boolean isDetectLabelParameters() { 1544 return detectLabelParameters; 1545 } 1546 1547 /** 1548 * Look for URLs in {@link String Strings}. 1549 * 1550 * @see Builder#disableDetectLinksInStrings() 1551 * @return 1552 * <jk>true</jk> if we should automatically convert strings to URLs if they look like a URL. 1553 */ 1554 protected final boolean isDetectLinksInStrings() { 1555 return detectLinksInStrings; 1556 } 1557 1558 /** 1559 * Link label parameter name. 1560 * 1561 * @see Builder#labelParameter(String) 1562 * @return 1563 * The parameter name to look for when resolving link labels. 1564 */ 1565 protected final String getLabelParameter() { 1566 return labelParameter; 1567 } 1568 1569 /** 1570 * Anchor text source. 1571 * 1572 * @see Builder#uriAnchorText(AnchorText) 1573 * @return 1574 * When creating anchor tags (e.g. <code><xt><a</xt> <xa>href</xa>=<xs>'...'</xs> 1575 * <xt>></xt>text<xt></a></xt></code>) in HTML, this setting defines what to set the inner text to. 1576 */ 1577 protected final AnchorText getUriAnchorText() { 1578 return uriAnchorText; 1579 } 1580 1581 //----------------------------------------------------------------------------------------------------------------- 1582 // Other methods 1583 //----------------------------------------------------------------------------------------------------------------- 1584 1585 @Override /* Context */ 1586 protected JsonMap properties() { 1587 return filteredMap() 1588 .append("uriAnchorText", uriAnchorText) 1589 .append("detectLabelParameters", detectLabelParameters) 1590 .append("detectLinksInStrings", detectLinksInStrings) 1591 .append("labelParameter", labelParameter) 1592 .append("addKeyValueTableHeaders", addKeyValueTableHeaders) 1593 .append("addBeanTypesHtml", addBeanTypesHtml); 1594 } 1595}