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.internal.ClassUtils.*;
016
017import org.apache.juneau.*;
018import org.apache.juneau.html.annotation.*;
019
020/**
021 * Metadata on bean properties specific to the HTML serializers and parsers pulled from the {@link Html @Html}
022 * annotation on the bean property.
023 */
024@SuppressWarnings("rawtypes")
025public final class HtmlBeanPropertyMeta extends ExtendedBeanPropertyMeta {
026
027   /**
028    * Default instance.
029    */
030   public static final HtmlBeanPropertyMeta DEFAULT = new HtmlBeanPropertyMeta();
031
032   private final boolean noTables, noTableHeaders;
033   private final HtmlFormat format;
034   private final HtmlRender render;
035   private final String link, anchorText;
036
037   /**
038    * Constructor.
039    *
040    * @param bpm The metadata of the bean property of this additional metadata.
041    * @param mp HTML metadata provider (for finding information about other artifacts).
042    */
043   public HtmlBeanPropertyMeta(BeanPropertyMeta bpm, HtmlMetaProvider mp) {
044      super(bpm);
045
046      Builder b = new Builder();
047      if (bpm.getInnerField() != null)
048         b.findHtmlInfo(mp.getAnnotation(Html.class, bpm.getInnerField()));
049      if (bpm.getGetter() != null)
050         b.findHtmlInfo(mp.getAnnotation(Html.class, bpm.getGetter()));
051      if (bpm.getSetter() != null)
052         b.findHtmlInfo(mp.getAnnotation(Html.class, bpm.getSetter()));
053
054      this.format = b.format;
055      this.noTables = b.noTables;
056      this.noTableHeaders = b.noTableHeaders;
057      this.render = castOrCreate(HtmlRender.class, b.render);
058      this.link = b.link;
059      this.anchorText = b.anchorText;
060   }
061
062   private HtmlBeanPropertyMeta() {
063      super(null);
064      this.format = HtmlFormat.HTML;
065      this.noTables = false;
066      this.noTableHeaders = false;
067      this.render = null;
068      this.link = null;
069      this.anchorText = null;
070   }
071
072   static final class Builder {
073      boolean noTables, noTableHeaders;
074      HtmlFormat format = HtmlFormat.HTML;
075      Class<? extends HtmlRender> render = HtmlRender.class;
076      String link, anchorText;
077
078      void findHtmlInfo(Html html) {
079         if (html == null)
080            return;
081         format = html.format();
082         if (html.noTables())
083            noTables = html.noTables();
084         if (html.noTableHeaders())
085            noTableHeaders = html.noTableHeaders();
086         if (html.render() != HtmlRender.class)
087            render = html.render();
088         if (! html.link().isEmpty())
089            link = html.link();
090         if (! html.anchorText().isEmpty())
091            anchorText = html.anchorText();
092      }
093   }
094
095   /**
096    * Returns the format of this bean property
097    *
098    * @return The value of the {@link Html#format()} annotation.
099    */
100   protected HtmlFormat getFormat() {
101      return format;
102   }
103
104   /**
105    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#XML}.
106    *
107    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#XML}.
108    */
109   protected boolean isXml() {
110      return format == HtmlFormat.XML;
111   }
112
113   /**
114    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#PLAIN_TEXT}.
115    *
116    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#PLAIN_TEXT}.
117    */
118   protected boolean isPlainText() {
119      return format == HtmlFormat.PLAIN_TEXT;
120   }
121
122   /**
123    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML}.
124    *
125    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML}.
126    */
127   protected boolean isHtml() {
128      return format == HtmlFormat.HTML;
129   }
130
131   /**
132    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_CDC}.
133    *
134    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_CDC}.
135    */
136   protected boolean isHtmlCdc() {
137      return format == HtmlFormat.HTML_CDC;
138   }
139
140   /**
141    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_SDC}.
142    *
143    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_SDC}.
144    */
145   protected boolean isHtmlSdc() {
146      return format == HtmlFormat.HTML_SDC;
147   }
148
149   /**
150    * Returns whether this bean property should not be serialized as an HTML table.
151    *
152    * @return
153    *    <jk>true</jk> if the the {@link Html @Html} annotation is specified, and {@link Html#noTables() @Html(noTables)} is
154    *    <jk>true</jk>.
155    */
156   protected boolean isNoTables() {
157      return noTables;
158   }
159
160   /**
161    * Returns whether this bean property should not include table headers when serialized as an HTML table.
162    *
163    * @return
164    *    <jk>true</jk> if the the {@link Html @Html} annotation is specified, and {@link Html#noTableHeaders() @Html(noTableHeaders)} is
165    *    <jk>true</jk>.
166    */
167   public boolean isNoTableHeaders() {
168      return noTableHeaders;
169   }
170
171   /**
172    * Returns the render class for rendering the style and contents of this property value in HTML.
173    *
174    * <p>
175    * This value is specified via the {@link Html#render() @Html(render)} annotation.
176    *
177    * @return The render class, never <jk>null</jk>.
178    */
179   public HtmlRender getRender() {
180      return render;
181   }
182
183   /**
184    * Adds a hyperlink to this value in HTML.
185    *
186    * <p>
187    * This value is specified via the {@link Html#link() @Html(link)} annotation.
188    *
189    * @return The link string, or <jk>null</jk> if not specified.
190    */
191   public String getLink() {
192      return link;
193   }
194
195   /**
196    * Specifies the anchor text for this property.
197    *
198    * <p>
199    * This value is specified via the {@link Html#anchorText() @Html(anchorText)} annotation.
200    *
201    * @return The link string, or <jk>null</jk> if not specified.
202    */
203   public String getAnchorText() {
204      return anchorText;
205   }
206}