KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jimm > properties > TranslateOMatic


1 package jimm.properties;
2 import java.util.*;
3 import java.io.*;
4 import java.awt.Dimension JavaDoc;
5 import java.awt.event.*;
6 import javax.swing.*;
7 import javax.swing.event.TreeSelectionEvent JavaDoc;
8 import javax.swing.event.TreeSelectionListener JavaDoc;
9 import javax.swing.tree.*;
10
11 public class TranslateOMatic
12     extends JFrame
13     implements ActionListener, TreeSelectionListener JavaDoc {
14
15 // ================================================================
16

17 /**
18  * A bundle association holds on to the "from" and "to" bundles, the
19  * prefix name (e.g., "datavision" or "menu"), and a list of
20  * exclusions---entries that should not be displayed.
21  */

22 class BundleAssoc {
23
24 String JavaDoc prefix;
25 ResourceBundle from;
26 MutableResourceBundle to;
27 List exclusions;
28
29 BundleAssoc(String JavaDoc 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 JavaDoc str) {
37     exclusions.add(str);
38 }
39
40 boolean exclude(String JavaDoc 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 // ================================================================
50

51 /**
52  * Represents a single entry change; used to remember what was being
53  * edited.
54  */

55 class Translation {
56 MutableResourceBundle to;
57 String JavaDoc key;
58
59 Translation(MutableResourceBundle to, String JavaDoc key) {
60     this.to = to;
61     this.key = key;
62 }
63
64 void save(String JavaDoc str) {
65     to.setString(key, str.trim());
66 }
67 }
68
69 // ================================================================
70

71 /**
72  * A mutable resource bundle.
73  */

74 class MutableResourceBundle {
75
76 String JavaDoc prefix;
77 String JavaDoc language;
78 String JavaDoc country;
79 ResourceBundle bundle;
80 HashMap newValues;
81
82 MutableResourceBundle(String JavaDoc prefix, String JavaDoc language, String JavaDoc 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 JavaDoc getString(String JavaDoc key) {
91     String JavaDoc str = (String JavaDoc)newValues.get(key);
92     if (str == null)
93     str = bundle.getString(key);
94     return str;
95 }
96
97 void setString(String JavaDoc key, String JavaDoc value) {
98     if (value != null) {
99     value = value.trim();
100     if (value.length() == 0) // Store null for empty strings
101
value = null;
102     }
103     newValues.put(key, value);
104 }
105
106 String JavaDoc fileName() {
107     return prefix + "_" + language + "_" + country + ".properties";
108 }
109 }
110
111 // ================================================================
112

113 static final Dimension JavaDoc WINDOW_SIZE = new Dimension JavaDoc(600, 350);
114 static final Dimension JavaDoc MIN_SIZE = new Dimension JavaDoc(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 JavaDoc encoding;
126
127 public TranslateOMatic(String JavaDoc localeLanguage, String JavaDoc localeCountry,
128                String JavaDoc 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     // Make sure we close the window when the user asks to close the window.
145
addWindowListener(new WindowAdapter() {
146     public void windowClosing(WindowEvent e) { maybeClose(); }
147     });
148
149     pack();
150     show();
151 }
152
153 protected void buildModel(String JavaDoc localeLanguage, String JavaDoc localeCountry) {
154     List prefixes = split(settings.getString("bundles"));
155     for (Iterator iter = prefixes.iterator(); iter.hasNext(); ) {
156     String JavaDoc prefix = (String JavaDoc)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     // Exclusions
165
try {
166         String JavaDoc 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         // Ignore missing resources
173
}
174     }
175
176     DefaultMutableTreeNode top = new DefaultMutableTreeNode();
177     createNodes(top);
178     model = new DefaultTreeModel(top);
179 }
180
181 /**
182  * Creates tree nodes.
183  *
184  * @param top top-level tree node
185  */

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 JavaDoc 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 JavaDoc key = e.nextElement().toString();
200     if (assoc.exclude(key))
201         continue;
202
203     String JavaDoc 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 /**
220  * Builds the window components.
221  */

222 protected void buildWindow() {
223     buildMenuBar();
224     buildContents();
225     getRootPane().setPreferredSize(WINDOW_SIZE);
226 }
227
228 /**
229  * Builds the window menu bar.
230  */

231 protected void buildMenuBar() {
232     JMenuBar bar = new JMenuBar();
233     bar.add(buildFileMenu());
234     getRootPane().setJMenuBar(bar);
235 }
236
237 /**
238  * Builds and returns the "File" menu.
239  *
240  * @return a menu
241  */

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 /**
251  * Builds window contents.
252  */

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     // Listen for selection changes
282
tree.addTreeSelectionListener(this);
283 }
284
285 public void valueChanged(TreeSelectionEvent JavaDoc e) {
286     // Save previously selected value
287
if (xlation != null)
288     xlation.save(toField.getText());
289
290     TreePath path = e.getPath();
291     if (path == null)
292     return;
293
294     // We ignore the 0'th entry which is an unnamed, unused root element.
295
Object JavaDoc[] elements = path.getPath();
296     if (elements.length < 3)
297     return;
298
299     String JavaDoc bundleName = elements[1].toString().toLowerCase();
300     BundleAssoc assoc = (BundleAssoc)bundles.get(bundleName);
301
302     String JavaDoc key = elements[elements.length - 1].toString();
303     String JavaDoc 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 /**
322  * Handles user actions.
323  */

324 public void actionPerformed(ActionEvent e) {
325     String JavaDoc cmd = e.getActionCommand();
326     if ("Quit".equals(cmd)) maybeClose();
327 }
328
329 /**
330  * Returns a string that can be written as a resource bundle value.
331  */

332 String JavaDoc escape(String JavaDoc str) {
333     if (str == null || str.length() == 0)
334     return str;
335
336     StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
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 /**
368  * Save the file and close the window.
369  */

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 JavaDoc key = e.nextElement().toString();
381         String JavaDoc 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 /**
396  * Save the file and close the window.
397  */

398 protected void maybeClose() {
399     // Save currently selected value
400
if (xlation != null)
401     xlation.save(toField.getText());
402
403     save();
404     dispose();
405     System.exit(0);
406 }
407
408 protected String JavaDoc firstPartOf(String JavaDoc key) {
409     int pos = key.indexOf('.');
410     return (pos == -1) ? key : key.substring(0, pos);
411 }
412
413 protected List split(String JavaDoc 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 JavaDoc[] 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 JavaDoc e) {
440     e.printStackTrace();
441     }
442 }
443
444 }
445
Popular Tags