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 */
033public class IndexEntry
034{
035    /**
036     * The parent entry.
037     */
038    private final IndexEntry parent;
039
040    /**
041     * The id of the entry.
042     */
043    private String id;
044
045    /**
046     * The entry title.
047     */
048    private String title;
049
050    /**
051     * The child entries.
052     */
053    private List<IndexEntry> childEntries = new ArrayList<>();
054
055    /**
056     * System-dependent EOL.
057     */
058    private static final String EOL = System.getProperty( "line.separator" );
059
060    /**
061     * Constructor.
062     *
063     * @param newId The id. May be null.
064     */
065    public IndexEntry( String newId )
066    {
067        this( null, newId );
068    }
069
070    /**
071     * Constructor.
072     *
073     * @param newParent The parent. May be null.
074     * @param newId     The id. May be null.
075     */
076    public IndexEntry( IndexEntry newParent, String newId )
077    {
078        this.parent = newParent;
079        this.id = newId;
080
081        if ( parent != null )
082        {
083            parent.childEntries.add( this );
084        }
085    }
086
087    /**
088     * Returns the parent entry.
089     *
090     * @return the parent entry.
091     */
092    public IndexEntry getParent()
093    {
094        return parent;
095    }
096
097    /**
098     * Returns the id.
099     *
100     * @return the id.
101     */
102    public String getId()
103    {
104        return id;
105    }
106
107    /**
108     * Set the id.
109     *
110     * @param id the id
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<>();
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     * Returns a string representation of the object.
278     *
279     * @return Returns a string representation of all objects
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}