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