Skip to main content

This CGIT instance is deprecated, and repositories have been moved to Gitlab or Github. See the repository descriptions for specific locations.

summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.utility/src/org')
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BidiStringConverter.java127
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/StringConverter.java68
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencePropertyValueModel.java334
-rw-r--r--jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java212
4 files changed, 741 insertions, 0 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BidiStringConverter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BidiStringConverter.java
new file mode 100644
index 0000000000..fcd8f4a311
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/BidiStringConverter.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. 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:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal;
+
+/**
+ * Used by various "pluggable" classes to transform objects
+ * into strings and vice versa.
+ *
+ * If anyone can come up with a better class name
+ * and/or method name, I would love to hear it. ~bjv
+ */
+public interface BidiStringConverter<T> extends StringConverter<T> {
+
+ /**
+ * Convert the specified string into an object.
+ * The semantics of "convert to object" is determined by the
+ * contract between the client and the server.
+ * Typically, if the string is null, null is returned.
+ */
+ T convertToObject(String s);
+
+
+ final class Default<S> implements BidiStringConverter<S> {
+ @SuppressWarnings("unchecked")
+ public static final BidiStringConverter INSTANCE = new Default();
+ @SuppressWarnings("unchecked")
+ public static <R> BidiStringConverter<R> instance() {
+ return INSTANCE;
+ }
+ // ensure single instance
+ private Default() {
+ super();
+ }
+ // simply return the object's #toString() result
+ public String convertToString(S o) {
+ return (o == null) ? null : o.toString();
+ }
+ // simply return the string
+ @SuppressWarnings("unchecked")
+ public S convertToObject(String s) {
+ return (S) s;
+ }
+ @Override
+ public String toString() {
+ return "BidiStringConverter.Default";
+ }
+ }
+
+ final class Disabled<S> implements BidiStringConverter<S> {
+ @SuppressWarnings("unchecked")
+ public static final BidiStringConverter INSTANCE = new Disabled();
+ @SuppressWarnings("unchecked")
+ public static <R> BidiStringConverter<R> instance() {
+ return INSTANCE;
+ }
+ // ensure single instance
+ private Disabled() {
+ super();
+ }
+ // throw an exception
+ public String convertToString(S o) {
+ throw new UnsupportedOperationException();
+ }
+ // throw an exception
+ public S convertToObject(String s) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public String toString() {
+ return "BidiStringConverter.Disabled";
+ }
+ }
+
+ final class BooleanConverter implements BidiStringConverter<Boolean> {
+ public static final BidiStringConverter<Boolean> INSTANCE = new BooleanConverter();
+ public static BidiStringConverter<Boolean> instance() {
+ return INSTANCE;
+ }
+ // ensure single instance
+ private BooleanConverter() {
+ super();
+ }
+ /** Return "true" if the Boolean is true, otherwise return "false". */
+ public String convertToString(Boolean b) {
+ return (b == null) ? null : b.toString();
+ }
+ /** Return Boolean.TRUE if the string is "true" (case-insensitive), otherwise return Boolean.FALSE. */
+ public Boolean convertToObject(String s) {
+ return (s == null) ? null : Boolean.valueOf(s);
+ }
+ @Override
+ public String toString() {
+ return "BidiStringConverter.BooleanConverter";
+ }
+ }
+
+ final class IntegerConverter implements BidiStringConverter<Integer> {
+ public static final BidiStringConverter<Integer> INSTANCE = new IntegerConverter();
+ public static BidiStringConverter<Integer> instance() {
+ return INSTANCE;
+ }
+ // ensure single instance
+ private IntegerConverter() {
+ super();
+ }
+ /** Integer's #toString() works well. */
+ public String convertToString(Integer integer) {
+ return (integer == null) ? null : integer.toString();
+ }
+ /** Convert the string to an Integer, if possible. */
+ public Integer convertToObject(String s) {
+ return (s == null) ? null : Integer.valueOf(s);
+ }
+ @Override
+ public String toString() {
+ return "BidiStringConverter.IntegerConverter";
+ }
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/StringConverter.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/StringConverter.java
new file mode 100644
index 0000000000..556b530862
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/StringConverter.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. 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:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal;
+
+/**
+ * Used by various "pluggable" classes to transform objects
+ * into strings.
+ */
+public interface StringConverter<T> {
+
+ /**
+ * Convert the specified object into a string.
+ * The semantics of "convert" is determined by the
+ * contract between the client and the server.
+ */
+ String convertToString(T o);
+
+
+ final class Default<S> implements StringConverter<S> {
+ @SuppressWarnings("unchecked")
+ public static final StringConverter INSTANCE = new Default();
+ @SuppressWarnings("unchecked")
+ public static <R> StringConverter<R> instance() {
+ return INSTANCE;
+ }
+ // ensure single instance
+ private Default() {
+ super();
+ }
+ // simply return the object's #toString() result
+ public String convertToString(S o) {
+ return (o == null) ? null : o.toString();
+ }
+ @Override
+ public String toString() {
+ return "StringConverter.Default";
+ }
+ }
+
+ final class Disabled<S> implements StringConverter<S> {
+ @SuppressWarnings("unchecked")
+ public static final StringConverter INSTANCE = new Disabled();
+ @SuppressWarnings("unchecked")
+ public static <R> StringConverter<R> instance() {
+ return INSTANCE;
+ }
+ // ensure single instance
+ private Disabled() {
+ super();
+ }
+ // throw an exception
+ public String convertToString(S o) {
+ throw new UnsupportedOperationException();
+ }
+ @Override
+ public String toString() {
+ return "StringConverter.Disabled";
+ }
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencePropertyValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencePropertyValueModel.java
new file mode 100644
index 0000000000..66025000ea
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencePropertyValueModel.java
@@ -0,0 +1,334 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. 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:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.value.prefs;
+
+import java.util.prefs.PreferenceChangeEvent;
+import java.util.prefs.PreferenceChangeListener;
+import java.util.prefs.Preferences;
+
+import org.eclipse.jpt.utility.internal.BidiStringConverter;
+import org.eclipse.jpt.utility.internal.model.value.AspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.PropertyValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ValueModel;
+
+/**
+ * This adapter wraps a Preference and converts it into a PropertyValueModel.
+ * It listens for the appropriate "preference" changes and converts them into
+ * VALUE property changes. It also allows the specification of a default value
+ * for the Preference, which, by default, is null (and is probably *not* a very
+ * good default).
+ *
+ * You can configure whether the preference's value is returned,
+ * unchanged, as a string or as some other object (e.g. an Integer) by
+ * setting the adapter's converter. Internally, the preference's value
+ * is stored as the converted object; and the conversions take place
+ * when reading or writing from the preferences node or retrieving the
+ * value from an event fired by the preferences node.
+ *
+ * This adapter is a bit different from most other adapters because the
+ * change events fired off by a Preferences node are asynchronous from
+ * the change itself. (AbstractPreferences uses an event dispatch daemon.)
+ * As a result, a client can set our value with #setValue(Object) and we
+ * will return from that method before we ever receive notification from
+ * the Preferences node that *it* has changed. This means we cannot
+ * rely on that event to keep our internally cached value in synch.
+ */
+public class PreferencePropertyValueModel
+ extends AspectAdapter
+ implements PropertyValueModel
+{
+ /** The key to the preference we use for the value. */
+ protected String key;
+
+ /**
+ * Cache the current (object) value of the preference so we
+ * can pass an "old value" when we fire a property change event.
+ */
+ protected Object value;
+
+ /**
+ * The default (object) value returned if there is no value
+ * associated with the preference.
+ */
+ protected Object defaultValue;
+
+ /**
+ * This converter is used to convert the preference's
+ * string value to and from an object.
+ */
+ protected BidiStringConverter converter;
+
+ /** A listener that listens to the appropriate preference. */
+ protected PreferenceChangeListener preferenceChangeListener;
+
+
+ // ********** constructors **********
+
+ /**
+ * Construct an adapter for the specified preference.
+ * The default value of the preference will be null.
+ */
+ public PreferencePropertyValueModel(Preferences preferences, String key) {
+ this(preferences, key, null);
+ }
+
+ /**
+ * Construct an adapter for the specified preference with
+ * the specified default value for the preference.
+ */
+ public PreferencePropertyValueModel(Preferences preferences, String key, Object defaultValue) {
+ super(preferences);
+ this.key = key;
+ this.defaultValue = defaultValue;
+ }
+
+ /**
+ * Construct an adapter for the specified preference with
+ * the specified default value for the preference.
+ */
+ public PreferencePropertyValueModel(Preferences preferences, String key, boolean defaultValue) {
+ this(preferences, key, defaultValue ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ /**
+ * Construct an adapter for the specified preference with
+ * the specified default value for the preference.
+ */
+ public PreferencePropertyValueModel(Preferences preferences, String key, int defaultValue) {
+ this(preferences, key, new Integer(defaultValue));
+ }
+
+ /**
+ * Construct an adapter for the specified preference.
+ * The default value of the preference will be null.
+ */
+ public PreferencePropertyValueModel(ValueModel preferencesHolder, String key) {
+ this(preferencesHolder, key, null);
+ }
+
+ /**
+ * Construct an adapter for the specified preference with
+ * the specified default value for the preference.
+ */
+ public PreferencePropertyValueModel(ValueModel preferencesHolder, String key, Object defaultValue) {
+ super(preferencesHolder);
+ this.key = key;
+ this.defaultValue = defaultValue;
+ }
+
+
+ // ********** initialization **********
+
+ @Override
+ protected void initialize() {
+ super.initialize();
+ // our value is null when we are not listening to the preference
+ this.value = null;
+ this.converter = BidiStringConverter.Default.instance();
+ this.preferenceChangeListener = this.buildPreferenceChangeListener();
+ }
+
+ /**
+ * A preference has changed, notify the listeners if necessary.
+ */
+ protected PreferenceChangeListener buildPreferenceChangeListener() {
+ // transform the preference change events into VALUE property change events
+ return new PreferenceChangeListener() {
+ public void preferenceChange(PreferenceChangeEvent e) {
+ PreferencePropertyValueModel.this.preferenceChanged(e.getKey(), e.getNewValue());
+ }
+ @Override
+ public String toString() {
+ return "preference change listener";
+ }
+ };
+ }
+
+
+ // ********** ValueModel implementation **********
+
+ /**
+ * Return the cached (converted) value.
+ */
+ public synchronized Object getValue() {
+ return this.value;
+ }
+
+
+ // ********** PropertyValueModel implementation **********
+
+ /**
+ * Set the cached value, then set the appropriate preference value.
+ */
+ public synchronized void setValue(Object value) {
+ if (this.hasNoListeners()) {
+ return; // no changes allowed when we have no listeners
+ }
+
+ Object old = this.value;
+ this.value = value;
+ this.fireAspectChange(old, value);
+
+ if ((this.subject != null) && this.shouldSetPreference(old, value)) {
+ this.setValueOnSubject(value);
+ }
+ }
+
+
+ // ********** AspectAdapter implementation **********
+
+ @Override
+ protected boolean hasListeners() {
+ return this.hasAnyPropertyChangeListeners(VALUE);
+ }
+
+ @Override
+ protected void fireAspectChange(Object oldValue, Object newValue) {
+ this.firePropertyChanged(VALUE, oldValue, newValue);
+ }
+
+ @Override
+ protected void engageNonNullSubject() {
+ ((Preferences) this.subject).addPreferenceChangeListener(this.preferenceChangeListener);
+ this.value = this.buildValue();
+ }
+
+ @Override
+ protected void disengageNonNullSubject() {
+ try {
+ ((Preferences) this.subject).removePreferenceChangeListener(this.preferenceChangeListener);
+ } catch (IllegalStateException ex) {
+ // for some odd reason, we are not allowed to remove a listener from a "dead"
+ // preferences node; so handle the exception that gets thrown here
+ if ( ! ex.getMessage().equals("Node has been removed.")) {
+ // if it is not the expected exception, re-throw it
+ throw ex;
+ }
+ }
+ this.value = null;
+ }
+
+
+ // ********** AbstractModel implementation **********
+
+ @Override
+ public void toString(StringBuilder sb) {
+ sb.append(this.key);
+ sb.append(" => ");
+ sb.append(this.value);
+ }
+
+
+ // ********** public API **********
+
+ /**
+ * Return the preference's key.
+ */
+ public String getKey() {
+ return this.key;
+ }
+
+ /**
+ * Return the converter used to convert the
+ * preference's value to and from a string.
+ * The default is to use the unconverted string.
+ */
+ public synchronized BidiStringConverter getConverter() {
+ return this.converter;
+ }
+
+ /**
+ * Set the converter used to convert the
+ * preference's value to and from a string.
+ * The default is to use the unconverted string.
+ */
+ public synchronized void setConverter(BidiStringConverter converter) {
+ this.converter = converter;
+ }
+
+
+ // ********** internal methods **********
+
+ /**
+ * Return the preference's value.
+ * At this point the subject may be null.
+ */
+ protected Object buildValue() {
+ if (this.subject == null) {
+ return null;
+ }
+ return this.getValueFromSubject();
+ }
+
+ /**
+ * Return the appropriate preference, converted to the appropriate object.
+ * At this point we can be sure that the subject is not null.
+ */
+ protected Object getValueFromSubject() {
+ return this.convertToObject(((Preferences) this.subject).get(this.key, this.convertToString(this.defaultValue)));
+ }
+
+ /**
+ * Set the appropriate preference after converting the value to a string.
+ * At this point we can be sure that the subject is not null.
+ */
+ protected void setValueOnSubject(Object value) {
+ ((Preferences) this.subject).put(this.key, this.convertToString(value));
+ }
+
+ /**
+ * Return whether the specified new value should be passed
+ * through to the preference. By default, only if the value has changed,
+ * will it be passed through to the preference. This also has the
+ * effect of not creating new preferences in the "backing store"
+ * if the new value is the same as the default value.
+ *
+ * Subclasses can override this method to return true if they
+ * would like to ALWAYS pass through the new value to the preference.
+ */
+ protected boolean shouldSetPreference(Object oldValue, Object newValue) {
+ return this.attributeValueHasChanged(oldValue, newValue);
+ }
+
+ /**
+ * Convert the specified object to a string that can be stored as
+ * the value of the preference.
+ */
+ protected String convertToString(Object o) {
+ return this.converter.convertToString(o);
+ }
+
+ /**
+ * Convert the specified preference value string to an
+ * appropriately-typed object to be returned to the client.
+ */
+ protected Object convertToObject(String s) {
+ return this.converter.convertToObject(s);
+ }
+
+ protected void preferenceChanged(String prefKey, String newValue) {
+ if (prefKey.equals(this.key)) {
+ this.preferenceChanged();
+ }
+ }
+
+ /**
+ * The underlying preference changed; either because we changed it
+ * in #setValueOnSubject(Object) or a third-party changed it.
+ * If this is called because of our own change, the event will be
+ * swallowed because the old and new values are the same.
+ */
+ protected synchronized void preferenceChanged() {
+ Object old = this.value;
+ this.value = this.buildValue();
+ this.fireAspectChange(old, this.value);
+ }
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java
new file mode 100644
index 0000000000..4fc5557086
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/model/value/prefs/PreferencesCollectionValueModel.java
@@ -0,0 +1,212 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Oracle. 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:
+ * Oracle - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.jpt.utility.internal.model.value.prefs;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.PreferenceChangeEvent;
+import java.util.prefs.PreferenceChangeListener;
+import java.util.prefs.Preferences;
+
+import org.eclipse.jpt.utility.internal.iterators.ArrayIterator;
+import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;
+import org.eclipse.jpt.utility.internal.model.value.AspectAdapter;
+import org.eclipse.jpt.utility.internal.model.value.CollectionValueModel;
+import org.eclipse.jpt.utility.internal.model.value.ValueModel;
+
+/**
+ * This adapter wraps a Preferences node and converts its preferences into a
+ * CollectionValueModel of PreferencePropertyValueModels. It listens for
+ * "preference" changes and converts them into VALUE collection changes.
+ */
+public class PreferencesCollectionValueModel
+ extends AspectAdapter
+ implements CollectionValueModel
+{
+
+ /** Cache the current preferences, stored in models and keyed by name. */
+ protected Map preferences;
+
+ /** A listener that listens to the preferences node for added or removed preferences. */
+ protected PreferenceChangeListener preferenceChangeListener;
+
+
+ // ********** constructors **********
+
+ /**
+ * Construct an adapter for the specified preferences node.
+ */
+ public PreferencesCollectionValueModel(Preferences preferences) {
+ super(preferences);
+ }
+
+ /**
+ * Construct an adapter for the specified preferences node.
+ */
+ public PreferencesCollectionValueModel(ValueModel preferencesHolder) {
+ super(preferencesHolder);
+ }
+
+
+ // ********** initialization **********
+
+ @Override
+ protected void initialize() {
+ super.initialize();
+ this.preferences = new HashMap();
+ this.preferenceChangeListener = this.buildPreferenceChangeListener();
+ }
+
+ /**
+ * A preferences have changed, notify the listeners.
+ */
+ protected PreferenceChangeListener buildPreferenceChangeListener() {
+ // transform the preference change events into VALUE collection change events
+ return new PreferenceChangeListener() {
+ public void preferenceChange(PreferenceChangeEvent e) {
+ PreferencesCollectionValueModel.this.preferenceChanged(e.getKey(), e.getNewValue());
+ }
+ @Override
+ public String toString() {
+ return "preference change listener";
+ }
+ };
+ }
+
+
+ // ********** ValueModel implementation **********
+
+ /**
+ * Return an iterator on the preference models.
+ */
+ public synchronized Object getValue() {
+ return this.preferences.values().iterator();
+ }
+
+
+ // ********** CollectionValueModel implementation **********
+
+ public void addItem(Object item) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void addItems(Collection items) {
+ for (Iterator stream = items.iterator(); stream.hasNext(); ) {
+ this.addItem(stream.next());
+ }
+ }
+
+ public void removeItem(Object item) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void removeItems(Collection items) {
+ for (Iterator stream = items.iterator(); stream.hasNext(); ) {
+ this.removeItem(stream.next());
+ }
+ }
+
+ public synchronized int size() {
+ return this.preferences.size();
+ }
+
+
+ // ********** AspectAdapter implementation **********
+
+ @Override
+ protected boolean hasListeners() {
+ return this.hasAnyCollectionChangeListeners(VALUE);
+ }
+
+ @Override
+ protected void fireAspectChange(Object oldValue, Object newValue) {
+ this.fireCollectionChanged(VALUE);
+ }
+
+ @Override
+ protected void engageNonNullSubject() {
+ ((Preferences) this.subject).addPreferenceChangeListener(this.preferenceChangeListener);
+ for (Iterator stream = this.preferenceModels(); stream.hasNext(); ) {
+ PreferencePropertyValueModel preferenceModel = (PreferencePropertyValueModel) stream.next();
+ this.preferences.put(preferenceModel.getKey(), preferenceModel);
+ }
+ }
+
+ @Override
+ protected void disengageNonNullSubject() {
+ try {
+ ((Preferences) this.subject).removePreferenceChangeListener(this.preferenceChangeListener);
+ } catch (IllegalStateException ex) {
+ // for some odd reason, we are not allowed to remove a listener from a "dead"
+ // preferences node; so handle the exception that gets thrown here
+ if ( ! ex.getMessage().equals("Node has been removed.")) {
+ // if it is not the expected exception, re-throw it
+ throw ex;
+ }
+ }
+ this.preferences.clear();
+ }
+
+
+ // ********** AbstractModel implementation **********
+
+ @Override
+ public void toString(StringBuilder sb) {
+ sb.append(this.subject);
+ }
+
+
+ // ********** internal methods **********
+
+ /**
+ * Return an iterator on the preference models.
+ * At this point we can be sure that the subject is not null.
+ */
+ protected Iterator preferenceModels() {
+ String[] keys;
+ try {
+ keys = ((Preferences) this.subject).keys();
+ } catch (BackingStoreException ex) {
+ throw new RuntimeException(ex);
+ }
+ return new TransformationIterator(new ArrayIterator(keys)) {
+ protected Object transform(Object next) {
+ return PreferencesCollectionValueModel.this.buildPreferenceModel((String) next);
+ }
+ };
+ }
+
+ /**
+ * Override this method to tweak the model used to wrap the
+ * specified preference (e.g. to customize the model's converter).
+ */
+ protected PreferencePropertyValueModel buildPreferenceModel(String key) {
+ return new PreferencePropertyValueModel(this.subjectHolder, key);
+ }
+
+ protected synchronized void preferenceChanged(String key, String newValue) {
+ if (newValue == null) {
+ // a preference was removed
+ PreferencePropertyValueModel preferenceModel = (PreferencePropertyValueModel) this.preferences.remove(key);
+ this.fireItemRemoved(VALUE, preferenceModel);
+ } else if ( ! this.preferences.containsKey(key)) {
+ // a preference was added
+ PreferencePropertyValueModel preferenceModel = this.buildPreferenceModel(key);
+ this.preferences.put(key, preferenceModel);
+ this.fireItemAdded(VALUE, preferenceModel);
+ } else {
+ // a preference's value changed - do nothing
+ }
+ }
+
+}

Back to the top