1 package jimm.properties; 2 import java.util.*; 3 import java.io.*; 4 import java.awt.Dimension ; 5 import java.awt.event.*; 6 import javax.swing.*; 7 import javax.swing.event.TreeSelectionEvent ; 8 import javax.swing.event.TreeSelectionListener ; 9 import javax.swing.tree.*; 10 11 public class TranslateOMatic 12 extends JFrame 13 implements ActionListener, TreeSelectionListener { 14 15 17 22 class BundleAssoc { 23 24 String prefix; 25 ResourceBundle from; 26 MutableResourceBundle to; 27 List exclusions; 28 29 BundleAssoc(String prefix, ResourceBundle from, MutableResourceBundle to) { 30 this.prefix = prefix; 31 this.from = from; 32 this.to = to; 33 exclusions = new ArrayList(); 34 } 35 36 void addExclusion(String str) { 37 exclusions.add(str); 38 } 39 40 boolean exclude(String str) { 41 int pos = str.lastIndexOf('.'); 42 if (pos >= 0) 43 str = str.substring(pos + 1); 44 return exclusions.contains(str); 45 } 46 47 } 48 49 51 55 class Translation { 56 MutableResourceBundle to; 57 String key; 58 59 Translation(MutableResourceBundle to, String key) { 60 this.to = to; 61 this.key = key; 62 } 63 64 void save(String str) { 65 to.setString(key, str.trim()); 66 } 67 } 68 69 71 74 class MutableResourceBundle { 75 76 String prefix; 77 String language; 78 String country; 79 ResourceBundle bundle; 80 HashMap newValues; 81 82 MutableResourceBundle(String prefix, String language, String country) { 83 this.prefix = prefix; 84 this.language = language; 85 this.country = country; 86 bundle = ResourceBundle.getBundle(prefix, new Locale(language, country)); 87 newValues = new HashMap(); 88 } 89 90 String getString(String key) { 91 String str = (String )newValues.get(key); 92 if (str == null) 93 str = bundle.getString(key); 94 return str; 95 } 96 97 void setString(String key, String value) { 98 if (value != null) { 99 value = value.trim(); 100 if (value.length() == 0) value = null; 102 } 103 newValues.put(key, value); 104 } 105 106 String fileName() { 107 return prefix + "_" + language + "_" + country + ".properties"; 108 } 109 } 110 111 113 static final Dimension WINDOW_SIZE = new Dimension (600, 350); 114 static final Dimension MIN_SIZE = new Dimension (100, 50); 115 static final int START_DIVIDER_LOCATION = 150; 116 static final int TEXT_FIELD_SIZE = 40; 117 118 HashMap bundles; 119 ResourceBundle settings; 120 DefaultTreeModel model; 121 JTree tree; 122 JLabel fromField; 123 JTextField toField; 124 Translation xlation; 125 String encoding; 126 127 public TranslateOMatic(String localeLanguage, String localeCountry, 128 String encodingName) 129 { 130 super("Translate-O-Matic"); 131 132 bundles = new HashMap(); 133 settings = ResourceBundle.getBundle("translate"); 134 135 encoding = encodingName; 136 if (encoding == null) 137 encoding = settings.getString("default_encoding"); 138 else 139 encoding = encoding.toUpperCase(); 140 141 buildModel(localeLanguage, localeCountry); 142 buildWindow(); 143 144 addWindowListener(new WindowAdapter() { 146 public void windowClosing(WindowEvent e) { maybeClose(); } 147 }); 148 149 pack(); 150 show(); 151 } 152 153 protected void buildModel(String localeLanguage, String localeCountry) { 154 List prefixes = split(settings.getString("bundles")); 155 for (Iterator iter = prefixes.iterator(); iter.hasNext(); ) { 156 String prefix = (String )iter.next(); 157 ResourceBundle from = ResourceBundle.getBundle(prefix); 158 MutableResourceBundle to = 159 new MutableResourceBundle(prefix, localeLanguage, localeCountry); 160 161 BundleAssoc assoc = new BundleAssoc(prefix, from, to); 162 bundles.put(prefix, assoc); 163 164 try { 166 String exclusions = settings.getString("exclusions." + prefix); 167 List l = split(exclusions); 168 for (Iterator iter2 = l.iterator(); iter2.hasNext(); ) 169 assoc.addExclusion(iter2.next().toString()); 170 } 171 catch (MissingResourceException mre) { 172 } 174 } 175 176 DefaultMutableTreeNode top = new DefaultMutableTreeNode(); 177 createNodes(top); 178 model = new DefaultTreeModel(top); 179 } 180 181 186 protected void createNodes(DefaultMutableTreeNode top) { 187 for (Iterator iter = bundles.values().iterator(); iter.hasNext(); ) 188 createNode(top, (BundleAssoc)iter.next()); 189 } 190 191 protected void createNode(DefaultMutableTreeNode top, BundleAssoc assoc) { 192 String name = assoc.prefix.substring(0, 1).toUpperCase() 193 + assoc.prefix.substring(1); 194 DefaultMutableTreeNode categoryNode = new DefaultMutableTreeNode(name); 195 top.add(categoryNode); 196 197 HashMap subnodes = new HashMap(); 198 for (Enumeration e = assoc.from.getKeys(); e.hasMoreElements(); ) { 199 String key = e.nextElement().toString(); 200 if (assoc.exclude(key)) 201 continue; 202 203 String firstPart = firstPartOf(key); 204 if (firstPart.equals(key)) 205 categoryNode.add(new DefaultMutableTreeNode(key)); 206 else { 207 DefaultMutableTreeNode subnode = 208 (DefaultMutableTreeNode)subnodes.get(firstPart); 209 if (subnode == null) { 210 subnode = new DefaultMutableTreeNode(firstPart); 211 subnodes.put(firstPart, subnode); 212 categoryNode.add(subnode); 213 } 214 subnode.add(new DefaultMutableTreeNode(key)); 215 } 216 } 217 } 218 219 222 protected void buildWindow() { 223 buildMenuBar(); 224 buildContents(); 225 getRootPane().setPreferredSize(WINDOW_SIZE); 226 } 227 228 231 protected void buildMenuBar() { 232 JMenuBar bar = new JMenuBar(); 233 bar.add(buildFileMenu()); 234 getRootPane().setJMenuBar(bar); 235 } 236 237 242 protected JMenu buildFileMenu() { 243 JMenu m = new JMenu("File"); 244 JMenuItem i = new JMenuItem("Quit"); 245 i.addActionListener(this); 246 m.add(i); 247 return m; 248 } 249 250 253 protected void buildContents() { 254 buildTree(); 255 256 JScrollPane treeScrollPane = new JScrollPane(tree); 257 treeScrollPane.setMinimumSize(MIN_SIZE); 258 259 Box box = Box.createVerticalBox(); 260 box.add(fromField = new JLabel(" ")); 261 fromField.setHorizontalAlignment(SwingConstants.LEFT); 262 box.add(toField = new JTextField(TEXT_FIELD_SIZE)); 263 JPanel p = new JPanel(); 264 p.add(box); 265 p.setMinimumSize(MIN_SIZE); 266 267 JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, 268 treeScrollPane, p); 269 sp.setDividerLocation(START_DIVIDER_LOCATION); 270 sp.setPreferredSize(WINDOW_SIZE); 271 272 getContentPane().add(sp); 273 } 274 275 protected void buildTree() { 276 tree = new JTree(model); 277 tree.setRootVisible(false); 278 tree.getSelectionModel() 279 .setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); 280 281 tree.addTreeSelectionListener(this); 283 } 284 285 public void valueChanged(TreeSelectionEvent e) { 286 if (xlation != null) 288 xlation.save(toField.getText()); 289 290 TreePath path = e.getPath(); 291 if (path == null) 292 return; 293 294 Object [] elements = path.getPath(); 296 if (elements.length < 3) 297 return; 298 299 String bundleName = elements[1].toString().toLowerCase(); 300 BundleAssoc assoc = (BundleAssoc)bundles.get(bundleName); 301 302 String key = elements[elements.length - 1].toString(); 303 String fromString = null, toString = null; 304 try { 305 fromString = assoc.from.getString(key); 306 toString = assoc.to.getString(key); 307 308 xlation = new Translation(assoc.to, key); 309 310 fromField.setText(fromString); 311 toField.setText(toString); 312 } 313 catch (MissingResourceException mre) { 314 xlation = null; 315 316 fromField.setText(" "); 317 toField.setText(""); 318 } 319 } 320 321 324 public void actionPerformed(ActionEvent e) { 325 String cmd = e.getActionCommand(); 326 if ("Quit".equals(cmd)) maybeClose(); 327 } 328 329 332 String escape(String str) { 333 if (str == null || str.length() == 0) 334 return str; 335 336 StringBuffer buf = new StringBuffer (); 337 338 int len = str.length(); 339 for (int i = 0; i < len; ++i) { 340 char c = str.charAt(i); 341 switch (c) { 342 case '=': 343 case ':': 344 buf.append('\\'); 345 buf.append(c); 346 break; 347 case '\n': 348 buf.append("\\n"); 349 break; 350 case '\r': 351 buf.append("\\r"); 352 break; 353 case '\t': 354 buf.append("\\t"); 355 break; 356 default: 357 if (i == 0 && Character.isWhitespace(c)) 358 buf.append('\\'); 359 buf.append(c); 360 break; 361 } 362 } 363 364 return buf.toString(); 365 } 366 367 370 protected void save() { 371 try { 372 for (Iterator iter = bundles.values().iterator(); iter.hasNext(); ) { 373 BundleAssoc assoc = (BundleAssoc)iter.next(); 374 File f = new File(assoc.to.fileName()); 375 PrintWriter out = 376 new PrintWriter(new OutputStreamWriter(new FileOutputStream(f), 377 encoding)); 378 379 for (Enumeration e = assoc.from.getKeys(); e.hasMoreElements(); ) { 380 String key = e.nextElement().toString(); 381 String val = escape(assoc.to.getString(key)); 382 if (val != null) 383 out.println(key + " = " + val); 384 } 385 386 out.flush(); 387 out.close(); 388 } 389 } 390 catch (IOException ioe) { 391 System.err.println(ioe.toString()); 392 } 393 } 394 395 398 protected void maybeClose() { 399 if (xlation != null) 401 xlation.save(toField.getText()); 402 403 save(); 404 dispose(); 405 System.exit(0); 406 } 407 408 protected String firstPartOf(String key) { 409 int pos = key.indexOf('.'); 410 return (pos == -1) ? key : key.substring(0, pos); 411 } 412 413 protected List split(String str) { 414 if (str == null) 415 return null; 416 417 ArrayList list = new ArrayList(); 418 419 int subStart, afterDelim = 0; 420 while ((subStart = str.indexOf(',', afterDelim)) != -1) { 421 list.add(str.substring(afterDelim, subStart).trim()); 422 afterDelim = subStart + 1; 423 } 424 if (afterDelim <= str.length()) 425 list.add(str.substring(afterDelim).trim()); 426 427 return list; 428 } 429 430 public static void main(String [] args) { 431 try { 432 if (args[0].toLowerCase() == "en" && args[1].toUpperCase() == "US") { 433 System.err.println("Can't modify en_US files"); 434 System.exit(1); 435 } 436 new TranslateOMatic(args[0], args[1], 437 (args.length >= 3) ? args[2] : null); 438 } 439 catch (Exception e) { 440 e.printStackTrace(); 441 } 442 } 443 444 } 445 | Popular Tags |