### Eclipse Workspace Patch 1.0 #P org.eclipse.core.databinding Index: src/org/eclipse/core/databinding/TargetsListener.java =================================================================== RCS file: src/org/eclipse/core/databinding/TargetsListener.java diff -N src/org/eclipse/core/databinding/TargetsListener.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/core/databinding/TargetsListener.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright (c) 2009 IBM Corporation 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 + * + * Contributors: + * IBM Corporation - initial API and implementation + ******************************************************************************/ + +package org.eclipse.core.databinding; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.core.databinding.observable.ChangeEvent; +import org.eclipse.core.databinding.observable.IChangeListener; +import org.eclipse.core.databinding.observable.IObservable; +import org.eclipse.core.databinding.observable.list.IListChangeListener; +import org.eclipse.core.databinding.observable.list.IObservableList; +import org.eclipse.core.databinding.observable.list.ListChangeEvent; +import org.eclipse.core.databinding.observable.list.ListDiff; +import org.eclipse.core.databinding.observable.list.ListDiffEntry; + +/** + * A TargetListener listens to changes of any target of any + * ValidationStatusProvider in the given context. + * + * @since 1.2 + * + */ +public class TargetsListener { + /** + * Creates a TargetsListener. Once when any target changes the listener will + * be notified and the TargetsListener will be disposed. + * + * @param context + * @param listener + * @return The TargetsListener is returned so it can be disposed even if no + * change occurs. It should not be used for anything else. + */ + public static TargetsListener listenOnce(DataBindingContext context, final IChangeListener listener) { + final TargetsListener targetsListener = new TargetsListener(context); + targetsListener.addChangeListener(new IChangeListener() { + public void handleChange(ChangeEvent event) { + listener.handleChange(event); + targetsListener.dispose(); + } + }); + return targetsListener; + } + + private final DataBindingContext context; + private final List changeListeners = new ArrayList(); + + private IChangeListener targetListener = new IChangeListener() { + public void handleChange(ChangeEvent event) { + Iterator iterator = changeListeners.iterator(); + while (iterator.hasNext()) { + IChangeListener listener = (IChangeListener) iterator.next(); + listener.handleChange(event); + } + } + }; + private IListChangeListener validationStatusProvidersListener = new IListChangeListener() { + public void handleListChange(ListChangeEvent event) { + ListDiff diff = event.diff; + ListDiffEntry[] differences = diff.getDifferences(); + for (int i = 0; i < differences.length; i++) { + ListDiffEntry listDiffEntry = differences[i]; + ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) listDiffEntry + .getElement(); + IObservableList targets = validationStatusProvider.getTargets(); + if (listDiffEntry.isAddition()) { + targets.addListChangeListener(validationStatusProviderTargetsListener); + for (Iterator it = targets.iterator(); it.hasNext();) { + ((IObservable) it.next()).addChangeListener(targetListener); + } + } else { + targets.removeListChangeListener(validationStatusProviderTargetsListener); + for (Iterator it = targets.iterator(); it.hasNext();) { + ((IObservable) it.next()).removeChangeListener(targetListener); + } + } + } + } + }; + private IListChangeListener validationStatusProviderTargetsListener = new IListChangeListener() { + public void handleListChange(ListChangeEvent event) { + ListDiff diff = event.diff; + ListDiffEntry[] differences = diff.getDifferences(); + for (int i = 0; i < differences.length; i++) { + ListDiffEntry listDiffEntry = differences[i]; + IObservable target = (IObservable) listDiffEntry.getElement(); + if (listDiffEntry.isAddition()) { + target.addChangeListener(targetListener); + } else { + target.removeChangeListener(targetListener); + } + } + } + }; + + /** + * A TargetListener listens to changes of any target of any + * ValidationStatusProvider in the given context. + * + * @param context + */ + public TargetsListener(DataBindingContext context) { + this.context = context; + IObservableList validationStatusProviders = context.getValidationStatusProviders(); + validationStatusProviders.addListChangeListener(validationStatusProvidersListener); + for (Iterator iter = validationStatusProviders.iterator(); iter.hasNext();) { + ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) iter.next(); + IObservableList targets = validationStatusProvider.getTargets(); + targets.addListChangeListener(validationStatusProviderTargetsListener); + for (Iterator it = targets.iterator(); it.hasNext();) { + ((IObservable) it.next()).addChangeListener(targetListener); + } + } + } + + /** + * Adds the {@link IChangeListener} to the list of target listeners. + * + * @param listener + * The IChangeListener that will be notified in case any target + * changes. + * @since 1.2 + */ + public final void addChangeListener(IChangeListener listener) { + changeListeners.add(listener); + } + + /** + * Removes the {@link IChangeListener} from the list of target listeners. + * + * @param listener + * The IChangeListener that should no longer be notified in case + * any target changes. + * @since 1.2 + */ + public final void removeChangeListener(IChangeListener listener) { + changeListeners.remove(listener); + } + + public void dispose() { + IObservableList validationStatusProviders = context.getValidationStatusProviders(); + validationStatusProviders.removeListChangeListener(validationStatusProvidersListener); + for (Iterator iter = validationStatusProviders.iterator(); iter.hasNext();) { + ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) iter.next(); + IObservableList targets = validationStatusProvider.getTargets(); + targets.removeListChangeListener(validationStatusProviderTargetsListener); + for (Iterator it = targets.iterator(); it.hasNext();) { + ((IObservable) it.next()).removeChangeListener(targetListener); + } + } + } +} #P org.eclipse.jface.databinding Index: src/org/eclipse/jface/databinding/dialog/DialogPageSupport.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jface.databinding/src/org/eclipse/jface/databinding/dialog/DialogPageSupport.java,v retrieving revision 1.2 diff -u -r1.2 DialogPageSupport.java --- src/org/eclipse/jface/databinding/dialog/DialogPageSupport.java 23 Oct 2008 17:47:08 -0000 1.2 +++ src/org/eclipse/jface/databinding/dialog/DialogPageSupport.java 28 Feb 2009 01:46:09 -0000 @@ -15,21 +15,13 @@ package org.eclipse.jface.databinding.dialog; -import java.util.Iterator; - import org.eclipse.core.databinding.AggregateValidationStatus; import org.eclipse.core.databinding.DataBindingContext; -import org.eclipse.core.databinding.ValidationStatusProvider; +import org.eclipse.core.databinding.TargetsListener; import org.eclipse.core.databinding.observable.ChangeEvent; import org.eclipse.core.databinding.observable.IChangeListener; -import org.eclipse.core.databinding.observable.IObservable; import org.eclipse.core.databinding.observable.IStaleListener; import org.eclipse.core.databinding.observable.StaleEvent; -import org.eclipse.core.databinding.observable.list.IListChangeListener; -import org.eclipse.core.databinding.observable.list.IObservableList; -import org.eclipse.core.databinding.observable.list.ListChangeEvent; -import org.eclipse.core.databinding.observable.list.ListDiff; -import org.eclipse.core.databinding.observable.list.ListDiffEntry; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.core.databinding.observable.value.IValueChangeListener; import org.eclipse.core.databinding.observable.value.ValueChangeEvent; @@ -68,55 +60,9 @@ private DataBindingContext dbc; private IObservableValue aggregateStatus; private boolean uiChanged = false; - private IChangeListener uiChangeListener = new IChangeListener() { - public void handleChange(ChangeEvent event) { - handleUIChanged(); - } - }; - private IListChangeListener validationStatusProvidersListener = new IListChangeListener() { - public void handleListChange(ListChangeEvent event) { - ListDiff diff = event.diff; - ListDiffEntry[] differences = diff.getDifferences(); - for (int i = 0; i < differences.length; i++) { - ListDiffEntry listDiffEntry = differences[i]; - ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) listDiffEntry - .getElement(); - IObservableList targets = validationStatusProvider.getTargets(); - if (listDiffEntry.isAddition()) { - targets - .addListChangeListener(validationStatusProviderTargetsListener); - for (Iterator it = targets.iterator(); it.hasNext();) { - ((IObservable) it.next()) - .addChangeListener(uiChangeListener); - } - } else { - targets - .removeListChangeListener(validationStatusProviderTargetsListener); - for (Iterator it = targets.iterator(); it.hasNext();) { - ((IObservable) it.next()) - .removeChangeListener(uiChangeListener); - } - } - } - } - }; - private IListChangeListener validationStatusProviderTargetsListener = new IListChangeListener() { - public void handleListChange(ListChangeEvent event) { - ListDiff diff = event.diff; - ListDiffEntry[] differences = diff.getDifferences(); - for (int i = 0; i < differences.length; i++) { - ListDiffEntry listDiffEntry = differences[i]; - IObservable target = (IObservable) listDiffEntry.getElement(); - if (listDiffEntry.isAddition()) { - target.addChangeListener(uiChangeListener); - } else { - target.removeChangeListener(uiChangeListener); - } - } - } - }; protected IStatus currentStatus; protected boolean currentStatusStale; + private TargetsListener targetsListener; /** * @param dialogPage @@ -161,19 +107,11 @@ currentStatus = (IStatus) aggregateStatus.getValue(); currentStatusStale = aggregateStatus.isStale(); handleStatusChanged(); - dbc.getValidationStatusProviders().addListChangeListener( - validationStatusProvidersListener); - for (Iterator it = dbc.getValidationStatusProviders().iterator(); it - .hasNext();) { - ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it - .next(); - IObservableList targets = validationStatusProvider.getTargets(); - targets - .addListChangeListener(validationStatusProviderTargetsListener); - for (Iterator iter = targets.iterator(); iter.hasNext();) { - ((IObservable) iter.next()).addChangeListener(uiChangeListener); + targetsListener = TargetsListener.listenOnce(dbc, new IChangeListener() { + public void handleChange(ChangeEvent event) { + handleUIChanged(); } - } + }); } /** @@ -184,20 +122,6 @@ if (currentStatus != null) { handleStatusChanged(); } - dbc.getValidationStatusProviders().removeListChangeListener( - validationStatusProvidersListener); - for (Iterator it = dbc.getValidationStatusProviders().iterator(); it - .hasNext();) { - ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it - .next(); - IObservableList targets = validationStatusProvider.getTargets(); - targets - .removeListChangeListener(validationStatusProviderTargetsListener); - for (Iterator iter = targets.iterator(); iter.hasNext();) { - ((IObservable) iter.next()) - .removeChangeListener(uiChangeListener); - } - } } /** @@ -298,26 +222,10 @@ public void dispose() { aggregateStatus.dispose(); if (!uiChanged) { - for (Iterator it = dbc.getValidationStatusProviders().iterator(); it - .hasNext();) { - ValidationStatusProvider validationStatusProvider = (ValidationStatusProvider) it - .next(); - IObservableList targets = validationStatusProvider.getTargets(); - targets - .removeListChangeListener(validationStatusProviderTargetsListener); - for (Iterator iter = targets.iterator(); iter.hasNext();) { - ((IObservable) iter.next()) - .removeChangeListener(uiChangeListener); - } - } - dbc.getValidationStatusProviders().removeListChangeListener( - validationStatusProvidersListener); + targetsListener.dispose(); } aggregateStatus = null; dbc = null; - uiChangeListener = null; - validationStatusProvidersListener = null; - validationStatusProviderTargetsListener = null; dialogPage = null; } }