/*
* Copyright 2015 Igor Maznitsa.
*
* 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 com.igormaznitsa.ideamindmap.facet;
import com.intellij.util.Base64;
import org.apache.commons.lang.StringEscapeUtils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.prefs.BackingStoreException;
import java.util.prefs.NodeChangeListener;
import java.util.prefs.PreferenceChangeEvent;
import java.util.prefs.PreferenceChangeListener;
import java.util.prefs.Preferences;
public class InMemoryPreferenceNode extends Preferences {
private final List<PreferenceChangeListener> preferenceChangeListeners = new ArrayList<PreferenceChangeListener>();
private final List<NodeChangeListener> nodeChangeListeners = new ArrayList<NodeChangeListener>();
private final Map<String,String> storage = new HashMap<String,String>();
private void firePreferenceListeners(final String key, final String newValue){
final PreferenceChangeEvent event = new PreferenceChangeEvent(this,key,newValue);
for(final PreferenceChangeListener l : this.preferenceChangeListeners){
l.preferenceChange(event);
}
}
@Override public void put(@Nonnull final String key, @Nonnull final String value) {
this.storage.put(key,value);
firePreferenceListeners(key,value);
}
@Override public String get(@Nonnull final String key, @Nullable String def) {
return this.storage.get(key);
}
@Override public void remove(@Nonnull final String key) {
if (this.storage.remove(key)!=null){
firePreferenceListeners(key,null);
}
}
@Override public void clear() throws BackingStoreException {
final Map<String,String> copy = new HashMap<String,String>(this.storage);
this.storage.clear();
for(final String k : copy.keySet()){
firePreferenceListeners(k,null);
}
}
@Override public void putInt(@Nonnull final String key, final int value) {
this.put(key,Integer.toString(value));
}
@Override public int getInt(@Nonnull String key, final int def) {
final String value = this.get(key,Integer.toString(def));
try{
return Integer.parseInt(value);
}catch(NumberFormatException ex){
return def;
}
}
@Override public void putLong(@Nonnull final String key, final long value) {
this.put(key,Long.toString(value));
}
@Override public long getLong(String key, long def) {
final String value = this.get(key,Long.toString(def));
try{
return Long.parseLong(value);
}catch(NumberFormatException ex){
return def;
}
}
@Override public void putBoolean(String key, boolean value) {
this.put(key,Boolean.toString(value));
}
@Override public boolean getBoolean(String key, boolean def) {
final String value = this.get(key,null);
return value == null ? def : Boolean.parseBoolean(value);
}
@Override public void putFloat(String key, float value) {
this.put(key,Float.toString(value));
}
@Override public float getFloat(String key, float def) {
final String value = get(key,Float.toString(def));
try{
return Float.parseFloat(value);
}catch(NumberFormatException ex){
return def;
}
}
@Override public void putDouble(String key, double value) {
this.put(key,Double.toString(value));
}
@Override public double getDouble(String key, double def) {
final String value = get(key,Double.toString(def));
try{
return Double.parseDouble(value);
}catch(NumberFormatException ex){
return def;
}
}
@Override public void putByteArray(String key, byte[] value) {
this.put(key, Base64.encode(value));
}
@Override public byte[] getByteArray(String key, byte[] def) {
final String value = this.get(key,null);
try{
return Base64.decode(value);
}catch(Exception ex){
return def;
}
}
@Override public String[] keys() throws BackingStoreException {
return this.storage.keySet().toArray(new String[this.storage.size()]);
}
@Override public String[] childrenNames() throws BackingStoreException {
return new String[0];
}
@Override public Preferences parent() {
return null;
}
@Override public Preferences node(final String pathName) {
return null;
}
@Override public boolean nodeExists(final String pathName) throws BackingStoreException {
return false;
}
@Override public void removeNode() throws BackingStoreException {
}
@Override public String name() {
return "..";
}
@Override public String absolutePath() {
return "..";
}
@Override public boolean isUserNode() {
return false;
}
@Override public String toString() {
return InMemoryPreferenceNode.class.getName()+"["+this.storage.size()+']';
}
@Override public void flush() throws BackingStoreException {
}
@Override public void sync() throws BackingStoreException {
}
@Override public void addPreferenceChangeListener(PreferenceChangeListener pcl) {
this.preferenceChangeListeners.add(pcl);
}
@Override public void removePreferenceChangeListener(PreferenceChangeListener pcl) {
this.preferenceChangeListeners.remove(pcl);
}
@Override public void addNodeChangeListener(NodeChangeListener ncl) {
this.nodeChangeListeners.add(ncl);
}
@Override public void removeNodeChangeListener(NodeChangeListener ncl) {
this.nodeChangeListeners.remove(ncl);
}
@Override public void exportNode(OutputStream os) throws IOException, BackingStoreException {
final StringBuilder builder = new StringBuilder();
for(final Map.Entry<String, String> entry : this.storage.entrySet()){
builder.append(StringEscapeUtils.escapeCsv(entry.getKey())).append(',').append(StringEscapeUtils.escapeCsv(entry.getValue())).append('\n');
}
os.write(builder.toString().getBytes("UTF-8"));
}
@Override public void exportSubtree(OutputStream os) throws IOException, BackingStoreException {
}
}