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.List;
023import java.util.ArrayList;
024import java.util.Collections;
025
026import org.codehaus.plexus.util.StringUtils;
027
028/**
029 * <p>IndexEntry class.</p>
030 *
031 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
032 * @version $Id$
033 */
034public class IndexEntry
035{
036    /**
037     * The parent entry.
038     */
039    private final IndexEntry parent;
040
041    /**
042     * The id of the entry.
043     */
044    private String id;
045
046    /**
047     * The entry title.
048     */
049    private String title;
050
051    /**
052     * The child entries.
053     */
054    private List<IndexEntry> childEntries = new ArrayList<IndexEntry>();
055
056    /**
057     * System-dependent EOL.
058     */
059    private static final String EOL = System.getProperty( "line.separator" );
060
061    /**
062     * Constructor.
063     *
064     * @param newId The id. May be null.
065     */
066    public IndexEntry( String newId )
067    {
068        this( null, newId );
069    }
070
071    /**
072     * Constructor.
073     *
074     * @param newParent The parent. May be null.
075     * @param newId     The id. May be null.
076     */
077    public IndexEntry( IndexEntry newParent, String newId )
078    {
079        this.parent = newParent;
080        this.id = newId;
081
082        if ( parent != null )
083        {
084            parent.childEntries.add( this );
085        }
086    }
087
088    /**
089     * Returns the parent entry.
090     *
091     * @return the parent entry.
092     */
093    public IndexEntry getParent()
094    {
095        return parent;
096    }
097
098    /**
099     * Returns the id.
100     *
101     * @return the id.
102     */
103    public String getId()
104    {
105        return id;
106    }
107
108    /**
109     * Set the id.
110     *
111     * @since 1.1.2
112     */
113    protected void setId( String id )
114    {
115        this.id = id;
116    }
117
118    /**
119     * Returns the title.
120     *
121     * @return the title.
122     */
123    public String getTitle()
124    {
125        return title;
126    }
127
128    /**
129     * Sets the title.
130     *
131     * @param newTitle the title.
132     */
133    public void setTitle( String newTitle )
134    {
135        this.title = newTitle;
136    }
137
138    /**
139     * Returns an unmodifiableList of the child entries.
140     *
141     * @return child entries.
142     */
143    public List<IndexEntry> getChildEntries()
144    {
145        return Collections.unmodifiableList( childEntries );
146    }
147
148    /**
149     * Sets the child entries or creates a new ArrayList if entries == null.
150     *
151     * @param entries the entries.
152     */
153    public void setChildEntries( List<IndexEntry> entries )
154    {
155        if ( entries == null )
156        {
157            childEntries = new ArrayList<IndexEntry>();
158        }
159
160        this.childEntries = entries;
161    }
162
163    // -----------------------------------------------------------------------
164    // Utils
165    // -----------------------------------------------------------------------
166
167    /**
168     * Returns the next entry.
169     *
170     * @return the next entry, or null if there is none.
171     */
172    public IndexEntry getNextEntry()
173    {
174        if ( parent == null )
175        {
176            return null;
177        }
178
179        List<IndexEntry> entries = parent.getChildEntries();
180
181        int index = entries.indexOf( this );
182
183        if ( index + 1 >= entries.size() )
184        {
185            return null;
186        }
187
188        return entries.get( index + 1 );
189    }
190
191    /**
192     * Returns the previous entry.
193     *
194     * @return the previous entry, or null if there is none.
195     */
196    public IndexEntry getPrevEntry()
197    {
198        if ( parent == null )
199        {
200            return null;
201        }
202
203        List<IndexEntry> entries = parent.getChildEntries();
204
205        int index = entries.indexOf( this );
206
207        if ( index == 0 )
208        {
209            return null;
210        }
211
212        return entries.get( index - 1 );
213    }
214
215    /**
216     * Returns the first entry.
217     *
218     * @return the first entry, or null if there is none.
219     */
220    public IndexEntry getFirstEntry()
221    {
222        List<IndexEntry> entries = getChildEntries();
223
224        if ( entries.size() == 0 )
225        {
226            return null;
227        }
228
229        return entries.get( 0 );
230    }
231
232    /**
233     * Returns the last entry.
234     *
235     * @return the last entry, or null if there is none.
236     */
237    public IndexEntry getLastEntry()
238    {
239        List<IndexEntry> entries = getChildEntries();
240
241        if ( entries.size() == 0 )
242        {
243            return null;
244        }
245
246        return entries.get( entries.size() - 1 );
247    }
248
249    /**
250     * Returns the root entry.
251     *
252     * @return the root entry, or null if there is none.
253     */
254    public IndexEntry getRootEntry()
255    {
256        List<IndexEntry> entries = getChildEntries();
257
258        if ( entries.size() == 0 )
259        {
260            return null;
261        }
262        else if ( entries.size() > 1 )
263        {
264            throw new RuntimeException( "This index has more than one root entry" );
265        }
266        else
267        {
268            return entries.get( 0 );
269        }
270    }
271
272    // -----------------------------------------------------------------------
273    // Object Overrides
274    // -----------------------------------------------------------------------
275
276    /**
277     * {@inheritDoc}
278     * <p/>
279     * Returns a string representation of the object.
280     */
281    public String toString()
282    {
283        return toString( 0 );
284    }
285
286    /**
287     * Returns a string representation of all objects to the given depth.
288     *
289     * @param depth The depth to descent to.
290     * @return A string.
291     */
292    public String toString( int depth )
293    {
294        StringBuilder message = new StringBuilder();
295
296        message.append( "Id: " ).append( id );
297
298        if ( StringUtils.isNotEmpty( title ) )
299        {
300            message.append( ", title: " ).append( title );
301        }
302
303        message.append( EOL );
304
305        StringBuilder indent = new StringBuilder( "" );
306
307        for ( int i = 0; i < depth; i++ )
308        {
309            indent.append( " " );
310        }
311
312        for ( IndexEntry entry : getChildEntries() )
313        {
314            message.append( indent ).append( entry.toString( depth + 1 ) );
315        }
316
317        return message.toString();
318    }
319}