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