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