/*
* This file is part of muCommander, http://www.mucommander.com
* Copyright (C) 2002-2016 Maxence Bernard
*
* muCommander is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* muCommander is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.mucommander.text;
import com.mucommander.commons.conf.ConfigurationEvent;
import com.mucommander.commons.conf.ConfigurationListener;
import com.mucommander.conf.MuConfigurations;
import com.mucommander.conf.MuPreference;
import com.mucommander.conf.MuPreferences;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* CustomDateFormat allows custom date formatting, according to the date format stored in the preferences.
*
* @author Maxence Bernard
*/
public class CustomDateFormat implements ConfigurationListener {
/** Singleton instance */
private static CustomDateFormat singleton;
/** Custom SimpleDateFormat instance */
private static SimpleDateFormat dateFormat;
/**
* Creates a new CustomDateFormat instance.
*/
private CustomDateFormat() {}
/**
* Forces static fields to be initialized
*/
public static void init() {
// Create a singleton instance and keep it as a static member of this class.
// Not doing it so would cause the garbage collector to GC it as MuConfiguration holds
// weak references of its listeners.
singleton = new CustomDateFormat();
MuConfigurations.addPreferencesListener(singleton);
dateFormat = createDateFormat();
}
/**
* Replace the default '/' separator in the given format string, by the given custom separator.
*
* @return the given format string with '/' separator characters replaced by the given separator character.
*/
public static String replaceDateSeparator(String dateFormatString, String separator) {
if(separator==null || separator.equals("/"))
return dateFormatString;
StringBuilder dateFormatStringSB = new StringBuilder();
int pos1 = 0;
int pos2;
while((pos2=dateFormatString.indexOf('/', pos1))>-1) {
dateFormatStringSB.append(dateFormatString.substring(pos1, pos2));
dateFormatStringSB.append(separator);
pos1 = pos2+1;
}
dateFormatStringSB.append(dateFormatString.substring(pos1, dateFormatString.length()));
return dateFormatStringSB.toString();
}
/**
* Returns the date format stored in the preferences and used by this class to format dates.
* The format of the returned string is the one used by the <code>java.text.SimpleDateFormat</code> class.
*/
public static String getDateFormatString() {
return replaceDateSeparator(
MuConfigurations.getPreferences().getVariable(MuPreference.DATE_FORMAT, MuPreferences.DEFAULT_DATE_FORMAT),
MuConfigurations.getPreferences().getVariable(MuPreference.DATE_SEPARATOR, MuPreferences.DEFAULT_DATE_SEPARATOR))
+ " " + MuConfigurations.getPreferences().getVariable(MuPreference.TIME_FORMAT, MuPreferences.DEFAULT_TIME_FORMAT);
}
/**
* Forces CustomDateFormat to update the date format by looking it up in the preferences.
*/
public static synchronized void updateDateFormat() {
dateFormat = createDateFormat();
}
/**
* Creates and returns a SimpleDateFormat instance using the date format stored in the preferences.
*/
private static SimpleDateFormat createDateFormat() {
return new SimpleDateFormat(getDateFormatString());
}
/**
* Formats the given with custom date format and returns a formatted date string.
*
* @return a formatted string representing the given date.
*/
public static synchronized String format(Date date) {
// Calls to SimpleDateFormat MUST be synchronized otherwise it will start throwing exceptions (verified that!),
// that is why this method is synchronized.
// Quote from SimpleDateFormat's Javadoc: "Date formats are not synchronized. It is recommended to create
// separate format instances for each thread. If multiple threads access a format concurrently,
// it must be synchronized externally."
return dateFormat.format(date);
}
///////////////////////////////////
// ConfigurationListener methods //
///////////////////////////////////
/**
* Listens to some configuration variables.
*/
public void configurationChanged(ConfigurationEvent event) {
String var = event.getVariable();
if (var.equals(MuPreferences.TIME_FORMAT) || var.equals(MuPreferences.DATE_FORMAT) || var.equals(MuPreferences.DATE_SEPARATOR))
updateDateFormat();
}
}