001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.core.joran.conditional;
015
016import java.util.ArrayList;
017import java.util.List;
018import java.util.Stack;
019
020import org.xml.sax.Attributes;
021
022import ch.qos.logback.core.joran.action.Action;
023import ch.qos.logback.core.joran.event.InPlayListener;
024import ch.qos.logback.core.joran.event.SaxEvent;
025import ch.qos.logback.core.joran.spi.ActionException;
026import ch.qos.logback.core.joran.spi.InterpretationContext;
027
028abstract public class ThenOrElseActionBase extends Action {
029
030    Stack<ThenActionState> stateStack = new Stack<ThenActionState>();
031
032    @Override
033    public void begin(InterpretationContext ic, String name, Attributes attributes) throws ActionException {
034
035        if (!weAreActive(ic))
036            return;
037
038        ThenActionState state = new ThenActionState();
039        if (ic.isListenerListEmpty()) {
040            ic.addInPlayListener(state);
041            state.isRegistered = true;
042        }
043        stateStack.push(state);
044    }
045
046    boolean weAreActive(InterpretationContext ic) {
047        Object o = ic.peekObject();
048        if (!(o instanceof IfAction))
049            return false;
050        IfAction ifAction = (IfAction) o;
051        return ifAction.isActive();
052    }
053
054    @Override
055    public void end(InterpretationContext ic, String name) throws ActionException {
056        if (!weAreActive(ic))
057            return;
058
059        ThenActionState state = stateStack.pop();
060        if (state.isRegistered) {
061            ic.removeInPlayListener(state);
062            Object o = ic.peekObject();
063            if (o instanceof IfAction) {
064                IfAction ifAction = (IfAction) o;
065                removeFirstAndLastFromList(state.eventList);
066                registerEventList(ifAction, state.eventList);
067            } else {
068                throw new IllegalStateException("Missing IfAction on top of stack");
069            }
070        }
071    }
072
073    abstract void registerEventList(IfAction ifAction, List<SaxEvent> eventList);
074
075    void removeFirstAndLastFromList(List<SaxEvent> eventList) {
076        eventList.remove(0);
077        eventList.remove(eventList.size() - 1);
078    }
079
080}
081
082class ThenActionState implements InPlayListener {
083
084    List<SaxEvent> eventList = new ArrayList<SaxEvent>();
085    boolean isRegistered = false;
086
087    public void inPlay(SaxEvent event) {
088        eventList.add(event);
089    }
090}