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 static org.apache.juneau.html.HtmlDocSerializer.*; 016 017import java.io.IOException; 018import java.util.*; 019 020import org.apache.juneau.*; 021import org.apache.juneau.collections.*; 022import org.apache.juneau.serializer.*; 023import org.apache.juneau.svl.*; 024 025/** 026 * Context object that lives for the duration of a single serialization of {@link HtmlSerializer} and its subclasses. 027 * 028 * <p> 029 * See {@link Serializer} for details. 030 * 031 * <p> 032 * This class is NOT thread safe. It is meant to be discarded after one-time use. 033 */ 034public class HtmlDocSerializerSession extends HtmlStrippedDocSerializerSession { 035 036 private static final VarResolver DEFAULT_VR = VarResolver.create().defaultVars().vars(HtmlWidgetVar.class).build(); 037 038 private final HtmlDocSerializer ctx; 039 private final String[] navlinks, head, header, nav, aside, footer; 040 private final AsideFloat asideFloat; 041 private final Set<String> style, stylesheet, script; 042 private final boolean nowrap; 043 044 /** 045 * Create a new session using properties specified in the context. 046 * 047 * @param ctx 048 * The context creating this session object. 049 * The context contains all the configuration settings for this object. 050 * @param args 051 * Runtime arguments. 052 */ 053 protected HtmlDocSerializerSession(HtmlDocSerializer ctx, SerializerSessionArgs args) { 054 super(ctx, args); 055 this.ctx = ctx; 056 057 header = getProperty(HTMLDOC_header, String[].class, ctx.getHeader()); 058 nav = getProperty(HTMLDOC_nav, String[].class, ctx.getNav()); 059 aside = getProperty(HTMLDOC_aside, String[].class, ctx.getAside()); 060 asideFloat = getProperty(HTMLDOC_asideFloat, AsideFloat.class, ctx.getAsideFloat()); 061 footer = getProperty(HTMLDOC_footer, String[].class, ctx.getFooter()); 062 navlinks = getProperty(HTMLDOC_navlinks, String[].class, ctx.getNavlinks()); 063 064 // These can contain dups after variable resolution, so de-dup them with hashsets. 065 style = ASet.of(getProperty(HTMLDOC_style, String[].class, ctx.getStyle())); 066 stylesheet = ASet.of(getProperty(HTMLDOC_stylesheet, String[].class, ctx.getStylesheet())); 067 script = ASet.of(getProperty(HTMLDOC_script, String[].class, ctx.getScript())); 068 069 head = getProperty(HTMLDOC_head, String[].class, ctx.getHead()); 070 nowrap = getProperty(HTMLDOC_nowrap, boolean.class, ctx.isNowrap()); 071 072 varSessionObject(HtmlWidgetVar.SESSION_htmlWidgets, ctx.getWidgets()); 073 } 074 075 @Override /* SerializerSession */ 076 protected VarResolverSession createDefaultVarResolverSession() { 077 return DEFAULT_VR.createSession(); 078 } 079 080 /** 081 * Returns the {@link HtmlDocSerializer#HTMLDOC_navlinks} setting value in this context. 082 * 083 * @return 084 * The {@link HtmlDocSerializer#HTMLDOC_navlinks} setting value in this context. 085 * <jk>null</jk> if not specified. 086 * Never an empty map. 087 */ 088 public final String[] getNavLinks() { 089 return navlinks; 090 } 091 092 @Override /* Serializer */ 093 protected void doSerialize(SerializerPipe out, Object o) throws IOException, SerializeException { 094 095 try (HtmlWriter w = getHtmlWriter(out)) { 096 try { 097 getTemplate().writeTo(this, w, o); 098 } catch (Exception e) { 099 throw new SerializeException(e); 100 } 101 } 102 } 103 104 /** 105 * Calls the parent {@link #doSerialize(SerializerPipe, Object)} method which invokes just the HTML serializer. 106 * 107 * @param out 108 * Where to send the output from the serializer. 109 * @param o The object being serialized. 110 * @throws Exception Error occurred during serialization. 111 */ 112 public void parentSerialize(Object out, Object o) throws Exception { 113 try (SerializerPipe pipe = createPipe(out)) { 114 super.doSerialize(pipe, o); 115 } 116 } 117 //----------------------------------------------------------------------------------------------------------------- 118 // Properties 119 //----------------------------------------------------------------------------------------------------------------- 120 121 /** 122 * Configuration property: Aside section contents. 123 * 124 * @see HtmlDocSerializer#HTMLDOC_aside 125 * @return 126 * The overridden contents of the aside section on the HTML page. 127 */ 128 protected final String[] getAside() { 129 return aside; 130 } 131 132 /** 133 * Configuration property: Aside section contents float. 134 * 135 * @see HtmlDocSerializer#HTMLDOC_asideFloat 136 * @return 137 * The location of where to place the aside section. 138 */ 139 protected final AsideFloat getAsideFloat() { 140 return asideFloat; 141 } 142 143 /** 144 * Configuration property: Footer section contents. 145 * 146 * @see HtmlDocSerializer#HTMLDOC_footer 147 * @return 148 * The overridden contents of the footer section on the HTML page. 149 */ 150 protected final String[] getFooter() { 151 return footer; 152 } 153 154 /** 155 * Configuration property: Additional head section content. 156 * 157 * @see HtmlDocSerializer#HTMLDOC_head 158 * @return 159 * HTML content to add to the head section of the HTML page. 160 */ 161 protected final String[] getHead() { 162 return head; 163 } 164 165 /** 166 * Configuration property: Header section contents. 167 * 168 * @see HtmlDocSerializer#HTMLDOC_header 169 * @return 170 * The overridden contents of the header section on the HTML page. 171 */ 172 protected final String[] getHeader() { 173 return header; 174 } 175 176 /** 177 * Configuration property: Nav section contents. 178 * 179 * @see HtmlDocSerializer#HTMLDOC_nav 180 * @return 181 * The overridden contents of the nav section on the HTML page. 182 */ 183 protected final String[] getNav() { 184 return nav; 185 } 186 187 /** 188 * Configuration property: Page navigation links. 189 * 190 * @see HtmlDocSerializer#HTMLDOC_navlinks 191 * @return 192 * Navigation links to add to the HTML page. 193 */ 194 protected final String[] getNavlinks() { 195 return navlinks; 196 } 197 198 /** 199 * Configuration property: No-results message. 200 * 201 * @see HtmlDocSerializer#HTMLDOC_noResultsMessage 202 * @return 203 * The message used when serializing an empty array or empty list. 204 */ 205 protected final String getNoResultsMessage() { 206 return ctx.getNoResultsMessage(); 207 } 208 209 /** 210 * Configuration property: Prevent word wrap on page. 211 * 212 * @see HtmlDocSerializer#HTMLDOC_nowrap 213 * @return 214 * <jk>true</jk> if <js>"* {white-space:nowrap}"</js> shoudl be added to the CSS instructions on the page to prevent word wrapping. 215 */ 216 protected final boolean isNowrap() { 217 return nowrap; 218 } 219 220 /** 221 * Configuration property: Javascript code. 222 * 223 * @see HtmlDocSerializer#HTMLDOC_script 224 * @return 225 * Arbitrary Javascript to add to the HTML page. 226 */ 227 protected final Set<String> getScript() { 228 return script; 229 } 230 231 /** 232 * Configuration property: CSS style code. 233 * 234 * @see HtmlDocSerializer#HTMLDOC_style 235 * @return 236 * The CSS instructions to add to the HTML page. 237 */ 238 protected final Set<String> getStyle() { 239 return style; 240 } 241 242 /** 243 * Configuration property: Stylesheet import URLs. 244 * 245 * @see HtmlDocSerializer#HTMLDOC_stylesheet 246 * @return 247 * The link to the stylesheet of the HTML page. 248 */ 249 protected final Set<String> getStylesheet() { 250 return stylesheet; 251 } 252 253 /** 254 * Configuration property: HTML document template. 255 * 256 * @see HtmlDocSerializer#HTMLDOC_template 257 * @return 258 * The template to use for serializing the page. 259 */ 260 protected final HtmlDocTemplate getTemplate() { 261 return ctx.getTemplate(); 262 } 263 264 /** 265 * Configuration property: Page navigation links. 266 * 267 * @see HtmlDocSerializer#HTMLDOC_navlinks 268 * @return 269 * Navigation links to add to the HTML page. 270 */ 271 protected final Collection<HtmlWidget> getWidgets() { 272 return ctx.getWidgets().values(); 273 } 274 275 //----------------------------------------------------------------------------------------------------------------- 276 // Other methods 277 //----------------------------------------------------------------------------------------------------------------- 278 279 @Override /* Session */ 280 public OMap toMap() { 281 return super.toMap() 282 .a("HtmlDocSerializerSession", new DefaultFilteringOMap() 283 .a("aside", aside) 284 .a("head", head) 285 .a("header", header) 286 .a("footer", footer) 287 .a("nav", nav) 288 .a("navlinks", navlinks) 289 .a("script", script) 290 .a("style", style) 291 .a("stylesheet", stylesheet) 292 .a("varResolver", getVarResolver()) 293 ); 294 } 295}