aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/musichub/business/Album.java145
-rw-r--r--src/main/java/musichub/business/AudioBook.java78
-rw-r--r--src/main/java/musichub/business/AudioElement.java88
-rw-r--r--src/main/java/musichub/business/Category.java14
-rw-r--r--src/main/java/musichub/business/Genre.java14
-rw-r--r--src/main/java/musichub/business/Language.java14
-rw-r--r--src/main/java/musichub/business/MusicHub.java329
-rw-r--r--src/main/java/musichub/business/NoAlbumFoundException.java8
-rw-r--r--src/main/java/musichub/business/NoElementFoundException.java8
-rw-r--r--src/main/java/musichub/business/NoPlayListFoundException.java8
-rw-r--r--src/main/java/musichub/business/PlayList.java100
-rw-r--r--src/main/java/musichub/business/Song.java56
-rw-r--r--src/main/java/musichub/main/Main.java248
-rw-r--r--src/main/java/musichub/util/XMLHandler.java74
14 files changed, 1184 insertions, 0 deletions
diff --git a/src/main/java/musichub/business/Album.java b/src/main/java/musichub/business/Album.java
new file mode 100644
index 0000000..01fd179
--- /dev/null
+++ b/src/main/java/musichub/business/Album.java
@@ -0,0 +1,145 @@
+package musichub.business;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+
+public class Album {
+ private final String title;
+ private final int lengthInSeconds;
+ private final UUID uuid;
+ private String artist;
+ private Date date;
+ private ArrayList<UUID> songsUIDs;
+
+ public Album(String title, String artist, int lengthInSeconds, String id, String date, ArrayList<UUID> songsUIDs) {
+ this.title = title;
+ this.artist = artist;
+ this.lengthInSeconds = lengthInSeconds;
+ this.uuid = UUID.fromString(id);
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ this.date = sdf.parse(date);
+ } catch (ParseException ex) {
+ ex.printStackTrace();
+ }
+ this.songsUIDs = songsUIDs;
+ }
+
+ public Album(String title, String artist, int lengthInSeconds, String date) {
+ this.title = title;
+ this.artist = artist;
+ this.lengthInSeconds = lengthInSeconds;
+ this.uuid = UUID.randomUUID();
+ try {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ this.date = sdf.parse(date);
+ } catch (ParseException ex) {
+ ex.printStackTrace();
+ }
+ this.songsUIDs = new ArrayList<>();
+ }
+
+ public Album(Element xmlElement) throws Exception {
+ {
+ this.title = xmlElement.getElementsByTagName("title").item(0).getTextContent();
+ this.lengthInSeconds = Integer.parseInt(xmlElement.getElementsByTagName("lengthInSeconds").item(0).getTextContent());
+ String uuid = null;
+ try {
+ uuid = xmlElement.getElementsByTagName("UUID").item(0).getTextContent();
+ } catch (Exception ex) {
+ System.out.println("Empty album UUID, will create a new one");
+ }
+ if ((uuid == null) || (uuid.isEmpty()))
+ this.uuid = UUID.randomUUID();
+ else this.uuid = UUID.fromString(uuid);
+
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ this.date = sdf.parse(xmlElement.getElementsByTagName("date").item(0).getTextContent());
+ //parse list of songs:
+ Node songsElement = xmlElement.getElementsByTagName("songs").item(0);
+ NodeList songUUIDNodes = songsElement.getChildNodes();
+ if (songUUIDNodes == null) return;
+
+ this.songsUIDs = new ArrayList<>();
+
+ for (int i = 0; i < songUUIDNodes.getLength(); i++) {
+ if (songUUIDNodes.item(i).getNodeType() == Node.ELEMENT_NODE) {
+ Element songElement = (Element) songUUIDNodes.item(i);
+ if (songElement.getNodeName().equals("UUID")) {
+ try {
+ this.addSong(UUID.fromString(songElement.getTextContent()));
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ public void addSong(UUID song) {
+ songsUIDs.add(song);
+ }
+
+
+ public List<UUID> getSongs() {
+ return songsUIDs;
+ }
+
+ public ArrayList<UUID> getSongsRandomly() {
+ ArrayList<UUID> shuffledSongs = songsUIDs;
+ Collections.shuffle(shuffledSongs);
+ return shuffledSongs;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+
+ public void createXMLElement(Document document, Element parentElement) {
+ Element albumElement = document.createElement("album");
+ parentElement.appendChild(albumElement);
+
+ Element nameElement = document.createElement("title");
+ nameElement.appendChild(document.createTextNode(title));
+ albumElement.appendChild(nameElement);
+
+ Element artistElement = document.createElement("artist");
+ artistElement.appendChild(document.createTextNode(artist));
+ albumElement.appendChild(artistElement);
+
+ Element lengthElement = document.createElement("lengthInSeconds");
+ lengthElement.appendChild(document.createTextNode(Integer.valueOf(lengthInSeconds).toString()));
+ albumElement.appendChild(lengthElement);
+
+ Element UUIDElement = document.createElement("UUID");
+ UUIDElement.appendChild(document.createTextNode(uuid.toString()));
+ albumElement.appendChild(UUIDElement);
+
+ Element dateElement = document.createElement("date");
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ dateElement.appendChild(document.createTextNode(sdf.format(date)));
+ albumElement.appendChild(dateElement);
+
+ Element songsElement = document.createElement("songs");
+ for (UUID currentUUID : this.songsUIDs) {
+ Element songUUIDElement = document.createElement("UUID");
+ songUUIDElement.appendChild(document.createTextNode(currentUUID.toString()));
+ songsElement.appendChild(songUUIDElement);
+ }
+ albumElement.appendChild(songsElement);
+
+ }
+} \ No newline at end of file
diff --git a/src/main/java/musichub/business/AudioBook.java b/src/main/java/musichub/business/AudioBook.java
new file mode 100644
index 0000000..80392d6
--- /dev/null
+++ b/src/main/java/musichub/business/AudioBook.java
@@ -0,0 +1,78 @@
+package musichub.business;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class AudioBook extends AudioElement {
+ private Language language;
+ private Category category;
+
+ public AudioBook(String title, String artist, int lengthInSeconds, String uid, String content, String language, String category) {
+ super(title, artist, lengthInSeconds, uid, content);
+ this.setLanguage(language);
+ this.setCategory(category);
+ }
+
+ public AudioBook(String title, String artist, int lengthInSeconds, String content, String language, String category) {
+ super(title, artist, lengthInSeconds, content);
+ this.setLanguage(language);
+ this.setCategory(category);
+ }
+
+ public AudioBook(Element xmlElement) {
+ super(xmlElement);
+ this.setLanguage(xmlElement.getElementsByTagName("language").item(0).getTextContent());
+ this.setCategory(xmlElement.getElementsByTagName("category").item(0).getTextContent());
+ }
+
+ public Language getLanguage() {
+ return this.language;
+ }
+
+ public void setLanguage(String language) {
+ switch (language.toLowerCase()) {
+ default -> this.language = Language.ENGLISH;
+ case "french" -> this.language = Language.FRENCH;
+ case "german" -> this.language = Language.GERMAN;
+ case "spanish" -> this.language = Language.SPANISH;
+ case "italian" -> this.language = Language.ITALIAN;
+ }
+ }
+
+ public Category getCategory() {
+ return this.category;
+ }
+
+ public void setCategory(String category) {
+ switch (category.toLowerCase()) {
+ default -> this.category = Category.YOUTH;
+ case "novel" -> this.category = Category.NOVEL;
+ case "theater" -> this.category = Category.THEATER;
+ case "documentary" -> this.category = Category.DOCUMENTARY;
+ case "speech" -> this.category = Category.SPEECH;
+ }
+ }
+
+
+ public String toString() {
+ return super.toString() + ", Language = " + getLanguage() + ", Category = " + getCategory() + "\n";
+ }
+
+
+ public void createXMLElement(Document document, Element parentElement) {
+ // audiobook element
+ Element audioBook = document.createElement("audiobook");
+
+ super.createXMLElement(document, audioBook);
+
+ Element languageElement = document.createElement("language");
+ languageElement.appendChild(document.createTextNode(language.getLanguage()));
+ audioBook.appendChild(languageElement);
+
+ Element categoryElement = document.createElement("category");
+ categoryElement.appendChild(document.createTextNode(category.getCategory()));
+ audioBook.appendChild(categoryElement);
+
+ parentElement.appendChild(audioBook);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/musichub/business/AudioElement.java b/src/main/java/musichub/business/AudioElement.java
new file mode 100644
index 0000000..e0a686b
--- /dev/null
+++ b/src/main/java/musichub/business/AudioElement.java
@@ -0,0 +1,88 @@
+package musichub.business;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import java.util.UUID;
+
+public abstract class AudioElement {
+ protected String title;
+ protected String artist;
+ protected int lengthInSeconds;
+ protected UUID uuid;
+ protected String content;
+
+ public AudioElement(String title, String artist, int lengthInSeconds, String id, String content) {
+ this.title = title;
+ this.artist = artist;
+ this.lengthInSeconds = lengthInSeconds;
+ this.uuid = UUID.fromString(id);
+ this.content = content;
+ }
+
+ public AudioElement(String title, String artist, int lengthInSeconds, String content) {
+ this.title = title;
+ this.artist = artist;
+ this.lengthInSeconds = lengthInSeconds;
+ this.content = content;
+ this.uuid = UUID.randomUUID();
+ }
+
+ public AudioElement(Element xmlElement) {
+ {
+ title = xmlElement.getElementsByTagName("title").item(0).getTextContent();
+ artist = xmlElement.getElementsByTagName("artist").item(0).getTextContent();
+ lengthInSeconds = Integer.parseInt(xmlElement.getElementsByTagName("length").item(0).getTextContent());
+ content = xmlElement.getElementsByTagName("content").item(0).getTextContent();
+ String uuid = null;
+ try {
+ uuid = xmlElement.getElementsByTagName("UUID").item(0).getTextContent();
+ } catch (Exception ex) {
+ System.out.println("Empty element UUID, will create a new one");
+ }
+ if ((uuid == null) || (uuid.isEmpty()))
+ this.uuid = UUID.randomUUID();
+ else this.uuid = UUID.fromString(uuid);
+ }
+ }
+
+ public UUID getUUID() {
+ return this.uuid;
+ }
+
+ public String getArtist() {
+ return this.artist;
+ }
+
+ public String getTitle() {
+ return this.title;
+ }
+
+ public String toString() {
+ return "Title = " + this.title + ", Artist = " + this.artist + ", Length = " + this.lengthInSeconds + ", Content = " + this.content;
+ }
+
+ public void createXMLElement(Document document, Element parentElement) {
+ Element nameElement = document.createElement("title");
+ nameElement.appendChild(document.createTextNode(title));
+ parentElement.appendChild(nameElement);
+
+ Element artistElement = document.createElement("artist");
+ artistElement.appendChild(document.createTextNode(artist));
+ parentElement.appendChild(artistElement);
+
+ Element lengthElement = document.createElement("length");
+ lengthElement.appendChild(document.createTextNode(Integer.valueOf(lengthInSeconds).toString()));
+ parentElement.appendChild(lengthElement);
+
+ Element UUIDElement = document.createElement("UUID");
+ UUIDElement.appendChild(document.createTextNode(uuid.toString()));
+ parentElement.appendChild(UUIDElement);
+
+ Element contentElement = document.createElement("content");
+ contentElement.appendChild(document.createTextNode(content));
+ parentElement.appendChild(contentElement);
+
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/musichub/business/Category.java b/src/main/java/musichub/business/Category.java
new file mode 100644
index 0000000..f676e51
--- /dev/null
+++ b/src/main/java/musichub/business/Category.java
@@ -0,0 +1,14 @@
+package musichub.business;
+
+public enum Category {
+ YOUTH("youth"), NOVEL("novel"), THEATER("theater"), DOCUMENTARY("documentary"), SPEECH("speech");
+ private final String category;
+
+ Category(String category) {
+ this.category = category;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/musichub/business/Genre.java b/src/main/java/musichub/business/Genre.java
new file mode 100644
index 0000000..18deca6
--- /dev/null
+++ b/src/main/java/musichub/business/Genre.java
@@ -0,0 +1,14 @@
+package musichub.business;
+
+public enum Genre {
+ JAZZ("jazz"), CLASSIC("classic"), HIPHOP("hiphop"), ROCK("rock"), POP("pop"), RAP("rap");
+ private final String genre;
+
+ Genre(String genre) {
+ this.genre = genre;
+ }
+
+ public String getGenre() {
+ return genre;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/musichub/business/Language.java b/src/main/java/musichub/business/Language.java
new file mode 100644
index 0000000..679e586
--- /dev/null
+++ b/src/main/java/musichub/business/Language.java
@@ -0,0 +1,14 @@
+package musichub.business;
+
+public enum Language {
+ FRENCH("french"), ENGLISH("english"), ITALIAN("italian"), SPANISH("spanish"), GERMAN("german");
+ private final String language;
+
+ Language(String language) {
+ this.language = language;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/musichub/business/MusicHub.java b/src/main/java/musichub/business/MusicHub.java
new file mode 100644
index 0000000..38e2214
--- /dev/null
+++ b/src/main/java/musichub/business/MusicHub.java
@@ -0,0 +1,329 @@
+package musichub.business;
+
+import musichub.util.XMLHandler;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.util.*;
+
+class SortByDate implements Comparator<Album> {
+ public int compare(Album a1, Album a2) {
+ return a1.getDate().compareTo(a2.getDate());
+ }
+}
+
+class SortByGenre implements Comparator<Song> {
+ public int compare(Song s1, Song s2) {
+ return s1.getGenre().compareTo(s2.getGenre());
+ }
+}
+
+class SortByAuthor implements Comparator<AudioElement> {
+ public int compare(AudioElement e1, AudioElement e2) {
+ return e1.getArtist().compareTo(e2.getArtist());
+ }
+}
+
+public class MusicHub {
+ public static final String DIR = System.getProperty("user.dir");
+ public static final String ALBUMS_FILE_PATH = DIR + "/files/albums.xml";
+ public static final String PLAYLISTS_FILE_PATH = DIR + "/files/playlists.xml";
+ public static final String ELEMENTS_FILE_PATH = DIR + "/files/elements.xml";
+ private final List<Album> albums;
+ private final List<PlayList> playlists;
+ private final List<AudioElement> elements;
+ private final XMLHandler xmlHandler = new XMLHandler();
+
+ public MusicHub() {
+ albums = new LinkedList<>();
+ playlists = new LinkedList<>();
+ elements = new LinkedList<>();
+ this.loadElements();
+ this.loadAlbums();
+ this.loadPlaylists();
+ }
+
+ public void addElement(AudioElement element) {
+ elements.add(element);
+ }
+
+ public void addAlbum(Album album) {
+ albums.add(album);
+ }
+
+ public void addPlaylist(PlayList playlist) {
+ playlists.add(playlist);
+ }
+
+ public void deletePlayList(String playListTitle) throws NoPlayListFoundException {
+
+ PlayList thePlayList = null;
+ boolean result = false;
+ for (PlayList pl : playlists) {
+ if (pl.getTitle().equalsIgnoreCase(playListTitle)) {
+ thePlayList = pl;
+ break;
+ }
+ }
+
+ if (thePlayList != null)
+ result = playlists.remove(thePlayList);
+ if (!result) throw new NoPlayListFoundException("Playlist " + playListTitle + " not found!");
+ }
+
+ public Iterator<Album> albums() {
+ return albums.listIterator();
+ }
+
+ public Iterator<PlayList> playlists() {
+ return playlists.listIterator();
+ }
+
+ public Iterator<AudioElement> elements() {
+ return elements.listIterator();
+ }
+
+ public String getAlbumsTitlesSortedByDate() {
+ StringBuilder titleList = new StringBuilder();
+ albums.sort(new SortByDate());
+ for (Album al : albums)
+ titleList.append(al.getTitle()).append("\n");
+ return titleList.toString();
+ }
+
+ public String getAudiobooksTitlesSortedByAuthor() {
+ StringBuilder titleList = new StringBuilder();
+ List<AudioElement> audioBookList = new ArrayList<>();
+ for (AudioElement ae : elements)
+ if (ae instanceof AudioBook)
+ audioBookList.add(ae);
+ audioBookList.sort(new SortByAuthor());
+ for (AudioElement ab : audioBookList)
+ titleList.append(ab.getArtist()).append("\n");
+ return titleList.toString();
+ }
+
+ public List<AudioElement> getAlbumSongs(String albumTitle) throws NoAlbumFoundException {
+ Album theAlbum = null;
+ ArrayList<AudioElement> songsInAlbum = new ArrayList<>();
+ for (Album al : albums) {
+ if (al.getTitle().equalsIgnoreCase(albumTitle)) {
+ theAlbum = al;
+ break;
+ }
+ }
+ if (theAlbum == null) throw new NoAlbumFoundException("No album with this title in the MusicHub!");
+
+ List<UUID> songIDs = theAlbum.getSongs();
+ for (UUID id : songIDs)
+ for (AudioElement el : elements) {
+ if (el instanceof Song) {
+ if (el.getUUID().equals(id)) songsInAlbum.add(el);
+ }
+ }
+ return songsInAlbum;
+
+ }
+
+ public List<Song> getAlbumSongsSortedByGenre(String albumTitle) throws NoAlbumFoundException {
+ Album theAlbum = null;
+ ArrayList<Song> songsInAlbum = new ArrayList<>();
+ for (Album al : albums) {
+ if (al.getTitle().equalsIgnoreCase(albumTitle)) {
+ theAlbum = al;
+ break;
+ }
+ }
+ if (theAlbum == null) throw new NoAlbumFoundException("No album with this title in the MusicHub!");
+
+ List<UUID> songIDs = theAlbum.getSongs();
+ for (UUID id : songIDs)
+ for (AudioElement el : elements) {
+ if (el instanceof Song) {
+ if (el.getUUID().equals(id)) songsInAlbum.add((Song) el);
+ }
+ }
+ songsInAlbum.sort(new SortByGenre());
+ return songsInAlbum;
+
+ }
+
+ public void addElementToAlbum(String elementTitle, String albumTitle) throws NoAlbumFoundException, NoElementFoundException {
+ Album theAlbum = null;
+ int i;
+ boolean found = false;
+ for (i = 0; i < albums.size(); i++) {
+ if (albums.get(i).getTitle().equalsIgnoreCase(albumTitle)) {
+ theAlbum = albums.get(i);
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ AudioElement theElement = null;
+ for (AudioElement ae : elements) {
+ if (ae.getTitle().equalsIgnoreCase(elementTitle)) {
+ theElement = ae;
+ break;
+ }
+ }
+ if (theElement != null) {
+ theAlbum.addSong(theElement.getUUID());
+ //replace the album in the list
+ albums.set(i, theAlbum);
+ } else throw new NoElementFoundException("Element " + elementTitle + " not found!");
+ } else throw new NoAlbumFoundException("Album " + albumTitle + " not found!");
+
+ }
+
+ public void addElementToPlayList(String elementTitle, String playListTitle) throws NoPlayListFoundException, NoElementFoundException {
+ PlayList thePlaylist = null;
+ int i;
+ boolean found = false;
+
+ for (i = 0; i < playlists.size(); i++) {
+ if (playlists.get(i).getTitle().equalsIgnoreCase(playListTitle)) {
+ thePlaylist = playlists.get(i);
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ AudioElement theElement = null;
+ for (AudioElement ae : elements) {
+ if (ae.getTitle().equalsIgnoreCase(elementTitle)) {
+ theElement = ae;
+ break;
+ }
+ }
+ if (theElement != null) {
+ thePlaylist.addElement(theElement.getUUID());
+ //replace the album in the list
+ playlists.set(i, thePlaylist);
+ } else throw new NoElementFoundException("Element " + elementTitle + " not found!");
+
+ } else throw new NoPlayListFoundException("Playlist " + playListTitle + " not found!");
+
+ }
+
+ private void loadAlbums() {
+ NodeList albumNodes = xmlHandler.parseXMLFile(ALBUMS_FILE_PATH);
+ if (albumNodes == null) return;
+
+ for (int i = 0; i < albumNodes.getLength(); i++) {
+ if (albumNodes.item(i).getNodeType() == Node.ELEMENT_NODE) {
+ Element albumElement = (Element) albumNodes.item(i);
+ if (albumElement.getNodeName().equals("album")) {
+ try {
+ this.addAlbum(new Album(albumElement));
+ } catch (Exception ex) {
+ System.out.println("Something is wrong with the XML album element");
+ }
+ }
+ }
+ }
+ }
+
+ private void loadPlaylists() {
+ NodeList playlistNodes = xmlHandler.parseXMLFile(PLAYLISTS_FILE_PATH);
+ if (playlistNodes == null) return;
+
+ for (int i = 0; i < playlistNodes.getLength(); i++) {
+ if (playlistNodes.item(i).getNodeType() == Node.ELEMENT_NODE) {
+ Element playlistElement = (Element) playlistNodes.item(i);
+ if (playlistElement.getNodeName().equals("playlist")) {
+ try {
+ this.addPlaylist(new PlayList(playlistElement));
+ } catch (Exception ex) {
+ System.out.println("Something is wrong with the XML playlist element");
+ }
+ }
+ }
+ }
+ }
+
+ private void loadElements() {
+ NodeList audioelementsNodes = xmlHandler.parseXMLFile(ELEMENTS_FILE_PATH);
+ if (audioelementsNodes == null) return;
+
+ for (int i = 0; i < audioelementsNodes.getLength(); i++) {
+ if (audioelementsNodes.item(i).getNodeType() == Node.ELEMENT_NODE) {
+ Element audioElement = (Element) audioelementsNodes.item(i);
+ if (audioElement.getNodeName().equals("song")) {
+ try {
+ AudioElement newSong = new Song(audioElement);
+ this.addElement(newSong);
+ } catch (Exception ex) {
+ System.out.println("Something is wrong with the XML song element");
+ }
+ }
+ if (audioElement.getNodeName().equals("audiobook")) {
+ try {
+ AudioElement newAudioBook = new AudioBook(audioElement);
+ this.addElement(newAudioBook);
+ } catch (Exception ex) {
+ System.out.println("Something is wrong with the XML audiobook element");
+ }
+ }
+ }
+ }
+ }
+
+
+ public void saveAlbums() {
+ Document document = xmlHandler.createXMLDocument();
+ if (document == null) return;
+
+ // root element
+ Element root = document.createElement("albums");
+ document.appendChild(root);
+
+ //save all albums
+ for (Iterator<Album> albumsIter = this.albums(); albumsIter.hasNext(); ) {
+ Album currentAlbum = albumsIter.next();
+ currentAlbum.createXMLElement(document, root);
+ }
+ xmlHandler.createXMLFile(document, ALBUMS_FILE_PATH);
+ }
+
+ public void savePlayLists() {
+ Document document = xmlHandler.createXMLDocument();
+ if (document == null) return;
+
+ // root element
+ Element root = document.createElement("playlists");
+ document.appendChild(root);
+
+ //save all playlists
+ for (Iterator<PlayList> playlistsIter = this.playlists(); playlistsIter.hasNext(); ) {
+ PlayList currentPlayList = playlistsIter.next();
+ currentPlayList.createXMLElement(document, root);
+ }
+ xmlHandler.createXMLFile(document, PLAYLISTS_FILE_PATH);
+ }
+
+ public void saveElements() {
+ Document document = xmlHandler.createXMLDocument();
+ if (document == null) return;
+
+ // root element
+ Element root = document.createElement("elements");
+ document.appendChild(root);
+
+ //save all AudioElements
+ for (AudioElement currentElement : elements) {
+
+ if (currentElement instanceof Song) {
+ currentElement.createXMLElement(document, root);
+ }
+ if (currentElement instanceof AudioBook) {
+ currentElement.createXMLElement(document, root);
+ }
+ }
+ xmlHandler.createXMLFile(document, ELEMENTS_FILE_PATH);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/musichub/business/NoAlbumFoundException.java b/src/main/java/musichub/business/NoAlbumFoundException.java
new file mode 100644
index 0000000..04cbfcd
--- /dev/null
+++ b/src/main/java/musichub/business/NoAlbumFoundException.java
@@ -0,0 +1,8 @@
+package musichub.business;
+
+public class NoAlbumFoundException extends Exception {
+
+ public NoAlbumFoundException(String msg) {
+ super(msg);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/musichub/business/NoElementFoundException.java b/src/main/java/musichub/business/NoElementFoundException.java
new file mode 100644
index 0000000..a9b0d76
--- /dev/null
+++ b/src/main/java/musichub/business/NoElementFoundException.java
@@ -0,0 +1,8 @@
+package musichub.business;
+
+public class NoElementFoundException extends Exception {
+
+ public NoElementFoundException(String msg) {
+ super(msg);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/musichub/business/NoPlayListFoundException.java b/src/main/java/musichub/business/NoPlayListFoundException.java
new file mode 100644
index 0000000..c5eb413
--- /dev/null
+++ b/src/main/java/musichub/business/NoPlayListFoundException.java
@@ -0,0 +1,8 @@
+package musichub.business;
+
+public class NoPlayListFoundException extends Exception {
+
+ public NoPlayListFoundException(String msg) {
+ super(msg);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/musichub/business/PlayList.java b/src/main/java/musichub/business/PlayList.java
new file mode 100644
index 0000000..4180a62
--- /dev/null
+++ b/src/main/java/musichub/business/PlayList.java
@@ -0,0 +1,100 @@
+package musichub.business;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.util.ArrayList;
+import java.util.UUID;
+
+public class PlayList {
+ private final String title;
+ private final UUID uuid;
+ private ArrayList<UUID> elementUUIDs;
+
+ public PlayList(String title, String id, ArrayList<UUID> elementUUIDs) {
+ this.title = title;
+ this.uuid = UUID.fromString(id);
+ this.elementUUIDs = elementUUIDs;
+ }
+
+ public PlayList(String title) {
+ this.title = title;
+ this.uuid = UUID.randomUUID();
+ this.elementUUIDs = new ArrayList<>();
+ }
+
+ public PlayList(Element xmlElement) {
+ {
+ this.title = xmlElement.getElementsByTagName("title").item(0).getTextContent();
+
+ String uuid = null;
+ try {
+ uuid = xmlElement.getElementsByTagName("UUID").item(0).getTextContent();
+ } catch (Exception ex) {
+ System.out.println("Empty playlist UUID, will create a new one");
+ }
+ if ((uuid == null) || (uuid.isEmpty()))
+ this.uuid = UUID.randomUUID();
+ else this.uuid = UUID.fromString(uuid);
+
+ //parse list of elements:
+ Node elementsElement = xmlElement.getElementsByTagName("elements").item(0);
+ NodeList elementUUIDNodes = elementsElement.getChildNodes();
+ if (elementUUIDNodes == null) return;
+
+ this.elementUUIDs = new ArrayList<>();
+
+
+ for (int i = 0; i < elementUUIDNodes.getLength(); i++) {
+ if (elementUUIDNodes.item(i).getNodeType() == Node.ELEMENT_NODE) {
+ Element elementElement = (Element) elementUUIDNodes.item(i);
+ if (elementElement.getNodeName().equals("UUID")) {
+ try {
+ this.addElement(UUID.fromString(elementElement.getTextContent()));
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void addElement(UUID element) {
+ elementUUIDs.add(element);
+ }
+
+ public ArrayList<UUID> getElements() {
+ return elementUUIDs;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void createXMLElement(Document document, Element parentElement) {
+ Element playlistElement = document.createElement("playlist");
+ parentElement.appendChild(playlistElement);
+
+ Element nameElement = document.createElement("title");
+ nameElement.appendChild(document.createTextNode(title));
+ playlistElement.appendChild(nameElement);
+
+ Element UUIDElement = document.createElement("UUID");
+ UUIDElement.appendChild(document.createTextNode(uuid.toString()));
+ playlistElement.appendChild(UUIDElement);
+
+
+ Element elementsElement = document.createElement("elements");
+ for (UUID currentUUID : this.elementUUIDs) {
+
+ Element elementUUIDElement = document.createElement("UUID");
+ elementUUIDElement.appendChild(document.createTextNode(currentUUID.toString()));
+ elementsElement.appendChild(elementUUIDElement);
+ }
+ playlistElement.appendChild(elementsElement);
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/musichub/business/Song.java b/src/main/java/musichub/business/Song.java
new file mode 100644
index 0000000..3e9011b
--- /dev/null
+++ b/src/main/java/musichub/business/Song.java
@@ -0,0 +1,56 @@
+package musichub.business;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+
+public class Song extends AudioElement {
+ private Genre genre;
+
+ public Song(String title, String artist, int length, String uid, String content, String genre) {
+ super(title, artist, length, uid, content);
+ this.setGenre(genre);
+ }
+
+ public Song(String title, String artist, int length, String content, String genre) {
+ super(title, artist, length, content);
+ this.setGenre(genre);
+ }
+
+ public Song(Element xmlElement) {
+ super(xmlElement);
+ this.setGenre(xmlElement.getElementsByTagName("genre").item(0).getTextContent());
+ }
+
+ public String getGenre() {
+ return genre.getGenre();
+ }
+
+ public void setGenre(String genre) {
+ switch (genre.toLowerCase()) {
+ default -> this.genre = Genre.JAZZ;
+ case "classic" -> this.genre = Genre.CLASSIC;
+ case "hiphop" -> this.genre = Genre.HIPHOP;
+ case "rock" -> this.genre = Genre.ROCK;
+ case "pop" -> this.genre = Genre.POP;
+ case "rap" -> this.genre = Genre.RAP;
+ }
+ }
+
+ public String toString() {
+ return super.toString() + ", Genre = " + getGenre() + "\n";
+ }
+
+ public void createXMLElement(Document document, Element parentElement) {
+ // song element
+ Element song = document.createElement("song");
+
+ super.createXMLElement(document, song);
+
+ Element genreElement = document.createElement("genre");
+ genreElement.appendChild(document.createTextNode(genre.getGenre()));
+ song.appendChild(genreElement);
+
+ parentElement.appendChild(song);
+ }
+} \ No newline at end of file
diff --git a/src/main/java/musichub/main/Main.java b/src/main/java/musichub/main/Main.java
new file mode 100644
index 0000000..b72a95b
--- /dev/null
+++ b/src/main/java/musichub/main/Main.java
@@ -0,0 +1,248 @@
+package musichub.main;
+
+import musichub.business.*;
+
+import java.util.Iterator;
+import java.util.Scanner;
+
+public class Main {
+ public static void main(String[] args) {
+
+ MusicHub theHub = new MusicHub();
+
+ System.out.println("Type h for available commands");
+
+
+ Scanner scan = new Scanner(System.in);
+ String choice = scan.nextLine();
+
+ String albumTitle;
+
+ if (choice.length() == 0) System.exit(0);
+
+ while (!choice.equals("")) { //if the user puts nothing, quit the loop/system
+ switch (choice.charAt(0)) {
+ case 'q': //added the option directly in the switch instead of the loop
+ System.exit(0);
+ case 'h':
+ printAvailableCommands();
+ choice = scan.nextLine();
+ break;
+ case 't':
+ //album titles, ordered by date
+ System.out.println(theHub.getAlbumsTitlesSortedByDate());
+ printAvailableCommands();
+ choice = scan.nextLine();
+ break;
+ case 'g':
+ //songs of an album, sorted by genre
+ System.out.println("Songs of an album sorted by genre will be displayed; enter the album name, available albums are:");
+ System.out.println(theHub.getAlbumsTitlesSortedByDate());
+
+ albumTitle = scan.nextLine();
+ try {
+ System.out.println(theHub.getAlbumSongsSortedByGenre(albumTitle));
+ } catch (NoAlbumFoundException ex) {
+ System.out.println("No album found with the requested title " + ex.getMessage());
+ }
+ printAvailableCommands();
+ choice = scan.nextLine();
+ break;
+ case 'd':
+ //songs of an album
+ System.out.println("Songs of an album will be displayed; enter the album name, available albums are:");
+ System.out.println(theHub.getAlbumsTitlesSortedByDate());
+
+ albumTitle = scan.nextLine();
+ try {
+ System.out.println(theHub.getAlbumSongs(albumTitle));
+ } catch (NoAlbumFoundException ex) {
+ System.out.println("No album found with the requested title " + ex.getMessage());
+ }
+ printAvailableCommands();
+ choice = scan.nextLine();
+ break;
+ case 'u':
+ //audiobooks ordered by author
+ System.out.println(theHub.getAudiobooksTitlesSortedByAuthor());
+ printAvailableCommands();
+ choice = scan.nextLine();
+ break;
+ case 'c':
+ // add a new song
+ System.out.println("Enter a new song: ");
+ System.out.println("Song title: ");
+ String title = scan.nextLine();
+ System.out.println("Song genre (jazz, classic, hiphop, rock, pop, rap):");
+ String genre = scan.nextLine();
+ System.out.println("Song artist: ");
+ String artist = scan.nextLine();
+ System.out.println("Song length in seconds: ");
+ int length = Integer.parseInt(scan.nextLine());
+ System.out.println("Song content: ");
+ String content = scan.nextLine();
+ Song s = new Song(title, artist, length, content, genre);
+ theHub.addElement(s);
+ System.out.println("New element list: ");
+ Iterator<AudioElement> it = theHub.elements();
+ while (it.hasNext()) System.out.println(it.next().getTitle());
+ System.out.println("Song created!");
+ printAvailableCommands();
+ choice = scan.nextLine();
+ break;
+ case 'a':
+ // add a new album
+ System.out.println("Enter a new album: ");
+ System.out.println("Album title: ");
+ String aTitle = scan.nextLine();
+ System.out.println("Album artist: ");
+ String aArtist = scan.nextLine();
+ System.out.println("Album length in seconds: ");
+ int aLength = Integer.parseInt(scan.nextLine());
+ System.out.println("Album date as YYYY-DD-MM: ");
+ String aDate = scan.nextLine();
+ Album a = new Album(aTitle, aArtist, aLength, aDate);
+ theHub.addAlbum(a);
+ System.out.println("New list of albums: ");
+ Iterator<Album> ita = theHub.albums();
+ while (ita.hasNext()) System.out.println(ita.next().getTitle());
+ System.out.println("Album created!");
+ printAvailableCommands();
+ choice = scan.nextLine();
+ break;
+ case '+':
+ //add a song to an album:
+ System.out.println("Add an existing song to an existing album");
+ System.out.println("Type the name of the song you wish to add. Available songs: ");
+ Iterator<AudioElement> itae = theHub.elements();
+ while (itae.hasNext()) {
+ AudioElement ae = itae.next();
+ if (ae instanceof Song) System.out.println(ae.getTitle());
+ }
+ String songTitle = scan.nextLine();
+
+ System.out.println("Type the name of the album you wish to enrich. Available albums: ");
+ Iterator<Album> ait = theHub.albums();
+ while (ait.hasNext()) {
+ Album al = ait.next();
+ System.out.println(al.getTitle());
+ }
+ String titleAlbum = scan.nextLine();
+ try {
+ theHub.addElementToAlbum(songTitle, titleAlbum);
+ } catch (NoAlbumFoundException | NoElementFoundException ex) {
+ System.out.println(ex.getMessage());
+ }
+ System.out.println("Song added to the album!");
+ printAvailableCommands();
+ choice = scan.nextLine();
+ break;
+ case 'l':
+ // add a new audiobook
+ System.out.println("Enter a new audiobook: ");
+ System.out.println("AudioBook title: ");
+ String bTitle = scan.nextLine();
+ System.out.println("AudioBook category (youth, novel, theater, documentary, speech)");
+ String bCategory = scan.nextLine();
+ System.out.println("AudioBook artist: ");
+ String bArtist = scan.nextLine();
+ System.out.println("AudioBook length in seconds: ");
+ int bLength = Integer.parseInt(scan.nextLine());
+ System.out.println("AudioBook content: ");
+ String bContent = scan.nextLine();
+ System.out.println("AudioBook language (french, english, italian, spanish, german)");
+ String bLanguage = scan.nextLine();
+ AudioBook b = new AudioBook(bTitle, bArtist, bLength, bContent, bLanguage, bCategory);
+ theHub.addElement(b);
+ System.out.println("Audiobook created! New element list: ");
+ Iterator<AudioElement> itl = theHub.elements();
+ while (itl.hasNext()) System.out.println(itl.next().getTitle());
+ printAvailableCommands();
+ choice = scan.nextLine();
+ break;
+ case 'p':
+ //create a new playlist from existing elements
+ System.out.println("Add an existing song or audiobook to a new playlist");
+ System.out.println("Existing playlists:");
+ Iterator<PlayList> itpl = theHub.playlists();
+ while (itpl.hasNext()) {
+ PlayList pl = itpl.next();
+ System.out.println(pl.getTitle());
+ }
+ System.out.println("Type the name of the playlist you wish to create:");
+ String playListTitle = scan.nextLine();
+ PlayList pl = new PlayList(playListTitle);
+ theHub.addPlaylist(pl);
+ System.out.println("Available elements: ");
+
+ Iterator<AudioElement> itael = theHub.elements();
+ while (itael.hasNext()) {
+ AudioElement ae = itael.next();
+ System.out.println(ae.getTitle());
+ }
+ while (choice.charAt(0) != 'n') {
+ System.out.println("Type the name of the audio element you wish to add or 'n' to exit:");
+ String elementTitle = scan.nextLine();
+ try {
+ theHub.addElementToPlayList(elementTitle, playListTitle);
+ } catch (NoPlayListFoundException | NoElementFoundException ex) {
+ System.out.println(ex.getMessage());
+ }
+
+ System.out.println("Type y to add a new one, n to end");
+ choice = scan.nextLine();
+ }
+ System.out.println("Playlist created!");
+ printAvailableCommands();
+ choice = scan.nextLine();
+ break;
+ case '-':
+ //delete a playlist
+ System.out.println("Delete an existing playlist. Available playlists:");
+ Iterator<PlayList> itp = theHub.playlists();
+ while (itp.hasNext()) {
+ PlayList p = itp.next();
+ System.out.println(p.getTitle());
+ }
+ String plTitle = scan.nextLine();
+ try {
+ theHub.deletePlayList(plTitle);
+ } catch (NoPlayListFoundException ex) {
+ System.out.println(ex.getMessage());
+ }
+ System.out.println("Playlist deleted!");
+ printAvailableCommands();
+ choice = scan.nextLine();
+ break;
+ case 's':
+ //save elements, albums, playlists
+ theHub.saveElements();
+ theHub.saveAlbums();
+ theHub.savePlayLists();
+ System.out.println("Elements, albums and playlists saved!");
+ printAvailableCommands();
+ choice = scan.nextLine();
+ break;
+ default:
+
+ break;
+ }
+ }
+ scan.close();
+ }
+
+ private static void printAvailableCommands() {
+ System.out.println("t: display the album titles, ordered by date");
+ System.out.println("g: display songs of an album, ordered by genre");
+ System.out.println("d: display songs of an album");
+ System.out.println("u: display audiobooks ordered by author");
+ System.out.println("c: add a new song");
+ System.out.println("a: add a new album");
+ System.out.println("+: add a song to an album");
+ System.out.println("l: add a new audiobook");
+ System.out.println("p: create a new playlist from existing songs and audio books");
+ System.out.println("-: delete an existing playlist");
+ System.out.println("s: save elements, albums, playlists");
+ System.out.println("q: quit program");
+ }
+} \ No newline at end of file
diff --git a/src/main/java/musichub/util/XMLHandler.java b/src/main/java/musichub/util/XMLHandler.java
new file mode 100644
index 0000000..4b61842
--- /dev/null
+++ b/src/main/java/musichub/util/XMLHandler.java
@@ -0,0 +1,74 @@
+package musichub.util;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.File;
+import java.io.IOException;
+
+
+public class XMLHandler {
+ TransformerFactory transformerFactory;
+ Transformer transformer;
+ DocumentBuilderFactory documentFactory;
+ DocumentBuilder documentBuilder;
+
+ public XMLHandler() {
+ try {
+ transformerFactory = TransformerFactory.newInstance();
+ transformer = transformerFactory.newTransformer();
+ documentFactory = DocumentBuilderFactory.newInstance();
+ documentBuilder = documentFactory.newDocumentBuilder();
+ } catch (TransformerException | ParserConfigurationException tfe) {
+ tfe.printStackTrace();
+ }
+ }
+
+ public void createXMLFile(Document document, String filePath) {
+ try {
+ // create the xml file
+ //transform the DOM Object to an XML File
+ DOMSource domSource = new DOMSource(document);
+ StreamResult streamResult = new StreamResult(new File(filePath));
+
+ // If you use
+ // StreamResult result = new StreamResult(System.out);
+ // the output will be pushed to the standard output ...
+ // You can use that for debugging
+
+ transformer.transform(domSource, streamResult);
+
+ } catch (TransformerException tfe) {
+ tfe.printStackTrace();
+ }
+ }
+
+ public Document createXMLDocument() {
+ return documentBuilder.newDocument();
+ }
+
+ public NodeList parseXMLFile(String filePath) {
+ NodeList elementNodes = null;
+ try {
+ Document document = documentBuilder.parse(new File(filePath));
+ Element root = document.getDocumentElement();
+
+ elementNodes = root.getChildNodes();
+ } catch (SAXException | IOException e) {
+ e.printStackTrace();
+ }
+ return elementNodes;
+ }
+
+
+} \ No newline at end of file