Transition.java
001 /*
002  *  Transition.java
003  *
004  *  Copyright (c) 1995-2010, The University of Sheffield. See the file
005  *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
006  *
007  *  This file is part of GATE (see http://gate.ac.uk/), and is free
008  *  software, licenced under the GNU Library General Public License,
009  *  Version 2, June 1991 (in the distribution as file licence.html,
010  *  and also available at http://gate.ac.uk/gate/licence.html).
011  *
012  *  Valentin Tablan, 11/Apr/2000
013  *
014  *  $Id: Transition.java 12006 2009-12-01 17:24:28Z thomas_heitz $
015  */
016 
017 package gate.fsm;
018 
019 import java.io.Serializable;
020 import java.util.LinkedList;
021 
022 import gate.Annotation;
023 import gate.jape.BasicPatternElement;
024 import gate.jape.Constraint;
025 
026 /**
027   * This class implements a Finite State Machine transition.
028   * A transition is owned by a gate.fsm.State object and contains set of
029   * restrictions and a reference to the next state that will be accessed after
030   * consuming a set of input symbols according to the restrictions.
031   * A transition can also hold information about the label that should be bound
032   * to the symbols (annotations) consumed during the state transition.
033   */
034 // >>> DAM
035 /*
036 public class Transition implements Serializable {
037 */
038 // >>> DAM, TransArray optimzation, now implements the Comparable interface
039 public class Transition implements Serializable, Comparable {
040 // >>> DAM, end
041 
042   /** Debug flag */
043   private static final boolean DEBUG = false;
044 
045   /**
046     * Default constructor. Creates a new transition with a new unique index.
047     * This constructor should be called by all other constructors.
048     */
049   public Transition() {
050     myIndex = Transition.index++;
051   }
052 
053   /**
054     * Creates a new transition using the given set of constraints and target
055     * state.
056     @param constraints the set on constraints associated to this transition
057     @param state the target state of this transition
058     */
059   public Transition(BasicPatternElement constraints, State state) {
060     this(constraints, state, new LinkedList());
061   }
062 
063   /**
064     * Creates a new transition from a set of constraints, a target state and a
065     * list of labels to be bound with the recognized input symbols
066     * (aka annotations).
067     */
068   public Transition(BasicPatternElement constraints, State state,
069                     LinkedList bindings) {
070     this();
071     this.constraints = constraints;
072     target = state;
073     this.bindings = bindings;
074   }
075 
076   /**
077     * Creates a new transition to the given State with the same
078     * bindings as this one.
079     */
080   public Transition spawn(State s)
081   {
082       return new Transition(constraints, s, bindings);
083   }
084 
085   /**
086     * Gets the target state of this transition
087     @return an object of type gate.fsm.State
088     */
089   public State getTarget(){ return target; }
090 
091   /**
092     * Gets the constraints associated to this transition
093     */
094   public BasicPatternElement getConstraints(){ return constraints; }
095 
096   /**
097     * Returns a boolean value indicating whether this Transition
098     * has any constraints on it.
099     */
100   public boolean hasConstraints()
101   {
102       return constraints != null;
103   }
104 
105   /**
106     * Returns true if all the constraints on this transition are satisfied
107     * by the given Annotations, false otherwise.  The given Annotations
108     * should be the set of Annotations beginning at a single point in the
109     * document.
110     */
111   public boolean satisfiedBy(Annotation[] coIncidentAnnos) {
112       Constraint[] allConstraints = getConstraints().getConstraints();
113 
114       processAllConstraints:
115       for (int i = 0; i < allConstraints.length; i++)
116       {
117           Constraint c = allConstraints[i];
118           boolean negated = c.isNegated();
119 
120           for (int j = 0; j < coIncidentAnnos.length; j++)
121           {
122               if (c.matches(coIncidentAnnos[j]null))
123               {
124                   // One of these puppies being satisfied invalidates the whole transition
125                   if (negatedreturn false;
126 
127                   // This constraint is satisfied, go on to the next one
128                   continue processAllConstraints;
129               }
130           }
131 
132           // No matching annotations found for this constraint
133           if (!negatedreturn false;
134       }
135 
136       // All constraints satisfied
137       return true;
138   }
139 
140   /**
141     * Returns a boolean value indicating whether this Transition
142     * deals with multiple types of annotations.
143     */
144   public boolean isMultiType() {
145       return constraints != null && constraints.isMultiType();
146   }
147 
148   /**
149     * Returns a textual desciption of this transition.
150     @return a String
151     */
152   public String toString(){
153     return toString(true);
154   }
155 
156   public String toString(boolean includeTarget){
157     StringBuffer toReturn = new StringBuffer();
158     if (includeTargettoReturn.append("If: ");
159     toReturn.append(constraints);
160     if (includeTargettoReturn.append(" then ->: " + target.getIndex());
161     return toReturn.toString();
162   }
163 
164   /**
165     * Returns a shorter description that toSting().
166     * Actually, it returns the unique index in String form.
167     */
168   public String shortDesc(){
169     String res = "" + myIndex;
170     return res;
171   }
172 
173   /**
174     *  Returns the list of bindings associated to this transition
175     */
176   public LinkedList getBindings(){ return bindings; }
177 
178   /**
179     * The constraints on this transition.
180     */
181   private BasicPatternElement constraints;
182 
183   /**
184     * The state this transition leads to
185     */
186   private State target;
187 
188   /**
189     * A list with all the labels associated to the annotations recognized by
190     * this transition.
191     * We need to use the actual object and not the interface (java.util.List)
192     * because we need this object to be cloneable
193     */
194   private LinkedList bindings;
195 
196   /** The unique index of this transition. This value is not used by any of
197     * the algorithms. It is only provided as a convenient method of identifying
198     * the transitions in textual representations (toString() and GML related
199     * methods)
200     */
201   private int myIndex;
202 
203   /** Static member used for generating unique IDs for the objects of type
204     * Transition*/
205   private static int index = 0;
206 
207 // >>> DAM, TransArray optimzation, now implements the Comparable interface
208   public int compareTo(Object o)
209   throws ClassCastException
210   {
211     if (!(instanceof Transition)) throw new ClassCastException("gate.frm.Transition(compareTo)");
212     return myIndex - ((Transition)o).myIndex;
213   }
214 // >>> DAM, end
215 // Transition