/**
*
*/
package com.soundlooper.system.preferences;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.soundlooper.system.preferences.recentfile.RecentFile;
import com.soundlooper.system.preferences.recentfile.RecentFileSet;
/**
* ----------------------------------------------------------------------------
* ---- Sound Looper is an audio player that allow user to loop between two
* points Copyright (C) 2014 Alexandre NEDJARI
*
* This program 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.
*
* This program 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/>.
*
* Preference access
*
* @author Alexandre NEDJARI
* @since 26 juil. 2011
* ----------------------------------------------------------
* ----------------------
*/
public final class Preferences {
/**
* Logger for this class
*/
private Logger logger = LogManager.getLogger(this.getClass());
/**
* The key for the always on top preference
*/
public static final String KEY_ALWAYS_ON_TOP = "always.on.top";
/**
* The key for the last path used preference
*/
public static final String KEY_LAST_PATH_USED = "last.path.used";
/**
* The key for the last path used preference
*/
public static final String KEY_LAST_VOLUME_USED = "last.volume.used";
/**
* The key for the recent file list preference
*/
public static final String KEY_RECENT_FILE_LIST = "recent.file.list";
/**
* The key for the recent file list size preference
*/
public static final String KEY_RECENT_FILE_LIST_SIZE = "recent.file.list.size";
/**
* Always on top preference
*/
private BooleanProperty alwaysOnTop = new SimpleBooleanProperty(false);
/**
* Last path used preference
*/
private String lastPathUsed = "";
/**
* Last volume used preference
*/
private int lastVolumeUsed = 100;
/**
* The recent file list
*/
private RecentFileSet recentFileSet = null;
/**
* The number of recent file to store
*/
private int recentFileListSize = 10;
/**
* list of listeners
*/
private ArrayList<PreferencesListener> listeners = new ArrayList<PreferencesListener>();
/**
* The instance
*/
private static Preferences instance = null;
/**
* The properties
*/
private Properties properties;
/**
* The properties file
*/
private File propertieFile;
/**
* Get the instance
*
* @return the instance
*/
public synchronized static Preferences getInstance() {
if (Preferences.instance == null) {
Preferences.instance = new Preferences();
}
return Preferences.instance;
}
/**
* Private constructor
*/
private Preferences() {
logger.info("Preferences initialisation");
propertieFile = new File("preferences.properties");
try {
this.properties = new Properties();
if (!this.propertieFile.exists()) {
this.propertieFile.createNewFile();
this.properties.storeToXML(new FileOutputStream(
this.propertieFile), "", "UTF-8");
}
this.properties
.loadFromXML(new FileInputStream(this.propertieFile));
// /////////////ALWAYS ON TOP////////////////////////////
String stringAlwaysOnTop = this.properties.getProperty(
Preferences.KEY_ALWAYS_ON_TOP, "false");
if (stringAlwaysOnTop.equals(Boolean.TRUE.toString())) {
this.alwaysOnTop.set(true);
} else if (stringAlwaysOnTop.equals(Boolean.FALSE.toString())) {
this.alwaysOnTop.set(false);
} else {
this.logger.warn("Value for " + Preferences.KEY_ALWAYS_ON_TOP
+ " is not valide : '" + stringAlwaysOnTop
+ "', use the default value");
}
this.alwaysOnTop.addListener(new ChangeListener<Boolean>() {
@Override
public void changed(
ObservableValue<? extends Boolean> observable,
Boolean oldValue, Boolean newValue) {
Preferences.this.properties.setProperty(
Preferences.KEY_ALWAYS_ON_TOP,
Boolean.toString(newValue));
};
});
// /////////////////////////////////////////////////////////
this.lastPathUsed = this.properties.getProperty(
Preferences.KEY_LAST_PATH_USED, "");
this.lastVolumeUsed = Integer.parseInt(this.properties.getProperty(
Preferences.KEY_LAST_VOLUME_USED, "100"));
this.recentFileListSize = Integer.parseInt(this.properties
.getProperty(Preferences.KEY_RECENT_FILE_LIST_SIZE, "10"));
this.recentFileSet = this.getRecentFileSet();
} catch (IOException e) {
this.logger.warn(
"Unable to read properties, use the default values", e);
}
this.logger.info("Initial value for '" + Preferences.KEY_ALWAYS_ON_TOP
+ "' : " + this.alwaysOnTop);
this.logger.info("Initial value for '" + Preferences.KEY_LAST_PATH_USED
+ "' : " + this.lastPathUsed);
}
/**
* File are stored as File1:Date1|File2:Date2
*
* @return the file as map
*/
private RecentFileSet getRecentFileSet() {
if (this.recentFileSet == null) {
String recentFileListString = this.properties.getProperty(
Preferences.KEY_RECENT_FILE_LIST, "");
this.logger.info("Initial value for '"
+ Preferences.KEY_RECENT_FILE_LIST + "' : "
+ recentFileListString);
this.recentFileSet = new RecentFileSet(this.recentFileListSize);
StringTokenizer recentFileStringTokenizer = new StringTokenizer(
recentFileListString, "|");
while (recentFileStringTokenizer.hasMoreElements()) {
String recentFileString = recentFileStringTokenizer.nextToken();
String[] recentFileTab = recentFileString.split("\\*");
if (recentFileTab.length != 2) {
continue;
}
File file = new File(recentFileTab[0]);
Date lastAccessDate = new Date(Long.valueOf(recentFileTab[1])
.longValue());
this.recentFileSet.addRecentFile(new RecentFile(file,
lastAccessDate));
}
}
return this.recentFileSet;
}
/**
* Get the last volume used
*
* @return the volume
*/
public int getLastVolumeUsed() {
return this.lastVolumeUsed;
}
/**
* @param newLastVolumeUsed
* the lastVolumeUsed to set
*/
public void setLastVolumeUsed(int newLastVolumeUsed) {
this.logger.info(Preferences.KEY_LAST_VOLUME_USED + " is changed from "
+ this.lastVolumeUsed + " to " + newLastVolumeUsed);
this.lastVolumeUsed = newLastVolumeUsed;
this.properties.setProperty(Preferences.KEY_LAST_VOLUME_USED,
Integer.toString(this.lastVolumeUsed));
for (PreferencesListener listener : this.listeners) {
this.logger.info("Notifie listener : " + listener.toString());
listener.onPreferenceChange(Preferences.KEY_LAST_VOLUME_USED,
Integer.valueOf(newLastVolumeUsed));
}
}
/**
* Get the recent file list
*
* @return the recent file list
*/
public List<RecentFile> getRecentFileList() {
return this.getRecentFileSet().getRecentFileListCopy();
}
/**
* Add a new file to the recent file list
*
* @param absoluteFilePath
* the file to add absolute path
*/
public void addFileToRecentFileList(String absoluteFilePath) {
this.getRecentFileSet().addRecentFile(
new RecentFile(new File(absoluteFilePath), new Date()));
String recentFileListRepresentation = "";
for (RecentFile recentFile : this.getRecentFileSet()
.getRecentFileListCopy()) {
recentFileListRepresentation += recentFile.getFile()
.getAbsolutePath()
+ "*"
+ recentFile.getLastAccessDate().getTime() + "|";
}
this.logger.info(Preferences.KEY_RECENT_FILE_LIST + " is changed to "
+ recentFileListRepresentation);
this.properties.setProperty(Preferences.KEY_RECENT_FILE_LIST,
recentFileListRepresentation);
for (PreferencesListener listener : this.listeners) {
this.logger.info("Notifie listener : " + listener.toString());
listener.onPreferenceChange(Preferences.KEY_RECENT_FILE_LIST,
this.getRecentFileSet());
}
}
public BooleanProperty alwaysOnTopProperty() {
return alwaysOnTop;
}
public boolean getAlwaysOnTop() {
return alwaysOnTop.getValue();
}
/**
* Get the last path used value
*
* @return the last path used value
*/
public String getLastPathUsed() {
return this.lastPathUsed;
}
/**
* Set the new last path used value
*
* @param newLastPathUsed
* the new value
*/
public void setLastPathUsed(String newLastPathUsed) {
this.logger.info(Preferences.KEY_LAST_PATH_USED + " is changed from "
+ this.lastPathUsed + " to " + newLastPathUsed);
this.lastPathUsed = newLastPathUsed;
this.properties.setProperty(Preferences.KEY_LAST_PATH_USED,
this.lastPathUsed);
for (PreferencesListener listener : this.listeners) {
this.logger.info("Notifie listener : " + listener.toString());
listener.onPreferenceChange(Preferences.KEY_LAST_PATH_USED,
Boolean.valueOf(newLastPathUsed));
}
}
/**
* Add a listener to the list
*
* @param listener
* the listener to add
*/
public void addListener(PreferencesListener listener) {
this.listeners.add(listener);
this.logger.info("Ajout d'un listener de pr�f�rences : "
+ listener.getClass().getSimpleName()
+ ". Nombre de listeners : " + this.listeners.size());
}
/**
* Save the preferences
*/
public void save() {
this.logger.info("Save preferences");
try {
this.properties.storeToXML(
new FileOutputStream(this.propertieFile), "", "UTF-8");
} catch (IOException e) {
this.logger.error("Preferences cannot be saved", e);
}
}
}