/* ***************************************************************************** * Copyright (C) 2000-2004, International Business Machines Corporation and * * others. All Rights Reserved. * ***************************************************************************** */ package com.ibm.rbm; import java.io.*; import javax.swing.*; import java.util.*; /** * This class provides a plug-in exporter utility for RBManager that outputs ICU * resource bundle files in the according to the file structure of Resource * Bundles. Most of the meta-data is lost in this export. * * @author George Rhoten * @see com.ibm.rbm.RBManager */ public class RBICUExporter extends RBExporter { /** Do characters beyond \\u007f need \\u escape notation? */ private boolean escapeNonAscii = false; /** Write the meta data for each resource? */ private boolean writeMetaData = true; /** Write the groups as keys? */ private boolean writeGroupsAsKeys = false; public RBICUExporter() { super(); // Initialize the file chooser if necessary if (chooser == null) { chooser = new JFileChooser(); chooser.setFileFilter(new javax.swing.filechooser.FileFilter(){ public String getDescription() { return "root ICU File"; } public boolean accept(File f) { if (f.isDirectory()) return true; return (f.getName().startsWith("root.")); } }); } // end if } public void export(RBManager rbm) throws IOException { if (rbm == null) return; // Open the Save Dialog int ret_val = chooser.showSaveDialog(null); if (ret_val != JFileChooser.APPROVE_OPTION) { return; } // Retrieve basic file information File file = chooser.getSelectedFile(); // The file(s) we will be working with File directory = new File(file.getParent()); // The directory we will be writing to String base_name = file.getName(); // The base name of the files we will write if (base_name == null || base_name.equals("")) { base_name = rbm.getBaseClass(); } if (base_name.toLowerCase().endsWith(".properties")) { base_name = base_name.substring(0,base_name.length()-11); } Vector bundle_v = rbm.getBundles(); for (int i=0; i < bundle_v.size(); i++) { Bundle bundle = (Bundle)bundle_v.elementAt(i); String base_enc = base_name; if (bundle.encoding != null && !bundle.encoding.equals("")) { base_enc = base_enc + "_" + bundle.encoding; } String file_name = base_enc + ".txt"; String header = "\ufeff// Resource Bundle: " + file_name + " - File automatically generated by RBManager at " + (new Date()); OutputStream fos = new FileOutputStream(new File(directory, file_name)); PrintWriter resOut = new PrintWriter(new OutputStreamWriter(fos, "UTF-8")); Vector group_v = bundle.getGroupsAsVector(); resOut.println(header); resOut.println(base_enc + " { "); for (int j=0; j < group_v.size(); j++) { BundleGroup group = (BundleGroup)group_v.elementAt(j); Vector itemVect = group.getItemsAsVector(); int itemVectSize = itemVect.size(); if (itemVectSize > 0) { if (writeMetaData) { String groupComment = group.getComment(); if (groupComment != null && !groupComment.equals("")) { resOut.println(" // @groupComment " + groupComment); } } boolean writeGroupName = !bundle.getUngroupedGroup().getName().equals(group.getName()); if (writeGroupName) { if (writeGroupsAsKeys) { resOut.println(" " + escapeString(group.getName(), true) + " { "); } else if (writeMetaData) { resOut.println(" // @group " + escapeString(group.getName(), true)); } } for (int k=0; k < itemVectSize; k++) { BundleItem item = (BundleItem)itemVect.elementAt(k); if (writeMetaData) { resOut.print(" //"); resOut.print(" @translated " + item.isTranslated()); resOut.print(" @created " + item.getCreatedDate()); resOut.print(" @modified " + item.getModifiedDate()); resOut.print(" @creator " + item.getCreator()); resOut.println(" @modifier " + item.getModifier()); String itemComment = item.getComment(); if (itemComment != null && !itemComment.equals("")) { resOut.println(" // @comment " + itemComment); } } resOut.println(" " + escapeString(item.getKey(), true) + " { " + escapeString(item.getTranslation(), false) + " }"); } // end for - k if (writeGroupName && writeGroupsAsKeys) { resOut.println(" }"); } } } // end for - j resOut.println("}"); // Write out the file resOut.close(); fos.close(); } // end for - i } /** * Escape a string according to how the ICU tool "genrb" handles strings. * @param str The string to escape * @param isKey If this is a key, then quotes are optional. * @return A string that can be used in an ICU resource bundle. */ protected String escapeString(String str, boolean isKey) throws IOException { StringBuffer strBuf = new StringBuffer(); int len = str.length(); boolean quoteRequired = !isKey; for (int idx = 0; idx < len; idx++) { int ch = str.charAt(idx); if (ch <= ' ' || '~' < ch) { if (isKey && ch != ' ') { IOException e = new IOException(str + " needs to use invariant characters for the key."); e.fillInStackTrace(); throw e; } else if (escapeNonAscii && ch != ' ') { String zeros; String hexNum; if ((ch & 0xf800) == 0xd800) { // We assume that we found a valid UTF-16 string with a surrogate int ch2 = str.charAt(idx++); int chSurrogate = (((ch)<<10)+(ch2)-((0xd800<<10)+0xdc00-0x10000)); zeros = "00000000"; hexNum = Integer.toHexString(chSurrogate); strBuf.append("\\U"); } else { zeros = "0000"; hexNum = Integer.toHexString(ch); strBuf.append("\\u"); } strBuf.append(zeros.substring(hexNum.length()) + hexNum.toUpperCase()); } else { quoteRequired = true; strBuf.append(ch); } } else if (ch == '\"') { quoteRequired = true; strBuf.append("\\\""); } else { if (ch == '{' || ch == '}') { quoteRequired = true; } strBuf.append(ch); } } if (quoteRequired) { strBuf.insert(0, '\"'); strBuf.append('\"'); } return strBuf.toString(); } }