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 10 import java.io.*; 11 import java.util.*; 12 13 import javax.xml.parsers.*; 14 15 import com.ibm.rbm.gui.RBManagerGUI; 16 import org.xml.sax.*; 17 import org.w3c.dom.*; 18 19 /** 20 * This imports XLIFF files into RBManager. 21 * For more information see 22 * <a href="http://www.oasis-open.org/committees/xliff/documents/xliff-specification.htm"> 23 * http://www.oasis-open.org/committees/xliff/documents/xliff-specification.htm</a> 24 * 25 * @author George Rhoten 26 * @see com.ibm.rbm.RBManager 27 */ 28 public class RBxliffImporter extends RBImporter { 29 30 Document xlf_xml = null; 31 32 /** 33 * Basic constructor for the XLIFF importer from the parent RBManager data and a Dialog title. 34 */ RBxliffImporter(String title, RBManager rbm, RBManagerGUI gui)35 public RBxliffImporter(String title, RBManager rbm, RBManagerGUI gui) { 36 super(title, rbm, gui); 37 } 38 setupFileChooser()39 protected void setupFileChooser() { 40 chooser.setFileFilter(new javax.swing.filechooser.FileFilter(){ 41 public boolean accept(File f) { 42 return (f.isDirectory() || f.getName().endsWith(".xlf")); 43 } 44 45 public String getDescription() { 46 return Resources.getTranslation("import_XLF_file_description"); 47 } 48 }); 49 } 50 beginImport()51 protected void beginImport() throws IOException { 52 super.beginImport(); 53 File xlf_file = getChosenFile(); 54 55 try { 56 FileInputStream fis = new FileInputStream(xlf_file); 57 InputSource is = new InputSource(fis); 58 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 59 xlf_xml = builder.parse(is); 60 fis.close(); 61 } 62 catch (SAXException e) { 63 e.printStackTrace(System.err); 64 throw new IOException(e.getMessage()); 65 } 66 catch (ParserConfigurationException pce) { 67 pce.printStackTrace(System.err); 68 throw new IOException(pce.getMessage()); 69 } 70 if (xlf_xml == null) 71 return; 72 73 importDoc(); 74 75 } 76 importDoc()77 private void importDoc() { 78 if (xlf_xml == null) 79 return; 80 String language = ""; 81 String bundle_note = null; 82 String bundle_name = null; 83 String manager_name = null; 84 String language_name = null; 85 String country_name = null; 86 String variant_name = null; 87 88 Element root = xlf_xml.getDocumentElement(); 89 Node fileNode = root.getFirstChild(); 90 Node header = null; 91 Node node = null; 92 while (fileNode != null && !(fileNode instanceof Element && fileNode.getNodeName().equalsIgnoreCase("file"))) { 93 fileNode = fileNode.getNextSibling(); 94 } 95 header = fileNode.getFirstChild(); 96 while (header != null 97 && !(header.getNodeType() == Node.ELEMENT_NODE 98 && (header.getNodeName().equalsIgnoreCase("header") 99 || header.getNodeName().equalsIgnoreCase("body")))) 100 { 101 header = header.getNextSibling(); 102 } 103 if (header.getNodeName().equalsIgnoreCase("header")) { 104 // Get the notes if from the header if they exist. 105 NodeList header_note_list = ((Element)header).getElementsByTagName("note"); 106 if (header_note_list.getLength() > 0) { 107 Text text_elem = (Text)header_note_list.item(0).getChildNodes().item(0); 108 if (text_elem != null) { 109 String value = text_elem.getNodeValue(); 110 if (value != null && value.length() > 0) { 111 bundle_note = value; 112 } 113 } 114 } 115 Node prop_group_list = ((Element)header).getElementsByTagName("prop-group").item(0); 116 NodeList prop_list = prop_group_list.getChildNodes(); 117 int propertyNum = prop_list.getLength(); 118 if (propertyNum > 0) { 119 for (int prop = 0; prop < propertyNum; prop++) { 120 if (prop_list.item(prop) instanceof Element) { 121 Element property_elem = (Element)prop_list.item(prop); 122 String propertyType = property_elem.getAttribute("prop-type"); 123 if (propertyType != null) { 124 String value = property_elem.getChildNodes().item(0).getNodeValue(); 125 if (value != null && value.length() > 0) { 126 if (propertyType.equals("name")) { 127 bundle_name = value; 128 } 129 else if (propertyType.equals("manager")) { 130 manager_name = value; 131 } 132 else if (propertyType.equals("language")) { 133 language_name = value; 134 } 135 else if (propertyType.equals("country")) { 136 country_name = value; 137 } 138 else if (propertyType.equals("variant")) { 139 variant_name = value; 140 } 141 } 142 } 143 } 144 } 145 } 146 } 147 node = header.getNextSibling(); 148 while (node != null && !(node instanceof Element && node.getNodeName().equalsIgnoreCase("body"))) { 149 node = node.getNextSibling(); 150 } 151 152 Element body = (Element)node; 153 //resolveEncodings(getEncodingsVector(body)); 154 155 String sourceLocale = ((Element)fileNode).getAttribute("source-language"); 156 String targetLocale = ((Element)fileNode).getAttribute("target-language"); 157 if (!sourceLocale.equals("")) { 158 language = sourceLocale; 159 } 160 if (!targetLocale.equals("")) { 161 // The target language is the real data. The source is only for reference. 162 // We could do verification that all the data is translated the same though. 163 language = targetLocale; 164 } 165 166 // Now do the actual import resource by resource 167 NodeList tu_list = body.getElementsByTagName("group"); 168 int body_nodes_length = body.getChildNodes().getLength(); 169 NodeList body_list = body.getChildNodes(); 170 int groupCount = 0, elementCount = 0; 171 Node last_group_node = null; 172 for (int i=0; i < body_nodes_length; i++) { 173 Node body_elem = body_list.item(i); 174 if (body_elem.getNodeType() == Node.ELEMENT_NODE) { 175 if (body_elem.getNodeName().equalsIgnoreCase("group")) { 176 groupCount++; 177 last_group_node = body_elem; 178 } 179 elementCount++; 180 } 181 } 182 if (elementCount == 1 && groupCount == 1) { 183 // ICU style group where the top group is just the locale. 184 Element localeNode = (Element)last_group_node; 185 tu_list = last_group_node.getChildNodes(); 186 String rootGroupName = localeNode.getAttribute("id"); 187 if (rootGroupName != null && rootGroupName.equals("root")) { 188 rootGroupName = ""; 189 } 190 // It's done this way because ICU handles rfc3066bis (the successor of rfc3066) 191 // XLIFF requires rfc3066, which doesn't handle scripts. 192 language = rootGroupName; 193 } 194 195 // Add the locale if needed, and normalize it to the correct format. 196 Vector localeNames = new Vector(); 197 char array[] = language.toCharArray(); 198 for (int k=0; k < array.length; k++) { 199 if (array[k] == '-') 200 array[k] = '_'; 201 } 202 language = String.valueOf(array); 203 localeNames.add(language); 204 resolveEncodings(localeNames); 205 Bundle main_bundle = rbm.getBundle(language); 206 main_bundle.name = bundle_name; 207 main_bundle.comment = bundle_note; 208 main_bundle.manager = manager_name; 209 main_bundle.language = language_name; 210 main_bundle.country = country_name; 211 main_bundle.variant = variant_name; 212 213 for (int i=0; i < tu_list.getLength(); i++) { 214 if (!(tu_list.item(i) instanceof Element)) { 215 continue; 216 } 217 Element tu_elem = (Element)tu_list.item(i); 218 219 // Get the key value 220 String name = tu_elem.getAttribute("id"); 221 if (name == null || name.length() < 1) 222 continue; 223 // Get the group if it exists 224 String group = null; 225 if (tu_elem.getNodeName().equalsIgnoreCase("group")) { 226 group = name; 227 String groupComment = ""; 228 NodeList notes_list = tu_elem.getElementsByTagName("note"); 229 if (notes_list.getLength() > 0) { 230 Text text_elem = (Text)notes_list.item(0).getChildNodes().item(0); 231 String value = text_elem.getNodeValue(); 232 if (value != null && value.length() > 0) { 233 groupComment = value; 234 } 235 } 236 rbm.createGroup(group, groupComment); 237 //NodeList group_list = tu_elem.getElementsByTagName("group"); 238 } 239 240 if (group == null || group.length() < 1) { 241 group = getDefaultGroup(); 242 parseTranslationUnit(language, group, tu_elem); 243 } 244 245 NodeList trans_unit_list = tu_elem.getElementsByTagName("trans-unit"); 246 // For each trans-unit element 247 for (int j=0; j < trans_unit_list.getLength(); j++) { 248 parseTranslationUnit(language, group, (Element)trans_unit_list.item(j)); 249 } 250 } 251 } 252 parseTranslationUnit(String language, String group, Element trans_unit_elem)253 private void parseTranslationUnit(String language, String group, Element trans_unit_elem) { 254 // Get the translation value 255 Node target_elem = trans_unit_elem.getElementsByTagName("target").item(0); 256 if (target_elem == null) { 257 // This is a template, or a skeleton 258 target_elem = trans_unit_elem.getElementsByTagName("source").item(0); 259 } 260 // If there is a source or target, even if empty, it must be parsed. 261 if (target_elem == null) 262 return; 263 target_elem.normalize(); 264 NodeList text_list = target_elem.getChildNodes(); 265 if (text_list.getLength() < 1) 266 return; 267 Text text_elem = (Text)text_list.item(0); 268 String transValue = text_elem.getNodeValue(); 269 if (transValue == null || transValue.length() < 1) 270 return; 271 /*NamedNodeMap attribMap = trans_unit_elem.getAttributes(); 272 for (int k = 0; k < attribMap.getLength(); k++) { 273 String attribMapName = attribMap.item(k).getNodeName(); 274 System.out.println(attribMapName); 275 }*/ 276 String name = trans_unit_elem.getAttribute("id"); 277 if (name == null || name.length() < 1) 278 return; 279 // Create the bundle item 280 BundleItem item = new BundleItem(null, name, transValue); 281 // Get creation, modification values 282 283 String state = trans_unit_elem.getAttribute("state"); 284 if (state != null && state.length() > 0) { 285 item.setTranslated(state.equalsIgnoreCase("translated")); 286 } 287 288 String date = trans_unit_elem.getAttribute("date"); 289 if (date != null && date.length() > 0) { 290 item.setModifiedDate(date); 291 } 292 293 Element note_elem = (Element)trans_unit_elem.getElementsByTagName("note").item(0); 294 if (note_elem != null) { 295 NodeList note_list = note_elem.getChildNodes(); 296 if (note_list.getLength() > 0) { 297 Text note_text_elem = (Text)note_list.item(0); 298 String comment = note_text_elem.getNodeValue(); 299 if (comment != null && comment.length() > 0) { 300 item.setComment(comment); 301 } 302 } 303 } 304 305 Element prop_group_elem = (Element)trans_unit_elem.getElementsByTagName("prop-group").item(0); 306 if (prop_group_elem != null) { 307 NodeList prop_list = prop_group_elem.getChildNodes(); 308 int propertyLen = prop_list.getLength(); 309 for (int prop = 0; prop < propertyLen; prop++) { 310 if (prop_list.item(prop) instanceof Element) { 311 Element property_elem = (Element)prop_list.item(prop); 312 String propertyType = property_elem.getAttribute("prop-type"); 313 if (propertyType != null) { 314 String value = property_elem.getChildNodes().item(0).getNodeValue(); 315 if (value != null && value.length() > 0) { 316 if (propertyType.equals("creator")) { 317 item.setCreator(value); 318 } 319 else if (propertyType.equals("created")) { 320 item.setCreatedDate(value); 321 } 322 else if (propertyType.equals("modifier")) { 323 item.setModifier(value); 324 } 325 } 326 } 327 } 328 } 329 } 330 331 // if (lookups != null) 332 // item.setLookups(lookups); 333 importResource(item, language, group); 334 } 335 } 336