/* * Main.java * * Created on 1.8.2007, 9:30:11 * * To change this template, choose Tools | Templates * and open the template in the editor. */ import java.io.*; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import sun.net.www.content.image.gif; /** * * @author Adam */ public class Main { final HashMap bundles = new HashMap(); final File root; public Main(File root) { this.root = root; } public Bundle getBundle(String path) { Bundle b = bundles.get(path); if (b == null) try { b = new Bundle(path); bundles.put(path, b); } catch (IOException ioe) { System.err.println("ERROR: Parsing of bundle failed: " + ioe.getMessage()); } return b; } static final Pattern PROPERTIES = Pattern.compile("^\\s*<\\s*Properties\\s*>\\s*$", Pattern.CASE_INSENSITIVE); static final Pattern PROPERTIES_END = Pattern.compile("^\\s*<\\s*/\\s*Properties\\s*>\\s*$", Pattern.CASE_INSENSITIVE); static final Pattern TEXT = Pattern.compile("^\\s*<\\s*Property\\s+name=\"text\"\\s+type=\"java.lang.String\"\\s+editor=\"org\\.netbeans\\.modules\\.i18n\\.form\\.FormI18nStringEditor\"\\s*>\\s*$", Pattern.CASE_INSENSITIVE); static final Pattern MNEMONICS = Pattern.compile("^\\s*<\\s*Property\\s+name=\"(displayed)?mnemonic\"\\s+type=\"int\"\\s+editor=\"org\\.netbeans\\.modules\\.i18n\\.form\\.FormI18nMnemonicEditor\"\\s*>\\s*$", Pattern.CASE_INSENSITIVE); static final Pattern RESOURCE = Pattern.compile("^\\s*<\\s*ResourceString\\s+bundle=\"([^\"]+)\"\\s+key=\"([^\"]+)\"\\s+replaceFormat=\"[^\"]*\"\\s*/\\s*>\\s*$", Pattern.CASE_INSENSITIVE); static final Pattern PROPERTY_END = Pattern.compile("^\\s*<\\s*/\\s*Property\\s*>\\s*$", Pattern.CASE_INSENSITIVE); public boolean parseForm(File f) { System.err.println("Parsing form: " + f.getAbsolutePath()); BufferedReader in = null; String mBundle = null, mnemonicsKey = null, textBundle = null, textKey = null; LinkedList lines = new LinkedList(); int deleteLine = 0; boolean modified = false; try { in = new BufferedReader(new InputStreamReader(new FileInputStream(f), "UTF-8")); String line; while ((line = in.readLine()) != null) { lines.add(line); if (PROPERTIES.matcher(line).matches()) { mBundle = null; mnemonicsKey = null; textBundle = null; textKey = null; deleteLine = 0; } else if (PROPERTIES_END.matcher(line).matches()) { if (mBundle != null && mnemonicsKey != null && (textBundle == null || textKey == null)) { System.err.println("WARNING: " + f.getAbsolutePath() + " missing text for mnemonics: " + mBundle + ":" + mnemonicsKey); } else if (mBundle != null && mnemonicsKey != null && textBundle != null && textKey != null) { if (!mBundle.equals(textBundle)) { System.err.println("ERROR: " + f.getAbsolutePath() + " keys from various bundles: " + textBundle + ":" + textKey + " " + mBundle + ":" + mnemonicsKey); } else { System.err.println("Replacing in bundle: " + textBundle + " textKey: " + textKey + " mnemonicsKey: " + mnemonicsKey); Bundle b = getBundle(textBundle); if (b == null) { System.err.println("ERROR: cannot get bundle: " + textBundle); return false; } b.replace(textKey, mnemonicsKey); if (deleteLine != 0) { lines.remove(deleteLine); lines.remove(deleteLine); lines.remove(deleteLine); modified = true; } } } } else if (TEXT.matcher(line).matches()) { if ((line = in.readLine()) != null) { lines.add(line); Matcher ma = RESOURCE.matcher(line); if (ma.matches()) { if ((line = in.readLine()) != null) { lines.add(line); if (PROPERTY_END.matcher(line).matches()) { if (textBundle != null || textKey != null) { System.err.println("ERROR: " + f.getAbsolutePath() + " invalid syntax: two mnemonic resources in one properties section!"); return false; } textBundle = ma.group(1); textKey = ma.group(2); System.err.println("Found bundle: " + textBundle + " text key: " + textKey); } } } } } else if (MNEMONICS.matcher(line).matches()) { if ((line = in.readLine()) != null) { lines.add(line); Matcher ma = RESOURCE.matcher(line); if (ma.matches()) { if ((line = in.readLine()) != null) { lines.add(line); if(PROPERTY_END.matcher(line).matches()) { if (mBundle != null || mnemonicsKey != null) { System.err.println("ERROR: " + f.getAbsolutePath() + " invalid syntax: two mnemonic resources in one properties section!"); return false; } mBundle = ma.group(1); mnemonicsKey = ma.group(2); deleteLine = lines.size() - 3; System.err.println("Found bundle: " + mBundle + " mnemonics key: " + mnemonicsKey); } } } } } } } catch (IOException ioe) { System.err.println("ERROR: " + f.getAbsolutePath() + " exception: " + ioe.getMessage()); return false; } finally { if (in != null) try {in.close();} catch (IOException ioe) {} } if (modified) try { System.err.println("!!!Writing file: " + f.getAbsolutePath()); PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8")); for (String s : lines) out.println(s); out.close(); } catch (IOException ioe) { System.err.println("ERROR: " + f.getAbsolutePath() + " exception when writing: " + ioe.getMessage()); return false; } return true; } public void writeBundles() { for (Map.Entry e : bundles.entrySet()) { File f = new File(root, e.getKey()); if (e.getValue().modified) try { System.err.println("!!!Writing file: " + f.getAbsolutePath()); PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(f), "8859_1")); ArrayList orig = e.getValue().originalLines; ArrayList modif = e.getValue().modifiedLines; for (int i = 0; i < orig.size(); i++) { String modL = modif.get(i); if (modL == null) out.println(orig.get(i)); else if (modL.length() > 0) out.println(modL); } out.close(); } catch (IOException ioe) { System.err.println("ERROR: " + f.getAbsolutePath() + " exception when writing: " + ioe.getMessage()); } } } /** * @param args the command line arguments */ public static void main(String[] args) { File root = new File(args[0]); Main m = new Main(root); LinkedList files = new LinkedList(); files.add(root); while (!files.isEmpty()) { File f = files.remove(0); if (f.isDirectory()) { files.addAll(Arrays.asList(f.listFiles())); } else if (f.getName().endsWith(".form")) { m.parseForm(f); } } m.writeBundles(); } class Bundle { final ArrayList originalLines; final ArrayList modifiedLines; final HashMap keys2lines; final String path; boolean modified = false; public Bundle(String path) throws IOException { this.path = path; System.err.println("Parsing bundle: " + path); originalLines = new ArrayList(); modifiedLines = new ArrayList(); keys2lines = new HashMap(); BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(new File(root, path)), "8859_1")); try { String line; while ((line = in.readLine()) != null) { originalLines.add(line); modifiedLines.add(null); if (!line.trim().startsWith("#")) { int i = line.indexOf('='); if (i > 0) { Integer old = keys2lines.put(line.substring(0, i), originalLines.size() - 1); if (old != null) { if (line.equals(originalLines.get(old))) { System.err.println("WARNING: " + path + " removing duplicate keys: " + old.toString() + ":" + originalLines.get(old) + " " + originalLines.size() + ":" + line); modifiedLines.set(modifiedLines.size() - 1, ""); modified = true; } else { System.err.println("ERROR: " + path + " duplicate keys with different values: " + old.toString() + ":" + originalLines.get(old) + " " + originalLines.size() + ":" + line); } } } } } } finally { in.close(); } } public boolean replace(String textKey, String mnemonicsKey) { Integer textLine = keys2lines.get(textKey); if (textLine == null) { System.err.println("ERROR: " + path + " key: " + textKey + " not found!"); return false; } Integer mnemonicsLine = keys2lines.get(mnemonicsKey); if (mnemonicsLine == null) { System.err.println("ERROR: " + path + " key: " + mnemonicsKey + " not found!"); return false; } String mnemonics = originalLines.get(mnemonicsLine); if (mnemonics.length() < mnemonicsKey.length() + 2) { System.err.println("ERROR: " + path + " invalid mnemonics value: " + mnemonicsLine + ":" + mnemonics); return false; } mnemonics = mnemonics.substring(mnemonicsKey.length() + 1, mnemonicsKey.length() + 2).toLowerCase(); String text = originalLines.get(textLine); int i = text.toLowerCase().indexOf(mnemonics, textKey.length() + 1); if (i < textKey.length()) { System.err.println("ERROR: " + path + " text: " + textLine + ":" + text + " does not contain mnemonics character: " + mnemonics); return false; } text = text.substring(0, i) + '&' + text.substring(i); String modL = modifiedLines.get(textLine); if (modL == null) { System.err.println("Replacing text: " + originalLines.get(textLine) + " with: " + text); modifiedLines.set(textLine, text); modified = true; } else { if (modL.length() == 0) { System.err.println("WARNING: " + path + " setting back already removed text: " + textLine); } else if (modL.equals(text)) { System.err.println("WARNING: " + path + " text already modified: " + textLine + ":" + text); } else { System.err.println("ERROR: " + path + " text already modified and differs: " + textLine + ":" + text + " " + modL); return false; } } modL = modifiedLines.get(mnemonicsLine); if (modL == null) { System.err.println("Removing mnemonics: " + originalLines.get(mnemonicsLine)); modifiedLines.set(mnemonicsLine, ""); modified = true; } else { if (modL.length() == 0) { System.err.println("WARNING: " + path +" already removed mnemonics: " + mnemonicsLine + ":" + mnemonicsKey); } else { System.err.println("WARNING: " + path + " could not remove mnemonics: " + mnemonicsLine + ":" + modL); } } return true; } } }