/** * (C) Copyright 2013 Jabylon (http://www.jabylon.org) 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 */ package org.jabylon.common.util; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.eclipse.core.runtime.preferences.InstanceScope; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; /** * @author Johannes Utzig (jutzig.dev@googlemail.com) * */ public class DelegatingPreferences implements Preferences, Serializable { private static final long serialVersionUID = -2100265681534715500L; private transient Preferences delegate; private String absolutePath; private boolean dirty; private List<DelegatingPreferences> children; private Map<String, Object> values; public DelegatingPreferences(Preferences delegate) { super(); this.delegate = delegate; absolutePath = delegate.absolutePath(); children = new ArrayList<DelegatingPreferences>(); values = new HashMap<String, Object>(); } public void put(String key, String value) { values.put(key, value); dirty = true; } public String get(String key, String def) { if(values.containsKey(key)) return String.valueOf(values.get(key)); return getDelegate().get(key, def); } public void remove(String key) { values.remove(key); dirty = true; } public void clear() throws BackingStoreException { getDelegate().clear(); dirty = true; } public void putInt(String key, int value) { getDelegate().putInt(key, value); dirty = true; } public int getInt(String key, int def) { if(values.containsKey(key)) return (Integer) values.get(key); return getDelegate().getInt(key, def); } public void putLong(String key, long value) { getDelegate().putLong(key, value); dirty = true; } public long getLong(String key, long def) { if(values.containsKey(key)) return (Long) values.get(key); return getDelegate().getLong(key, def); } public void putBoolean(String key, boolean value) { getDelegate().putBoolean(key, value); dirty = true; } public boolean getBoolean(String key, boolean def) { if(values.containsKey(key)) return (Boolean) values.get(key); return getDelegate().getBoolean(key, def); } public void putFloat(String key, float value) { getDelegate().putFloat(key, value); dirty = true; } public float getFloat(String key, float def) { if(values.containsKey(key)) return (Float) values.get(key); return getDelegate().getFloat(key, def); } public void putDouble(String key, double value) { getDelegate().putDouble(key, value); dirty = true; } public double getDouble(String key, double def) { if(values.containsKey(key)) return (Double) values.get(key); return getDelegate().getDouble(key, def); } public void putByteArray(String key, byte[] value) { getDelegate().putByteArray(key, value); dirty = true; } public byte[] getByteArray(String key, byte[] def) { if(values.containsKey(key)) return (byte[]) values.get(key); return getDelegate().getByteArray(key, def); } public String[] keys() throws BackingStoreException { Set<String> keys = new HashSet<String>(values.keySet()); keys.addAll(Arrays.asList(getDelegate().keys())); return keys.toArray(new String[keys.size()]); } public String[] childrenNames() throws BackingStoreException { return getDelegate().childrenNames(); } public Preferences parent() { return getDelegate().parent(); } public Preferences node(String pathName) { try { if (!nodeExists(pathName)) dirty = true; } catch (BackingStoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } DelegatingPreferences child = new DelegatingPreferences(getDelegate().node(pathName)); children.add(child); return child; } public boolean nodeExists(String pathName) throws BackingStoreException { return getDelegate().nodeExists(pathName); } public void removeNode() throws BackingStoreException { dirty = true; getDelegate().removeNode(); } public String name() { return getDelegate().name(); } public String absolutePath() { return getDelegate().absolutePath(); } public void flush() throws BackingStoreException { for (Entry<String, Object> entry : values.entrySet()) { setValue(entry.getKey(), entry.getValue()); } for (DelegatingPreferences child : children) { child.flush(); } getDelegate().flush(); dirty = false; } public void sync() throws BackingStoreException { getDelegate().sync(); } public boolean isDirty() { if (dirty) return true; for (DelegatingPreferences child : children) { if (child.isDirty()) return true; } return false; } protected void setValue(String key, Object value) { if (value instanceof String) getDelegate().put(key, (String) value); else if (value instanceof Boolean) getDelegate().putBoolean(key, (Boolean) value); else if (value instanceof byte[]) getDelegate().putByteArray(key, (byte[]) value); else if (value instanceof Double) getDelegate().putDouble(key, (Double) value); else if (value instanceof Float) getDelegate().putFloat(key, (Float) value); else if (value instanceof Integer) getDelegate().putInt(key, (Integer) value); else if (value instanceof Long) getDelegate().putLong(key, (Long) value); else if(value==null) getDelegate().remove(key); else throw new IllegalArgumentException("Object type "+value+" not supported"); } private Preferences getDelegate() { if(delegate==null) { delegate = InstanceScope.INSTANCE.getNode(absolutePath); } return delegate; } }