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.model;
018
019import java.util.ArrayList;
020import java.util.Collections;
021import java.util.List;
022import java.util.StringTokenizer;
023
024/**
025 * The class in this SCXML object model that corresponds to the
026 * <transition> SCXML element. Transition rules are triggered
027 * by "events" and conditionalized via
028 * "guard-conditions".
029 *
030 */
031public class Transition extends SimpleTransition implements DocumentOrder {
032
033    /**
034     * The document order of this transition
035     */
036    private int order;
037
038    /**
039     * Property that specifies the trigger(s) for this transition.
040     */
041    private String event;
042
043    /**
044     * This transition event descriptors
045     */
046    private List<String> events = Collections.emptyList();
047
048    /**
049     * Indicator for a event-less transition
050     */
051    private boolean noEvents;
052
053    /**
054     * Indicator for a transition matching all events (*)
055     */
056    private boolean allEvents;
057
058    /**
059     * Optional guard condition.
060     */
061    private String cond;
062
063    /**
064     * Constructor.
065     */
066    public Transition() {
067        super();
068    }
069
070
071    /**
072     * @return the document order of this transition
073     * @see DocumentOrder
074     */
075    @Override
076    public final int getOrder() {
077        return order;
078    }
079
080    /**
081     * Sets the document order of this transition
082     * @param order the document order
083     * @see DocumentOrder
084     */
085    public final void setOrder(int order) {
086        this.order = order;
087    }
088
089    /**
090     * Get the guard condition (may be null).
091     *
092     * @return Returns the cond.
093     */
094    public String getCond() {
095        return cond;
096    }
097
098    /**
099     * Set the guard condition.
100     *
101     * @param cond The cond to set.
102     */
103    public void setCond(final String cond) {
104        this.cond = cond;
105    }
106
107    /**
108     * Get the event that will trigger this transition (pending
109     * evaluation of the guard condition in favor).
110     *
111     * @return Returns the event.
112     */
113    public String getEvent() {
114        return event;
115    }
116
117    /**
118     * Set the event that will trigger this transition (pending
119     * evaluation of the guard condition in favor).
120     *
121     * @param event The event to set.
122     */
123    public void setEvent(final String event) {
124        this.event = event == null ? null : event.trim();
125        if (this.event != null) {
126            // 'event' is a space separated list of event descriptors
127            events = new ArrayList<String>();
128            StringTokenizer st = new StringTokenizer(this.event);
129            while (st.hasMoreTokens()) {
130                String token = st.nextToken();
131                if (token.equals("*")) {
132                    events.clear();
133                    events.add(token);
134                    break;
135                }
136                else {
137                    if (token.endsWith("*")) {
138                        token = token.substring(0, token.length()-1);
139                    }
140                    if (token.endsWith(".")) {
141                        token = token.substring(0, token.length()-1);
142                    }
143                    if (token.length() > 0) {
144                        events.add(token);
145                    }
146                }
147            }
148        }
149        else {
150            events = Collections.emptyList();
151        }
152        noEvents = events.isEmpty();
153        allEvents = !noEvents && events.get(0).equals("*");
154    }
155
156    /**
157     * @return The list of this transition event descriptors
158     */
159    public final List<String> getEvents() {
160        return events;
161    }
162
163    /**
164     * @return True if this transition is event-less
165     */
166    public final boolean isNoEventsTransition() {
167        return noEvents;
168    }
169
170    /**
171     * @return True if this transition matches any events (*)
172     */
173    public final boolean isAllEventsTransition() {
174        return allEvents;
175    }
176}