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.marshall.html;
018
019import static org.apache.juneau.commons.utils.ThrowableUtils.*;
020
021import java.util.function.*;
022
023import org.apache.juneau.commons.lang.*;
024import org.apache.juneau.marshall.*;
025
026/**
027 * Metadata on classes specific to the HTML serializers and parsers pulled from the {@link Html @Html} annotation on
028 * the class.
029 *
030 * <h5 class='section'>See Also:</h5><ul>
031 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/HtmlSupport">HTML</a>
032
033 * </ul>
034 */
035@SuppressWarnings({
036   "java:S1452"  // Wildcard required - HtmlRender<?> for render callback
037})
038public class HtmlClassMeta extends ExtendedClassMeta {
039
040   private final boolean noTables;
041   private final boolean noTableHeaders;
042   private final HtmlFormat format;
043   private final HtmlRender<?> render;
044
045   /**
046    * Constructor.
047    *
048    * @param cm The class that this annotation is defined on.
049    *    <br>Must not be <jk>null</jk>.
050    * @param mp HTML metadata provider (for finding information about other artifacts).
051    */
052   public HtmlClassMeta(ClassMeta<?> cm, HtmlMetaProvider mp) {
053      super(cm);
054
055      var noTables2 = Holder.<Boolean>empty();
056      var noTableHeaders2 = Holder.<Boolean>empty();
057      var format2 = Holder.<HtmlFormat>empty();
058      var render2 = Holder.<HtmlRender<?>>empty();
059
060      Consumer<Html> c = x -> {
061         if (x.noTables())
062            noTables2.set(true);
063         if (x.noTableHeaders())
064            noTableHeaders2.set(true);
065         if (x.format() != HtmlFormat.HTML)
066            format2.set(x.format());
067         if (x.render() != HtmlRender.class) {
068            try {
069               render2.set(x.render().getDeclaredConstructor().newInstance());
070            } catch (Exception e) {
071               throw toRex(e);
072            }
073         }
074      };
075      cm.forEachAnnotation(Html.class, x -> true, c);
076
077      this.noTables = noTables2.orElse(false);
078      this.noTableHeaders = noTableHeaders2.orElse(false);
079      this.render = render2.orElse(null);
080      this.format = format2.orElse(HtmlFormat.HTML);
081   }
082
083   /**
084    * Returns the {@link Html#render() @Html(render)} annotation defined on the class.
085    *
086    * @return The value of the annotation, or <jk>null</jk> if not specified.
087    */
088   public HtmlRender<?> getRender() { return render; }
089
090   /**
091    * Returns the {@link Html#noTableHeaders() @Html(noTableHeaders)} annotation defined on the class.
092    *
093    * @return The value of the annotation.
094    */
095   public boolean isNoTableHeaders() { return noTableHeaders; }
096
097   /**
098    * Returns the {@link Html#format() @Html(format)} annotation defined on the class.
099    *
100    * @return The value of the annotation.
101    */
102   protected HtmlFormat getFormat() { return format; }
103
104   /**
105    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML}.
106    *
107    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML}.
108    */
109   protected boolean isHtml() { return format == HtmlFormat.HTML; }
110
111   /**
112    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_CDC}.
113    *
114    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_CDC}.
115    */
116   protected boolean isHtmlCdc() { return format == HtmlFormat.HTML_CDC; }
117
118   /**
119    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_SDC}.
120    *
121    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_SDC}.
122    */
123   protected boolean isHtmlSdc() { return format == HtmlFormat.HTML_SDC; }
124
125   /**
126    * Returns the {@link Html#noTables() @Html(noTables)} annotation defined on the class.
127    *
128    * @return The value of the annotation.
129    */
130   protected boolean isNoTables() { return noTables; }
131
132   /**
133    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#PLAIN_TEXT}.
134    *
135    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#PLAIN_TEXT}.
136    */
137   protected boolean isPlainText() { return format == HtmlFormat.PLAIN_TEXT; }
138
139   /**
140    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#XML}.
141    *
142    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#XML}.
143    */
144   protected boolean isXml() { return format == HtmlFormat.XML; }
145}