All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.juneau.html.HtmlSerializer Maven / Gradle / Ivy

// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau.html;

import static org.apache.juneau.collections.JsonMap.*;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.nio.charset.*;
import java.util.*;
import java.util.concurrent.*;

import org.apache.juneau.*;
import org.apache.juneau.collections.*;
import org.apache.juneau.html.annotation.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.utils.*;
import org.apache.juneau.xml.*;

/**
 * Serializes POJO models to HTML.
 *
 * 
Media types
*

* Handles Accept types: text/html *

* Produces Content-Type types: text/html * *

Description
*

* The conversion is as follows... *

    *
  • * {@link Map Maps} (e.g. {@link HashMap}, {@link TreeMap}) and beans are converted to HTML tables with * 'key' and 'value' columns. *
  • * {@link Collection Collections} (e.g. {@link HashSet}, {@link LinkedList}) and Java arrays are converted * to HTML ordered lists. *
  • * {@code Collections} of {@code Maps} and beans are converted to HTML tables with keys as headers. *
  • * Everything else is converted to text. *
* *

* This serializer provides several serialization options. Typically, one of the predefined DEFAULT * serializers will be sufficient. * However, custom serializers can be constructed to fine-tune behavior. * *

* The {@link HtmlLink} annotation can be used on beans to add hyperlinks to the output. * *

Behavior-specific subclasses
*

* The following direct subclasses are provided for convenience: *

    *
  • * {@link Sq} - Default serializer, single quotes. *
  • * {@link SqReadable} - Default serializer, single quotes, whitespace added. *
* *
Example:
*

* // Use one of the default serializers to serialize a POJO * String html = HtmlSerializer.DEFAULT.serialize(someObject); * * // Create a custom serializer that doesn't use whitespace and newlines * HtmlSerializer serializer = HtmlSerializer.create().ws().build(); * * // Same as above, except uses cloning * HtmlSerializer serializer = HtmlSerializer.DEFAULT.copy().ws().build(); * * // Serialize POJOs to HTML * * // Produces: * // <ul><li>1<li>2<li>3</ul> * List list = JsonList.of(1, 2, 3); * String html = HtmlSerializer.DEFAULT.serialize(list); * * // Produces: * // <table> * // <tr><th>firstName</th><th>lastName</th></tr> * // <tr><td>Bob</td><td>Costas</td></tr> * // <tr><td>Billy</td><td>TheKid</td></tr> * // <tr><td>Barney</td><td>Miller</td></tr> * // </table> * html = JsonList.of( * JsonMap.ofJson("{firstName:'Bob',lastName:'Costas'}"), * JsonMap.ofJson("{firstName:'Billy',lastName:'TheKid'}"), * JsonMap.ofJson("{firstName:'Barney',lastName:'Miller'}") * ); * String html = HtmlSerializer.DEFAULT.serialize(list); * * // Produces: * // <table> * // <tr><th>key</th><th>value</th></tr> * // <tr><td>foo</td><td>bar</td></tr> * // <tr><td>baz</td><td>123</td></tr> * // </table> * Map map = JsonMap.ofJson("{foo:'bar',baz:123}"); * String html = HtmlSerializer.DEFAULT.serialize(map); * * // HTML elements can be nested arbitrarily deep * // Produces: * // <table> * // <tr><th>key</th><th>value</th></tr> * // <tr><td>foo</td><td>bar</td></tr> * // <tr><td>baz</td><td>123</td></tr> * // <tr><td>someNumbers</td><td><ul><li>1<li>2<li>3</ul></td></tr> * // <tr><td>someSubMap</td><td> * // <table> * // <tr><th>key</th><th>value</th></tr> * // <tr><td>a</td><td>b</td></tr> * // </table> * // </td></tr> * // </table> * Map map = JsonMap.ofJson("{foo:'bar',baz:123}"); * map.put("someNumbers", JsonList.of(1, 2, 3)); * map.put("someSubMap", JsonMap.ofJson("{a:'b'}")); * String html = HtmlSerializer.DEFAULT.serialize(map); *

* *
Notes:
    *
  • This class is thread safe and reusable. *
* *
See Also:
*/ public class HtmlSerializer extends XmlSerializer implements HtmlMetaProvider { //------------------------------------------------------------------------------------------------------------------- // Static //------------------------------------------------------------------------------------------------------------------- /** Default serializer, all default settings. */ public static final HtmlSerializer DEFAULT = new HtmlSerializer(create()); /** Default serializer, single quotes. */ public static final HtmlSerializer DEFAULT_SQ = new HtmlSerializer.Sq(create()); /** Default serializer, single quotes, whitespace added. */ public static final HtmlSerializer DEFAULT_SQ_READABLE = new HtmlSerializer.SqReadable(create()); /** * Creates a new builder for this object. * * @return A new builder. */ public static Builder create() { return new Builder(); } //------------------------------------------------------------------------------------------------------------------- // Static subclasses //------------------------------------------------------------------------------------------------------------------- /** Default serializer, single quotes. */ public static class Sq extends HtmlSerializer { /** * Constructor. * * @param builder The builder for this object. */ public Sq(Builder builder) { super(builder.quoteChar('\'')); } } /** Default serializer, single quotes, whitespace added. */ public static class SqReadable extends HtmlSerializer { /** * Constructor. * * @param builder The builder for this object. */ public SqReadable(Builder builder) { super(builder.quoteChar('\'').useWhitespace()); } } //------------------------------------------------------------------------------------------------------------------- // Instance //------------------------------------------------------------------------------------------------------------------- /** * Builder class. */ @FluentSetters public static class Builder extends XmlSerializer.Builder { private static final Cache CACHE = Cache.of(HashKey.class, HtmlSerializer.class).build(); boolean addBeanTypesHtml, addKeyValueTableHeaders, disableDetectLabelParameters, disableDetectLinksInStrings; String labelParameter; AnchorText uriAnchorText; /** * Constructor, default settings. */ protected Builder() { produces("text/html"); addBeanTypesHtml = env("HtmlSerializer.addBeanTypesHtml", false); addKeyValueTableHeaders = env("HtmlSerializer.addKeyValueTableHeaders", false); disableDetectLabelParameters = env("HtmlSerializer.disableDetectLabelParameters", false); disableDetectLinksInStrings = env("HtmlSerializer.disableDetectLinksInStrings", false); uriAnchorText = env("HtmlSerializer.uriAnchorText", AnchorText.TO_STRING); labelParameter = env("HtmlSerializer.labelParameter", "label"); } /** * Copy constructor. * * @param copyFrom The bean to copy from. */ protected Builder(HtmlSerializer copyFrom) { super(copyFrom); addBeanTypesHtml = copyFrom.addBeanTypesHtml; addKeyValueTableHeaders = copyFrom.addKeyValueTableHeaders; disableDetectLabelParameters = ! copyFrom.detectLabelParameters; disableDetectLinksInStrings = ! copyFrom.detectLinksInStrings; labelParameter = copyFrom.labelParameter; uriAnchorText = copyFrom.uriAnchorText; } /** * Copy constructor. * * @param copyFrom The builder to copy from. */ protected Builder(Builder copyFrom) { super(copyFrom); addBeanTypesHtml = copyFrom.addBeanTypesHtml; addKeyValueTableHeaders = copyFrom.addKeyValueTableHeaders; disableDetectLabelParameters = copyFrom.disableDetectLabelParameters; disableDetectLinksInStrings = copyFrom.disableDetectLinksInStrings; labelParameter = copyFrom.labelParameter; uriAnchorText = copyFrom.uriAnchorText; } @Override /* Context.Builder */ public Builder copy() { return new Builder(this); } @Override /* Context.Builder */ public HtmlSerializer build() { return cache(CACHE).build(HtmlSerializer.class); } @Override /* Context.Builder */ public HashKey hashKey() { return HashKey.of( super.hashKey(), addBeanTypesHtml, addKeyValueTableHeaders, disableDetectLabelParameters, disableDetectLinksInStrings, labelParameter, uriAnchorText ); } //----------------------------------------------------------------------------------------------------------------- // Properties //----------------------------------------------------------------------------------------------------------------- /** * Add "_type" properties when needed. * *

* If true, then "_type" properties will be added to beans if their type cannot be inferred * through reflection. * *

* When present, this value overrides the {@link org.apache.juneau.serializer.Serializer.Builder#addBeanTypes()} setting and is * provided to customize the behavior of specific serializers in a {@link SerializerSet}. * * @return This object. */ @FluentSetter public Builder addBeanTypesHtml() { return addBeanTypesHtml(true); } /** * Same as {@link #addBeanTypesHtml()} but allows you to explicitly specify the value. * * @param value The value for this setting. * @return This object. */ @FluentSetter public Builder addBeanTypesHtml(boolean value) { addBeanTypesHtml = value; return this; } /** * HtmlSerializer configuration property:  Add key/value headers on bean/map tables. * *

* When enabled, key and value column headers are added to tables. * *

Example:
*

* // Our bean class. * public class MyBean { * public String f1 = "foo"; * public String f2 = "bar"; * } * * // Serializer without headers. * WriterSerializer serializer1 = HtmlSerializer.DEFAULT; * * // Serializer with headers. * WriterSerializer serializer2 = HtmlSerializer * .create() * .addKeyValueTableHeaders() * .build(); * * String withoutHeaders = serializer1.serialize(new MyBean()); * String withHeaders = serializer2.serialize(new MyBean()); *

* *

* The following shows the difference between the two generated outputs: * *

* * * * * * * * *
withoutHeaderswithHeaders
* * * *
f1foo
f2bar
*
* * * * *
keyvalue
f1foo
f2bar
*
* * @return This object. */ @FluentSetter public Builder addKeyValueTableHeaders() { return addKeyValueTableHeaders(true); } /** * Same as {@link #addKeyValueTableHeaders()} but allows you to explicitly specify the value. * * @param value The value for this setting. * @return This object. */ @FluentSetter public Builder addKeyValueTableHeaders(boolean value) { addKeyValueTableHeaders = value; return this; } /** * HtmlSerializer configuration property:  Don't look for URLs in {@link String Strings}. * *

* Disables the feature where if a string looks like a URL (i.e. starts with "http://" or "https://", then treat it like a URL * and make it into a hyperlink based on the rules specified by {@link Builder#uriAnchorText(AnchorText)}. * *

Example:
*

* // Our bean class with a property containing what looks like a URL. * public class MyBean { * public String f1 = "http://www.apache.org"; * } * * // Serializer with link detection. * WriterSerializer serializer1 = HtmlSerializer * .create() * .addKeyValueTableHeaders() * .build(); * * // Serializer without link detection. * WriterSerializer serializer2 = HtmlSerializer * .create() * .addKeyValueTableHeaders() * .disableDetectLinksInStrings() * .build(); * * String withLinks = serializer1.serialize(new MyBean()); * String withoutLinks = serializer2.serialize(new MyBean()); *

* *

* The following shows the difference between the two generated outputs: * *

* * * * * * * * *
withLinkswithoutLinks
* * * *
keyvalue
f1http://www.apache.org
*
* * * *
keyvalue
f1http://www.apache.org
*
* * @return This object. */ @FluentSetter public Builder disableDetectLinksInStrings() { return disableDetectLinksInStrings(true); } /** * Same as {@link #disableDetectLinksInStrings()} but allows you to explicitly specify the value. * * @param value The value for this setting. * @return This object. */ @FluentSetter public Builder disableDetectLinksInStrings(boolean value) { disableDetectLinksInStrings = value; return this; } /** * HtmlSerializer configuration property:  Link label parameter name. * *

* The parameter name to look for when resolving link labels}. * * @param value * The new value for this property. *
The default is "label". * @return This object. */ @FluentSetter public Builder labelParameter(String value) { labelParameter = value; return this; } /** * HtmlSerializer configuration property:  Dont look for link labels in URIs. * *

* Disables the feature where if the URL has a label parameter (e.g. "?label=foobar"), then use that as the anchor text of the link. * *

* The parameter name can be changed via the {@link #labelParameter(String)} property. * *

Example:
*

* // Our bean class with a property containing what looks like a URL. * public class MyBean { * public URI f1 = URI.create("http://www.apache.org?label=Apache%20Foundation"); * } * * // Serializer with label detection. * WriterSerializer serializer1 = HtmlSerializer * .create() * .addKeyValueTableHeaders() * .build(); * * // Serializer without label detection. * WriterSerializer serializer2 = HtmlSerializer * .create() * .addKeyValueTableHeaders() * .disableDetectLabelParameters() * .build(); * * String withLabels = serializer1.serialize(new MyBean()); * String withoutLabels = serializer2.serialize(new MyBean()); *

* *

* The following shows the difference between the two generated outputs. *
Note that they're both hyperlinks, but the anchor text differs: * *

* * * * * * * * *
withLabelswithoutLabels
* * * *
keyvalue
f1Apache Foundation
*
* * * *
keyvalue
f1http://www.apache.org?label=Apache%20Foundation
*
* * @return This object. */ @FluentSetter public Builder disableDetectLabelParameters() { return disableDetectLabelParameters(true); } /** * Same as {@link #disableDetectLabelParameters()} but allows you to explicitly specify the value. * * @param value The value for this setting. * @return This object. */ @FluentSetter public Builder disableDetectLabelParameters(boolean value) { disableDetectLabelParameters = value; return this; } /** * HtmlSerializer configuration property:  Anchor text source. * *

* When creating anchor tags (e.g. <a href='...' * >text</a>) in HTML, this setting defines what to set the inner text to. * *

* The possible values are: *

    *
  • {@link AnchorText} *
      *
    • {@link AnchorText#TO_STRING TO_STRING} (default) - Set to whatever is returned by {@link #toString()} on the object. *
      *
      Example:
      *

      * // Our bean class with a URI property. * public class MyBean { * public URI f1 = URI.create("http://www.apache.org?foo=bar#myAnchor"); * } * * // Serializer with TO_STRING anchor text. * WriterSerializer serializer1 = HtmlSerializer.create().anchorText(TO_STRING).build(); * * // Produces: <a href='http://www.apache.org?foo=bar#myAnchor'>http://www.apache.org?foo=bar#myAnchor</a> * String html = serializer1.serialize(new MyBean()); *

      *
    • {@link AnchorText#PROPERTY_NAME PROPERTY_NAME} - Set to the bean property name. *
      *
      Example:
      *

      * // Our bean class with a URI property. * public class MyBean { * public URI f1 = URI.create("http://www.apache.org?foo=bar#myAnchor"); * } * * // Serializer with PROPERTY_NAME anchor text. * WriterSerializer serializer1 = HtmlSerializer.create().anchorText(PROPERTY_NAME).build(); * * // Produces: <a href='http://www.apache.org?foo=bar#myAnchor'>f1</a> * String html = serializer1.serialize(new MyBean()); *

      *
    • {@link AnchorText#URI URI} - Set to the URI value. *
      *
      Example:
      *

      * // Our bean class with a URI property. * public class MyBean { * public URI f1 = URI.create("http://www.apache.org?foo=bar#myAnchor"); * } * * // Serializer with URI anchor text. * WriterSerializer serializer1 = HtmlSerializer.create().anchorText(URI).build(); * * // Produces: <a href='http://www.apache.org?foo=bar#myAnchor'>http://www.apache.org?foo=bar</a> * String html = serializer1.serialize(new MyBean()); *

      *
    • {@link AnchorText#LAST_TOKEN LAST_TOKEN} - Set to the last token of the URI value. *
      *
      Example:
      *

      * // Our bean class with a URI property. * public class MyBean { * public URI f1 = URI.create("http://www.apache.org/foo/bar?baz=qux#myAnchor"); * } * * // Serializer with LAST_TOKEN anchor text. * WriterSerializer serializer1 = HtmlSerializer.create().anchorText(LAST_TOKEN).build(); * * // Produces: <a href='http://www.apache.org/foo/bar?baz=qux#myAnchor'>bar</a> * String html = serializer1.serialize(new MyBean()); *

      *
    • {@link AnchorText#URI_ANCHOR URI_ANCHOR} - Set to the anchor of the URL. *
      *
      Example:
      *

      * // Our bean class with a URI property. * public class MyBean { * public URI f1 = URI.create("http://www.apache.org/foo/bar?baz=qux#myAnchor"); * } * * // Serializer with URI_ANCHOR anchor text. * WriterSerializer serializer1 = HtmlSerializer.create().anchorText(URI_ANCHOR).build(); * * // Produces: <a href='http://www.apache.org/foo/bar?baz=qux#myAnchor'>myAnchor</a> * String html = serializer1.serialize(new MyBean()); *

      *
    • {@link AnchorText#CONTEXT_RELATIVE CONTEXT_RELATIVE} - Same as {@link AnchorText#TO_STRING TO_STRING} but assumes it's a context-relative path. *
      *
      Example:
      *

      * // Our bean class with a URI property. * public class MyBean { * public URI f1 = URI.create("bar/baz"); * } * * // Serializer with CONTEXT_RELATIVE anchor text. * WriterSerializer serializer1 = HtmlSerializer * .create() * .anchorText(CONTEXT_RELATIVE) * .uriResolution(ROOT_RELATIVE) * .uriRelativity(RESOURCE) * .uriContext("{authority:'http://localhost:10000',contextRoot:'/myContext',servletPath:'/myServlet',pathInfo:'/foo'}") * .build(); * * // Produces: <a href='/myContext/myServlet/bar/baz'>myServlet/bar/baz</a> * String html = serializer1.serialize(new MyBean()); *

      *
    • {@link AnchorText#SERVLET_RELATIVE SERVLET_RELATIVE} - Same as {@link AnchorText#TO_STRING TO_STRING} but assumes it's a servlet-relative path. *
      *
      Example:
      *

      * // Our bean class with a URI property. * public class MyBean { * public URI f1 = URI.create("bar/baz"); * } * * // Serializer with SERVLET_RELATIVE anchor text. * WriterSerializer serializer1 = HtmlSerializer * .create() * .anchorText(SERVLET_RELATIVE) * .uriResolution(ROOT_RELATIVE) * .uriRelativity(RESOURCE) * .uriContext("{authority:'http://localhost:10000',contextRoot:'/myContext',servletPath:'/myServlet',pathInfo:'/foo'}") * .build(); * * // Produces: <a href='/myContext/myServlet/bar/baz'>bar/baz</a> * String html = serializer1.serialize(new MyBean()); *

      *
    • {@link AnchorText#PATH_RELATIVE PATH_RELATIVE} - Same as {@link AnchorText#TO_STRING TO_STRING} but assumes it's a path-relative path. *
      *
      Example:
      *

      * // Our bean class with a URI property. * public class MyBean { * public URI f1 = URI.create("bar/baz"); * } * * // Serializer with PATH_RELATIVE anchor text. * WriterSerializer serializer1 = HtmlSerializer * .create() * .anchorText(PATH_RELATIVE) * .uriResolution(ROOT_RELATIVE) * .uriRelativity(PATH_INFO) * .uriContext("{authority:'http://localhost:10000',contextRoot:'/myContext',servletPath:'/myServlet',pathInfo:'/foo'}") * .build(); * * // Produces: <a href='/myContext/myServlet/foo/bar/baz'>bar/baz</a> * String html = serializer1.serialize(new MyBean()); *

      *
    *
* * @param value * The new value for this property. *
The default is {@link AnchorText#TO_STRING}. * @return This object. */ @FluentSetter public Builder uriAnchorText(AnchorText value) { uriAnchorText = value; return this; } // @Override /* GENERATED - org.apache.juneau.Context.Builder */ public Builder annotations(Annotation...values) { super.annotations(values); return this; } @Override /* GENERATED - org.apache.juneau.Context.Builder */ public Builder apply(AnnotationWorkList work) { super.apply(work); return this; } @Override /* GENERATED - org.apache.juneau.Context.Builder */ public Builder applyAnnotations(java.lang.Class...fromClasses) { super.applyAnnotations(fromClasses); return this; } @Override /* GENERATED - org.apache.juneau.Context.Builder */ public Builder applyAnnotations(Method...fromMethods) { super.applyAnnotations(fromMethods); return this; } @Override /* GENERATED - org.apache.juneau.Context.Builder */ public Builder cache(Cache value) { super.cache(value); return this; } @Override /* GENERATED - org.apache.juneau.Context.Builder */ public Builder debug() { super.debug(); return this; } @Override /* GENERATED - org.apache.juneau.Context.Builder */ public Builder debug(boolean value) { super.debug(value); return this; } @Override /* GENERATED - org.apache.juneau.Context.Builder */ public Builder impl(Context value) { super.impl(value); return this; } @Override /* GENERATED - org.apache.juneau.Context.Builder */ public Builder type(Class value) { super.type(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanClassVisibility(Visibility value) { super.beanClassVisibility(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanConstructorVisibility(Visibility value) { super.beanConstructorVisibility(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanContext(BeanContext value) { super.beanContext(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanContext(BeanContext.Builder value) { super.beanContext(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanDictionary(java.lang.Class...values) { super.beanDictionary(values); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanFieldVisibility(Visibility value) { super.beanFieldVisibility(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanInterceptor(Class on, Class> value) { super.beanInterceptor(on, value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanMapPutReturnsOldValue() { super.beanMapPutReturnsOldValue(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanMethodVisibility(Visibility value) { super.beanMethodVisibility(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanProperties(Map values) { super.beanProperties(values); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanProperties(Class beanClass, String properties) { super.beanProperties(beanClass, properties); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanProperties(String beanClassName, String properties) { super.beanProperties(beanClassName, properties); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanPropertiesExcludes(Map values) { super.beanPropertiesExcludes(values); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanPropertiesExcludes(Class beanClass, String properties) { super.beanPropertiesExcludes(beanClass, properties); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanPropertiesExcludes(String beanClassName, String properties) { super.beanPropertiesExcludes(beanClassName, properties); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanPropertiesReadOnly(Map values) { super.beanPropertiesReadOnly(values); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanPropertiesReadOnly(Class beanClass, String properties) { super.beanPropertiesReadOnly(beanClass, properties); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanPropertiesReadOnly(String beanClassName, String properties) { super.beanPropertiesReadOnly(beanClassName, properties); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanPropertiesWriteOnly(Map values) { super.beanPropertiesWriteOnly(values); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanPropertiesWriteOnly(Class beanClass, String properties) { super.beanPropertiesWriteOnly(beanClass, properties); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beanPropertiesWriteOnly(String beanClassName, String properties) { super.beanPropertiesWriteOnly(beanClassName, properties); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beansRequireDefaultConstructor() { super.beansRequireDefaultConstructor(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beansRequireSerializable() { super.beansRequireSerializable(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder beansRequireSettersForGetters() { super.beansRequireSettersForGetters(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder dictionaryOn(Class on, java.lang.Class...values) { super.dictionaryOn(on, values); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder disableBeansRequireSomeProperties() { super.disableBeansRequireSomeProperties(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder disableIgnoreMissingSetters() { super.disableIgnoreMissingSetters(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder disableIgnoreTransientFields() { super.disableIgnoreTransientFields(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder disableIgnoreUnknownNullBeanProperties() { super.disableIgnoreUnknownNullBeanProperties(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder disableInterfaceProxies() { super.disableInterfaceProxies(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder example(Class pojoClass, T o) { super.example(pojoClass, o); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder example(Class pojoClass, String json) { super.example(pojoClass, json); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder findFluentSetters() { super.findFluentSetters(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder findFluentSetters(Class on) { super.findFluentSetters(on); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder ignoreInvocationExceptionsOnGetters() { super.ignoreInvocationExceptionsOnGetters(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder ignoreInvocationExceptionsOnSetters() { super.ignoreInvocationExceptionsOnSetters(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder ignoreUnknownBeanProperties() { super.ignoreUnknownBeanProperties(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder ignoreUnknownEnumValues() { super.ignoreUnknownEnumValues(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder implClass(Class interfaceClass, Class implClass) { super.implClass(interfaceClass, implClass); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder implClasses(Map,Class> values) { super.implClasses(values); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder interfaceClass(Class on, Class value) { super.interfaceClass(on, value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder interfaces(java.lang.Class...value) { super.interfaces(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder locale(Locale value) { super.locale(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder mediaType(MediaType value) { super.mediaType(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder notBeanClasses(java.lang.Class...values) { super.notBeanClasses(values); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder notBeanPackages(String...values) { super.notBeanPackages(values); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder propertyNamer(Class value) { super.propertyNamer(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder propertyNamer(Class on, Class value) { super.propertyNamer(on, value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder sortProperties() { super.sortProperties(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder sortProperties(java.lang.Class...on) { super.sortProperties(on); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder stopClass(Class on, Class value) { super.stopClass(on, value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder swap(Class normalClass, Class swappedClass, ThrowingFunction swapFunction) { super.swap(normalClass, swappedClass, swapFunction); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder swap(Class normalClass, Class swappedClass, ThrowingFunction swapFunction, ThrowingFunction unswapFunction) { super.swap(normalClass, swappedClass, swapFunction, unswapFunction); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder swaps(java.lang.Class...values) { super.swaps(values); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder timeZone(TimeZone value) { super.timeZone(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder typeName(Class on, String value) { super.typeName(on, value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder typePropertyName(String value) { super.typePropertyName(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder typePropertyName(Class on, String value) { super.typePropertyName(on, value); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder useEnumNames() { super.useEnumNames(); return this; } @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */ public Builder useJavaBeanIntrospector() { super.useJavaBeanIntrospector(); return this; } @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ public Builder detectRecursions() { super.detectRecursions(); return this; } @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ public Builder detectRecursions(boolean value) { super.detectRecursions(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ public Builder ignoreRecursions() { super.ignoreRecursions(); return this; } @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ public Builder ignoreRecursions(boolean value) { super.ignoreRecursions(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ public Builder initialDepth(int value) { super.initialDepth(value); return this; } @Override /* GENERATED - org.apache.juneau.BeanTraverseContext.Builder */ public Builder maxDepth(int value) { super.maxDepth(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder accept(String value) { super.accept(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder addBeanTypes() { super.addBeanTypes(); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder addBeanTypes(boolean value) { super.addBeanTypes(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder addRootType() { super.addRootType(); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder addRootType(boolean value) { super.addRootType(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder keepNullProperties() { super.keepNullProperties(); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder keepNullProperties(boolean value) { super.keepNullProperties(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder listener(Class value) { super.listener(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder produces(String value) { super.produces(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder sortCollections() { super.sortCollections(); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder sortCollections(boolean value) { super.sortCollections(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder sortMaps() { super.sortMaps(); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder sortMaps(boolean value) { super.sortMaps(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder trimEmptyCollections() { super.trimEmptyCollections(); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder trimEmptyCollections(boolean value) { super.trimEmptyCollections(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder trimEmptyMaps() { super.trimEmptyMaps(); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder trimEmptyMaps(boolean value) { super.trimEmptyMaps(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder trimStrings() { super.trimStrings(); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder trimStrings(boolean value) { super.trimStrings(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder uriContext(UriContext value) { super.uriContext(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder uriRelativity(UriRelativity value) { super.uriRelativity(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.Serializer.Builder */ public Builder uriResolution(UriResolution value) { super.uriResolution(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ public Builder fileCharset(Charset value) { super.fileCharset(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ public Builder maxIndent(int value) { super.maxIndent(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ public Builder quoteChar(char value) { super.quoteChar(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ public Builder quoteCharOverride(char value) { super.quoteCharOverride(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ public Builder sq() { super.sq(); return this; } @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ public Builder streamCharset(Charset value) { super.streamCharset(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ public Builder useWhitespace() { super.useWhitespace(); return this; } @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ public Builder useWhitespace(boolean value) { super.useWhitespace(value); return this; } @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializer.Builder */ public Builder ws() { super.ws(); return this; } @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ public Builder addBeanTypesXml() { super.addBeanTypesXml(); return this; } @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ public Builder addBeanTypesXml(boolean value) { super.addBeanTypesXml(value); return this; } @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ public Builder addNamespaceUrisToRoot() { super.addNamespaceUrisToRoot(); return this; } @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ public Builder addNamespaceUrisToRoot(boolean value) { super.addNamespaceUrisToRoot(value); return this; } @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ public Builder defaultNamespace(Namespace value) { super.defaultNamespace(value); return this; } @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ public Builder disableAutoDetectNamespaces() { super.disableAutoDetectNamespaces(); return this; } @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ public Builder disableAutoDetectNamespaces(boolean value) { super.disableAutoDetectNamespaces(value); return this; } @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ public Builder enableNamespaces() { super.enableNamespaces(); return this; } @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ public Builder enableNamespaces(boolean value) { super.enableNamespaces(value); return this; } @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ public Builder namespaces(Namespace...values) { super.namespaces(values); return this; } @Override /* GENERATED - org.apache.juneau.xml.XmlSerializer.Builder */ public Builder ns() { super.ns(); return this; } // } //------------------------------------------------------------------------------------------------------------------- // Instance //------------------------------------------------------------------------------------------------------------------- final AnchorText uriAnchorText; final boolean detectLabelParameters, detectLinksInStrings, addKeyValueTableHeaders, addBeanTypesHtml; final String labelParameter; private final Map,HtmlClassMeta> htmlClassMetas = new ConcurrentHashMap<>(); private final Map htmlBeanPropertyMetas = new ConcurrentHashMap<>(); private volatile HtmlSchemaSerializer schemaSerializer; /** * Constructor. * * @param builder The builder for this object. */ public HtmlSerializer(Builder builder) { super(builder); detectLabelParameters = ! builder.disableDetectLabelParameters; detectLinksInStrings = ! builder.disableDetectLinksInStrings; addKeyValueTableHeaders = builder.addKeyValueTableHeaders; labelParameter = builder.labelParameter; uriAnchorText = builder.uriAnchorText; addBeanTypesHtml = builder.addBeanTypesHtml; } @Override /* Context */ public Builder copy() { return new Builder(this); } @Override /* Context */ public HtmlSerializerSession.Builder createSession() { return HtmlSerializerSession.create(this); } @Override /* Context */ public HtmlSerializerSession getSession() { return createSession().build(); } /** * Returns the schema serializer. * * @return The schema serializer. */ public HtmlSerializer getSchemaSerializer() { if (schemaSerializer == null) schemaSerializer = HtmlSchemaSerializer.create().beanContext(getBeanContext()).build(); return schemaSerializer; } //----------------------------------------------------------------------------------------------------------------- // Extended metadata //----------------------------------------------------------------------------------------------------------------- @Override /* HtmlMetaProvider */ public HtmlClassMeta getHtmlClassMeta(ClassMeta cm) { HtmlClassMeta m = htmlClassMetas.get(cm); if (m == null) { m = new HtmlClassMeta(cm, this); htmlClassMetas.put(cm, m); } return m; } @Override /* HtmlMetaProvider */ public HtmlBeanPropertyMeta getHtmlBeanPropertyMeta(BeanPropertyMeta bpm) { if (bpm == null) return HtmlBeanPropertyMeta.DEFAULT; HtmlBeanPropertyMeta m = htmlBeanPropertyMetas.get(bpm); if (m == null) { m = new HtmlBeanPropertyMeta(bpm.getDelegateFor(), this); htmlBeanPropertyMetas.put(bpm, m); } return m; } //----------------------------------------------------------------------------------------------------------------- // Properties //----------------------------------------------------------------------------------------------------------------- /** * Add "_type" properties when needed. * * @see Builder#addBeanTypesHtml() * @return * true if "_type" properties will be added to beans if their type cannot be inferred * through reflection. */ @Override protected final boolean isAddBeanTypes() { return addBeanTypesHtml || super.isAddBeanTypes(); } /** * Add key/value headers on bean/map tables. * * @see Builder#addKeyValueTableHeaders() * @return * true if key and value column headers are added to tables. */ protected final boolean isAddKeyValueTableHeaders() { return addKeyValueTableHeaders; } /** * Look for link labels in URIs. * * @see Builder#disableDetectLabelParameters() * @return * true if we should look for URL label parameters (e.g. "?label=foobar"). */ protected final boolean isDetectLabelParameters() { return detectLabelParameters; } /** * Look for URLs in {@link String Strings}. * * @see Builder#disableDetectLinksInStrings() * @return * true if we should automatically convert strings to URLs if they look like a URL. */ protected final boolean isDetectLinksInStrings() { return detectLinksInStrings; } /** * Link label parameter name. * * @see Builder#labelParameter(String) * @return * The parameter name to look for when resolving link labels. */ protected final String getLabelParameter() { return labelParameter; } /** * Anchor text source. * * @see Builder#uriAnchorText(AnchorText) * @return * When creating anchor tags (e.g. <a href='...' * >text</a>) in HTML, this setting defines what to set the inner text to. */ protected final AnchorText getUriAnchorText() { return uriAnchorText; } //----------------------------------------------------------------------------------------------------------------- // Other methods //----------------------------------------------------------------------------------------------------------------- @Override /* Context */ protected JsonMap properties() { return filteredMap() .append("uriAnchorText", uriAnchorText) .append("detectLabelParameters", detectLabelParameters) .append("detectLinksInStrings", detectLinksInStrings) .append("labelParameter", labelParameter) .append("addKeyValueTableHeaders", addKeyValueTableHeaders) .append("addBeanTypesHtml", addBeanTypesHtml); } }