public void addCopies(Set<BookCopy> bookCopiesSet) throws BookStoreException { int ISBN, numCopies; if (bookCopiesSet == null) { throw new BookStoreException(BookStoreConstants.NULL_INPUT); } try { bsLock.updateLock().lock(); for (BookCopy bookCopy : bookCopiesSet) { ISBN = bookCopy.getISBN(); numCopies = bookCopy.getNumCopies(); if (BookStoreUtility.isInvalidISBN(ISBN)) throw new BookStoreException(BookStoreConstants.ISBN + ISBN + BookStoreConstants.INVALID); if (!bookMap.containsKey(ISBN)) throw new BookStoreException(BookStoreConstants.ISBN + ISBN + BookStoreConstants.INVALID); if (BookStoreUtility.isInvalidNoCopies(numCopies)) throw new BookStoreException( BookStoreConstants.NUM_COPIES + numCopies + BookStoreConstants.INVALID); } bsLock.writeLock().lock(); BookStoreBook book; // Update the number of copies for (BookCopy bookCopy : bookCopiesSet) { ISBN = bookCopy.getISBN(); numCopies = bookCopy.getNumCopies(); book = bookMap.get(ISBN); book.addCopies(numCopies); } } finally { bsLock.writeLock().unlock(); bsLock.updateLock().unlock(); } }
public List<Book> getBooks(Set<Integer> isbnSet) throws BookStoreException { if (isbnSet == null) { throw new BookStoreException(BookStoreConstants.NULL_INPUT); } List<Book> listBooks = new ArrayList<Book>(); try { bsLock.readLock().lock(); // Check that all ISBNs that we rate are there first. for (Integer ISBN : isbnSet) { if (BookStoreUtility.isInvalidISBN(ISBN)) throw new BookStoreException(BookStoreConstants.ISBN + ISBN + BookStoreConstants.INVALID); if (!bookMap.containsKey(ISBN)) throw new BookStoreException( BookStoreConstants.ISBN + ISBN + BookStoreConstants.NOT_AVAILABLE); } // Get the books for (Integer ISBN : isbnSet) { listBooks.add(bookMap.get(ISBN).immutableBook()); } } finally { bsLock.readLock().unlock(); } return listBooks; }
public void updateEditorPicks(Set<BookEditorPick> editorPicks) throws BookStoreException { // Check that all ISBNs that we add/remove are there first. if (editorPicks == null) { throw new BookStoreException(BookStoreConstants.NULL_INPUT); } int ISBNVal; try { bsLock.updateLock().lock(); for (BookEditorPick editorPickArg : editorPicks) { ISBNVal = editorPickArg.getISBN(); if (BookStoreUtility.isInvalidISBN(ISBNVal)) throw new BookStoreException( BookStoreConstants.ISBN + ISBNVal + BookStoreConstants.INVALID); if (!bookMap.containsKey(ISBNVal)) throw new BookStoreException( BookStoreConstants.ISBN + ISBNVal + BookStoreConstants.NOT_AVAILABLE); } bsLock.writeLock().lock(); for (BookEditorPick editorPickArg : editorPicks) { bookMap.get(editorPickArg.getISBN()).setEditorPick(editorPickArg.isEditorPick()); } } finally { bsLock.writeLock().unlock(); bsLock.updateLock().unlock(); } return; }
public List<StockBook> getBooks() { List<StockBook> listBooks = new ArrayList<StockBook>(); try { bsLock.readLock().lock(); Collection<BookStoreBook> bookMapValues = bookMap.values(); for (BookStoreBook book : bookMapValues) { listBooks.add(book.immutableStockBook()); } } finally { bsLock.readLock().unlock(); } return listBooks; }
@Override public List<Book> getTopRatedBooks(int numBooks) throws BookStoreException { // TODO Auto-generated method stub // No negative number if (numBooks <= 0) { throw new BookStoreException("numBooks = " + numBooks + ", but it must be positive"); } Collection<BookStoreBook> books = bookMap.values(); if (books.isEmpty()) { throw new BookStoreException("No books in the bookstore"); } List<BookStoreBook> listRatedBooks = new ArrayList<BookStoreBook>(); List<Book> listTopRatedBooks = new ArrayList<Book>(); try { bsLock.readLock().lock(); // block other from writing data // we only count the book has a rating for (BookStoreBook book : books) { if (book.getAverageRating() > 0) listRatedBooks.add(book); } Comparator<BookStoreBook> comparator = new Comparator<BookStoreBook>() { public int compare(BookStoreBook book1, BookStoreBook book2) { return Float.compare( book2.getAverageRating(), book1.getAverageRating()); // get right order of books } }; Collections.sort(listRatedBooks, comparator); for (BookStoreBook book : listRatedBooks) { listTopRatedBooks.add(book.immutableStockBook()); if (listTopRatedBooks.size() == numBooks) break; } } finally { bsLock.readLock().unlock(); } // return the certain amount of books by its rating return listTopRatedBooks; }
public void buyBooks(Set<BookCopy> bookCopiesToBuy) throws BookStoreException { if (bookCopiesToBuy == null) { throw new BookStoreException(BookStoreConstants.NULL_INPUT); } // Check that all ISBNs that we buy are there first. int ISBN; BookStoreBook book; Boolean saleMiss = false; try { bsLock.updateLock().lock(); for (BookCopy bookCopyToBuy : bookCopiesToBuy) { ISBN = bookCopyToBuy.getISBN(); if (BookStoreUtility.isInvalidISBN(ISBN)) throw new BookStoreException(BookStoreConstants.ISBN + ISBN + BookStoreConstants.INVALID); if (!bookMap.containsKey(ISBN)) throw new BookStoreException( BookStoreConstants.ISBN + ISBN + BookStoreConstants.NOT_AVAILABLE); book = bookMap.get(ISBN); if (!book.areCopiesInStore(bookCopyToBuy.getNumCopies())) { book.addSaleMiss(); // If we cannot sell the copies of the // book // its a miss saleMiss = true; } } // We throw exception now since we want to see how many books in the // order incurred misses which is used by books in demand if (saleMiss) throw new BookStoreException(BookStoreConstants.BOOK + BookStoreConstants.NOT_AVAILABLE); bsLock.writeLock().lock(); // Then make purchase for (BookCopy bookCopyToBuy : bookCopiesToBuy) { book = bookMap.get(bookCopyToBuy.getISBN()); book.buyCopies(bookCopyToBuy.getNumCopies()); } } finally { bsLock.writeLock().unlock(); bsLock.updateLock().unlock(); } return; }
@Override public List<StockBook> getBooksInDemand() throws BookStoreException { // TODO Auto-generated method stub bsLock.updateLock().lock(); List<StockBook> listBooksInDemand = new ArrayList<StockBook>(); Collection<BookStoreBook> books = bookMap.values(); if (books.isEmpty()) { throw new BookStoreException("No books in the bookstore"); } try { for (BookStoreBook book : books) { if (book.hadSaleMiss()) { listBooksInDemand.add(book.immutableStockBook()); } } } finally { bsLock.updateLock().unlock(); } return listBooksInDemand; }
@Override public void rateBooks(Set<BookRating> bookRating) throws BookStoreException { // TODO Auto-generated method stub // lock update lock, only allow read bsLock.updateLock().lock(); try { /* Check if the input is valid */ if (bookRating == null) throw new BookStoreException(BookStoreConstants.NULL_INPUT); int ISBN, rating; BookStoreBook book; for (BookRating br : bookRating) { ISBN = br.getISBN(); rating = br.getRating(); if (BookStoreUtility.isInvalidISBN(ISBN)) throw new BookStoreException(BookStoreConstants.ISBN + ISBN + BookStoreConstants.INVALID); if (!bookMap.containsKey(ISBN)) throw new BookStoreException( BookStoreConstants.ISBN + ISBN + BookStoreConstants.NOT_AVAILABLE); if (BookStoreUtility.isInvalidRating(rating)) throw new BookStoreException( BookStoreConstants.RATING + rating + BookStoreConstants.INVALID); } try { bsLock.writeLock().lock(); // upgrade to write lock /* Inputs are valid so, ready to rate the books change */ for (BookRating br : bookRating) { book = bookMap.get(br.getISBN()); book.addRating(br.getRating()); } } finally { bsLock.writeLock().unlock(); // downgrade to update lock } } finally { bsLock.updateLock().unlock(); } return; }
public List<Book> getEditorPicks(int numBooks) throws BookStoreException { if (numBooks < 0) { throw new BookStoreException("numBooks = " + numBooks + ", but it must be positive"); } List<BookStoreBook> listAllEditorPicks = new ArrayList<BookStoreBook>(); List<Book> listEditorPicks = new ArrayList<Book>(); try { bsLock.readLock().lock(); Iterator<Entry<Integer, BookStoreBook>> it = bookMap.entrySet().iterator(); BookStoreBook book; // Get all books that are editor picks while (it.hasNext()) { Entry<Integer, BookStoreBook> pair = (Entry<Integer, BookStoreBook>) it.next(); book = (BookStoreBook) pair.getValue(); if (book.isEditorPick()) { listAllEditorPicks.add(book); } } // Find numBooks random indices of books that will be picked Random rand = new Random(); Set<Integer> tobePicked = new HashSet<Integer>(); int rangePicks = listAllEditorPicks.size(); if (rangePicks < numBooks) { throw new BookStoreException("Only " + rangePicks + " editor picks are available."); } int randNum; while (tobePicked.size() < numBooks) { randNum = rand.nextInt(rangePicks); tobePicked.add(randNum); } // Get the numBooks random books for (Integer index : tobePicked) { book = listAllEditorPicks.get(index); listEditorPicks.add(book.immutableBook()); } } finally { bsLock.readLock().unlock(); } return listEditorPicks; }
public void addBooks(Set<StockBook> bookSet) throws BookStoreException { if (bookSet == null) { throw new BookStoreException(BookStoreConstants.NULL_INPUT); } try { // Check if all are there bsLock.updateLock().lock(); for (StockBook book : bookSet) { int ISBN = book.getISBN(); String bookTitle = book.getTitle(); String bookAuthor = book.getAuthor(); int noCopies = book.getNumCopies(); float bookPrice = book.getPrice(); if (BookStoreUtility.isInvalidISBN(ISBN) || BookStoreUtility.isEmpty(bookTitle) || BookStoreUtility.isEmpty(bookAuthor) || BookStoreUtility.isInvalidNoCopies(noCopies) || bookPrice < 0.0) { throw new BookStoreException( BookStoreConstants.BOOK + book.toString() + BookStoreConstants.INVALID); } else if (bookMap.containsKey(ISBN)) { throw new BookStoreException( BookStoreConstants.ISBN + ISBN + BookStoreConstants.DUPLICATED); } } bsLock.writeLock().lock(); for (StockBook book : bookSet) { int ISBN = book.getISBN(); bookMap.put(ISBN, new BookStoreBook(book)); } } finally { bsLock.writeLock().unlock(); bsLock.updateLock().unlock(); } return; }