Author: dieppe
Date: 2008-04-22 23:39:58 +0000 (Tue, 22 Apr 2008)
New Revision: 19512
Added:
trunk/apps/thingamablog/src/net/sf/thingamablog/util/io/FileUtil.java
trunk/apps/thingamablog/src/thingamablog/
trunk/apps/thingamablog/src/thingamablog/l10n/
trunk/apps/thingamablog/src/thingamablog/l10n/FSParseException.java
trunk/apps/thingamablog/src/thingamablog/l10n/Fields.java
trunk/apps/thingamablog/src/thingamablog/l10n/L10n.java
trunk/apps/thingamablog/src/thingamablog/l10n/LineReader.java
trunk/apps/thingamablog/src/thingamablog/l10n/SimpleFieldSet.java
trunk/apps/thingamablog/src/thingamablog/l10n/i18n.java
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/App.java
trunk/apps/thingamablog/src/net/sf/thingamablog/TBGlobals.java
trunk/apps/thingamablog/src/net/sf/thingamablog/blog/TBWeblog.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/GUILoginPrompt.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/ImageViewerDialog.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/JAboutBox.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/StandardDialog.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/ExportTemplatePackDialog.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/FeedPropertiesDialog.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/FeedTableModel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/ImportEntriesDialog.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/InstallTemplateDialog.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/LogPanel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/SelectTemplatePanel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/StatusBar.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TBOptionsDialog.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TBSearchDialog.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TBViewerPaneModel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TaskDialog.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TemplatePropertiesPanel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TemplateSelectionPanel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/ThingamablogFrame.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/WeblogTableModel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/WeblogTreeModel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/editor/EntryEditor.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/editor/HTMLEditor.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/ASCIIPanel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/EditableList.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBArchivingPanel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBCategoriesPanel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBCustomVariablesPanel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBEmailPanel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBFlogNodeWizardDialog.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBFlogWizardDialog.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBFrontPagePanel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBPublishTransportPanel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBTemplatesPanel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBWeblogPropertiesDialog.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBWizardDialog.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/WeblogEditableListModel.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/WeblogPropertiesDialogFactory.java
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/XmlRpcPingPanel.java
Log:
Add all the sources needed for the L10n framework.
Modify all (except 3) files containing i18n messages.
Modified: trunk/apps/thingamablog/src/net/sf/thingamablog/App.java
===================================================================
--- trunk/apps/thingamablog/src/net/sf/thingamablog/App.java 2008-04-22
22:52:29 UTC (rev 19511)
+++ trunk/apps/thingamablog/src/net/sf/thingamablog/App.java 2008-04-22
23:39:58 UTC (rev 19512)
@@ -33,13 +33,13 @@
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.sf.thingamablog.gui.app.ExperiencedBlue;
import net.sf.thingamablog.gui.app.ThingamablogFrame;
import com.jgoodies.plaf.LookUtils;
import com.jgoodies.plaf.Options;
import com.jgoodies.plaf.plastic.PlasticLookAndFeel;
+import thingamablog.l10n.i18n;
/** Application starter */
@@ -86,18 +86,8 @@
//set up the I18n resource bundles
if(TBGlobals.getProperty("LANG_LOCALE") != null)
- I18n.setLocale(TBGlobals.getProperty("LANG_LOCALE"));
+ i18n.setLocale(TBGlobals.getProperty("LANG_LOCALE"));
- I18n.setBundleForPackage("net.sf.thingamablog.blog", langPack);
- I18n.setBundleForPackage("net.sf.thingamablog.gui", langPack);
- I18n.setBundleForPackage("net.sf.thingamablog.gui.app", langPack);
- I18n.setBundleForPackage("net.sf.thingamablog.gui.editor", langPack);
- I18n.setBundleForPackage("net.sf.thingamablog.gui.properties",
langPack);
- I18n.setBundleForPackage("net.atlanticbb.tantlinger.ui", langPack);
- I18n.setBundleForPackage("net.atlanticbb.tantlinger.ui.text",
langPack);
- I18n.setBundleForPackage("net.atlanticbb.tantlinger.ui.text.actions",
langPack);
- I18n.setBundleForPackage("net.atlanticbb.tantlinger.ui.text.dialogs",
langPack);
-
//OSX properties
System.setProperty("apple.laf.useScreenMenuBar", "true");
System.setProperty("com.apple.mrj.application.apple.menu.about.name",
TBGlobals.APP_NAME);
Modified: trunk/apps/thingamablog/src/net/sf/thingamablog/TBGlobals.java
===================================================================
--- trunk/apps/thingamablog/src/net/sf/thingamablog/TBGlobals.java
2008-04-22 22:52:29 UTC (rev 19511)
+++ trunk/apps/thingamablog/src/net/sf/thingamablog/TBGlobals.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -51,13 +51,13 @@
public class TBGlobals
{
/** The name of the application */
- public static final String APP_NAME = "@APP_NAME@";
+ public static final String APP_NAME = "Thingamablog";
/** The version of the application */
- public static final String VERSION = "@VERSION@";
+ public static final String VERSION = "1.1b6";
/** The build of the application */
- public static final String BUILD = "@BUILD@";
+ public static final String BUILD = "20080423.120";
/** The home page of the application */
- public static final String APP_URL = "@APP_URL@";
+ public static final String APP_URL =
"http://thingamablog.sourceforge.net";
/** Platform specific path separator */
public static final String SEP = System.getProperty("file.separator");
Modified: trunk/apps/thingamablog/src/net/sf/thingamablog/blog/TBWeblog.java
===================================================================
--- trunk/apps/thingamablog/src/net/sf/thingamablog/blog/TBWeblog.java
2008-04-22 22:52:29 UTC (rev 19511)
+++ trunk/apps/thingamablog/src/net/sf/thingamablog/blog/TBWeblog.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -35,11 +35,10 @@
import java.util.logging.Level;
import java.util.logging.Logger;
-
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.io.IOUtils;
import net.sf.thingamablog.generator.PageGenerator;
import net.sf.thingamablog.transport.FCPTransport;
+import thingamablog.l10n.i18n;
/**
@@ -51,7 +50,6 @@
public class TBWeblog extends Weblog
{
private static Logger logger =
Logger.getLogger("net.sf.thingamablog.blog");
- private static I18n i18n = I18n.getInstance("net.sf.thingamablog.blog");
//vaid chars for category page files names
private static final String VALID_CHARS =
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/GUILoginPrompt.java
===================================================================
--- trunk/apps/thingamablog/src/net/sf/thingamablog/gui/GUILoginPrompt.java
2008-04-22 22:52:29 UTC (rev 19511)
+++ trunk/apps/thingamablog/src/net/sf/thingamablog/gui/GUILoginPrompt.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -28,8 +28,8 @@
import javax.swing.JPasswordField;
import javax.swing.JTextField;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.sf.thingamablog.transport.LoginPrompt;
+import thingamablog.l10n.i18n;
/**
@@ -44,8 +44,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui");
private JPasswordField pwField;
private JTextField userField;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/ImageViewerDialog.java
===================================================================
--- trunk/apps/thingamablog/src/net/sf/thingamablog/gui/ImageViewerDialog.java
2008-04-22 22:52:29 UTC (rev 19511)
+++ trunk/apps/thingamablog/src/net/sf/thingamablog/gui/ImageViewerDialog.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -38,8 +38,8 @@
import javax.swing.JToolBar;
import javax.swing.border.BevelBorder;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.UIUtils;
+import thingamablog.l10n.i18n;
/**
@@ -54,8 +54,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui");
private ImagePanel imagePanel;
private File currentImageFile;
Modified: trunk/apps/thingamablog/src/net/sf/thingamablog/gui/JAboutBox.java
===================================================================
--- trunk/apps/thingamablog/src/net/sf/thingamablog/gui/JAboutBox.java
2008-04-22 22:52:29 UTC (rev 19511)
+++ trunk/apps/thingamablog/src/net/sf/thingamablog/gui/JAboutBox.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -39,7 +39,6 @@
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
-import java.net.URL;
import java.util.StringTokenizer;
import javax.swing.Box;
@@ -53,11 +52,8 @@
import javax.swing.JTextArea;
import javax.swing.Scrollable;
import javax.swing.border.EmptyBorder;
+import thingamablog.l10n.i18n;
-import net.atlanticbb.tantlinger.i18n.I18n;
-
-import org.jdesktop.jdic.desktop.Desktop;
-
//import com.Ostermiller.util.Browser;
/**
@@ -77,7 +73,6 @@
*
*/
private static final long serialVersionUID = 1L;
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui");
private final String MAILTO = "mailto:"; //$NON-NLS-1$
private JLabel appTitleLabel = new JLabel();
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/StandardDialog.java
===================================================================
--- trunk/apps/thingamablog/src/net/sf/thingamablog/gui/StandardDialog.java
2008-04-22 22:52:29 UTC (rev 19511)
+++ trunk/apps/thingamablog/src/net/sf/thingamablog/gui/StandardDialog.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -11,12 +11,11 @@
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
+import thingamablog.l10n.i18n;
-import net.atlanticbb.tantlinger.i18n.I18n;
-
/**
* This class implements a standard data entry dialog with "Ok" and
* "Cancel" buttons. Subclasses can override the isDataValid(),
@@ -35,8 +34,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui");
// Constants
public static final int BUTTONS_CENTER = FlowLayout.CENTER;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/ExportTemplatePackDialog.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/ExportTemplatePackDialog.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/ExportTemplatePackDialog.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -38,7 +38,6 @@
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.io.IOUtils;
import net.atlanticbb.tantlinger.ui.UIUtils;
import net.atlanticbb.tantlinger.ui.text.TextEditPopupManager;
@@ -47,6 +46,7 @@
import net.sf.thingamablog.blog.TemplatePack;
import net.sf.thingamablog.blog.ZipExportableTemplatePack;
import net.sf.thingamablog.gui.StandardDialog;
+import thingamablog.l10n.i18n;
@@ -60,7 +60,6 @@
*
*/
private static final long serialVersionUID = 1L;
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app"); //$NON-NLS-1$
private static final String TITLE = i18n.str("export_templates");
//$NON-NLS-1$
private JLabel msgLabel = null;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/FeedPropertiesDialog.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/FeedPropertiesDialog.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/FeedPropertiesDialog.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -40,10 +40,10 @@
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.sf.thingamablog.feed.Feed;
import net.sf.thingamablog.gui.LabelledItemPanel;
import net.sf.thingamablog.gui.StandardDialog;
+import thingamablog.l10n.i18n;
/**
* @author Bob Tantlinger
@@ -55,8 +55,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app");
private Feed feed;
private JTextField urlField;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/FeedTableModel.java
===================================================================
--- trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/FeedTableModel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++ trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/FeedTableModel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -24,9 +24,9 @@
package net.sf.thingamablog.gui.app;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.sf.thingamablog.feed.FeedItem;
import net.sf.thingamablog.gui.table.DefaultSortTableModel;
+import thingamablog.l10n.i18n;
/**
* @author Bob Tantlinger
@@ -40,8 +40,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app");
public static final Object READ = " "; //$NON-NLS-1$
public static final Object ITEM = i18n.str("item"); //$NON-NLS-1$
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/ImportEntriesDialog.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/ImportEntriesDialog.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/ImportEntriesDialog.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -49,11 +49,11 @@
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.text.TextEditPopupManager;
import net.sf.thingamablog.blog.Weblog;
import net.sf.thingamablog.gui.CustomFileFilter;
import net.sf.thingamablog.xml.RSSImportExport;
+import thingamablog.l10n.i18n;
/**
* @author Bob Tantlinger
@@ -67,8 +67,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app");
private JButton cancelButton;
private JButton importButton;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/InstallTemplateDialog.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/InstallTemplateDialog.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/InstallTemplateDialog.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -25,12 +25,12 @@
import javax.swing.JOptionPane;
import javax.swing.JPanel;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.io.IOUtils;
import net.atlanticbb.tantlinger.ui.UIUtils;
import net.sf.thingamablog.TBGlobals;
import net.sf.thingamablog.blog.TemplatePack;
import net.sf.thingamablog.blog.ZipTemplatePack;
+import thingamablog.l10n.i18n;
@@ -39,9 +39,7 @@
*
*/
public class InstallTemplateDialog extends JDialog
-{
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app");
-
+{
private static final long serialVersionUID = 1L;
private JLabel instrLabel = null;
private JButton openButton = null;
Modified: trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/LogPanel.java
===================================================================
--- trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/LogPanel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++ trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/LogPanel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -32,13 +32,13 @@
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.UIUtils;
import net.atlanticbb.tantlinger.ui.text.TextEditPopupManager;
import net.sf.thingamablog.blog.PingProgress;
import net.sf.thingamablog.blog.PingService;
import net.sf.thingamablog.blog.PublishProgress;
import net.sf.thingamablog.transport.MailTransportProgress;
+import thingamablog.l10n.i18n;
/**
@@ -51,8 +51,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app"); //$NON-NLS-1$
private JProgressBar progressBar;
private JButton abortButton;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/SelectTemplatePanel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/SelectTemplatePanel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/SelectTemplatePanel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -13,17 +13,17 @@
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
+import thingamablog.l10n.i18n;
-import net.atlanticbb.tantlinger.i18n.I18n;
+
public class SelectTemplatePanel extends JPanel
{
/**
*
*/
private static final long serialVersionUID = 1L;
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app");
public static final String TEMPLATE_ZIP_PATH = "templateZip"; //
@jve:decl-index=0: //$NON-NLS-1$
public static final String TEMPLATE_NAME = "templateName"; //$NON-NLS-1$
Modified: trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/StatusBar.java
===================================================================
--- trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/StatusBar.java
2008-04-22 22:52:29 UTC (rev 19511)
+++ trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/StatusBar.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -36,10 +36,10 @@
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.UIUtils;
import net.sf.thingamablog.blog.Weblog;
import net.sf.thingamablog.feed.Feed;
+import thingamablog.l10n.i18n;
@@ -55,8 +55,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app");
final static Icon blogIcon = UIUtils.getIcon(UIUtils.X16, "blog.png");
//$NON-NLS-1$
final static Icon feedIcon = UIUtils.getIcon(UIUtils.X16,
"blogpages.png"); //$NON-NLS-1$
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TBOptionsDialog.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TBOptionsDialog.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TBOptionsDialog.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -66,12 +66,12 @@
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.UIUtils;
import net.sf.thingamablog.TBGlobals;
import net.sf.thingamablog.gui.LabelledItemPanel;
import net.sf.thingamablog.gui.MultilineText;
import net.sf.thingamablog.gui.StandardDialog;
+import thingamablog.l10n.i18n;
/**
* @author Bob Tantlinger
@@ -85,8 +85,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app"); //$NON-NLS-1$
private final String fontSizes[] = new String[] {"8", "9", "10", "11",
//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"12", "14",
"16", "18", "20", "22", "24", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
//$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
@@ -165,12 +163,12 @@
lafCombo.setModel(new DefaultComboBoxModel(lfNames));
lafCombo.setSelectedItem(UIManager.getLookAndFeel().getName());
- Vector locs = new
Vector(Arrays.asList(I18n.getAvailableLanguagePackLocales()));
+ Vector locs = new
Vector(Arrays.asList(i18n.getAvailableLanguagePackLocales()));
Collections.sort(locs, new LocaleComparator());
- if(!locs.contains(I18n.getLocale()))
- locs.add(I18n.getLocale());
+ if(!locs.contains(i18n.getLocale()))
+ locs.add(i18n.getLocale());
langCombo = new JComboBox(locs);
- langCombo.setSelectedItem(I18n.getLocale());
+ langCombo.setSelectedItem(i18n.getLocale());
langCombo.setRenderer(new LocaleListCellRenderer());
File dictDir = new File(TBGlobals.DICT_DIR);
@@ -473,7 +471,7 @@
String msg = ""; //$NON-NLS-1$
String curLaf = TBGlobals.getLookAndFeelClassName();
String selLaf = lfinfo[lafCombo.getSelectedIndex()].getClassName();
- if(!curLaf.equals(selLaf) ||
(!langCombo.getSelectedItem().equals(I18n.getLocale())))
+ if(!curLaf.equals(selLaf) ||
(!langCombo.getSelectedItem().equals(i18n.getLocale())))
{
msg += i18n.str("look_and_feel_prompt"); //$NON-NLS-1$
}
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TBSearchDialog.java
===================================================================
--- trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TBSearchDialog.java
2008-04-22 22:52:29 UTC (rev 19511)
+++ trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TBSearchDialog.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -48,7 +48,6 @@
import javax.swing.border.BevelBorder;
import javax.swing.border.EmptyBorder;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.sf.thingamablog.blog.BackendException;
import net.sf.thingamablog.blog.BlogEntry;
import net.sf.thingamablog.blog.CategoryEvent;
@@ -62,6 +61,7 @@
import net.sf.thingamablog.feed.FeedSearch;
import net.sf.thingamablog.gui.LabelledItemPanel;
import net.sf.thingamablog.gui.StandardDialog;
+import thingamablog.l10n.i18n;
import com.tantlinger.jdatepicker.JCalendarComboBox;
@@ -77,8 +77,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app");
private final String DRAFTS = i18n.str("drafts"); //$NON-NLS-1$
private final String POSTS = i18n.str("posts"); //$NON-NLS-1$
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TBViewerPaneModel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TBViewerPaneModel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TBViewerPaneModel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -32,21 +32,19 @@
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.sf.thingamablog.TBGlobals;
import net.sf.thingamablog.blog.BlogEntry;
import net.sf.thingamablog.blog.Weblog;
import net.sf.thingamablog.feed.FeedItem;
import net.sf.thingamablog.gui.ViewerPaneModel;
import net.sf.thingamablog.gui.editor.EntryImageUtils;
+import thingamablog.l10n.i18n;
/**
* @author Bob Tantlinger
*/
public class TBViewerPaneModel implements ViewerPaneModel
-{
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app"); //$NON-NLS-1$
-
+{
private static final String exts[] = {".gif", ".jpg", ".png"};
//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
private Object data;
private SimpleDateFormat sdf = new SimpleDateFormat("MMMM dd, yyyy
hh:mm a z"); //$NON-NLS-1$
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TaskDialog.java
===================================================================
--- trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TaskDialog.java
2008-04-22 22:52:29 UTC (rev 19511)
+++ trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TaskDialog.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -30,12 +30,12 @@
import javax.swing.JLabel;
import javax.swing.JPanel;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.sf.thingamablog.TBGlobals;
import net.sf.thingamablog.blog.PingProgress;
import net.sf.thingamablog.blog.PublishProgress;
import net.sf.thingamablog.blog.Weblog;
import net.sf.thingamablog.transport.MailTransportProgress;
+import thingamablog.l10n.i18n;
/**
@@ -48,8 +48,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app"); //$NON-NLS-1$
private JButton closeButton, clearButton;
private JComboBox blogCombo;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TemplatePropertiesPanel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TemplatePropertiesPanel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TemplatePropertiesPanel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -18,9 +18,9 @@
import javax.swing.BorderFactory;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.text.TextEditPopupManager;
import net.sf.thingamablog.blog.TemplatePack;
+import thingamablog.l10n.i18n;
/**
@@ -29,7 +29,6 @@
*/
public class TemplatePropertiesPanel extends JPanel
{
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app");
private static final long serialVersionUID = 1L;
private JLabel titleLabel = null;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TemplateSelectionPanel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TemplateSelectionPanel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/TemplateSelectionPanel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -23,12 +23,12 @@
import javax.swing.JList;
import javax.swing.JPanel;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.sf.thingamablog.TBGlobals;
import net.sf.thingamablog.blog.Author;
import net.sf.thingamablog.blog.TBWeblog;
import net.sf.thingamablog.blog.TemplatePack;
import net.sf.thingamablog.blog.WeblogBackend;
+import thingamablog.l10n.i18n;
/**
@@ -41,8 +41,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app");
private JComboBox tmplCombo;
private TemplatePropertiesPanel propertyPanel;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/ThingamablogFrame.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/ThingamablogFrame.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/ThingamablogFrame.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -67,7 +67,6 @@
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.io.IOUtils;
import net.atlanticbb.tantlinger.ui.UIUtils;
import net.atlanticbb.tantlinger.ui.text.TextEditPopupManager;
@@ -113,6 +112,7 @@
import com.l2fprod.common.swing.JDirectoryChooser;
import freenet.utils.BrowserLaunch;
+import thingamablog.l10n.i18n;
@@ -128,7 +128,6 @@
*
*/
private static final long serialVersionUID = 1L;
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app"); //$NON-NLS-1$
private static Logger logger =
Logger.getLogger("net.sf.thingamablog.gui.app"); //$NON-NLS-1$
private final JFrame FRAME = this;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/WeblogTableModel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/WeblogTableModel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/WeblogTableModel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -1,8 +1,8 @@
package net.sf.thingamablog.gui.app;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.sf.thingamablog.blog.BlogEntry;
import net.sf.thingamablog.gui.table.DefaultSortTableModel;
+import thingamablog.l10n.i18n;
public class WeblogTableModel extends DefaultSortTableModel
@@ -11,8 +11,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app");
public static final Object TITLE = i18n.str("title"); //$NON-NLS-1$
public static final Object POST_DATE = i18n.str("date_posted");
//$NON-NLS-1$
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/WeblogTreeModel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/WeblogTreeModel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/app/WeblogTreeModel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -34,9 +34,9 @@
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.sf.thingamablog.blog.Weblog;
import net.sf.thingamablog.blog.WeblogList;
+import thingamablog.l10n.i18n;
/**
* @author Bob Tantlinger
@@ -45,9 +45,7 @@
*
*/
public class WeblogTreeModel implements TreeModel
-{
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.app");
-
+{
public static final String ROOT = i18n.str("my_sites"); //$NON-NLS-1$
public static final String CURRENT = i18n.str("current"); //$NON-NLS-1$
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/editor/EntryEditor.java
===================================================================
--- trunk/apps/thingamablog/src/net/sf/thingamablog/gui/editor/EntryEditor.java
2008-04-22 22:52:29 UTC (rev 19511)
+++ trunk/apps/thingamablog/src/net/sf/thingamablog/gui/editor/EntryEditor.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -73,7 +73,6 @@
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.undo.UndoManager;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.DefaultAction;
import net.atlanticbb.tantlinger.ui.UIUtils;
import net.atlanticbb.tantlinger.ui.text.CompoundUndoManager;
@@ -129,6 +128,7 @@
import org.dts.spell.swing.JTextComponentSpellChecker;
import com.tantlinger.jdatepicker.JCalendarComboBox;
+import thingamablog.l10n.i18n;
//TODO table edit actions on wysiwyg popup menu
@@ -144,8 +144,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.editor"); //$NON-NLS-1$
public static final int NEW_ENTRY_MODE = -1;
public static final int UPDATE_ENTRY_MODE = -2;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/editor/HTMLEditor.java
===================================================================
--- trunk/apps/thingamablog/src/net/sf/thingamablog/gui/editor/HTMLEditor.java
2008-04-22 22:52:29 UTC (rev 19511)
+++ trunk/apps/thingamablog/src/net/sf/thingamablog/gui/editor/HTMLEditor.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -44,7 +44,6 @@
import javax.swing.event.DocumentListener;
import javax.swing.undo.UndoManager;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.UIUtils;
import net.atlanticbb.tantlinger.ui.text.CompoundUndoManager;
import net.atlanticbb.tantlinger.ui.text.IndentationFilter;
@@ -66,6 +65,7 @@
import org.bushe.swing.action.ActionList;
import org.bushe.swing.action.ActionUIFactory;
+import thingamablog.l10n.i18n;
/**
@@ -78,8 +78,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.editor");
public static final int TEMPLATE_MODE = 1;
public static final int FILE_MODE = 2;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/ASCIIPanel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/ASCIIPanel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/ASCIIPanel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -25,8 +25,8 @@
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.text.TextEditPopupManager;
+import thingamablog.l10n.i18n;
public class ASCIIPanel extends JPanel implements ActionListener
{
@@ -34,8 +34,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties");
private JScrollPane jScrollPane = null;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/EditableList.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/EditableList.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/EditableList.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -9,9 +9,10 @@
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
+import thingamablog.l10n.i18n;
-import net.atlanticbb.tantlinger.i18n.I18n;
+
/*
* Created on Jun 29, 2004
*
@@ -48,8 +49,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties");
private JList list;
private JButton addButton;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBArchivingPanel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBArchivingPanel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBArchivingPanel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -40,13 +40,13 @@
import javax.swing.SpinnerNumberModel;
import javax.swing.border.TitledBorder;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.text.TextEditPopupManager;
import net.sf.thingamablog.TBGlobals;
import net.sf.thingamablog.blog.TBWeblog;
import net.sf.thingamablog.gui.LabelledItemPanel;
import com.tantlinger.jdatepicker.JCalendarComboBox;
+import thingamablog.l10n.i18n;
/**
* @author Bob Tantlinger
@@ -60,8 +60,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties");
private static final String MONTHLY = i18n.str("monthly"); //$NON-NLS-1$
private static final String WEEKLY = i18n.str("weekly"); //$NON-NLS-1$
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBCategoriesPanel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBCategoriesPanel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBCategoriesPanel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -35,10 +35,10 @@
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.sf.thingamablog.TBGlobals;
import net.sf.thingamablog.blog.TBWeblog;
import net.sf.thingamablog.gui.LabelledItemPanel;
+import thingamablog.l10n.i18n;
@@ -55,8 +55,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties");
private TBWeblog weblog;
private EditableList eCatList;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBCustomVariablesPanel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBCustomVariablesPanel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBCustomVariablesPanel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -36,11 +36,11 @@
import javax.swing.JTextArea;
import javax.swing.JTextField;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.text.TextEditPopupManager;
import net.sf.thingamablog.blog.TBWeblog;
import net.sf.thingamablog.generator.CustomTag;
import net.sf.thingamablog.gui.StandardDialog;
+import thingamablog.l10n.i18n;
/**
@@ -55,8 +55,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties");
private TBWeblog weblog;
private EditableList eList;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBEmailPanel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBEmailPanel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBEmailPanel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -18,9 +18,9 @@
import javax.swing.JTextField;
import javax.swing.SpinnerNumberModel;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.text.TextEditPopupManager;
import net.sf.thingamablog.blog.Weblog;
+import thingamablog.l10n.i18n;
/**
@@ -34,8 +34,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties"); //$NON-NLS-1$
private static final String[] PROTOCOLS = {"POP3", "IMAP"}; //$NON-NLS-1$
//$NON-NLS-2$
private JLabel protocolLabel = null;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBFlogNodeWizardDialog.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBFlogNodeWizardDialog.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBFlogNodeWizardDialog.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -11,7 +11,6 @@
import java.awt.BorderLayout;
import java.awt.CardLayout;
-import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GridLayout;
@@ -30,11 +29,8 @@
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
-import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
-import net.atlanticbb.tantlinger.i18n.I18n;
-import net.atlanticbb.tantlinger.ui.UIUtils;
import net.sf.thingamablog.TBGlobals;
import net.sf.thingamablog.blog.BackendException;
@@ -45,6 +41,7 @@
import net.sf.thingamablog.gui.MultilineText;
import net.sf.thingamablog.transport.FCPTransport;
import net.sf.thingamablog.util.freenet.fcp.fcpManager;
+import thingamablog.l10n.i18n;
/**
*
@@ -52,7 +49,6 @@
*/
public class TBFlogNodeWizardDialog extends JDialog {
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties");
private Logger logger =
Logger.getLogger("net.sf.thingamablog.gui.properties");
private PropertyPanel nodePanel;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBFlogWizardDialog.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBFlogWizardDialog.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBFlogWizardDialog.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -12,10 +12,8 @@
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
-import java.io.IOException;
import java.util.List;
import java.util.Vector;
-import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BorderFactory;
@@ -31,10 +29,8 @@
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.UIUtils;
import net.atlanticbb.tantlinger.ui.text.TextEditPopupManager;
-import net.sf.thingamablog.TBGlobals;
import net.sf.thingamablog.blog.Author;
import net.sf.thingamablog.blog.BackendException;
import net.sf.thingamablog.blog.TBWeblog;
@@ -48,7 +44,7 @@
import net.sf.thingamablog.transport.FCPTransport;
import net.sf.thingamablog.transport.LocalTransport;
import net.sf.thingamablog.util.freenet.fcp.fcpManager;
-import net.sf.thingamablog.util.string.ASCIIconv;
+import thingamablog.l10n.i18n;
@@ -65,7 +61,6 @@
*/
private static final long serialVersionUID = 1L;
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties"); //$NON-NLS-1$
private Logger logger =
Logger.getLogger("net.sf.thingamablog.gui.properties");
private static final String CANCEL = i18n.str("cancel"); //$NON-NLS-1$
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBFrontPagePanel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBFrontPagePanel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBFrontPagePanel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -37,10 +37,10 @@
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.text.TextEditPopupManager;
import net.sf.thingamablog.blog.TBWeblog;
import net.sf.thingamablog.gui.LabelledItemPanel;
+import thingamablog.l10n.i18n;
/**
* @author Bob Tantlinger
@@ -54,8 +54,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties");
private TBWeblog weblog;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBPublishTransportPanel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBPublishTransportPanel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBPublishTransportPanel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -28,13 +28,10 @@
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.SortedMap;
-import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
@@ -47,7 +44,6 @@
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.text.TextEditPopupManager;
import net.sf.thingamablog.TBGlobals;
import net.sf.thingamablog.blog.TBWeblog;
@@ -60,6 +56,7 @@
import net.sf.thingamablog.transport.SFTPTransport;
import net.sf.thingamablog.util.freenet.fcp.fcpManager;
import net.sf.thingamablog.util.string.ASCIIconv;
+import thingamablog.l10n.i18n;
/**
* @author Bob Tantlinger
@@ -73,8 +70,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties");
private final String FTP = "FTP"; //$NON-NLS-1$
private final String SFTP = "SFTP"; //$NON-NLS-1$
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBTemplatesPanel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBTemplatesPanel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBTemplatesPanel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -9,11 +9,11 @@
import javax.swing.BorderFactory;
import javax.swing.JLabel;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.UIUtils;
import net.sf.thingamablog.blog.TBWeblog;
import net.sf.thingamablog.blog.TemplatePack;
import net.sf.thingamablog.gui.app.TemplateSelectionPanel;
+import thingamablog.l10n.i18n;
/**
@@ -26,8 +26,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties");
private TemplateSelectionPanel tmplPanel;
private TBWeblog blog;
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBWeblogPropertiesDialog.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBWeblogPropertiesDialog.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBWeblogPropertiesDialog.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -26,10 +26,10 @@
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.UIUtils;
import net.sf.thingamablog.blog.TBWeblog;
import net.sf.thingamablog.gui.StandardDialog;
+import thingamablog.l10n.i18n;
/**
* @author Bob Tantlinger
@@ -42,8 +42,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties"); //$NON-NLS-1$
private TBWeblog tbw;
private Vector opts = new Vector();
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBWizardDialog.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBWizardDialog.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/TBWizardDialog.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -12,16 +12,13 @@
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
-import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Vector;
-import java.util.logging.Logger;
import javax.swing.BorderFactory;
import javax.swing.JButton;
-import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
@@ -33,10 +30,8 @@
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.atlanticbb.tantlinger.ui.UIUtils;
import net.atlanticbb.tantlinger.ui.text.TextEditPopupManager;
-import net.sf.thingamablog.TBGlobals;
import net.sf.thingamablog.blog.Author;
import net.sf.thingamablog.blog.BackendException;
import net.sf.thingamablog.blog.TBWeblog;
@@ -47,8 +42,7 @@
import net.sf.thingamablog.gui.MultilineText;
import net.sf.thingamablog.gui.app.TemplateSelectionPanel;
import net.sf.thingamablog.gui.app.WeblogPreviewer;
-import net.sf.thingamablog.util.freenet.fcp.fcpManager;
-import net.sf.thingamablog.util.string.ASCIIconv;
+import thingamablog.l10n.i18n;
@@ -65,8 +59,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties"); //$NON-NLS-1$
private static final String CANCEL = i18n.str("cancel"); //$NON-NLS-1$
private static final String FINISH = i18n.str("finish");
//$NON-NLS-1$
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/WeblogEditableListModel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/WeblogEditableListModel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/WeblogEditableListModel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -27,11 +27,11 @@
import javax.swing.JOptionPane;
import javax.swing.JTextField;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.sf.thingamablog.blog.Author;
import net.sf.thingamablog.blog.BackendException;
import net.sf.thingamablog.blog.Weblog;
import net.sf.thingamablog.gui.LabelledItemPanel;
+import thingamablog.l10n.i18n;
/**
* @author Bob Tantlinger
@@ -41,9 +41,7 @@
*/
public class WeblogEditableListModel implements EditableListModel
{
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties");
-
- public static final int CATEGORIES = -1;
+ public static final int CATEGORIES = -1;
public static final int AUTHORS = -2;
private int mode;
private Vector listEdits = new Vector();
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/WeblogPropertiesDialogFactory.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/WeblogPropertiesDialogFactory.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/WeblogPropertiesDialogFactory.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -5,10 +5,10 @@
package net.sf.thingamablog.gui.properties;
import java.awt.Frame;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.sf.thingamablog.blog.TBWeblog;
import net.sf.thingamablog.blog.Weblog;
import net.sf.thingamablog.gui.StandardDialog;
+import thingamablog.l10n.i18n;
/**
* @author Bob Tantlinger
@@ -16,9 +16,7 @@
* Creates and shows the appropriate weblog properties dialog
*/
public class WeblogPropertiesDialogFactory
-{
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties");
-
+{
/**
* Shows a weblog property dialog box
* @param wb - The weblog
Modified:
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/XmlRpcPingPanel.java
===================================================================
---
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/XmlRpcPingPanel.java
2008-04-22 22:52:29 UTC (rev 19511)
+++
trunk/apps/thingamablog/src/net/sf/thingamablog/gui/properties/XmlRpcPingPanel.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -41,11 +41,11 @@
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
-import net.atlanticbb.tantlinger.i18n.I18n;
import net.sf.thingamablog.blog.PingService;
import net.sf.thingamablog.blog.Weblog;
import net.sf.thingamablog.blog.WeblogsDotComPing;
import net.sf.thingamablog.gui.LabelledItemPanel;
+import thingamablog.l10n.i18n;
/**
* @author Bob Tantlinger
@@ -59,8 +59,6 @@
*
*/
private static final long serialVersionUID = 1L;
-
- private static final I18n i18n =
I18n.getInstance("net.sf.thingamablog.gui.properties");
private Weblog weblog;
private PingerTableModel model;
Added: trunk/apps/thingamablog/src/net/sf/thingamablog/util/io/FileUtil.java
===================================================================
--- trunk/apps/thingamablog/src/net/sf/thingamablog/util/io/FileUtil.java
(rev 0)
+++ trunk/apps/thingamablog/src/net/sf/thingamablog/util/io/FileUtil.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -0,0 +1,295 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package net.sf.thingamablog.util.io;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.logging.Level;
+
+import java.util.logging.Logger;
+import net.sf.thingamablog.transport.DefaultMIMETypes;
+
+final public class FileUtil {
+
+ private static final int BUFFER_SIZE = 4096;
+ private static Logger logger =
Logger.getLogger("net.sf.thingamablog.util.io");
+
+ /** Round up a value to the next multiple of a power of 2 */
+ private static final long roundup_2n(long val, int blocksize) {
+ int mask=blocksize-1;
+ return (val+mask)&~mask;
+ }
+
+ /**
+ * Guesstimate real disk usage for a file with a given filename, of a
given length.
+ */
+ public static long estimateUsage(File file, long flen) {
+ /**
+ * It's possible that none of these assumptions are accurate for any
filesystem;
+ * this is intended to be a plausible worst case.
+ */
+ // Assume 4kB clusters for calculating block usage (NTFS)
+ long blockUsage = roundup_2n(flen, 4096);
+ // Assume 512 byte filename entries, with 100 bytes overhead, for
filename overhead (NTFS)
+ String filename = file.getName();
+ int nameLength = filename.getBytes().length + 100;
+ long filenameUsage = roundup_2n(nameLength, 512);
+ // Assume 50 bytes per block tree overhead with 1kB blocks (reiser3
worst case)
+ long extra = (roundup_2n(flen, 1024) / 1024) * 50;
+ return blockUsage + filenameUsage + extra;
+ }
+
+ /**
+ * Is possParent a parent of filename?
+ * Why doesn't java provide this? :(
+ * */
+ public static boolean isParent(File poss, File filename) {
+ File canon = FileUtil.getCanonicalFile(poss);
+ File canonFile = FileUtil.getCanonicalFile(filename);
+
+ if(isParentInner(poss, filename)) return true;
+ if(isParentInner(poss, canonFile)) return true;
+ if(isParentInner(canon, filename)) return true;
+ if(isParentInner(canon, canonFile)) return true;
+ return false;
+ }
+
+ private static boolean isParentInner(File possParent, File filename) {
+ while(true) {
+ if(filename.equals(possParent)) return true;
+ filename = filename.getParentFile();
+ if(filename == null) return false;
+ }
+ }
+
+ public static File getCanonicalFile(File file) {
+ File result;
+ try {
+ result = file.getCanonicalFile();
+ } catch (IOException e) {
+ result = file.getAbsoluteFile();
+ }
+ return result;
+ }
+
+ public static String readUTF(File file) throws FileNotFoundException,
IOException {
+ return readUTF(file, 0);
+ }
+
+ public static String readUTF(File file, long offset) throws
FileNotFoundException, IOException {
+ StringBuffer result = new StringBuffer();
+ FileInputStream fis = null;
+ BufferedInputStream bis = null;
+ InputStreamReader isr = null;
+
+ try {
+ fis = new FileInputStream(file);
+ skipFully(fis, offset);
+ bis = new BufferedInputStream(fis);
+ isr = new InputStreamReader(bis, "UTF-8");
+
+ char[] buf = new char[4096];
+ int length = 0;
+
+ while((length = isr.read(buf)) > 0) {
+ result.append(buf, 0, length);
+ }
+
+ } finally {
+ try {
+ if(isr != null) isr.close();
+ if(bis != null) bis.close();
+ if(fis != null) fis.close();
+ } catch (IOException e) {}
+ }
+ return result.toString();
+ }
+
+ /**
+ * Reliably skip a number of bytes or throw.
+ */
+ public static void skipFully(InputStream is, long skip) throws IOException
{
+ long skipped = 0;
+ while(skipped < skip) {
+ long x = is.skip(skip - skipped);
+ if(x <= 0) throw new IOException("Unable to skip "+(skip -
skipped)+" bytes");
+ skipped += x;
+ }
+ }
+
+ public static boolean writeTo(InputStream input, File target) throws
FileNotFoundException, IOException {
+ DataInputStream dis = null;
+ FileOutputStream fos = null;
+ File file = File.createTempFile("temp", ".tmp",
target.getParentFile());
+ logger.log(Level.INFO, "Writing to "+file+" to be renamed to "+target);
+
+ try {
+ dis = new DataInputStream(input);
+ fos = new FileOutputStream(file);
+
+ int len = 0;
+ byte[] buffer = new byte[4096];
+ while ((len = dis.read(buffer)) > 0) {
+ fos.write(buffer, 0, len);
+ }
+ } catch (IOException e) {
+ throw e;
+ } finally {
+ if(dis != null) dis.close();
+ if(fos != null) fos.close();
+ }
+
+ if(FileUtil.renameTo(file, target))
+ return true;
+ else {
+ file.delete();
+ return false;
+ }
+ }
+
+ public static boolean renameTo(File orig, File dest) {
+ // Try an atomic rename
+ // Shall we prevent symlink-race-conditions here ?
+ if(orig.equals(dest))
+ throw new IllegalArgumentException("Huh? the two file descriptors
are the same!");
+ if(!orig.exists()) {
+ throw new IllegalArgumentException("Original doesn't exist!");
+ }
+ if (!orig.renameTo(dest)) {
+ // Not supported on some systems (Windows)
+ if (!dest.delete()) {
+ if (dest.exists()) {
+ logger.log(Level.SEVERE, "Could not delete " + dest + " -
check permissions");
+ }
+ }
+ if (!orig.renameTo(dest)) {
+ logger.log(Level.SEVERE, "Could not rename " + orig + " to " +
dest +
+ (dest.exists() ? " (target exists)" : "") +
+ (orig.exists() ? " (source exists)" : "") +
+ " - check permissions");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static String sanitize(String s) {
+ StringBuffer sb = new StringBuffer(s.length());
+ for(int i=0;i<s.length();i++) {
+ char c = s.charAt(i);
+ if((c == '/') || (c == '\\') || (c == '%') || (c == '>') || (c ==
'<') || (c == ':') || (c == '\'') || (c == '\"'))
+ continue;
+ if(Character.isDigit(c))
+ sb.append(c);
+ else if(Character.isLetter(c))
+ sb.append(c);
+ else if(Character.isWhitespace(c))
+ sb.append(' ');
+ else if((c == '-') || (c == '_') || (c == '.'))
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+
+ public static String sanitize(String filename, String mimeType) {
+ filename = sanitize(filename);
+ if(mimeType == null) return filename;
+ if(filename.indexOf('.') >= 0) {
+ String oldExt = filename.substring(filename.lastIndexOf('.'));
+ if(DefaultMIMETypes.isValidExt(mimeType, oldExt)) return filename;
+ }
+ String defaultExt = DefaultMIMETypes.getExtension(filename);
+ if(defaultExt == null) return filename;
+ else return filename + '.' + defaultExt;
+ }
+
+ /**
+ * Find the length of an input stream. This method will consume the
complete
+ * input stream until its {@link InputStream#read(byte[])} method returns
+ * <code>-1</code>, thus signalling the end of the stream.
+ *
+ * @param source
+ * The input stream to find the length of
+ * @return The numbe of bytes that can be read from the stream
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public static long findLength(InputStream source) throws IOException {
+ long length = 0;
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int read = 0;
+ while (read > -1) {
+ read = source.read(buffer);
+ if (read != -1) {
+ length += read;
+ }
+ }
+ return length;
+ }
+
+ /**
+ * Copies <code>length</code> bytes from the source input stream to the
+ * destination output stream. If <code>length</code> is <code>-1</code>
+ * as much bytes as possible will be copied (i.e. until
+ * {@link InputStream#read()} returns <code>-1</code> to signal the end of
+ * the stream).
+ *
+ * @param source
+ * The input stream to read from
+ * @param destination
+ * The output stream to write to
+ * @param length
+ * The number of bytes to copy
+ * @throws IOException
+ * if an I/O error occurs
+ */
+ public static void copy(InputStream source, OutputStream destination, long
length) throws IOException {
+ long remaining = length;
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int read = 0;
+ while ((remaining == -1) || (remaining > 0)) {
+ read = source.read(buffer, 0, ((remaining > BUFFER_SIZE) ||
(remaining == -1)) ? BUFFER_SIZE : (int) remaining);
+ if (read == -1) {
+ if (length == -1) {
+ return;
+ }
+ throw new EOFException("stream reached eof");
+ }
+ destination.write(buffer, 0, read);
+ remaining -= read;
+ }
+ }
+
+ /** Delete everything in a directory. Only use this when we are *very
sure* there is no
+ * important data below it! */
+ public static boolean removeAll(File wd) {
+ if(!wd.isDirectory()) {
+ System.err.println("DELETING FILE "+wd);
+ if(!wd.delete() && wd.exists()) {
+ logger.log(Level.SEVERE, "Could not delete file: "+wd);
+ return false;
+ }
+ } else {
+ File[] subfiles = wd.listFiles();
+ for(int i=0;i<subfiles.length;i++) {
+ if(!removeAll(subfiles[i])) return false;
+ }
+ if(!wd.delete()) {
+ logger.log(Level.SEVERE, "Could not delete directory: "+wd);
+ }
+ }
+ return true;
+ }
+
+}
Added: trunk/apps/thingamablog/src/thingamablog/l10n/FSParseException.java
===================================================================
--- trunk/apps/thingamablog/src/thingamablog/l10n/FSParseException.java
(rev 0)
+++ trunk/apps/thingamablog/src/thingamablog/l10n/FSParseException.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -0,0 +1,21 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package thingamablog.l10n;
+
+/**
+ * Exception thrown when we cannot parse a supplied peers file in
+ * SimpleFieldSet format (after it has been turned into a SFS).
+ */
+public class FSParseException extends Exception {
+ private static final long serialVersionUID = -1;
+ public FSParseException(Exception e) {
+ super(e);
+ }
+
+ public FSParseException(String msg) {
+ super(msg);
+ }
+
+}
Added: trunk/apps/thingamablog/src/thingamablog/l10n/Fields.java
===================================================================
--- trunk/apps/thingamablog/src/thingamablog/l10n/Fields.java
(rev 0)
+++ trunk/apps/thingamablog/src/thingamablog/l10n/Fields.java 2008-04-22
23:39:58 UTC (rev 19512)
@@ -0,0 +1,752 @@
+package thingamablog.l10n;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.StringTokenizer;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class contains static methods used for parsing boolean and unsigned
+ * long fields in Freenet messages. Also some general utility methods for
+ * dealing with string and numeric data.
+ *
+ * @author oskar
+ */
+public abstract class Fields {
+
+ /**
+ * All possible chars for representing a number as a String. Used to
+ * optimize numberList().
+ */
+ private final static char[] digits =
+ {
+ '0',
+ '1',
+ '2',
+ '3',
+ '4',
+ '5',
+ '6',
+ '7',
+ '8',
+ '9',
+ 'a',
+ 'b',
+ 'c',
+ 'd',
+ 'e',
+ 'f',
+ 'g',
+ 'h',
+ 'i',
+ 'j',
+ 'k',
+ 'l',
+ 'm',
+ 'n',
+ 'o',
+ 'p',
+ 'q',
+ 'r',
+ 's',
+ 't',
+ 'u',
+ 'v',
+ 'w',
+ 'x',
+ 'y',
+ 'z' };
+
+ private static Logger logger =
Logger.getLogger("net.sf.thingamablog.util.io");
+
+ /**
+ * Converts a hex string into a long. Long.parseLong(hex, 16) assumes the
+ * input is nonnegative unless there is a preceding minus sign. This method
+ * reads the input as twos complement instead, so if the input is 8 bytes
+ * long, it will correctly restore a negative long produced by
+ * Long.toHexString() but not neccesarily one produced by
+ * Long.toString(x,16) since that method will produce a string like '-FF'
+ * for negative longs values.
+ *
+ * @param hex
+ * A string in capital or lower case hex, of no more then 16
+ * characters.
+ * @throws NumberFormatException
+ * if the string is more than 16 characters long, or if any
+ * character is not in the set [0-9a-fA-f]
+ */
+ public static final long hexToLong(String hex)
+ throws NumberFormatException {
+ int len = hex.length();
+ if (len > 16)
+ throw new NumberFormatException();
+
+ long l = 0;
+ for (int i = 0; i < len; i++) {
+ l <<= 4;
+ int c = Character.digit(hex.charAt(i), 16);
+ if (c < 0)
+ throw new NumberFormatException();
+ l |= c;
+ }
+ return l;
+ }
+
+ /**
+ * Converts a hex string into an int. Integer.parseInt(hex, 16) assumes the
+ * input is nonnegative unless there is a preceding minus sign. This method
+ * reads the input as twos complement instead, so if the input is 8 bytes
+ * long, it will correctly restore a negative int produced by
+ * Integer.toHexString() but not neccesarily one produced by
+ * Integer.toString(x,16) since that method will produce a string like
+ * '-FF' for negative integer values.
+ *
+ * @param hex
+ * A string in capital or lower case hex, of no more then 16
+ * characters.
+ * @throws NumberFormatException
+ * if the string is more than 16 characters long, or if any
+ * character is not in the set [0-9a-fA-f]
+ */
+ public static final int hexToInt(String hex) throws NumberFormatException {
+ int len = hex.length();
+ if (len > 16)
+ throw new NumberFormatException();
+
+ int l = 0;
+ for (int i = 0; i < len; i++) {
+ l <<= 4;
+ int c = Character.digit(hex.charAt(i), 16);
+ if (c < 0)
+ throw new NumberFormatException();
+ l |= c;
+ }
+ return l;
+ }
+
+ /**
+ * Finds the boolean value of the field, by doing a caseless match with the
+ * strings "true" and "false".
+ *
+ * @param s
+ * The string
+ * @param def
+ * The default value if the string can't be parsed. If the
+ * default is true, it checks that the string is not "false"; if
+ * it is false, it checks whether the string is "true".
+ * @return the boolean field value or the default value if the field value
+ * couldn't be parsed.
+ */
+ /* wooo, rocket science! (this is purely abstraction people) */
+ public static final boolean stringToBool(String s, boolean def) {
+ if(s == null) return def;
+ return (def ? !s.equalsIgnoreCase("false") :
s.equalsIgnoreCase("true"));
+ }
+
+ /**
+ * Find the boolean value of the field. Throw if the string is neither
"yes"/"true" nor "no"/"false".
+ * @param s
+ * @return
+ */
+ public static boolean stringToBool(String s) throws NumberFormatException {
+ if(s == null) throw new NumberFormatException("Null");
+ if(s.equalsIgnoreCase("false") || s.equalsIgnoreCase("no")) return
false;
+ if(s.equalsIgnoreCase("true") || s.equalsIgnoreCase("yes")) return
true;
+ throw new NumberFormatException("Invalid boolean: "+s);
+ }
+
+ /**
+ * Converts a boolean to a String of either "true" or "false".
+ *
+ * @param b
+ * the boolean value to convert.
+ * @return A "true" or "false" String.
+ */
+ public static final String boolToString(boolean b) {
+ return b ? "true" : "false";
+ }
+
+ public static final String[] commaList(String ls) {
+ if(ls == null) return null;
+ StringTokenizer st = new StringTokenizer(ls, ",");
+ String[] r = new String[st.countTokens()];
+ for (int i = 0; i < r.length; i++) {
+ r[i] = st.nextToken().trim();
+ }
+ return r;
+ }
+
+ public static final String commaList(String[] ls) {
+ return textList(ls, ',');
+ }
+
+ public static final String textList(String[] ls, char ch) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < ls.length; i++) {
+ sb.append(ls[i]);
+ if (i != ls.length - 1)
+ sb.append(ch);
+ }
+ return sb.toString();
+ }
+
+ public static final long[] numberList(String ls)
+ throws NumberFormatException {
+ StringTokenizer st = new StringTokenizer(ls, ",");
+ long[] r = new long[st.countTokens()];
+ for (int i = 0; i < r.length; i++) {
+ r[i] = hexToLong(st.nextToken());
+ }
+ return r;
+ }
+
+ public static final String numberList(long[] ls) {
+ char[] numberBuf = new char[64];
+ StringBuffer listBuf = new StringBuffer(ls.length * 18);
+ for (int i = 0; i < ls.length; i++) {
+
+ // Convert the number into a string in a fixed size buffer.
+ long l = ls[i];
+ int charPos = 64;
+ do {
+ numberBuf[--charPos] = digits[(int) (l & 0x0F)];
+ l >>>= 4;
+ } while (l != 0);
+
+ listBuf.append(numberBuf, charPos, (64 - charPos));
+ if (i != ls.length - 1) {
+ listBuf.append(',');
+ }
+ }
+ return listBuf.toString();
+ }
+
+ /**
+ * Parses a time and date value, using a very strict format. The value has
+ * to be of the form YYYYMMDD-HH:MM:SS (where seconds may include a
+ * decimal) or YYYYMMDD (in which case 00:00:00 is assumed for time).
+ * Another accepted format is +/-{integer}{day|month|year|minute|second}
+ *
+ * @return millis of the epoch of at the time described.
+ */
+ public static final long dateTime(String date)
+ throws NumberFormatException {
+
+ if (date.length() == 0)
+ throw new NumberFormatException("Date time empty");
+
+ if ((date.charAt(0) == '-') || (date.charAt(0) == '+')) {
+ // Relative date
+ StringBuffer sb = new StringBuffer(10);
+ for (int x = 1; x < date.length(); x++) {
+ char c = date.charAt(x);
+ if (Character.isDigit(c)) {
+ sb.append(c);
+ } else
+ break;
+ }
+ int num = Integer.parseInt(sb.toString());
+ int chop = 1 + sb.length();
+ int deltaType = 0;
+ if (date.length() == chop)
+ deltaType = Calendar.DAY_OF_YEAR;
+ else {
+ String deltaTypeString = date.substring(chop).toLowerCase();
+ if (deltaTypeString.equals("y")
+ || deltaTypeString.equals("year"))
+ deltaType = Calendar.YEAR;
+ else if (
+ deltaTypeString.equals("month")
+ || deltaTypeString.equals("mo"))
+ deltaType = Calendar.MONTH;
+ else if (
+ deltaTypeString.equals("week")
+ || deltaTypeString.equals("w"))
+ deltaType = Calendar.WEEK_OF_YEAR;
+ else if (
+ deltaTypeString.equals("day")
+ || deltaTypeString.equals("d"))
+ deltaType = Calendar.DAY_OF_YEAR;
+ else if (
+ deltaTypeString.equals("hour")
+ || deltaTypeString.equals("h"))
+ deltaType = Calendar.HOUR;
+ else if (
+ deltaTypeString.equals("minute")
+ || deltaTypeString.equals("min"))
+ deltaType = Calendar.MINUTE;
+ else if (
+ deltaTypeString.equals("second")
+ || deltaTypeString.equals("s")
+ || deltaTypeString.equals("sec"))
+ deltaType = Calendar.SECOND;
+ else
+ throw new NumberFormatException(
+ "unknown time/date delta type: " +
deltaTypeString);
+ GregorianCalendar gc = new GregorianCalendar();
+ gc.add(deltaType, (date.charAt(0) == '+') ? num : -num);
+ return gc.getTime().getTime();
+ }
+ }
+
+ int dash = date.indexOf('-');
+
+ if (!((dash == -1) && (date.length() == 8))
+ && !((dash == 8) && (date.length() == 17)))
+ throw new NumberFormatException(
+ "Date time: " + date + " not correct.");
+ int year = Integer.parseInt(date.substring(0, 4));
+ int month = Integer.parseInt(date.substring(4, 6));
+ int day = Integer.parseInt(date.substring(6, 8));
+
+ int hour = dash == -1 ? 0 : Integer.parseInt(date.substring(9, 11));
+ int minute = dash == -1 ? 0 : Integer.parseInt(date.substring(12, 14));
+ int second = dash == -1 ? 0 : Integer.parseInt(date.substring(15, 17));
+
+ // Note that month is zero based in GregorianCalender!
+ try {
+ return (
+ new GregorianCalendar(
+ year,
+ month - 1,
+ day,
+ hour,
+ minute,
+ second))
+ .getTime()
+ .getTime();
+ } catch (Exception e) {
+ e.printStackTrace();
+ // The API docs don't say which exception is thrown on bad numbers!
+ throw new NumberFormatException("Invalid date " + date + ": " + e);
+ }
+
+ }
+
+ public static final String secToDateTime(long time) {
+ //Calendar c = Calendar.getInstance();
+ //c.setTime(new Date(time));
+ //gc.setTimeInMillis(time*1000);
+
+ DateFormat f = new SimpleDateFormat("yyyyMMdd-HH:mm:ss");
+ //String dateString = f.format(c.getTime());
+ String dateString = f.format(new Date(time * 1000));
+
+ if (dateString.endsWith("-00:00:00"))
+ dateString = dateString.substring(0, 8);
+
+ return dateString;
+ }
+
+ public static final int compareBytes(byte[] b1, byte[] b2) {
+ int len = Math.max(b1.length, b2.length);
+ for (int i = 0; i < len; ++i) {
+ if (i == b1.length)
+ return i == b2.length ? 0 : -1;
+ else if (i == b2.length)
+ return 1;
+ else if ((0xff & b1[i]) > (0xff & b2[i]))
+ return 1;
+ else if ((0xff & b1[i]) < (0xff & b2[i]))
+ return -1;
+ }
+ return 0;
+ }
+
+ public static final int compareBytes(
+ byte[] a,
+ byte[] b,
+ int aoff,
+ int boff,
+ int len) {
+ for (int i = 0; i < len; ++i) {
+ if (i + aoff == a.length)
+ return i + boff == b.length ? 0 : -1;
+ else if (i + boff == b.length)
+ return 1;
+ else if ((0xff & a[i + aoff]) > (0xff & b[i + boff]))
+ return 1;
+ else if ((0xff & a[i + aoff]) < (0xff & b[i + boff]))
+ return -1;
+ }
+ return 0;
+ }
+
+ public static final boolean byteArrayEqual(byte[] a, byte[] b) {
+ if (a.length != b.length)
+ return false;
+ for (int i = 0; i < a.length; ++i)
+ if (a[i] != b[i])
+ return false;
+ return true;
+ }
+
+ public static final boolean byteArrayEqual(
+ byte[] a,
+ byte[] b,
+ int aoff,
+ int boff,
+ int len) {
+ if ((a.length < aoff + len) || (b.length < boff + len))
+ return false;
+ for (int i = 0; i < len; ++i)
+ if (a[i + aoff] != b[i + boff])
+ return false;
+ return true;
+ }
+
+ /**
+ * Compares byte arrays lexicographically.
+ */
+ public static final class ByteArrayComparator implements Comparator {
+ public final int compare(Object o1, Object o2) {
+ return compare((byte[]) o1, (byte[]) o2);
+ }
+ public static final int compare(byte[] o1, byte[] o2) {
+ return compareBytes(o1, o2);
+ }
+ }
+
+ // could add stuff like IntegerComparator, LongComparator etc.
+ // if we need it
+
+ public static final int hashCode(byte[] b) {
+ return hashCode(b, 0, b.length);
+ }
+
+ /**
+ * A generic hashcode suited for byte arrays that are more or less random.
+ */
+ public static final int hashCode(byte[] b, int ptr, int length) {
+ int h = 0;
+ for (int i = length - 1; i >= 0; --i) {
+ int x = b[ptr+i] & 0xff;
+ h ^= x << ((i & 3) << 3);
+ }
+ return h;
+ }
+
+ /**
+ * Long version of above Not believed to be secure in any sense of the
word :)
+ */
+ public static final long longHashCode(byte[] b) {
+ long h = 0;
+ for (int i = b.length - 1; i >= 0; --i) {
+ int x = b[i] & 0xff;
+ h ^= ((long) x) << ((i & 7) << 3);
+ }
+ return h;
+ }
+
+ /**
+ * Long version of above Not believed to be secure in any sense of the
word :)
+ */
+ public static final long longHashCode(byte[] b, int offset, int length) {
+ long h = 0;
+ for (int i = length - 1; i >= 0; --i) {
+ int x = b[i+offset] & 0xff;
+ h ^= ((long) x) << ((i & 7) << 3);
+ }
+ return h;
+ }
+
+ /**
+ * @param addr
+ * @return
+ */
+ public static String commaList(Object[] addr) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < addr.length; i++) {
+ sb.append(addr[i]);
+ if (i != addr.length - 1)
+ sb.append(',');
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Convert an array of longs to an array of bytes, using a
+ * consistent endianness.
+ */
+ public static byte[] longsToBytes(long[] longs) {
+ byte[] buf = new byte[longs.length * 8];
+ for(int i=0;i<longs.length;i++) {
+ long x = longs[i];
+ for(int j=0;j<8;j++) {
+ buf[i*8+j] = (byte)x;
+ x >>>= 8;
+ }
+ }
+ return buf;
+ }
+
+ /**
+ * Convert an array of bytes to an array of longs.
+ */
+ public static long[] bytesToLongs(byte[] buf) {
+ return bytesToLongs(buf, 0, buf.length);
+ }
+
+ /**
+ * Convert an array of bytes to an array of longs.
+ * @param buf
+ * @param length
+ * @param offset
+ * @return
+ */
+ public static long[] bytesToLongs(byte[] buf, int offset, int length) {
+ if(length % 8 != 0) throw new IllegalArgumentException();
+ long[] longs = new long[length/8];
+ for(int i=0;i<longs.length;i++) {
+ long x = 0;
+ for(int j=7;j>=0;j--) {
+ long y = (buf[offset+i*8+j] & 0xff);
+ x = (x << 8) | y;
+ }
+ longs[i] = x;
+ }
+ return longs;
+ }
+
+ /**
+ * Convert an array of bytes to a single long.
+ */
+ public static long bytesToLong(byte[] buf) {
+ if(buf.length < 8) throw new IllegalArgumentException();
+ long x = 0;
+ for(int j=7;j>=0;j--) {
+ long y = (buf[j] & 0xff);
+ x = (x << 8) | y;
+ }
+ return x;
+ }
+
+ /**
+ * Convert an array of bytes to a single int.
+ */
+ public static int bytesToInt(byte[] buf, int offset) {
+ if(buf.length < 4) throw new IllegalArgumentException();
+ int x = 0;
+ for(int j=3;j>=0;j--) {
+ int y = (buf[j+offset] & 0xff);
+ x = (x << 8) | y;
+ }
+ return x;
+ }
+
+ public static int[] bytesToInts(byte[] buf, int offset, int length) {
+ if(length % 4 != 0) throw new IllegalArgumentException();
+ int[] ints = new int[length/4];
+ for(int i=0;i<ints.length;i++) {
+ int x = 0;
+ for(int j=3;j>=0;j--) {
+ int y = (buf[j+offset] & 0xff);
+ x = (x << 8) | y;
+ }
+ ints[i] = x;
+ }
+ return ints;
+ }
+
+ public static int[] bytesToInts(byte[] buf) {
+ return bytesToInts(buf, 0, buf.length);
+ }
+
+ public static byte[] longToBytes(long x) {
+ byte[] buf = new byte[8];
+ for(int j=0;j<8;j++) {
+ buf[j] = (byte)x;
+ x >>>= 8;
+ }
+ return buf;
+ }
+
+ public static byte[] intsToBytes(int[] ints) {
+ byte[] buf = new byte[ints.length * 8];
+ for(int i=0;i<ints.length;i++) {
+ long x = ints[i];
+ for(int j=0;j<4;j++) {
+ buf[i*4+j] = (byte)x;
+ x >>>= 8;
+ }
+ }
+ return buf;
+ }
+
+ public static long parseLong(String s, long defaultValue) {
+ try {
+ return Long.parseLong(s);
+ } catch (NumberFormatException e) {
+ logger.log(Level.SEVERE, "Failed to parse value as long: "+s+" :
"+e, e);
+ return defaultValue;
+ }
+ }
+
+ public static int parseInt(String s, int defaultValue) {
+ try {
+ return Integer.parseInt(s);
+ } catch (NumberFormatException e) {
+ logger.log(Level.SEVERE, "Failed to parse value as int: "+s+" :
"+e, e);
+ return defaultValue;
+ }
+ }
+
+ public static long parseShort(String s, short defaultValue) {
+ try {
+ return Short.parseShort(s);
+ } catch (NumberFormatException e) {
+ logger.log(Level.SEVERE, "Failed to parse value as short: "+s+" :
"+e, e);
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Parse a human-readable string possibly including SI units into a short.
+ * @throws NumberFormatException
+ * if the string is not parseable
+ */
+ public static short parseSIShort(String s) throws NumberFormatException {
+ short res = 1;
+ int x = s.length() - 1;
+ int idx;
+ try {
+ long[] l =
+ {
+ 1000,
+ 1 << 10 };
+ while ((x >= 0)
+ && ((idx = "kK".indexOf(s.charAt(x))) != -1)) {
+ x--;
+ res *= l[idx];
+ }
+ res *= Double.parseDouble(s.substring(0, x + 1));
+ } catch (ArithmeticException e) {
+ res = Short.MAX_VALUE;
+ throw new NumberFormatException(e.getMessage());
+ }
+ return res;
+ }
+
+ /**
+ * Parse a human-readable string possibly including SI units into an
integer.
+ * @throws NumberFormatException
+ * if the string is not parseable
+ */
+ public static int parseSIInt(String s) throws NumberFormatException {
+ int res = 1;
+ int x = s.length() - 1;
+ int idx;
+ try {
+ long[] l =
+ {
+ 1000,
+ 1 << 10,
+ 1000 * 1000,
+ 1 << 20,
+ 1000 * 1000 * 1000,
+ 1 << 30 };
+ while ((x >= 0)
+ && ((idx = "kKmMgG".indexOf(s.charAt(x))) != -1)) {
+ x--;
+ res *= l[idx];
+ }
+ res *= Double.parseDouble(s.substring(0, x + 1));
+ } catch (ArithmeticException e) {
+ res = Integer.MAX_VALUE;
+ throw new NumberFormatException(e.getMessage());
+ }
+ return res;
+ }
+
+ /**
+ * Parse a human-readable string possibly including SI units into a long.
+ * @throws NumberFormatException
+ * if the string is not parseable
+ */
+ public static long parseSILong(String s) throws NumberFormatException {
+ long res = 1;
+ int x = s.length() - 1;
+ int idx;
+ try {
+ long[] l =
+ {
+ 1000,
+ 1 << 10,
+ 1000 * 1000,
+ 1 << 20,
+ 1000l * 1000l * 1000l,
+ 1l << 30,
+ 1000l * 1000l * 1000l * 1000l,
+ 1l << 40,
+ 1000l * 1000l * 1000l * 1000l * 1000,
+ 1l << 50,
+ 1000l * 1000l * 1000l * 1000l * 1000l * 1000l,
+ 1l << 60 };
+ while ((x >= 0)
+ && ((idx = "kKmMgGtTpPeE".indexOf(s.charAt(x))) != -1)) {
+ x--;
+ res *= l[idx];
+ }
+ String multiplier = s.substring(0, x + 1).trim();
+ if(multiplier.indexOf('.') > -1 || multiplier.indexOf('E') > -1) {
+ res *= Double.parseDouble(multiplier);
+// if(Logger.shouldLog(Logger.MINOR,
Fields.class)) Logger.minor(Fields.class, "Parsed "+multiplier+" of "+s+" as
double: "+res);
+ } else {
+ res *= Long.parseLong(multiplier);
+// if(Logger.shouldLog(Logger.MINOR,
Fields.class)) Logger.minor(Fields.class, "Parsed "+multiplier+" of "+s+" as
long: "+res);
+ }
+ } catch (ArithmeticException e) {
+ res = Long.MAX_VALUE;
+ throw new NumberFormatException(e.getMessage());
+ }
+ return res;
+ }
+
+ public static double[] bytesToDoubles(byte[] data, int offset, int length)
{
+ long[] longs = bytesToLongs(data, offset, length);
+ double[] doubles = new double[longs.length];
+ for(int i=0;i<longs.length;i++)
+ doubles[i] = Double.longBitsToDouble(longs[i]);
+ return doubles;
+ }
+
+ public static byte[] doublesToBytes(double[] doubles) {
+ long[] longs = new long[doubles.length];
+ for(int i=0;i<longs.length;i++)
+ longs[i] = Double.doubleToLongBits(doubles[i]);
+ return longsToBytes(longs);
+ }
+
+ public static double[] bytesToDoubles(byte[] data) {
+ return bytesToDoubles(data, 0, data.length);
+ }
+
+ /**
+ * Assumes the array is sorted in ascending order, [begin] is lowest and
[end] is highest.
+ */
+ public static int binarySearch(long[] values, long key, int origBegin, int
origEnd) {
+ int begin = origBegin;
+ int end = origEnd;
+ while(true) {
+ if(end < begin) // so we can use origEnd=length-1 without
worrying length=0
+ return -begin-1;
+
+ int middle = (begin + end) >>> 1;
+ if(values[middle] == key)
+ return middle;
+
+ if(values[middle] > key) {
+ end = middle - 1;
+ } else if(values[middle] < key) {
+ begin = middle + 1;
+ }
+ }
+ }
+
+}
+
Added: trunk/apps/thingamablog/src/thingamablog/l10n/L10n.java
===================================================================
--- trunk/apps/thingamablog/src/thingamablog/l10n/L10n.java
(rev 0)
+++ trunk/apps/thingamablog/src/thingamablog/l10n/L10n.java 2008-04-22
23:39:58 UTC (rev 19512)
@@ -0,0 +1,357 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+
+package thingamablog.l10n;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.logging.Level;
+
+import java.util.logging.Logger;
+import net.sf.thingamablog.util.io.Closer;
+import thingamablog.l10n.SimpleFieldSet;
+import net.sf.thingamablog.util.io.FileUtil;
+
+
+/**
+ * This class provides a trivial internationalization framework to a Freenet
node.
+ *
+ * @author Florent Daignière <nextgens at freenetproject.org>
+ *
+ * TODO: Maybe base64 the override file ?
+ *
+ * comment(mario): for www interface we might detect locale from http requests?
+ * for other access (telnet) using system locale would probably be good, but
+ * it would be nice to have a command to switch locale on the fly.
+ */
+public class L10n {
+ public static final String CLASS_NAME = "l10n";
+ public static final String PREFIX = "thingamablog.l10n.";
+ public static final String SUFFIX = ".properties";
+ public static final String OVERRIDE_SUFFIX = ".override" + SUFFIX;
+
+ public static final String FALLBACK_DEFAULT = "en";
+ public static final String[] AVAILABLE_LANGUAGES = { "en", "de", "fr",
"es", "ja"};
+ private final String selectedLanguage;
+
+ private static SimpleFieldSet currentTranslation = null;
+ private static SimpleFieldSet fallbackTranslation = null;
+ private static L10n currentClass = null;
+
+ private static SimpleFieldSet translationOverride;
+ private static final Object sync = new Object();
+
+ private static Logger logger =
Logger.getLogger("net.sf.thingamablog.L10n");
+
+ L10n(String selected) {
+ selectedLanguage = selected;
+ File tmpFile = new File(L10n.PREFIX + selected + L10n.OVERRIDE_SUFFIX);
+
+ try {
+ if(tmpFile.exists() && tmpFile.canRead() && tmpFile.length() > 0) {
+ logger.log(Level.INFO, "Override file detected : let's try to
load it");
+ translationOverride = SimpleFieldSet.readFrom(tmpFile, false,
false);
+ } else {
+ // try to restore a backup
+ File backup = new File(tmpFile.getParentFile(),
tmpFile.getName()+".bak");
+ if(backup.exists() && backup.length() > 0) {
+ logger.log(Level.INFO, "Override-backup file detected :
let's try to load it");
+ translationOverride = SimpleFieldSet.readFrom(backup,
false, false);
+ }
+ translationOverride = null;
+ }
+
+ } catch (IOException e) {
+ translationOverride = null;
+ logger.log(Level.SEVERE, "IOError while accessing the file!" +
e.getMessage(), e);
+ }
+ currentTranslation = loadTranslation(selectedLanguage);
+ if(currentTranslation == null) {
+ logger.log(Level.SEVERE, "The translation file for " +
selectedLanguage + " is invalid. The node will load an empty template.");
+ currentTranslation = null;
+ translationOverride = new SimpleFieldSet(false);
+ }
+ }
+
+ /**
+ * Set the default language used by the framework.
+ *
+ * @param selectedLanguage (2 letter code)
+ * @throws MissingResourceException
+ */
+ public static void setLanguage(String selectedLanguage) throws
MissingResourceException {
+ synchronized (sync) {
+ for(int i=0; i<AVAILABLE_LANGUAGES.length; i++){
+ if(selectedLanguage.equalsIgnoreCase(AVAILABLE_LANGUAGES[i])){
+ selectedLanguage = AVAILABLE_LANGUAGES[i];
+ logger.log(Level.INFO, "Changing the current language to :
" + selectedLanguage);
+
+ currentClass = new L10n(selectedLanguage);
+
+ if(currentTranslation == null) {
+ currentClass = new L10n(FALLBACK_DEFAULT);
+ throw new MissingResourceException("Unable to load the
translation file for "+selectedLanguage, "l10n", selectedLanguage);
+ }
+
+ return;
+ }
+ }
+
+ currentClass = new L10n(FALLBACK_DEFAULT);
+ logger.log(Level.SEVERE, "The requested translation is not
available!" + selectedLanguage);
+ throw new MissingResourceException("The requested translation
("+selectedLanguage+") hasn't been found!", CLASS_NAME, selectedLanguage);
+ }
+ }
+
+ public static void setOverride(String key, String value) {
+ key = key.trim();
+ value = value.trim();
+ synchronized (sync) {
+ // Is the override already declared ? if not, create it.
+ if(translationOverride == null)
+ translationOverride = new SimpleFieldSet(false);
+
+ // If there is no need to keep it in the override, remove it...
+ // unless the original/default is the same as the translation
+ if(("".equals(value) || L10n.getString(key).equals(value)) &&
!L10n.getDefaultString(key).equals(value)) {
+ translationOverride.removeValue(key);
+ } else {
+ value = value.replaceAll("(\r|\n|\t)+", "");
+
+ // Set the value of the override
+ translationOverride.putOverwrite(key, value);
+ logger.log(Level.INFO, "Got a new translation key: set the
Override!");
+ }
+
+ // Save the file to disk
+ _saveTranslationFile();
+ }
+ }
+
+ private static void _saveTranslationFile() {
+ FileOutputStream fos = null;
+ File finalFile = new File(L10n.PREFIX + L10n.getSelectedLanguage() +
L10n.OVERRIDE_SUFFIX);
+
+ try {
+ // We don't set deleteOnExit on it : if the save operation fails,
we want a backup
+ File tempFile = new File(finalFile.getParentFile(),
finalFile.getName()+".bak");
+ logger.log(Level.INFO, "The temporary filename is : " + tempFile);
+
+ fos = new FileOutputStream(tempFile);
+ L10n.translationOverride.writeTo(fos);
+
+ FileUtil.renameTo(tempFile, finalFile);
+ logger.log(Level.INFO, "Override file saved successfully!");
+ } catch (IOException e) {
+ logger.log(Level.SEVERE, "Error while saving the translation
override: "+ e.getMessage(), e);
+ } finally {
+ Closer.close(fos);
+ }
+ }
+
+ /**
+ * Return a new copy of the current translation file
+ *
+ * @return SimpleFieldSet or null
+ */
+ public static SimpleFieldSet getCurrentLanguageTranslation() {
+ synchronized (sync) {
+ return (currentTranslation == null ? null : new
SimpleFieldSet(currentTranslation));
+ }
+ }
+
+ /**
+ * Return a copy of the current translation override if it exists or null
+ *
+ * @return SimpleFieldSet or null
+ */
+ public static SimpleFieldSet getOverrideForCurrentLanguageTranslation() {
+ synchronized (sync) {
+ return (translationOverride == null ? null : new
SimpleFieldSet(translationOverride));
+ }
+ }
+
+ /**
+ * Return a copy of the default translation file (english one)
+ *
+ * @return SimpleFieldSet
+ */
+ public static SimpleFieldSet getDefaultLanguageTranslation() {
+ synchronized (sync) {
+ if(fallbackTranslation == null)
+ fallbackTranslation = loadTranslation(FALLBACK_DEFAULT);
+
+ return new SimpleFieldSet(fallbackTranslation);
+ }
+ }
+
+ /**
+ * The real meat
+ *
+ * Same thing as getString(key, false);
+ * Ensure it will *always* return a String value.
+ *
+ * @param key
+ * @return the translated string or the default value from the default
language or the key if nothing is found
+ */
+ public static String getString(String key) {
+ return getString(key, false);
+ }
+
+ /**
+ * You probably don't want to use that one directly
+ * @see getString(String)
+ */
+ public static String getString(String key, boolean returnNullIfNotFound) {
+ String result = null;
+ synchronized (sync) {
+ if(translationOverride != null)
+ result = translationOverride.get(key);
+ }
+ if(result != null) return result;
+
+ synchronized (sync) {
+ if(currentTranslation != null)
+ result = currentTranslation.get(key);
+ }
+ if(result != null)
+ return result;
+ else {
+ logger.log(Level.INFO, "The translation for " + key + " hasn't
been found ("+getSelectedLanguage()+")! please tell the maintainer.");
+ return (returnNullIfNotFound ? null : getDefaultString(key));
+ }
+ }
+
+ /**
+ * Return the english translation of the key or the key itself if it
doesn't exist.
+ *
+ * @param key
+ * @return String
+ */
+ public static String getDefaultString(String key) {
+ String result = null;
+ // We instanciate it only if necessary
+ synchronized (sync) {
+ if(fallbackTranslation == null)
+ fallbackTranslation = loadTranslation(FALLBACK_DEFAULT);
+ result = fallbackTranslation.get(key);
+ }
+
+ if(result != null) {
+ return result;
+ }
+ logger.log(Level.SEVERE, "The default translation for " + key + "
hasn't been found!");
+ System.err.println("The default translation for " + key + " hasn't
been found!");
+ new Exception().printStackTrace();
+ return key;
+ }
+
+ /**
+ * Allows things like :
+ * L10n.getString("testing.test", new String[]{ "test1", "test2" }, new
String[] { "a", "b" })
+ *
+ * @param key
+ * @param patterns : a list of patterns wich are matchable from the
translation
+ * @param values : the values corresponding to the list
+ * @return the translated string or the default value from the default
language or the key if nothing is found
+ */
+ public static String getString(String key, String[] patterns, String[]
values) {
+ assert(patterns.length == values.length);
+ String result = getString(key);
+
+ for(int i=0; i<patterns.length; i++)
+ result = result.replaceAll("\\$\\{"+patterns[i]+"\\}",
quoteReplacement(values[i]));
+
+ return result;
+ }
+
+ private static String quoteReplacement(String s) {
+ if ((s.indexOf('\\') == -1) && (s.indexOf('$') == -1))
+ return s;
+ StringBuffer sb = new StringBuffer();
+ for (int i=0; i<s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == '\\') {
+ sb.append('\\');
+ sb.append('\\');
+ } else if (c == '$') {
+ sb.append('\\');
+ sb.append('$');
+ } else {
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Return the ISO code of the language used by the framework
+ *
+ * @return String
+ */
+ public static String getSelectedLanguage() {
+ synchronized (sync) {
+ if(currentClass == null) return null;
+ return currentClass.selectedLanguage;
+ }
+ }
+
+ /**
+ * Load a translation file depending on the given name and using the prefix
+ *
+ * @param name
+ * @return the Properties object or null if not found
+ */
+ public static SimpleFieldSet loadTranslation(String name) {
+ name = PREFIX.replace('.',
'/').concat(PREFIX.concat(name.concat(SUFFIX)));
+
+ SimpleFieldSet result = null;
+ InputStream in = null;
+ try {
+ ClassLoader loader = ClassLoader.getSystemClassLoader();
+
+ // Returns null on lookup failures:
+ in = loader.getResourceAsStream(name);
+ if(in != null)
+ result = SimpleFieldSet.readFrom(in, false, false);
+ } catch (Exception e) {
+ logger.log(Level.SEVERE, "Error while loading the l10n file from "
+ name + " :" + e.getMessage(), e);
+ result = null;
+ } finally {
+ Closer.close(in);
+ }
+
+ return result;
+ }
+
+ public static boolean isOverridden(String key) {
+ synchronized(sync) {
+ if(translationOverride == null) return false;
+ return translationOverride.get(key) != null;
+ }
+ }
+
+ public static String getString(String key, String pattern, String value) {
+ return getString(key, new String[] { pattern }, new String[] { value
}); // FIXME code efficiently!
+ }
+
+ public static char getMnemonic(String mnemoKey){
+ String key = mnemoKey + ".mnemonic";
+ String tmp = getString(key);
+ char ret;
+ if (tmp.length() != 0) {
+ ret = tmp.charAt(0);
+ } else {
+ //Should never happen, but did once...
+ System.out.println("Mnemonic key not found : " + key);
+ ret = '_';
+ }
+ return ret;
+ }
+
+}
Added: trunk/apps/thingamablog/src/thingamablog/l10n/LineReader.java
===================================================================
--- trunk/apps/thingamablog/src/thingamablog/l10n/LineReader.java
(rev 0)
+++ trunk/apps/thingamablog/src/thingamablog/l10n/LineReader.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -0,0 +1,16 @@
+/* This code is part of Freenet. It is distributed under the GNU General
+ * Public License, version 2 (or at your option any later version). See
+ * http://www.gnu.org/ for further details of the GPL. */
+package thingamablog.l10n;
+
+import java.io.IOException;
+
+public interface LineReader {
+
+ /**
+ * Read a \n or \r\n terminated line of UTF-8 or ISO-8859-1.
+ */
+ public String readLine(int maxLength, int bufferSize, boolean utf) throws
IOException;
+
+}
+
Added: trunk/apps/thingamablog/src/thingamablog/l10n/SimpleFieldSet.java
===================================================================
--- trunk/apps/thingamablog/src/thingamablog/l10n/SimpleFieldSet.java
(rev 0)
+++ trunk/apps/thingamablog/src/thingamablog/l10n/SimpleFieldSet.java
2008-04-22 23:39:58 UTC (rev 19512)
@@ -0,0 +1,888 @@
+/*
+ * SimpleFieldSet.java
+ *
+ * Created on 16 avril 2008, 22:23
+ *
+ * To change this template, choose Tools | Template Manager
+ * and open the template in the editor.
+ */
+
+package thingamablog.l10n;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.Map;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedWriter;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+
+import thingamablog.l10n.FSParseException;
+import thingamablog.l10n.LineReader;
+import net.sf.thingamablog.util.io.Closer;
+
+/**
+ * @author amphibian
+ *
+ * Very very simple FieldSet type thing, which uses the standard
+ * Java facilities.
+ */
+public class SimpleFieldSet {
+
+ private final Map values;
+ private Map subsets;
+ private String endMarker;
+ private final boolean shortLived;
+ static public final char MULTI_LEVEL_CHAR = '.';
+ static public final char MULTI_VALUE_CHAR = ';';
+ static public final char KEYVALUE_SEPARATOR_CHAR = '=';
+ private static final String[] EMPTY_STRING_ARRAY = new String[0];
+ private Logger logger = Logger.getLogger("net.sf.thingamablog.L10n");
+
+ /**
+ * Create a SimpleFieldSet.
+ * @param shortLived If false, strings will be interned to ensure that
they use as
+ * little memory as possible. Only set to true if the SFS will be
short-lived or
+ * small.
+ */
+ public SimpleFieldSet(boolean shortLived) {
+ values = new HashMap();
+ subsets = null;
+ this.shortLived = shortLived;
+ }
+
+ /**
+ * Construct a SimpleFieldSet from reading a BufferedReader.
+ * @param br
+ * @param allowMultiple If true, multiple lines with the same field name
will be
+ * combined; if false, the constructor will throw.
+ * @param shortLived If false, strings will be interned to ensure that
they use as
+ * little memory as possible. Only set to true if the SFS will be
short-lived or
+ * small.
+ * @throws IOException If the buffer could not be read, or if there was a
formatting
+ * problem.
+ */
+ public SimpleFieldSet(BufferedReader br, boolean allowMultiple, boolean
shortLived) throws IOException {
+ this(shortLived);
+ read(br, allowMultiple);
+ }
+
+ public SimpleFieldSet(SimpleFieldSet sfs){
+ values = new HashMap(sfs.values);
+ if(sfs.subsets != null)
+ subsets = new HashMap(sfs.subsets);
+ this.shortLived = false; // it's been copied!
+ endMarker = sfs.endMarker;
+ }
+
+ public SimpleFieldSet(LineReader lis, int maxLineLength, int
lineBufferSize, boolean tolerant, boolean utf8OrIso88591, boolean
allowMultiple, boolean shortLived) throws IOException {
+ this(shortLived);
+ read(lis, maxLineLength, lineBufferSize, tolerant, utf8OrIso88591,
allowMultiple);
+ }
+
+ /**
+ * Construct from a string.
+ * String format:
+ * blah=blah
+ * blah=blah
+ * End
+ * @param shortLived If false, strings will be interned to ensure that
they use as
+ * little memory as possible. Only set to true if the SFS will be
short-lived or
+ * small.
+ * @throws IOException if the string is too short or invalid.
+ */
+ public SimpleFieldSet(String content, boolean allowMultiple, boolean
shortLived) throws IOException {
+ this(shortLived);
+ StringReader sr = new StringReader(content);
+ BufferedReader br = new BufferedReader(sr);
+ read(br, allowMultiple);
+ }
+
+ /**
+ * Read from disk
+ * Format:
+ * blah=blah
+ * blah=blah
+ * End
+ * @param allowMultiple
+ */
+ private void read(BufferedReader br, boolean allowMultiple) throws
IOException {
+ boolean firstLine = true;
+ while(true) {
+ String line = br.readLine();
+ if(line == null) {
+ if(firstLine) throw new EOFException();
+ throw new IOException("No end Marker!");
+ }
+ firstLine = false;
+ int index = line.indexOf(KEYVALUE_SEPARATOR_CHAR);
+ if(index >= 0) {
+ // Mapping
+ String before = line.substring(0, index);
+ String after = line.substring(index+1);
+ if(!shortLived) after = after.intern();
+ put(before, after, allowMultiple, false);
+ } else {
+ endMarker = line;
+ return;
+ }
+
+ }
+ }
+
+ /**
+ * Read from disk
+ * Format:
+ * blah=blah
+ * blah=blah
+ * End
+ * @param utfOrIso88591 If true, read as UTF-8, otherwise read as
ISO-8859-1.
+ */
+ private void read(LineReader br, int maxLength, int bufferSize, boolean
tolerant, boolean utfOrIso88591, boolean allowMultiple) throws IOException {
+ boolean firstLine = true;
+ while(true) {
+ String line = br.readLine(maxLength, bufferSize, utfOrIso88591);
+ if(line == null) {
+ if(firstLine) throw new EOFException();
+ if(tolerant)
+ logger.log(Level.SEVERE, "No end marker");
+ else
+ throw new IOException("No end marker");
+ return;
+ }
+ if((line.length() == 0) && tolerant) continue; // ignore
+ firstLine = false;
+ int index = line.indexOf(KEYVALUE_SEPARATOR_CHAR);
+ if(index >= 0) {
+ // Mapping
+ String before = line.substring(0, index);
+ String after = line.substring(index+1);
+ if(!shortLived) after = after.intern();
+ put(before, after, allowMultiple, false);
+ } else {
+ endMarker = line;
+ return;
+ }
+
+ }
+ }
+
+ public synchronized String get(String key) {
+ int idx = key.indexOf(MULTI_LEVEL_CHAR);
+ if(idx == -1)
+ return (String) values.get(key);
+ else if(idx == 0)
+ return (subset("") == null) ? null :
subset("").get(key.substring(1));
+ else {
+ if(subsets == null) return null;
+ String before = key.substring(0, idx);
+ String after = key.substring(idx+1);
+ SimpleFieldSet fs = (SimpleFieldSet) (subsets.get(before));
+ if(fs == null) return null;
+ return fs.get(after);
+ }
+ }
+
+ public String[] getAll(String key) {
+ String k = get(key);
+ if(k == null) return null;
+ return split(k);
+ }
+
+ private static final String[] split(String string) {
+ if(string == null) return new String[0];
+ return string.split(String.valueOf(MULTI_VALUE_CHAR)); // slower???
+// int index = string.indexOf(';');
+// if(index == -1) return null;
+// Vector v=new Vector();
+// v.removeAllElements();
+// while(index>0){
+// // Mapping
+// String before = string.substring(0, index);
+// String after = string.substring(index+1);
+// v.addElement(before);
+// string=after;
+// index = string.indexOf(';');
+// }
+//
+// return (String[]) v.toArray();
+ }
+
+ private static final String unsplit(String[] strings) {
+ StringBuffer sb = new StringBuffer();
+ for(int i=0;i<strings.length;i++) {
+ if(i != 0) sb.append(MULTI_VALUE_CHAR);
+ sb.append(strings[i]);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Put contents of a fieldset, overwrite old values.
+ */
+ public void putAllOverwrite(SimpleFieldSet fs) {
+ Iterator i = fs.values.keySet().iterator();
+ while(i.hasNext()) {
+ String key = (String) i.next();
+ String hisVal = (String) fs.values.get(key);
+ values.put(key, hisVal); // overwrite old
+ }
+ if(fs.subsets == null) return;
+ if(subsets == null) subsets = new HashMap();
+ i = fs.subsets.keySet().iterator();
+ while(i.hasNext()) {
+ String key = (String) i.next();
+ SimpleFieldSet hisFS = (SimpleFieldSet) fs.subsets.get(key);
+ SimpleFieldSet myFS = (SimpleFieldSet) subsets.get(key);
+ if(myFS != null) {
+ myFS.putAllOverwrite(hisFS);
+ } else {
+ subsets.put(key, hisFS);
+ }
+ }
+ }
+
+ /**
+ * Set a key to a value. If the value already exists, throw
IllegalStateException.
+ * @param key The key.
+ * @param value The value.
+ */
+ public void putSingle(String key, String value) {
+ if(value == null) return;
+ if(!shortLived) value = value.intern();
+ if(!put(key, value, false, false))
+ throw new IllegalStateException("Value already exists: "+value+"
but want to set "+key+" to "+value);
+ }
+
+ /**
+ * Aggregating put. Set a key to a value, if the value already exists,
append to it.
+ * @param key The key.
+ * @param value The value.
+ */
+ public void putAppend(String key, String value) {
+ if(value == null) return;
+ if(!shortLived) value = value.intern();
+ put(key, value, true, false);
+ }
+
+ /**
+ * Set a key to a value, overwriting any existing value if present.
+ * @param key The key.
+ * @param value The value.
+ */
+ public void putOverwrite(String key, String value) {
+ if(value == null) return;
+ if(!shortLived) value = value.intern();
+ put(key, value, false, true);
+ }
+
+ /**
+ * Set a key to a value.
+ * @param key The key.
+ * @param value The value.
+ * @param allowMultiple If true, if the key already exists then the value
will be
+ * appended to the existing value. If false, we return false to indicate
that the
+ * old value is unchanged.
+ * @return True unless allowMultiple was false and there was a
pre-existing value,
+ * or value was null.
+ */
+ private synchronized final boolean put(String key, String value, boolean
allowMultiple, boolean overwrite) {
+ int idx;
+ if(value == null) return true; // valid no-op
+ if(value.indexOf('\n') != -1) throw new IllegalArgumentException("A
simplefieldSet can't accept newlines !");
+ if((idx = key.indexOf(MULTI_LEVEL_CHAR)) == -1) {
+ String x = (String) values.get(key);
+
+ if(!shortLived) key = key.intern();
+ if(x == null || overwrite) {
+ values.put(key, value);
+ } else {
+ if(!allowMultiple) return false;
+ values.put(key, ((String)values.get(key))+ MULTI_VALUE_CHAR
+value);
+ }
+ } else {
+ String before = key.substring(0, idx);
+ String after = key.substring(idx+1);
+ SimpleFieldSet fs = null;
+ if(subsets == null)
+ subsets = new HashMap();
+ fs = (SimpleFieldSet) (subsets.get(before));
+ if(fs == null) {
+ fs = new SimpleFieldSet(shortLived);
+ if(!shortLived) before = before.intern();
+ subsets.put(before, fs);
+ }
+ fs.put(after, value, allowMultiple, overwrite);
+ }
+ return true;
+ }
+
+ public void put(String key, int value) {
+ // Use putSingle so it does the intern check
+ putSingle(key, Integer.toString(value));
+ }
+
+ public void put(String key, long value) {
+ putSingle(key, Long.toString(value));
+ }
+
+ public void put(String key, short value) {
+ putSingle(key, Short.toString(value));
+ }
+
+ public void put(String key, char c) {
+ putSingle(key, Character.toString(c));
+ }
+
+ public void put(String key, boolean b) {
+ // Don't use putSingle, avoid intern check (Boolean.toString returns
interned strings anyway)
+ put(key, Boolean.toString(b), false, false);
+ }
+
+ public void put(String key, double windowSize) {
+ putSingle(key, Double.toString(windowSize));
+ }
+
+ /**
+ * Write the contents of the SimpleFieldSet to a Writer.
+ * Note: The caller *must* buffer the writer to avoid lousy performance!
+ * (StringWriter is by definition buffered, otherwise wrap it in a
BufferedWriter)
+ *
+ * @warning keep in mind that a Writer is not necessarily UTF-8!!
+ */
+ public void writeTo(Writer w) throws IOException {
+ writeTo(w, "", false);
+ }
+
+ /**
+ * Write the contents of the SimpleFieldSet to a Writer.
+ * Note: The caller *must* buffer the writer to avoid lousy performance!
+ * (StringWriter is by definition buffered, otherwise wrap it in a
BufferedWriter)
+ *
+ * @warning keep in mind that a Writer is not necessarily UTF-8!!
+ */
+ synchronized void writeTo(Writer w, String prefix, boolean noEndMarker)
throws IOException {
+ for(Iterator i = values.entrySet().iterator();i.hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ String key = (String) entry.getKey();
+ String value = (String) entry.getValue();
+ w.write(prefix);
+ w.write(key);
+ w.write(KEYVALUE_SEPARATOR_CHAR);
+ w.write(value);
+ w.write('\n');
+ }
+ if(subsets != null) {
+ for(Iterator i = subsets.entrySet().iterator();i.hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ String key = (String) entry.getKey();
+ SimpleFieldSet subset = (SimpleFieldSet) entry.getValue();
+ if(subset == null) throw new NullPointerException();
+ subset.writeTo(w, prefix+key+MULTI_LEVEL_CHAR, true);
+ }
+ }
+ if(!noEndMarker) {
+ if(endMarker == null)
+ w.write("End\n");
+ else {
+ w.write(endMarker);
+ w.write('\n');
+ }
+ }
+ }
+
+ public void writeToOrdered(Writer w) throws IOException {
+ writeToOrdered(w, "", false);
+ }
+
+ private synchronized void writeToOrdered(Writer w, String prefix, boolean
noEndMarker) throws IOException {
+ String[] keys = (String[]) values.keySet().toArray(new
String[values.size()]);
+ int i=0;
+
+ // Sort
+ Arrays.sort(keys);
+
+ // Output
+ for(i=0; i < keys.length; i++)
+ w.write(prefix+keys[i]+KEYVALUE_SEPARATOR_CHAR+get(keys[i])+'\n');
+
+ if(subsets != null) {
+ String[] orderedPrefixes = (String[]) subsets.keySet().toArray(new
String[subsets.size()]);
+ // Sort
+ Arrays.sort(orderedPrefixes);
+
+ for(i=0; i < orderedPrefixes.length; i++) {
+ SimpleFieldSet subset = subset(orderedPrefixes[i]);
+ if(subset == null) throw new NullPointerException();
+ subset.writeToOrdered(w,
prefix+orderedPrefixes[i]+MULTI_LEVEL_CHAR, true);
+ }
+ }
+
+ if(!noEndMarker) {
+ if(endMarker == null)
+ w.write("End\n");
+ else
+ w.write(endMarker+ '\n');
+ }
+ }
+
+ public String toString() {
+ StringWriter sw = new StringWriter();
+ try {
+ writeTo(sw);
+ } catch (IOException e) {
+ logger.log(Level.SEVERE, "WTF?!: "+e+" in toString()!", e);
+ }
+ return sw.toString();
+ }
+
+ public String toOrderedString() {
+ StringWriter sw = new StringWriter();
+ try {
+ writeToOrdered(sw);
+ } catch (IOException e) {
+ logger.log(Level.SEVERE, "WTF?!: "+e+" in toString()!", e);
+ }
+ return sw.toString();
+ }
+
+ public String getEndMarker() {
+ return endMarker;
+ }
+
+ public void setEndMarker(String s) {
+ endMarker = s;
+ }
+
+ public synchronized SimpleFieldSet subset(String key) {
+ if(subsets == null) return null;
+ int idx = key.indexOf(MULTI_LEVEL_CHAR);
+ if(idx == -1)
+ return (SimpleFieldSet) subsets.get(key);
+ String before = key.substring(0, idx);
+ String after = key.substring(idx+1);
+ SimpleFieldSet fs = (SimpleFieldSet) subsets.get(before);
+ if(fs == null) return null;
+ return fs.subset(after);
+ }
+
+ /**
+ * Like subset(), only throws instead of returning null.
+ * @throws FSParseException
+ */
+ public synchronized SimpleFieldSet getSubset(String key) throws
FSParseException {
+ SimpleFieldSet fs = subset(key);
+ if(fs == null) throw new FSParseException("No such subset "+key);
+ return fs;
+ }
+
+ public Iterator keyIterator() {
+ return new KeyIterator("");
+ }
+
+ public KeyIterator keyIterator(String prefix) {
+ return new KeyIterator(prefix);
+ }
+
+ public Iterator toplevelKeyIterator() {
+ return values.keySet().iterator();
+ }
+
+ public class KeyIterator implements Iterator {
+
+ final Iterator valuesIterator;
+ final Iterator subsetIterator;
+ KeyIterator subIterator;
+ String prefix;
+
+ /**
+ * It provides an iterator for the SimpleSetField
+ * which passes through every key.
+ * (e.g. for key1=value1 key2.sub2=value2 key1.sub=value3
+ * it will provide key1,key2.sub2,key1.sub)
+ * @param a prefix to put BEFORE every key
+ * (e.g. for key1=value, if the iterator is created with prefix
"aPrefix",
+ * it will provide aPrefixkey1
+ */
+ public KeyIterator(String prefix) {
+ synchronized(SimpleFieldSet.this) {
+ valuesIterator = values.keySet().iterator();
+ if(subsets != null)
+ subsetIterator = subsets.keySet().iterator();
+ else
+ subsetIterator = null;
+ while(true) {
+ if(valuesIterator != null && valuesIterator.hasNext())
break;
+ if(subsetIterator == null || !subsetIterator.hasNext())
break;
+ String name = (String) subsetIterator.next();
+ if(name == null) continue;
+ SimpleFieldSet fs = (SimpleFieldSet) subsets.get(name);
+ if(fs == null) continue;
+ String newPrefix = prefix + name + MULTI_LEVEL_CHAR;
+ subIterator = fs.keyIterator(newPrefix);
+ if(subIterator.hasNext()) break;
+ subIterator = null;
+ }
+ this.prefix = prefix;
+ }
+ }
+
+ public boolean hasNext() {
+ synchronized(SimpleFieldSet.this) {
+ while(true) {
+ if(valuesIterator.hasNext()) return true;
+ if((subIterator != null) && subIterator.hasNext()) return
true;
+ if(subIterator != null) subIterator = null;
+ if(subsetIterator != null && subsetIterator.hasNext()) {
+ String key = (String) subsetIterator.next();
+ SimpleFieldSet fs = (SimpleFieldSet) subsets.get(key);
+ String newPrefix = prefix + key + MULTI_LEVEL_CHAR;
+ subIterator = fs.keyIterator(newPrefix);
+ } else
+ return false;
+ }
+ }
+ }
+
+ public final Object next() {
+ return nextKey();
+ }
+
+ public String nextKey() {
+ synchronized(SimpleFieldSet.this) {
+ String ret = null;
+ if(valuesIterator != null && valuesIterator.hasNext()) {
+ return prefix + valuesIterator.next();
+ }
+ // Iterate subsets.
+ while(true) {
+ if(subIterator != null && subIterator.hasNext()) {
+ // If we have a retval, and we have a next value,
return
+ if(ret != null) return ret;
+ ret = (String) subIterator.next();
+ if(subIterator.hasNext())
+ // If we have a retval, and we have a next value,
return
+ if(ret != null) return ret;
+ }
+ // Otherwise, we need to get a new subIterator (or
hasNext() will return false)
+ subIterator = null;
+ if(subsetIterator != null && subsetIterator.hasNext()) {
+ String key = (String) subsetIterator.next();
+ SimpleFieldSet fs = (SimpleFieldSet) subsets.get(key);
+ String newPrefix = prefix + key + MULTI_LEVEL_CHAR;
+ subIterator = fs.keyIterator(newPrefix);
+ } else {
+ // No more subIterator's
+ if(ret == null)
+ logger.log(Level.SEVERE, "Returning null from
KeyIterator.nextKey() - should never happen!");
+ return ret;
+ }
+ }
+ }
+ }
+
+ public synchronized void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /** Tolerant put(); does nothing if fs is empty */
+ public void tput(String key, SimpleFieldSet fs) {
+ if(fs == null || fs.isEmpty()) return;
+ put(key, fs);
+ }
+
+ public void put(String key, SimpleFieldSet fs) {
+ if(fs == null) return; // legal no-op, because used everywhere
+ if(fs.isEmpty()) // can't just no-op, because caller might add the FS
then populate it...
+ throw new IllegalArgumentException("Empty");
+ if(subsets == null)
+ subsets = new HashMap();
+ if(subsets.containsKey(key))
+ throw new IllegalArgumentException("Already contains "+key+" but
trying to add a SimpleFieldSet!");
+ if(!shortLived) key = key.intern();
+ subsets.put(key, fs);
+ }
+
+ public synchronized void removeValue(String key) {
+ int idx;
+ if((idx = key.indexOf(MULTI_LEVEL_CHAR)) == -1) {
+ values.remove(key);
+ } else {
+ if(subsets == null) return;
+ String before = key.substring(0, idx);
+ String after = key.substring(idx+1);
+ SimpleFieldSet fs = (SimpleFieldSet) (subsets.get(before));
+ if(fs == null) {
+ return;
+ }
+ fs.removeValue(after);
+ if(fs.isEmpty()) {
+ subsets.remove(before);
+ if(subsets.isEmpty())
+ subsets = null;
+ }
+ }
+ }
+
+ /**
+ * It removes the specified subset.
+ * For example, in a SimpleFieldSet like this:
+ * foo=bar
+ * foo.bar=foobar
+ * foo.bar.boo=foobarboo
+ * calling it with the parameter "foo"
+ * means to drop the second and the third line.
+ * @param is the subset to remove
+ */
+ public synchronized void removeSubset(String key) {
+ if(subsets == null) return;
+ int idx;
+ if((idx = key.indexOf(MULTI_LEVEL_CHAR)) == -1) {
+ subsets.remove(key);
+ } else {
+ String before = key.substring(0, idx);
+ String after = key.substring(idx+1);
+ SimpleFieldSet fs = (SimpleFieldSet) (subsets.get(before));
+ if(fs == null) {
+ return;
+ }
+ fs.removeSubset(after);
+ if(fs.isEmpty()) {
+ subsets.remove(before);
+ if(subsets.isEmpty())
+ subsets = null;
+ }
+ }
+ }
+
+ /** Is this SimpleFieldSet empty? */
+ public boolean isEmpty() {
+ return values.isEmpty() && (subsets == null || subsets.isEmpty());
+ }
+
+ public Iterator directSubsetNameIterator() {
+ return (subsets == null) ? null : subsets.keySet().iterator();
+ }
+
+ public String[] namesOfDirectSubsets() {
+ return (subsets == null) ? EMPTY_STRING_ARRAY : (String[])
subsets.keySet().toArray(new String[subsets.size()]);
+ }
+
+ public static SimpleFieldSet readFrom(InputStream is, boolean
allowMultiple, boolean shortLived) throws IOException {
+ BufferedInputStream bis = null;
+ InputStreamReader isr = null;
+ BufferedReader br = null;
+
+ try {
+ bis = new BufferedInputStream(is);
+ try {
+ isr = new InputStreamReader(bis, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ System.out.println("Impossible: "+e);
+ e.getStackTrace();
+ is.close();
+ return null;
+ }
+ br = new BufferedReader(isr);
+ SimpleFieldSet fs = new SimpleFieldSet(br, allowMultiple,
shortLived);
+ br.close();
+
+ return fs;
+ } finally {
+ Closer.close(br);
+ Closer.close(isr);
+ Closer.close(bis);
+ }
+ }
+
+ public static SimpleFieldSet readFrom(File f, boolean allowMultiple,
boolean shortLived) throws IOException {
+ return readFrom(new FileInputStream(f), allowMultiple, shortLived);
+ }
+
+ /** Write to the given OutputStream, close it and flush it. */
+ public void writeTo(OutputStream os) throws IOException {
+ BufferedOutputStream bos = null;
+ OutputStreamWriter osw = null;
+ BufferedWriter bw = null;
+
+ try {
+ bos = new BufferedOutputStream(os);
+ try {
+ osw = new OutputStreamWriter(bos, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ logger.log(Level.SEVERE, "Impossible: " + e, e);
+ os.close();
+ return;
+ }
+ bw = new BufferedWriter(osw);
+ writeTo(bw);
+ // close() calls flush() but IGNORES ALL ERRORS!
+ bw.flush();
+ bw.close();
+ }finally {
+ Closer.close(bw);
+ Closer.close(osw);
+ Closer.close(bos);
+ }
+ }
+
+ public int getInt(String key, int def) {
+ String s = get(key);
+ if(s == null) return def;
+ try {
+ return Integer.parseInt(s);
+ } catch (NumberFormatException e) {
+ return def;
+ }
+ }
+
+ public int getInt(String key) throws FSParseException {
+ String s = get(key);
+ if(s == null) throw new FSParseException("No key "+key);
+ try {
+ return Integer.parseInt(s);
+ } catch (NumberFormatException e) {
+ throw new FSParseException("Cannot parse "+s+" for integer "+key);
+ }
+ }
+
+ public double getDouble(String key, double def) {
+ String s = get(key);
+ if(s == null) return def;
+ try {
+ return Double.parseDouble(s);
+ } catch (NumberFormatException e) {
+ return def;
+ }
+ }
+
+ public double getDouble(String key) throws FSParseException {
+ String s = get(key);
+ if(s == null) throw new FSParseException("No key "+key);
+ try {
+ return Double.parseDouble(s);
+ } catch (NumberFormatException e) {
+ throw new FSParseException("Cannot parse "+s+" for integer "+key);
+ }
+ }
+
+ public long getLong(String key, long def) {
+ String s = get(key);
+ if(s == null) return def;
+ try {
+ return Long.parseLong(s);
+ } catch (NumberFormatException e) {
+ return def;
+ }
+ }
+
+ public long getLong(String key) throws FSParseException {
+ String s = get(key);
+ if(s == null) throw new FSParseException("No key "+key);
+ try {
+ return Long.parseLong(s);
+ } catch (NumberFormatException e) {
+ throw new FSParseException("Cannot parse "+s+" for long "+key);
+ }
+ }
+
+ public short getShort(String key) throws FSParseException {
+ String s = get(key);
+ if(s == null) throw new FSParseException("No key "+key);
+ try {
+ return Short.parseShort(s);
+ } catch (NumberFormatException e) {
+ throw new FSParseException("Cannot parse "+s+" for short "+key);
+ }
+ }
+
+ public short getShort(String key, short def) {
+ String s = get(key);
+ if(s == null) return def;
+ try {
+ return Short.parseShort(s);
+ } catch (NumberFormatException e) {
+ return def;
+ }
+ }
+
+ public char getChar(String key) throws FSParseException {
+ String s = get(key);
+ if(s == null) throw new FSParseException("No key "+key);
+ if (s.length() == 1)
+ return s.charAt(0);
+ else
+ throw new FSParseException("Cannot parse "+s+" for char "+key);
+ }
+
+ public char getChar(String key, char def) {
+ String s = get(key);
+ if(s == null) return def;
+ if (s.length() == 1)
+ return s.charAt(0);
+ else
+ return def;
+ }
+
+ public boolean getBoolean(String key, boolean def) {
+ return Fields.stringToBool(get(key), def);
+ }
+
+ public boolean getBoolean(String key) throws FSParseException {
+ try {
+ return Fields.stringToBool(get(key));
+ } catch(NumberFormatException e) {
+ throw new FSParseException(e);
+ }
+ }
+
+ public void put(String key, int[] value) {
+ // FIXME this could be more efficient...
+ removeValue(key);
+ for(int i=0;i<value.length;i++)
+ putAppend(key, Integer.toString(value[i]));
+ }
+
+ public int[] getIntArray(String key) {
+ String[] strings = getAll(key);
+ if(strings == null) return null;
+ int[] ret = new int[strings.length];
+ for(int i=0;i<strings.length;i++) {
+ try {
+ ret[i] = Integer.parseInt(strings[i]);
+ } catch (NumberFormatException e) {
+ logger.log(Level.SEVERE, "Cannot parse "+strings[i]+" : "+e,
e);
+ return null;
+ }
+ }
+ return ret;
+ }
+
+ public void putOverwrite(String key, String[] strings) {
+ putOverwrite(key, unsplit(strings));
+ }
+
+ public String getString(String key) throws FSParseException {
+ String s = get(key);
+ if(s == null) throw new FSParseException("No such element "+key);
+ return s;
+ }
+
+}
Added: trunk/apps/thingamablog/src/thingamablog/l10n/i18n.java
===================================================================
--- trunk/apps/thingamablog/src/thingamablog/l10n/i18n.java
(rev 0)
+++ trunk/apps/thingamablog/src/thingamablog/l10n/i18n.java 2008-04-22
23:39:58 UTC (rev 19512)
@@ -0,0 +1,49 @@
+/*
+ * i18n.java
+ *
+ * Created on 21 avril 2008, 17:17
+ */
+
+package thingamablog.l10n;
+
+import java.lang.reflect.Method;
+import java.util.Locale;
+import thingamablog.l10n.L10n;
+
+/**
+ * Extends the L10n class, to keep the same name and interface as before
+ * @author dieppe
+ */
+public class i18n extends L10n{
+
+ i18n(String selected){
+ super(selected);
+ }
+
+ public static void setLocale(String selected){
+ setLanguage(selected);
+ }
+
+ public static String str(String key){
+ return getString(key);
+ }
+
+ public static char mnem(String MnemoKey){
+ return getMnemonic(MnemoKey);
+ }
+
+ public static Locale getLocale(){
+ String loc = getSelectedLanguage();
+ return new Locale(loc);
+ }
+
+ public static Locale[] getAvailableLanguagePackLocales() {
+ int Length = AVAILABLE_LANGUAGES.length;
+ Locale result[] = new Locale[Length];
+ for(int i = 0; i<Length; i++) {
+ String loc = AVAILABLE_LANGUAGES[i];
+ result[i]= new Locale(loc);
+ }
+ return result;
+ }
+}