Further refactor of Reservation system in Challenge 6
- Author
- Vngngdn
- Date
- Dec. 12, 2016, 12:30 p.m.
- Hash
- 212ab469ae6defcc415d9558e2bf77a3bb06039f
- Parent
- 607ccd02260ec7cfe256edf8c459db78dd6d2feb
- Modified files
- Challenge 6/Reservation.java
- Challenge 6/ReservationController.java
Challenge 6/Reservation.java ¶
1 addition and 0 deletions.
View changes Hide changes
1 |
1 |
import java.util.HashSet; |
2 |
2 |
import java.util.Date; |
3 |
3 |
|
4 |
4 |
/** |
5 |
5 |
* Represents a reservation in a hostel. |
6 |
6 |
* Reservation is a simple class that allows one to store reservation |
7 |
7 |
* information, request it when necessary, and so on. |
8 |
8 |
* Certain methods are provided for interaction, which use contracts to assert |
9 |
9 |
* proper functioning. |
10 |
10 |
* |
11 |
11 |
* Note: There is a form of redundancy in this class. |
12 |
12 |
* Reservation holds a Set of Beds, and an integer, indicating the amount of |
13 |
13 |
* people that are in this Reservation. |
14 |
14 |
* Normally, the amount of people in the Reservation is determined by the amount |
15 |
15 |
* of reserved Beds, because the amount of Beds implied the amount of people to |
16 |
16 |
* facilitate. |
17 |
17 |
* Because of the design of this program, I've weighed the advantages and |
18 |
18 |
* disadvantages of holding this implication, of using a seperate member |
19 |
19 |
* explicitely indicating the amount of people. |
20 |
20 |
* |
21 |
21 |
* I've chosen the latter option. It scales better in terms of weird |
22 |
22 |
* afterthoughts ("I also want to make people sleep on the floor"), but being |
23 |
23 |
* explicit is also a tad easier to manage. It also allows the other classes to |
24 |
24 |
* be far more decoupled from Reservation (otherwise, they'd have to check for |
25 |
25 |
* errors every time themselves, hindering cohesiveness). |
26 |
26 |
* |
27 |
27 |
* To overcome the possible difference, I've made it so that, every time, the |
28 |
28 |
* relation between the values is changed (the people in the Reservation |
29 |
29 |
* changes, for example), the class automatically checks if the values are |
30 |
30 |
* corresponding. If they're not, a warning is printed to system.out.err, |
31 |
31 |
* informing about the fact that there's a discrepancy. |
32 |
32 |
* |
33 |
33 |
* I think that's the best way to overcome this problem. |
34 |
34 |
* @author Maarten Vangeneugden - 1438256 |
35 |
35 |
*/ |
36 |
36 |
public class Reservation { |
37 |
37 |
|
38 |
38 |
// Members |
39 |
39 |
private String groupName; |
40 |
40 |
private Date begin; |
41 |
41 |
private Date end; |
42 |
42 |
private Set<Bed> reservedBeds; |
43 |
43 |
private int people; // The amount of people in this Reservation |
44 |
44 |
private int reservationID; |
45 |
45 |
private String roomType; // Room type requested by group |
46 |
46 |
private Set<String> roomFacilities; // Requested room facilities |
47 |
47 |
private Set<Date> breakfastDays; // Set of days the group wants breakfast |
48 |
48 |
// Controllers |
49 |
49 |
private RoomController roomController; |
50 |
50 |
private ReservationController reservationController; |
51 |
51 |
|
52 |
52 |
/** |
53 |
53 |
* Create a new Reservation. |
54 |
54 |
* Be aware about the limitations of a Reservation: it's not the |
55 |
55 |
* Reservation's duty to check whether the provided Beds are properly |
56 |
56 |
* reserved; take care of this accordingly. |
57 |
57 |
* |
58 |
58 |
* Some information is implicit. For example: The size of the set of |
59 |
59 |
* reserved Beds implies the amount of people in the group; no breakfast |
60 |
60 |
* days implies no breakfast, ... |
61 |
61 |
* @param groupName The name of the group. |
62 |
62 |
* @param people The amount of people that are reserving. |
63 |
63 |
* @param begin The date that the Reservation begins. |
64 |
64 |
* @param end The date that the Reservation ends. |
65 |
65 |
* @param reservedBeds The set of Beds reserved and assigned to this |
66 |
66 |
* Reservation. |
67 |
67 |
* @param roomType The requested room type. |
68 |
68 |
* @param roomFacilities The set of all requested room facilities. |
69 |
69 |
* @param breakfastDays A set of all days that the group wants breakfast. |
70 |
70 |
* @param reservationID An ID for this reservation, to differentiate from |
71 |
71 |
* other Reservations. |
72 |
72 |
* @pre No parameter must be a null pointer. |
73 |
73 |
* @pre people must be a natural number, different from 0. |
74 |
74 |
* @pre begin must come before end. |
75 |
75 |
* @pre All dates in breakfastDays must fall between begin and end. |
76 |
76 |
* @pre No string parameter may be empty. |
77 |
77 |
* @post The amount of people in the Reservation is determined by the amount |
78 |
78 |
* of reserved Beds. |
79 |
79 |
* @throws NullPointerException if any parameter is a null pointer. |
80 |
80 |
* @throws IllegalArgumentException if any of the other preconditions is not |
81 |
81 |
* met. |
82 |
82 |
*/ |
83 |
83 |
public Reservation(String groupName, int people, Date begin, Date end, Set<Bed> reservedBeds, String roomType, Set<String> roomFacilities) { |
84 |
84 |
// Contract validation: |
85 |
85 |
if(people < 1) { |
86 |
86 |
throw IllegalArgumentException("The amount of people should be at least 1."); |
87 |
87 |
} |
88 |
88 |
if(!begin.before(end)) { |
89 |
89 |
throw IllegalArgumentException("The begin date occurs after the end date."); |
90 |
90 |
} |
91 |
91 |
if(groupName.isEmpty() || roomType.isEmpty()) { |
92 |
92 |
throw IllegalArgumentException("groupName and/or roomType were empty strings."); |
93 |
93 |
} |
94 |
94 |
for(String roomFacility: roomFacilities) { |
95 |
95 |
if(roomFacility.isEmpty()) { |
96 |
96 |
throw IllegalArgumentException("One of the room facilities was an empty string."); |
97 |
97 |
} |
98 |
98 |
} |
99 |
99 |
for(Date breakfastDay : breakfastDays) { |
100 |
100 |
if(breakfastDay.before(begin) || breakfastDay.after(end)) { |
101 |
101 |
throw IllegalArgumentException("One of the breakfast days occurs before/after the reservation period."); |
102 |
102 |
} |
103 |
103 |
} |
104 |
104 |
// Contract validated, execute constructor |
105 |
105 |
this.groupName = groupName; |
106 |
106 |
this.people = people; |
107 |
107 |
this.beginDate = begin; |
108 |
108 |
this.endDate = end; |
109 |
109 |
this.reservedBeds = reservedBeds; |
110 |
110 |
this.reservationID = reservationID; |
111 |
111 |
this.roomType = roomType; |
112 |
112 |
this.roomFacilities = roomFacilities; |
113 |
113 |
this.breakfastDays = breakfastDays |
114 |
114 |
} |
115 |
115 |
|
116 |
116 |
/** |
117 |
117 |
* Checks whether the amount of people corresponds with the reserved Beds. |
118 |
118 |
* Call this method whenever a change in the amount of Beds, or the amount |
119 |
119 |
* of people is made, or, whenever you need to assure consistency. |
120 |
120 |
* |
121 |
121 |
* It also prints a warning to system.out.err to inform about a discrepancy, |
122 |
122 |
* should one be found. |
123 |
123 |
* |
124 |
124 |
* @return True if the counts are consistent, false otherwise. |
125 |
125 |
*/ |
126 |
126 |
private boolean checkPeopleCountConsistency() { |
127 |
127 |
int people = this.getPeople(); |
128 |
128 |
int beds = this.getReservedBeds().size(); |
129 |
129 |
if(people != beds) { |
130 |
130 |
system.out.err("There's a discrepancy in the amount of people in Reservation"+ |
131 |
131 |
this.reservationID +":"); |
132 |
132 |
system.out.err("People: "+String.valueOf(people)); |
133 |
133 |
system.out.err("Reserved Beds: "+String.valueOf(beds)); |
134 |
134 |
return false; |
135 |
135 |
} |
136 |
136 |
return true; |
137 |
137 |
} |
138 |
138 |
|
139 |
139 |
/** |
140 |
140 |
* Set the group name for this Reservation. |
141 |
141 |
* @param groupName The new group name. |
142 |
142 |
* @pre groupName mustn't be empty, or a null pointer. |
143 |
143 |
* @post The group name is changed to the given name. |
144 |
144 |
* @throws NullPointerException if groupName is a null pointer. |
145 |
145 |
* @throws IllegalArgumentException if groupName is an empty String. |
146 |
146 |
*/ |
147 |
147 |
public void setGroupName(String groupName) { |
148 |
148 |
if(groupName.isEmpty()) |
149 |
149 |
throw IllegalArgumentException("groupName is an empty String."); |
150 |
150 |
this.groupName = groupName; |
151 |
151 |
} |
152 |
152 |
|
153 |
153 |
/** |
154 |
154 |
* Retrieve the current group name. |
155 |
155 |
* @return The group name of this Reservation. |
156 |
156 |
*/ |
157 |
157 |
public String getGroupName() { |
158 |
158 |
return this.groupName; |
159 |
159 |
} |
160 |
160 |
|
161 |
161 |
/** |
162 |
162 |
* Get amount of people in this Reservation. |
163 |
163 |
* @post A warning will be printed to system.out.err if the amount of people |
164 |
164 |
* is inconsistent with the amount of reserved Beds. |
165 |
165 |
* @see Reservation.checkPeopleCountConsistency |
166 |
166 |
* @return The amount of people in this Reservation. |
167 |
167 |
*/ |
168 |
168 |
public int getPeople() { |
169 |
169 |
return this.people; |
+ |
170 |
return this.people; |
170 |
171 |
} |
171 |
172 |
|
172 |
173 |
/** |
173 |
174 |
* Set the amount of people for this Reservation. |
174 |
175 |
* Note that this method will not notify you if the new amount of people is |
175 |
176 |
* equal to the previous amount. |
176 |
177 |
* |
177 |
178 |
* This method will print |
178 |
179 |
* @param people The new amount of people in this Reservation. |
179 |
180 |
* @pre people must be at least 1. |
180 |
181 |
* @post A warning will be printed to system.out.err if the amount of people |
181 |
182 |
* is inconsistent with the amount of reserved Beds. |
182 |
183 |
* @post The amount of people is changed to the given value. |
183 |
184 |
* @throws IllegalArgumentException if people is less than 1. |
184 |
185 |
*/ |
185 |
186 |
public void setPeople(int people) { |
186 |
187 |
if(people < 1) { |
187 |
188 |
throw IllegalArgumentException("people must be at least 1."); |
188 |
189 |
} |
189 |
190 |
this.people = people; |
190 |
191 |
this.checkPeopleCountConsistency(); |
191 |
192 |
} |
192 |
193 |
/** |
193 |
194 |
* Set the begin date for this Reservation. |
194 |
195 |
* @param begin The new begin date. |
195 |
196 |
* @pre begin mustn't be a null pointer. |
196 |
197 |
* @pre begin must come strictly before the end date. |
197 |
198 |
* @post The begin date is updated accordingly. |
198 |
199 |
* @throws NullPointerException if begin is a null pointer. |
199 |
200 |
* @throws IllegalArgumentException if begin comes after the end date. |
200 |
201 |
*/ |
201 |
202 |
public void setBegin(Date begin) { |
202 |
203 |
if(!begin.before(this.getEnd())) |
203 |
204 |
throw IllegalArgumentException("begin comes after the end date.") |
204 |
205 |
this.begin = begin; |
205 |
206 |
} |
206 |
207 |
|
207 |
208 |
|
208 |
209 |
|
209 |
210 |
/** |
210 |
211 |
* Set the end date for this Reservation. |
211 |
212 |
* @param end The new end date. |
212 |
213 |
* @pre end mustn't be a null pointer. |
213 |
214 |
* @pre end must come strictly after the begin date. |
214 |
215 |
* @post The end date is updated accordingly. |
215 |
216 |
* @throws NullPointerException if end is a null pointer. |
216 |
217 |
* @throws IllegalArgumentException if end comes after the end date. |
217 |
218 |
*/ |
218 |
219 |
public Date getDate() { |
219 |
220 |
return date; |
220 |
221 |
} |
221 |
222 |
|
222 |
223 |
public void setReservedBeds(Set<Bed> reservedBeds) { |
223 |
224 |
this.reservedBeds = reservedBeds; |
224 |
225 |
this.checkPeopleCountConsistency(); |
225 |
226 |
} |
226 |
227 |
|
227 |
228 |
public Set<Bed> getReservedBeds() { |
228 |
229 |
return reservedBeds; |
229 |
230 |
this.checkPeopleCountConsistency(); |
230 |
231 |
} |
231 |
232 |
|
232 |
233 |
// TODO: Write documentation for all of these, even though it's all mostly |
233 |
234 |
// copy/pasting. pfffff |
234 |
235 |
public void setReservationID(int reservationID) { |
235 |
236 |
this.reservationID = reservationID; |
236 |
237 |
} |
237 |
238 |
|
238 |
239 |
public int getReservationID() { |
239 |
240 |
return reservationID; |
240 |
241 |
} |
241 |
242 |
|
242 |
243 |
public void setRoomType(String roomType) { |
243 |
244 |
this.roomType = roomType; |
244 |
245 |
} |
245 |
246 |
|
246 |
247 |
public String getRoomType() { |
247 |
248 |
return roomType; |
248 |
249 |
} |
249 |
250 |
|
250 |
251 |
public void setRoomFacilities(Set<String> roomFacilities) { |
251 |
252 |
this.roomFacilities = roomFacilities; |
252 |
253 |
} |
253 |
254 |
|
254 |
255 |
public Set<String> getRoomFacilities() { |
255 |
256 |
return roomFacilities; |
256 |
257 |
} |
257 |
258 |
|
258 |
259 |
/** |
259 |
260 |
* Calculates the price of the Reservation, based on its current state. |
260 |
261 |
* Price table: |
261 |
262 |
* - 20/person/day |
262 |
263 |
* - 5 less in low season, 5 more in high season |
263 |
264 |
* - 4/breakfast ordered |
264 |
265 |
* - If room is fully booked by the group --> 10% discount |
265 |
266 |
* @return The price in euros. |
266 |
267 |
*/ |
267 |
268 |
public int getPrice() { |
268 |
269 |
int totalPrice = 0; |
269 |
270 |
// Jan - Apr: Mid |
270 |
271 |
// May - Aug: High |
271 |
272 |
// Sep - Dec: Low |
272 |
273 |
|
273 |
274 |
// Calculate bed prices |
274 |
275 |
int month = this.getDate().getMonth(); |
275 |
276 |
int bedPrice = 20; |
276 |
277 |
if(month >=8) { // From September: |
277 |
278 |
bedPrice -= 5; |
278 |
279 |
} else if(month >=4) { // From May: |
279 |
280 |
bedPrice += 5; |
280 |
281 |
} |
281 |
282 |
totalPrice += (this.getReservedBeds().size() * this.getNights() * bedPrice); |
282 |
283 |
// Calculate price for breakfasts |
283 |
284 |
int breakfasts = this.getBreakfastDays().length; |
284 |
285 |
totalPrice += breakfasts * this.getReservedBeds().size(); |
285 |
286 |
// Check if eligible for discount |
286 |
287 |
for(Room room: roomController.getRooms()) { |
287 |
288 |
Set<Bed> roomBeds = room.getBeds(); |
288 |
289 |
if(roomBeds.containsAll(this.reservedBeds)) { |
289 |
290 |
double discount = (double)totalPrice * 0.1; |
290 |
291 |
totalPrice -= (int)discount; |
291 |
292 |
} |
292 |
293 |
} |
293 |
294 |
return totalPrice; |
294 |
295 |
} |
295 |
296 |
|
296 |
297 |
|
297 |
298 |
|
298 |
299 |
|
299 |
300 |
|
300 |
301 |
|
301 |
302 |
|
302 |
303 |
public void setBreakfastDays(int[] breakfastDays) { |
303 |
304 |
this.breakfastDays = breakfastDays; |
304 |
305 |
} |
305 |
306 |
public int[] getBreakfastDays() { |
306 |
307 |
return this.breakfastDays; |
307 |
308 |
} |
308 |
309 |
|
309 |
310 |
} |
310 |
311 |
Challenge 6/ReservationController.java ¶
22 additions and 3 deletions.
View changes Hide changes
1 |
1 |
import java.util.HashSet; |
2 |
2 |
import java.util.Date; |
3 |
3 |
|
4 |
4 |
/** |
5 |
5 |
* Controller class for the Reservations of this program. |
6 |
6 |
* Since this program handles a youth hostel, it's imperative that it holds a |
7 |
7 |
* number of Reservations. |
8 |
8 |
* |
9 |
9 |
* ReservationController takes the responsibility of handling the addition, |
10 |
10 |
* cancelling, editing, ... of Reservations, and the related tasks inherent to |
11 |
11 |
* these responsibilities, such as reserving beds, generating IDs, ... |
12 |
12 |
* @author Maarten Vangeneugden - 1438256 |
13 |
13 |
*/ |
14 |
14 |
public class ReservationController { |
15 |
15 |
|
16 |
16 |
/* Rationale: |
17 |
17 |
* Normally I'd put this as an interface (Set), but an interface does not |
18 |
18 |
* inherit from Object, and thus, does not provide clone(). This is |
19 |
19 |
* necessary, because otherwise, there's no point in having private |
20 |
20 |
* members. |
21 |
21 |
*/ |
22 |
22 |
private HashSet<Reservation> reservations; // Holds all Reservations |
23 |
23 |
|
+ |
24 |
|
24 |
25 |
/** |
25 |
26 |
* Creates the ReservationController. |
26 |
27 |
*/ |
+ |
28 |
* WARNING: This program avoids the use of null pointers, but because of |
+ |
29 |
* circular dependency issues, this class requires that the developer (which |
+ |
30 |
* means YOU) set the RoomController reference member manually. |
+ |
31 |
* Be advised that the setRoomController() method will not accept a null |
+ |
32 |
* pointer. |
+ |
33 |
* |
+ |
34 |
* Once again: Set the RoomController reference manually ASAP. Failure to do |
+ |
35 |
* so will cause this program to blow up. You've been warned. |
+ |
36 |
* @see ReservationController.setRoomController |
+ |
37 |
*/ |
27 |
38 |
public ReservationController() { |
28 |
39 |
this.reservations = new HashSet<>(); |
29 |
40 |
} |
30 |
41 |
|
31 |
42 |
/** |
32 |
43 |
* Returns a copy of all Reservations. |
33 |
44 |
* Emphasis on "copy"; There is no setReservations() for a reason, using |
34 |
45 |
* this to edit the pointer variable would omit the use of 'private'. |
35 |
46 |
* @return A verbatim copy of all Reservations. |
36 |
47 |
*/ |
37 |
48 |
@SuppressWarnings("unchecked") |
38 |
49 |
public Set<Reservation> getReservations() { |
39 |
50 |
return (HashSet<Reservation>)this.reservations.clone(); |
40 |
51 |
} |
41 |
52 |
|
42 |
53 |
/** |
43 |
54 |
* Generates a unique ID for a new Reservation. |
44 |
55 |
* This method is to be called when a new Reservation is to be stored. |
45 |
56 |
* As every Reservation carries an ID, this method searches for a unique |
46 |
57 |
* one, and returns it. |
47 |
58 |
* @return An integer, different from all other stored Reservation IDs. |
48 |
59 |
*/ |
49 |
60 |
public int generateReservationID() { |
50 |
61 |
/* Small optimization idea: |
51 |
62 |
* Instead of starting from 0, and incrementing until it's unique, it |
52 |
63 |
* will take the amount of stored Reservations, and test that as an ID. |
53 |
64 |
* This may still overlap (by removing an older Reservation), but may be |
54 |
65 |
* much faster. Consider implemting and testing for effectiveness if |
55 |
66 |
* generating an ID takes too long. |
56 |
67 |
*/ |
57 |
68 |
int ID = 0; |
58 |
69 |
boolean isUnique = false; |
59 |
70 |
do { |
60 |
71 |
ID++; |
61 |
72 |
isUnique = true; |
62 |
73 |
for(Reservation reservation: this.reservations) { |
63 |
74 |
if(ID == reservation.getReservationID()) { |
64 |
75 |
isUnique = false; |
65 |
76 |
} |
66 |
77 |
} |
67 |
78 |
} while(!isUnique); |
68 |
79 |
// Test: |
69 |
80 |
for(Reservation reservation: this.reservations) { |
70 |
81 |
assert reservation.getReservationID() != ID : "Duplicate ID generated!"; |
71 |
82 |
} |
72 |
83 |
return ID; |
73 |
84 |
} |
74 |
85 |
|
75 |
86 |
/** |
76 |
87 |
* Check if Reservation can be made. |
77 |
88 |
* Call this method whenever you're planning on adding a new Reservation. It |
78 |
89 |
* will check the provided requirements (Room facilities, for example), and |
79 |
90 |
* return whether this Reservation can continue. |
80 |
91 |
* @param reservation The Reservation to check for possible addition. |
81 |
92 |
* @pre reservation mustn't be null. |
82 |
93 |
* @throws NullPointerException if reservation is null. |
83 |
94 |
* @return True if reservation can be added, False otherwise. |
84 |
95 |
*/ |
85 |
96 |
public boolean checkReservation(Reservation reservation) { |
86 |
97 |
if(reservation == null) { |
87 |
98 |
throw NullPointerException("reservation was a null pointer."); |
88 |
99 |
} |
89 |
100 |
if(this.getRoomController().getQualifiedRooms(reservation).size() == 0) { |
90 |
101 |
return null; |
91 |
102 |
} |
92 |
103 |
|
93 |
104 |
/** |
94 |
105 |
* Adds and confirms the reservation. |
95 |
106 |
* By calling this method, the given reservation will be stored in the |
96 |
107 |
* system, and the given room will be filled. |
97 |
108 |
* You are to collect the necessary data, and assure yourself that all |
98 |
109 |
* preconditions have been met. |
99 |
110 |
* |
100 |
111 |
* The best way to accomplish this, is to only send 'sterile' Reservations |
101 |
112 |
* as the first parameter. That is: Reservations without reserved Beds, |
102 |
113 |
* without prior addition to the active Reservations, etc. |
103 |
114 |
* NOTE: You must check for yourself if the Reservation can take place in |
104 |
115 |
* this Room! If there are not enough Beds available, an exception will be |
105 |
116 |
* thrown. |
106 |
117 |
* @param reservation The Reservation to add. |
107 |
118 |
* @param room The Room in which the people will reside. |
108 |
119 |
* @pre room must have enough empty beds. |
109 |
120 |
* @pre room must accomodate the Reservation's requirements. |
110 |
121 |
* @pre No parameter must be null. |
111 |
122 |
* @pre reservation mustn't already be stored in the active Reservations. |
112 |
123 |
* @post reservation is stored in the active Reservations. |
113 |
124 |
* @post The Beds in the provided Room are reserved for the Reservation's |
114 |
125 |
* period. |
115 |
126 |
* @throws IllegalArgumentException if the given Room can't fulfill the |
116 |
127 |
* requirements of the Reservation, or occupants is less than 1. |
117 |
128 |
* @throws NullPointerException if any parameter is a null pointer. |
118 |
129 |
*/ |
119 |
130 |
public void addReservation(Reservation reservation, Room room) { |
120 |
131 |
// Contract validation |
121 |
- | if(occupants < 1) |
+ |
132 |
// methods. |
+ |
133 |
if(occupants < 1) |
122 |
134 |
throw IllegalArgumentException("An invalid amount of occupants was given."); |
123 |
135 |
if(occupants > room.getEmptyBeds(reservation.getBegin(), reservation.getEnd()).size()) |
124 |
136 |
throw IllegalArgumentException("The given Room has not enough empty Beds for the Reservation period."); |
125 |
137 |
if(!this.getRoomController().getQualifiedRooms(reservation).contains(room)) |
126 |
138 |
throw IllegalArgumentException("The given Room cannot meet all requirements of the Reservation."); |
127 |
139 |
if(this.getReservations().contains(reservation)) { |
128 |
- | throw IllegalArgumentException("The given Reservation was already included as |
129 |
- | |
+ |
140 |
throw IllegalArgumentException("The given Reservation was already included in the active Reservations."); |
+ |
141 |
// Contract validated |
+ |
142 |
this.reservations.add(reservation); |
+ |
143 |
Set<Bed> beds |
+ |
144 |
for(int i=0; i<occupants; i++) { |
+ |
145 |
|
+ |
146 |
|
+ |
147 |
|
+ |
148 |
|
130 |
149 |
|
131 |
150 |
// TODO: Add reservation to the set, and add the reserved days to the |
132 |
151 |
// beds in the given room. |
133 |
152 |
} |
134 |
153 |
/** |
135 |
154 |
* Cancels and removes the given Reservation. |
136 |
155 |
* If you want to remove a Reservation, use this method, and provide the |
137 |
156 |
* Reservation up for removal. |
138 |
157 |
* This method will take care of related actions, such as releasing Beds. |
139 |
158 |
* @param reservation The Reservation to be removed. |
140 |
159 |
* @pre reservation mustn't be null. |
141 |
160 |
* @pre reservation must be contained in the active Reservations. |
142 |
161 |
* @post The Reservation is removed from the active Reservations. |
143 |
162 |
* @post The Beds, previously reserved for this Reservation, are now |
144 |
163 |
* released, and can be reserved for another Reservation. |
145 |
164 |
* @throws NullPointerException if reservation is a null pointer. |
146 |
165 |
* @throws IllegalArgumentException if reservation is not contained in the |
147 |
166 |
* active Reservations. |
148 |
167 |
*/ |
149 |
168 |
public void cancelReservation(Reservation reservation) { |
150 |
169 |
// Contract validation |
151 |
170 |
if(!this.getReservations().contains(reservation)) { |
152 |
171 |
throw IllegalArgumentException("The given Reservation was not contained in the active Reservations."); |
153 |
172 |
} |
154 |
173 |
if(reservation == null) { |
155 |
174 |
throw NullPointerException(); |
156 |
175 |
} |
157 |
176 |
// Contract validated, execute method |
158 |
177 |
this.reservations.remove(reservation); // Remove from active Reservations |
159 |
178 |
for(Bed bed: reservation.getReservedBeds()) { // Release reserved Beds |
160 |
179 |
bed.removeReservationPeriod(reservation.getBegin(), reservation.getEnd()); |
161 |
180 |
} |
162 |
181 |
// Asserting post conditions are met |
163 |
182 |
assert !this.getReservation().contains(reservation) : "The reservation is still part of the active Reservations."; |
164 |
183 |
for(Bed bed: reservation.getReservedBeds()) { |
165 |
184 |
assert bed.isFree(reservation.getBegin(), reservation.getEnd()) : "One or more of the Beds are still reserved."; |
166 |
185 |
} |
167 |
186 |
} |
168 |
187 |
|
169 |
188 |
} |
170 |
189 |