Package cambridge.model

Source Code of cambridge.model.FragmentList

package cambridge.model;

import cambridge.ExpressionLanguage;
import cambridge.TemplateParsingException;
import cambridge.behaviors.ConditionalTagBehavior;

import java.util.ArrayList;
import java.util.Iterator;

import static cambridge.behaviors.ConditionalTagBehavior.ConditionType.FIRST;

/**
* @author Erdinc Yilmazel
*         Date: Oct 13, 2009
*         Time: 1:01:56 PM
*/
public class FragmentList extends ArrayList<Fragment>
{
    final ExpressionLanguage expressionLanguage;

    public FragmentList(ExpressionLanguage expressionLanguage)
    {
        this.expressionLanguage = expressionLanguage;
    }

    Fragment current;

    public FragmentList append(String contents)
    {
        if (!(current instanceof StaticFragment))
        {
            if (current != null)
            {
                add(current);
            }
            current = new StaticFragment();
        }

        ((StaticFragment) current).append(contents);
        return this;
    }

    public void addFragment(Fragment f)
    {
        if (current != null)
        {
            add(current);
        }

        current = f;
    }

    private TagNode getNextTag(TagNode t)
    {
        TemplateNode next = t.getNextSibling();
        TemplateNode nextNext = null;

        if (next instanceof TextNode && ((TextNode) next).isWhiteSpace())
        {
            nextNext = next.getNextSibling();
        }

        return (next instanceof TagNode) ? (TagNode) next :
            (nextNext instanceof TagNode) ? (TagNode) nextNext : null;
    }

    public void pack()
    {
        if (current != null)
        {
            add(current);
        }

        mergeConditionalBlocks();

        for (Fragment f : this)
        {
            f.pack();
        }
    }

    public ExpressionLanguage getExpressionLanguage()
    {
        return expressionLanguage;
    }

    private void mergeConditionalBlocks()
    {
        if (size() < 2)
        {
            return;
        }

        ArrayList<TagNode> conditionals = new ArrayList<TagNode>();
        for (Fragment f : this)
        {
            if (f instanceof TagNode)
            {
                TagNode t = (TagNode) f;
                ConditionalTagBehavior behavior = t.getConditionalBehavior();
                if (behavior != null)
                {
                    conditionals.add(t);
                }
            }
        }

        if (conditionals.size() == 0)
        {
            return;
        }

        ArrayList<ConditionalBlock> blocks = new ArrayList<ConditionalBlock>();

        for (int i = 0; i < conditionals.size(); i++)
        {
            ConditionalBlock currentBlock = null;
            TagNode t = conditionals.get(i);

            ConditionalTagBehavior behavior = t.getConditionalBehavior();

            main:
            do
            {
                TagNode nextTag = getNextTag(t);

                TagNode nextConditional = i + 1 < conditionals.size() ? conditionals.get(i + 1) : null;

                if (currentBlock == null && behavior.getType() == FIRST
                    && nextTag == nextConditional && nextTag != null
                    && nextConditional.getConditionalBehavior().getType() != FIRST)
                {
                    currentBlock = new ConditionalBlock(t);
                }

                if (nextTag == null || nextConditional == null)
                {
                    break;
                }

                if (currentBlock == null && behavior.getType() != FIRST)
                {
                    throw new TemplateParsingException(behavior.getValidationError(), nextTag.getBeginLine(), nextTag.getBeginColumn());
                }

                if (nextTag == nextConditional)
                {
                    switch (nextTag.getConditionalBehavior().getType())
                    {
                        case FIRST:
                            break main;
                        case ALTERNATE:
                            currentBlock.addAlternateCondition(nextTag);
                            break;
                        case DEFAULT:
                            currentBlock.setDefaultCondition(nextTag);
                            i++;
                            t = nextTag;
                            break main;
                    }
                }
                else
                {
                    break;
                }

                i++;
                t = nextTag;
            } while (true);

            if (currentBlock != null)
            {
                if (currentBlock.isComplete())
                {
                    blocks.add(currentBlock);
                }
            }
        }

        for (ConditionalBlock block : blocks)
        {
            TagNode first = block.getFirstTag();
            TagNode last = block.getLastTag();

            int i = 0;
            Iterator<Fragment> iter = iterator();
            boolean remove = false;
            while (iter.hasNext())
            {
                Fragment cur = iter.next();
                if (remove)
                {
                    iter.remove();
                }

                if (cur == last)
                {
                    break;
                }

                if (cur == first)
                {
                    set(i, block);
                    remove = true;
                }
                i++;
            }
        }
    }
}
TOP

Related Classes of cambridge.model.FragmentList

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.