blob: 689e9e64533d9b29c4beaaef4f39d6a252805fb9 [file] [log] [blame]
/*
* Copyright 1999,2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j.chainsaw.prefs;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.EventListener;
import java.util.Properties;
import javax.swing.event.EventListenerList;
/**
* SettingManager allows components to register interest in Saving/Loading
* of general application preferences/settings.
*
* @author Paul Smith <psmith@apache.org>
* @author Scott Deboy <sdeboy@apache.org>
*
*/
public final class SettingsManager {
private static final SettingsManager instance = new SettingsManager();
private static final String GLOBAL_SETTINGS_FILE_NAME = "chainsaw.settings.properties";
private static final String HEADER = "Chainsaws Settings Files";
private EventListenerList listenerList = new EventListenerList();
private Properties defaultProperties = new Properties();
/**
* Initialises the SettingsManager by loading the default Properties from
* a resource
*
*/
private SettingsManager() {
// load the default properties as a Resource
InputStream is = null;
try {
is = this.getClass().getClassLoader()
.getResource("org/apache/log4j/chainsaw/prefs/default.properties")
.openStream();
defaultProperties.load(is);
// defaultProperties.list(System.out);
is.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (Exception e) {
}
}
}
}
/**
* Returns the singleton instance of the SettingsManager
* @return settings manager
*/
public static final SettingsManager getInstance() {
return instance;
}
/**
* Registers the listener with the manager
* @param listener
*/
public void addSettingsListener(SettingsListener listener) {
listenerList.add(SettingsListener.class, listener);
}
/**
* Requests that the settings be loaded, all listeners will be notified of
* this call, and configure themselves according to the values found in the
* loaded settings
*
*/
public void loadSettings() {
/*
* Ok, note we ensure we have a .chainsaw directory in the users
* home folder, and create a chainsaw.settings.properties file..
*/
File settingsDir = getSettingsDirectory();
if (!settingsDir.exists()) {
settingsDir.mkdir();
}
loadGlobalSettings();
loadProfileableSettings();
}
/**
*
*/
private void loadProfileableSettings() {
EventListener[] listeners = listenerList.getListeners(SettingsListener.class);
for (int i = 0; i < listeners.length; i++) {
SettingsListener settingsListener = (SettingsListener) listeners[i];
if (settingsListener instanceof Profileable) {
Profileable p = (Profileable) settingsListener;
loadProfileble(p);
}
}
}
private void loadProfileble(Profileable p) {
LoadSettingsEvent event = createProfilebleEvent(p);
p.loadSettings(event);
}
private LoadSettingsEvent createProfilebleEvent(Profileable p) {
Properties loadedProperties = new Properties();
loadedProperties.putAll(getDefaultSettings());
loadedProperties.putAll(loadProperties(p));
LoadSettingsEvent event = new LoadSettingsEvent(this, loadedProperties);
return event;
}
/**
* @param p
* @return
*/
private Properties loadProperties(Profileable p) {
Properties properties = new Properties(defaultProperties);
InputStream is = null;
File f = new File(getSettingsDirectory(),
URLEncoder.encode(p.getNamespace() + ".properties"));
if (!f.exists()) {
f = new File(getSettingsDirectory(),
p.getNamespace() + ".properties");
}
if (f.exists()) {
try {
is = new BufferedInputStream(new FileInputStream(f));
Properties toLoad = new Properties();
toLoad.load(is);
properties.putAll(toLoad);
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
return properties;
}
private void loadGlobalSettings() {
EventListener[] listeners = listenerList.getListeners(SettingsListener.class);
LoadSettingsEvent event = null;
for (int i = 0; i < listeners.length; i++) {
SettingsListener settingsListener = (SettingsListener) listeners[i];
if (event == null) {
Properties loadedProperties = loadGlobalProperties();
// loadedProperties.list(System.out);
event = new LoadSettingsEvent(this, loadedProperties);
}
settingsListener.loadSettings(event);
}
}
/**
* Creates a SaveSettingsEvent and calls all the SettingsListeners
* to populate the properties with configuration information
*
*/
public void saveSettings() {
/*
* Ok, note we ensure we have a .chainsaw directory in the users
* home folder, and create a chainsaw.settings.properties file..
*/
File settingsDir = getSettingsDirectory();
if (!settingsDir.exists()) {
settingsDir.mkdir();
}
saveGlobalSettings(settingsDir);
saveProfileableSetting(settingsDir);
}
/**
* Looks up all the Profileable's that have been registered
* and creates a new event for each of them, and ensures that they
* are saved within a separate external store
* @param settingsDir
*/
private void saveProfileableSetting(File settingsDir) {
EventListener[] listeners = listenerList.getListeners(SettingsListener.class);
SaveSettingsEvent event = null;
for (int i = 0; i < listeners.length; i++) {
SettingsListener settingsListener = (SettingsListener) listeners[i];
if (settingsListener instanceof Profileable) {
Profileable profileable = (Profileable) settingsListener;
event = new SaveSettingsEvent(this, getSettingsDirectory());
profileable.saveSettings(event);
OutputStream os = null;
try {
os = new BufferedOutputStream(new FileOutputStream(
new File(settingsDir,
URLEncoder.encode(profileable.getNamespace()) + ".properties")));
event.getProperties().store(os, HEADER);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
}
}
private void saveGlobalSettings(File settingsDir) {
EventListener[] listeners = listenerList.getListeners(SettingsListener.class);
SaveSettingsEvent event = null;
for (int i = 0; i < listeners.length; i++) {
SettingsListener settingsListener = (SettingsListener) listeners[i];
if (!(settingsListener instanceof Profileable)) {
if (event == null) {
event = new SaveSettingsEvent(this, getSettingsDirectory());
}
settingsListener.saveSettings(event);
}
}
OutputStream os = null;
try {
os = new BufferedOutputStream(new FileOutputStream(
new File(settingsDir, GLOBAL_SETTINGS_FILE_NAME)));
event.getProperties().store(os, HEADER);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
public File getSettingsDirectory() {
return new File(System.getProperty("user.home"), ".chainsaw");
}
public void configure(SettingsListener listener) {
if (listener instanceof Profileable) {
loadProfileble((Profileable) listener);
} else {
Properties loadedProperties = loadGlobalProperties();
LoadSettingsEvent event = new LoadSettingsEvent(this,
loadedProperties);
listener.loadSettings(event);
}
}
/**
* Returns the current Properties settings for this user
* by merging the default Properties with the ones we find in their directory.
*
* @return
*/
private Properties loadGlobalProperties() {
Properties properties = new Properties(defaultProperties);
InputStream is = null;
File f = new File(getSettingsDirectory(), GLOBAL_SETTINGS_FILE_NAME);
if (f.exists()) {
try {
is = new BufferedInputStream(new FileInputStream(f));
Properties toLoad = new Properties();
toLoad.load(is);
properties.putAll(toLoad);
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
return properties;
}
/**
* Returns the loaded default settings, which can be used by
* other classes within this package.
* @return Properties defaults
*/
public Properties getDefaultSettings() {
return defaultProperties;
}
}