001: /*
002: *****************************************************************************
003: * Copyright (C) 2000-2004, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: *****************************************************************************
006: */
007: package com.ibm.rbm;
008:
009: import java.io.*;
010: import java.util.*;
011:
012: import javax.xml.parsers.*;
013:
014: import com.ibm.rbm.gui.RBManagerGUI;
015: import org.xml.sax.*;
016: import org.w3c.dom.*;
017:
018: /**
019: * This imports XLIFF files into RBManager.
020: * For more information see
021: * <a href="http://www.oasis-open.org/committees/xliff/documents/xliff-specification.htm">
022: * http://www.oasis-open.org/committees/xliff/documents/xliff-specification.htm</a>
023: *
024: * @author George Rhoten
025: * @see com.ibm.rbm.RBManager
026: */
027: public class RBxliffImporter extends RBImporter {
028:
029: Document xlf_xml = null;
030:
031: /**
032: * Basic constructor for the XLIFF importer from the parent RBManager data and a Dialog title.
033: */
034: public RBxliffImporter(String title, RBManager rbm, RBManagerGUI gui) {
035: super (title, rbm, gui);
036: }
037:
038: protected void setupFileChooser() {
039: chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
040: public boolean accept(File f) {
041: return (f.isDirectory() || f.getName().endsWith(".xlf"));
042: }
043:
044: public String getDescription() {
045: return Resources
046: .getTranslation("import_XLF_file_description");
047: }
048: });
049: }
050:
051: protected void beginImport() throws IOException {
052: super .beginImport();
053: File xlf_file = getChosenFile();
054:
055: try {
056: FileInputStream fis = new FileInputStream(xlf_file);
057: InputSource is = new InputSource(fis);
058: DocumentBuilder builder = DocumentBuilderFactory
059: .newInstance().newDocumentBuilder();
060: xlf_xml = builder.parse(is);
061: fis.close();
062: } catch (SAXException e) {
063: e.printStackTrace(System.err);
064: throw new IOException(e.getMessage());
065: } catch (ParserConfigurationException pce) {
066: pce.printStackTrace(System.err);
067: throw new IOException(pce.getMessage());
068: }
069: if (xlf_xml == null)
070: return;
071:
072: importDoc();
073:
074: }
075:
076: private void importDoc() {
077: if (xlf_xml == null)
078: return;
079: String language = "";
080: String bundle_note = null;
081: String bundle_name = null;
082: String manager_name = null;
083: String language_name = null;
084: String country_name = null;
085: String variant_name = null;
086:
087: Element root = xlf_xml.getDocumentElement();
088: Node fileNode = root.getFirstChild();
089: Node header = null;
090: Node node = null;
091: while (fileNode != null
092: && !(fileNode instanceof Element && fileNode
093: .getNodeName().equalsIgnoreCase("file"))) {
094: fileNode = fileNode.getNextSibling();
095: }
096: header = fileNode.getFirstChild();
097: while (header != null
098: && !(header.getNodeType() == Node.ELEMENT_NODE && (header
099: .getNodeName().equalsIgnoreCase("header") || header
100: .getNodeName().equalsIgnoreCase("body")))) {
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)
106: .getElementsByTagName("note");
107: if (header_note_list.getLength() > 0) {
108: Text text_elem = (Text) header_note_list.item(0)
109: .getChildNodes().item(0);
110: if (text_elem != null) {
111: String value = text_elem.getNodeValue();
112: if (value != null && value.length() > 0) {
113: bundle_note = value;
114: }
115: }
116: }
117: Node prop_group_list = ((Element) header)
118: .getElementsByTagName("prop-group").item(0);
119: NodeList prop_list = prop_group_list.getChildNodes();
120: int propertyNum = prop_list.getLength();
121: if (propertyNum > 0) {
122: for (int prop = 0; prop < propertyNum; prop++) {
123: if (prop_list.item(prop) instanceof Element) {
124: Element property_elem = (Element) prop_list
125: .item(prop);
126: String propertyType = property_elem
127: .getAttribute("prop-type");
128: if (propertyType != null) {
129: String value = property_elem
130: .getChildNodes().item(0)
131: .getNodeValue();
132: if (value != null && value.length() > 0) {
133: if (propertyType.equals("name")) {
134: bundle_name = value;
135: } else if (propertyType
136: .equals("manager")) {
137: manager_name = value;
138: } else if (propertyType
139: .equals("language")) {
140: language_name = value;
141: } else if (propertyType
142: .equals("country")) {
143: country_name = value;
144: } else if (propertyType
145: .equals("variant")) {
146: variant_name = value;
147: }
148: }
149: }
150: }
151: }
152: }
153: }
154: node = header.getNextSibling();
155: while (node != null
156: && !(node instanceof Element && node.getNodeName()
157: .equalsIgnoreCase("body"))) {
158: node = node.getNextSibling();
159: }
160:
161: Element body = (Element) node;
162: //resolveEncodings(getEncodingsVector(body));
163:
164: String sourceLocale = ((Element) fileNode)
165: .getAttribute("source-language");
166: String targetLocale = ((Element) fileNode)
167: .getAttribute("target-language");
168: if (!sourceLocale.equals("")) {
169: language = sourceLocale;
170: }
171: if (!targetLocale.equals("")) {
172: // The target language is the real data. The source is only for reference.
173: // We could do verification that all the data is translated the same though.
174: language = targetLocale;
175: }
176:
177: // Now do the actual import resource by resource
178: NodeList tu_list = body.getElementsByTagName("group");
179: int body_nodes_length = body.getChildNodes().getLength();
180: NodeList body_list = body.getChildNodes();
181: int groupCount = 0, elementCount = 0;
182: Node last_group_node = null;
183: for (int i = 0; i < body_nodes_length; i++) {
184: Node body_elem = body_list.item(i);
185: if (body_elem.getNodeType() == Node.ELEMENT_NODE) {
186: if (body_elem.getNodeName().equalsIgnoreCase("group")) {
187: groupCount++;
188: last_group_node = body_elem;
189: }
190: elementCount++;
191: }
192: }
193: if (elementCount == 1 && groupCount == 1) {
194: // ICU style group where the top group is just the locale.
195: Element localeNode = (Element) last_group_node;
196: tu_list = last_group_node.getChildNodes();
197: String rootGroupName = localeNode.getAttribute("id");
198: if (rootGroupName != null && rootGroupName.equals("root")) {
199: rootGroupName = "";
200: }
201: // It's done this way because ICU handles rfc3066bis (the successor of rfc3066)
202: // XLIFF requires rfc3066, which doesn't handle scripts.
203: language = rootGroupName;
204: }
205:
206: // Add the locale if needed, and normalize it to the correct format.
207: Vector localeNames = new Vector();
208: char array[] = language.toCharArray();
209: for (int k = 0; k < array.length; k++) {
210: if (array[k] == '-')
211: array[k] = '_';
212: }
213: language = String.valueOf(array);
214: localeNames.add(language);
215: resolveEncodings(localeNames);
216: Bundle main_bundle = rbm.getBundle(language);
217: main_bundle.name = bundle_name;
218: main_bundle.comment = bundle_note;
219: main_bundle.manager = manager_name;
220: main_bundle.language = language_name;
221: main_bundle.country = country_name;
222: main_bundle.variant = variant_name;
223:
224: for (int i = 0; i < tu_list.getLength(); i++) {
225: if (!(tu_list.item(i) instanceof Element)) {
226: continue;
227: }
228: Element tu_elem = (Element) tu_list.item(i);
229:
230: // Get the key value
231: String name = tu_elem.getAttribute("id");
232: if (name == null || name.length() < 1)
233: continue;
234: // Get the group if it exists
235: String group = null;
236: if (tu_elem.getNodeName().equalsIgnoreCase("group")) {
237: group = name;
238: String groupComment = "";
239: NodeList notes_list = tu_elem
240: .getElementsByTagName("note");
241: if (notes_list.getLength() > 0) {
242: Text text_elem = (Text) notes_list.item(0)
243: .getChildNodes().item(0);
244: String value = text_elem.getNodeValue();
245: if (value != null && value.length() > 0) {
246: groupComment = value;
247: }
248: }
249: rbm.createGroup(group, groupComment);
250: //NodeList group_list = tu_elem.getElementsByTagName("group");
251: }
252:
253: if (group == null || group.length() < 1) {
254: group = getDefaultGroup();
255: parseTranslationUnit(language, group, tu_elem);
256: }
257:
258: NodeList trans_unit_list = tu_elem
259: .getElementsByTagName("trans-unit");
260: // For each trans-unit element
261: for (int j = 0; j < trans_unit_list.getLength(); j++) {
262: parseTranslationUnit(language, group,
263: (Element) trans_unit_list.item(j));
264: }
265: }
266: }
267:
268: private void parseTranslationUnit(String language, String group,
269: Element trans_unit_elem) {
270: // Get the translation value
271: Node target_elem = trans_unit_elem.getElementsByTagName(
272: "target").item(0);
273: if (target_elem == null) {
274: // This is a template, or a skeleton
275: target_elem = trans_unit_elem
276: .getElementsByTagName("source").item(0);
277: }
278: // If there is a source or target, even if empty, it must be parsed.
279: if (target_elem == null)
280: return;
281: target_elem.normalize();
282: NodeList text_list = target_elem.getChildNodes();
283: if (text_list.getLength() < 1)
284: return;
285: Text text_elem = (Text) text_list.item(0);
286: String transValue = text_elem.getNodeValue();
287: if (transValue == null || transValue.length() < 1)
288: return;
289: /*NamedNodeMap attribMap = trans_unit_elem.getAttributes();
290: for (int k = 0; k < attribMap.getLength(); k++) {
291: String attribMapName = attribMap.item(k).getNodeName();
292: System.out.println(attribMapName);
293: }*/
294: String name = trans_unit_elem.getAttribute("id");
295: if (name == null || name.length() < 1)
296: return;
297: // Create the bundle item
298: BundleItem item = new BundleItem(null, name, transValue);
299: // Get creation, modification values
300:
301: String state = trans_unit_elem.getAttribute("state");
302: if (state != null && state.length() > 0) {
303: item.setTranslated(state.equalsIgnoreCase("translated"));
304: }
305:
306: String date = trans_unit_elem.getAttribute("date");
307: if (date != null && date.length() > 0) {
308: item.setModifiedDate(date);
309: }
310:
311: Element note_elem = (Element) trans_unit_elem
312: .getElementsByTagName("note").item(0);
313: if (note_elem != null) {
314: NodeList note_list = note_elem.getChildNodes();
315: if (note_list.getLength() > 0) {
316: Text note_text_elem = (Text) note_list.item(0);
317: String comment = note_text_elem.getNodeValue();
318: if (comment != null && comment.length() > 0) {
319: item.setComment(comment);
320: }
321: }
322: }
323:
324: Element prop_group_elem = (Element) trans_unit_elem
325: .getElementsByTagName("prop-group").item(0);
326: if (prop_group_elem != null) {
327: NodeList prop_list = prop_group_elem.getChildNodes();
328: int propertyLen = prop_list.getLength();
329: for (int prop = 0; prop < propertyLen; prop++) {
330: if (prop_list.item(prop) instanceof Element) {
331: Element property_elem = (Element) prop_list
332: .item(prop);
333: String propertyType = property_elem
334: .getAttribute("prop-type");
335: if (propertyType != null) {
336: String value = property_elem.getChildNodes()
337: .item(0).getNodeValue();
338: if (value != null && value.length() > 0) {
339: if (propertyType.equals("creator")) {
340: item.setCreator(value);
341: } else if (propertyType.equals("created")) {
342: item.setCreatedDate(value);
343: } else if (propertyType.equals("modifier")) {
344: item.setModifier(value);
345: }
346: }
347: }
348: }
349: }
350: }
351:
352: // if (lookups != null)
353: // item.setLookups(lookups);
354: importResource(item, language, group);
355: }
356: }
|