/**
* The given code is provided to assist you to complete the required tasks. But the
* given code is often incomplete. You have to read and understand the given code
* carefully, before you can apply the code properly. You might need to implement
* additional procedures, such as error checking and handling, in order to apply the
* code properly.
*/
package Lab4_persistent_data;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
// you need to import some xml libraries
import java.io.*;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
// import any standard library if needed
/**
* A book collection holds 0 or more books in a collection.
*/
public class BookCollection {
private List
/**
* Creates a new collection with no books by default.
*/
public BookCollection() {
this.books = new ArrayList
}
/**
* Creates a new book collection with the specified list of books pre-defined.
*
* @param books A books list.
*/
public BookCollection(List
this.books = books;
}
/**
* Returns the current list of books stored by this collection.
*
* @return A (mutable) list of books.
*/
public List
return books;
}
/**
* Sets the list of books in this collection to the specified value.
*/
public void setList(List
this.books = books;
}
/**
* A simple human-readable toString implementation. Not particularly useful to
* save to disk.
*
* @return A human-readable string for printing
*/
@Override
public String toString() {
return this.books.stream().map(book -> ” – ” + book.display() + “\n”).collect(Collectors.joining());
}
/**
* Saves this collection to the specified “bespoke” file.
*
* @param file The path to a file.
*/
public void saveToBespokeFile(File file) {
// TODO: Implement this function yourself. The specific hierarchy is up to you,
// but it must be in a bespoke format and should match the
// load function.
try(BufferedWriter bw = new BufferedWriter(new FileWriter(file)))
{
for (Book book:books) {
bw.write(book.title+”], “+book.authorName+”], “+book.yearReleased+”], “+book.bookGenre.name+”], “);
bw.newLine();
}
//bw.flush();
}catch(IOException e)
{
e.printStackTrace();
}
}
/**
* Saves this collection to the specified JSON file.
*
* @param file The path to a file.
*/
public void saveToJSONFile(File file) {
// TODO: Implement this function yourself. The specific hierarchy is up to you,
// but it must be in a JSON format and should match the load function.
Gson gson = new GsonBuilder().setPrettyPrinting().create();
try(FileWriter fileWriter = new FileWriter(file)){
gson.toJson(books, fileWriter);
}catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Saves this collection to the specified XML file.
*
* @param file The path to a file.
*/
public void saveToXMLFile(File file) {
// TODO: Implement this function yourself. The specific hierarchy is up to you,
// but it must be in an XML format and should match the
// load function.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder(); //create a DocumentBuilder
Document d = db.newDocument(); //create a DOM document
//create the structure of document
//create an element names books(root)
Element booksElement = d.createElement(“books”);
//append books to the document
d.appendChild(booksElement);
//loop through all books to create each book element
for(Book book : books)
{
//create an element names book(each loop has one)
Element bookElement = d.createElement(“book”);
//each book have title
Element title = d.createElement(“title”);
title.appendChild(d.createTextNode(book.title));
bookElement.appendChild(title);
//each book have authorName
Element authorName = d.createElement(“authorName”);
authorName.appendChild(d.createTextNode(book.authorName));
bookElement.appendChild(authorName);
//each book have yearReleased
Element yearReleased = d.createElement(“yearReleased”);
yearReleased.appendChild(d.createTextNode(Integer.toString (book.yearReleased)));
bookElement.appendChild(yearReleased);
//each book have bookGenre
Element bookGenre = d.createElement(“bookGenre”);
bookGenre.appendChild(d.createTextNode(book.bookGenre.name));
bookElement.appendChild(bookGenre);
//add book into books
booksElement.appendChild(bookElement);
}
//transform a source tree into a result tree
//transformer process XML from a variety of sources and write the transformation output to a variety of sinks
Transformer transformer = TransformerFactory.newInstance().newTransformer();
//set encoding
transformer.setOutputProperty(OutputKeys.ENCODING, “utf-8”);
//indent the output document
transformer.setOutputProperty(OutputKeys.INDENT, “yes”);
//create document
DOMSource source = new DOMSource(d);
StreamResult result = new StreamResult(file);
transformer.transform(source, result); //transform source to result.
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Load a pre-existing book collection from a “bespoke” file.
*
* @param file The file to load from. This is guaranteed to exist.
* @return An initialised book collection.
*/
public static BookCollection loadFromBespokeFile(File file) {
// TODO: Implement this function yourself.
BookCollection books=new BookCollection();
try (BufferedReader br = new BufferedReader(new FileReader(file)))
{
List
BookGenre bookGenre;
int i=0;
String records;
//read nextLine
while((records=br.readLine()) !=null)
{
String[] bookinfo = records.split(“], “);
//judge the type of BookGenre
if (bookinfo[3].equals(BookGenre.NON_FICTION.name)) {
bookGenre = BookGenre.NON_FICTION;
}
else if (bookinfo[3].equals(BookGenre.FICTION_ACTION.name)) {
bookGenre = BookGenre.FICTION_ACTION;
}
else if (bookinfo[3].equals(BookGenre.FICTION_COMEDY.name)) {
bookGenre = BookGenre.FICTION_COMEDY;
} else if (bookinfo[3].equals(BookGenre.FICTION_FANTASY.name)) {
bookGenre = BookGenre.FICTION_FANTASY;
} else {
bookGenre = BookGenre.NON_FICTION;;
}
getbooks.add(i,new Book(bookinfo[0],bookinfo[1],Integer.parseInt(bookinfo[2]),bookGenre));
//System.out.println(getbooks.get(i).bookGenre);
i++;
}
//set booklist into BookCollection
books.setList(getbooks);
}catch(IOException e)
{
e.printStackTrace();
}
return books;
}
/**
* Load a pre-existing book collection from a JSON file.
*
* @param file The file to load from. This is guaranteed to exist.
* @return An initialised book collection.
*/
public static BookCollection loadFromJSONFile(File file) {
// TODO: Implement this function yourself.
Gson gson = new Gson();
JsonReader jsonReader = null;
BookCollection books=new BookCollection();
List
try{
jsonReader = new JsonReader(new FileReader(file));
//put the list into the getbooks
getbooks=gson.fromJson(jsonReader,TypeToken.getParameterized(ArrayList.class, Book.class).getType());
//set booklist into BookCollection
books.setList(getbooks);
}catch (Exception e) {
e.printStackTrace();
}
return books;
}
/**
* Load a pre-existing book collection from an XML file.
*
* @param file The file to load from. This is guaranteed to exist.
* @return An initialised book collection.
*/
public static BookCollection loadFromXMLFile(File file) {
// TODO: Implement this function yourself.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
List
BookCollection books=new BookCollection();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
Document d = db.parse(file); //parse file,the root of the document tree
d.getDocumentElement().normalize(); //remove the redundancies
//get a nodeslist by tag name book
NodeList nodeList = d.getElementsByTagName(“book”);
for(int i = 0; i < nodeList.getLength(); i++)
{
Node n = nodeList.item(i);
if(n.getNodeType() == Node.ELEMENT_NODE) {
//each node is an element
Element element = (Element) n;
String title = element.getElementsByTagName("title").item(0).getTextContent();
String authorName = element.getElementsByTagName("authorName").item(0).getTextContent();
Integer yearReleased = Integer.parseInt(element.getElementsByTagName("yearReleased").item(0).getTextContent());
String bookGenreElement=element.getElementsByTagName("bookGenre").item(0).getTextContent();
BookGenre bookGenre;
if (bookGenreElement.equals(BookGenre.NON_FICTION.name)) {
bookGenre = BookGenre.NON_FICTION;
}
else if (bookGenreElement.equals(BookGenre.FICTION_ACTION.name)) {
bookGenre = BookGenre.FICTION_ACTION;
}
else if (bookGenreElement.equals(BookGenre.FICTION_COMEDY.name)) {
bookGenre = BookGenre.FICTION_COMEDY;
} else if (bookGenreElement.equals(BookGenre.FICTION_FANTASY.name)) {
bookGenre = BookGenre.FICTION_FANTASY;
} else {
bookGenre = BookGenre.NON_FICTION;;
}
//add the attributes into book
Book book = new Book(title, authorName, yearReleased,bookGenre);
//add book into booklist
getbooks.add(book);
}
}
//set booklist into BookCollection
books.setList(getbooks);
}
catch(Exception e)
{
e.printStackTrace();
}
return books;
}
}