• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *****************************************************************************
3  * Copyright (C) 2000-2007, 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 
12 import com.ibm.rbm.gui.RBManagerGUI;
13 
14 import java.util.*;
15 import java.awt.*;
16 import java.awt.event.*;
17 
18 /**
19  * <P>This is the super class for all importer plug-in classes.</P>
20  * <P>
21  * In terms of general functionality of this class or its children classes, the following steps should happen in order:
22  * <OL>
23  * <LI>A Dialog is shown from which the user may select options about the import, including the file from which to import.</LI>
24  * <LI>The 'Import' button is pressed, closing the options dialog and opening a progress bar dialog box.</LI>
25  * <LI>The class should resolve all conflicts with locale encodings existing in the import files, but not in the active resource bundle.</LI>
26  * <LI>The class should parse resources one at a time and use the importResource() method to insert them into the resource bundle.</LI>
27  * <LI>The class should report when all resources have been read and the import is complete.</LI>
28  * </OL>
29  * </P>
30  *
31  * @author Jared Jackson
32  * @see com.ibm.rbm.RBManager
33  */
34 public class RBImporter extends JDialog {
35     private final static int FILE_OPTION_POPULATE      = 0;            // Create a new locale file populated from base file
36     private final static int FILE_OPTION_EMPTY         = 1;            // Create a new empty locale file
37     private final static int FILE_OPTION_IGNORE        = 2;            // Ignore all resources from this encoding
38     private final static int FILE_OPTION_PROMPT        = 3;            // Prompt for each conflict
39     private final static int RESOURCE_OPTION_OVERWRITE = 0;            // Use the value from the source import file
40     private final static int RESOURCE_OPTION_IGNORE    = 1;            // Ignore the import and use existing value
41     private final static int RESOURCE_OPTION_PROMPT    = 2;            // Propmpt for each conflict
42 
43     protected static JFileChooser chooser;
44     protected int    num_conflicts;
45     protected int    num_extra_files;
46     protected String title;
47     protected RBManager rbm;
48     protected RBManagerGUI gui;
49     protected boolean pathSet = false;
50 
51     // Visual Components
52     JRadioButton resourceOverwriteRadio    = new JRadioButton(Resources.getTranslation("import_resource_conflict_overwrite"), false);
53     JRadioButton resourceIgnoreRadio       = new JRadioButton(Resources.getTranslation("import_resource_conflict_ignore"), false);
54     JRadioButton resourcePromptRadio       = new JRadioButton(Resources.getTranslation("import_conflict_prompt"), true);
55     JRadioButton fileGeneratePopulateRadio = new JRadioButton(Resources.getTranslation("import_file_conflict_generate_populate"), false);
56     JRadioButton fileGenerateEmptyRadio    = new JRadioButton(Resources.getTranslation("import_file_conflict_generate_empty"), false);
57     JRadioButton fileIgnoreRadio           = new JRadioButton(Resources.getTranslation("import_file_conflict_ignore"), false);
58     JRadioButton filePromptRadio           = new JRadioButton(Resources.getTranslation("import_conflict_prompt"), true);
59 
60     JCheckBox markTranslatedCheck = new JCheckBox(Resources.getTranslation("import_default_translated"), true);
61     JCheckBox createGroupsCheck = new JCheckBox(Resources.getTranslation("import_default_group_creation"), true);
62     JComboBox groupComboBox = new JComboBox();
63 
64     JLabel sourceLabel;
65 
66     JDialog progressBarDialog;
67     JProgressBar progressBar;
68 
69     /**
70      * Constructor
71      * @param title The title that appears in the Dialog box
72      * @param rbm An RBManager instance
73      * @param gui The RBManager GUI instance associated with the RBManager instance
74      */
75 
RBImporter(String title, RBManager rbm, RBManagerGUI gui)76     public RBImporter(String title, RBManager rbm, RBManagerGUI gui) {
77         super(new Frame(), title, true);
78         this.title = title;
79         this.rbm = rbm;
80         this.gui = gui;
81         init();
82     }
83 
init()84     protected void init() {
85         chooser = new JFileChooser();
86         setupFileChooser();
87         num_conflicts = 0;
88         num_extra_files = 0;
89         initComponents();
90         setVisible(true);
91     }
92 
setupFileChooser()93     protected void setupFileChooser() {
94         // To be overwritten
95     }
96 
beginImport()97     protected void beginImport() throws IOException {
98         // To be overwritten
99         if (!pathSet)
100             throw new IOException("Path not set yet");
101     }
102 
chooseFile()103     protected void chooseFile() {
104         int result = chooser.showOpenDialog(this);
105         if (result == JFileChooser.APPROVE_OPTION) {
106             File f = chooser.getSelectedFile();
107             sourceLabel.setText(Resources.getTranslation("import_source_file",f.getAbsolutePath()));
108             pathSet = true;
109         }
110     }
111 
getChosenFile()112     protected File getChosenFile() {
113         return chooser.getSelectedFile();
114     }
115 
116     /**
117      * A super class method intended for use of nearly all subclass importers, once a resource
118      * is found by those subclasses. This method is called in order to create the new resource
119      * and handle the various conflict errors that may result as a part of that import.
120      */
121 
importResource(BundleItem item, String encoding, String group_name)122     protected void importResource(BundleItem item, String encoding, String group_name) {
123         Bundle bundle = null;
124         BundleGroup group = null;
125         BundleGroup backup_group = null;
126 
127         if (group_name == null)
128         	group_name = getDefaultGroup();
129         if (encoding == null)
130         	return;
131         // Get the bundle to which we will be adding this resource
132         bundle = rbm.getBundle(encoding);
133         // Skip this import if the bundle is non-existent (Should have been resolved if wanted)
134         if (bundle == null)
135         	return;
136         // Find the group in the bundle, Ungrouped if non-existent
137         Vector gv = bundle.getGroupsAsVector();
138         for (int i=0; i < gv.size(); i++) {
139             BundleGroup tempg = (BundleGroup)gv.elementAt(i);
140             if (i==0) backup_group = tempg;
141             if (tempg.getName().equals("Ungrouped Items")) backup_group = tempg;
142             else if (tempg.getName().equals(group_name)) {
143                 group = tempg;
144                 break;
145             }
146         }
147         if (group == null) {
148             if (getDefaultGroupCreation()) {
149                 // Create a new group by this name
150                 bundle.addBundleGroup(group_name, "");
151                 gv = bundle.getGroupsAsVector();
152                 for (int i=0; i < gv.size(); i++) {
153                     BundleGroup tempg = (BundleGroup)gv.elementAt(i);
154                     if (tempg.getName().equals(group_name)) {
155                         group = tempg;
156                         break;
157                     }
158                 }
159             } else {
160                 // Use the backup_group
161                 group = backup_group;
162             }
163         }
164         // If all group identification efforts fail, we fail
165         if (group == null)
166         	return;
167         item.setParentGroup(group);
168         // Check for and resolve conflicts
169         if (bundle.allItems.containsKey(item.getKey())) {
170             resolveResource(bundle,item);
171             RBManagerGUI.debugMsg("Resolve conflict");
172         } else {
173             // Insert the resource
174             bundle.addBundleItem(item);
175         }
176     }
177 
178     /**
179      * This method should be called when trying to import and item whose key all ready exists within the bundle.
180      */
181 
resolveResource(Bundle bundle, BundleItem item)182     protected void resolveResource(Bundle bundle, BundleItem item) {
183         if (this.getResourceConflictOption() == RESOURCE_OPTION_IGNORE)
184         	return;
185         else if (this.getResourceConflictOption() == RESOURCE_OPTION_OVERWRITE) {
186             bundle.removeItem(item.getKey());
187             bundle.addBundleItem(item);
188         } else if (this.getResourceConflictOption() == RESOURCE_OPTION_PROMPT) {
189             BundleItem original = (BundleItem)bundle.allItems.get(item.getKey());
190             if (original == null)
191             	return;
192             String trans = original.getTranslation();
193             String options[] = { Resources.getTranslation("import_resource_conflict_overwrite"),
194                                  Resources.getTranslation("import_resource_conflict_ignore")};
195             String insert[] = {item.getKey(), (bundle.encoding.equals("") ? "(Base Class)" : bundle.encoding)};
196             String result = (String)JOptionPane.showInputDialog(this,  Resources.getTranslation("import_resource_conflict_choose", insert) +
197                 "\n" + Resources.getTranslation("import_resource_conflict_choose_source", item.getTranslation()) +
198                 "\n" + Resources.getTranslation("import_resource_conflict_choose_target", trans),
199                 Resources.getTranslation("import_file_conflicts"), JOptionPane.QUESTION_MESSAGE,
200                 null, options, options[0]);
201             if (result == null)
202             	return;
203             if (result.equals(Resources.getTranslation("import_resource_conflict_overwrite"))) {
204                 bundle.removeItem(item.getKey());
205                 bundle.addBundleItem(item);
206             } else if (result.equals(Resources.getTranslation("import_resource_conflict_ignore")))
207             	return;
208         }
209     }
210 
211     /**
212      * Given a vector of strings containing locale encodings (e.g. {"en", "en_us", "de"}), attempts
213      * to resolve those conflicts according to the preferences selected by the user.
214      */
215 
resolveEncodings(Vector v)216     protected void resolveEncodings(Vector v) {
217         for (int i=0; i < v.size(); i++) {
218             String encoding = (String)v.elementAt(i);
219             if (encoding == null || encoding.equals("") || rbm.hasResource(encoding)) {
220                 continue;
221             }
222 
223             // We need to resolve this conflict
224             if (this.getFileConflictOption() == FILE_OPTION_IGNORE) continue;
225             else if (this.getFileConflictOption() == FILE_OPTION_POPULATE) {
226                 rbm.createResource(null, null, null, encoding, null, null, null, true);
227             } else if (this.getFileConflictOption() == FILE_OPTION_EMPTY) {
228                 rbm.createResource(null, null, null, encoding, null, null, null, true);
229             } else if (this.getFileConflictOption() == FILE_OPTION_PROMPT) {
230                 String options[] = { Resources.getTranslation("import_file_conflict_generate_populate"),
231                                      Resources.getTranslation("import_file_conflict_generate_empty"),
232                                      Resources.getTranslation("import_file_conflict_ignore")};
233 
234                 String result = (String)JOptionPane.showInputDialog(this, Resources.getTranslation("import_file_conflict_choose", encoding),
235                     Resources.getTranslation("import_file_conflicts"), JOptionPane.QUESTION_MESSAGE,
236                     null, options, options[0]);
237                 if (result == null) continue;
238                 if (result.equals(Resources.getTranslation("import_file_conflict_ignore"))) continue;
239                 else if (result.equals(Resources.getTranslation("import_file_conflict_generate_populate"))) {
240                     rbm.createResource(null, null, null, encoding, null, null, null, true);
241                 } else if (result.equals(Resources.getTranslation("import_file_conflict_generate_empty"))) {
242                     rbm.createResource(null, null, null, encoding, null, null, null, false);
243                 }
244             }
245         }
246         gui.updateDisplayTree();
247     }
248 
249     // Returns an integer mask describing the user's selection for file resolving missing file locale conflicts
250 
getFileConflictOption()251     private int getFileConflictOption() {
252         if (fileGeneratePopulateRadio.isSelected()) return FILE_OPTION_POPULATE;
253         if (fileGenerateEmptyRadio.isSelected()) return FILE_OPTION_EMPTY;
254         if (fileIgnoreRadio.isSelected()) return FILE_OPTION_IGNORE;
255         if (filePromptRadio.isSelected()) return FILE_OPTION_PROMPT;
256         return FILE_OPTION_PROMPT;
257     }
258 
259     // Returns an integer mask describing the user's selection for duplicate resource key conflicts
260 
getResourceConflictOption()261     private int getResourceConflictOption() {
262         if (resourceOverwriteRadio.isSelected()) return RESOURCE_OPTION_OVERWRITE;
263         if (resourceIgnoreRadio.isSelected()) return RESOURCE_OPTION_IGNORE;
264         if (resourcePromptRadio.isSelected()) return RESOURCE_OPTION_PROMPT;
265         return RESOURCE_OPTION_PROMPT;
266     }
267 
268     // Returns the group name for use when no group name is specified
269 
getDefaultGroup()270     protected String getDefaultGroup() {
271         return groupComboBox.getSelectedItem().toString();
272     }
273 
274     // Returns the default translation value
275 
getDefaultTranslated()276     protected boolean getDefaultTranslated() {
277         return markTranslatedCheck.isSelected();
278     }
279 
280     // Returns whether or not a group of name non-existant in the active bundle is created
281 
getDefaultGroupCreation()282     protected boolean getDefaultGroupCreation() {
283         return createGroupsCheck.isSelected();
284     }
285 
showProgressBar(int steps)286     protected void showProgressBar(int steps) {
287         thisWindowClosing();
288         JDialog progressBarDialog = new JDialog(this, Resources.getTranslation("dialog_title_import_progress"), false);
289         JProgressBar progressBar = new JProgressBar(0, steps);
290         progressBar.setValue(0);
291         progressBarDialog.getContentPane().add(progressBar);
292         progressBarDialog.pack();
293         progressBarDialog.setVisible(true);
294     }
295 
incrementProgressBar()296     protected void incrementProgressBar() {
297         if (progressBar == null) return;
298         progressBar.setValue(progressBar.getValue()+1);
299         if (progressBar.getValue() == progressBar.getMaximum()) hideProgressBar();
300     }
301 
hideProgressBar()302     protected void hideProgressBar() {
303         if (progressBarDialog != null) progressBarDialog.setVisible(false);
304     }
305 
306     /**
307      * Initialize the visual components for selecting an import file and setting the appropriate
308      * options
309      */
310 
initComponents()311     protected void initComponents() {
312         // Create Components
313         JLabel titleLabel       = new JLabel(title);
314         sourceLabel             = new JLabel(Resources.getTranslation("import_source_file","--"));
315         JLabel insertGroupLabel = new JLabel(Resources.getTranslation("import_insert_group"));
316 
317         JButton fileChooseButton = new JButton(Resources.getTranslation("button_choose"));
318         JButton cancelButton     = new JButton(Resources.getTranslation("button_cancel"));
319         JButton importButton     = new JButton(Resources.getTranslation("button_import"));
320 
321         ButtonGroup resourceGroup = new ButtonGroup();
322         ButtonGroup fileGroup = new ButtonGroup();
323 
324         JPanel topPanel = new JPanel(new BorderLayout());
325         JPanel midPanel = new JPanel(new BorderLayout());
326         JPanel botPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
327 
328         JPanel topInnerPanel = new JPanel(new BorderLayout());
329 
330         Box midBox = new Box(BoxLayout.Y_AXIS);
331 
332         JPanel resourcePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
333         JPanel filePanel     = new JPanel(new FlowLayout(FlowLayout.LEFT));
334         JPanel defaultPanel  = new JPanel(new FlowLayout(FlowLayout.LEFT));
335         JPanel defaultPanel2 = new JPanel(new BorderLayout());
336 
337         Box resourceBox = new Box(BoxLayout.Y_AXIS);
338         Box fileBox     = new Box(BoxLayout.Y_AXIS);
339         Box groupBox    = new Box(BoxLayout.X_AXIS);
340 
341         // Setup title
342         titleLabel.setFont(new Font("Serif",Font.BOLD,16));
343 
344         // Setup panels
345         midPanel.setBorder(BorderFactory.createTitledBorder(Resources.getTranslation("import_options")));
346         resourcePanel.setBorder(BorderFactory.createTitledBorder(Resources.getTranslation("import_resource_conflicts")));
347         filePanel.setBorder(BorderFactory.createTitledBorder(Resources.getTranslation("import_file_conflicts")));
348         defaultPanel.setBorder(BorderFactory.createTitledBorder(Resources.getTranslation("import_default_values")));
349 
350         // Arrange button groups
351         fileGroup.add(fileGeneratePopulateRadio);
352         fileGroup.add(fileGenerateEmptyRadio);
353         fileGroup.add(fileIgnoreRadio);
354         fileGroup.add(filePromptRadio);
355         resourceGroup.add(resourceOverwriteRadio);
356         resourceGroup.add(resourceIgnoreRadio);
357         resourceGroup.add(resourcePromptRadio);
358 
359         // Add action listeners
360         cancelButton.addActionListener(new ActionListener(){
361             public void actionPerformed(ActionEvent ev) {
362                 thisWindowClosing();
363             }
364         });
365 
366         importButton.addActionListener(new ActionListener(){
367             public void actionPerformed(ActionEvent ev) {
368                 try {
369                     beginImport();
370                     gui.updateProjectTree();
371                     gui.updateDisplayTree();
372                     thisWindowClosing();
373                 } catch (IOException ioe) {
374                 	ioe.printStackTrace(System.err);
375                     JOptionPane.showMessageDialog(null,
376                         Resources.getTranslation("error") + "\n" + ioe.getLocalizedMessage(),
377                         Resources.getTranslation("error"), JOptionPane.ERROR_MESSAGE);
378                 }
379             }
380         });
381 
382         fileChooseButton.addActionListener(new ActionListener(){
383             public void actionPerformed(ActionEvent ev) {
384                 chooseFile();
385             }
386         });
387 
388         // Setup combo box
389         Bundle baseBundle = ((Bundle)rbm.getBundles().elementAt(0));
390         BundleGroup ungroupedGroup = baseBundle.getUngroupedGroup();
391         groupComboBox = new JComboBox(baseBundle.getGroupsAsVector());
392         int groupComboBoxCount = groupComboBox.getItemCount();
393         for (int selectedIndex = 0; selectedIndex < groupComboBoxCount; selectedIndex++) {
394         	BundleGroup bundGroup = ((BundleGroup)groupComboBox.getItemAt(selectedIndex));
395         	if (bundGroup.getName().equals(ungroupedGroup.getName())) {
396         		// By default, use the ungrouped group. Probably named 'Ungrouped Items'.
397         		groupComboBox.setSelectedIndex(selectedIndex);
398         		break;
399         	}
400         }
401 
402         // Arange components
403         groupBox.add(Box.createHorizontalGlue());
404         groupBox.add(insertGroupLabel);
405         groupBox.add(Box.createHorizontalStrut(5));
406         groupBox.add(groupComboBox);
407 
408         defaultPanel2.add(groupBox, BorderLayout.NORTH);
409         defaultPanel2.add(markTranslatedCheck, BorderLayout.CENTER);
410         defaultPanel2.add(createGroupsCheck, BorderLayout.SOUTH);
411 
412         fileBox.add(fileGeneratePopulateRadio);
413         fileBox.add(fileGenerateEmptyRadio);
414         fileBox.add(fileIgnoreRadio);
415         fileBox.add(filePromptRadio);
416 
417         resourceBox.add(resourceOverwriteRadio);
418         resourceBox.add(resourceIgnoreRadio);
419         resourceBox.add(resourcePromptRadio);
420 
421         defaultPanel.add(defaultPanel2);
422         filePanel.add(fileBox);
423         resourcePanel.add(resourceBox);
424 
425         midBox.add(resourcePanel);
426         midBox.add(filePanel);
427         midBox.add(defaultPanel);
428 
429         midPanel.add(midBox, BorderLayout.CENTER);
430 
431         topInnerPanel.add(sourceLabel, BorderLayout.CENTER);
432         topInnerPanel.add(fileChooseButton, BorderLayout.EAST);
433 
434         topPanel.add(titleLabel, BorderLayout.NORTH);
435         topPanel.add(topInnerPanel, BorderLayout.CENTER);
436 
437         botPanel.add(cancelButton);
438         botPanel.add(importButton);
439 
440         getContentPane().setLayout(new BorderLayout());
441         getContentPane().add(topPanel, BorderLayout.NORTH);
442         getContentPane().add(midPanel, BorderLayout.CENTER);
443         getContentPane().add(botPanel, BorderLayout.SOUTH);
444 
445         pack();
446     }
447 
thisWindowClosing()448     protected void thisWindowClosing() {
449         setVisible(false);
450         dispose();
451     }
452 }