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.sink.SinkEventAttributes;
29  import org.apache.maven.doxia.siterenderer.DocumentContent;
30  import org.apache.maven.doxia.siterenderer.DocumentRenderingContext;
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<>();
47  
48      private final StringWriter headWriter;
49  
50      private final Writer writer;
51  
52      private DocumentRenderingContext docRenderingContext;
53  
54      /**
55       * Construct a new SiteRendererSink for a document.
56       *
57       * @param docRenderingContext the document's rendering context.
58       */
59      public SiteRendererSink(DocumentRenderingContext docRenderingContext) {
60          this(new StringWriter(), docRenderingContext);
61      }
62  
63      /**
64       * Construct a new SiteRendererSink for a document.
65       *
66       * @param writer the writer for the sink.
67       * @param docRenderingContext the document's rendering context.
68       */
69      private SiteRendererSink(StringWriter writer, DocumentRenderingContext docRenderingContext) {
70          super(writer);
71  
72          this.writer = writer;
73          this.headWriter = new StringWriter();
74          this.docRenderingContext = docRenderingContext;
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 must not be in title.
94       * @see org.apache.maven.doxia.module.xhtml5.Xhtml5Sink#title()
95       */
96      @Override
97      public void title(SinkEventAttributes attributes) {
98          resetTextBuffer();
99      }
100 
101     /** {@inheritDoc} */
102     @Override
103     public void author(SinkEventAttributes attributes) {
104         resetTextBuffer();
105     }
106 
107     /** {@inheritDoc} */
108     @Override
109     public void author_() {
110         if (getTextBuffer().length() > 0) {
111             String text = getTextBuffer().toString().trim();
112             authors.add(text);
113         }
114 
115         resetTextBuffer();
116     }
117 
118     /** {@inheritDoc} */
119     @Override
120     public void date(SinkEventAttributes attributes) {
121         resetTextBuffer();
122     }
123 
124     /** {@inheritDoc} */
125     @Override
126     public void date_() {
127         if (getTextBuffer().length() > 0) {
128             date = getTextBuffer().toString().trim();
129         }
130 
131         resetTextBuffer();
132     }
133 
134     /**
135      * {@inheritDoc}
136      *
137      * Do nothing.
138      * @see org.apache.maven.doxia.module.xhtml5.Xhtml5Sink#body_()
139      */
140     @Override
141     public void body_() {
142         // nop
143     }
144 
145     /**
146      * {@inheritDoc}
147      *
148      * Do nothing.
149      * @see org.apache.maven.doxia.module.xhtml5.Xhtml5Sink#body()
150      */
151     @Override
152     public void body(SinkEventAttributes attributes) {
153         // nop
154     }
155 
156     /** {@inheritDoc} */
157     @Override
158     public void head_() {
159         setHeadFlag(false);
160     }
161 
162     /** {@inheritDoc} */
163     @Override
164     public void head(SinkEventAttributes attributes) {
165         setHeadFlag(true);
166     }
167 
168     /** {@inheritDoc} */
169     @Override
170     protected void write(String text) {
171         String txt = text;
172 
173         if (isHeadFlag()) {
174             headWriter.write(unifyEOLs(txt));
175 
176             return;
177         }
178 
179         if (docRenderingContext != null) {
180             String relativePathToBasedir = docRenderingContext.getRelativePath();
181 
182             if (relativePathToBasedir == null) {
183                 txt = StringUtils.replace(txt, "$relativePath", ".");
184             } else {
185                 txt = StringUtils.replace(txt, "$relativePath", relativePathToBasedir);
186             }
187         }
188 
189         super.write(txt);
190     }
191 
192     // DocumentContent interface
193 
194     /** {@inheritDoc} */
195     public String getTitle() {
196         return title;
197     }
198 
199     /** {@inheritDoc} */
200     public List<String> getAuthors() {
201         return authors;
202     }
203 
204     /** {@inheritDoc} */
205     public String getDate() {
206         return date;
207     }
208 
209     /** {@inheritDoc} */
210     public String getBody() {
211         String body = writer.toString();
212 
213         return body.length() > 0 ? body : null;
214     }
215 
216     /** {@inheritDoc} */
217     public String getHead() {
218         String head = headWriter.toString();
219 
220         return head.length() > 0 ? head : null;
221     }
222 
223     /** {@inheritDoc} */
224     public DocumentRenderingContext getRenderingContext() {
225         return docRenderingContext;
226     }
227 }