package org.korsakow.domain.k3.parser; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.log4j.Logger; import org.korsakow.domain.k3.K3Project; import org.korsakow.domain.k3.K3ProjectSettings; import org.korsakow.domain.k3.K3RatingCalculator; import org.korsakow.domain.k3.K3Rule; import org.korsakow.domain.k3.K3Snu; import org.korsakow.domain.k3.code.K3Symbol; import org.korsakow.ide.util.FileUtil; /** * File format is flakey, so parsing is leaninent. * @author d * */ public class K3DatabaseParser { public K3Project parse(File file) throws K3ParserException, IOException { LineContext context = new LineContext(); context.lines = FileUtil.readFileLines(file); K3ProjectSettings settings = new K3ProjectSettings(); context.gotoLine(14); parseSettings(context, settings); List<K3Snu> snus = new ArrayList<K3Snu>(); context.gotoLine(24); while (context.hasNextLine()) { String next = context.peekNextLine(); // satellite section if (next.startsWith("#") && next.contains("#LOOP#")) { // currently we just skip it context.nextLine(); context.nextLine(); while (!context.currentLine().startsWith("#")) context.nextLine(); continue; } snus.add(parseSnu(context)); } K3Project project = new K3Project(); project.settings = settings; project.snus = snus; return project; } private static K3Snu parseSnu(LineContext context) throws K3ParserException { K3ParseUtil parseHelper = new K3ParseUtil(context); if (!context.nextLine().startsWith("#")) throw new K3ParserException("expected '#', found: '" + context.currentLine() + "'"); K3Snu snu = new K3Snu(); // line 1 String line1 = context.nextLine(); // System.out.println(line1); String[] bits = line1.split(","); if (bits.length > 0) snu.filename = parseHelper.parseString(bits[0]); if (bits.length > 1) snu.foldername = parseHelper.parseString(bits[1]); if (bits.length > 2) snu.lives = parseHelper.specialNullValue( parseHelper.parseLong(bits[2]), 999L); if (bits.length > 3) snu.backgroundSoundEnabled = parseHelper.parseBooleanPrefix(bits[3], "s"); if (bits.length > 4) snu.duration = parseHelper.parseLong(bits[4]); if (bits.length > 5) snu.looping = parseHelper.parseBooleanPrefix(bits[5], "l"); // line 2 String line2 = context.nextLine(); bits = line2.split(","); if (bits.length > 0) snu.previewText = parseHelper.parseString(bits[0]); if (bits.length > 1) snu.insertText = parseHelper.parseString(bits[1]); context.nextLine(); // rLink snu.movieRating = (float)K3RatingCalculator.calculate(parseHelper.parseFloat(context.nextLine())); context.nextLine(); // _sing/NL String line = ""; while (context.hasNextLine()) { line = context.nextLine(); if (line.startsWith("#")) break; bits = line.split(","); long time = (long)(parseHelper.parseFloat(bits[0].trim().split(" ")[0]) * 1000); // db file is in seconds Long maxLinks = (long)(parseHelper.parseFloat(bits[1].trim().split(" ")[0])); if (maxLinks == 0) // 0 means no max maxLinks = null; String code = ""; K3Rule rule = new K3Rule(); for (int i = 2; i < bits.length; ++i) code += bits[i] + K3Symbol.DEFAULT_WHITESPACE_STRING; rule.lineNumber = context.currentLine; rule.time = time; rule.maxLinks = maxLinks; rule.code = code; snu.rules.add(rule); } if (!line.startsWith("#")) throw new K3ParserException("expected '#', found: '" + line + "'"); return snu; } private static void parseSettings(LineContext context, K3ProjectSettings settings) throws K3ParserException { K3ParseUtil parseHelper = new K3ParseUtil(context); // first configuration line String settingsLine1 = context.nextLine(); String[] parts = settingsLine1.split(","); if (parts.length <= 29) throw new K3ParserException("missing first configuration line", context.currentLine+1); settings.startFilmFilename = parseHelper.parseString(parts[0]); settings.startFilmFoldername = parseHelper.parseString(parts[1]); settings.logWindow = parseHelper.parseString(parts[2]); settings.movieRatingFactor = parseHelper.parseFloat(parts[3]); settings.automaticClick = parseHelper.parseBooleanValue(parts[4], "clicklessMouseAn"); settings.unknown16_6 = parseHelper.parseString(parts[5]); settings.keepOldLinksIfNoNewLinks = parseHelper.parseBooleanValue(parts[6], "ruecktrittAn"); settings.randomLinkMode = parseHelper.parseBooleanValue(parts[7], "randomLinkAn"); settings.endFilmFilename = parseHelper.parseString(parts[8]); settings.endFilmFoldername = parseHelper.parseString(parts[9]); settings.randomLinkIcon = parseHelper.parseString(parts[10]); settings.unknown16_12 = parseHelper.parseString(parts[11]); settings.unknown16_13 = parseHelper.parseString(parts[12]); settings.pseudoRandomLink = parseHelper.parseString(parts[13]); settings.presentationMode = parseHelper.parseBooleanPrefix(parts[14], "PresMode="); settings.positiveLinking = parseHelper.parseBooleanPrefix(parts[15], "posLink"); settings.kairoSpecialSetting = parseHelper.parseBooleanPrefix(parts[16], "kairo="); settings.videoWidth = parseHelper.parseInt(parts[17]); settings.videoHeight = parseHelper.parseInt(parts[18]); settings.subtitles = parseHelper.parseString(parts[19]); settings.stageWidth = parseHelper.parseInt(parts[20]); settings.stageHeight = parseHelper.parseInt(parts[21]); settings.backgroundColor = parseHelper.parseInt(parts[22], "BgCol"); settings.foregroundColor = parseHelper.parseInt(parts[23], "FoCol"); settings.insertTextColor = parseHelper.specialNullValue( parseHelper.parseInt(parts[24], "iTxtC"), 999 ); settings.insertTextFontFamily = parseHelper.specialNullValue( parseHelper.parseStringPrefix(parts[25], "iTxtF"), "999" ); settings.previewTextColor = parseHelper.specialNullValue( parseHelper.parseInt(parts[26], "PTxtC"), 999 ); settings.previewTextFontFamily = parseHelper.specialNullValue( parseHelper.parseStringPrefix(parts[27], "PTxtF"), "999" ); settings.subtitleTextColor = parseHelper.specialNullValue( parseHelper.parseInt(parts[28], "STxtC"), 999 ); settings.subtitleTextFontFamily = parseHelper.specialNullValue( parseHelper.parseStringPrefix(parts[29], "STxtF"), "999" ); // second configuration line String settingsLine2 = context.nextLine(); parts = settingsLine2.split(","); if (parts.length > 0) settings.insertTextSize = parseHelper.parseInt(parts[0], "iTxtS"); if (parts.length > 1) settings.previewTextSize = parseHelper.parseInt(parts[1], "PTxtS"); if (parts.length > 2) settings.subtitleTextSize = parseHelper.parseInt(parts[2], "STxtS"); if (parts.length > 3) settings.link3Lines = parseHelper.parseBooleanPrefix(parts[3], "3Link3Lines="); if (parts.length > 4) settings.use3LinkInterface = parseHelper.parseBooleanPrefix(parts[4], "3Link="); if (parts.length > 5) settings.delayValue = parseHelper.parseInt(parts[5], "delayValue="); if (parts.length > 6) settings.loopSnus = parseHelper.parseBooleanPrefix(parts[6], "loopMain="); try {// version compatibility if (parts.length > 7) settings.loopPreviews = parseHelper.parseBooleanPrefix(parts[7], "prvwL="); } catch (K3ParserException e) { if (parts.length > 7) settings.loopPreviews = parseHelper.parseBooleanPrefix(parts[7], "loopPreview="); } if (parts.length > 8) settings.satelliteMode = parseHelper.parseBooleanPrefix(parts[8], "sat="); if (parts.length > 9) settings.backgroundSound = parseHelper.parseBooleanPrefix(parts[9], "BGsound="); if (parts.length > 10) settings.backgroundSoundVolume = parseHelper.parseInt(parts[10], "vol=")/255.0f; if (parts.length > 11) settings.chair = parseHelper.parseBooleanPrefix(parts[11], "chair="); if (parts.length > 12) settings.unknown17_13 = parseHelper.parseStringPrefix(parts[12], "TmRel="); if (parts.length > 13) settings.saveHistory = parseHelper.parseBoolean(parts[13].substring(parts[13].length()-1)); // this one is prefixed by a random number WTF!!!!! if (parts.length > 14) settings.databaseHistory = parts[14]; if (parts.length > 15) settings.manyLinkPreviewWidth = parseHelper.parseInt(parts[15], "iconW"); if (parts.length > 16) settings.manyLinkPreviewHeight = parseHelper.parseInt(parts[16], "iconH"); if (parts.length > 17) settings.unknown17_18 = parts[17]; if (parts.length > 18) settings.satelliteId = parts[18]; if (parts.length > 19) settings.unknown17_20 = parts[19]; if (parts.length > 20) settings.unknown17_21 = parts[20]; if (parts.length > 21) settings.unknown17_22 = parts[21]; if (parts.length > 22) settings.useSnuAsPreview = parseHelper.parseBooleanPrefix(parts[22], "mPrev"); if (parts.length > 23) settings.manyLinkMaxLinks = parseHelper.parseInt(parts[23], "MaxLnk"); if (parts.length > 24) settings.useNewInterface = parseHelper.parseBooleanPrefix(parts[24], "NEWi"); if (parts.length > 25) settings.autoLinkMode = parseHelper.parseBooleanPrefix(parts[25], "AuLi"); if (parts.length > 26) settings.autoLinkTimeout = parseHelper.parseInt(parts[26], "AuLiNach"); } }