001 package sale;
002
003 import users.User;
004
005 /**
006 * A {@link Gate gate} at which a {@link FormSheet} and/or a {@link MenuSheet} can be displayed. The
007 * {@link Transition transition} that leaves the gate will depend on the users interaction with the Form-
008 * and/or MenuSheet.
009 *
010 * @author Steffen Zschaler
011 * @version 2.0 17/08/1999
012 * @since v2.0
013 */
014 public class UIGate extends Object implements Gate {
015
016 /**
017 * The FormSheet to be displayed.
018 *
019 * @serial
020 */
021 protected FormSheet m_fsFormSheet;
022
023 /**
024 * The MenuSheet to be displayed.
025 *
026 * @serial
027 */
028 protected MenuSheet m_msMenuSheet;
029
030 /**
031 * The transition that will leave this gate.
032 */
033 private transient Transition m_tTransition;
034
035 /**
036 * The monitor synchronizing access to the elements as well as a communications channel.
037 */
038 private transient Object m_oLock;
039
040 /**
041 * Return the monitor synchronizing access to the elements as well as a communications channel.
042 *
043 * @override Never
044 */
045 private final Object getLock() {
046 if (m_oLock == null) {
047 m_oLock = new Object();
048 }
049
050 return m_oLock;
051 }
052
053 /**
054 * Bit field indicating the last change.
055 */
056 private transient int m_nChanged = NOTHING;
057 /**
058 * Nothing changed.
059 */
060 private static final int NOTHING = 0;
061 /**
062 * The FormSheet changed.
063 */
064 private static final int FORMSHEET = 1;
065 /**
066 * The MenuSheet changed.
067 */
068 private static final int MENUSHEET = 2;
069 /**
070 * The transition was set.
071 */
072 private static final int TRANSITION = 8;
073
074 /**
075 * Create a new UIGate.
076 *
077 * @param fs the FormSheet to be displayed. Can be <code> null</code>.
078 * @param ms the MenuSheet to be displayed. Can be <code> null</code>.
079 */
080 public UIGate(FormSheet fs, MenuSheet ms) {
081 super();
082
083 m_fsFormSheet = fs;
084 m_msMenuSheet = ms;
085 }
086
087 /**
088 * Returns the next Transition to jump to.
089 * @override Never
090 */
091 public Transition getNextTransition(SaleProcess pOwner, User usr) throws InterruptedException {
092
093 synchronized (getLock()) {
094 m_tTransition = null;
095 m_nChanged = FORMSHEET | MENUSHEET;
096 // e.g. 0011 & 1000 == 0000 => something changed, but no transition found yet
097 while ((m_nChanged & TRANSITION) == 0) {
098 // e.g. 0011 & 0010 == 0010 => MenuSheet changed
099 if ((m_nChanged & MENUSHEET) != 0) {
100 pOwner.getContext().setMenuSheet(pOwner, m_msMenuSheet);
101 }
102 // e.g. 0011 & 0001 == 0001 => FormSheet changed
103 if ((m_nChanged & FORMSHEET) != 0) {
104 if (m_fsFormSheet != null) {
105 m_fsFormSheet.setWaitResponse(false);
106 }
107 pOwner.getContext().setFormSheet(pOwner, m_fsFormSheet);
108 }
109
110 m_nChanged = NOTHING;
111
112 getLock().wait();
113 }
114 }
115 return m_tTransition;
116 }
117
118 /**
119 * Set the FormSheet that is being displayed at this Gate.
120 *
121 * @override Never
122 *
123 * @param fs the new FormSheet
124 */
125 public void setFormSheet(FormSheet fs) {
126 synchronized (getLock()) {
127 m_fsFormSheet = fs;
128 m_nChanged |= FORMSHEET;
129
130 getLock().notifyAll();
131 }
132 }
133
134 /**
135 * Set the MenuSheet that is being displayed at this gate.
136 *
137 * @override Never
138 *
139 * @param ms the MenuSheet.
140 */
141 public void setMenuSheet(MenuSheet ms) {
142 synchronized (getLock()) {
143 m_msMenuSheet = ms;
144 m_nChanged |= MENUSHEET;
145
146 getLock().notifyAll();
147 }
148 }
149
150 /**
151 * Set the transition that will leave this gate. This will leave the gate at once and enter the Transition.
152 * The transition may return to the gate.
153 *
154 * @override Never
155 *
156 * @param tNext the transition. Must not be <code>null</code>.
157 */
158 public void setNextTransition(Transition tNext) {
159 if (tNext == null) {
160 throw new NullPointerException();
161 }
162
163 synchronized (getLock()) {
164 m_tTransition = tNext;
165 m_nChanged |= TRANSITION;
166
167 getLock().notifyAll();
168 }
169 }
170 }