package ru.csu.stan.ui.code; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.text.MessageFormat; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; /** * Класс, определяющий файл исходного кода, в котором необходимо расставить якоря для навигации. * Позволяет обработать исходный файл и вывести результат в JavaScript-файл. * * @author mz * */ public class SourceFile { private String filename; private List<Anchor> anchorList = new LinkedList<Anchor>(); private static final String LINE_SEPARATOR = System.getProperty("line.separator"); private static final String JS_LINE_SEPARATOR = "\\n\\"; private static final String JS_FUNCTION_BEGIN_TEMPLATE = "sourceFiles.{0} = function()'{'\n return \""; private static final String JS_FUNCTION_END = "\";\n}\n"; private static final String JS_ENSURE_PACKAGE_EXIST = "if (typeof sourceFiles.{0} == 'undefined')\n sourceFiles.{0} = '{}';\n\n"; private SourceFile(String filename) { this.filename = filename; } static SourceFile getInstance(String filename){ return new SourceFile(filename); } public String getFilename() { return filename; } public void setFilename(String filename) { this.filename = filename; } public List<Anchor> getAnchorList() { return anchorList; } public void addAnchor(Anchor anchor) { this.anchorList.add(anchor); } public void createAnchor(int line, int col, String name, String id){ addAnchor(Anchor.createInstance(line, col, name, id)); } public void processFile(File src, File dst) throws FileNotFoundException, IOException{ if (anchorList.isEmpty()) return; Collections.sort(anchorList, new AnchorComparator()); BufferedReader reader = new BufferedReader(new FileReader(src)); BufferedWriter writer = new BufferedWriter(new FileWriter(dst)); String line; int lineNumber = 1; Iterator<Anchor> it = anchorList.iterator(); Anchor anchor = it.next(); writeJSPackageEnsurance(writer); writer.write(MessageFormat.format(JS_FUNCTION_BEGIN_TEMPLATE, getFilePackageName())); while ((line = reader.readLine()) != null){ while (anchor != null && anchor.getLine() == lineNumber){ line = anchor.processLine(line); if (it.hasNext()) anchor = it.next(); else anchor = null; } writer.write(line.replaceAll("\"", "\\\\\"")); writer.write(JS_LINE_SEPARATOR); writer.write(LINE_SEPARATOR); lineNumber++; } writer.write(JS_FUNCTION_END); reader.close(); writer.close(); } private void writeJSPackageEnsurance(Writer writer) throws IOException{ String packageName = filename.replaceAll(System.getProperty("file.separator"), "."); if (packageName.charAt(0) == '.') packageName = packageName.substring(1); String[] packages = packageName.split("\\."); String current = ""; if (packages.length > 2) for (int i = 0; i < packages.length - 2; i++) { current += packages[i]; writer.write(MessageFormat.format(JS_ENSURE_PACKAGE_EXIST, current)); current += '.'; } } private String getFilePackageName(){ StringBuffer sb = new StringBuffer(filename.replaceAll(System.getProperty("file.separator"), ".")); if (sb.charAt(0) == '.') sb.deleteCharAt(0); if (sb.lastIndexOf(".") > 0) sb.delete(sb.lastIndexOf("."), sb.length()); return sb.toString(); } }