1/*
2 *****************************************************************************
3 * Copyright (C) 2000-2007, International Business Machines Corporation and  *
4 * others. All Rights Reserved.                                              *
5 *****************************************************************************
6 */
7package com.ibm.rbm;
8
9
10import java.io.*;
11import javax.swing.*;
12import java.util.*;
13
14import org.apache.xerces.dom.DocumentImpl;
15import org.apache.xml.serialize.*;
16import org.w3c.dom.*;
17
18/**
19 * This class is a plug-in to RBManager that allows the user to export Resource Bundles
20 * along with some of the meta-data associated by RBManager to the TMX specification.
21 * For more information on TMX visit the web site <a href="http://www.lisa.org/tmx/">http://www.lisa.org/tmx/</a>
22 *
23 * @author Jared Jackson
24 * @see com.ibm.rbm.RBManager
25 */
26public class RBTMXExporter extends RBExporter {
27    private static final String VERSION = "0.5a";
28
29    /**
30     * Default constructor for the TMX exporter.
31     */
32
33    public RBTMXExporter() {
34        super();
35
36        // Initialize the file chooser if necessary
37        if (chooser == null) {
38            chooser = new JFileChooser();
39            chooser.setFileFilter(new javax.swing.filechooser.FileFilter(){
40                public String getDescription() {
41                    return "TMX Files";
42                }
43                public boolean accept(File f) {
44                    if (f.isDirectory()) return true;
45                    if (f.getName().endsWith(".tmx")) return true;
46                    return false;
47                }
48            });
49        } // end if
50    }
51
52    private String convertToISO(Date d) {
53        GregorianCalendar gc = new GregorianCalendar();
54        gc.setTime(d);
55        return convertToISO(gc);
56    }
57
58    private String convertToISO(GregorianCalendar gc) {
59        StringBuffer buffer = new StringBuffer();
60        buffer.append(String.valueOf(gc.get(Calendar.YEAR)));
61        int month = gc.get(Calendar.MONTH)+1;
62        buffer.append(((month < 10) ? "0" : "") + String.valueOf(month));
63        int day = gc.get(Calendar.DAY_OF_MONTH);
64        buffer.append(((day < 10) ? "0" : "") + String.valueOf(day));
65        buffer.append("T");
66        int hour = gc.get(Calendar.HOUR_OF_DAY);
67        buffer.append(((hour < 10) ? "0" : "") + String.valueOf(hour));
68        int minute = gc.get(Calendar.MINUTE);
69        buffer.append(((minute < 10) ? "0" : "") + String.valueOf(minute));
70        int second = gc.get(Calendar.SECOND);
71        buffer.append(((second < 10) ? "0" : "") + String.valueOf(second));
72        buffer.append("Z");
73        return buffer.toString();
74    }
75
76    private String convertEncoding(BundleItem item) {
77        if (item != null && item.getParentGroup() != null && item.getParentGroup().getParentBundle() != null) {
78            String language = item.getParentGroup().getParentBundle().getLanguageEncoding();
79            String country = item.getParentGroup().getParentBundle().getCountryEncoding();
80            String variant = item.getParentGroup().getParentBundle().getVariantEncoding();
81            if (language != null && !language.equals("")) {
82                //language = language.toUpperCase();
83                if (country != null && !country.equals("")) {
84                    //country = country.toUpperCase();
85                    if (variant != null && !variant.equals("")) {
86                        //variant = variant.toUpperCase();
87                        return language + "-" + country + "-" + variant;
88                    }
89                    return language + "-" + country;
90                }
91                return language;
92            }
93        }
94        return "";
95    }
96
97    private void appendTUV(Document xml, Element tu, BundleItem item) {
98        Element tuv = xml.createElement("tuv");
99        tuv.setAttribute("lang", convertEncoding(item));
100        tuv.setAttribute("creationdate",convertToISO(item.getCreatedDate()));
101        tuv.setAttribute("creationid",item.getCreator());
102        tuv.setAttribute("changedate",convertToISO(item.getModifiedDate()));
103        tuv.setAttribute("changeid",item.getModifier());
104        item.getComment();
105        item.isTranslated();
106
107        Element comment_prop = xml.createElement("prop");
108        comment_prop.appendChild(xml.createTextNode(item.getComment()));
109        comment_prop.setAttribute("type","x-Comment");
110        tuv.appendChild(comment_prop);
111
112        Element translated_prop = xml.createElement("prop");
113        translated_prop.appendChild(xml.createTextNode(String.valueOf(item.isTranslated())));
114        translated_prop.setAttribute("type","x-Translated");
115        tuv.appendChild(translated_prop);
116
117        Hashtable lookups = item.getLookups();
118        Enumeration keys = lookups.keys();
119        while (keys.hasMoreElements()) {
120            String key = (String)keys.nextElement();
121            String value = (String)lookups.get(key);
122            Element lookup_prop = xml.createElement("prop");
123            lookup_prop.appendChild(xml.createTextNode(key + "=" + value));
124            lookup_prop.setAttribute("type","x-Lookup");
125            tuv.appendChild(lookup_prop);
126        }
127
128        Element seg = xml.createElement("seg");
129        seg.appendChild(xml.createTextNode(item.getTranslation()));
130        tuv.appendChild(seg);
131
132        tu.appendChild(tuv);
133    }
134
135    public void export(RBManager rbm) throws IOException {
136        if (rbm == null) return;
137        // Open the Save Dialog
138        int ret_val = chooser.showSaveDialog(null);
139        if (ret_val != JFileChooser.APPROVE_OPTION) return;
140        // Retrieve basic file information
141        File file = chooser.getSelectedFile();                  // The file(s) we will be working with
142        File directory = new File(file.getParent());            // The directory we will be writing to
143        String base_name = file.getName();                      // The base name of the files we will write
144        if (base_name == null || base_name.equals("")) base_name = rbm.getBaseClass();
145        if (base_name.endsWith(".tmx")) base_name = base_name.substring(0,base_name.length()-4);
146
147        String file_name = base_name + ".tmx";
148
149        Vector bundle_v = rbm.getBundles();
150        Bundle main_bundle = (Bundle)bundle_v.elementAt(0);
151
152        Document xml = new DocumentImpl();
153        Element root = xml.createElement("tmx");
154        root.setAttribute("version", "1.2");
155        xml.appendChild(root);
156
157        Element header = xml.createElement("header");
158        Element note = xml.createElement("note");
159        note.appendChild(xml.createTextNode("This document was created automatically by RBManager"));
160        header.appendChild(note);
161        header.setAttribute("creationtool", "RBManager");
162        header.setAttribute("creationtoolversion", VERSION);
163        header.setAttribute("datatype", "PlainText");
164        header.setAttribute("segtype", "sentance");
165        header.setAttribute("adminlang", "en-us");
166        header.setAttribute("srclang", "EN");
167        header.setAttribute("o-tmf", "none");
168        header.setAttribute("creationdate", convertToISO(new Date()));
169        root.appendChild(header);
170
171        Element body = xml.createElement("body");
172        root.appendChild(body);
173
174        Vector group_v = main_bundle.getGroupsAsVector();
175        // Loop through each bundle group in main_bundle
176        for (int i=0; i < group_v.size(); i++) {
177            BundleGroup main_group = (BundleGroup)group_v.elementAt(i);
178            // Gather a group of groups of the same name as main_group
179            Vector all_groups_v = new Vector();
180            for (int j=1; j < bundle_v.size(); j++) {
181                Bundle bundle = (Bundle)bundle_v.elementAt(j);
182                if (bundle.hasGroup(main_group.getName())) {
183                    Vector groups = bundle.getGroupsAsVector();
184                    for (int k=0; k < groups.size(); k++) {
185                        BundleGroup group = (BundleGroup)groups.elementAt(k);
186                        if (group.getName().equals(main_group.getName())) all_groups_v.addElement(group);
187                    }
188                }
189            } // end for - j
190            // Loop through each item in main_group
191            for (int j=0; j < main_group.getItemCount(); j++) {
192                BundleItem main_item = main_group.getBundleItem(j);
193                Element tu = xml.createElement("tu");
194                tu.setAttribute("tuid",main_item.getKey());
195                tu.setAttribute("datatype","Text");
196                // Insert the group name for the item
197                Element group_prop = xml.createElement("prop");
198                group_prop.appendChild(xml.createTextNode(main_group.getName()));
199                group_prop.setAttribute("type", "x-Group");
200                tu.appendChild(group_prop);
201                // Add the main_item to the xml
202                appendTUV(xml, tu, main_item);
203                // Loop through the rest of the groups of the same name as main_group
204                for (int k=0; k < all_groups_v.size(); k++) {
205                    BundleGroup group = (BundleGroup)all_groups_v.elementAt(k);
206                    // Loop through the items in each group
207                    for (int l=0; l < group.getItemCount(); l++) {
208                        BundleItem item = group.getBundleItem(l);
209                        if (item.getKey().equals(main_item.getKey())) {
210                            appendTUV(xml, tu, item);
211                            break;
212                        }
213                    } // end for - l
214                } // end for - k
215                body.appendChild(tu);
216            } // end for - j
217        } // end for - i
218        FileWriter fw = new FileWriter(new File(directory,file_name));
219        OutputFormat of = new OutputFormat(xml);
220        of.setIndenting(true);
221        of.setEncoding("ISO-8859-1");
222        XMLSerializer serializer = new XMLSerializer(fw, of);
223        serializer.serialize(xml);
224    }
225}