001package myhw2.data;
002
003import java.util.Map;
004import java.util.HashMap;
005import java.util.Comparator;
006import java.util.Collections;
007import java.util.Iterator;
008
009/**
010 * Implementation of Inventory interface.
011 * @see Data
012 */
013final class InventorySet implements Inventory {
014        // Chose to use Map of Record, rather than RecordObj, because of
015        // Java's broken generic types.  The story is too sad to retell, but
016        // involves the fact that Iterable<? extends Record> is not a valid
017        // type, and that Iterator<RecordObj> is not a subtype of
018        // Iterator<Record>.
019        //
020        // Seems like the best approach for Java generics is to use the
021        // external representation internally and downcast when necessary.
022        private final Map<Video,Record> data;
023
024        InventorySet() {
025                data = new HashMap<Video,Record>();
026        }
027
028        public int size() {
029                // TODO
030                return 0;
031        }
032
033        public Record get(Video v) {
034                // TODO
035                return null;
036        }
037
038        public Iterator<Record> iterator() {
039                return Collections.unmodifiableCollection(data.values()).iterator();
040        }
041
042        public Iterator<Record> iterator(Comparator<Record> comparator) {
043                // Hint: Look at Collections.sort
044                // TODO
045                return null;
046        }
047
048        /**
049         * Add or remove copies of a video from the inventory.
050         * If a video record is not already present (and change is
051         * positive), a record is created.
052         * If a record is already present, <code>numOwned</code> is
053         * modified using <code>change</code>.
054         * If <code>change</code> brings the number of copies to be zero,
055         * the record is removed from the inventory.
056         * @param video the video to be added.
057         * @param change the number of copies to add (or remove if negative).
058         * @throws IllegalArgumentException if video null, change is zero, if attempting to remove more copies than are owned, or if attempting to remove copies that are checked out.
059         */
060        void addNumOwned(Video video, int change) {
061                // TODO
062        }
063
064        /**
065         * Check out a video.
066         * @param video the video to be checked out.
067         * @throws IllegalArgumentException if video has no record or numOut
068         * equals numOwned.
069         */
070        void checkOut(Video video) {
071                // TODO
072        }
073
074        /**
075         * Check in a video.
076         * @param video the video to be checked in.
077         * @throws IllegalArgumentException if video has no record or numOut
078         * non-positive.
079         */
080        void checkIn(Video video) {
081                // TODO
082        }
083
084        /**
085         * Remove all records from the inventory.
086         */
087        void clear() {
088                // TODO
089        }
090
091        public String toString() {
092                StringBuilder buffer = new StringBuilder();
093                buffer.append("Database:\n");
094                for (Record r : data.values()) {
095                        buffer.append("  ");
096                        buffer.append(r);
097                        buffer.append("\n");
098                }
099                return buffer.toString();
100        }
101
102
103        /**
104         * Implementation of Record interface.
105         *
106         * <p>This is a utility class for Inventory.  Fields are mutable and
107         * package-private.</p>
108         *
109         * <p><b>Class Invariant:</b> No two instances may reference the same Video.</p>
110         *
111         * @see Record
112         */
113        private static final class RecordObj implements Record {
114                Video video;    // the video
115                int numOwned;   // copies owned
116                int numOut;     // copies currently rented
117                int numRentals; // total times video has been rented
118
119                RecordObj(Video video, int numOwned, int numOut, int numRentals) {
120                        this.video = video;
121                        this.numOwned = numOwned;
122                        this.numOut = numOut;
123                        this.numRentals = numRentals;
124                }
125                public Video video() {
126                        return video;
127                }
128                public int numOwned() {
129                        return numOwned;
130                }
131                public int numOut() {
132                        return numOut;
133                }
134                public int numRentals() {
135                        return numRentals;
136                }
137                public String toString() {
138                        StringBuilder buffer = new StringBuilder();
139                        buffer.append(video);
140                        buffer.append(" [");
141                        buffer.append(numOwned);
142                        buffer.append(",");
143                        buffer.append(numOut);
144                        buffer.append(",");
145                        buffer.append(numRentals);
146                        buffer.append("]");
147                        return buffer.toString();
148                }
149        }
150}