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 org.apache.juneau.internal.*;
016
017/**
018 * A basic template for the HTML doc serializer.
019 * 
020 * <p>
021 * This class can be subclassed to customize page rendering.
022 */
023public class HtmlDocTemplateBasic implements HtmlDocTemplate {
024
025   @Override /* HtmlDocTemplate */
026   public void head(HtmlDocSerializerSession session, HtmlWriter w, Object o) throws Exception {
027
028      String[] head = session.getHead();
029      for (int i = 0; i < head.length; i++)
030         w.sIf(i > 0).appendln(2, head[i]);
031
032      if (hasStyle(session)) {
033         w.sTag(2, "style").nl(2);
034         style(session, w, o);
035         w.ie(2).eTag("style").nl(2);
036      }
037      if (hasScript(session)) {
038         w.sTag(2, "script").nl(2);
039         script(session, w, o);
040         w.ie(2).eTag("script").nl(2);
041      }
042   }
043
044   @Override /* HtmlDocTemplate */
045   public void style(HtmlDocSerializerSession session, HtmlWriter w, Object o) throws Exception {
046
047      int i = 0;
048      for (String s : session.getStylesheet())
049         w.sIf(i++ > 0).append(3, "@import ").q().append(session.resolveUri(s)).q().appendln(";");
050
051      if (session.isNoWrap())
052         w.appendln(3, "div.data * {white-space:nowrap;} ");
053
054      for (String s : session.getStyle())
055         w.sIf(i > 0).appendln(3, s);
056   }
057
058   @Override /* HtmlDocTemplate */
059   public void script(HtmlDocSerializerSession session, HtmlWriter w, Object o) throws Exception {
060      int i = 0;
061      for (String s : session.getScript())
062         w.sIf(i++ > 0).append(3, s).append('\n'); // Must always append a newline even if whitespace disabled!
063   }
064
065   @Override /* HtmlDocTemplate */
066   public void body(HtmlDocSerializerSession session, HtmlWriter w, Object o) throws Exception {
067
068      if (hasHeader(session)) {
069         w.sTag(2, "header").nl(2);
070         header(session, w, o);
071         w.ie(2).eTag("header").nl(2);
072      }
073
074      if (hasNav(session)) {
075         w.sTag(2, "nav").nl(2);
076         nav(session, w, o);
077         w.ie(2).eTag("nav").nl(2);
078      }
079
080      w.sTag(2, "section").nl(2);
081
082      w.sTag(3, "article").nl(3);
083      article(session, w, o);
084      w.ie(3).eTag("article").nl(3);
085
086      if (hasAside(session)) {
087         w.sTag(3, "aside").nl(3);
088         aside(session, w, o);
089         w.ie(3).eTag("aside").nl(3);
090      }
091
092      w.ie(2).eTag("section").nl(2);
093
094      if (hasFooter(session)) {
095         w.sTag(2, "footer").nl(2);
096         footer(session, w, o);
097         w.ie(2).eTag("footer").nl(2);
098      }
099   }
100
101   @Override /* HtmlDocTemplate */
102   public void header(HtmlDocSerializerSession session, HtmlWriter w, Object o) throws Exception {
103      // Write the title of the page.
104      String[] header = session.getHeader();
105      for (int i = 0; i < header.length; i++)
106         w.sIf(i > 0).appendln(3, header[i]);
107   }
108
109
110   @Override /* HtmlDocTemplate */
111   public void nav(HtmlDocSerializerSession session, HtmlWriter w, Object o) throws Exception {
112      String[] nav = session.getNav();
113      if (nav.length > 0) {
114         for (int i = 0; i < nav.length; i++)
115            w.sIf(i > 0).appendln(3, nav[i]);
116      } else {
117         String[] links = session.getNavLinks();
118         if (links.length > 0) {
119            w.sTag(3, "ol").nl(3);
120            for (String l : links) {
121               w.sTag(4, "li");
122               if (l.matches("(?s)\\S+\\:.*")) {
123                  int i = l.indexOf(':');
124                  String key = l.substring(0, i);
125                  String val = l.substring(i+1).trim();
126                  if (val.startsWith("<"))
127                     w.nl(4).appendln(5, val);
128                  else
129                     w.oTag("a").attr("href", session.resolveUri(val), true).cTag().text(key, true).eTag("a");
130                  w.eTag("li").nl(4);
131               } else {
132                  w.nl(4).appendln(5, l);
133                  w.eTag(4, "li").nl(4);
134               }
135            }
136            w.eTag(3, "ol").nl(3);
137         }
138      }
139   }
140
141   @Override /* HtmlDocTemplate */
142   public void aside(HtmlDocSerializerSession session, HtmlWriter w, Object o) throws Exception {
143      String[] aside = session.getAside();
144      for (int i = 0; i < aside.length; i++)
145         w.sIf(i > 0).appendln(4, aside[i]);
146   }
147
148   @Override /* HtmlDocTemplate */
149   public void article(HtmlDocSerializerSession session, HtmlWriter w, Object o) throws Exception {
150      // To allow for page formatting using CSS, we encapsulate the data inside two div tags:
151      // <div class='outerdata'><div class='data' id='data'>...</div></div>
152      w.oTag(4, "div").attr("class","outerdata").append('>').nl(4);
153      w.oTag(5, "div").attr("class","data").attr("id", "data").append('>').nl(5);
154
155      if (o == null) {
156         w.append(6, "<null/>").nl(6);
157      } else if (ObjectUtils.isEmpty(o)){
158         String m = session.getNoResultsMessage();
159         if (exists(m))
160            w.append(6, m).nl(6);
161      } else {
162         session.indent = 6;
163         w.flush();
164         session.parentSerialize(w, o);
165      }
166
167      w.ie(5).eTag("div").nl(5);
168      w.ie(4).eTag("div").nl(4);
169   }
170
171   @Override /* HtmlDocTemplate */
172   public void footer(HtmlDocSerializerSession session, HtmlWriter w, Object o) throws Exception {
173      String[] footer = session.getFooter();
174      for (int i = 0; i < footer.length; i++)
175         w.sIf(i > 0).appendln(3, footer[i]);
176   }
177
178   @Override /* HtmlDocTemplate */
179   public boolean hasStyle(HtmlDocSerializerSession session) {
180      return true;
181   }
182
183   @Override /* HtmlDocTemplate */
184   public boolean hasScript(HtmlDocSerializerSession session) {
185      return true;
186   }
187
188   @Override /* HtmlDocTemplate */
189   public boolean hasHeader(HtmlDocSerializerSession session) {
190      return session.getHeader().length > 0;
191   }
192
193   @Override /* HtmlDocTemplate */
194   public boolean hasNav(HtmlDocSerializerSession session) {
195      return session.getNav().length > 0 || session.getNavLinks().length > 0;
196   }
197
198   @Override /* HtmlDocTemplate */
199   public boolean hasAside(HtmlDocSerializerSession session) {
200      return session.getAside().length > 0;
201   }
202
203   @Override /* HtmlDocTemplate */
204   public boolean hasFooter(HtmlDocSerializerSession session) {
205      return session.getFooter().length > 0;
206   }
207
208   private static boolean exists(String s) {
209      return s != null && ! "NONE".equals(s);
210   }
211}