package model.collector.lastfm; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import model.collector.Track; public class XMLTrackParser { /** * the logger */ private final Logger logger = Logger.getLogger(this.getClass().getName()); /** * the track */ private Track track; /** * gets the track * * @return the track */ public Track getTrack() { return this.track; } /** * Constructor * * @param url * the url where the xml code can be found * * @throws MalformedURLException * @throws XMLStreamException * @throws IOException */ public XMLTrackParser(String url) throws MalformedURLException, XMLStreamException, IOException { logger.log(Level.FINER, "parse track xml. URL: " + url); this.track = new Track(); XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader parser = factory.createXMLStreamReader(new URL(url).openStream()); extractTrack(parser); } /** * extracts the track * * @param parser * the parser * * @throws XMLStreamException */ private void extractTrack(XMLStreamReader parser) throws XMLStreamException { while (parser.hasNext()) { switch (parser.getEventType()) { case XMLStreamConstants.START_ELEMENT: { // check status first if (parser.getLocalName().equalsIgnoreCase("lfm")) { String status = "failed"; if (parser.getAttributeCount() > 0) status = parser.getAttributeValue(0); if (!status.equalsIgnoreCase("ok")) return; } else if (parser.getLocalName().equalsIgnoreCase("name")) { parser.next(); if (parser.getEventType() == XMLStreamConstants.CHARACTERS) this.track.setTitle(parser.getText()); logger.log(Level.FINER, "extract title: " + this.track.getTitle()); } else if (parser.getLocalName().equalsIgnoreCase("artist")) { extractArtist(parser); } else if (parser.getLocalName().equalsIgnoreCase("album")) { if (parser.getAttributeCount() > 0) this.track.setTrackNr(Integer.parseInt(parser.getAttributeValue(0))); logger.log(Level.FINER, "extract track#: " + this.track.getTrackNr()); extractAlbum(parser); } else if (parser.getLocalName().equalsIgnoreCase("tag")) { extractTags(parser); } break; } case XMLStreamConstants.END_ELEMENT: { break; } case XMLStreamConstants.END_DOCUMENT: { logger.log(Level.FINER, "Document finished"); parser.close(); return; } } parser.next(); } } /** * extracts the artist * * @param parser * the parser * * @throws XMLStreamException */ private void extractArtist(XMLStreamReader parser) throws XMLStreamException { while (parser.hasNext()) { switch (parser.getEventType()) { case XMLStreamConstants.START_ELEMENT: { if (parser.getLocalName().equalsIgnoreCase("name")) { parser.next(); if (parser.getEventType() == XMLStreamConstants.CHARACTERS) this.track.setArtist(parser.getText()); logger.log(Level.FINER, "extract artist name: " + this.track.getArtist()); } break; } case XMLStreamConstants.END_ELEMENT: { if (parser.getLocalName().equalsIgnoreCase("artist")) { return; } break; } } parser.next(); } } /** * extracts the album * * @param parser * the parser * * @throws XMLStreamException */ private void extractAlbum(XMLStreamReader parser) throws XMLStreamException { while (parser.hasNext()) { switch (parser.getEventType()) { case XMLStreamConstants.START_ELEMENT: { if (parser.getLocalName().equalsIgnoreCase("artist")) { parser.next(); // artist doesnt match -> no album if (parser.getEventType() == XMLStreamConstants.CHARACTERS) { if (!parser.getText().equalsIgnoreCase(this.track.getArtist())) { this.track.setTrackNr(-1); return; } } } else if (parser.getLocalName().equalsIgnoreCase("title")) { parser.next(); if (parser.getEventType() == XMLStreamConstants.CHARACTERS) this.track.setAlbum(parser.getText()); logger.log(Level.FINER, "extract album name: " + this.track.getAlbum()); } break; } case XMLStreamConstants.END_ELEMENT: { if (parser.getLocalName().equalsIgnoreCase("album")) { return; } break; } } parser.next(); } } /** * extracts the tag * * @param parser * the parser * * @throws XMLStreamException */ private void extractTags(XMLStreamReader parser) throws XMLStreamException { while (parser.hasNext()) { switch (parser.getEventType()) { case XMLStreamConstants.START_ELEMENT: { if (parser.getLocalName().equalsIgnoreCase("name")) { parser.next(); String tag = ""; if (parser.getEventType() == XMLStreamConstants.CHARACTERS) tag = parser.getText(); this.track.addTag(tag); logger.log(Level.FINER, "added Tag: " + tag); } break; } case XMLStreamConstants.END_ELEMENT: { if (parser.getLocalName().equalsIgnoreCase("tag")) { return; } break; } } parser.next(); } } }