EventManager.java 13.3 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.xfa;

import com.adobe.xfa.*;
import com.adobe.xfa.form.FormModel;
import com.adobe.xfa.ut.*;
import com.adobe.xfa.ut.trace.Trace;

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

public class EventManager {
    private final List<EventID> mEventIDs = new ArrayList<EventID>();
    private final AppModel mAppModel;
    private final Trace scriptTrace = Element.oScriptTrace;
    private String msCurrentEvent;

    public static void resetEventTable(EventTable eventTable) {
        if (eventTable != null) {
            eventTable.clear();
        }
    }

    protected EventManager(AppModel appModel) {
        this.mAppModel = appModel;
    }

    public boolean cancelAction(String sAction) {
        EventPseudoModel poEventPseudoModel = this.getEventPseudoModel();
        if (poEventPseudoModel != null) {
            return poEventPseudoModel.cancelAction(sAction);
        }
        return false;
    }

    public boolean cancelEvent(String sEvent) {
        EventPseudoModel poEventPseudoModel = this.getEventPseudoModel();
        if (poEventPseudoModel != null) {
            return poEventPseudoModel.cancelEvent(sEvent);
        }
        return false;
    }

    public boolean eventOccurred(int nEventID, Obj object) {
        if (object == null) {
            return false;
        }
        boolean bScriptsHaveExecuted = false;
        assert (nEventID < this.mEventIDs.size());
        EventID event = this.mEventIDs.get(nEventID);
        assert (event != null);
        if (!event.mbDispatcherOrCalloutRegistered) {
            if (this.isPostActionEvent(event.msEventName)) {
                if (this.cancelEvent(event.msEventName)) {
                    return false;
                }
                this.msCurrentEvent = event.msEventName;
                this.resetCancelAction();
                this.msCurrentEvent = null;
            }
            return false;
        }
        if (this.cancelEvent(event.msEventName)) {
            return false;
        }
        if (this.scriptTrace.isEnabled(3)) {
            String sClass = object.getClassAtom() + ":";
            MsgFormatPos msg = new MsgFormatPos(ResId.TraceEventOccurred);
            msg.format(sClass + event.msEventName);
            this.scriptTrace.trace(3, msg);
        }
        for (int i = 0; i < event.mUnInitializedEvents.size(); ++i) {
            Dispatcher dispatcher = event.mUnInitializedEvents.get(i);
            Obj otherEventContext = this.resolveEventContext(dispatcher);
            if (otherEventContext == null) continue;
            EventTable otherEventTable = otherEventContext.getEventTable(true);
            assert (otherEventTable != null);
            otherEventTable.add(dispatcher);
            event.mUnInitializedEvents.remove(i);
            --i;
        }
        ArrayList dispatcherList = null;
        EventTable eventTable = object.getEventTable(false);
        if (eventTable != null) {
            Dispatcher dispatcher;
            int i2;
            boolean bRemoveNonRecurring = false;
            for (i2 = 0; i2 < eventTable.size(); ++i2) {
                dispatcher = (Dispatcher)eventTable.get(i2);
                if (dispatcher.getEventID() != nEventID) continue;
                if (dispatcherList == null) {
                    dispatcherList = new ArrayList<Dispatcher>();
                }
                dispatcherList.add(dispatcher);
                bRemoveNonRecurring |= !dispatcher.getRecurring();
            }
            if (bRemoveNonRecurring) {
                for (i2 = eventTable.size() - 1; i2 >= 0; --i2) {
                    dispatcher = (Dispatcher)eventTable.get(i2);
                    if (dispatcher.getEventID() != nEventID || dispatcher.getRecurring()) continue;
                    eventTable.remove(i2);
                }
            }
        }
        if (event.mbListenToDescendentsRegistered) {
            Node contextNode = (Node)object;
            assert (contextNode != null);
            for (Element parent = contextNode.getXFAParent(); parent != null; parent = parent.getXFAParent()) {
                EventTable parentEventTable = parent.getEventTable(false);
                if (parentEventTable == null) continue;
                int nDispatchersAtThisLevel = 0;
                for (int i3 = 0; i3 < parentEventTable.size(); ++i3) {
                    Dispatcher dispatcher = (Dispatcher)parentEventTable.get(i3);
                    if (dispatcher.getEventID() != nEventID || !dispatcher.getListenToDescendents()) continue;
                    if (dispatcherList == null) {
                        dispatcherList = new ArrayList();
                    }
                    dispatcherList.add(nDispatchersAtThisLevel, dispatcher);
                    ++nDispatchersAtThisLevel;
                    if (dispatcher.getRecurring()) continue;
                    parentEventTable.remove(i3);
                    --i3;
                }
            }
        }
        if (this.isPreActionEvent(event.msEventName) || this.isPostActionEvent(event.msEventName)) {
            this.msCurrentEvent = event.msEventName;
        }
        EventPseudoModel poEventPseudoModel = this.getEventPseudoModel();
        boolean bLegacyV32Scripting = this.mAppModel == null || this.mAppModel.getLegacySetting(AppModel.XFA_LEGACY_V32_SCRIPTING);
        boolean bSetTargetToNullPostDispatch = false;
        if (poEventPseudoModel != null && !bLegacyV32Scripting) {
            Obj oTarget = object;
            if (poEventPseudoModel.getTarget() == null) {
                if (object instanceof FormModel) {
                    bSetTargetToNullPostDispatch = true;
                }
                poEventPseudoModel.setTarget(oTarget);
            }
            if (poEventPseudoModel.getName() == 0) {
                int eExecuteReason = ScriptHandler.stringToExecuteReason(event.msEventName);
                poEventPseudoModel.setName(eExecuteReason);
            }
            bScriptsHaveExecuted = this.dispatch(event, dispatcherList);
            if (bSetTargetToNullPostDispatch) {
                poEventPseudoModel.setTarget(null);
            }
        } else {
            bScriptsHaveExecuted = this.dispatch(event, dispatcherList);
        }
        return bScriptsHaveExecuted;
    }

    private boolean dispatch(EventID event, List<Dispatcher> dispatcherList) {
        boolean bEventDispatched = false;
        if (dispatcherList != null) {
            int nSize = dispatcherList.size();
            try {
                bEventDispatched = nSize > 0;
                for (int i = 0; i < nSize; ++i) {
                    Dispatcher d = dispatcherList.get(i);
                    d.setOccurring(true);
                    d.dispatch();
                    d.setOccurring(false);
                }
            }
            catch (ExFull ex) {
                for (int i = 0; i < nSize; ++i) {
                    dispatcherList.get(i).setOccurring(false);
                }
                if (this.isPostActionEvent(event.msEventName)) {
                    this.resetCancelAction();
                }
                if (this.isPreActionEvent(event.msEventName) || this.isPostActionEvent(event.msEventName)) {
                    this.msCurrentEvent = null;
                }
                throw ex;
            }
        }
        if (this.isPostActionEvent(event.msEventName)) {
            this.resetCancelAction();
        }
        if (this.isPreActionEvent(event.msEventName) || this.isPostActionEvent(event.msEventName)) {
            this.msCurrentEvent = null;
        }
        return bEventDispatched;
    }

    String getCurrentEvent() {
        return this.msCurrentEvent;
    }

    public int getEventID(String sEventName) {
        for (int i = 0; i < this.mEventIDs.size(); ++i) {
            if (!this.mEventIDs.get((int)i).msEventName.equals(sEventName)) continue;
            return i;
        }
        EventID eventID = new EventID(sEventName);
        this.mEventIDs.add(eventID);
        return this.mEventIDs.size() - 1;
    }

    public EventID getEventIDByIndex(int nIndex) {
        return this.mEventIDs.get(nIndex);
    }

    private EventPseudoModel getEventPseudoModel() {
        EventPseudoModel eventPseudoModel = null;
        assert (this.mAppModel != null);
        if (this.mAppModel != null) {
            eventPseudoModel = (EventPseudoModel)this.mAppModel.lookupPseudoModel("$event");
        }
        return eventPseudoModel;
    }

    int getNumEventIDs() {
        return this.mEventIDs.size();
    }

    private boolean isPreActionEvent(String sEvent) {
        EventPseudoModel oEventPseudoModel = this.getEventPseudoModel();
        if (oEventPseudoModel != null) {
            return oEventPseudoModel.isPreActionEvent(sEvent);
        }
        return false;
    }

    private boolean isPostActionEvent(String sEvent) {
        EventPseudoModel oEventPseudoModel = this.getEventPseudoModel();
        if (oEventPseudoModel != null) {
            return oEventPseudoModel.isPostActionEvent(sEvent);
        }
        return false;
    }

    public void registerEvents(Dispatcher dispatcher) {
        Obj object;
        int nIndex = dispatcher.getEventID();
        assert (nIndex < this.mEventIDs.size());
        EventID event = this.mEventIDs.get(nIndex);
        event.mbDispatcherOrCalloutRegistered = true;
        if (dispatcher.getListenToDescendents()) {
            event.mbListenToDescendentsRegistered = true;
        }
        if ((object = this.resolveEventContext(dispatcher)) != null) {
            EventTable eventTable = object.getEventTable(true);
            assert (eventTable != null);
            eventTable.add(dispatcher);
        } else {
            this.mEventIDs.get((int)nIndex).mUnInitializedEvents.add(dispatcher);
        }
    }

    public void reset() {
        for (int i = 0; i < this.mEventIDs.size(); ++i) {
            EventID event = this.mEventIDs.get(i);
            for (int j = 0; j < event.mUnInitializedEvents.size(); ++j) {
                Dispatcher dispatcher = event.mUnInitializedEvents.get(j);
                dispatcher.setEventManager(null);
            }
            event.mUnInitializedEvents.clear();
        }
        if (this.mAppModel != null) {
            this.mAppModel.resetPseudoModelEvents();
        }
    }

    private void resetCancelAction() {
        EventPseudoModel poEventPseudoModel = this.getEventPseudoModel();
        if (poEventPseudoModel != null) {
            poEventPseudoModel.setCancelAction(false, null);
        }
    }

    private Obj resolveEventContext(Dispatcher dispatcher) {
        Obj eventContext = null;
        if (dispatcher != null) {
            eventContext = dispatcher.getEventContextObj();
            if (eventContext != null) {
                return eventContext;
            }
            String sEventContext = dispatcher.getEventContext();
            if (StringUtils.isEmpty(sEventContext)) {
                return eventContext;
            }
            Element actionContext = dispatcher.getActionContextNode();
            if (sEventContext.equals("$")) {
                dispatcher.setEventContextObj(dispatcher.getActionContextNode());
            } else {
                SOMParser parser = new SOMParser(null);
                ArrayList<SOMParser.SomResultInfo> lhsResult = new ArrayList<SOMParser.SomResultInfo>();
                parser.resolve(actionContext, sEventContext, lhsResult);
                Obj eventContextObject = null;
                if (lhsResult.size() > 0) {
                    eventContextObject = lhsResult.get((int)0).object;
                }
                dispatcher.setEventContextObj(eventContextObject);
            }
            eventContext = dispatcher.getEventContextObj();
        }
        return eventContext;
    }

    public static final class EventTable
    extends ArrayList<Dispatcher> {
        private static final long serialVersionUID = -127450503214773632L;

        @Override
        public boolean add(Dispatcher dispatcher) {
            for (int i = 0; i < this.size(); ++i) {
                if (dispatcher.getEventID() <= ((Dispatcher)this.get(i)).getEventID()) continue;
                ArrayList.super.add(i, dispatcher);
                return true;
            }
            return ArrayList.super.add(dispatcher);
        }

        @Override
        public void add(int index, Dispatcher element) {
            throw new ExNotImplemented();
        }

        @Override
        public boolean addAll(Collection<? extends Dispatcher> eventTable) {
            boolean bChanged = false;
            for (Dispatcher dispatcher : eventTable) {
                this.add(dispatcher);
                bChanged = true;
            }
            return bChanged;
        }

        @Override
        public boolean addAll(int index, Collection<? extends Dispatcher> eventTable) {
            throw new ExNotImplemented();
        }

        @Override
        public Dispatcher set(int index, Dispatcher element) {
            throw new ExNotImplemented();
        }
    }

    public static final class EventID {
        public final String msEventName;
        public final List<Dispatcher> mUnInitializedEvents = new ArrayList<Dispatcher>();
        public boolean mbListenToDescendentsRegistered;
        public boolean mbDispatcherOrCalloutRegistered;

        public EventID(String sEventName) {
            this.msEventName = sEventName;
        }
    }

}