/*
GanttProject is an opensource project management tool. License: GPL3
Copyright (C) 2011 Dmitry Barashev
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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package biz.ganttproject.core.option;
import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.SortedSet;
public abstract class GPAbstractOption<T> implements GPOption<T> {
public abstract static class I18N {
private static I18N ourInstance;
protected static void setI18N(I18N i18n) {
ourInstance = i18n;
}
protected abstract String i18n(String key);
}
private final String myID;
//private final List<ChangeValueListener> myListeners = new ArrayList<ChangeValueListener>();
private final Listeners myListeners = new Listeners();
private final PropertyChangeSupport myPropertyChangeSupport = new PropertyChangeSupport(this);
private boolean isWritable = true;
private T myValue;
private T myInitialValue;
private boolean isScreened;
private boolean myHasUi = true;
protected GPAbstractOption(String id) {
this(id, null);
}
protected GPAbstractOption(String id, T initialValue) {
myID = id;
myInitialValue = initialValue;
myValue = initialValue;
}
@Override
public String getID() {
return myID;
}
@Override
public T getValue() {
return myValue;
}
@Override
public void setValue(T value) {
resetValue(value, false, null);
}
public void setValue(T value, Object clientId) {
resetValue(value, false, clientId);
}
protected T getInitialValue() {
return myInitialValue;
}
protected void resetValue(T value, boolean resetInitial) {
resetValue(value, resetInitial, null);
}
protected void resetValue(T value, boolean resetInitial, Object triggerId) {
if (resetInitial) {
myInitialValue = value;
}
ChangeValueEvent event = new ChangeValueEvent(getID(), myValue, value, triggerId);
myValue = value;
fireChangeValueEvent(event);
}
@Override
public boolean isChanged() {
if (myInitialValue == null) {
return myValue != null;
}
return !myInitialValue.equals(myValue);
}
@Override
public void lock() {
}
@Override
public void commit() {
}
@Override
public void rollback() {
}
@Override
public Runnable addChangeValueListener(final ChangeValueListener listener) {
return myListeners.add(listener, Listeners.DEFAULT_PRIORITY);
}
@Override
public Runnable addChangeValueListener(final ChangeValueListener listener, int priority) {
return myListeners.add(listener, priority);
}
protected void fireChangeValueEvent(ChangeValueEvent event) {
myListeners.fire(event);
}
@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {
myPropertyChangeSupport.addPropertyChangeListener(listener);
}
@Override
public void removePropertyChangeListener(PropertyChangeListener listener) {
myPropertyChangeSupport.removePropertyChangeListener(listener);
}
@Override
public boolean isWritable() {
return isWritable;
}
public void setWritable(boolean isWritable) {
this.isWritable = isWritable;
myPropertyChangeSupport.firePropertyChange("isWritable", Boolean.valueOf(!isWritable), Boolean.valueOf(isWritable));
}
@Override
public boolean isScreened() {
return isScreened;
}
@Override
public void setScreened(boolean value) {
isScreened = value;
}
public boolean hasUi() {
return myHasUi;
}
public void setHasUi(boolean hasUi) {
myHasUi = hasUi;
}
protected PropertyChangeSupport getPropertyChangeSupport() {
return myPropertyChangeSupport;
}
protected static String i18n(String key) {
return I18N.ourInstance.i18n(key);
}
static class Listeners {
public static final int DEFAULT_PRIORITY = 0;
class Entry implements Comparable {
final int priority;
final int ordinal;
final ChangeValueListener listener;
Entry(ChangeValueListener listener, int ordinal, int priority) {
this.listener = Preconditions.checkNotNull(listener);
this.ordinal = ordinal;
this.priority = priority;
}
@Override
public int compareTo(Object o) {
Preconditions.checkArgument(o instanceof Entry);
Entry that = (Entry) o;
int result = this.priority - that.priority;
return result != 0 ? result : this.ordinal - that.ordinal;
}
}
private SortedSet<Entry> myListeners = Sets.newTreeSet();
Runnable add(ChangeValueListener listener, int priority) {
final Entry e = new Entry(listener, myListeners.size(), priority);
myListeners.add(e);
return new Runnable() {
@Override
public void run() {
myListeners.remove(e);
}
};
}
void fire(ChangeValueEvent event) {
for (Entry e : myListeners) {
e.listener.changeValue(event);
}
}
}
}