All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xwiki.rendering.wikimodel.util.TreeBuilder Maven / Gradle / Ivy

There is a newer version: 16.10.2
Show newest version
/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.xwiki.rendering.wikimodel.util;

import java.util.ArrayList;
import java.util.List;

/**
 * This is an internal utility class used as a context to keep in memory the
 * current state of parsed trees (list items).
 *
 * @version $Id: a65caf30ecb590902e0b74aa4117a8bfc683ee12 $
 * @since 4.0M1
 */
public final class TreeBuilder>
{
    /**
     * This interface identifies position of elements in rows.
     *
     * @author MikhailKotelnikov
     */
    public interface IPos>
    {
        /**
         * @return true if the underlying data in both positions
         *         are the same
         */
        boolean equalsData(X pos);

        /**
         * @return the position of the node
         */
        int getPos();
    }

    public interface ITreeListener>
    {
        void onBeginRow(X n);

        void onBeginTree(X n);

        void onEndRow(X n);

        void onEndTree(X n);
    }

    private static > void addTail(
        ITreeListener listener,
        List firstArray,
        List secondArray,
        int secondPos,
        boolean openTree)
    {
        X n = getNode(secondArray, secondPos);
        if (n == null) {
            return;
        }
        if (openTree) {
            listener.onBeginTree(n);
        }
        listener.onBeginRow(n);
        firstArray.add(n);
        addTail(listener, firstArray, secondArray, secondPos + 1, true);
    }

    private static > void doAlign(
        ITreeListener listener,
        List firstArray,
        List secondArray,
        boolean expand)
    {
        boolean newTree = true;
        int f;
        int s;
        int firstLen = firstArray.size();
        int secondLen = secondArray.size();
        for (f = 0, s = 0; f < firstLen && s < secondLen; f++) {
            X first = firstArray.get(f);
            X second = secondArray.get(s);
            int firstPos = first.getPos();
            int secondPos = second.getPos();
            if (firstPos >= secondPos) {
                if (!first.equalsData(second)) {
                    break;
                } else if (s == secondLen - 1) {
                    newTree = false;
                    break;
                }
                s++;
            }
        }
        removeTail(listener, firstArray, f, newTree, expand);
        if (expand) {
            addTail(listener, firstArray, secondArray, s, newTree);
        }
    }

    private static > X getNode(List list, int pos)
    {
        return pos < 0 || pos >= list.size() ? null : list.get(pos);
    }

    private static > void removeTail(
        ITreeListener listener,
        List array,
        int pos,
        boolean closeTree,
        boolean remove)
    {
        X node = getNode(array, pos);
        if (node == null) {
            return;
        }
        removeTail(listener, array, pos + 1, true, true);
        listener.onEndRow(node);
        if (closeTree) {
            listener.onEndTree(node);
        }
        if (remove) {
            array.remove(pos);
        }
    }

    public List fList = new ArrayList();

    private ITreeListener fListener;

    public TreeBuilder(ITreeListener listener)
    {
        super();
        fListener = listener;
    }

    public void align(List row)
    {
        doAlign(fListener, fList, row, true);
    }

    public void align(X pos)
    {
        List list = new ArrayList();
        if (pos != null) {
            list.add(pos);
        }
        align(list);
    }

    public X get(int pos)
    {
        return pos >= 0 && pos < fList.size() ? fList.get(pos) : null;
    }

    public X getPeek()
    {
        return get(fList.size() - 1);
    }

    public void trim(List row)
    {
        doAlign(fListener, fList, row, false);
    }

    public void trim(X pos)
    {
        List list = new ArrayList();
        if (pos != null) {
            list.add(pos);
        }
        trim(list);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy