001: package auction.model;
002:
003: import auction.exceptions.BusinessException;
004: import java.text.DateFormat;
005: import java.text.FieldPosition;
006: import java.text.ParseException;
007: import java.text.ParsePosition;
008: import java.util.ArrayList;
009: import java.util.Collection;
010: import java.util.Date;
011: import java.util.HashMap;
012: import java.util.HashSet;
013: import java.util.List;
014: import java.util.Locale;
015: import java.util.Map;
016: import java.util.Set;
017:
018: public class Book {
019:
020: private Long id = null;
021: private int version = 0;
022:
023: private String title;
024: private User seller;
025: private String author;
026: private String description;
027: private Language language;
028: private long initialPrice;
029: private long reservePrice;
030: private Date startDate;
031: private Date endDate;
032: private String image;
033: private boolean active = false;
034:
035: private List<Bid> bids = new ArrayList<Bid>();
036: private Bid successfulBid;
037:
038: private Set<Category> categories = new HashSet<Category>();
039: private Date created = new Date();
040:
041: private DateFormat dateFormat = DateFormat.getDateInstance(
042: DateFormat.LONG, Locale.ENGLISH);
043:
044: public Book() {
045: }
046:
047: public Book(String title, String author, String description,
048: Language language, User seller, long initialPrice,
049: long reservePrice, Date startDate, Date endDate) {
050: this .title = title;
051: this .description = description;
052: this .language = language;
053: this .seller = seller;
054: this .author = author;
055: this .initialPrice = initialPrice;
056: this .reservePrice = reservePrice;
057: this .startDate = startDate;
058: this .endDate = endDate;
059:
060: seller.getBooksForSale().add(this );
061: }
062:
063: public Long getId() {
064: return id;
065: }
066:
067: public int getVersion() {
068: return version;
069: }
070:
071: public String getTitle() {
072: return title;
073: }
074:
075: public void setTitle(String title) {
076: this .title = title;
077: }
078:
079: public boolean isActive() {
080: return active;
081: }
082:
083: public void setActive(boolean state) {
084: active = state;
085: }
086:
087: public String getActiveS() {
088: return (isActive() ? "1" : "0");
089: }
090:
091: public void setActiveS(String state) {
092: setActive("1".equals(state));
093: }
094:
095: public String getBookLocation() {
096: String city = seller.getHomeAddress().getCity();
097: String zipcode = seller.getHomeAddress().getZipcode();
098: String street = seller.getHomeAddress().getStreet();
099: return (zipcode + " " + city + ", " + street);
100: }
101:
102: public String getDescription() {
103: return description;
104:
105: }
106:
107: public void setDescription(String description) {
108: this .description = description;
109: }
110:
111: public User getSeller() {
112: return seller;
113: }
114:
115: public String getAuthor() {
116: return author;
117: }
118:
119: public void setAuthor(String author) {
120: this .author = author;
121: }
122:
123: public long getInitialPrice() {
124: return initialPrice;
125: }
126:
127: public void setInitialPrice(long initialPrice) {
128: this .initialPrice = initialPrice;
129: }
130:
131: public long getReservePrice() {
132: return reservePrice;
133: }
134:
135: public void setReservePrice(long reservePrice) {
136: this .reservePrice = reservePrice;
137: }
138:
139: public void setReservePrice(String reservePrice) {
140: try {
141: this .reservePrice = Long.parseLong(reservePrice);
142: } catch (RuntimeException ex) {
143: }
144: }
145:
146: public void setInitialPrice(String initialPrice) {
147: try {
148: this .initialPrice = Long.parseLong(initialPrice);
149: } catch (RuntimeException ex) {
150: }
151: }
152:
153: public String getInitialPriceEur() {
154: return (String.valueOf(initialPrice) + " eur");
155: }
156:
157: public String getReservePriceEur() {
158: return (String.valueOf(reservePrice) + " eur");
159: }
160:
161: public void setStartDate(Date startDate) {
162: this .startDate = startDate;
163: }
164:
165: public Date getStartDate() {
166: return startDate;
167: }
168:
169: public void setEndDate(Date endDate) {
170: this .endDate = endDate;
171: }
172:
173: public Date getEndDate() {
174: return endDate;
175: }
176:
177: public String getStartDateString() {
178: return dateFormat.format(startDate);
179: }
180:
181: public String getEndDateString() {
182: return dateFormat.format(endDate);
183: }
184:
185: public void setStartDateString(String sd) {
186: try {
187: startDate = dateFormat.parse(sd);
188: } catch (ParseException ex) {
189: throw (new RuntimeException(ex));
190: }
191: }
192:
193: public void setEndDateString(String sd) {
194: try {
195: endDate = dateFormat.parse(sd);
196: } catch (ParseException ex) {
197: throw (new RuntimeException(ex));
198: }
199: }
200:
201: public List<Bid> getBids() {
202: return bids;
203: }
204:
205: public void addBid(Bid bid) {
206: if (bid == null)
207: throw new IllegalArgumentException("Can't add a null Bid.");
208: this .getBids().add(0, bid);
209: // Don't have to set the "other" side, a Bid can only be instantiated with a given item
210: }
211:
212: public Bid getSuccessfulBid() {
213: return successfulBid;
214: }
215:
216: public void setSuccessfulBid(Bid successfulBid) {
217: // Has to preserve the integrity by using a procedure and loop, bad Java...
218: if (successfulBid != null) {
219: for (Bid bid : getBids())
220: bid.setSuccessful(false);
221: successfulBid.setSuccessful(true);
222: this .successfulBid = successfulBid;
223: }
224: }
225:
226: public Set<Category> getCategories() {
227: return categories;
228: }
229:
230: public void setImage(String image) {
231: this .image = image;
232: }
233:
234: public String getImage() {
235: return image;
236: }
237:
238: public Language getLanguage() {
239: return language;
240: }
241:
242: public void setLanguage(Language language) {
243: this .language = language;
244: }
245:
246: public Date getCreated() {
247: return created;
248: }
249:
250: // ********************** Common Methods ********************** //
251:
252: public boolean equals(Object o) {
253: if (this == o)
254: return true;
255: if (!(o instanceof Book))
256: return false;
257:
258: final Book book = (Book) o;
259:
260: if (!(created.getTime() == book.created.getTime()))
261: return false;
262: if (title != null ? !title.equals(book.title)
263: : book.title != null)
264: return false;
265:
266: return true;
267: }
268:
269: public int hashCode() {
270: int result;
271: result = (title != null ? title.hashCode() : 0);
272: result = 29 * result + created.hashCode();
273: return result;
274: }
275:
276: public String getName() {
277: return "Book ('" + getId() + "'), " + "Title: '" + getTitle()
278: + "' " + "Initial Price: '" + getInitialPrice() + "'";
279: }
280:
281: public String getActiveTxt() {
282: return (isActive() ? "active" : "inactive");
283: }
284:
285: public int compareTo(Object o) {
286: if (o instanceof Book) {
287: return Long.valueOf(this .getCreated().getTime()).compareTo(
288: Long.valueOf(((Book) o).getCreated().getTime()));
289: }
290: return 0;
291: }
292:
293: // ********************** Business Methods ********************** //
294:
295: /**
296: * Places a bid while checking business constraints.
297: *
298: * This method may throw a BusinessException if one of the requirements
299: * for the bid placement wasn't met, e.g. if the auction already ended.
300: *
301: * @param bidder
302: * @param bidAmount
303: * @param currentMaxBid the most valuable bid for this item
304: * @param currentMinBid the least valuable bid for this item
305: * @return
306: * @throws BusinessException
307: */
308: public Bid placeBid(User bidder, long bidAmount, Bid currentMaxBid)
309: throws BusinessException {
310:
311: // Check initial price
312: if (initialPrice > bidAmount) {
313: throw new BusinessException("Bid lower than initial price");
314: }
315:
316: // Check highest bid (can also be a different Strategy (pattern))
317: if (currentMaxBid != null
318: && currentMaxBid.getAmount() > bidAmount) {
319: throw new BusinessException("Bid too low");
320: }
321:
322: // Auction still valid
323: /*
324: if ( this.getEndDate().before( new Date() ) )
325: throw new BusinessException("Can't place new bid, auction already ended");
326: */
327:
328: // Place bid for this item
329: Bid newBid = new Bid(bidAmount, this , bidder);
330: this .addBid(newBid);
331:
332: if (newBid.getAmount() >= getReservePrice()) {
333: this .setActive(false);
334: newBid.setSuccessful(true);
335: }
336:
337: Long bidId = newBid.getId();
338:
339: return newBid;
340: }
341:
342: public boolean removeBid(Bid bid) {
343: return this.getBids().remove(bid);
344: }
345:
346: }
|