[Schmitzm-commits] r907 - in trunk/src/schmitzm: lang swing swing/resource/locales
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Thu Jun 10 22:15:32 CEST 2010
Author: mojays
Date: 2010-06-10 22:15:31 +0200 (Thu, 10 Jun 2010)
New Revision: 907
Modified:
trunk/src/schmitzm/lang/ResourceProvider.java
trunk/src/schmitzm/swing/ResourceProviderManagerFrame.java
trunk/src/schmitzm/swing/resource/locales/SwingResourceBundle.properties
trunk/src/schmitzm/swing/resource/locales/SwingResourceBundle_de.properties
Log:
Update functionality in ResourceProvider and ResourceProviderManagerFrame
Modified: trunk/src/schmitzm/lang/ResourceProvider.java
===================================================================
--- trunk/src/schmitzm/lang/ResourceProvider.java 2010-06-10 11:12:57 UTC (rev 906)
+++ trunk/src/schmitzm/lang/ResourceProvider.java 2010-06-10 20:15:31 UTC (rev 907)
@@ -29,16 +29,27 @@
******************************************************************************/
package schmitzm.lang;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
+import java.text.DateFormat;
+import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.SortedSet;
@@ -46,6 +57,8 @@
import org.apache.log4j.Logger;
+import schmitzm.io.FileInputStream;
+import schmitzm.io.IOUtil;
import schmitzm.jfree.JFreeChartUtil;
/**
@@ -163,23 +176,20 @@
* @param missingResourceString
* Alternativ-String der - wenn fehlende Ressourcen ignoriert
* werden - von {@link #getString(String)} zurueckgegeben wird
+ * @param register
+ * Flag, ob das neue Bundle registriert werden soll (nur fuer interne
+ * Zwecke verfuegbar!)
*/
protected ResourceProvider(String defaultResourceBundle, Locale rootLocale,
- boolean ignoreMissingResource, String missingResourceString) {
+ boolean ignoreMissingResource, String missingResourceString, boolean register) {
this.defaultResourceBundle = defaultResourceBundle;
this.rootLocale = rootLocale;
this.resourceBundle = null;
this.ignoreMissingResource = ignoreMissingResource;
this.missingResourceString = missingResourceString;
// Registrieren des neuen ResourceProvider
- RESOURCE_PROVIDER.put(defaultResourceBundle, this);
- // Wenn Auto-Reset aktiviert, automatisch das Alternativ-Bundle
- // setzen, mit dem Original-Bundle als Prefix
- if ( autoReset )
- resetResourceBundle(autoResetBundle, getDefaultBundleSimpleName());
-
- // Registrieren des neuen ResourceProvider als sortierbare Liste
- RESOURCE_PROVIDER_SORTABLE.add(this);
+ if( register )
+ registerResourceProvider(this);
}
/**
@@ -202,7 +212,7 @@
// only create a new provider if none is yet created for
// the bundle name
if ( provider == null ) {
- provider = new ResourceProvider(defaultResourceBundle,rootLocale,ignoreMissingResource,missingResourceString);
+ provider = new ResourceProvider(defaultResourceBundle,rootLocale,ignoreMissingResource,missingResourceString,true);
}
return provider;
}
@@ -762,7 +772,8 @@
* wenn {@code true}, wird eine bestehende Datei erweitert,
* andernfalls ueberschrieben
* @param rootPath
- *
+ * Pfad unterhalb dem das Bundle-Package angelegt wird (wenn {@code null}
+ * wird der Pfad aus dem System-Classpath ermittelt)
*/
public static void createPropertyFile(ResourceProvider provider, Locale l,
boolean append, File rootPath) throws URISyntaxException, FileNotFoundException, MalformedURLException {
@@ -793,7 +804,7 @@
// Keys mit Dummy-Werten in Datei schreiben
for (String key : provider.getKeys()) {
- // Some spacial characters have to be escaped, e.g. Newline \n
+ // Some special characters have to be escaped, e.g. Newline \n
String originalString = provider.getString(key);
originalString = originalString.replaceAll("\\n", "\\\\n");
@@ -806,14 +817,145 @@
out.close();
}
- /**
+ /**
+ * Erzeugt eine Property-Datei ({@code .properties}) fuer ein Resource
+ * Bundle. In dieser sind <b>NUR diejenigen</b> Keys des Bundles enthalten,
+ * welche in der angegebenen {@link Locale} derzeit nicht explizit hinterlegt
+ * sind.
+ *
+ * @param provider
+ * Resource-Provider fuer welches auf fehlende Definitionen
+ * geprueft wird
+ * @param l
+ * Sprache, die geprueft wird
+ * @param append
+ * wenn {@code true}, wird eine bestehende Datei erweitert,
+ * andernfalls ueberschrieben
+ * @param rootPath
+ * Pfad unterhalb dem das Bundle-Package angelegt wird
+ *
+ * @exception IllegalArgumentException wenn {@code append = FALSE} und
+ * {@code rootPath = NULL}, da dann die bestehende Bundle-Datei
+ * ueberschrieben wuerde
+ */
+ public static boolean updatePropertyFile(ResourceProvider provider, Locale l,
+ boolean append, File rootPath) throws URISyntaxException, FileNotFoundException, MalformedURLException, IOException {
+ if ( !append && rootPath == null )
+ throw new IllegalArgumentException("NULL-rootPath only allowed on append mode. Otherwise the existing bundle file would be overwritten!");
+
+ File existingBundleFile = getPropertyFile(provider, l, null);
+ File newBundleFile = getPropertyFile(provider, l, rootPath);
+ // create package subdirectories if necessary
+ if ( newBundleFile.getParentFile() != null )
+ newBundleFile.getParentFile().mkdirs();
+ // Neuen ResourceProvider nur fuer die angegebene Locale erstellen,
+ // um Fallback zu vermeiden
+ ResourceProvider inBundle = new ResourceProvider(
+ provider.getDefaultBundleName()+"_"+l.toString(),
+ l,
+ false,
+ "???",
+ false
+ );
+ if ( !provider.getDefaultBundleName().equals( provider.getBundleName() ) )
+ inBundle.resetResourceBundle(provider.getBundleName()+"_"+l.toString(), provider.getKeyPrefix());
+
+ // Updates zunaechst in Buffer schreiben, da (bei append = TRUE)
+ // die Ausgabe-Datei u.U. identisch mit der Eingabe-Datei!
+ StringBuffer pipedOut = new StringBuffer();
+
+ // Update-Header erstellen
+ if (!newBundleFile.exists() || newBundleFile.length() == 0) {
+ pipedOut.append("# ----------------------------------------------------------------------------------").append("\n");
+ pipedOut.append("# LANGUAGE: " + l.toString() + " = " + l.getDisplayLanguage()).append("\n");
+ pipedOut.append("# ----------------------------------------------------------------------------------").append("\n");
+ }
+ pipedOut.append("# Original bundle: " + provider.getDefaultBundleName()).append("\n");
+ pipedOut.append("# UPDATE ["+DateFormat.getInstance().format(new Date())+"]").append("\n");
+
+ // etwaiges Key-Prefix ermitteln
+ String prefix = provider.getKeyPrefix();
+ if (prefix == null)
+ prefix = "";
+ if (!prefix.equals(""))
+ prefix += ".";
+
+ // Pruefen, welche Keys des Providers in der Property-Datei
+ // der angegebenen Locale fehlen. Diese mit Dummy-Wert in die
+ // Update-Datei schreiben.
+ boolean updates = false;
+ for (String key : provider.getKeys()) {
+ try {
+ if (inBundle != null)
+ inBundle.getObject(key);
+ } catch (MissingResourceException err) {
+ // Ressource fehlt --> in Update aufnehmen
+ // Dummy-Wert fuer Key erzeugen (und spezielle Zeichen escapen)
+ String originalString = provider.getString(key);
+ originalString = originalString.replaceAll("\\n", "\\\\n");
+ pipedOut.append(prefix + key + "=?" + l.toString() + "? " + originalString).append("\n");
+ updates = true;
+ }
+
+ }
+ pipedOut.append("# ----------------------------------------------------------------------------------").append("\n");
+
+ // Gepufferte Updates in Bundle-Datei schreiben
+ if ( updates ) {
+ // Ausgabe-Datei oeffnen
+ PrintWriter outWriter = new PrintWriter(new FileOutputStream(newBundleFile,append));
+ // Gepufferte Updates als Eingabe-Stream oeffnen
+ BufferedReader newProp = new BufferedReader(new StringReader(pipedOut.toString()));
+ // Alle Zeilen in Ausgabe-Datei uebertragen
+ String propLine = null;
+ while( (propLine = newProp.readLine()) != null )
+ outWriter.println(propLine);
+ // Ausgabe-Stream schliessen
+ outWriter.flush();
+ outWriter.close();
+ // Eingabe-Stream schliessen
+ newProp.close();
+ }
+ return updates;
+ }
+
+ /**
* Liefert alle instanziierten {@link ResourceProvider}.
*/
public static SortableVector<ResourceProvider> getRegisteredResourceProvider() {
- return RESOURCE_PROVIDER_SORTABLE;
+ return new SortableVector<ResourceProvider>(RESOURCE_PROVIDER_SORTABLE);
}
/**
+ * Registriert einen {@link ResourceProvider} in der Liste der
+ * instanziierten {@link ResourceProvider}. Wird automatisch im Konstruktor
+ * gemacht, deshalb ist diese Methode {@code private}!
+ * @param rp ein {@link ResourceProvider}
+ */
+ private static void registerResourceProvider(ResourceProvider rp) {
+ // Registrieren des neuen ResourceProvider
+ RESOURCE_PROVIDER.put(rp.getDefaultBundleName(), rp);
+ // Wenn Auto-Reset aktiviert, automatisch das Alternativ-Bundle
+ // setzen, mit dem Original-Bundle als Prefix
+ if ( autoReset )
+ rp.resetResourceBundle(autoResetBundle, rp.getDefaultBundleSimpleName());
+
+ // Registrieren des neuen ResourceProvider als sortierbare Liste
+ RESOURCE_PROVIDER_SORTABLE.add(rp);
+ }
+
+ /**
+ * Entfernt einen {@link ResourceProvider} aus der Liste der registrierten
+ * {@link ResourceProvider}.
+ */
+ public static void unregisterResourceProvider(ResourceProvider rp) {
+ if ( rp == null )
+ return;
+ RESOURCE_PROVIDER.remove(rp.getDefaultBundleName());
+ RESOURCE_PROVIDER_SORTABLE.remove(rp);
+ }
+
+ /**
* (De)Aktiviert, dass jeder instanziiere {@link ResourceProvider} automatisch
* auf ein alternatives Bundle resettet wird (mittels {@link ResourceProvider#resetResourceBundle(String, String)}).
* Als Prefix wird jeweils der Name des Original-Bundles verwendet.
@@ -829,6 +971,6 @@
if ( backdated )
for (ResourceProvider rp : RESOURCE_PROVIDER_SORTABLE)
rp.resetResourceBundle(bundle, rp.getDefaultBundleSimpleName() );
- }
-
+ }
+
}
Modified: trunk/src/schmitzm/swing/ResourceProviderManagerFrame.java
===================================================================
--- trunk/src/schmitzm/swing/ResourceProviderManagerFrame.java 2010-06-10 11:12:57 UTC (rev 906)
+++ trunk/src/schmitzm/swing/ResourceProviderManagerFrame.java 2010-06-10 20:15:31 UTC (rev 907)
@@ -33,15 +33,19 @@
import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Component;
+import java.awt.Cursor;
import java.awt.FlowLayout;
+import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.io.File;
+import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.TreeSet;
+import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.JButton;
@@ -50,8 +54,11 @@
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.SwingWorker;
import javax.swing.table.AbstractTableModel;
+import schmitzm.io.IOUtil;
import schmitzm.lang.LocaleComparator;
import schmitzm.lang.ResourceProvider;
import schmitzm.swing.event.InputOptionAdapter;
@@ -67,6 +74,7 @@
private JLabel infoText = null; // use JLabel to interpret HTML
private JButton cancelButton = null;
private JButton newLangButton = null;
+ private JButton updateLangButton = null;
private JButton openFolderButton = null;
private JTable bundleTable = null;
private JPanel controlPanel = null;
@@ -123,7 +131,7 @@
private void initGUI(String infoMess) throws Exception {
//imageLabel.setIcon(new ImageIcon(XuluMainFrame_Infodialog.class.getResource("[Ihre Grafik]")));
this.setTitle(getResource("Title"));
- this.setSize(500,400);
+ this.setSize(650,400);
this.getContentPane().setLayout(new BorderLayout());
if (infoMess != null) {
@@ -142,6 +150,8 @@
cancelButton.addActionListener(this);
newLangButton = new JButton(getResource("NewLang"));
newLangButton.addActionListener(this);
+ updateLangButton = new JButton(getResource("UpdateLang"));
+ updateLangButton.addActionListener(this);
openFolderButton = new JButton(SwingUtil.R("OpenFolder"));
openFolderButton.addActionListener(this);
@@ -149,6 +159,7 @@
controlPanel.setLayout( new FlowLayout(FlowLayout.CENTER) );
controlPanel.add( cancelButton );
controlPanel.add( newLangButton );
+ controlPanel.add( updateLangButton );
controlPanel.add( openFolderButton );
if ( infoText != null )
@@ -187,27 +198,45 @@
TreeSet<Locale> sortedLocales = new TreeSet<Locale>(new LocaleComparator(true));
for (Locale l : Locale.getAvailableLocales())
sortedLocales.add(l);
+
+ InputOption[] dialogOption = prepareLanguageDialog(sortedLocales, true);
+ newLangDialog_LangDesc = (SelectionInputOption) dialogOption[0];
+ newLangDialog_LangCode = (ManualInputOption) dialogOption[1];
+ }
+ /**
+ * Prepares the input options for a dialog to choose a language. The dialog
+ * itself must be created by {@link MultipleOptionPane}.
+ * @param locales the available locales in the input options
+ * @param inclOther flag whether the option "Other language" is available
+ * @return
+ */
+ private InputOption[] prepareLanguageDialog(Set<Locale> locales, boolean inclOther) {
// insert descriptions and language codes to arrays
- String[] avLocaleDesc = new String[sortedLocales.size()+1];
- String[] avLocaleCode = new String[sortedLocales.size()+1];
+ int avLocaleSize = locales.size();
+ if ( inclOther )
+ avLocaleSize++;
+ String[] avLocaleDesc = new String[avLocaleSize];
+ String[] avLocaleCode = new String[avLocaleSize];
int i = 0;
- for (Locale l : sortedLocales) {
+ for (Locale l : locales) {
avLocaleDesc[i] = l.getDisplayName();
avLocaleCode[i] = l.toString();
i++;
}
// additional option "other language"
- avLocaleDesc[i] = getResource("OtherLang");
- avLocaleCode[i] = "";
-
+ if ( inclOther ) {
+ avLocaleDesc[i] = getResource("OtherLang");
+ avLocaleCode[i] = "";
+ }
+
// create input option for the language code
- newLangDialog_LangCode = new ManualInputOption.Text(
+ final ManualInputOption langCode = new ManualInputOption.Text(
getResource("LanguageCode"),
true
);
// create input option for predefined languages
- newLangDialog_LangDesc = new SelectionInputOption.Combo(
+ final SelectionInputOption langDesc = new SelectionInputOption.Combo(
getResource("Language"),
true,
avLocaleCode,
@@ -216,14 +245,25 @@
);
// if the language selection changes, also the language code should
// change
- newLangDialog_LangDesc.addInputOptionListener(new InputOptionAdapter() {
+ langDesc.addInputOptionListener(new InputOptionAdapter() {
public void optionChanged(InputOption option, Object oldValue, Object newValue) {
- newLangDialog_LangCode.setValue(newValue);
- newLangDialog_LangCode.transferFocus();
- newLangDialog_LangCode.setEnabled( "".equals(newValue));
+ langCode.setValue(newValue);
+ langCode.transferFocus();
+ langCode.setEnabled( "".equals(newValue));
}
});
+
+ // Fill return array
+ InputOption[] inputOption = new InputOption[] {
+ langDesc,
+ langCode
+ };
+ return inputOption;
+
+
}
+
+
/**
* Closes the window, if {@code e} is a <code>WindowEvent.WINDOW_CLOSING<code>-event.
@@ -258,7 +298,8 @@
if ( input == null )
return;
- // create the property files for all bundles
+ setCursor( Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR) );
+ // create the property files for all bundles
Locale newLocale = new Locale((String)input[1]);
try {
// check whether the file exists for one bundle
@@ -287,6 +328,7 @@
ResourceBundle.clearCache();
((AbstractTableModel)bundleTable.getModel()).fireTableDataChanged();
// show message
+ setCursor( Cursor.getDefaultCursor() );
JOptionPane.showMessageDialog(
this,
getResource("FinishMess"),
@@ -294,11 +336,59 @@
JOptionPane.INFORMATION_MESSAGE
);
} catch (Exception err) {
+ setCursor( Cursor.getDefaultCursor() );
+ ExceptionDialog.show(this,err,err.getClass().getSimpleName(),null);
+ }
+ }
+
+ /**
+ * Opens the language dialog and creates the new bundles.
+ */
+ private void updateLanguage() {
+ // sort the provided languages according to their description
+ TreeSet<Locale> sortedLocales = new TreeSet<Locale>(new LocaleComparator(true));
+ for (ResourceProvider rp : ResourceProvider.getRegisteredResourceProvider())
+ for (Locale l : rp.getAvailableLocales(false))
+ sortedLocales.add(l);
+ InputOption[] dialogOption = prepareLanguageDialog(sortedLocales, false);
+ ((SelectionInputOption) dialogOption[0]).setSelectedIndex(0);
+
+ // show the dialog
+ Object[] input = MultipleOptionPane.showMultipleInputDialog(
+ this,
+ getResource("UpdateLang"),
+ dialogOption
+ );
+ if ( input == null )
+ return;
+
+ setCursor( Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR) );
+ // create the property files for all bundles
+ Locale updateLocale = new Locale((String)input[1]);
+ try {
+ // Update files (with APPEND-function)
+ int updatedFiles = 0;
+ for ( ResourceProvider rp : new Vector<ResourceProvider>(ResourceProvider.getRegisteredResourceProvider()) )
+ if ( ResourceProvider.updatePropertyFile(rp, updateLocale, true, getRootPath()) )
+ updatedFiles++;
+
+ // Update table
+ ResourceBundle.clearCache();
+ ((AbstractTableModel)bundleTable.getModel()).fireTableDataChanged();
+ // show message
+ setCursor( Cursor.getDefaultCursor() );
+ JOptionPane.showMessageDialog(
+ this,
+ getResource("UpdateMess",updatedFiles),
+ SwingUtil.R("Information")+"...",
+ JOptionPane.INFORMATION_MESSAGE
+ );
+ } catch (Exception err) {
+ setCursor( Cursor.getDefaultCursor() );
ExceptionDialog.show(this,err,err.getClass().getSimpleName(),null);
}
}
-
/**
* Performs the button action.
*/
@@ -307,6 +397,8 @@
cancel();
if (e.getSource() == newLangButton)
createNewLanguage();
+ if (e.getSource() == updateLangButton)
+ updateLanguage();
if (e.getSource() == openFolderButton)
SwingUtil.openOSFolder(getRootPath());
}
Modified: trunk/src/schmitzm/swing/resource/locales/SwingResourceBundle.properties
===================================================================
--- trunk/src/schmitzm/swing/resource/locales/SwingResourceBundle.properties 2010-06-10 11:12:57 UTC (rev 906)
+++ trunk/src/schmitzm/swing/resource/locales/SwingResourceBundle.properties 2010-06-10 20:15:31 UTC (rev 907)
@@ -218,9 +218,11 @@
ResourceProviderManagerFrame.RootLang=Root language
ResourceProviderManagerFrame.AdditionalLang=Additional languages
ResourceProviderManagerFrame.NewLang=Create new language files...
+ResourceProviderManagerFrame.UpdateLang=Update language files...
ResourceProviderManagerFrame.OtherLang=<other language>
ResourceProviderManagerFrame.Language=Language
ResourceProviderManagerFrame.LanguageCode=Language code
ResourceProviderManagerFrame.FinishMess=Property files successfully created...
+ResourceProviderManagerFrame.UpdateMess=${0} resource bundles updated...
Modified: trunk/src/schmitzm/swing/resource/locales/SwingResourceBundle_de.properties
===================================================================
--- trunk/src/schmitzm/swing/resource/locales/SwingResourceBundle_de.properties 2010-06-10 11:12:57 UTC (rev 906)
+++ trunk/src/schmitzm/swing/resource/locales/SwingResourceBundle_de.properties 2010-06-10 20:15:31 UTC (rev 907)
@@ -204,7 +204,9 @@
ResourceProviderManagerFrame.RootLang=Standard Sprache
ResourceProviderManagerFrame.AdditionalLang=Weitere Sprachen
ResourceProviderManagerFrame.NewLang=Neue Sprachdateien anlegen...
+ResourceProviderManagerFrame.UpdateLang=Sprachdateien aktualisieren...
ResourceProviderManagerFrame.OtherLang=<andere Sprache>
ResourceProviderManagerFrame.Language=Sprache
ResourceProviderManagerFrame.LanguageCode=Sprachcode
ResourceProviderManagerFrame.FinishMess=Property-Dateien erfolgreich erstellt...
+ResourceProviderManagerFrame.UpdateMess=${0} Sprach-Pakete aktualisiert...
More information about the Schmitzm-commits
mailing list