001package org.apache.maven.doxia.index;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.util.Stack;
023
024import org.apache.maven.doxia.sink.impl.SinkAdapter;
025import org.apache.maven.doxia.util.HtmlTools;
026
027/**
028 * A sink implementation for index.
029 *
030 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
031 * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
032 * @version $Id$
033 */
034public class IndexingSink
035    extends SinkAdapter
036{
037    /** Section 1. */
038    private static final int TYPE_SECTION_1 = 1;
039
040    /** Section 2. */
041    private static final int TYPE_SECTION_2 = 2;
042
043    /** Section 3. */
044    private static final int TYPE_SECTION_3 = 3;
045
046    /** Section 4. */
047    private static final int TYPE_SECTION_4 = 4;
048
049    /** Section 5. */
050    private static final int TYPE_SECTION_5 = 5;
051
052    /** Defined term. */
053    private static final int TYPE_DEFINED_TERM = 6;
054
055    /** Figure. */
056    private static final int TYPE_FIGURE = 7;
057
058    /** Table. */
059    private static final int TYPE_TABLE = 8;
060
061    /** Title. */
062    private static final int TITLE = 9;
063
064    /** The current type. */
065    private int type;
066
067    /** The current title. */
068    private String title;
069
070    /** The stack. */
071    private final Stack<IndexEntry> stack;
072
073    /**
074     * Default constructor.
075     *
076     * @param sectionEntry The first index entry.
077     */
078    public IndexingSink( IndexEntry sectionEntry )
079    {
080        stack = new Stack<>();
081        stack.push( sectionEntry );
082
083        init();
084    }
085
086    /**
087     * <p>Getter for the field <code>title</code>.</p>
088     *
089     * @return the title
090     */
091    public String getTitle()
092    {
093        return title;
094    }
095
096    // ----------------------------------------------------------------------
097    // Sink Overrides
098    // ----------------------------------------------------------------------
099
100    /** {@inheritDoc} */
101    public void title()
102    {
103        this.type = TITLE;
104    }
105
106    /** {@inheritDoc} */
107    public void section1()
108    {
109        pushNewEntry();
110    }
111
112    /** {@inheritDoc} */
113    public void sectionTitle1()
114    {
115        this.type = TYPE_SECTION_1;
116    }
117
118    /** {@inheritDoc} */
119    public void title_()
120    {
121        this.type = 0;
122    }
123
124    public void sectionTitle1_()
125    {
126        this.type = 0;
127    }
128
129    /** {@inheritDoc} */
130    public void section1_()
131    {
132        pop();
133    }
134
135    /** {@inheritDoc} */
136    public void section2()
137    {
138        pushNewEntry();
139    }
140
141    /** {@inheritDoc} */
142    public void sectionTitle2()
143    {
144        this.type = TYPE_SECTION_2;
145    }
146
147    public void sectionTitle2_()
148    {
149        this.type = 0;
150    }
151
152    /** {@inheritDoc} */
153    public void section2_()
154    {
155        pop();
156    }
157
158    /** {@inheritDoc} */
159    public void section3()
160    {
161        pushNewEntry();
162    }
163
164    /** {@inheritDoc} */
165    public void sectionTitle3()
166    {
167        this.type = TYPE_SECTION_3;
168    }
169
170    public void sectionTitle3_()
171    {
172        this.type = 0;
173    }
174
175    /** {@inheritDoc} */
176    public void section3_()
177    {
178        pop();
179    }
180
181    /** {@inheritDoc} */
182    public void section4()
183    {
184        pushNewEntry();
185    }
186
187    /** {@inheritDoc} */
188    public void sectionTitle4()
189    {
190        this.type = TYPE_SECTION_4;
191    }
192
193    public void sectionTitle4_()
194    {
195        this.type = 0;
196    }
197
198    /** {@inheritDoc} */
199    public void section4_()
200    {
201        pop();
202    }
203
204    /** {@inheritDoc} */
205    public void section5()
206    {
207        pushNewEntry();
208    }
209
210    /** {@inheritDoc} */
211    public void sectionTitle5()
212    {
213        this.type = TYPE_SECTION_5;
214    }
215
216    public void sectionTitle5_()
217    {
218        this.type = 0;
219    }
220
221    /** {@inheritDoc} */
222    public void section5_()
223    {
224        pop();
225    }
226
227    // public void definedTerm()
228    // {
229    // type = TYPE_DEFINED_TERM;
230    // }
231    //
232    // public void figureCaption()
233    // {
234    // type = TYPE_FIGURE;
235    // }
236    //
237    // public void tableCaption()
238    // {
239    // type = TYPE_TABLE;
240    // }
241
242    /** {@inheritDoc} */
243    public void text( String text )
244    {
245        switch ( this.type )
246        {
247            case TITLE:
248                this.title = text;
249                break;
250            case TYPE_SECTION_1:
251            case TYPE_SECTION_2:
252            case TYPE_SECTION_3:
253            case TYPE_SECTION_4:
254            case TYPE_SECTION_5:
255                // -----------------------------------------------------------------------
256                // Sanitize the id. The most important step is to remove any blanks
257                // -----------------------------------------------------------------------
258
259                // append text to current entry
260                IndexEntry entry = stack.lastElement();
261
262                String title = entry.getTitle() + text;
263                title = title.replaceAll( "[\\r\\n]+", "" );
264                entry.setTitle( title );
265
266                entry.setId( HtmlTools.encodeId( title ) );
267
268                break;
269            // Dunno how to handle these yet
270            case TYPE_DEFINED_TERM:
271            case TYPE_FIGURE:
272            case TYPE_TABLE:
273            default:
274                break;
275        }
276    }
277
278    /**
279     * Creates and pushes a new IndexEntry onto the top of this stack.
280     */
281    public void pushNewEntry()
282    {
283        IndexEntry entry = new IndexEntry( peek(), "" );
284
285        entry.setTitle( "" );
286
287        stack.push( entry );
288    }
289
290    /**
291     * Pushes an IndexEntry onto the top of this stack.
292     *
293     * @param entry to put.
294     */
295    public void push( IndexEntry entry )
296    {
297        stack.push( entry );
298    }
299
300    /**
301     * Removes the IndexEntry at the top of this stack.
302     */
303    public void pop()
304    {
305        stack.pop();
306    }
307
308    /**
309     * <p>peek.</p>
310     *
311     * @return Looks at the IndexEntry at the top of this stack.
312     */
313    public IndexEntry peek()
314    {
315        return stack.peek();
316    }
317
318    /** {@inheritDoc} */
319    public void close()
320    {
321        super.close();
322
323        init();
324    }
325
326    /** {@inheritDoc} */
327    protected void init()
328    {
329        this.type = 0;
330        this.title = null;
331    }
332}