View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.doxia.siterenderer.sink;
20  
21  import java.io.StringWriter;
22  import java.io.Writer;
23  import java.util.ArrayList;
24  import java.util.List;
25  
26  import org.apache.maven.doxia.markup.HtmlMarkup;
27  import org.apache.maven.doxia.module.xhtml5.Xhtml5Sink;
28  import org.apache.maven.doxia.siterenderer.DocumentContent;
29  import org.apache.maven.doxia.siterenderer.RenderingContext;
30  import org.apache.maven.doxia.util.HtmlTools;
31  import org.codehaus.plexus.util.StringUtils;
32  
33  /**
34   * Sink for site rendering of a document, to allow later merge document's output with a template.
35   * During raw Doxia rendering, content is stored in multiple fields for later use when incorporating
36   * into skin or template: title, date, authors, head, body
37   *
38   * @author <a href="mailto:evenisse@codehaus.org">Emmanuel Venisse</a>
39   */
40  @SuppressWarnings("checkstyle:methodname")
41  public class SiteRendererSink extends Xhtml5Sink implements DocumentContent {
42      private String date;
43  
44      private String title;
45  
46      private List<String> authors = new ArrayList<String>();
47  
48      private final StringWriter headWriter;
49  
50      private final Writer writer;
51  
52      private RenderingContext renderingContext;
53  
54      /**
55       * Construct a new SiteRendererSink for a document.
56       *
57       * @param renderingContext the document's RenderingContext.
58       */
59      public SiteRendererSink(RenderingContext renderingContext) {
60          this(new StringWriter(), renderingContext);
61      }
62  
63      /**
64       * Construct a new SiteRendererSink for a document.
65       *
66       * @param writer the writer for the sink.
67       * @param renderingContext the document's RenderingContext.
68       */
69      private SiteRendererSink(StringWriter writer, RenderingContext renderingContext) {
70          super(writer);
71  
72          this.writer = writer;
73          this.headWriter = new StringWriter();
74          this.renderingContext = renderingContext;
75  
76          /* the template is expected to have used the main tag, which can be used only once */
77          super.contentStack.push(HtmlMarkup.MAIN);
78      }
79  
80      /** {@inheritDoc} */
81      @Override
82      public void title_() {
83          if (getTextBuffer().length() > 0) {
84              title = getTextBuffer().toString();
85          }
86  
87          resetTextBuffer();
88      }
89  
90      /**
91       * {@inheritDoc}
92       *
93       * Reset text buffer, since text content before title mustn't be in title.
94       * @see org.apache.maven.doxia.module.xhtml5.Xhtml5Sink#title()
95       */
96      @Override
97      public void title() {
98          resetTextBuffer();
99      }
100 
101     /** {@inheritDoc} */
102     @Override
103     public void author() {
104         resetTextBuffer();
105     }
106 
107     /** {@inheritDoc} */
108     @Override
109     public void author_() {
110         if (getTextBuffer().length() > 0) {
111             String text = HtmlTools.escapeHTML(getTextBuffer().toString());
112             text = StringUtils.replace(text, "&amp;#", "&#");
113             authors.add(text.trim());
114         }
115 
116         resetTextBuffer();
117     }
118 
119     /** {@inheritDoc} */
120     @Override
121     public void date() {
122         resetTextBuffer();
123     }
124 
125     /** {@inheritDoc} */
126     @Override
127     public void date_() {
128         if (getTextBuffer().length() > 0) {
129             date = getTextBuffer().toString().trim();
130         }
131 
132         resetTextBuffer();
133     }
134 
135     /**
136      * {@inheritDoc}
137      *
138      * Do nothing.
139      * @see org.apache.maven.doxia.module.xhtml5.Xhtml5Sink#body_()
140      */
141     @Override
142     public void body_() {
143         // nop
144     }
145 
146     /**
147      * {@inheritDoc}
148      *
149      * Do nothing.
150      * @see org.apache.maven.doxia.module.xhtml5.Xhtml5Sink#body()
151      */
152     @Override
153     public void body() {
154         // nop
155     }
156 
157     /** {@inheritDoc} */
158     @Override
159     public void head_() {
160         setHeadFlag(false);
161     }
162 
163     /** {@inheritDoc} */
164     @Override
165     public void head() {
166         setHeadFlag(true);
167     }
168 
169     /** {@inheritDoc} */
170     @Override
171     protected void write(String text) {
172         String txt = text;
173 
174         if (isHeadFlag()) {
175             headWriter.write(unifyEOLs(txt));
176 
177             return;
178         }
179 
180         if (renderingContext != null) {
181             String relativePathToBasedir = renderingContext.getRelativePath();
182 
183             if (relativePathToBasedir == null) {
184                 txt = StringUtils.replace(txt, "$relativePath", ".");
185             } else {
186                 txt = StringUtils.replace(txt, "$relativePath", relativePathToBasedir);
187             }
188         }
189 
190         super.write(txt);
191     }
192 
193     // DocumentContent interface
194 
195     /** {@inheritDoc} */
196     public String getTitle() {
197         return title;
198     }
199 
200     /** {@inheritDoc} */
201     public List<String> getAuthors() {
202         return authors;
203     }
204 
205     /** {@inheritDoc} */
206     public String getDate() {
207         return date;
208     }
209 
210     /** {@inheritDoc} */
211     public String getBody() {
212         String body = writer.toString();
213 
214         return body.length() > 0 ? body : null;
215     }
216 
217     /** {@inheritDoc} */
218     public String getHead() {
219         String head = headWriter.toString();
220 
221         return head.length() > 0 ? head : null;
222     }
223 
224     /** {@inheritDoc} */
225     public RenderingContext getRenderingContext() {
226         return renderingContext;
227     }
228 }