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 HtmlDocSerializer ctx;
034   private final String[] navlinks, head, header, nav, aside, footer;
035   private final Set<String> style, stylesheet, script;
036
037   /**
038    * Create a new session using properties specified in the context.
039    *
040    * @param ctx
041    *    The context creating this session object.
042    *    The context contains all the configuration settings for this object.
043    * @param args
044    *    Runtime arguments.
045    */
046   protected HtmlDocSerializerSession(HtmlDocSerializer ctx, SerializerSessionArgs args) {
047      super(ctx, args);
048      this.ctx = ctx;
049
050      header = getProperty(HTMLDOC_header, String[].class, ctx.getHeader());
051      nav = getProperty(HTMLDOC_nav, String[].class, ctx.getNav());
052      aside = getProperty(HTMLDOC_aside, String[].class, ctx.getAside());
053      footer = getProperty(HTMLDOC_footer, String[].class, ctx.getFooter());
054      navlinks = getProperty(HTMLDOC_navlinks, String[].class, ctx.getNavlinks());
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.getStyle())));
058      stylesheet = new LinkedHashSet<>(Arrays.asList(getProperty(HTMLDOC_stylesheet, String[].class, ctx.getStylesheet())));
059      script = new LinkedHashSet<>(Arrays.asList(getProperty(HTMLDOC_script, String[].class, ctx.getScript())));
060
061      head = getProperty(HTMLDOC_head, String[].class, ctx.getHead());
062   }
063
064   @Override /* Session */
065   public ObjectMap asMap() {
066      return super.asMap()
067         .append("HtmlDocSerializerSession", new ObjectMap()
068            .append("aside", aside)
069            .append("head", head)
070            .append("header", header)
071            .append("footer", footer)
072            .append("nav", nav)
073            .append("navlinks", navlinks)
074            .append("script", script)
075            .append("style", style)
076            .append("stylesheet", stylesheet)
077         );
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 Exception {
094
095      try (HtmlWriter w = getHtmlWriter(out)) {
096         getTemplate().writeTo(this, w, o);
097      }
098   }
099
100   /**
101    * Calls the parent {@link #doSerialize(SerializerPipe, Object)} method which invokes just the HTML serializer.
102    *
103    * @param out
104    *    Where to send the output from the serializer.
105    * @param o The object being serialized.
106    * @throws Exception
107    */
108   public void parentSerialize(Object out, Object o) throws Exception {
109      try (SerializerPipe pipe = createPipe(out)) {
110         super.doSerialize(pipe, o);
111      }
112   }
113   //-----------------------------------------------------------------------------------------------------------------
114   // Properties
115   //-----------------------------------------------------------------------------------------------------------------
116
117   /**
118    * Configuration property:  CSS style code.
119    *
120    * @see HtmlDocSerializer#HTMLDOC_style
121    * @return
122    *    The CSS instructions to add to the HTML page.
123    */
124   protected final Set<String> getStyle() {
125      return style;
126   }
127
128   /**
129    * Configuration property:  Stylesheet import URLs.
130    *
131    * @see HtmlDocSerializer#HTMLDOC_stylesheet
132    * @return
133    *    The link to the stylesheet of the HTML page.
134    */
135   protected final Set<String> getStylesheet() {
136      return stylesheet;
137   }
138
139   /**
140    * Configuration property:  Javascript code.
141    *
142    * @see HtmlDocSerializer#HTMLDOC_script
143    * @return
144    *    Arbitrary Javascript to add to the HTML page.
145    */
146   protected final Set<String> getScript() {
147      return script;
148   }
149
150   /**
151    * Configuration property:  Page navigation links.
152    *
153    * @see HtmlDocSerializer#HTMLDOC_navlinks
154    * @return
155    *    Navigation links to add to the HTML page.
156    */
157   protected final String[] getNavlinks() {
158      return navlinks;
159   }
160
161   /**
162    * Configuration property:  Additional head section content.
163    *
164    * @see HtmlDocSerializer#HTMLDOC_head
165    * @return
166    *    HTML content to add to the head section of the HTML page.
167    */
168   protected final String[] getHead() {
169      return head;
170   }
171
172   /**
173    * Configuration property:  Header section contents.
174    *
175    * @see HtmlDocSerializer#HTMLDOC_header
176    * @return
177    *    The overridden contents of the header section on the HTML page.
178    */
179   protected final String[] getHeader() {
180      return header;
181   }
182
183   /**
184    * Configuration property:  Nav section contents.
185    *
186    * @see HtmlDocSerializer#HTMLDOC_nav
187    * @return
188    *    The overridden contents of the nav section on the HTML page.
189    */
190   protected final String[] getNav() {
191      return nav;
192   }
193
194   /**
195    * Configuration property:  Aside section contents.
196    *
197    * @see HtmlDocSerializer#HTMLDOC_aside
198    * @return
199    *    The overridden contents of the aside section on the HTML page.
200    */
201   protected final String[] getAside() {
202      return aside;
203   }
204
205   /**
206    * Configuration property:  Footer section contents.
207    *
208    * @see HtmlDocSerializer#HTMLDOC_footer
209    * @return
210    *    The overridden contents of the footer section on the HTML page.
211    */
212   protected final String[] getFooter() {
213      return footer;
214   }
215
216   /**
217    * Configuration property:  No-results message.
218    *
219    * @see HtmlDocSerializer#HTMLDOC_noResultsMessage
220    * @return
221    *    The message used when serializing an empty array or empty list.
222    */
223   protected final String getNoResultsMessage() {
224      return ctx.getNoResultsMessage();
225   }
226
227   /**
228    * Configuration property:  Prevent word wrap on page.
229    *
230    * @see HtmlDocSerializer#HTMLDOC_nowrap
231    * @return
232    *    <jk>true</jk> if <js>"* {white-space:nowrap}"</js> shoudl be added to the CSS instructions on the page to prevent word wrapping.
233    */
234   protected final boolean isNowrap() {
235      return ctx.isNowrap();
236   }
237
238   /**
239    * Configuration property:  HTML document template.
240    *
241    * @see HtmlDocSerializer#HTMLDOC_template
242    * @return
243    *    The template to use for serializing the page.
244    */
245   protected final HtmlDocTemplate getTemplate() {
246      return ctx.getTemplate();
247   }
248}