001    /*
002     * RecipieModel.java
003     *
004     * Created on December 10, 2002, 5:17 PM
005     */
006    
007    package spirograph;
008    
009    import java.io.Serializable;
010    
011    import java.util.Vector;
012    
013    import javax.swing.event.ChangeEvent;
014    
015    import spirograph.RecipieListener;
016    
017    /** 
018     * Models the student code input, or "Recipie". A recipie consists of two
019     * strings. The first string may contain any number of variable declarations and
020     * defintions. The second string esentially contains a method body which is
021     * interpreted to control the movement of a dot on the x or y axis (or both).
022     * Classes which implement the {@link RecipieListener} interface may register
023     * be notified of changes in either the field text or the statement (method
024     * body) text. An always empty static instance of this class is maintained as
025     * the "null Recipie". Any recipie variable can point to this static instance
026     * and be assured, both that it exists and that it will never have any code
027     * or fields text.
028     *
029     * <p>Copyright © 2003 Franklin W. Olin College of Engineering.</p>
030     *
031     * @author Patrick G. Heck, gus.heck@olin.edu
032     * @version $Id: Recipie.java,v 1.9 2004/02/09 20:55:03 gus Exp $
033     * @see RecipieView
034     */
035    public class Recipie implements Serializable, CodeSource {
036    
037        private static int instances = 0;
038        private int idNum;
039        
040        /**
041         * A recipie that represents a no data condition.
042         * It should always have id 0, and all fields should be empty or zero at
043         * all times. Attempts to modify this object should result in an
044         * <code>UnsupportedOperationException</code>
045         *
046         */
047        public static final Recipie nullRecipie = new Recipie();
048        
049        private ChangeEvent ce = new ChangeEvent(this);
050        private Vector listeners = new Vector();
051        private String fields = "";
052        private String code = "";
053         
054        private boolean compiled = true;
055        
056        
057        /** Creates a new instance of RecipieModel
058         */
059        public Recipie() {
060            idNum = instances;
061            instances++;
062        }
063        
064        /**
065         * Ask this recipie if it has been compiled since it's last modification.
066         *
067         * @return True if no modifications have been made since the last
068         *           <code>setCompiled(true)</code> call
069         */    
070        public boolean isCompiled() {
071            return compiled;
072        }
073        
074        /** 
075         * Get a unique identifier for this object.
076         *
077         * @return An identfying integer that is unique to any given instance.
078         */    
079        public int getIdNum() {
080            return idNum;
081        }
082    
083        /**
084         * Get the student code that represents a method body.
085         *
086         * @return The student method body code
087         */    
088        public String getCode() {
089            return code;
090        }
091        
092        /**
093         * Get the student code that represents variable declarations and definitions.
094         *
095         * @return The student variable declarations and defintions
096         */    
097        public String getFields() {
098            return fields;
099        }
100        
101        /**
102         * Mark this code as having been compiled since it's last edit, or edited
103         * since it's last compile.
104         *
105         * @param isComp <code>true</code> if the code has been compiled, <code>false</code> if it has been modified
106         */    
107        public void setCompiled(boolean isComp) {
108            compiled = isComp;
109            updateListeners();
110        }
111        
112        /** Store new student code.
113         * @param statements The student code to store.
114         * @throws UnsupportedOperationException if invoked on {@link Recipie#nullRecipie}
115         */    
116        public void setCode(String statements) throws UnsupportedOperationException {
117            if (this == nullRecipie) {
118                throw new UnsupportedOperationException("Cannot modify "+
119                                                        "the \"null recipie!\"");
120            }
121            code = statements;
122            compiled = false;
123            updateListeners();
124        }
125        
126        /** Store new student fields.
127         * @param fields The variable declarations and definitions to store.
128         * @throws UnsupportedOperationException if invoked on {@link Recipie#nullRecipie}
129         */    
130        public void setFields(String fields) throws UnsupportedOperationException {
131            if (this == nullRecipie) {
132                throw new UnsupportedOperationException("Cannot modify "+
133                                                        "the \"null recipie!\"");
134            }
135            fields = fields;
136            compiled = false;
137            updateListeners();
138        }
139    
140        /** Register an object for notification of changes to this recipie.
141         * @param rl The object to register
142         */    
143        public void addRecipieListener(RecipieListener rl) {
144            listeners.add(rl);        
145        }
146        
147        /** Unregister an object that was listening to this recipie.
148         * @param rl The object that wishes to be unregistered.
149         */    
150        public void removeRecipieListener(RecipieListener rl) {
151            listeners.remove(rl);
152        }
153        
154        /**
155         * Manually ensure that all listners are updated.
156         *
157         */    
158        public void fireRecipieChanged() {
159            updateListeners();
160        }
161        
162        private void updateListeners() {
163            for (int i=0; i<listeners.size(); i++){
164                ((RecipieListener) listeners.get(i)).recipieUpdated(ce);
165            }
166        }
167    }
168    
169    /*
170     * $Log: Recipie.java,v $
171     * Revision 1.9  2004/02/09 20:55:03  gus
172     * javadoc fixes
173     *
174     * Revision 1.8  2003/01/17 23:57:17  gus
175     * see tag added
176     *
177     * Revision 1.7  2003/01/15 17:36:10  gus
178     * adding log keywords to files that don't have them
179     *
180     */