/* * (C) Copyright 2013 Arnaud Bailly (arnaud.oqube@gmail.com), * Yves Roos (yroos@lifl.fr) and others. * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package rationals.ioautomata; import rationals.State; import rationals.Transition; /** A transition that distinguishes input, output and internal letters. This class takes care of relabelling of letters according to their type: <ul> <li>An input action is prefixed with '?'</li> <li>An output action is prefixed with '!'</li> <li>An internal action is prefixed with '^'</li> </ul> A helper method {@see canSynchronizeWith(IOTransition)}is provided that synchronizes input/output pairs. @author nono @version $Id: IOTransition.java 2 2006-08-24 14:41:48Z oqube $ */ public class IOTransition extends Transition<Object> { private IOAlphabetType type; public static class IOLetter { public final Object label; public final IOAlphabetType type; public IOLetter(Object lbl, IOAlphabetType t) { this.label = lbl; this.type = t; } public static IOLetter send(Object message) { return new IOLetter(message, IOAlphabetType.OUTPUT); } public static IOLetter receive(Object message) { return new IOLetter(message, IOAlphabetType.INPUT); } /* * (non-Javadoc) * * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object obj) { IOLetter lt = (IOLetter) obj; if (lt == null) return false; return (type == lt.type) && ((label == null) ? (lt.label == null) : label.equals(lt.label)); } /* * (non-Javadoc) * * @see java.lang.Object#hashCode() */ public int hashCode() { return label.hashCode() ^ (type.ordinal() << 8); } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ public String toString() { StringBuffer sb = new StringBuffer(); switch (type) { case INPUT: sb.append('?'); break; case OUTPUT: sb.append('!'); break; case INTERNAL: sb.append('^'); break; } sb.append(label); return sb.toString(); } } /** * @param start * @param label * @param end */ public IOTransition(State start, Object label, State end, IOAlphabetType type) { super(start, new IOLetter(label, type), end); this.type = type; } /** * This constructor should be used only for the purpose of completing an IOautomaton, hence its restricted access. * * @param q start state * @param object the label. Must be an IOLetter or a ClassCastException will be thrown * @param q2 end state */ public IOTransition(State q, Object object, State q2) { this(q, ((IOLetter) object).label, q2, ((IOLetter) object).type); } /** @return Returns the type. */ public IOAlphabetType getType() { return type; } }