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 static org.apache.juneau.common.utils.ThrowableUtils.*;
020
021import java.util.function.*;
022
023import org.apache.juneau.*;
024import org.apache.juneau.html.annotation.*;
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/HtmlBasics">HTML Basics</a>
032
033 * </ul>
034 */
035public class HtmlClassMeta extends ExtendedClassMeta {
036
037   private final boolean noTables, noTableHeaders;
038   private final HtmlFormat format;
039   private final HtmlRender<?> render;
040
041   /**
042    * Constructor.
043    *
044    * @param cm The class that this annotation is defined on.
045    * @param mp HTML metadata provider (for finding information about other artifacts).
046    */
047   public HtmlClassMeta(ClassMeta<?> cm, HtmlMetaProvider mp) {
048      super(cm);
049
050      Value<Boolean> noTables = Value.empty(), noTableHeaders = Value.empty();
051      Value<HtmlFormat> format = Value.empty();
052      Value<HtmlRender<?>> render = Value.empty();
053
054      Consumer<Html> c = x -> {
055         if (x.noTables())
056            noTables.set(true);
057         if (x.noTableHeaders())
058            noTableHeaders.set(true);
059         if (x.format() != HtmlFormat.HTML)
060            format.set(x.format());
061         if (x.render() != HtmlRender.class) {
062            try {
063               render.set(x.render().getDeclaredConstructor().newInstance());
064            } catch (Exception e) {
065               throw asRuntimeException(e);
066            }
067         }
068      };
069      cm.forEachAnnotation(Html.class, x -> true, c);
070
071      this.noTables = noTables.orElse(false);
072      this.noTableHeaders = noTableHeaders.orElse(false);
073      this.render = render.orElse(null);
074      this.format = format.orElse(HtmlFormat.HTML);
075   }
076
077   /**
078    * Returns the {@link Html#format() @Html(format)} annotation defined on the class.
079    *
080    * @return The value of the annotation.
081    */
082   protected HtmlFormat getFormat() {
083      return format;
084   }
085
086   /**
087    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#XML}.
088    *
089    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#XML}.
090    */
091   protected boolean isXml() {
092      return format == HtmlFormat.XML;
093   }
094
095   /**
096    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#PLAIN_TEXT}.
097    *
098    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#PLAIN_TEXT}.
099    */
100   protected boolean isPlainText() {
101      return format == HtmlFormat.PLAIN_TEXT;
102   }
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() {
110      return format == HtmlFormat.HTML;
111   }
112
113   /**
114    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_CDC}.
115    *
116    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_CDC}.
117    */
118   protected boolean isHtmlCdc() {
119      return format == HtmlFormat.HTML_CDC;
120   }
121
122   /**
123    * Returns <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_SDC}.
124    *
125    * @return <jk>true</jk> if {@link #getFormat()} returns {@link HtmlFormat#HTML_SDC}.
126    */
127   protected boolean isHtmlSdc() {
128      return format == HtmlFormat.HTML_SDC;
129   }
130
131   /**
132    * Returns the {@link Html#noTables() @Html(noTables)} annotation defined on the class.
133    *
134    * @return The value of the annotation.
135    */
136   protected boolean isNoTables() {
137      return noTables;
138   }
139
140   /**
141    * Returns the {@link Html#noTableHeaders() @Html(noTableHeaders)} annotation defined on the class.
142    *
143    * @return The value of the annotation.
144    */
145   public boolean isNoTableHeaders() {
146      return noTableHeaders;
147   }
148
149   /**
150    * Returns the {@link Html#render() @Html(render)} annotation defined on the class.
151    *
152    * @return The value of the annotation.
153    */
154   public HtmlRender<?> getRender() {
155      return render;
156   }
157}