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         for (Html html : mp.getAnnotations(Html.class, bpm.getInnerField()))
049            b.findHtmlInfo(html);
050      if (bpm.getGetter() != null)
051         for (Html html : mp.getAnnotations(Html.class, bpm.getGetter()))
052            b.findHtmlInfo(html);
053      if (bpm.getSetter() != null)
054         for (Html html : mp.getAnnotations(Html.class, bpm.getSetter()))
055            b.findHtmlInfo(html);
056
057      this.format = b.format;
058      this.noTables = b.noTables;
059      this.noTableHeaders = b.noTableHeaders;
060      this.render = castOrCreate(HtmlRender.class, b.render);
061      this.link = b.link;
062      this.anchorText = b.anchorText;
063   }
064
065   private HtmlBeanPropertyMeta() {
066      super(null);
067      this.format = HtmlFormat.HTML;
068      this.noTables = false;
069      this.noTableHeaders = false;
070      this.render = null;
071      this.link = null;
072      this.anchorText = null;
073   }
074
075   static final class Builder {
076      boolean noTables, noTableHeaders;
077      HtmlFormat format = HtmlFormat.HTML;
078      Class<? extends HtmlRender> render = HtmlRender.class;
079      String link, anchorText;
080
081      void findHtmlInfo(Html html) {
082         if (html == null)
083            return;
084         format = html.format();
085         if (html.noTables())
086            noTables = html.noTables();
087         if (html.noTableHeaders())
088            noTableHeaders = html.noTableHeaders();
089         if (html.render() != HtmlRender.class)
090            render = html.render();
091         if (! html.link().isEmpty())
092            link = html.link();
093         if (! html.anchorText().isEmpty())
094            anchorText = html.anchorText();
095      }
096   }
097
098   /**
099    * Returns the format of this bean property
100    *
101    * @return The value of the {@link Html#format()} annotation.
102    */
103   protected HtmlFormat getFormat() {
104      return format;
105   }
106
107   /**
108    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#XML}.
109    *
110    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#XML}.
111    */
112   protected boolean isXml() {
113      return format == HtmlFormat.XML;
114   }
115
116   /**
117    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#PLAIN_TEXT}.
118    *
119    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#PLAIN_TEXT}.
120    */
121   protected boolean isPlainText() {
122      return format == HtmlFormat.PLAIN_TEXT;
123   }
124
125   /**
126    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML}.
127    *
128    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML}.
129    */
130   protected boolean isHtml() {
131      return format == HtmlFormat.HTML;
132   }
133
134   /**
135    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_CDC}.
136    *
137    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_CDC}.
138    */
139   protected boolean isHtmlCdc() {
140      return format == HtmlFormat.HTML_CDC;
141   }
142
143   /**
144    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_SDC}.
145    *
146    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_SDC}.
147    */
148   protected boolean isHtmlSdc() {
149      return format == HtmlFormat.HTML_SDC;
150   }
151
152   /**
153    * Returns whether this bean property should not be serialized as an HTML table.
154    *
155    * @return
156    *    <jk>true</jk> if the the {@link Html @Html} annotation is specified, and {@link Html#noTables() @Html(noTables)} is
157    *    <jk>true</jk>.
158    */
159   protected boolean isNoTables() {
160      return noTables;
161   }
162
163   /**
164    * Returns whether this bean property should not include table headers when serialized as an HTML table.
165    *
166    * @return
167    *    <jk>true</jk> if the the {@link Html @Html} annotation is specified, and {@link Html#noTableHeaders() @Html(noTableHeaders)} is
168    *    <jk>true</jk>.
169    */
170   public boolean isNoTableHeaders() {
171      return noTableHeaders;
172   }
173
174   /**
175    * Returns the render class for rendering the style and contents of this property value in HTML.
176    *
177    * <p>
178    * This value is specified via the {@link Html#render() @Html(render)} annotation.
179    *
180    * @return The render class, never <jk>null</jk>.
181    */
182   public HtmlRender getRender() {
183      return render;
184   }
185
186   /**
187    * Adds a hyperlink to this value in HTML.
188    *
189    * <p>
190    * This value is specified via the {@link Html#link() @Html(link)} annotation.
191    *
192    * @return The link string, or <jk>null</jk> if not specified.
193    */
194   public String getLink() {
195      return link;
196   }
197
198   /**
199    * Specifies the anchor text for this property.
200    *
201    * <p>
202    * This value is specified via the {@link Html#anchorText() @Html(anchorText)} annotation.
203    *
204    * @return The link string, or <jk>null</jk> if not specified.
205    */
206   public String getAnchorText() {
207      return anchorText;
208   }
209}