Skip to main content
summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorBrian Vosburgh2016-07-27 19:06:07 +0000
committerBrian Vosburgh2017-05-18 22:38:21 +0000
commitbac7b6fc927794b7912f14722db96c19ef89e454 (patch)
tree334987103b61d641afc13057ba6c73cb901d23d6 /common
parent054872c48934336548f6b6f7f87af49e4c1c7f9c (diff)
downloadwebtools.dali-bac7b6fc927794b7912f14722db96c19ef89e454.tar.gz
webtools.dali-bac7b6fc927794b7912f14722db96c19ef89e454.tar.xz
webtools.dali-bac7b6fc927794b7912f14722db96c19ef89e454.zip
refactor subclasses of AspectPropertyValueModelAdapter
Diffstat (limited to 'common')
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/BasePluggablePropertyValueModel.java4
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ModelPropertyAspectAdapter.java115
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ModifiablePropertyAspectAdapter.java54
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PluggablePropertyAspectAdapter.java217
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyAspectAdapter.java209
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyValueModelTools.java70
-rw-r--r--common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/model/value/CompoundPropertyValueModelTests.java2
7 files changed, 417 insertions, 254 deletions
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/BasePluggablePropertyValueModel.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/BasePluggablePropertyValueModel.java
index 1863e3d6ab..7814396fe8 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/BasePluggablePropertyValueModel.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/BasePluggablePropertyValueModel.java
@@ -171,7 +171,9 @@ public abstract class BasePluggablePropertyValueModel<V, A extends BasePluggable
// ********** Adapter Listener **********
/**
- * Simple callback. Allows us to keep the callback method internal.
+ * Simple callback.
+ * Allows us to keep the callback method internal.
+ * Also, a type cannot extend or implement one of its member types.
*/
/* CU private */ class AdapterListener
implements Adapter.Listener<V>
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ModelPropertyAspectAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ModelPropertyAspectAdapter.java
new file mode 100644
index 0000000000..0038844ca8
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ModelPropertyAspectAdapter.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2016 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.common.utility.internal.model.value;
+
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+import org.eclipse.jpt.common.utility.model.Model;
+import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.common.utility.transformer.Transformer;
+
+/**
+ * This adapter can be used by a {@link PluggablePropertyAspectAdapter
+ * pluggable property aspect adapter} to convert one of a {@link Model model's}
+ * <em>bound</em> properties to a
+ * {@link org.eclipse.jpt.common.utility.model.value.PropertyValueModel property value model}.
+ *
+ * @param <V> the type of the adapter's value
+ * @param <S> the type of the subject whose <em>bound</em> property is transformed into
+ * the value
+ */
+public final class ModelPropertyAspectAdapter<V, S extends Model>
+ implements PluggablePropertyAspectAdapter.SubjectAdapter<V, S>, PropertyChangeListener
+{
+ private final String propertyName;
+
+ private final Transformer<? super S, ? extends V> propertyTransformer;
+
+ private final PluggablePropertyAspectAdapter.SubjectAdapter.Listener<V> listener; // backpointer to aspect adapter
+
+
+ public ModelPropertyAspectAdapter(String propertyName, Transformer<? super S, ? extends V> propertyTransformer, PluggablePropertyAspectAdapter.SubjectAdapter.Listener<V> listener) {
+ super();
+ if (propertyName == null) {
+ throw new NullPointerException();
+ }
+ this.propertyName = propertyName;
+
+ if (propertyTransformer == null) {
+ throw new NullPointerException();
+ }
+ this.propertyTransformer = propertyTransformer;
+
+ if (listener == null) {
+ throw new NullPointerException();
+ }
+ this.listener = listener;
+ }
+
+ public V engageSubject(S subject) {
+ if (subject != null) {
+ subject.addPropertyChangeListener(this.propertyName, this);
+ }
+ return this.propertyTransformer.transform(subject);
+ }
+
+ public V disengageSubject(S subject) {
+ if (subject != null) {
+ subject.removePropertyChangeListener(this.propertyName, this);
+ }
+ return this.propertyTransformer.transform(subject);
+ }
+
+ public void propertyChanged(PropertyChangeEvent event) {
+ @SuppressWarnings("unchecked")
+ V newValue = (V) event.getNewValue();
+ this.listener.valueChanged(newValue);
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this, this.propertyName);
+ }
+
+
+ // ********** Factory **********
+
+ /**
+ * @see PluggablePropertyAspectAdapter
+ */
+ public static final class Factory<V, S extends Model>
+ implements PluggablePropertyAspectAdapter.SubjectAdapter.Factory<V, S>
+ {
+ /* CU private */ final String propertyName;
+ /* CU private */ final Transformer<? super S, ? extends V> propertyTransformer;
+
+ public Factory(String propertyName, Transformer<? super S, ? extends V> propertyTransformer) {
+ super();
+ if (propertyName == null) {
+ throw new NullPointerException();
+ }
+ this.propertyName = propertyName;
+
+ if (propertyTransformer == null) {
+ throw new NullPointerException();
+ }
+ this.propertyTransformer = propertyTransformer;
+ }
+
+ public PluggablePropertyAspectAdapter.SubjectAdapter<V, S> buildAdapter(PluggablePropertyAspectAdapter.SubjectAdapter.Listener<V> listener) {
+ return new ModelPropertyAspectAdapter<>(this.propertyName, this.propertyTransformer, listener);
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this);
+ }
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ModifiablePropertyAspectAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ModifiablePropertyAspectAdapter.java
index 70612a2b5f..d8a3e5bd4d 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ModifiablePropertyAspectAdapter.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/ModifiablePropertyAspectAdapter.java
@@ -11,9 +11,7 @@ package org.eclipse.jpt.common.utility.internal.model.value;
import org.eclipse.jpt.common.utility.closure.BiClosure;
import org.eclipse.jpt.common.utility.internal.ObjectTools;
-import org.eclipse.jpt.common.utility.model.Model;
import org.eclipse.jpt.common.utility.model.value.ModifiablePropertyValueModel;
-import org.eclipse.jpt.common.utility.model.value.PropertyValueModel;
import org.eclipse.jpt.common.utility.transformer.Transformer;
/**
@@ -28,26 +26,26 @@ import org.eclipse.jpt.common.utility.transformer.Transformer;
*
* @param <V> the type of the adapter's value
* @param <S> the type of the subject (and the subject model's value)
- * @param <SM> the type of the subject model
*
* @see PluggableModifiablePropertyValueModel
*/
-public final class ModifiablePropertyAspectAdapter<V, S extends Model, SM extends PropertyValueModel<S>>
+public final class ModifiablePropertyAspectAdapter<V, S>
implements PluggableModifiablePropertyValueModel.Adapter<V>
{
- /** The "get" half of the aspect adapter */
- private final PropertyAspectAdapter<V, S, SM> adapter;
+ /** The adapter used to "get" the subject's aspect value. */
+ private final GetAdapter<V, S> getAdapter;
/** The closure used to "set" the subject's new aspect value. */
private final BiClosure<? super S, ? super V> setClosure;
- public ModifiablePropertyAspectAdapter(PropertyAspectAdapter<V, S, SM> adapter, BiClosure<? super S, ? super V> setClosure) {
+ public ModifiablePropertyAspectAdapter(GetAdapter<V, S> getAdapter, BiClosure<? super S, ? super V> setClosure) {
super();
- if (adapter == null) {
+ if (getAdapter == null) {
throw new NullPointerException();
}
- this.adapter = adapter;
+ this.getAdapter = getAdapter;
+
if (setClosure == null) {
throw new NullPointerException();
}
@@ -55,37 +53,55 @@ public final class ModifiablePropertyAspectAdapter<V, S extends Model, SM extend
}
public V engageModel() {
- return this.adapter.engageModel();
+ return this.getAdapter.engageModel();
}
public V disengageModel() {
- return this.adapter.disengageModel();
+ return this.getAdapter.disengageModel();
}
public void setValue(V value) {
- this.setClosure.execute(this.adapter.subject, value);
+ this.setClosure.execute(this.getAdapter.getSubject(), value);
}
@Override
public String toString() {
- return ObjectTools.toString(this, this.adapter.buildValue());
+ return ObjectTools.toString(this, this.getAdapter);
}
+ /**
+ * Extend the pluggable pvm adapter so we can get the
+ * other adapter's subject and set the value of its aspect.
+ */
+ public interface GetAdapter<V, S>
+ extends PluggablePropertyValueModel.Adapter<V>
+ {
+ /**
+ * Return the adapter's subject.
+ */
+ S getSubject();
+
+ interface Factory<V, S> {
+ GetAdapter<V, S> buildAdapter(BasePluggablePropertyValueModel.Adapter.Listener<V> listener);
+ }
+ }
+
// ********** Factory **********
- public static final class Factory<V, S extends Model, SM extends PropertyValueModel<S>>
+ public static final class Factory<V, S>
implements PluggableModifiablePropertyValueModel.Adapter.Factory<V>
{
- private final PropertyAspectAdapter.Factory<V, S, SM> factory;
+ private final ModifiablePropertyAspectAdapter.GetAdapter.Factory<V, S> getAdapterFactory;
private final BiClosure<? super S, ? super V> setClosure;
- public Factory(PropertyAspectAdapter.Factory<V, S, SM> factory, BiClosure<? super S, ? super V> setClosure) {
+ public Factory(GetAdapter.Factory<V, S> getAdapterFactory, BiClosure<? super S, ? super V> setClosure) {
super();
- if (factory == null) {
+ if (getAdapterFactory == null) {
throw new NullPointerException();
}
- this.factory = factory;
+ this.getAdapterFactory = getAdapterFactory;
+
if (setClosure == null) {
throw new NullPointerException();
}
@@ -94,7 +110,7 @@ public final class ModifiablePropertyAspectAdapter<V, S extends Model, SM extend
@Override
public PluggableModifiablePropertyValueModel.Adapter<V> buildAdapter(BasePluggablePropertyValueModel.Adapter.Listener<V> listener) {
- return new ModifiablePropertyAspectAdapter<>(this.factory.buildAdapter(listener), this.setClosure);
+ return new ModifiablePropertyAspectAdapter<>(this.getAdapterFactory.buildAdapter(listener), this.setClosure);
}
}
}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PluggablePropertyAspectAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PluggablePropertyAspectAdapter.java
new file mode 100644
index 0000000000..dbdc48992b
--- /dev/null
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PluggablePropertyAspectAdapter.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2012, 2016 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.common.utility.internal.model.value;
+
+import org.eclipse.jpt.common.utility.internal.ObjectTools;
+import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent;
+import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener;
+import org.eclipse.jpt.common.utility.model.value.PropertyValueModel;
+
+/**
+ * This adapter adapts an subject property value model whose value is another model
+ * and treats the <em>inner</em> model's value as this adapter's models's value.
+ * As a result, this adapter listens for changes to either model
+ * (<em>inner</em> or <em>subject</em>).
+ * <p>
+ * A typical usage:<br>A (simple) model <code>A</code> is wrapped by
+ * a transformation model <code>B</code> that transforms model <code>A</code>'s
+ * value to yet another model <code>C</code>. This adapter is
+ * then constructed with model <code>B</code>.<ul>
+ * <li>If model <code>A</code>'s value changes
+ * (e.g. as the result of an Eclipse-generated event), model <code>B</code>
+ * will recalculate its value, a new model <code>C</code>, and this adapter's value will
+ * be recalculated etc.</li>
+ * <li>If model <code>C</code>'s value changes
+ * (e.g. its value is deleted from the Eclipse workspace), this adapter's value will
+ * be recalculated etc.</li>
+ * </ul>
+ * This is an adapter that can be used by a {@link BasePluggablePropertyValueModel}.
+ *
+ * @param <V> the type of the adapter's value
+ * @param <S> the type of the subject (and the subject model's value)
+ * @param <SM> the type of the subject model
+ *
+ * @see BasePluggablePropertyValueModel
+ * @see ModifiablePropertyAspectAdapter
+ */
+public final class PluggablePropertyAspectAdapter<V, S, SM extends PropertyValueModel<? extends S>>
+ implements ModifiablePropertyAspectAdapter.GetAdapter<V, S>, PropertyChangeListener
+{
+ private final SM subjectModel;
+
+ private volatile S subject;
+
+ private final SubjectAdapter<V, S> subjectAdapter;
+
+ private final BasePluggablePropertyValueModel.Adapter.Listener<V> listener; // backpointer
+
+
+ public PluggablePropertyAspectAdapter(SM subjectModel, SubjectAdapter.Factory<V, S> subjectAdapterFactory, BasePluggablePropertyValueModel.Adapter.Listener<V> listener) {
+ super();
+ if (subjectModel == null) {
+ throw new NullPointerException();
+ }
+ this.subjectModel = subjectModel;
+
+ if (subjectAdapterFactory == null) {
+ throw new NullPointerException();
+ }
+ this.subjectAdapter = subjectAdapterFactory.buildAdapter(new SubjectAdapterListener());
+
+ if (listener == null) {
+ throw new NullPointerException();
+ }
+ this.listener = listener;
+ }
+
+ /**
+ * Simple callback.
+ * Allows us to keep the callback method internal.
+ * Also, a type cannot extend or implement one of its member types.
+ */
+ /* CU private */ class SubjectAdapterListener
+ implements SubjectAdapter.Listener<V>
+ {
+ public void valueChanged(V newValue) {
+ PluggablePropertyAspectAdapter.this.aspectChanged(newValue);
+ }
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this);
+ }
+ }
+
+
+ // ********** BasePluggablePropertyValueModel.Adapter **********
+
+ public V engageModel() {
+ this.subjectModel.addPropertyChangeListener(PropertyValueModel.VALUE, this);
+ this.subject = this.subjectModel.getValue();
+ return this.subjectAdapter.engageSubject(this.subject);
+ }
+
+ public V disengageModel() {
+ S old = this.subject;
+ this.subjectModel.removePropertyChangeListener(PropertyValueModel.VALUE, this);
+ this.subject = null;
+ return this.subjectAdapter.disengageSubject(old);
+ }
+
+ public S getSubject() {
+ return this.subject;
+ }
+
+
+ // ********** event handling **********
+
+ /**
+ * Move our subject adapter to the new subject.
+ */
+ public void propertyChanged(PropertyChangeEvent event) {
+ @SuppressWarnings("unchecked")
+ S newSubject = (S) event.getNewValue();
+ this.subjectAdapter.disengageSubject(this.subject);
+ this.subject = newSubject;
+ this.listener.valueChanged(this.subjectAdapter.engageSubject(this.subject));
+ }
+
+ /* CU private */ void aspectChanged(V newValue) {
+ this.listener.valueChanged(newValue);
+ }
+
+
+ // ********** misc **********
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this, this.subjectAdapter);
+ }
+
+
+ // ********** Subject Adapter **********
+
+ /**
+ * Adapt an arbitrary subject to the aspect adapter's value;
+ * notifying the aspect adapter (via the {@link SubjectAdapter.Listener} interface)
+ * of any changes to the value.
+ */
+ public interface SubjectAdapter<V, S> {
+
+ /**
+ * Engage the specified subject, which can be <code>null</code>,
+ * and return the current value.
+ */
+ V engageSubject(S subject);
+
+ /**
+ * Disengage the specified subject, which can be <code>null</code>,
+ * and return the current value.
+ */
+ V disengageSubject(S subject);
+
+ /**
+ * Callback interface.
+ */
+ interface Listener<V> {
+ /**
+ * Callback to notify listener that the subject's aspect value
+ * has changed.
+ */
+ void valueChanged(V newValue);
+ }
+
+ /**
+ * Subject adapter factory interface.
+ * This factory allows both the pluggable property value model adapter and its
+ * subject adapter to have circular <em>final</em> references to each other.
+ */
+ interface Factory<V, S> {
+ /**
+ * Create a subject adapter with the specified listener.
+ */
+ SubjectAdapter<V, S> buildAdapter(Listener<V> listener);
+ }
+ }
+
+
+ // ********** Factory **********
+
+ /**
+ * @see PluggablePropertyAspectAdapter
+ */
+ public static final class Factory<V, S, SM extends PropertyValueModel<? extends S>>
+ implements PluggablePropertyValueModel.Adapter.Factory<V>, ModifiablePropertyAspectAdapter.GetAdapter.Factory<V, S>
+ {
+ private final SM subjectModel;
+ private final SubjectAdapter.Factory<V, S> subjectAdapterFactory;
+
+ public Factory(SM subjectModel, SubjectAdapter.Factory<V, S> subjectAdapterFactory) {
+ super();
+ if (subjectModel == null) {
+ throw new NullPointerException();
+ }
+ this.subjectModel = subjectModel;
+
+ if (subjectAdapterFactory == null) {
+ throw new NullPointerException();
+ }
+ this.subjectAdapterFactory = subjectAdapterFactory;
+ }
+
+ public PluggablePropertyAspectAdapter<V, S, SM> buildAdapter(BasePluggablePropertyValueModel.Adapter.Listener<V> listener) {
+ return new PluggablePropertyAspectAdapter<>(this.subjectModel, this.subjectAdapterFactory, listener);
+ }
+
+ @Override
+ public String toString() {
+ return ObjectTools.toString(this);
+ }
+ }
+}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyAspectAdapter.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyAspectAdapter.java
deleted file mode 100644
index a26367788f..0000000000
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyAspectAdapter.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012, 2016 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.common.utility.internal.model.value;
-
-import org.eclipse.jpt.common.utility.internal.ObjectTools;
-import org.eclipse.jpt.common.utility.model.Model;
-import org.eclipse.jpt.common.utility.model.event.PropertyChangeEvent;
-import org.eclipse.jpt.common.utility.model.listener.PropertyChangeAdapter;
-import org.eclipse.jpt.common.utility.model.listener.PropertyChangeListener;
-import org.eclipse.jpt.common.utility.model.value.PropertyValueModel;
-import org.eclipse.jpt.common.utility.transformer.Transformer;
-
-/**
- * This adapter adapts an subject property value model whose value is another model
- * and treats the <em>inner</em> model's value as this adapter's models's value.
- * As a result, this adapter listens for changes to either model
- * (<em>inner</em> or <em>subject</em>).
- * <p>
- * A typical usage:<br>A (simple) model <code>A</code> is wrapped by
- * a transformation model <code>B</code> that transforms model <code>A</code>'s
- * value to yet another model <code>C</code>. This adapter is
- * then constructed with model <code>B</code>.<ul>
- * <li>If model <code>A</code>'s value changes
- * (e.g. as the result of an Eclipse-generated event), model <code>B</code>
- * will recalculate its value, a new model <code>C</code>, and this adapter's value will
- * be recalculated etc.</li>
- * <li>If model <code>C</code>'s value changes
- * (e.g. its value is deleted from the Eclipse workspace), this adapter's value will
- * be recalculated etc.</li>
- * </ul>
- * This is an adapter that can be used by a {@link BasePluggablePropertyValueModel}.
- *
- * @param <V> the type of the adapter's value
- * @param <S> the type of the subject (and the subject model's value)
- * @param <SM> the type of the subject model
- *
- * @see BasePluggablePropertyValueModel
- */
-public final class PropertyAspectAdapter<V, S extends Model, SM extends PropertyValueModel<? extends S>>
- implements PluggablePropertyValueModel.Adapter<V>
-{
- /** The subject model; whose value is cached as {@link #subject}. */
- private final SM subjectModel;
-
- /** Listens to {@link #subjectModel}. */
- private final PropertyChangeListener subjectListener;
-
- /** The subject; which is the value of {@link #subjectModel}. Can be <code>null</code>. */
- /* package */ volatile S subject;
-
- /** The name of the {@link #subject}'s aspect, which is transformed into the adapter's value. */
- private final String aspectName;
-
- /** The transformer that converts {@link #subject} into the adapter's value. */
- private final Transformer<? super S, ? extends V> transformer;
-
- /** Listens to {@link #subject}, if present. */
- private final PropertyChangeListener aspectListener;
-
- /** Backpointer to the <em>real</em> adapter. */
- private final BasePluggablePropertyValueModel.Adapter.Listener<V> listener;
-
-
- public PropertyAspectAdapter(Factory<V, S, SM> factory, BasePluggablePropertyValueModel.Adapter.Listener<V> listener) {
- super();
- if (factory == null) {
- throw new NullPointerException();
- }
- this.subjectModel = factory.subjectModel;
- this.subjectListener = new SubjectListener();
-
- this.aspectName = factory.aspectName;
- this.transformer = factory.transformer;
-
- this.aspectListener = new AspectListener();
-
- if (listener == null) {
- throw new NullPointerException();
- }
- this.listener = listener;
- }
-
- /* CU private */ class SubjectListener
- extends PropertyChangeAdapter
- {
- @Override
- public void propertyChanged(PropertyChangeEvent event) {
- @SuppressWarnings("unchecked")
- S newSubject = (S) event.getNewValue();
- PropertyAspectAdapter.this.subjectChanged(newSubject);
- }
- }
-
- /* CU private */ class AspectListener
- extends PropertyChangeAdapter
- {
- @Override
- public void propertyChanged(PropertyChangeEvent event) {
- @SuppressWarnings("unchecked")
- V newValue = (V) event.getNewValue();
- PropertyAspectAdapter.this.aspectChanged(newValue);
- }
- }
-
-
- // ********** BasePluggablePropertyValueModel.Adapter **********
-
- public V engageModel() {
- this.subjectModel.addPropertyChangeListener(PropertyValueModel.VALUE, this.subjectListener);
- this.subject = this.subjectModel.getValue();
- return this.engageSubject();
- }
-
- private V engageSubject() {
- if (this.subject != null) {
- this.subject.addPropertyChangeListener(this.aspectName, this.aspectListener);
- }
- return this.buildValue();
- }
-
- public V disengageModel() {
- this.subjectModel.removePropertyChangeListener(PropertyValueModel.VALUE, this.subjectListener);
- return this.disengageSubject();
- }
-
- private V disengageSubject() {
- if (this.subject != null) {
- this.subject.removePropertyChangeListener(this.aspectName, this.aspectListener);
- this.subject = null;
- }
- return null;
- }
-
-
- // ********** event handling **********
-
- /**
- * Move our aspect listener to the new subject.
- */
- protected void subjectChanged(S newSubject) {
- this.disengageSubject();
- this.subject = newSubject;
- this.listener.valueChanged(this.engageSubject());
- }
-
- protected void aspectChanged(V newValue) {
- this.listener.valueChanged(newValue);
- }
-
-
- // ********** misc **********
-
- /* package */ V buildValue() {
- return this.transformer.transform(this.subject);
- }
-
- @Override
- public String toString() {
- return ObjectTools.toString(this, this.buildValue());
- }
-
-
- // ********** Factory **********
-
- /**
- * @see PropertyAspectAdapter
- */
- public static final class Factory<V, S extends Model, SM extends PropertyValueModel<? extends S>>
- implements PluggablePropertyValueModel.Adapter.Factory<V>
- {
- /* CU private */ final SM subjectModel;
- /* CU private */ final String aspectName;
- /* CU private */ final Transformer<? super S, ? extends V> transformer;
-
- public Factory(SM subjectModel, String aspectName, Transformer<? super S, ? extends V> transformer) {
- super();
- if (subjectModel == null) {
- throw new NullPointerException();
- }
- this.subjectModel = subjectModel;
-
- if (aspectName == null) {
- throw new NullPointerException();
- }
- this.aspectName = aspectName;
-
- if (transformer == null) {
- throw new NullPointerException();
- }
- this.transformer = transformer;
- }
-
- public PropertyAspectAdapter<V, S, SM> buildAdapter(BasePluggablePropertyValueModel.Adapter.Listener<V> listener) {
- return new PropertyAspectAdapter<>(this, listener);
- }
-
- @Override
- public String toString() {
- return ObjectTools.toString(this);
- }
- }
-}
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyValueModelTools.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyValueModelTools.java
index b4765d099c..1a50efd17f 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyValueModelTools.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/model/value/PropertyValueModelTools.java
@@ -850,8 +850,8 @@ public final class PropertyValueModelTools {
* If the <em>outer</em> model's value is ever <code>null</code>,
* the factory's model's value will also be <code>null</code>.
*/
- public static <V, IM extends PropertyValueModel<? extends V>, OM extends PropertyValueModel<? extends IM>> PropertyAspectAdapter.Factory<V, IM, OM> compoundPropertyValueModelAdapterFactory(OM outerModel) {
- return aspectAdapterFactory_(
+ public static <V, IM extends PropertyValueModel<? extends V>, OM extends PropertyValueModel<? extends IM>> PluggablePropertyAspectAdapter.Factory<V, IM, OM> compoundPropertyValueModelAdapterFactory(OM outerModel) {
+ return modelAspectAdapterFactory_(
outerModel,
PropertyValueModel.VALUE,
valueTransformer()
@@ -866,8 +866,8 @@ public final class PropertyValueModelTools {
* If the <em>outer</em> model's value is ever <code>null</code>,
* the factory's model will throw a {@link NullPointerException}.
*/
- public static <V, IM extends PropertyValueModel<? extends V>, OM extends PropertyValueModel<? extends IM>> PropertyAspectAdapter.Factory<V, IM, OM> compoundPropertyValueModelAdapterFactory_(OM outerModel) {
- return aspectAdapterFactory_(
+ public static <V, IM extends PropertyValueModel<? extends V>, OM extends PropertyValueModel<? extends IM>> PluggablePropertyAspectAdapter.Factory<V, IM, OM> compoundPropertyValueModelAdapterFactory_(OM outerModel) {
+ return modelAspectAdapterFactory_(
outerModel,
PropertyValueModel.VALUE,
valueTransformer_()
@@ -936,65 +936,87 @@ public final class PropertyValueModelTools {
// ********** aspect adapters **********
/**
- * Construct a property aspect adapter for the
+ * Construct a model property aspect adapter for the
* specified subject model, aspect name, and transformer.
* <p>
* <strong>NB:</strong>
* The specified transformer will <em>never</em> be passed a <code>null</code> subject.
* Instead, a <code>null</code> subject will be transformed into a <code>null</code> value.
*/
- public static <V, S extends Model, SM extends PropertyValueModel<? extends S>> PropertyValueModel<V> aspectAdapter(
+ public static <V, S extends Model, SM extends PropertyValueModel<? extends S>> PropertyValueModel<V> modelAspectAdapter(
SM subjectModel,
String aspectName,
Transformer<? super S, ? extends V> transformer
) {
- return propertyValueModel(aspectAdapterFactory(subjectModel, aspectName, transformer));
+ return propertyValueModel(modelAspectAdapterFactory(subjectModel, aspectName, transformer));
}
/**
- * Construct a property aspect adapter for the
+ * Construct a model property aspect adapter for the
* specified subject model, aspect name, and transformer.
* <p>
* <strong>NB:</strong>
* The specified transformer must be able to handle a <code>null</code> subject.
*/
- public static <V, S extends Model, SM extends PropertyValueModel<? extends S>> PropertyValueModel<V> aspectAdapter_(
+ public static <V, S extends Model, SM extends PropertyValueModel<? extends S>> PropertyValueModel<V> modelAspectAdapter_(
SM subjectModel,
String aspectName,
Transformer<? super S, ? extends V> transformer
) {
- return propertyValueModel(aspectAdapterFactory_(subjectModel, aspectName, transformer));
+ return propertyValueModel(modelAspectAdapterFactory_(subjectModel, aspectName, transformer));
}
/**
- * Construct a property aspect adapter factory for the
+ * Construct a model property aspect adapter factory for the
* specified subject model, aspect name, and transformer.
* <p>
* <strong>NB:</strong>
* The specified transformer will <em>never</em> be passed a <code>null</code> subject.
* Instead, a <code>null</code> subject will be transformed into a <code>null</code> value.
*/
- public static <V, S extends Model, SM extends PropertyValueModel<? extends S>> PropertyAspectAdapter.Factory<V, S, SM> aspectAdapterFactory(
+ public static <V, S extends Model, SM extends PropertyValueModel<? extends S>> PluggablePropertyAspectAdapter.Factory<V, S, SM> modelAspectAdapterFactory(
SM subjectModel,
String aspectName,
Transformer<? super S, ? extends V> transformer
) {
- return aspectAdapterFactory_(subjectModel, aspectName, TransformerTools.nullCheck(transformer));
+ return modelAspectAdapterFactory_(subjectModel, aspectName, TransformerTools.nullCheck(transformer));
}
/**
- * Construct a property aspect adapter factory for the
+ * Construct a model property aspect adapter factory for the
* specified subject model, aspect name, and transformer.
* <p>
* <strong>NB:</strong>
* The specified transformer must be able to handle a <code>null</code> subject.
*/
- public static <V, S extends Model, SM extends PropertyValueModel<? extends S>> PropertyAspectAdapter.Factory<V, S, SM> aspectAdapterFactory_(
+ public static <V, S extends Model, SM extends PropertyValueModel<? extends S>> PluggablePropertyAspectAdapter.Factory<V, S, SM> modelAspectAdapterFactory_(
SM subjectModel,
String aspectName,
Transformer<? super S, ? extends V> transformer
) {
- return new PropertyAspectAdapter.Factory<>(subjectModel, aspectName, transformer);
+ return pluggableAspectAdapterFactory(subjectModel, new ModelPropertyAspectAdapter.Factory<>(aspectName, transformer));
+ }
+
+ /**
+ * Construct a property aspect adapter for the
+ * specified subject model and subject adapter factory.
+ */
+ public static <V, S, SM extends PropertyValueModel<? extends S>> PropertyValueModel<V> aspectAdapter(
+ SM subjectModel,
+ PluggablePropertyAspectAdapter.SubjectAdapter.Factory<V, S> subjectAdapterFactory
+ ) {
+ return propertyValueModel(pluggableAspectAdapterFactory(subjectModel, subjectAdapterFactory));
+ }
+
+ /**
+ * Construct a property aspect adapter factory for the
+ * specified subject model and subject adapter factory.
+ */
+ public static <V, S, SM extends PropertyValueModel<? extends S>> PluggablePropertyAspectAdapter.Factory<V, S, SM> pluggableAspectAdapterFactory(
+ SM subjectModel,
+ PluggablePropertyAspectAdapter.SubjectAdapter.Factory<V, S> subjectAdapterFactory
+ ) {
+ return new PluggablePropertyAspectAdapter.Factory<>(subjectModel, subjectAdapterFactory);
}
@@ -1053,7 +1075,7 @@ public final class PropertyValueModelTools {
Transformer<? super S, ? extends V> getTransformer,
BiClosure<? super S, ? super V> setClosure
) {
- return modifiablePropertyAspectAdapterFactory(aspectAdapterFactory(subjectModel, aspectName, getTransformer), setClosure);
+ return modifiablePropertyAspectAdapterFactory(modelAspectAdapterFactory(subjectModel, aspectName, getTransformer), setClosure);
}
/**
@@ -1071,7 +1093,7 @@ public final class PropertyValueModelTools {
Transformer<? super S, ? extends V> getTransformer,
BiClosure<? super S, ? super V> setClosure
) {
- return modifiablePropertyAspectAdapterFactory_(aspectAdapterFactory_(subjectModel, aspectName, getTransformer), setClosure);
+ return modifiablePropertyAspectAdapterFactory_(modelAspectAdapterFactory_(subjectModel, aspectName, getTransformer), setClosure);
}
/**
@@ -1082,11 +1104,11 @@ public final class PropertyValueModelTools {
* If the subject is <code>null</code>, the specified closure will
* not be executed.
*/
- public static <V, S extends Model, SM extends PropertyValueModel<S>> PluggableModifiablePropertyValueModel.Adapter.Factory<V> modifiablePropertyAspectAdapterFactory(
- PropertyAspectAdapter.Factory<V, S, SM> factory,
+ public static <V, S> PluggableModifiablePropertyValueModel.Adapter.Factory<V> modifiablePropertyAspectAdapterFactory(
+ ModifiablePropertyAspectAdapter.GetAdapter.Factory<V, S> getAdapterFactory,
BiClosure<? super S, ? super V> setClosure
) {
- return modifiablePropertyAspectAdapterFactory_(factory, nullCheckSetClosureWrapper(setClosure));
+ return modifiablePropertyAspectAdapterFactory_(getAdapterFactory, nullCheckSetClosureWrapper(setClosure));
}
/**
@@ -1097,11 +1119,11 @@ public final class PropertyValueModelTools {
* The specified closure must be able to handle a <code>null</code>
* subject (i.e. first argument).
*/
- public static <V, S extends Model, SM extends PropertyValueModel<S>> PluggableModifiablePropertyValueModel.Adapter.Factory<V> modifiablePropertyAspectAdapterFactory_(
- PropertyAspectAdapter.Factory<V, S, SM> factory,
+ public static <V, S> PluggableModifiablePropertyValueModel.Adapter.Factory<V> modifiablePropertyAspectAdapterFactory_(
+ ModifiablePropertyAspectAdapter.GetAdapter.Factory<V, S> getAdapterFactory,
BiClosure<? super S, ? super V> setClosure
) {
- return new ModifiablePropertyAspectAdapter.Factory<>(factory, setClosure);
+ return new ModifiablePropertyAspectAdapter.Factory<>(getAdapterFactory, setClosure);
}
diff --git a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/model/value/CompoundPropertyValueModelTests.java b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/model/value/CompoundPropertyValueModelTests.java
index 1f126b396e..4f60c24c5b 100644
--- a/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/model/value/CompoundPropertyValueModelTests.java
+++ b/common/tests/org.eclipse.jpt.common.utility.tests/src/org/eclipse/jpt/common/utility/tests/internal/model/value/CompoundPropertyValueModelTests.java
@@ -125,7 +125,7 @@ public class CompoundPropertyValueModelTests
assertEquals("foo", this.keyModel.getValue()); // simple PVM
assertNull(this.valueModelModel.getValue());
- assertNull(this.testModel.getValue());
+ assertEquals("XXX", this.testModel.getValue());
}
public void testLazyListening() {

Back to the top