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.collections.JsonMap.*; 016 017import java.io.IOException; 018import java.lang.reflect.*; 019import java.nio.charset.*; 020import java.util.*; 021import java.util.function.*; 022 023import org.apache.juneau.*; 024import org.apache.juneau.collections.*; 025import org.apache.juneau.httppart.*; 026import org.apache.juneau.internal.*; 027import org.apache.juneau.serializer.*; 028import org.apache.juneau.svl.*; 029 030/** 031 * Context object that lives for the duration of a single serialization of {@link HtmlSerializer} and its subclasses. 032 * 033 * <p> 034 * See {@link Serializer} for details. 035 * 036 * <h5 class='section'>Notes:</h5><ul> 037 * <li class='warn'>This class is not thread safe and is typically discarded after one use. 038 * </ul> 039 * 040 * <h5 class='section'>See Also:</h5><ul> 041 * <li class='link'><a class="doclink" href="../../../../index.html#jm.HtmlDetails">HTML Details</a> 042 043 * </ul> 044 */ 045public class HtmlDocSerializerSession extends HtmlStrippedDocSerializerSession { 046 047 //----------------------------------------------------------------------------------------------------------------- 048 // Static 049 //----------------------------------------------------------------------------------------------------------------- 050 051 private static final VarResolver DEFAULT_VR = VarResolver.create().defaultVars().vars(HtmlWidgetVar.class).build(); 052 053 /** 054 * Creates a new builder for this object. 055 * 056 * @param ctx The context creating this session. 057 * @return A new builder. 058 */ 059 public static Builder create(HtmlDocSerializer ctx) { 060 return new Builder(ctx); 061 } 062 063 //----------------------------------------------------------------------------------------------------------------- 064 // Builder 065 //----------------------------------------------------------------------------------------------------------------- 066 067 /** 068 * Builder class. 069 */ 070 @FluentSetters 071 public static class Builder extends HtmlStrippedDocSerializerSession.Builder { 072 073 HtmlDocSerializer ctx; 074 075 /** 076 * Constructor 077 * 078 * @param ctx The context creating this session. 079 */ 080 protected Builder(HtmlDocSerializer ctx) { 081 super(ctx); 082 this.ctx = ctx; 083 } 084 085 @Override 086 public HtmlDocSerializerSession build() { 087 return new HtmlDocSerializerSession(this); 088 } 089 090 // <FluentSetters> 091 092 @Override /* GENERATED - org.apache.juneau.ContextSession.Builder */ 093 public <T> Builder apply(Class<T> type, Consumer<T> apply) { 094 super.apply(type, apply); 095 return this; 096 } 097 098 @Override /* GENERATED - org.apache.juneau.ContextSession.Builder */ 099 public Builder debug(Boolean value) { 100 super.debug(value); 101 return this; 102 } 103 104 @Override /* GENERATED - org.apache.juneau.ContextSession.Builder */ 105 public Builder properties(Map<String,Object> value) { 106 super.properties(value); 107 return this; 108 } 109 110 @Override /* GENERATED - org.apache.juneau.ContextSession.Builder */ 111 public Builder property(String key, Object value) { 112 super.property(key, value); 113 return this; 114 } 115 116 @Override /* GENERATED - org.apache.juneau.ContextSession.Builder */ 117 public Builder unmodifiable() { 118 super.unmodifiable(); 119 return this; 120 } 121 122 @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */ 123 public Builder locale(Locale value) { 124 super.locale(value); 125 return this; 126 } 127 128 @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */ 129 public Builder localeDefault(Locale value) { 130 super.localeDefault(value); 131 return this; 132 } 133 134 @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */ 135 public Builder mediaType(MediaType value) { 136 super.mediaType(value); 137 return this; 138 } 139 140 @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */ 141 public Builder mediaTypeDefault(MediaType value) { 142 super.mediaTypeDefault(value); 143 return this; 144 } 145 146 @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */ 147 public Builder timeZone(TimeZone value) { 148 super.timeZone(value); 149 return this; 150 } 151 152 @Override /* GENERATED - org.apache.juneau.BeanSession.Builder */ 153 public Builder timeZoneDefault(TimeZone value) { 154 super.timeZoneDefault(value); 155 return this; 156 } 157 158 @Override /* GENERATED - org.apache.juneau.serializer.SerializerSession.Builder */ 159 public Builder javaMethod(Method value) { 160 super.javaMethod(value); 161 return this; 162 } 163 164 @Override /* GENERATED - org.apache.juneau.serializer.SerializerSession.Builder */ 165 public Builder resolver(VarResolverSession value) { 166 super.resolver(value); 167 return this; 168 } 169 170 @Override /* GENERATED - org.apache.juneau.serializer.SerializerSession.Builder */ 171 public Builder schema(HttpPartSchema value) { 172 super.schema(value); 173 return this; 174 } 175 176 @Override /* GENERATED - org.apache.juneau.serializer.SerializerSession.Builder */ 177 public Builder schemaDefault(HttpPartSchema value) { 178 super.schemaDefault(value); 179 return this; 180 } 181 182 @Override /* GENERATED - org.apache.juneau.serializer.SerializerSession.Builder */ 183 public Builder uriContext(UriContext value) { 184 super.uriContext(value); 185 return this; 186 } 187 188 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializerSession.Builder */ 189 public Builder fileCharset(Charset value) { 190 super.fileCharset(value); 191 return this; 192 } 193 194 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializerSession.Builder */ 195 public Builder streamCharset(Charset value) { 196 super.streamCharset(value); 197 return this; 198 } 199 200 @Override /* GENERATED - org.apache.juneau.serializer.WriterSerializerSession.Builder */ 201 public Builder useWhitespace(Boolean value) { 202 super.useWhitespace(value); 203 return this; 204 } 205 206 // </FluentSetters> 207 } 208 209 //----------------------------------------------------------------------------------------------------------------- 210 // Instance 211 //----------------------------------------------------------------------------------------------------------------- 212 213 /** 214 * Constructor. 215 * 216 * @param builder The builder for this object. 217 */ 218 protected HtmlDocSerializerSession(Builder builder) { 219 super(builder); 220 ctx = builder.ctx; 221 addVarBean(HtmlWidgetMap.class, ctx.getWidgets()); 222 } 223 224 private final HtmlDocSerializer ctx; 225 226 @Override /* SerializerSession */ 227 protected VarResolverSession createDefaultVarResolverSession() { 228 return DEFAULT_VR.createSession(); 229 } 230 231 /** 232 * Returns the {@link HtmlDocSerializer.Builder#navlinks(String...)} setting value in this context. 233 * 234 * @return 235 * The {@link HtmlDocSerializer.Builder#navlinks(String...)} setting value in this context. 236 * <jk>null</jk> if not specified. 237 * Never an empty map. 238 */ 239 public final String[] getNavLinks() { 240 return ctx.navlinks; 241 } 242 243 @Override /* Serializer */ 244 protected void doSerialize(SerializerPipe out, Object o) throws IOException, SerializeException { 245 246 try (HtmlWriter w = getHtmlWriter(out)) { 247 try { 248 getTemplate().writeTo(this, w, o); 249 } catch (Exception e) { 250 throw new SerializeException(e); 251 } 252 } 253 } 254 255 /** 256 * Calls the parent {@link #doSerialize(SerializerPipe, Object)} method which invokes just the HTML serializer. 257 * 258 * @param out 259 * Where to send the output from the serializer. 260 * @param o The object being serialized. 261 * @throws Exception Error occurred during serialization. 262 */ 263 public void parentSerialize(Object out, Object o) throws Exception { 264 try (SerializerPipe pipe = createPipe(out)) { 265 super.doSerialize(pipe, o); 266 } 267 } 268 //----------------------------------------------------------------------------------------------------------------- 269 // Properties 270 //----------------------------------------------------------------------------------------------------------------- 271 272 /** 273 * Aside section contents. 274 * 275 * @see HtmlDocSerializer.Builder#aside(String...) 276 * @return 277 * The overridden contents of the aside section on the HTML page. 278 */ 279 protected final String[] getAside() { 280 return ctx.aside; 281 } 282 283 /** 284 * Aside section contents float. 285 * 286 * @see HtmlDocSerializer.Builder#asideFloat(AsideFloat) 287 * @return 288 * The location of where to place the aside section. 289 */ 290 protected final AsideFloat getAsideFloat() { 291 return ctx.asideFloat; 292 } 293 294 /** 295 * Footer section contents. 296 * 297 * @see HtmlDocSerializer.Builder#footer(String...) 298 * @return 299 * The overridden contents of the footer section on the HTML page. 300 */ 301 protected final String[] getFooter() { 302 return ctx.footer; 303 } 304 305 /** 306 * Additional head section content. 307 * 308 * @see HtmlDocSerializer.Builder#head(String...) 309 * @return 310 * HTML content to add to the head section of the HTML page. 311 */ 312 protected final String[] getHead() { 313 return ctx.head; 314 } 315 316 /** 317 * Header section contents. 318 * 319 * @see HtmlDocSerializer.Builder#header(String...) 320 * @return 321 * The overridden contents of the header section on the HTML page. 322 */ 323 protected final String[] getHeader() { 324 return ctx.header; 325 } 326 327 /** 328 * Nav section contents. 329 * 330 * @see HtmlDocSerializer.Builder#nav(String...) 331 * @return 332 * The overridden contents of the nav section on the HTML page. 333 */ 334 protected final String[] getNav() { 335 return ctx.nav; 336 } 337 338 /** 339 * Page navigation links. 340 * 341 * @see HtmlDocSerializer.Builder#navlinks(String...) 342 * @return 343 * Navigation links to add to the HTML page. 344 */ 345 protected final String[] getNavlinks() { 346 return ctx.navlinks; 347 } 348 349 /** 350 * No-results message. 351 * 352 * @see HtmlDocSerializer.Builder#noResultsMessage(String) 353 * @return 354 * The message used when serializing an empty array or empty list. 355 */ 356 protected final String getNoResultsMessage() { 357 return ctx.getNoResultsMessage(); 358 } 359 360 /** 361 * Prevent word wrap on page. 362 * 363 * @see HtmlDocSerializer.Builder#nowrap() 364 * @return 365 * <jk>true</jk> if <js>"* {white-space:nowrap}"</js> should be added to the CSS instructions on the page to prevent word wrapping. 366 */ 367 protected final boolean isNowrap() { 368 return ctx.nowrap; 369 } 370 371 /** 372 * Resolve $ variables in serialized POJO. 373 * 374 * @see HtmlDocSerializer.Builder#resolveBodyVars() 375 * @return 376 * <jk>true</jk> if $ variables in serialized POJO should be resolved. 377 */ 378 protected final boolean isResolveBodyVars() { 379 return ctx.resolveBodyVars; 380 } 381 382 /** 383 * Javascript code. 384 * 385 * @see HtmlDocSerializer.Builder#script(String...) 386 * @return 387 * Arbitrary Javascript to add to the HTML page. 388 */ 389 protected final String[] getScript() { 390 return ctx.script; 391 } 392 393 /** 394 * CSS style code. 395 * 396 * @see HtmlDocSerializer.Builder#style(String...) 397 * @return 398 * The CSS instructions to add to the HTML page. 399 */ 400 protected final String[] getStyle() { 401 return ctx.style; 402 } 403 404 /** 405 * Stylesheet import URLs. 406 * 407 * @see HtmlDocSerializer.Builder#stylesheet(String...) 408 * @return 409 * The link to the stylesheet of the HTML page. 410 */ 411 protected final String[] getStylesheet() { 412 return ctx.stylesheet; 413 } 414 415 /** 416 * HTML document template. 417 * 418 * @see HtmlDocSerializer.Builder#template(Class) 419 * @return 420 * The template to use for serializing the page. 421 */ 422 protected final HtmlDocTemplate getTemplate() { 423 return ctx.getTemplate(); 424 } 425 426 /** 427 * Performs an action on all widgets defined in his session. 428 * 429 * @param action The action to perform. 430 * @see HtmlDocSerializer.Builder#widgets(Class...) 431 * @return This object. 432 */ 433 protected final HtmlDocSerializerSession forEachWidget(Consumer<HtmlWidget> action) { 434 ctx.forEachWidget(action); 435 return this; 436 } 437 438 //----------------------------------------------------------------------------------------------------------------- 439 // Other methods 440 //----------------------------------------------------------------------------------------------------------------- 441 442 @Override /* ContextSession */ 443 protected JsonMap properties() { 444 return filteredMap("ctx", ctx, "varResolver", getVarResolver()); 445 } 446}