package folioxml.export; import folioxml.config.*; import folioxml.core.InvalidMarkupException; import folioxml.folio.FolioTokenReader; import folioxml.slx.ISlxTokenReader; import folioxml.slx.SlxRecord; import folioxml.slx.SlxRecordReader; import folioxml.tools.OutputRedirector; import folioxml.translation.SlxTranslatingReader; import folioxml.xml.SlxToXmlTransformer; import folioxml.xml.XmlRecord; import java.io.*; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.HashMap; import java.util.List; import java.util.Map; public class InfobaseSetVisitor implements LogStreamProvider { public InfobaseSetVisitor(InfobaseSet set, List<InfobaseSetPlugin> plugins) { this.set = set; this.plugins = plugins; if (set.getObject("logs") != null) { Map<String, Object> logs = (Map<String, Object>) set.getObject("logs"); for (Map.Entry<String, Object> pair : logs.entrySet()) { if (pair.getValue() instanceof Boolean) { if ((Boolean) pair.getValue() == false) log_stream_merges.put(pair.getKey(), null); } else if (pair.getValue() instanceof String) { log_stream_merges.put(pair.getKey(), (String) pair.getValue()); } } } } Map<String, String> log_stream_merges = new HashMap<String, String>(); List<InfobaseSetPlugin> plugins; InfobaseSet set; Path baseLogPath; Map<String, Writer> openLogs = new HashMap<String, Writer>(); public void complete() throws UnsupportedEncodingException, FileNotFoundException, InvalidMarkupException, IOException { closeLogs(); ExportLocations export = set.generateExportLocations(); baseLogPath = export.getLocalPath("log_", AssetType.Text, FolderCreation.CreateParents); Path logPath = export.getLocalPath("log.txt", AssetType.Text, FolderCreation.CreateParents); OutputRedirector redir = new OutputRedirector(logPath.toString()); redir.open(); //Plugin hooks for (InfobaseSetPlugin p : plugins) p.beginInfobaseSet(set, export, this); ISlxTokenReader slxReader = null; int recordCount = 0; long tokenCount = 0; try { for (InfobaseConfig conf : set.getInfobases()) { System.out.println("Opening infobase " + conf.getFlatFilePath()); //Plugin hooks for (InfobaseSetPlugin p : plugins) p.beginInfobase(conf); //Open reader FolioTokenReader ftr = new FolioTokenReader(new File(conf.getFlatFilePath())); //Folio-to-xml translating reader may need to be wrapped slxReader = new SlxTranslatingReader(ftr); for (InfobaseSetPlugin p : plugins) slxReader = p.wrapSlxReader(slxReader); //Record reader SlxRecordReader srr = new SlxRecordReader(slxReader, null); XmlRecord root = null; SlxRecord r = null; int recordsRead = 0; while ((r = srr.read()) != null) { r.getHeading(); //Causes Slx to be evaluated, caches result in heading="" attribute //onSlxRecordParsed for (InfobaseSetPlugin p : plugins) p.onSlxRecordParsed(r); XmlRecord rx = new SlxToXmlTransformer().convert(r); //onRecordTransformed for (InfobaseSetPlugin p : plugins) p.onRecordTransformed(rx, r); FileNode fn = null; //assignFileNode for (InfobaseSetPlugin p : plugins) { FileNode temp = p.assignFileNode(rx, r); if (temp != null) { fn = temp; break; } } //onRecordComplete for (InfobaseSetPlugin p : plugins) p.onRecordComplete(rx, fn); if (r.isRootRecord()) { root = rx; } else { recordsRead++; } } getNamedStream("rootnode") .append("\nRoot node\n") .append(root.toXmlString(true)); //endInfobase for (InfobaseSetPlugin p : plugins) p.endInfobase(conf); tokenCount += ftr.tokensRead; recordCount += recordsRead; System.out.printf("Visited %s records and %s tokens from %s.\n", recordCount, tokenCount, conf.getFlatFilePath()); } System.out.printf("Read %s records and %s tokens from %s infobases.\n", recordCount, tokenCount, set.getInfobases().size()); //Plugin hooks for (InfobaseSetPlugin p : plugins) p.endInfobaseSet(set); } finally { if (slxReader != null) slxReader.close(); redir.close(); closeLogs(); } } @Override public Appendable getNamedStream(String name) throws IOException { if (log_stream_merges.containsKey(name)) { name = log_stream_merges.get(name); if (name == null) return new NilAppendable(); } if (!openLogs.containsKey(name)) { BufferedWriter bw = Files.newBufferedWriter(Paths.get(baseLogPath + name + ".txt"), Charset.forName("UTF-8"), StandardOpenOption.WRITE, StandardOpenOption.APPEND, StandardOpenOption.CREATE); openLogs.put(name, bw); } return openLogs.get(name); } private class NilAppendable implements Appendable { @Override public Appendable append(CharSequence csq) throws IOException { return this; } @Override public Appendable append(CharSequence csq, int start, int end) throws IOException { return this; } @Override public Appendable append(char c) throws IOException { return this; } } void closeLogs() throws IOException { for (Map.Entry<String, Writer> e : openLogs.entrySet()) { e.getValue().close(); } openLogs.clear(); } }