001package org.apache.maven.doxia.module.confluence.parser.list;
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.ArrayList;
023import java.util.List;
024
025import org.apache.maven.doxia.module.confluence.parser.Block;
026import org.apache.maven.doxia.module.confluence.parser.ChildBlocksBuilder;
027
028/**
029 * <p>TreeListBuilder class.</p>
030 */
031public class TreeListBuilder
032{
033    private TreeComponent root;
034
035    private TreeComponent current;
036
037    TreeListBuilder()
038    {
039        root = new TreeComponent( null, "root", 0 );
040
041        current = root;
042    }
043
044    void feedEntry( int type, int level, String text )
045    {
046        int currentDepth = current.getDepth();
047
048        int incomingLevel = level - 1;
049
050        if ( incomingLevel == currentDepth )
051        {
052            // nothing to move
053        }
054        else if ( incomingLevel > currentDepth )
055        {
056            // el actual ahora es el �ltimo que insert�
057            List<TreeComponent> components = current.getChildren();
058
059            if ( components.size() == 0 )
060            {
061                /* for example:
062                 *        * item1
063                 *     * item2
064                 */
065                for ( int i = 0, n = incomingLevel - currentDepth; i < n; i++ )
066                {
067                    current = current.addChildren( "", type );
068                }
069            }
070            else
071            {
072                current = components.get( components.size() - 1 );
073            }
074        }
075        else
076        {
077            for ( int i = 0, n = currentDepth - incomingLevel; i < n; i++ )
078            {
079                current = current.getFather();
080
081                if ( current == null )
082                {
083                    throw new IllegalStateException();
084                }
085            }
086        }
087        current.addChildren( text.trim(), type );
088    }
089
090    ListBlock getBlock()
091    {
092        return getList( root );
093    }
094
095    private ListBlock getList( TreeComponent treeComponent )
096    {
097        List<Block> list = getListItems( treeComponent );
098
099        int type = treeComponent.getChildren().get( 0 ).getType();
100
101        if ( type == ListBlockParser.BULLETED_LIST )
102        {
103            return new BulletedListBlock( list );
104        }
105
106        return new NumberedListBlock( list );
107    }
108
109    private List<Block> getListItems( TreeComponent tc )
110    {
111        List<Block> blocks = new ArrayList<>();
112
113        for ( TreeComponent child : tc.getChildren() )
114        {
115            List<Block> childBlocks = new ArrayList<>();
116
117            if ( child.getFather() != null )
118            {
119                childBlocks.addAll( new ChildBlocksBuilder( child.getText() ).getBlocks() );
120            }
121
122            if ( child.getChildren().size() != 0 )
123            {
124                blocks.add( new ListItemBlock( childBlocks, getList( child ) ) );
125            }
126            else
127            {
128                blocks.add( new ListItemBlock( childBlocks ) );
129            }
130        }
131
132        return blocks;
133    }
134}