• MyTrackCSVReader.java

  • §
    package MusicLandscape.util.io;
    
    import MusicLandscape.entities.Artist;
    import MusicLandscape.entities.Track;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.util.Scanner;
    import java.util.regex.Pattern;
  • §

    This class is the same as in ES06, except it skips empty lines in CSV files now.

    /**
     * Class for reading a Track from a CSV input.
     * <p>
     * The order of the Track fields in the CSV line must be:
     *
     * <ol>
     *     <li>Title</li>
     *     <li>Writer</li>
     *     <li>Performer</li>
     *     <li>Duration</li>
     *     <li>Year</li>
     * </ol>
     *
     * @author Jonas Altrock (ew20b126@technikum-wien.at)
     * @version 1
     * @since ExerciseSheet06
     */
    public class MyTrackCSVReader extends MyReader<Track> {
        /**
         * CSV field delimiter.
         */
        private static final String delimiter = ",|$";
    
        /**
         * Regular expression pattern for a quoted string field.
         */
        private static final Pattern quotedString = Pattern.compile("\"(\\\\\"|[^\"])*?\"");
    
        /**
         * Regular expression for whitespace.
         */
        private static final Pattern whitespace = Pattern.compile("\\p{javaWhitespace}*");
    
        /**
         * constructs a MyCSVTrackReader from a Buffered Reader.<br>
         * the underlying stream cannot be null. In case a null object is passed to
         * this constructor an IllegalArgumentException including
         * a custom message "expected non-null ReaderObject" is thrown.
         *
         * @param in the underlying stream
         */
        public MyTrackCSVReader(BufferedReader in) {
            super(in);
        }
    
        /**
         * reads the current line of the BufferedReader, displays it as is at the console and returns the contained Track
         * of this line<br>
         * displays "Error reading." in case of an IOException<br>
         * displays "Error parsing." in case of any other exception
         *
         * @return Track in case a new Track was created successfully, null otherwise
         */
        @Override
        public Track get() {
            String line = "";
    
            try {
                line = in.readLine();
    
                if (line == null || line.isEmpty()) {
                    return null;
                }
    
                Scanner scan = new Scanner(line).useDelimiter(delimiter);
    
                Track t = new Track();
                t.setTitle(nextMaybeQuoted(scan));
                t.setWriter(new Artist(nextMaybeQuoted(scan)));
                t.setPerformer(new Artist(nextMaybeQuoted(scan)));
                t.setDuration(nextInt(scan));
                t.setYear(nextInt(scan));
                return t;
            } catch (IOException e) {
                System.out.println("Error reading.");
            } catch (Exception e) {
                System.out.println(line + "Error parsing.");
            }
    
            return null;
        }
    
        /**
         * Read a possibly quoted string field from the scanner.
         *
         * @param s the scanner to use
         * @return the text of the next field
         */
        private String nextMaybeQuoted(Scanner s) {
            String r = null;
  • §

    imposed by MyWriterTest: skip leading whitespace

            s.skip(whitespace);
    
            if (s.hasNext("\\\".*")) {
                r = s.findInLine(quotedString);
    
                if (r != null) {
                    r = r.substring(1, r.length() - 1).replaceAll("\\\\\"", "\"");
                }
            } else if (s.hasNext()) {
                r = s.next().trim();
            }
    
            s.skip(s.delimiter());
            return r;
        }
    
        /**
         * Read an integer field.
         *
         * @param s the scanner to use
         * @return the next field as an integer
         */
        private int nextInt(Scanner s) {
  • §

    imposed by MyWriterTest: skip leading whitespace

            s.skip(whitespace);
            int r = s.nextInt();
            s.skip(s.delimiter());
            return r;
        }
    }