Package org.pirkaengine.core.template

Source Code of org.pirkaengine.core.template.LoopNode

package org.pirkaengine.core.template;

import static org.pirkaengine.core.util.EqualsHelper.*;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.pirkaengine.core.RenderException;
import org.pirkaengine.core.expression.ExpressionEngine;
import org.pirkaengine.core.expression.Function;
import org.pirkaengine.core.util.EqualsHelper;


/**
* 繰り返し処理を行うノード。
* <p> 内包されたノードを繰り返し評価する。 <br/>
* <code>
*   prk:for="item in items"
* </code>
* </p>
* @author shuji.w6e
* @since 0.1.0
*/
public class LoopNode extends CompositeNode {
    private static final long serialVersionUID = 1L;
    /** インデックス名 */
    private final String indexName;
    /** 項目名 */
    private final String itemName;
    /** 配列名 */
    private final String itemsName;

    /**
     * コンストラクタ.
     * @param startTagNode
     * @param endTagNode
     * @param nodes
     */
    public LoopNode(StartTagNode startTagNode, EndTagNode endTagNode, Node[] nodes) {
        super(startTagNode, endTagNode, nodes);
        String[] params = startTagNode.attrValue.split("(\\s|,)+");
        if (params.length == 3) {
            indexName = null;
            itemName = params[0];
            checkIn(params, 1);
            itemsName = params[2];
        } else if (params.length == 4) {
            indexName = params[0];
            itemName = params[1];
            checkIn(params, 2);
            itemsName = params[3];
        } else {
            throw new RenderException("illegal format for prk:for :" + startTagNode.attrValue);
        }
    }

    /**
     * 配列名を取得する.
     * @return 配列名
     */
    public String getItemsName() {
        return this.itemsName;
    }

    /**
     * 項目名を取得する.
     * @return 項目名
     */
    public String getItemName() {
        return this.itemName;
    }

    private void checkIn(String[] params, int index) {
        if (!params[index].equals("in")) throw new RenderException("Illegal expression: " + startTagNode.attrValue);
    }

    private Iterable<?> getIterable(Map<String, Object> model, Map<String, Function> functions) {
        Object iterable = ExpressionEngine.getInstance().getValue(this.itemsName, model, functions);
        if (iterable instanceof Iterable<?>) {
            return (Iterable<?>) iterable;
        } else if (iterable.getClass().isArray()) {
            return Arrays.asList((Object[]) iterable);
        }
        throw new RenderException("not iteratable object: " + iterable);
    }
   
    @Override
    public String[] getExpressions() {
        Set<String> expressions = new HashSet<String>();
        for (Node node : this.nodes) {
            for (String expression : node.getExpressions()) {
                expressions.add(expression);
            }
        }
        return expressions.toArray(new String[expressions.size()]);
    }

    @Override
    public String getText(Map<String, Object> model, Map<String, Function> functions) {
        if (model.containsKey(itemName)) throw new RenderException("duplicated key: " + itemName);
        if (indexName != null && model.containsKey(indexName)) throw new RenderException("duplicated key: " + indexName);
        StringBuilder buf = new StringBuilder();
        int index = 0;
        for (Object item : getIterable(model, functions)) {
            model.put(itemName, item);
            if (!startTagNode.isPrkTag()) buf.append(startTagNode.getText(model, functions));
            if (indexName != null) model.put(indexName, index);
            for (Node node : nodes) {
                buf.append(node.getText(model, functions));
            }
            if (!endTagNode.isPrkTag()) buf.append(endTagNode.getText(model, functions));
            index++;
        }
        model.remove(itemName);
        if (indexName != null) model.remove(indexName);
        return buf.toString();
    }

    /*
     * (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (!super.equals(obj)) return false;
        if (!(obj instanceof LoopNode)) return false;
        LoopNode node = LoopNode.class.cast(obj);
        if (!EqualsHelper.equals(indexName, node.indexName)) return false;
        if (!EqualsHelper.equals(itemName, node.itemName)) return false;
        if (!EqualsHelper.equals(itemsName, node.itemsName)) return false;
        return true;
    }

    /*
     * (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        int hash = super.hashCode();
        hash = hash * 13 + strHashCode(indexName);
        hash = hash * 13 + strHashCode(itemName);
        hash = hash * 13 + strHashCode(itemsName);
        return hash;
    }

}
TOP

Related Classes of org.pirkaengine.core.template.LoopNode

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.