summaryrefslogtreecommitdiff
path: root/gettext-tools/src/gnu/gettext/DumpResource.java
diff options
context:
space:
mode:
Diffstat (limited to 'gettext-tools/src/gnu/gettext/DumpResource.java')
-rw-r--r--gettext-tools/src/gnu/gettext/DumpResource.java236
1 files changed, 236 insertions, 0 deletions
diff --git a/gettext-tools/src/gnu/gettext/DumpResource.java b/gettext-tools/src/gnu/gettext/DumpResource.java
new file mode 100644
index 0000000..77c6e01
--- /dev/null
+++ b/gettext-tools/src/gnu/gettext/DumpResource.java
@@ -0,0 +1,236 @@
+/* GNU gettext for Java
+ * Copyright (C) 2001-2003, 2007 Free Software Foundation, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package gnu.gettext;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.io.*;
+
+/**
+ * This programs dumps a resource as a PO file. The resource must be
+ * accessible through the CLASSPATH.
+ *
+ * @author Bruno Haible
+ */
+public class DumpResource {
+ private Writer out;
+ private void dumpString (String str) throws IOException {
+ int n = str.length();
+ out.write('"');
+ for (int i = 0; i < n; i++) {
+ char c = str.charAt(i);
+ if (c == 0x0008) {
+ out.write('\\'); out.write('b');
+ } else if (c == 0x000c) {
+ out.write('\\'); out.write('f');
+ } else if (c == 0x000a) {
+ out.write('\\'); out.write('n');
+ } else if (c == 0x000d) {
+ out.write('\\'); out.write('r');
+ } else if (c == 0x0009) {
+ out.write('\\'); out.write('t');
+ } else if (c == '\\' || c == '"') {
+ out.write('\\'); out.write(c);
+ } else
+ out.write(c);
+ }
+ out.write('"');
+ }
+ private void dumpMessage (String msgid, String msgid_plural, Object msgstr) throws IOException {
+ int separatorPos = msgid.indexOf('\u0004');
+ if (separatorPos >= 0) {
+ String msgctxt = msgid.substring(0,separatorPos);
+ msgid = msgid.substring(separatorPos+1);
+ out.write("msgctxt "); dumpString(msgctxt);
+ }
+ out.write("msgid "); dumpString(msgid); out.write('\n');
+ if (msgid_plural != null) {
+ out.write("msgid_plural "); dumpString(msgid_plural); out.write('\n');
+ for (int i = 0; i < ((String[])msgstr).length; i++) {
+ out.write("msgstr[" + i + "] ");
+ dumpString(((String[])msgstr)[i]);
+ out.write('\n');
+ }
+ } else {
+ out.write("msgstr "); dumpString((String)msgstr); out.write('\n');
+ }
+ out.write('\n');
+ }
+ private ResourceBundle catalog;
+ private Method lookupMethod;
+ // Lookup the value corresponding to a key found in catalog.getKeys().
+ // Here we assume that the catalog returns a non-inherited value for
+ // these keys. FIXME: Not true. Better see whether handleGetObject is
+ // public - it is in ListResourceBundle and PropertyResourceBundle.
+ private Object lookup (String key) {
+ Object value = null;
+ if (lookupMethod != null) {
+ try {
+ value = lookupMethod.invoke(catalog, new Object[] { key });
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ e.getTargetException().printStackTrace();
+ }
+ } else {
+ try {
+ value = catalog.getObject(key);
+ } catch (MissingResourceException e) {
+ }
+ }
+ return value;
+ }
+ private void dump () throws IOException {
+ lookupMethod = null;
+ try {
+ lookupMethod = catalog.getClass().getMethod("lookup", new Class[] { java.lang.String.class });
+ } catch (NoSuchMethodException e) {
+ } catch (SecurityException e) {
+ }
+ Method pluralMethod = null;
+ try {
+ pluralMethod = catalog.getClass().getMethod("get_msgid_plural_table", new Class[0]);
+ } catch (NoSuchMethodException e) {
+ } catch (SecurityException e) {
+ }
+ Field pluralField = null;
+ try {
+ pluralField = catalog.getClass().getField("plural");
+ } catch (NoSuchFieldException e) {
+ } catch (SecurityException e) {
+ }
+ // Search for the header entry.
+ {
+ Object header_entry = null;
+ Enumeration keys = catalog.getKeys();
+ while (keys.hasMoreElements())
+ if ("".equals(keys.nextElement())) {
+ header_entry = lookup("");
+ break;
+ }
+ // If there is no header entry, fake one.
+ // FIXME: This is not needed; right after po_lex_charset_init set
+ // the PO charset to UTF-8.
+ if (header_entry == null)
+ header_entry = "Content-Type: text/plain; charset=UTF-8\n";
+ dumpMessage("",null,header_entry);
+ }
+ // Now the other messages.
+ {
+ Enumeration keys = catalog.getKeys();
+ Object plural = null;
+ if (pluralMethod != null) {
+ // msgfmt versions > 0.13.1 create a static get_msgid_plural_table()
+ // method.
+ try {
+ plural = pluralMethod.invoke(catalog, new Object[0]);
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ e.getTargetException().printStackTrace();
+ }
+ } else if (pluralField != null) {
+ // msgfmt versions <= 0.13.1 create a static plural field.
+ try {
+ plural = pluralField.get(catalog);
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ if (plural instanceof String[]) {
+ // A GNU gettext created class with plural handling, Java2 format.
+ int i = 0;
+ while (keys.hasMoreElements()) {
+ String key = (String)keys.nextElement();
+ Object value = lookup(key);
+ String key_plural = (value instanceof String[] ? ((String[])plural)[i++] : null);
+ if (!"".equals(key))
+ dumpMessage(key,key_plural,value);
+ }
+ if (i != ((String[])plural).length)
+ throw new RuntimeException("wrong plural field length");
+ } else if (plural instanceof Hashtable) {
+ // A GNU gettext created class with plural handling, Java format.
+ while (keys.hasMoreElements()) {
+ String key = (String)keys.nextElement();
+ if (!"".equals(key)) {
+ Object value = lookup(key);
+ String key_plural = (value instanceof String[] ? (String)((Hashtable)plural).get(key) : null);
+ dumpMessage(key,key_plural,value);
+ }
+ }
+ } else if (plural == null) {
+ // No plural handling.
+ while (keys.hasMoreElements()) {
+ String key = (String)keys.nextElement();
+ if (!"".equals(key))
+ dumpMessage(key,null,lookup(key));
+ }
+ } else
+ throw new RuntimeException("wrong plural field value");
+ }
+ }
+
+ public DumpResource (String resource_name, String locale_name) {
+ // Split locale_name into language_country_variant.
+ String language;
+ String country;
+ String variant;
+ language = locale_name;
+ {
+ int i = language.indexOf('_');
+ if (i >= 0) {
+ country = language.substring(i+1);
+ language = language.substring(0,i);
+ } else
+ country = "";
+ }
+ {
+ int j = country.indexOf('_');
+ if (j >= 0) {
+ variant = country.substring(j+1);
+ country = country.substring(0,j);
+ } else
+ variant = "";
+ }
+ Locale locale = new Locale(language,country,variant);
+ // Get the resource.
+ ResourceBundle catalog = ResourceBundle.getBundle(resource_name,locale);
+ // We are only interested in the messsages belonging to the locale
+ // itself, not in the inherited messages. But catalog.getLocale() exists
+ // only in Java2 and sometimes differs from the given locale.
+ try {
+ Writer w1 = new OutputStreamWriter(System.out,"UTF8");
+ Writer w2 = new BufferedWriter(w1);
+ this.out = w2;
+ this.catalog = catalog;
+ dump();
+ w2.close();
+ w1.close();
+ System.out.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ public static void main (String[] args) {
+ new DumpResource(args[0], args.length > 1 ? args[1] : "");
+ System.exit(0);
+ }
+}