package bluej.utility;

import java.util.*;
import java.io.*;
import java.nio.charset.Charset;

import bluej.Config;


| BlueJFileReader - a (static) class grouping all functions to read and write | BlueJ specific files. | | The BlueJ files are help files (used for compiler help, exception help, | editor help), dialogue files (for message and error dialogues) and templates | (for class skeletons). | | Help texts and dialogue texts are handled through the "readHelpText" method. |* The files consist of text IDs (a short string) followed by the full text. * <p> * Class skeletons (handled by the "translateFile" method) are text files with * place holders (variables) in them that will be replaced using a dictionary. * * @author Michael Kolling */ public class BlueJFileReader{ private static final int tabSize = Config.getPropInteger("bluej.editor.tabsize", 4); private static final String spaces = " "; private static final char TAB_CHAR = '\t'; /** * Read a help text out of a help file. * <p> * Help files are named (language)/(baseFileName).help (for example * "english/moe.help"). Help texts inside the file are identified by * a help ID (a string). * <p> * The files are expected to be in ISO 8859-1 character encoding, with "slash-u-XXXX" unicode * escape sequences. * * @param file The help file * @param textID ID string for the help message * @param exactMatch If true, match ID string exactly. If false, | wildcards are used. | | @return The help text or null. | public static String readHelpText(File file, String textID, boolean exactMatch) { BufferedReader in = null; try { in = new BufferedReader(new InputStreamReader(new FileInputStream(file), "8859_1")); String msg; String line; String helptext = ""; boolean match; while ((msg = in.readLine()) != null){ msg = msg.trim(); if (exactMatch) { match = msg.equals(textID); } else { match = helpTextMatch(textID, msg); } if (match) { line = in.readLine(); if ((line != null) && (line.length() > 0)) { helptext = line; line = in.readLine(); } while ((line != null) && (line.length() > 0)){ helptext += "\n" + line; line = in.readLine(); } return convert(helptext); } else { line = in.readLine(); while ((line != null) && (line.length() > 0)){ line = in.readLine(); } } } } catch(IOException e) { } finally { if (in != null) { try { in.close(); } catch(Exception e) { } } } return null; }
| Helper function for "readHelpText" (above). Used to determine |* help ID matches when accepting wildcards in the message. Recognised * wildcards are asterisks (*) at the start or end of the pattern. */ private static boolean helpTextMatch(String message, String pattern) | |{ | |if (pattern.length() == 0) { | |return false; | |} | |if (pattern.charAt(pattern.length()-1) == '*') { | |if (pattern.charAt(0) == '*') { // * at both ends | |pattern = pattern.substring(1, pattern.length()-3); | |return (message.indexOf(pattern) > -1); | |} | |else { // * at end | |return message.startsWith( | |pattern.substring(0, pattern.length()-2)); | |} | |} | |else if (pattern.charAt(0) == '*') { | |return message.endsWith(pattern.substring(1)); | |} | |else { | |return pattern.equals(message); | |} | |} | |/** | Copy a file while replacing special keywords within the file by | definitions. | | Keywords are marked with a dollar sign and a name ($KEYWORD). | 'translations' contains definitions to be used as replacements. This is | used to create shell files from the shell file template. | | @param templateCharset Charset that should be used to read the template file. | public static void translateFile(File template, File dest, Dictionary<String,String> translations, Charset templateCharset, Charset outputCharset) throws IOException { translateFile(template, dest, translations, true, templateCharset, outputCharset); }
| Copy a file while replacing special keywords within the file by definitions. | | Keywords are marked with a dollar sign and a name ($KEYWORD). 'translations' contains definitions | to be used as replacements. This is used to create shell files from the shell file template. | | @param templateCharset Charset that should be used to read the template file. | @param outputCharset Charset that should be used to write the output file. | private static void translateFile(File template, File dest, Dictionary<String,String> translations, boolean replaceTabs, Charset templateCharset, Charset outputCharset) throws IOException { InputStreamReader in = null; OutputStreamWriter out = null; String newline = System.getProperty("line.separator"); try { in = new InputStreamReader(new FileInputStream(template), templateCharset); out = new OutputStreamWriter(new FileOutputStream(dest), outputCharset); for (int c; (c = in.read()) != -1; ) { if (c == '$') { StringBuffer buf = new StringBuffer(); while (((c = in.read()) != -1) && Character.isLetter((char)c)) { buf.append((char)c); } String key = buf.toString(); if (key.length() != 0) { String value = translations.get(key); if (value == null) { out.write('$'); value = key; } if (replaceTabs && value.indexOf(TAB_CHAR) != -1) { value = convertTabsToSpaces(value); } out.write(value); } else if (c != '$') { out.write('$'); } if (c != -1) { out.write(c); } } else if (replaceTabs && c == TAB_CHAR) { out.write(tabAsSpace()); } else if (c == '\r') { int nc = in.read(); if (nc == '\n') { out.write(newline); } else { out.write(c); if (nc != -1) { out.write(nc); } } } else { out.write(c); } } in.close(); out.close(); } catch(IOException e) { if (in != null) { in.close(); } if (out != null) { out.close(); } throw e; } }
| Copy a file while replacing a string with another within the file. | | 'translations' contains definitions to be used as replacements. | This is used to create a copy of a class with different names. | public static void duplicateFile(File original, File destination, Dictionary<String,String> translations) throws IOException { BufferedReader in = null; BufferedWriter out = null; try { in = new BufferedReader(new FileReader(original)); out = new BufferedWriter(new FileWriter(destination)); String line; while ((line = in.readLine()) != null){ StringTokenizer st = new StringTokenizer(line, " (){}.,\"><", true); while (st.hasMoreTokens()){ String key = st.nextToken(); String value = translations.get(key); if (value == null) { value = key; } out.write(value); } out.newLine(); } in.close(); out.close(); } catch(IOException e) { if (in != null) { in.close(); } if (out != null) { out.close(); } throw e; } }
| Convert tab chars to the applicable number of spaces | private static String convertTabsToSpaces(String tabString) { return tabString.replaceAll("\t", tabAsSpace()); }
| Return a String representing the number of spaces to be used in replacing a tab character | private static String tabAsSpace() { return spaces.substring(0, tabSize); }
| Converts encoded \uxxxx to unicode chars | | Copied large chunks from java.util.Properties#loadConvert | private static String convert(String theString) { char aChar; int len = theString.length(); StringBuffer outBuffer = new StringBuffer(len); for (int x=0; x<len; ) { aChar = theString.charAt(x++); if (aChar == '\\') { aChar = theString.charAt(x++); if (aChar == 'u') { int value=0; for (int i=0; i<4; i++) { aChar = theString.charAt(x++); switch (aChar) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': value = (value << 4) + aChar - '0'; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': value = (value << 4) + 10 + aChar - 'a'; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': value = (value << 4) + 10 + aChar - 'A'; break; default: } } outBuffer.append((char)value); } else { outBuffer.append('\\'); outBuffer.append(aChar); } } else{ outBuffer.append(aChar); } } return outBuffer.toString(); } }

.   readHelpText
.   translateFile
.   translateFile
.   duplicateFile
.   convertTabsToSpaces
.   tabAsSpace
.   convert




357 neLoCode + 54 LoComm