package org.wikiup.servlet.ms;

import org.wikiup.core.impl.Null;
import org.wikiup.core.inf.Document;
import org.wikiup.core.inf.Dictionary;
import org.wikiup.core.inf.BeanContainer;
import org.wikiup.core.util.Documents;
import org.wikiup.core.util.XPath;
import org.wikiup.servlet.inf.ProcessorContext;

import java.util.Iterator;
import java.util.Stack;

public class ProcessorContextModelContainerStack implements ProcessorContext {
    private Stack<ProcessorContextModelContainer> contextStack = new Stack<ProcessorContextModelContainer>();

    public BeanContainer getModelContainer(String name, Dictionary<?> params) {
        return getModelContainerFromStack(name, params);
    }

    public BeanContainer getModelContainerFromStack(String name, Dictionary<?> params) {
        int i;
        for(i = contextStack.size() - 1; i >= 0; i--) {
            ProcessorContextModelContainer container = contextStack.get(i);
            BeanContainer mc = container.getModelContainer(name, params);
            if(mc != null)
                return mc;
        }
        return null;
    }

    public Object getValueFromContextStack(String name, Dictionary<?> params) {
        int i = contextStack.size();
        Object value = getValueByXPath(name, params);
        while(value == null && i > 0)
            value = contextStack.get(--i).get(name);
        return value;
    }

    private Object getValueByXPath(String xpath, Dictionary<?> params) {
        XPath xp = new XPath(xpath);
        String cond = xp.getCondition();
        if(xp.isXPath() && cond != null) {
            BeanContainer modelProvider = getModelContainer(xp.getPath(), params);
            Document doc = modelProvider != null ? modelProvider.query(Document.class) : null;
            return doc != null ? Documents.getAttributeValue(doc, cond, null) : null;
        }
        return null;
    }

    public Iterator<BeanContainer> getIteratorFromContextStack(String name) {
        ProcessorContextModelContainer container = peek();
        return container != null ? container.getIterator(name) : Null.getInstance();
    }

    public Object get(String name) {
        return getValueFromContextStack(name, null);
    }

    public Iterator<BeanContainer> getIterator(String name) {
        return contextStack.empty() ? Null.getInstance() : contextStack.peek().getIterator(name);
    }

    public ProcessorContextModelContainer push(ProcessorContextModelContainer token) {
        return contextStack.push(token);
    }

    public ProcessorContextModelContainer pop() {
        return contextStack.pop();
    }

    public ProcessorContextModelContainer peek() {
        return contextStack.empty() ? null : contextStack.peek();
    }
}

@@ -23,24 +23,79 @@
 vlet.ms;%0D%0A%0D%0A
+import java.util.Iterator;%0D%0Aimport java.util.Stack;%0D%0A%0D%0A
 import org.w
@@ -144,24 +144,29 @@
 ore.inf.
-Document
+BeanContainer
 ;%0D%0Aimpor
@@ -223,37 +223,32 @@
 up.core.inf.
-BeanContainer
+Document
 ;%0D%0Aimport or
@@ -369,61 +369,19 @@
 %0D%0A%0D%0A
-import java.util.Iterator;%0D%0Aimport java.util.Stack;%0D%0A
+@Deprecated
 %0D%0Apu

make ProcessorContextModelContainerStack as deprecated