/**
Copyright 2012 Fahad Al-Khameesi, Madeleine Appert, Niklas Logren, Arild Matsson and Jonathan Orr�.
This file is part of Bibbla.
Bibbla is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bibbla is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bibbla. If not, see <http://www.gnu.org/licenses/>.
**/
package dat255.grupp06.bibbla.backend.tasks;
import java.util.ArrayList;
import java.util.List;
import org.jsoup.Connection.Method;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import dat255.grupp06.bibbla.backend.Backend;
import dat255.grupp06.bibbla.model.Book;
import dat255.grupp06.bibbla.model.PhysicalBook;
import dat255.grupp06.bibbla.utils.Error;
import dat255.grupp06.bibbla.utils.Message;
/**
* Fetches the detailed view of a book, and
* saves the additional information in a new Book.
*
* @author Fahad Al-Khameesi
*/
public class DetailedViewJob extends Job {
private Book originalBook, newBook;
private Message message = new Message();
public DetailedViewJob(Book book){
this.originalBook = book;
this.newBook = (Book)originalBook.clone();
}
/**
* Fetches the detailed view of a book.
*
* @returns a new Book, containing the additional information present in its detailed view.
*/
public Message run(){
try {
System.out.print("\n****** DetailedViewJob\n");
System.out.print("* step 1: fetch book details... ");
Response response = connectAndRetry();
System.out.print("* step 2: parse book details... ");
parseBookDetails(response);
System.out.print("succeeded! *\n*");
System.out.print("****** DetailedViewJob done \n");
} catch (Exception e) {
message.error = (message.error!=null) ? message.error : Error.DETAILED_VIEW_FAILED;
}
return message;
}
@Override
/**
* Fetches the details of the supplied book.
*
* @throws Exception if HTTP connection failed.
*/
protected Response connect() throws Exception {
// Performs connection using Jsoup.
Response r = Jsoup.connect(originalBook.getUrl())
.method(Method.GET)
.timeout(Backend.CONNECTION_TIMEOUT)
.execute();
return r;
}
/**
* Parses the HTML document fetched by fetchBookDetails().
*
* @throws Exception if parsing fails.
*/
private void parseBookDetails(Response response) throws Exception{
// Prepare HTML for parsing.
Document html = response.parse();
List<PhysicalBook> physicalBooks = new ArrayList<PhysicalBook>();
Elements tableRows = html.select("table.bibItems").select("tr.bibItemsEntry");
// Create all our PhysicalBooks.
for (Element row : tableRows) {
Elements columns = row.getElementsByTag("td");
String library = columns.get(0).text();
String shelf = columns.get(1).text();
String status = columns.get(2).text();
String message = columns.get(3).text();
PhysicalBook physicalBook = new PhysicalBook(library, shelf, status, message);
physicalBooks.add(physicalBook);
}
// Select all rows containing detailed information.
Elements rows = html.select("div#orders").select("table.bibDetail").select("tr");
String description = "", notes = "", isbn = "";
// Loop through all rows.
for(int i=1;i<rows.size();i++) {
// If we find a physical description,
if(rows.get(i).select("td.bibInfoLabel").text().equals((String) "Fysisk beskrivning")){
// Save the text present on row #1,
description += (rows.get(i)).select("td.bibInfoData").text();
int n = i+1;
// And if there are rows without labels following it,
// they are also part of the description.
while((rows.get(n).select("td.bibInfoLabel").size() == 0)){
description += (rows.get(n)).select("td.bibInfoData").text();
n++;
}
}
// If we find a note,
if(rows.get(i).select("td.bibInfoLabel").text().equals((String) "Anm�rkning")) {
// Save the text on row #1
notes += (rows.get(i)).select("td.bibInfoData").text();
int n = i+1;
// And save text of possible following rows that has no label.
while((rows.get(n).select("td.bibInfoLabel").size() == 0)) {
notes += (rows.get(n)).select("td.bibInfoData").text();
n++;
}
}
// If we find an ISBN, save it.
if(rows.get(i).select("td.bibInfoLabel").text().equals((String) "ISBN")){
isbn = (rows.get(i)).select("td.bibInfoData").text();
}
}
Elements table = html.select("table.bibDetail").first().select("tr");
for(int i=0;i<table.size();i++){
if( table.get(i).select("td.bibInfoLabel").text().equals((String) "Upphov")){
newBook.setAuthor(table.get(i).select("td.bibInfoData").text());
}
if( table.get(i).select("td.bibInfoLabel").text().equals((String) "Titel")){
String[] temp =(table.get(i).select("td.bibInfoData").text().split("/"));
newBook.setName(temp[0]);
}
if( table.get(i).select("td.bibInfoLabel").text().equals((String) "Utgivning")){
newBook.setPublisher(table.get(i).select("td.bibInfoData").text());
}
}
// Update newBook with this information.
newBook.setPhysicalBooks(physicalBooks);
newBook.setIsbn(isbn);
newBook.setNotes(notes);
newBook.setPhysicalDescription(description);
message.obj = newBook;
}
}