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.util.*;
018
019import org.apache.juneau.*;
020import org.apache.juneau.serializer.*;
021
022/**
023 * Context object that lives for the duration of a single serialization of {@link HtmlSerializer} and its subclasses.
024 * 
025 * <p>
026 * See {@link Serializer} for details.
027 * 
028 * <p>
029 * This class is NOT thread safe.  It is meant to be discarded after one-time use.
030 */
031public class HtmlDocSerializerSession extends HtmlStrippedDocSerializerSession {
032
033   private final String noResultsMessage;
034   private final String[] navlinks, head, header, nav, aside, footer;
035   private final Set<String> style, stylesheet, script;
036   private final boolean nowrap;
037   private final HtmlDocTemplate template;
038
039   /**
040    * Create a new session using properties specified in the context.
041    * 
042    * @param ctx
043    *    The context creating this session object.
044    *    The context contains all the configuration settings for this object.
045    * @param args
046    *    Runtime arguments.
047    */
048   protected HtmlDocSerializerSession(HtmlDocSerializer ctx, SerializerSessionArgs args) {
049      super(ctx, args);
050      header = getProperty(HTMLDOC_header, String[].class, ctx.nav);
051      nav = getProperty(HTMLDOC_nav, String[].class, ctx.nav);
052      aside = getProperty(HTMLDOC_aside, String[].class, ctx.aside);
053      footer = getProperty(HTMLDOC_footer, String[].class, ctx.footer);
054      navlinks = getProperty(HTMLDOC_navlinks, String[].class, ctx.navlinks);
055      
056      // These can contain dups after variable resolution, so de-dup them with hashsets. 
057      style = new LinkedHashSet<>(Arrays.asList(getProperty(HTMLDOC_style, String[].class, ctx.style)));
058      stylesheet = new LinkedHashSet<>(Arrays.asList(getProperty(HTMLDOC_stylesheet, String[].class, ctx.stylesheet)));
059      script = new LinkedHashSet<>(Arrays.asList(getProperty(HTMLDOC_script, String[].class, ctx.script)));
060      
061      head = getProperty(HTMLDOC_head, String[].class, ctx.head);
062      nowrap = getProperty(HTMLDOC_nowrap, boolean.class, ctx.nowrap);
063      noResultsMessage = getProperty(HTMLDOC_noResultsMessage, String.class, ctx.noResultsMessage);
064      template = getInstanceProperty(HTMLDOC_template, HtmlDocTemplate.class, ctx.template);
065   }
066
067   @Override /* Session */
068   public ObjectMap asMap() {
069      return super.asMap()
070         .append("HtmlDocSerializerSession", new ObjectMap()
071            .append("aside", aside)
072            .append("head", head)
073            .append("header", header)
074            .append("footer", footer)
075            .append("nav", nav)
076            .append("navlinks", navlinks)
077            .append("noResultsMessage", noResultsMessage)
078            .append("nowrap", nowrap)
079            .append("script", script)
080            .append("style", style)
081            .append("stylesheet", stylesheet)
082            .append("template", template)
083         );
084   }
085
086   /**
087    * Returns the {@link HtmlDocSerializer#HTMLDOC_style} setting value in this context.
088    * 
089    * @return
090    *    The {@link HtmlDocSerializer#HTMLDOC_style} setting value in this context.
091    *    An empty array if not specified.
092    *    Never <jk>null</jk>.
093    */
094   public final Set<String> getStyle() {
095      return style;
096   }
097
098   /**
099    * Returns the {@link HtmlDocSerializer#HTMLDOC_stylesheet} setting value in this context.
100    * 
101    * @return
102    *    The {@link HtmlDocSerializer#HTMLDOC_stylesheet} setting value in this context.
103    *    An empty array if not specified.
104    *    Never <jk>null</jk>.
105    */
106   public final Set<String> getStylesheet() {
107      return stylesheet;
108   }
109
110   /**
111    * Returns the {@link HtmlDocSerializer#HTMLDOC_script} setting value in this context.
112    * 
113    * @return
114    *    The {@link HtmlDocSerializer#HTMLDOC_script} setting value in this context.
115    *    An empty array if not specified.
116    *    Never <jk>null</jk>.
117    */
118   public final Set<String> getScript() {
119      return script;
120   }
121
122   /**
123    * Returns the {@link HtmlDocSerializer#HTMLDOC_head} setting value in this context.
124    * 
125    * @return
126    *    The {@link HtmlDocSerializer#HTMLDOC_head} setting value in this context.
127    *    An empty array if not specified.
128    *    Never <jk>null</jk>.
129    */
130   public final String[] getHead() {
131      return head;
132   }
133
134   /**
135    * Returns the {@link HtmlDocSerializer#HTMLDOC_nowrap} setting value in this context.
136    * 
137    * @return The {@link HtmlDocSerializer#HTMLDOC_nowrap} setting value in this context.
138    */
139   public final boolean isNoWrap() {
140      return nowrap;
141   }
142
143   /**
144    * Returns the {@link HtmlDocSerializer#HTMLDOC_header} setting value in this context.
145    * 
146    * @return
147    *    The {@link HtmlDocSerializer#HTMLDOC_header} setting value in this context.
148    *    <jk>null</jk> if not specified.
149    *     Never an empty string.
150    */
151   public final String[] getHeader() {
152      return header;
153   }
154
155   /**
156    * Returns the {@link HtmlDocSerializer#HTMLDOC_navlinks} setting value in this context.
157    * 
158    * @return
159    *    The {@link HtmlDocSerializer#HTMLDOC_navlinks} setting value in this context.
160    *    <jk>null</jk> if not specified.
161    *    Never an empty map.
162    */
163   public final String[] getNavLinks() {
164      return navlinks;
165   }
166
167   /**
168    * Returns the template to use for generating the HTML page.
169    * 
170    * @return
171    *    The HTML page generator.
172    *    Never <jk>null</jk>.
173    */
174   public final HtmlDocTemplate getTemplate() {
175      return template;
176   }
177
178   /**
179    * Returns the {@link HtmlDocSerializer#HTMLDOC_nav} setting value in this context.
180    * 
181    * @return
182    *    The {@link HtmlDocSerializer#HTMLDOC_nav} setting value in this context.
183    *    <jk>null</jk> if not specified.
184    *    Never an empty string.
185    */
186   public final String[] getNav() {
187      return nav;
188   }
189
190   /**
191    * Returns the {@link HtmlDocSerializer#HTMLDOC_aside} setting value in this context.
192    * 
193    * @return
194    *    The {@link HtmlDocSerializer#HTMLDOC_aside} setting value in this context.
195    *    <jk>null</jk> if not specified.
196    *    Never an empty string.
197    */
198   public final String[] getAside() {
199      return aside;
200   }
201
202   /**
203    * Returns the {@link HtmlDocSerializer#HTMLDOC_footer} setting value in this context.
204    * 
205    * @return
206    *    The {@link HtmlDocSerializer#HTMLDOC_footer} setting value in this context.
207    *    <jk>null</jk> if not specified.
208    *    Never an empty string.
209    */
210   public final String[] getFooter() {
211      return footer;
212   }
213
214   /**
215    * Returns the {@link HtmlDocSerializer#HTMLDOC_noResultsMessage} setting value in this context.
216    * 
217    * @return
218    *    The {@link HtmlDocSerializer#HTMLDOC_noResultsMessage} setting value in this context.
219    *    <jk>null</jk> if not specified.
220    *    Never an empty string.
221    */
222   public final String getNoResultsMessage() {
223      return noResultsMessage;
224   }
225
226   @Override /* Serializer */
227   protected void doSerialize(SerializerPipe out, Object o) throws Exception {
228
229      try (HtmlWriter w = getHtmlWriter(out)) {
230         HtmlDocTemplate t = getTemplate();
231
232         w.sTag("html").nl(0);
233         w.sTag(1, "head").nl(1);
234         t.head(this, w, o);
235         w.eTag(1, "head").nl(1);
236         w.sTag(1, "body").nl(1);
237         t.body(this, w, o);
238         w.eTag(1, "body").nl(1);
239         w.eTag("html").nl(0);
240      }
241   }
242
243   /**
244    * Calls the parent {@link #doSerialize(SerializerPipe, Object)} method which invokes just the HTML serializer.
245    * 
246    * @param out
247    *    Where to send the output from the serializer.
248    * @param o The object being serialized.
249    * @throws Exception
250    */
251   public void parentSerialize(Object out, Object o) throws Exception {
252      try (SerializerPipe pipe = createPipe(out)) {
253         super.doSerialize(pipe, o);
254      }
255   }
256}