001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.scxml2.issues;
018
019import java.util.ArrayList;
020import java.util.LinkedList;
021import java.util.List;
022import java.util.Queue;
023
024import org.apache.commons.scxml2.ActionExecutionContext;
025import org.apache.commons.scxml2.SCXMLExecutor;
026import org.apache.commons.scxml2.SCXMLExpressionException;
027import org.apache.commons.scxml2.SCXMLTestHelper;
028import org.apache.commons.scxml2.model.Action;
029import org.apache.commons.scxml2.model.CustomAction;
030import org.apache.commons.scxml2.model.ModelException;
031import org.apache.commons.scxml2.model.SCXML;
032import org.junit.After;
033import org.junit.Assert;
034import org.junit.Test;
035
036/**
037 * Test cases for issue 112.
038 * OPEN
039 */
040public class Issue112Test {
041
042    /**
043     * Tear down instance variables required by this test case.
044     */
045    @After
046    public void tearDown() {
047        Application.QUEUE.clear();
048    }
049
050    // Example using a custom <my:enqueue> action that generates more events during event processing.
051    // An external event queue is used by <my:enqueue> instead of SCXMLExecutor#triggerEvent(TriggerEvent)    
052    @Test
053    public void test01issue112() throws Exception {
054
055        CustomAction ca1 =
056            new CustomAction("http://my.custom-actions.domain/CUSTOM", "enqueue", Enqueue.class);
057        List<CustomAction> customActions = new ArrayList<CustomAction>();
058        customActions.add(ca1);
059
060        SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/issues/queue-01.xml", customActions);
061        SCXMLExecutor exec = SCXMLTestHelper.getExecutor(scxml);
062        exec.go();
063        Assert.assertEquals("init", exec.getStatus().getStates().
064                iterator().next().getId());
065
066        // Add an event, other external events could be added to the queue at any time (this test only adds one).
067        Application.QUEUE.add("next");
068
069        // Rest of the events in this test are added by custom action invocation during processing of the one above.
070        // Same concept applies to adding events in listeners, invokes and WRT AbstractStateMachine, state handlers.
071        while (!Application.QUEUE.isEmpty()) {
072            try {
073                SCXMLTestHelper.fireEvent(exec, Application.QUEUE.remove());
074            } catch (Exception e) {
075                e.printStackTrace();
076            }
077        }
078
079        Assert.assertTrue(exec.getStatus().isFinal());
080        Assert.assertEquals("end", exec.getStatus().getStates().
081                iterator().next().getId());
082
083    }
084
085    /**
086     * A custom action that generates external events.
087     */
088    public static class Enqueue extends Action {
089
090        private static final long serialVersionUID = 1L;
091        private String event;
092
093        public Enqueue() {
094            super();
095        }
096
097        public String getEvent() {
098            return event;
099        }
100
101        public void setEvent(String event) {
102            this.event = event;
103        }
104
105        @Override
106        public void execute(ActionExecutionContext exctx) throws ModelException, SCXMLExpressionException {
107
108            Application.QUEUE.add(event);
109
110        }
111
112    }
113
114    // Test external event queue
115    private static final class Application {
116        private static final Queue<String> QUEUE = new LinkedList<String>();
117    }
118
119}
120