/** * Parse the non-standard REM COMMENT command. * <p/> * REM COMMENT [comment] * * @param input */ private static void parseRemComment(final LineOfInput input) { CueParser.logger.entering(CueParser.class.getCanonicalName(), "parseRemComment(LineOfInput)", input); Matcher matcher = PATTERN_REM_COMMENT.matcher(input.getInput()); if (matcher.find()) { String comment = matcher.group(2); if (comment.charAt(0) == '"' && comment.charAt(comment.length() - 1) == '"') { comment = comment.substring(1, comment.length() - 1); } input.getAssociatedSheet().setComment(comment); } else { addWarning(input, WARNING_UNPARSEABLE_INPUT); } CueParser.logger.exiting(CueParser.class.getCanonicalName(), "parseRemComment(LineOfInput)"); }
/** * Parse the non-standard REM GENRE command. * <p/> * REM GENRE [genre] * * @param input */ private static void parseRemGenre(final LineOfInput input) { CueParser.logger.entering(CueParser.class.getCanonicalName(), "parseRemGenre(LineOfInput)", input); Matcher matcher = PATTERN_REM_GENRE.matcher(input.getInput()); if (matcher.find()) { String genre = matcher.group(2); if (genre.charAt(0) == '"' && genre.charAt(genre.length() - 1) == '"') { genre = genre.substring(1, genre.length() - 1); } input.getAssociatedSheet().setGenre(genre); } else { addWarning(input, WARNING_UNPARSEABLE_INPUT); } CueParser.logger.exiting(CueParser.class.getCanonicalName(), "parseRemGenre(LineOfInput)"); }
/** * Determine if the input contains the specified pattern. Will return true if it matches. If there is a match and * and there is a capturing group, then the first such group will be checked for case. If it is not uppercase, * then a "TOKEN NOT UPPERCASE" warning will be added to the cue sheet associated with the input. * * @param input The input to check. * @param pattern {@link java.util.regex.Pattern} to check for. If it contains a capturing group, then on a match, * this group will be * checked for case as per the method description. * @return True if there is a match. False otherwise. */ private static boolean contains(final LineOfInput input, final Pattern pattern) { CueParser.logger.entering (CueParser.class.getCanonicalName(), "contains(LineOfInput,Pattern)", new Object[]{input, pattern}); final Matcher matcher = pattern.matcher(input.getInput()); if (matcher.find()) { if (matcher.groupCount() > 0 && !matcher.group(1).equals(matcher.group(1).toUpperCase())) { addWarning(input, WARNING_TOKEN_NOT_UPPERCASE); } CueParser.logger.exiting(CueParser.class.getCanonicalName(), "contains(LineOfInput,Pattern)", true); return true; } else { CueParser.logger.exiting(CueParser.class.getCanonicalName(), "contains(LineOfInput,Pattern)", false); return false; } }
/** * Determine if the input starts with some string. Will return true if it matches, regardless of case. If there is * a match, but the case differs, then a "TOKEN NOT UPPERCASE" warning will be added to the cue sheet associated * with the input. * * @param input The input to check. * @param start The starting string to check for. Should be uppercase, or else the warning will not make sense. * @return True if there is a match. False otherwise. */ private static boolean startsWith(final LineOfInput input, final String start) { CueParser.logger.entering (CueParser.class.getCanonicalName(), "startsWith(LineOfInput,String)", new Object[]{input, start}); if (input.getInput().startsWith(start)) { CueParser.logger.exiting(CueParser.class.getCanonicalName(), "startsWith(LineOfInput,String)", true); return true; } else if (input.getInput().substring(0, start.length()).equalsIgnoreCase(start)) { addWarning(input, WARNING_TOKEN_NOT_UPPERCASE); CueParser.logger.exiting(CueParser.class.getCanonicalName(), "startsWith(LineOfInput,String)", true); return true; } else { CueParser.logger.exiting(CueParser.class.getCanonicalName(), "startsWith(LineOfInput,String)", false); return false; } }
/** * Parse the non-standard REM DISCID command. * <p/> * REM DISCID [discid] * * @param input */ private static void parseRemDiscid(final LineOfInput input) { CueParser.logger.entering(CueParser.class.getCanonicalName(), "parseRemDiscid(LineOfInput)", input); Matcher matcher = PATTERN_REM_DISCID.matcher(input.getInput()); if (matcher.find()) { String discid = matcher.group(2); if (discid.charAt(0) == '"' && discid.charAt(discid.length() - 1) == '"') { discid = discid.substring(1, discid.length() - 1); } input.getAssociatedSheet().setDiscid(discid); } else { addWarning(input, WARNING_UNPARSEABLE_INPUT); } CueParser.logger.exiting(CueParser.class.getCanonicalName(), "parseRemDiscid(LineOfInput)"); }
/** * Create a new MessageImplementation. * @param type The type of the message. * @param lineOfInput The line of input that this message applies to. * @param message The message text. */ public MessageImplementation(final String type, final LineOfInput lineOfInput, final String message) { MessageImplementation.logger.entering ( MessageImplementation.class.getCanonicalName() , "MessageImplementation(String,LineOfInput,String)" , new Object[] {type, lineOfInput, message} ); this.input = lineOfInput.getInput(); this.lineNumber = lineOfInput.getLineNumber(); this.message = message; this.type = type; MessageImplementation.logger.exiting (MessageImplementation.class.getCanonicalName(), "MessageImplementation(String,LineOfInput,String)"); }
/** * Parse the non-standard REM DATE command. * <p/> * REM DATE [year] * * @param input */ private static void parseRemDate(final LineOfInput input) { CueParser.logger.entering(CueParser.class.getCanonicalName(), "parseRemDate(LineOfInput)", input); Matcher matcher = PATTERN_REM_DATE.matcher(input.getInput()); if (matcher.find()) { int year = Integer.parseInt(matcher.group(2)); if (year < 1 || year > 9999) { addWarning(input, WARNING_INVALID_YEAR); } input.getAssociatedSheet().setYear(year); } else { addWarning(input, WARNING_UNPARSEABLE_INPUT); } CueParser.logger.exiting(CueParser.class.getCanonicalName(), "parseRemDate(LineOfInput)"); }
/** * Parse the CDTEXTFILE command. * <p/> * CDTEXTFILE [filename] * File that contains cd text data. Not mandatory. * * @param input */ private static void parseCdTextFile(final LineOfInput input) { CueParser.logger.entering(CueParser.class.getCanonicalName(), "parseCdTextFile(LineOfInput)", input); Matcher cdTextFileMatcher = PATTERN_CDTEXTFILE.matcher(input.getInput()); if (startsWith(input, "CDTEXTFILE") && cdTextFileMatcher.matches()) { if (input.getAssociatedSheet().getCdTextFile() != null) { CueParser.logger.warning(WARNING_DATUM_APPEARS_TOO_OFTEN); input.getAssociatedSheet().addWarning(input, WARNING_DATUM_APPEARS_TOO_OFTEN); } // If the file name is enclosed in quotes, remove those. String file = cdTextFileMatcher.group(1); if (file.length() > 0 && file.charAt(0) == '"' && file.charAt(file.length() - 1) == '"') { file = file.substring(1, file.length() - 1); } input.getAssociatedSheet().setCdTextFile(file); } else { addWarning(input, WARNING_UNPARSEABLE_INPUT); } CueParser.logger.exiting(CueParser.class.getCanonicalName(), "parseCdTextFile(LineOfInput)"); }
CueParser.logger.entering(CueParser.class.getCanonicalName(), "parseFile(LineOfInput)", input); Matcher fileMatcher = PATTERN_FILE.matcher(input.getInput());
/** * Parse the CATALOG command. * <p/> * CATALOG [media-catalog-number] * CD catalog number. Code follows UPC/EAN rules. * Usually the first command, but this is not required. Not a mandatory command. * * @param input */ private static void parseCatalog(final LineOfInput input) { CueParser.logger.entering(CueParser.class.getCanonicalName(), "parseCatalog(LineOfInput)", input); if (startsWith(input, "CATALOG")) { String catalogNumber = input.getInput().substring("CATALOG".length()).trim(); if (!PATTERN_CATALOG_NUMBER.matcher(catalogNumber).matches()) { addWarning(input, WARNING_INVALID_CATALOG_NUMBER); } if (input.getAssociatedSheet().getCatalog() != null) { addWarning(input, WARNING_DATUM_APPEARS_TOO_OFTEN); } input.getAssociatedSheet().setCatalog(catalogNumber); } else { addWarning(input, WARNING_UNPARSEABLE_INPUT); } CueParser.logger.exiting(CueParser.class.getCanonicalName(), "parseCatalog(LineOfInput)"); }
/** * Parse the POSTGAP command. * <p/> * POSTGAP [mm:ss:ff] * Must come after all INDEX fields for a track. Only one per track allowed. * * @param input */ private static void parsePostgap(final LineOfInput input) { CueParser.logger.entering(CueParser.class.getCanonicalName(), "parsePostgap(LineOfInput)", input); Matcher postgapMatcher = PATTERN_POSTGAP.matcher(input.getInput()); if (startsWith(input, "POSTGAP") && postgapMatcher.matches()) { TrackData trackData = getLastTrackData(input); if (trackData.getPostgap() != null) { addWarning(input, WARNING_DATUM_APPEARS_TOO_OFTEN); } trackData.setPostgap(parsePosition(input, postgapMatcher.group(1))); } else { addWarning(input, WARNING_UNPARSEABLE_INPUT); } CueParser.logger.exiting(CueParser.class.getCanonicalName(), "parsePostgap(LineOfInput)"); }
CueParser.logger.entering(CueParser.class.getCanonicalName(), "parseFlags(LineOfInput)", input); Matcher flagsMatcher = PATTERN_FLAGS.matcher(input.getInput());
CueParser.logger.entering(CueParser.class.getCanonicalName(), "parseTrack(LineOfInput)", input); Matcher trackMatcher = PATTERN_TRACK.matcher(input.getInput());
/** * Parse the PREGAP command. * <p/> * PREGAP [mm:ss:ff] * Must come after TRACK, but before INDEX fields for that track. * * @param input */ private static void parsePregap(final LineOfInput input) { CueParser.logger.entering(CueParser.class.getCanonicalName(), "parsePregap(LineOfInput)", input); Matcher pregapMatcher = PATTERN_PREGAP.matcher(input.getInput()); if (startsWith(input, "PREGAP") && pregapMatcher.matches()) { TrackData trackData = getLastTrackData(input); if (trackData.getPregap() != null) { addWarning(input, WARNING_DATUM_APPEARS_TOO_OFTEN); } if (trackData.getIndices().size() > 0) { addWarning(input, WARNING_PREGAP_IN_WRONG_PLACE); } trackData.setPregap(parsePosition(input, pregapMatcher.group(1))); } else { addWarning(input, WARNING_UNPARSEABLE_INPUT); } CueParser.logger.exiting(CueParser.class.getCanonicalName(), "parsePregap(LineOfInput)"); }
/** * Parse the ISRC command. * <p/> * ISRC [code] * International Standard Recording Code of track. Must come after TRACK, but before INDEX. * * @param input */ private static void parseIsrc(final LineOfInput input) { CueParser.logger.entering(CueParser.class.getCanonicalName(), "parseIsrc(LineOfInput)", input); if (startsWith(input, "ISRC")) { String isrcCode = input.getInput().substring("ISRC".length()).trim(); if (!PATTERN_ISRC_CODE.matcher(isrcCode).matches()) { addWarning(input, WARNING_NONCOMPLIANT_ISRC_CODE); } TrackData trackData = getLastTrackData(input); if (trackData.getIndices().size() > 0) { addWarning(input, WARNING_ISRC_IN_WRONG_PLACE); } if (trackData.getIsrcCode() != null) { addWarning(input, WARNING_DATUM_APPEARS_TOO_OFTEN); } trackData.setIsrcCode(isrcCode); } else { addWarning(input, WARNING_UNPARSEABLE_INPUT); } CueParser.logger.exiting(CueParser.class.getCanonicalName(), "parseIsrc(LineOfInput)"); }
CueParser.logger.entering(CueParser.class.getCanonicalName(), "parseIndex(LineOfInput)", input); Matcher indexMatcher = PATTERN_INDEX.matcher(input.getInput());
CueParser.logger.entering(CueParser.class.getCanonicalName(), "parsePerformer(LineOfInput)", input); Matcher performerMatcher = PATTERN_PERFORMER.matcher(input.getInput());
CueParser.logger.entering(CueParser.class.getCanonicalName(), "parseSongwriter(LineOfInput)", input); Matcher songwriterMatcher = PATTERN_SONGWRITER.matcher(input.getInput());
CueParser.logger.entering(CueParser.class.getCanonicalName(), "parseTitle(LineOfInput)", input); Matcher titleMatcher = PATTERN_TITLE.matcher(input.getInput());
String comment = input.getInput().substring("REM".length()).trim();