/*
* Copyright (c) 2007-2009, 2011, 2012 Eike Stepper (Berlin, Germany) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eike Stepper - initial API and implementation
*/
package org.eclipse.net4j.internal.util.om.pref;
import org.eclipse.net4j.internal.util.bundle.AbstractBundle;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.event.Notifier;
import org.eclipse.net4j.util.io.IORunnable;
import org.eclipse.net4j.util.io.IORuntimeException;
import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.net4j.util.om.pref.OMPreference;
import org.eclipse.net4j.util.om.pref.OMPreferences;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* @author Eike Stepper
*/
public class Preferences extends Notifier implements OMPreferences
{
private AbstractBundle bundle;
private Map<String, Preference<?>> prefs = new HashMap<String, Preference<?>>();
private boolean loaded;
private boolean dirty;
public Preferences(AbstractBundle bundle)
{
this.bundle = bundle;
}
public AbstractBundle getBundle()
{
return bundle;
}
public synchronized void load()
{
if (!loaded)
{
loaded = true;
final Properties properties = new Properties();
File file = getFile();
if (file.exists())
{
IOUtil.safeInput(file, new IORunnable<FileInputStream>()
{
public void run(FileInputStream io) throws IOException
{
properties.load(io);
}
});
}
for (Preference<?> preference : prefs.values())
{
String name = preference.getName();
String value = properties.getProperty(name);
preference.init(value);
}
}
}
public synchronized void save()
{
if (dirty)
{
final Properties properties = new Properties();
for (Preference<?> preference : prefs.values())
{
if (preference.isSet())
{
String name = preference.getName();
String value = preference.getString();
if (value != null)
{
properties.put(name, value);
}
}
}
File file = getFile();
if (properties.isEmpty())
{
if (file.exists())
{
file.delete();
}
}
else
{
IOUtil.safeOutput(file, new IORunnable<FileOutputStream>()
{
public void run(FileOutputStream io) throws IOException
{
properties.store(io, "Preferences of " + bundle.getBundleID()); //$NON-NLS-1$
}
});
}
dirty = false;
}
}
public boolean isDirty()
{
return dirty;
}
public OMPreference<Boolean> init(String name, boolean defaultValue)
{
return init(new BooleanPreference(this, name, defaultValue));
}
public OMPreference<Integer> init(String name, int defaultValue)
{
return init(new IntegerPreference(this, name, defaultValue));
}
public OMPreference<Long> init(String name, long defaultValue)
{
return init(new LongPreference(this, name, defaultValue));
}
public OMPreference<Float> init(String name, float defaultValue)
{
return init(new FloatPreference(this, name, defaultValue));
}
public OMPreference<Double> init(String name, double defaultValue)
{
return init(new DoublePreference(this, name, defaultValue));
}
public OMPreference<String> init(String name, String defaultValue)
{
return init(new StringPreference(this, name, defaultValue));
}
public OMPreference<String[]> init(String name, String[] defaultValue)
{
return init(new ArrayPreference(this, name, defaultValue));
}
public OMPreference<byte[]> init(String name, byte[] defaultValue)
{
return init(new BytesPreference(this, name, defaultValue));
}
public OMPreference<Boolean> initBoolean(String name)
{
return init(name, DEFAULT_BOOLEAN);
}
public OMPreference<Integer> initInteger(String name)
{
return init(name, DEFAULT_INTEGER);
}
public OMPreference<Long> initLong(String name)
{
return init(name, DEFAULT_LONG);
}
public OMPreference<Float> initFloat(String name)
{
return init(name, DEFAULT_FLOAT);
}
public OMPreference<Double> initDouble(String name)
{
return init(name, DEFAULT_DOUBLE);
}
public OMPreference<String> initString(String name)
{
return init(name, DEFAULT_STRING);
}
public OMPreference<String[]> initArray(String name)
{
return init(name, DEFAULT_ARRAY);
}
public OMPreference<byte[]> initBytes(String name)
{
return init(name, DEFAULT_BYTES);
}
public boolean contains(String name)
{
return prefs.containsKey(name);
}
public OMPreference<?> get(String name)
{
return prefs.get(name);
}
@SuppressWarnings("unchecked")
public OMPreference<Boolean> getBoolean(String name)
{
return (OMPreference<Boolean>)get(name);
}
@SuppressWarnings("unchecked")
public OMPreference<Integer> getInteger(String name)
{
return (OMPreference<Integer>)get(name);
}
@SuppressWarnings("unchecked")
public OMPreference<Long> getLong(String name)
{
return (OMPreference<Long>)get(name);
}
@SuppressWarnings("unchecked")
public OMPreference<Float> getFloat(String name)
{
return (OMPreference<Float>)get(name);
}
@SuppressWarnings("unchecked")
public OMPreference<Double> getDouble(String name)
{
return (OMPreference<Double>)get(name);
}
@SuppressWarnings("unchecked")
public OMPreference<String> getString(String name)
{
return (OMPreference<String>)get(name);
}
@SuppressWarnings("unchecked")
public OMPreference<String[]> getArray(String name)
{
return (OMPreference<String[]>)get(name);
}
@SuppressWarnings("unchecked")
public OMPreference<byte[]> getBytes(String name)
{
return (OMPreference<byte[]>)get(name);
}
public <T> void fireChangeEvent(Preference<T> preference, T oldValue, T newValue)
{
dirty = true;
IListener[] listeners = getListeners();
if (listeners != null)
{
fireEvent(new PreferencesChangeEvent<T>(preference, oldValue, newValue), listeners);
}
}
private <T> OMPreference<T> init(Preference<T> preference)
{
String name = preference.getName();
if (prefs.containsKey(name))
{
throw new IllegalArgumentException("Duplicate name: " + name); //$NON-NLS-1$
}
prefs.put(name, preference);
return preference;
}
private File getFile()
{
File file = new File(bundle.getStateLocation(), ".prefs"); //$NON-NLS-1$
if (file.exists() && !file.isFile())
{
throw new IORuntimeException("Not a file: " + file.getAbsolutePath()); //$NON-NLS-1$
}
return file;
}
}