001: package csdl.stackmvc.model;
002:
003: import edu.hawaii.stack.Stack;
004: import edu.hawaii.stack.EmptyStackException;
005:
006: import java.util.ArrayList;
007:
008: /**
009: * Implements a singleton Stack instance.
010: * The command classes manipulate this singleton in response to user input.
011: * The StackModel manipulates string objects only.
012: * To prevent multi-threaded access from corrupting the stack, all operations on the
013: * singleton StackModel instance are synchronized.
014: *
015: * @author Jitender Miglani
016: * @author Philip Johnson
017: */
018: public class StackModel {
019:
020: /** The singleton StackModel instance. */
021: private static StackModel theInstance;
022:
023: /** The internal stack implementation. */
024: private Stack stack;
025:
026: /** Private constructor used to create a single instance of stack */
027: private StackModel() {
028: this .stack = new Stack();
029: }
030:
031: /**
032: * Get the single instance of StackModel object.
033: *
034: * @return A StackModel.
035: */
036: public static StackModel getInstance() {
037: if (StackModel.theInstance == null) {
038: StackModel.theInstance = new StackModel();
039: }
040: return StackModel.theInstance;
041: }
042:
043: /**
044: * Pushes a string object onto the stack.
045: *
046: * @param number The number to be pushed.
047: */
048: public synchronized void push(String number) {
049: this .stack.push(number);
050: }
051:
052: /**
053: * Pops a string number out of the stack.
054: *
055: * @return The number popped out of the stack.
056: * @throws EmptyStackException If an empty stack was popped.
057: */
058: public synchronized String pop() throws EmptyStackException {
059: return (String) this .stack.pop();
060: }
061:
062: /**
063: * Gets top element of the stack.
064: *
065: * @return The number on the top of the stack.
066: * @throws EmptyStackException If an empty stack was popped.
067: */
068: public synchronized String top() throws EmptyStackException {
069: return (String) this .stack.top();
070: }
071:
072: /**
073: * Duplicates the elements in the stack.
074: *
075: * @throws EmptyStackException If an empty stack was popped.
076: */
077: public synchronized void doubles() throws EmptyStackException {
078: ArrayList stackTrace = new ArrayList();
079:
080: try {
081: // get all elements in original stack
082: while (true) {
083: stackTrace.add(this .stack.pop());
084: }
085: } catch (EmptyStackException e) {
086: if (stackTrace.size() == 0) {
087: throw new EmptyStackException(e);
088: }
089: }
090:
091: // double contents of original stack
092: for (int i = 0; i < 2; i++) {
093: for (int j = stackTrace.size() - 1; j >= 0; j--) {
094: this .stack.push((String) stackTrace.get(j));
095: }
096: }
097: }
098:
099: /** Clears the stack. */
100: public synchronized void clearStack() {
101: this .stack = new Stack();
102: }
103:
104: /**
105: * Return a copy of the stack as an array.
106: * Used for presentation purposes.
107: *
108: * @return An array containing the stack data.
109: */
110: public Object[] toArray() {
111: return this.stack.toArray();
112: }
113: }
|