X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fcom%2Fdogcows%2FEditor.java;h=19cee34defaae895f389d69cadb070bd5e016bb5;hb=4afcc19722d6dde23c36f9491ebab9f7b6e38e8b;hp=15dad35a8f5712c70c21017377e30e73dbea181f;hpb=5513994bbc39ef7c7ca1917e2d07d8c53b30ea8d;p=chaz%2Fvimcoder diff --git a/src/com/dogcows/Editor.java b/src/com/dogcows/Editor.java index 15dad35..19cee34 100644 --- a/src/com/dogcows/Editor.java +++ b/src/com/dogcows/Editor.java @@ -1,12 +1,9 @@ package com.dogcows; -import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; -import java.io.InputStream; import java.util.*; import com.topcoder.client.contestant.ProblemComponentModel; @@ -27,24 +24,34 @@ public class Editor /** * The problem ID number. */ - private String id; - + private String id; + /** * The name of the class. */ - private String name; - + private String name; + + /** + * The name of the contest. + */ + private String contestName; + + /** + * The point value. + */ + private String points; + /** * The path of the current source file. */ - private File sourceFile; - + private File sourceFile; + /** * The path of the problem directory. */ - private File directory; - - + private File directory; + + /** * Map languages names to file extensions. */ @@ -58,7 +65,7 @@ public class Editor languageExtension.put("Python", "py"); } - + /** * Construct an editor with the problem objects given us by the Arena. * @param component A container for the particulars of the problem. @@ -67,44 +74,57 @@ public class Editor * @throws Exception If the editor could not set itself up. */ public Editor(ProblemComponentModel component, - Language language, - Renderer renderer) throws Exception + Language language, Renderer renderer) throws Exception { this.id = String.valueOf(component.getProblem().getProblemID()); this.name = component.getClassName(); - + this.contestName = component.getProblem().getRound().getContestName().replaceAll(" ", "-"); + this.points = String.valueOf(component.getPoints().intValue()); + // Make sure the top-level vimcoder directory exists. File topDir = VimCoder.getStorageDirectory(); if (!topDir.isDirectory()) { if (!topDir.mkdirs()) throw new IOException(topDir.getPath()); } - + // Make sure the problem directory exists. - this.directory = new File(topDir, id); - if (!directory.isDirectory()) + File newStyleDirectory = new File(new File(topDir, contestName), points); + File oldStyleDirectory = new File(topDir, id); + if (newStyleDirectory.isDirectory()) { + this.directory = newStyleDirectory; + } + else if (oldStyleDirectory.isDirectory()) + { + this.directory = oldStyleDirectory; + } + else if (VimCoder.isContestDirNames()) + { + this.directory = newStyleDirectory; if (!directory.mkdirs()) throw new IOException(directory.getPath()); } - + else + { + this.directory = oldStyleDirectory; + if (!directory.mkdirs()) throw new IOException(directory.getPath()); + } + String lang = language.getName(); - String ext = languageExtension.get(lang); - + String ext = languageExtension.get(lang); + // Set up the terms used for the template expansion. HashMap terms = new HashMap(); - terms.put("RETURNTYPE",component.getReturnType().getDescriptor(language).replaceAll("\\s+", "")); - terms.put("CLASSNAME", name); - terms.put("METHODNAME", component.getMethodName()); - terms.put("METHODPARAMS", getMethodParams(component.getParamTypes(), - component.getParamNames(), - language)); - terms.put("METHODPARAMNAMES", Util.join(component.getParamNames(), ", ")); - terms.put("METHODPARAMSTREAMIN", Util.join(component.getParamNames(), " >> ")); - terms.put("METHODPARAMSTREAMOUT", Util.join(component.getParamNames(), " << ")); - terms.put("METHODPARAMDECLARES", getMethodParamDeclarations(component.getParamTypes(), - component.getParamNames(), - language)); - + terms.put("RETURNTYPE", component.getReturnType().getDescriptor(language)); + terms.put("CLASSNAME", name); + terms.put("METHODNAME", component.getMethodName()); + terms.put("METHODPARAMS", getMethodParams(component.getParamTypes(), component.getParamNames(), language)); + terms.put("METHODPARAMNAMES", Util.join(component.getParamNames(), ", ")); + terms.put("METHODPARAMSTREAMIN", Util.join(component.getParamNames(), " >> ")); + terms.put("METHODPARAMSTREAMOUT", Util.join(component.getParamNames(), " << \", \" << ")); + terms.put("METHODPARAMDECLARES", getMethodParamDeclarations(component.getParamTypes(), component.getParamNames(), language)); + terms.put("VIMCODER", VimCoder.version); + // Write the problem statement as an HTML file in the problem directory. File problemFile = new File(directory, "Problem.html"); if (!problemFile.canRead()) @@ -119,25 +139,23 @@ public class Editor writer.close(); } } - + // Expand the template for the main class and write it to the current // source file. - sourceFile = new File(directory, name + "." + ext); + this.sourceFile = new File(directory, name + "." + ext); if (!sourceFile.canRead()) { - String text = Util.expandTemplate(readTemplate(lang + "Template"), - terms); + String text = Util.expandTemplate(readTemplate(lang + "Template"), terms); FileWriter writer = new FileWriter(sourceFile); writer.write(text); writer.close(); } - + // Expand the driver template and write it to a source file. File driverFile = new File(directory, "driver." + ext); if (!driverFile.canRead()) { - String text = Util.expandTemplate(readTemplate(lang + "Driver"), - terms); + String text = Util.expandTemplate(readTemplate(lang + "Driver"), terms); FileWriter writer = new FileWriter(driverFile); writer.write(text); writer.close(); @@ -164,12 +182,12 @@ public class Editor writer.write(text.toString()); writer.close(); } - + // Finally, expand the Makefile template and write it. File makeFile = new File(directory, "Makefile"); + if (!makeFile.canRead()) { - String text = Util.expandTemplate(readTemplate(lang + "Makefile"), - terms); + String text = Util.expandTemplate(readTemplate(lang + "Makefile"), terms); FileWriter writer = new FileWriter(makeFile); writer.write(text); writer.close(); @@ -198,51 +216,52 @@ public class Editor */ public String getSource() throws IOException { - return Util.readFile(sourceFile) + "\n// Edited by " + - VimCoder.version + "\n// " + VimCoder.website + "\n\n"; + return Util.readFile(sourceFile); } - - + + /** - * Send a command to the Vim server. If the server isn't running, it will - * be started with the name VIMCODER#### where #### is the problem ID. + * Send a command to the Vim server. + * If the server isn't running, it will be started with the name + * VIMCODER#### where #### is the problem ID. * @param command The command to send to the server. * @param argument A single argument for the remote command. * @throws Exception If the command could not be sent. */ - private void sendVimCommand(String command, - String argument) throws Exception + private void sendVimCommand(String command, String argument) throws Exception { String[] arguments = {argument}; sendVimCommand(command, arguments); } - + /** - * Send a command to the Vim server. If the server isn't running, it will - * be started with the name VIMCODER#### where #### is the problem ID. + * Send a command to the Vim server. + * If the server isn't running, it will be started with the name + * VIMCODER#### where #### is the problem ID. * @param command The command to send to the server. * @param argument Arguments for the remote command. * @throws Exception If the command could not be sent. */ - private void sendVimCommand(String command, - String[] arguments) throws Exception + private void sendVimCommand(String command, String[] arguments) throws Exception { String[] vimCommand = VimCoder.getVimCommand().split("\\s"); String[] flags = {"--servername", "VimCoder" + id, command}; vimCommand = Util.concat(vimCommand, flags); vimCommand = Util.concat(vimCommand, arguments); Process child = Runtime.getRuntime().exec(vimCommand, null, directory); - - /* FIXME: This is a hack with a magic number. The problem is the Vim - * process doesn't fork to the background on some systems, so we can't - * wait on the child. At the same time, calling this method before the - * previous child could finish initializing the server may result in - * multiple editor windows popping up. We'd also like to be able to - * get the return code from the child if we can. The workaround here is - * to stall the thread for a little while or until we know the child - * does exit. If the child never exits before the timeout, we will - * assume it is not backgrounding and that everything worked. */ - long expire = System.currentTimeMillis() + 250; + + /* FIXME: This is a pretty bad hack. The problem is that the Vim + * process doesn't fork to the background on some systems, so we + * can't wait on the child. At the same time, calling this method + * before the previous child could finish initializing the server + * may result in multiple editor windows popping up. We'd also + * like to be able to get the return code from the child if we can. + * The workaround here is to stall the thread for a little while or + * until we see that the child exits. If the child never exits + * before the timeout, we will assume it is not backgrounding and + * that everything worked. This works as long as the Vim server is + * able to start within the stall period. */ + long expire = System.currentTimeMillis() + 2500; while (System.currentTimeMillis() < expire) { Thread.yield(); @@ -258,11 +277,12 @@ public class Editor } } } - - + + /** - * Read a template. We first look in the storage directory. If we can't - * find one, we look among the resources. + * Read a template. + * We first look in the storage directory. If we can't find one, we + * look among the resources. * @param tName The name of the template. * @return The contents of the template file, or an empty string. */ @@ -279,8 +299,8 @@ public class Editor return ""; } } - - + + /** * Convert an array of data types to an array of strings according to a * given language. @@ -293,40 +313,38 @@ public class Editor String[] strings = new String[types.length]; for (int i = 0; i < types.length; ++i) { - strings[i] = types[i].getDescriptor(language).replaceAll("\\s+", ""); + strings[i] = types[i].getDescriptor(language); } return strings; } - + /** * Combine the data types and parameter names into a comma-separated list of - * the method parameters. The result could be used inside the parentheses - * of a method declaration. + * the method parameters. + * The result could be used inside the parentheses of a method + * declaration. * @param types The data types of the parameters. * @param names The names of the parameters. * @param language The language used for representing the data types. * @return The list of parameters. */ - private String getMethodParams(DataType[] types, - String[] names, - Language language) + private String getMethodParams(DataType[] types, String[] names, Language language) { String[] typeStrings = getStringTypes(types, language); return Util.join(Util.combine(typeStrings, names, " "), ", "); } - + /** * Combine the data types and parameter names into a group of variable - * declarations. Each declaration is separated by a new line and terminated - * with a semicolon. + * declarations. + * Each declaration is separated by a new line and terminated with a + * semicolon. * @param types The data types of the parameters. * @param names The names of the parameters. * @param language The language used for representing the data types. * @return The parameters as a block of declarations. */ - private String getMethodParamDeclarations(DataType[] types, - String[] names, - Language language) + private String getMethodParamDeclarations(DataType[] types, String[] names, Language language) { final String end = ";" + System.getProperty("line.separator"); String[] typeStrings = getStringTypes(types, language); @@ -334,3 +352,4 @@ public class Editor } } +// vim:et:ts=8:sts=4:sw=4