001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.html;
018
019import org.apache.juneau.*;
020import org.apache.juneau.cp.*;
021import org.apache.juneau.html.annotation.*;
022
023/**
024 * Metadata on bean properties specific to the HTML serializers and parsers pulled from the {@link Html @Html}
025 * annotation on the bean property.
026 *
027 * <h5 class='section'>See Also:</h5><ul>
028 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/HtmlBasics">HTML Basics</a>
029
030 * </ul>
031 */
032@SuppressWarnings("rawtypes")
033public class HtmlBeanPropertyMeta extends ExtendedBeanPropertyMeta {
034
035   /**
036    * Default instance.
037    */
038   public static final HtmlBeanPropertyMeta DEFAULT = new HtmlBeanPropertyMeta();
039
040   private final boolean noTables, noTableHeaders;
041   private final HtmlFormat format;
042   private final HtmlRender render;
043   private final String link, anchorText;
044
045   /**
046    * Constructor.
047    *
048    * @param bpm The metadata of the bean property of this additional metadata.
049    * @param mp HTML metadata provider (for finding information about other artifacts).
050    */
051   public HtmlBeanPropertyMeta(BeanPropertyMeta bpm, HtmlMetaProvider mp) {
052      super(bpm);
053
054      Builder b = new Builder();
055      if (bpm.getInnerField() != null)
056         mp.forEachAnnotation(Html.class, bpm.getInnerField(), x-> true, x -> b.findHtmlInfo(x));
057      if (bpm.getGetter() != null)
058         mp.forEachAnnotation(Html.class, bpm.getGetter(), x-> true, x -> b.findHtmlInfo(x));
059      if (bpm.getSetter() != null)
060         mp.forEachAnnotation(Html.class, bpm.getSetter(), x-> true, x -> b.findHtmlInfo(x));
061
062      this.format = b.format;
063      this.noTables = b.noTables;
064      this.noTableHeaders = b.noTableHeaders;
065      this.render = b.render.orElse(null);
066      this.link = b.link;
067      this.anchorText = b.anchorText;
068   }
069
070   private HtmlBeanPropertyMeta() {
071      super(null);
072      this.format = HtmlFormat.HTML;
073      this.noTables = false;
074      this.noTableHeaders = false;
075      this.render = null;
076      this.link = null;
077      this.anchorText = null;
078   }
079
080   static class Builder {
081      boolean noTables, noTableHeaders;
082      HtmlFormat format = HtmlFormat.HTML;
083      BeanCreator<HtmlRender> render = BeanCreator.of(HtmlRender.class);
084      String link, anchorText;
085
086      void findHtmlInfo(Html html) {
087         if (html == null)
088            return;
089         format = html.format();
090         if (html.noTables())
091            noTables = html.noTables();
092         if (html.noTableHeaders())
093            noTableHeaders = html.noTableHeaders();
094         if (html.render() != HtmlRender.class)
095            render.type(html.render());
096         if (! html.link().isEmpty())
097            link = html.link();
098         if (! html.anchorText().isEmpty())
099            anchorText = html.anchorText();
100      }
101   }
102
103   /**
104    * Returns the format of this bean property
105    *
106    * @return The value of the {@link Html#format()} annotation.
107    */
108   protected HtmlFormat getFormat() {
109      return format;
110   }
111
112   /**
113    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#XML}.
114    *
115    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#XML}.
116    */
117   protected boolean isXml() {
118      return format == HtmlFormat.XML;
119   }
120
121   /**
122    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#PLAIN_TEXT}.
123    *
124    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#PLAIN_TEXT}.
125    */
126   protected boolean isPlainText() {
127      return format == HtmlFormat.PLAIN_TEXT;
128   }
129
130   /**
131    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML}.
132    *
133    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML}.
134    */
135   protected boolean isHtml() {
136      return format == HtmlFormat.HTML;
137   }
138
139   /**
140    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_CDC}.
141    *
142    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_CDC}.
143    */
144   protected boolean isHtmlCdc() {
145      return format == HtmlFormat.HTML_CDC;
146   }
147
148   /**
149    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_SDC}.
150    *
151    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_SDC}.
152    */
153   protected boolean isHtmlSdc() {
154      return format == HtmlFormat.HTML_SDC;
155   }
156
157   /**
158    * Returns whether this bean property should not be serialized as an HTML table.
159    *
160    * @return
161    *    <jk>true</jk> if the the {@link Html @Html} annotation is specified, and {@link Html#noTables() @Html(noTables)} is
162    *    <jk>true</jk>.
163    */
164   protected boolean isNoTables() {
165      return noTables;
166   }
167
168   /**
169    * Returns whether this bean property should not include table headers when serialized as an HTML table.
170    *
171    * @return
172    *    <jk>true</jk> if the the {@link Html @Html} annotation is specified, and {@link Html#noTableHeaders() @Html(noTableHeaders)} is
173    *    <jk>true</jk>.
174    */
175   public boolean isNoTableHeaders() {
176      return noTableHeaders;
177   }
178
179   /**
180    * Returns the render class for rendering the style and contents of this property value in HTML.
181    *
182    * <p>
183    * This value is specified via the {@link Html#render() @Html(render)} annotation.
184    *
185    * @return The render class, never <jk>null</jk>.
186    */
187   public HtmlRender getRender() {
188      return render;
189   }
190
191   /**
192    * Adds a hyperlink to this value in HTML.
193    *
194    * <p>
195    * This value is specified via the {@link Html#link() @Html(link)} annotation.
196    *
197    * @return The link string, or <jk>null</jk> if not specified.
198    */
199   public String getLink() {
200      return link;
201   }
202
203   /**
204    * Specifies the anchor text for this property.
205    *
206    * <p>
207    * This value is specified via the {@link Html#anchorText() @Html(anchorText)} annotation.
208    *
209    * @return The link string, or <jk>null</jk> if not specified.
210    */
211   public String getAnchorText() {
212      return anchorText;
213   }
214}