1 /* 2 ***************************************************************************** 3 * Copyright (C) 2000-2004, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ***************************************************************************** 6 */ 7 package com.ibm.rbm; 8 9 import java.io.*; 10 import javax.swing.*; 11 import java.util.*; 12 13 /** 14 * This class provides a plug-in exporter utility for RBManager that outputs ICU 15 * resource bundle files in the according to the file structure of Resource 16 * Bundles. Most of the meta-data is lost in this export. 17 * 18 * @author George Rhoten 19 * @see com.ibm.rbm.RBManager 20 */ 21 public class RBICUExporter extends RBExporter { 22 /** Do characters beyond \\u007f need \\u escape notation? */ 23 private boolean escapeNonAscii = false; 24 25 /** Write the meta data for each resource? */ 26 private boolean writeMetaData = true; 27 28 /** Write the groups as keys? */ 29 private boolean writeGroupsAsKeys = false; 30 RBICUExporter()31 public RBICUExporter() { 32 super(); 33 34 // Initialize the file chooser if necessary 35 if (chooser == null) { 36 chooser = new JFileChooser(); 37 chooser.setFileFilter(new javax.swing.filechooser.FileFilter(){ 38 public String getDescription() { 39 return "root ICU File"; 40 } 41 public boolean accept(File f) { 42 if (f.isDirectory()) return true; 43 return (f.getName().startsWith("root.")); 44 } 45 }); 46 } // end if 47 } 48 export(RBManager rbm)49 public void export(RBManager rbm) throws IOException { 50 if (rbm == null) return; 51 // Open the Save Dialog 52 int ret_val = chooser.showSaveDialog(null); 53 if (ret_val != JFileChooser.APPROVE_OPTION) { 54 return; 55 } 56 // Retrieve basic file information 57 File file = chooser.getSelectedFile(); // The file(s) we will be working with 58 File directory = new File(file.getParent()); // The directory we will be writing to 59 String base_name = file.getName(); // The base name of the files we will write 60 if (base_name == null || base_name.equals("")) { 61 base_name = rbm.getBaseClass(); 62 } 63 if (base_name.toLowerCase().endsWith(".properties")) { 64 base_name = base_name.substring(0,base_name.length()-11); 65 } 66 67 Vector bundle_v = rbm.getBundles(); 68 for (int i=0; i < bundle_v.size(); i++) { 69 Bundle bundle = (Bundle)bundle_v.elementAt(i); 70 String base_enc = base_name; 71 if (bundle.encoding != null && !bundle.encoding.equals("")) { 72 base_enc = base_enc + "_" + bundle.encoding; 73 } 74 String file_name = base_enc + ".txt"; 75 String header = "\ufeff// Resource Bundle: " + file_name + " - File automatically generated by RBManager at " + (new Date()); 76 77 OutputStream fos = new FileOutputStream(new File(directory, file_name)); 78 PrintWriter resOut = new PrintWriter(new OutputStreamWriter(fos, "UTF-8")); 79 80 Vector group_v = bundle.getGroupsAsVector(); 81 resOut.println(header); 82 resOut.println(base_enc + " { "); 83 for (int j=0; j < group_v.size(); j++) { 84 BundleGroup group = (BundleGroup)group_v.elementAt(j); 85 86 Vector itemVect = group.getItemsAsVector(); 87 int itemVectSize = itemVect.size(); 88 if (itemVectSize > 0) { 89 if (writeMetaData) { 90 String groupComment = group.getComment(); 91 if (groupComment != null && !groupComment.equals("")) { 92 resOut.println(" // @groupComment " + groupComment); 93 } 94 } 95 96 boolean writeGroupName = !bundle.getUngroupedGroup().getName().equals(group.getName()); 97 if (writeGroupName) { 98 if (writeGroupsAsKeys) { 99 resOut.println(" " + escapeString(group.getName(), true) + " { "); 100 } 101 else if (writeMetaData) { 102 resOut.println(" // @group " + escapeString(group.getName(), true)); 103 } 104 } 105 for (int k=0; k < itemVectSize; k++) { 106 BundleItem item = (BundleItem)itemVect.elementAt(k); 107 108 if (writeMetaData) { 109 resOut.print(" //"); 110 resOut.print(" @translated " + item.isTranslated()); 111 resOut.print(" @created " + item.getCreatedDate()); 112 resOut.print(" @modified " + item.getModifiedDate()); 113 resOut.print(" @creator " + item.getCreator()); 114 resOut.println(" @modifier " + item.getModifier()); 115 String itemComment = item.getComment(); 116 if (itemComment != null && !itemComment.equals("")) { 117 resOut.println(" // @comment " + itemComment); 118 } 119 } 120 121 resOut.println(" " + escapeString(item.getKey(), true) 122 + " { " + escapeString(item.getTranslation(), false) + " }"); 123 } // end for - k 124 if (writeGroupName && writeGroupsAsKeys) { 125 resOut.println(" }"); 126 } 127 } 128 } // end for - j 129 resOut.println("}"); 130 131 // Write out the file 132 resOut.close(); 133 fos.close(); 134 } // end for - i 135 } 136 137 /** 138 * Escape a string according to how the ICU tool "genrb" handles strings. 139 * @param str The string to escape 140 * @param isKey If this is a key, then quotes are optional. 141 * @return A string that can be used in an ICU resource bundle. 142 */ escapeString(String str, boolean isKey)143 protected String escapeString(String str, boolean isKey) throws IOException { 144 StringBuffer strBuf = new StringBuffer(); 145 int len = str.length(); 146 boolean quoteRequired = !isKey; 147 for (int idx = 0; idx < len; idx++) { 148 int ch = str.charAt(idx); 149 if (ch <= ' ' || '~' < ch) { 150 if (isKey && ch != ' ') { 151 IOException e = new IOException(str + " needs to use invariant characters for the key."); 152 e.fillInStackTrace(); 153 throw e; 154 } else if (escapeNonAscii && ch != ' ') { 155 String zeros; 156 String hexNum; 157 if ((ch & 0xf800) == 0xd800) { 158 // We assume that we found a valid UTF-16 string with a surrogate 159 int ch2 = str.charAt(idx++); 160 int chSurrogate = (((ch)<<10)+(ch2)-((0xd800<<10)+0xdc00-0x10000)); 161 162 zeros = "00000000"; 163 hexNum = Integer.toHexString(chSurrogate); 164 strBuf.append("\\U"); 165 } else { 166 zeros = "0000"; 167 hexNum = Integer.toHexString(ch); 168 strBuf.append("\\u"); 169 } 170 strBuf.append(zeros.substring(hexNum.length()) + hexNum.toUpperCase()); 171 } else { 172 quoteRequired = true; 173 strBuf.append(ch); 174 } 175 } else if (ch == '\"') { 176 quoteRequired = true; 177 strBuf.append("\\\""); 178 } else { 179 if (ch == '{' || ch == '}') { 180 quoteRequired = true; 181 } 182 strBuf.append(ch); 183 } 184 } 185 if (quoteRequired) { 186 strBuf.insert(0, '\"'); 187 strBuf.append('\"'); 188 } 189 return strBuf.toString(); 190 } 191 }