View Javadoc

1   package org.apache.maven.doxia.siterenderer.sink;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.StringWriter;
23  import java.io.Writer;
24  import java.util.ArrayList;
25  import java.util.HashSet;
26  import java.util.List;
27  import java.util.Set;
28  
29  import javax.swing.text.html.HTML.Attribute;
30  
31  import org.apache.maven.doxia.module.xhtml.XhtmlSink;
32  import org.apache.maven.doxia.sink.render.RenderingContext;
33  import org.apache.maven.doxia.sink.Sink;
34  import org.apache.maven.doxia.sink.SinkEventAttributes;
35  import org.apache.maven.doxia.util.HtmlTools;
36  
37  import org.codehaus.plexus.util.StringUtils;
38  
39  /**
40   * Sink for site rendering.
41   *
42   * @author <a href="mailto:evenisse@codehaus.org">Emmanuel Venisse</a>
43   * @version $Id: SiteRendererSink.java 1185529 2011-10-18 08:27:44Z ltheussl $
44   */
45  public class SiteRendererSink
46      extends XhtmlSink
47      implements Sink, org.codehaus.doxia.sink.Sink
48  {
49      private String date = "";
50  
51      private String title = "";
52  
53      private List<String> authors = new ArrayList<String>();
54  
55      private final StringWriter headWriter;
56  
57      private StringBuffer sectionTitleBuffer;
58  
59      private boolean sectionHasID;
60  
61      private boolean isSectionTitle;
62  
63      private Set<String> anchorsInSectionTitle;
64  
65      private final Writer writer;
66  
67      private RenderingContext renderingContext;
68  
69      /**
70       * Construct a new SiteRendererSink.
71       *
72       * @param renderingContext the RenderingContext.
73       */
74      public SiteRendererSink( RenderingContext renderingContext )
75      {
76          this( new StringWriter(), renderingContext );
77      }
78  
79      /**
80       * Construct a new SiteRendererSink.
81       *
82       * @param writer the writer for the sink.
83       * @param renderingContext the RenderingContext.
84       */
85      private SiteRendererSink( StringWriter writer, RenderingContext renderingContext )
86      {
87          super( writer );
88  
89          this.writer = writer;
90          this.headWriter = new StringWriter();
91          this.renderingContext = renderingContext;
92      }
93  
94      /** {@inheritDoc} */
95      @Override
96      public void title_()
97      {
98          if ( getTextBuffer().length() > 0 )
99          {
100             title = getTextBuffer().toString();
101         }
102 
103         resetTextBuffer();
104     }
105 
106     /**
107      * {@inheritDoc}
108      *
109      * Do nothing.
110      * @see org.apache.maven.doxia.module.xhtml.XhtmlSink#title()
111      */
112     @Override
113     public void title()
114     {
115         // nop
116     }
117 
118     /**
119      * <p>Getter for the field <code>title</code>.</p>
120      *
121      * @return a {@link java.lang.String} object.
122      */
123     public String getTitle()
124     {
125         return title;
126     }
127 
128     /** {@inheritDoc} */
129     @Override
130     public void author_()
131     {
132         if ( getTextBuffer().length() > 0 )
133         {
134             String text = HtmlTools.escapeHTML( getTextBuffer().toString() );
135             text = StringUtils.replace( text, "&amp;#", "&#" );
136             authors.add( text.trim() );
137         }
138 
139         resetTextBuffer();
140     }
141 
142     /**
143      * <p>Getter for the field <code>authors</code>.</p>
144      *
145      * @return a {@link java.util.List} object.
146      */
147     public List<String> getAuthors()
148     {
149         return authors;
150     }
151 
152     /** {@inheritDoc} */
153     @Override
154     public void date_()
155     {
156         if ( getTextBuffer().length() > 0 )
157         {
158             date = getTextBuffer().toString().trim();
159         }
160 
161         resetTextBuffer();
162     }
163 
164     /**
165      * <p>Getter for the field <code>date</code>.</p>
166      *
167      * @return a {@link java.lang.String} object.
168      */
169     public String getDate()
170     {
171         return date;
172     }
173 
174     /**
175      * {@inheritDoc}
176      *
177      * Do nothing.
178      * @see org.apache.maven.doxia.module.xhtml.XhtmlSink#body_()
179      */
180     @Override
181     public void body_()
182     {
183         // nop
184     }
185 
186     /**
187      * {@inheritDoc}
188      *
189      * Do nothing.
190      * @see org.apache.maven.doxia.module.xhtml.XhtmlSink#body()
191      */
192     @Override
193     public void body()
194     {
195         // nop
196     }
197 
198     /**
199      * <p>getBody.</p>
200      *
201      * @return a {@link java.lang.String} object.
202      */
203     public String getBody()
204     {
205         return writer.toString();
206     }
207 
208     /**
209      * <p>getHead.</p>
210      *
211      * @return a {@link java.lang.String} object.
212      *
213      * @since 1.1.1
214      */
215     public String getHead()
216     {
217         return headWriter.toString();
218     }
219 
220     /** {@inheritDoc} */
221     @Override
222     public void head_()
223     {
224         setHeadFlag( false );
225     }
226 
227     /** {@inheritDoc} */
228     @Override
229     public void head()
230     {
231         setHeadFlag( true );
232     }
233 
234     /** {@inheritDoc} */
235     @Override
236     public void anchor( String name, SinkEventAttributes attributes )
237     {
238         super.anchor( name, attributes );
239         if ( isSectionTitle )
240         {
241             if ( anchorsInSectionTitle == null )
242             {
243                 anchorsInSectionTitle = new HashSet<String>();
244             }
245             anchorsInSectionTitle.add( name );
246         }
247     }
248 
249     /** {@inheritDoc} */
250     @Override
251     protected void onSectionTitle( int depth, SinkEventAttributes attributes )
252     {
253         this.sectionTitleBuffer = new StringBuffer();
254         sectionHasID = ( attributes != null && attributes.isDefined ( Attribute.ID.toString() ) );
255         isSectionTitle = true;
256 
257         super.onSectionTitle( depth, attributes );
258     }
259 
260     /** {@inheritDoc} */
261     @Override
262     protected void onSectionTitle_( int depth )
263     {
264         String sectionTitle = sectionTitleBuffer.toString();
265         this.sectionTitleBuffer = null;
266 
267         if ( !sectionHasID && !StringUtils.isEmpty( sectionTitle ) )
268         {
269             String id = HtmlTools.encodeId( sectionTitle );
270             if ( ( anchorsInSectionTitle == null ) || (! anchorsInSectionTitle.contains( id ) ) )
271             {
272                 anchor( id );
273                 anchor_();
274             }
275         }
276         else
277         {
278             sectionHasID = false;
279         }
280 
281         this.isSectionTitle = false;
282         anchorsInSectionTitle = null;
283         super.onSectionTitle_( depth );
284     }
285 
286     /**
287      * <p>Getter for the field <code>renderingContext</code>.</p>
288      *
289      * @return the current rendering context
290      * @since 1.1
291      */
292     public RenderingContext getRenderingContext()
293     {
294         return renderingContext;
295     }
296 
297     /** {@inheritDoc} */
298     @Override
299     public void text( String text )
300     {
301         if ( sectionTitleBuffer != null )
302         {
303             // this implies we're inside a section title, collect text events for anchor generation
304             sectionTitleBuffer.append( text );
305         }
306 
307         super.text( text );
308     }
309 
310     /** {@inheritDoc} */
311     @Override
312     protected void write( String text )
313     {
314         String txt = text;
315 
316         if ( isHeadFlag() )
317         {
318             headWriter.write( unifyEOLs( txt ) );
319 
320             return;
321         }
322 
323         if ( renderingContext != null )
324         {
325             String relativePathToBasedir = renderingContext.getRelativePath();
326 
327             if ( relativePathToBasedir == null )
328             {
329                 txt = StringUtils.replace( txt, "$relativePath", "." );
330             }
331             else
332             {
333                 txt = StringUtils.replace( txt, "$relativePath", relativePathToBasedir );
334             }
335         }
336 
337         super.write( txt );
338     }
339 }