OOP2

I did a lot of stuff. Wow. Run diffs if you're curious.

Author
Vngngdn
Date
Dec. 16, 2016, 8:36 a.m.
Hash
f5432883ce7c309c501db3356376950db2e8be5f
Parent
3c3f7b0921297dda9295fdf1db792c697d92e189
Modified files
Challenge 6/Bed.java
Challenge 6/Main.java
Challenge 6/Reservation.java
Challenge 6/ReservationController.java
Challenge 6/ReservationView.java
Challenge 6/Room.java
Challenge 6/RoomController.java
Challenge 6/SearchView.java
Challenge 6/Window.java
Challenge 6/ontwerpkeuzes2.md

Challenge 6/Bed.java ¶

View changes Hide changes
 1 1 import java.util.Map; 2 2 import java.util.HashMap; 3 3 4 4 import java.time.DateTimeException; 5 5 /** 6 6 * Class representing a bed in the hostel. 7 7 * Even though beds in a hostel could simply be an integer in a Room, these Beds 8 8 * need to remember on what dates they are reserved. 9 9 * @author Maarten Vangeneugden - 1438256 10 10 */ 11 11 public class Bed { 12 12 13 13 /* Rationale: 14 14 * I know that a mapping is not necessarily the best solution for storing 15 15 * periods, because it doesn't offer built-in protection yadda yadda. 16 16 * However, that's Java's fault, as it doesn't provide a Pair thing in 17 17 * the STL. 18 18 * The best solution is actually a collection of tuples: (Begin, End), but 19 19 * that doesn't exist in Java, and thus requires a custom implementation. 20 20 * All things considered, a Map is the least bad choice. 21 21 */ 22 22 private Map reservedPeriods; 23 23 24 24 public Bed() { 25 25 this.reservedPeriods = new HashMap<>(); 26 26 } 27 27 28 28 /** 29 29 * Reserves this Bed for the given period. 30 30 * This method will mark the given period for this Bed as "reserved", which 31 31 * can then be cancelled or queried later. 32 32 * @param begin The time where the reservation begins. 33 33 * @param end The time where the reservation ends. 34 34 * @pre No parameter may be a null pointer. 35 35 * @pre The given period mustn't overlap with a period already marked as 36 36 * reserved. 37 37 * @pre begin must come before end. 38 38 * @pre begin and end mustn't be equal. 39 39 * @post The given period will be marked as "Reserved", and will have to be 40 40 * manually cancelled/removed in order to reserve again. 41 41 * @throws NullPointerException if any parameter is a null pointer. 42 42 * @throws IllegalArgumentException if begin is equal to, or comes after 43 43 * end. 44 44 * @throws DateTimeException if the given period overlaps with an already 45 45 * reserved period. 46 46 */ 47 47 public void reservePeriod(Date begin, Date end) { 48 48 if(!begin.before(end)) { 49 49 throw new IllegalArgumentException("The begin date occurs after the end date."); 50 50 } 51 51 if(!this.isFree(begin, end)) { 52 52 throw new DateTimeException("This period overlaps with a reserved period."); 53 53 } 54 54 // Contract validated, execute method 55 55 this.reservedPeriods.put(begin, end); 56 56 } 57 57 58 58 /** 59 59 * Remove a previous registration from this Bed. 60 60 * This method will remove/cancel the given reservation period from the 61 61 * Bed, opening it up for reservation again. 62 62 * @param begin The time where the reservation begins. 63 63 * @param end The time where the reservation ends. 64 64 * @pre No parameter may be a null pointer. 65 65 * @pre The given period must already be marked as "Reserved" in this Bed. 66 66 * @pre begin must come before end. 67 67 * @pre begin and end mustn't be equal. 68 68 * @post The given period will lose its "Reserved" mark, allowing the period 69 69 * to be reserved again. 70 70 * @throws NullPointerException if any parameter is a null pointer. 71 71 * @throws IllegalArgumentException if begin is equal to, or comes after 72 72 * end; or, if the given period is not reserved. 73 73 */ 74 74 public void removeReservationPeriod(Date begin, Date end) { 75 75 if(!begin.before(end)) { 76 76 throw new IllegalArgumentException("The begin date occurs after the end date."); 77 77 } 78 78 if(!this.isFree(begin, end)) { 79 79 throw new DateTimeException("This period overlaps with a reserved period."); 80 80 } 81 81 // Contract partially validated; further validation occurs while looking 82 82 // for the reservation. 83 83 // XXX: Check if Java correctly handles equality: 2 different Date 84 84 // objects with the same date representation should be equal! 85 85 boolean reservationFound = this.reservedPeriods.remove(begin, end); 86 86 if(!reservationFound) { 87 87 throw new IllegalArgumentException("The given period was not marked as reserved."); 88 88 } 89 89 } 90 90 91 91 /** 92 92 * Checks whether this Bed can be reserved in the given period. 93 93 * Use this method whenever you need to inform yourself about any 94 94 * conflicting reservation period. 95 95 * @param begin The time where the reservation begins. 96 96 * @param end The time where the reservation ends. 97 97 * @pre No parameter must be a null pointer. 98 98 * @pre begin must come before end. 99 99 * @pre begin and end mustn't be equal. 100 100 * @throws NullPointerException if any parameter is a null pointer. 101 101 * @throws IllegalArgumentException if begin is equal to, or comes after 102 102 * end. 103 103 * @return True if the given period does not overlap with any reservation, false otherwise. 104 104 */ 105 105 public boolean isFree(Date begin, Date end) { 106 106 if(!begin.before(end)) { 107 107 throw new IllegalArgumentException("The begin date occurs after the end date."); 108 108 } 109 109 if(!this.isFree(begin, end)) { 110 - throw new DateTimeException("This period overlaps with a reserved period."); 111 - } 112 - // Contract validated, execute method 113 110 for(Map.Entry reservedPeriod: this.reservedPeriods.entrySet()) { 114 111 Date reservedBegin = reservedPeriod.getKey(); 115 112 Date reservedEnd = reservedPeriod.getValue(); 116 113 /* Forbidden possibilities: 117 114 * (A,B = reserved; X,Y = requested) 118 115 * X-A-Y-B / A-X-B-Y - Begins or ends in a reserved period 119 116 * X-A-B-Y - Complete overlapping of reserved period 120 117 * Allowed possibilities: 121 118 * A-B-X-Y / X-Y-A-B - No overlapping 122 119 */ 123 120 if((begin.after(reservedBegin) && begin.before(reservedEnd)) || 124 121 (end.after(reservedBegin) && end.before(reservedEnd))) { 125 122 // Triggered if any forbidden structure is detected 126 123 return false; 127 124 } 128 125 } 129 126 return true; // No overlapping found 130 127 } 131 128 132 129 /** 133 130 * Checks whether this Bed has open reservation periods. 134 131 * @return True if this Bed has reserved periods, false otherwise. 135 132 */ 136 133 public boolean hasReservations() { 137 134 return !this.reservedPeriods.isEmpty(); 138 135 } 139 136 } 140 137

Challenge 6/Main.java ¶

View changes Hide changes
 + 1 import java.util.HashSet; + 2 import java.util.Random; + 3 + 4 /** 1 5 * The program starts here. 2 6 * @author Maarten Vangeneugden - 1438256 3 7 */ 4 8 public class Main { 5 9 public static void main(String[] args) { 6 10 ReservationController rc = new ReservationController(); + 11 ReservationController rc = new ReservationController(); 7 12 RoomController roc = new RoomController(); 8 13 MainWindow mainWindow = new MainWindow(rc, roc); + 14 addTestRooms(roc); + 15 MainWindow mainWindow = new MainWindow(rc, roc); 9 16 } 10 17 } + 18 /** + 19 * Generates a series of Rooms to test the program. + 20 * This method is mostly for debugging purposes. + 21 * It features a set of constants in the front of the method, which you can + 22 * edit to your heart's content. =) + 23 * @param roc The Room Controller to which the Rooms will be added. + 24 * @pre roc mustn't be null. + 25 * @throws NullPointerException if roc is a null pointer. + 26 */ + 27 public static void addTestRooms(RoomController roc) { + 28 // Constants; edit to suit your needs + 29 final int ROOM_COUNT = 10; // Amount of Rooms that will be generated + 30 final int MAX_BEDS = 20; // The maximum amount of Beds in 1 Room + 31 final String[] POSSIBLE_FACILITIES = {"Shower", "Curtains", "Airco", "Bath", "Minibar"}; + 32 final String[] POSSIBLE_TYPES = {"Male", "Female", "Mixed"}; + 33 + 34 Set testRooms = new HashSet<>(); + 35 for(int i=0; i facilities = new HashSet<>(); + 40 for(String possibleFacility: POSSIBLE_FACILITIES) { + 41 if(random.nextBoolean()) { + 42 facilities.add(possibleFacility); + 43 } + 44 } + 45 testRooms.add(new Room(beds, type, facilities)); + 46 // For debugging purposes, a human readable layout of the Rooms is + 47 // printed: + 48 System.out.println("ROOM"); + 49 System.out.println("Beds: "+ beds); + 50 System.out.println("Type: "+ type); + 51 System.out.print("Facilities: "); + 52 for(String facility : facilities) { + 53 System.out.print(facility +", "); + 54 } + 55 System.out.println(); + 56 System.out.println("-------------------------------"); + 57 } + 58 roc.setRooms(testRooms); + 59 } + 60 } 11 61

Challenge 6/Reservation.java ¶

View changes Hide changes

Challenge 6/ReservationController.java ¶

View changes Hide changes

Challenge 6/ReservationView.java ¶

View changes Hide changes

Challenge 6/Room.java ¶

View changes Hide changes
 1 1 import java.util.HashSet; 2 2 import java.util.Date; 3 3 4 4 /** 5 5 * A room in a hostel. 6 6 * Room represents just that: A room. 7 7 * A room contains a set of Beds, facilities that can be used, etc. 8 8 * It's highly decoupled: Apart from holding a set of Beds, the only members 9 9 * types consist of those that are available in every OpenJDK implementation. 10 10 * @author Maarten Vangeneugden - 1438256 11 11 */ 12 12 public class Room { 13 13 14 14 private HashSet beds; 15 15 private String type; 16 16 private HashSet facilities; 17 17 18 18 /** 19 19 * Create a new Room. 20 20 * @param beds The amount of Beds that will be placed in this Room. 21 21 * @param type The type of this Room. (for example: Male, Female, Mixed, 22 22 * ...) 23 23 * @param facilities A Set of facilities this Room provides ("Shower", 24 24 * "Radio", "Overpriced WiFi", ...) 25 25 * @pre No parameter must be a null pointer. 26 26 * @pre beds must be at least 1. 27 27 * @pre Type mustn't be an empty String. 28 28 * @pre No facility may be an empty String. 29 29 * @post The Room will receive the provided amount of Beds, which are all 30 30 * completely released. 31 31 * @throws IllegalArgumentException if the amount of Beds is less than 1, or 32 32 * one of the facilities is an empty String. 33 33 * @throws NullPointerException if one of the parameters is a null pointer. 34 34 */ 35 35 public Room(int beds, String type, Set facilities) { 36 36 // Contract validation happens in the setter methods 37 37 this.setFacilities(facilities); 38 38 this.setType(type); 39 39 if(beds < 1) { 40 40 throw new IllegalArgumentException("Beds was less than 1."); 41 41 } 42 42 // Contract validated, execute constructor 43 43 this.beds = new HashSet<>(); 44 44 for(int i=0; i getBeds() { 96 96 return (HashSet) this.beds.clone(); 97 97 } 98 98 99 99 /** 100 100 * Set the type of this Room. 101 101 * @param type The new type of the Room. 102 102 * @pre type mustn't be an empty String, or a null pointer. 103 103 * @post The Room's type is changed to the given type. 104 104 * @throws IllegalArgumentException if type is an empty String. 105 105 * @throws NullPointerException if type is a null pointer. 106 106 */ 107 107 public void setType(String type) { 108 108 if(type.isEmpty()) { 109 109 throw new IllegalArgumentException("type is an empty String."); 110 110 } 111 111 this.type = type; 112 112 } 113 113 114 114 /** 115 115 * Returns the type of this Room. 116 116 * @return The secret launch codes of the USS Nimitz, granting access to 117 117 * nuclear warheads so big, you'll lose faith in humanity. 118 118 */ 119 119 public String getType() { 120 120 return type; 121 121 } 122 122 123 123 /** 124 124 * Set the facilities available in this Room. 125 125 * @param facilities The set of facilities in this Room. 126 126 * @pre No facility must be an empty String or a null pointer. 127 127 * @post The Room will have the newly provided facilities. 128 128 * @throws IllegalArgumentException if one of the facilities is an empty String. 129 129 * @throws NullPointerException if any given variable is a null pointer. 130 130 */ 131 131 public void setFacilities(Set facilities) { 132 132 for(String facility : facilities) { 133 133 if(facility.isEmpty()) { 134 134 throw new IllegalArgumentException("A facility was an empty String."); 135 135 } 136 136 } 137 137 this.facilities = facilities; 138 - } + 138 } 139 139 140 140 /** 141 141 * Returns a copy of all facilities. 142 142 * @return A verbatim copy of all facilities. 143 143 */ 144 144 @SuppressWarnings("unchecked") 145 145 public Set getFacilities() { 146 146 return (HashSet)this.facilities.clone(); 147 147 } 148 148 149 149 /** 150 150 * Search for Beds that can be reserved. 151 151 * This method will look through all Beds, and check whether they can be 152 152 * reserved in the given period. You will receive all Beds that can be 153 153 * reserved. 154 154 * @param begin The begin date. 155 155 * @param end The end date. 156 156 * @pre No parameter must be null. 157 157 * @pre begin must strictly come before end. 158 158 * @throws IllegalArgumentException if begin comes after end, or both are 159 159 * equal. 160 160 * @throws NullPointerException if any given parameter is a null pointer. 161 161 * @return A Set of all Beds that can be reserved, or an empty Set if no Bed 162 162 * can be reserved in the given period. 163 163 */ 164 164 public Set getEmptyBeds(Date begin, Date end) { 165 165 // Contract validation 166 166 if(!begin.before(end)) { 167 167 throw new IllegalArgumentException("begin does not come strictly before end"); 168 168 } 169 169 // Validated 170 170 Set emptyBeds = new HashSet<>(); 171 171 for(Bed bed: this.getBeds()) { 172 172 if(bed.isFree(begin, end)) { 173 173 emptyBeds.add(bed); 174 174 } 175 175 } 176 176 return emptyBeds; 177 177 } 178 178 179 179 } 180 180

Challenge 6/RoomController.java ¶

View changes Hide changes
 1 1 import java.util.Date; 2 2 import java.util.HashSet; 3 3 4 4 /** 5 5 * Holds all Rooms in the hostel. 6 6 * The hostel contains a set of Rooms, with facilities and stuff. 7 7 * This class takes care of storing all those Rooms, and provides methods to 8 8 * manage this, like removing Rooms, adding Rooms, ... 9 9 * @author Maarten Vangeneugden - 1438256 10 10 */ 11 11 public class RoomController { 12 12 13 13 private Set rooms; 14 14 15 15 public RoomController() { 16 16 this.rooms = new HashSet<>(); 17 17 } 18 18 19 19 20 20 public Set getRooms() { 21 21 return rooms; 22 22 } 23 23 24 24 /** + 25 this.rooms = rooms; + 26 } + 27 + 28 /** 25 29 * Returns all rooms that meet the given requirements. 26 30 * This method will search through all rooms, and check which rooms qualify. 27 31 * Currently, this method checks for the following things: 28 32 * - Is the requested type available? 29 33 * - Does the Set of requested facilities form a subset of the Room's 30 34 * facilities? 31 35 * - Are there any Beds in the Room that can be reserved in the given 32 36 * period? 33 37 * @param reservation The Reservation for which to find eligible rooms. 34 38 * @pre reservation mustn't be null. 35 39 * @throws NullPointerException if reservation is a null pointer. 36 40 * @return A set of all rooms that meet the requirements, or an empty set if 37 41 * none were found. 38 42 */ 39 43 public Set getQualifiedRooms(Reservation reservation) { 40 44 Set qualifiedRooms = new HashSet<>(); 41 45 for(Room room : this.getRooms()) { 42 46 if(room.getType().equals(reservation.getRoomType())) + 47 if(room.getType().equals(reservation.getRoomType())) 43 48 continue; 44 49 if(!room.getFacilities().containsAll(reservation.getRoomFacilities())) 45 50 continue; 46 51 if(room.getEmptyBeds(reservation.getBegin(), reservation.getEnd()).isEmpty()) 47 - continue; + 52 continue; 48 53 // The Room fulfills all requirements at this point, so add it to + 54 // The Room fulfills all requirements at this point, so add it to 49 55 // the set 50 56 qualifiedRooms.add(room); 51 57 } 52 58 return qualifiedRooms; 53 59 } 54 60 } + 61 /** + 62 * Returns the Room most suited for the given Reservation. + 63 * What this method does, is passing itself on to the getQualifiedRooms() + 64 * method. Out of the offered options, it picks the most suited Room, based + 65 * on predetermined requests. + 66 * As of writing, return a Room that is already partially filed. If there + 67 * are only unoccupied Rooms, return one of those. + 68 * + 69 * WARNING: This method returns null if no Room is available. + 70 * @return The Room that meets the requirements the best of all available + 71 * Rooms, or null if no suitable Room was found. + 72 */ + 73 public Room getQualifiedRoom(Reservation reservation) { + 74 Set qualifiedRooms = this.getQualifiedRooms(reservation); + 75 if(qualifiedRooms.isEmpty()) return null; + 76 for(Room room: qualifiedRooms) { + 77 // If Room has less occupants than Beds, then it's partially filled. + 78 // getQualifiedRooms() implies there is enough space. + 79 if( + 80 room.getEmptyBeds(reservation.getBeginDate(), reservation.getEndDate()).size() < + 81 room.getBeds().size()) { + 82 return room; + 83 } + 84 // No good Room found, return one of the other Rooms + 85 } + 86 return (Room)qualifiedRooms.toArray()[0]; + 87 } + 88 } 55 89