package org.ntlab.featureExtractor; import java.io.BufferedReader; import java.io.IOException; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; public class MagnetronParser { public static Map<String, Object> doParse(BufferedReader reader) throws IOException, ExpectedLeftCurlyBraket, ExpectedRightCurlyBraket, ExpectedFeatures, ExpectedExtracts { return parseMagnetron(reader); } private static Map<String, Object> parseMagnetron(BufferedReader reader) throws IOException, ExpectedLeftCurlyBraket, ExpectedRightCurlyBraket, ExpectedFeatures, ExpectedExtracts { Map<String, Object> magnet = new HashMap<>(); String line = skipBlankLines(null, reader); if (line == null || !line.startsWith("{")) { throw new ExpectedLeftCurlyBraket(); } line = line.substring(1); line = parseKeyValue(line, reader, magnet); // Trace file name if (line == null || !line.startsWith(",")) throw new ExpectedFeatures(); line = line.substring(1); String keys[] = new String[1]; line = parseKey(line, reader, keys); if (line == null) new ExpectedFeatures(); if (keys[0].equals("format")) { // Trace file format Object[] values = new Object[1]; line = parseValue(line, reader, values); magnet.put("format", values[0]); // JSON or PlainText if (line == null || !line.startsWith(",")) throw new ExpectedFeatures(); line = line.substring(1); line = parseKey(line, reader, keys); if (line == null) new ExpectedFeatures(); } else { // JSON format is default. magnet.put("format", "JSON"); } // Features in the trace file if (!keys[0].equals("features")) new ExpectedFeatures(); List<Feature> freatures = new ArrayList<>(); line = parseFeatures(line, reader, freatures); magnet.put("features", freatures); return magnet; } private static String parseFeatures(String residual, BufferedReader reader, List<Feature> freatures) throws IOException, ExpectedLeftCurlyBraket, ExpectedRightCurlyBraket, ExpectedExtracts { residual = skipBlankLines(residual, reader); if (residual == null || !residual.startsWith("[")) { throw new ExpectedLeftCurlyBraket(); } residual = residual.substring(1); do { residual = parseFeature(residual, reader, freatures); residual = skipBlankLines(residual, reader); if (residual.startsWith(",")) { residual = residual.substring(1); continue; } } while (!residual.startsWith("]")); return residual.substring(1); } private static String parseFeature(String residual, BufferedReader reader, List<Feature> freatures) throws IOException, ExpectedLeftCurlyBraket, ExpectedRightCurlyBraket, ExpectedExtracts { residual = skipBlankLines(residual, reader); if (residual == null || !residual.startsWith("{")) { throw new ExpectedLeftCurlyBraket(); } residual = residual.substring(1); Feature feature = new Feature(); Map<String, Object> keyValue = new HashMap<>(); residual = parseKeyValue(residual, reader, keyValue); // Feature name feature.setName((String) keyValue.get("feature")); if (residual == null || !residual.startsWith(",")) throw new ExpectedExtracts(); residual = residual.substring(1); String keys[] = new String[1]; residual = parseKey(residual, reader, keys); // Features in the trace file if (residual == null || !keys[0].equals("extracts")) new ExpectedExtracts(); List<Extract> extracts = new ArrayList<>(); residual = parseExtracts(residual, reader, extracts); feature.setExtracts(extracts); freatures.add(feature); residual = skipBlankLines(residual, reader); if (residual == null || !residual.startsWith("}")) { throw new ExpectedRightCurlyBraket(); } return residual.substring(1); } private static String parseExtracts(String residual, BufferedReader reader, List<Extract> extracts) throws IOException, ExpectedLeftCurlyBraket, ExpectedRightCurlyBraket { residual = skipBlankLines(residual, reader); if (residual == null || !residual.startsWith("[")) { throw new ExpectedLeftCurlyBraket(); } residual = residual.substring(1); do { residual = parseExtract(residual, reader, extracts); residual = skipBlankLines(residual, reader); if (residual.startsWith(",")) { residual = residual.substring(1); continue; } } while (!residual.startsWith("]")); return residual.substring(1); } private static String parseExtract(String residual, BufferedReader reader, List<Extract> extracts) throws IOException, ExpectedLeftCurlyBraket, ExpectedRightCurlyBraket { residual = skipBlankLines(residual, reader); if (residual == null || !residual.startsWith("{")) { throw new ExpectedLeftCurlyBraket(); } Map<String, Object> object = new HashMap<>(); residual = parseObject(residual, reader, object); Map<String, Object> srcObject = (Map<String, Object>) object.get("src"); Map<String, Object> dstObject = (Map<String, Object>) object.get("dst"); int order = Integer.parseInt((String) object.get("order")); Extract extract = new Extract( (String) srcObject.get("id"), (String) srcObject.get("class"), (String) dstObject.get("id"), (String) dstObject.get("class"), (String) object.get("type"), order); extracts.add(extract); return residual; } private static String parseObject(String residual, BufferedReader reader, Map<String, Object>object) throws IOException, ExpectedLeftCurlyBraket, ExpectedRightCurlyBraket { residual = skipBlankLines(residual, reader); if (residual == null || !residual.startsWith("{")) { throw new ExpectedLeftCurlyBraket(); } residual = residual.substring(1); do { residual = parseKeyValue(residual, reader, object); if (residual == null) throw new ExpectedRightCurlyBraket(); residual = skipBlankLines(residual, reader); if (residual.startsWith(",")) { residual = residual.substring(1); continue; } } while (!residual.startsWith("}")); return residual.substring(1); } private static String parseKey(String residual, BufferedReader reader, String[] keys) throws IOException, ExpectedLeftCurlyBraket, ExpectedRightCurlyBraket { String line = skipBlankLines(residual, reader); if (line == null) return null; line = line.trim(); if (!line.startsWith("\"")) return null; String strings[] = line.split("\""); if (strings.length < 1) return null; String key = strings[1]; if (line.indexOf(":") < 0) return null; residual = line.substring(line.indexOf(":") + 1); keys[0] = key; return residual; } private static String parseKeyValue(String residual, BufferedReader reader, Map<String, Object> object) throws IOException, ExpectedLeftCurlyBraket, ExpectedRightCurlyBraket { String keys[] = new String[1]; residual = parseKey(residual, reader, keys); if (residual == null) return null; Object[] values = new Object[1]; residual = parseValue(residual, reader, values); object.put(keys[0], values[0]); return residual; } private static String parseValue(String residual, BufferedReader reader, Object[] values) throws IOException, ExpectedLeftCurlyBraket, ExpectedRightCurlyBraket { String line = skipBlankLines(residual, reader); line = line.trim(); if (line.startsWith("\"")) { line = line.substring(1); values[0] = line.substring(0, line.indexOf("\"")); residual = line.substring(line.indexOf("\"") + 1); } else if (line.startsWith("{")) { Map<String, Object>object = new HashMap<>(); residual = parseObject(line, reader, object); values[0] = object; } else if (line.startsWith("[")) { // To Do } else if (line.startsWith("null")) { residual = line.substring(4); values[0] = null; } else { // To Do } return residual; } private static String skipBlankLines(String residual, BufferedReader reader) throws IOException { String line = residual; if (line == null || line.equals("")) { do { line = reader.readLine(); if (line == null) break; line = line.trim(); } while (line.equals("")); } else { line = line.trim(); } return line; } }