diff options
author | Ed Merks | 2020-09-17 14:06:42 +0000 |
---|---|---|
committer | Ed Merks | 2020-09-17 14:06:42 +0000 |
commit | 684fca6acf66f6e7810cee53299fadf0d9fae827 (patch) | |
tree | 15c153b5660b534a28884b5fac89a1cb06420f20 | |
parent | 2d4fa9f4703efdd5b3aa7feea16947892ed1aeca (diff) | |
download | org.eclipse.emf-684fca6acf66f6e7810cee53299fadf0d9fae827.tar.gz org.eclipse.emf-684fca6acf66f6e7810cee53299fadf0d9fae827.tar.xz org.eclipse.emf-684fca6acf66f6e7810cee53299fadf0d9fae827.zip |
[566747] FindAndReplaceTarget prevents garbage collection of EcoreEditor
leading to memory exhaustion
7 files changed, 104 insertions, 10 deletions
diff --git a/features/org.eclipse.emf-feature/feature.xml b/features/org.eclipse.emf-feature/feature.xml index 8a1938346..04aa184d7 100644 --- a/features/org.eclipse.emf-feature/feature.xml +++ b/features/org.eclipse.emf-feature/feature.xml @@ -2,7 +2,7 @@ <feature id="org.eclipse.emf" label="%featureName" - version="2.23.0.qualifier" + version="2.24.0.qualifier" provider-name="%providerName" license-feature="org.eclipse.emf.license" license-feature-version="2.11.0"> diff --git a/features/org.eclipse.emf-feature/pom.xml b/features/org.eclipse.emf-feature/pom.xml index 4f3d8b9cf..6b2bddb79 100644 --- a/features/org.eclipse.emf-feature/pom.xml +++ b/features/org.eclipse.emf-feature/pom.xml @@ -12,7 +12,7 @@ <groupId>org.eclipse.emf.features</groupId> <artifactId>org.eclipse.emf</artifactId> - <version>2.23.0-SNAPSHOT</version> + <version>2.24.0-SNAPSHOT</version> <packaging>eclipse-feature</packaging> </project> diff --git a/features/org.eclipse.emf.edit.ui-feature/feature.xml b/features/org.eclipse.emf.edit.ui-feature/feature.xml index 68acb5ab2..5aed7826c 100644 --- a/features/org.eclipse.emf.edit.ui-feature/feature.xml +++ b/features/org.eclipse.emf.edit.ui-feature/feature.xml @@ -2,7 +2,7 @@ <feature id="org.eclipse.emf.edit.ui" label="%featureName" - version="2.19.0.qualifier" + version="2.20.0.qualifier" provider-name="%providerName" license-feature="org.eclipse.emf.license" license-feature-version="2.11.0"> diff --git a/features/org.eclipse.emf.edit.ui-feature/pom.xml b/features/org.eclipse.emf.edit.ui-feature/pom.xml index 033492e51..2a62327d8 100644 --- a/features/org.eclipse.emf.edit.ui-feature/pom.xml +++ b/features/org.eclipse.emf.edit.ui-feature/pom.xml @@ -12,7 +12,7 @@ <groupId>org.eclipse.emf.features</groupId> <artifactId>org.eclipse.emf.edit.ui</artifactId> - <version>2.19.0-SNAPSHOT</version> + <version>2.20.0-SNAPSHOT</version> <packaging>eclipse-feature</packaging> </project> diff --git a/plugins/org.eclipse.emf.edit.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.edit.ui/META-INF/MANIFEST.MF index d3d62b98c..d20c8fe1a 100644 --- a/plugins/org.eclipse.emf.edit.ui/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.edit.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.emf.edit.ui;singleton:=true -Bundle-Version: 2.18.0.qualifier +Bundle-Version: 2.19.0.qualifier Bundle-ClassPath: . Bundle-Activator: org.eclipse.emf.edit.ui.EMFEditUIPlugin$Implementation Bundle-Vendor: %providerName diff --git a/plugins/org.eclipse.emf.edit.ui/pom.xml b/plugins/org.eclipse.emf.edit.ui/pom.xml index 9ea2c9548..88acd3202 100644 --- a/plugins/org.eclipse.emf.edit.ui/pom.xml +++ b/plugins/org.eclipse.emf.edit.ui/pom.xml @@ -12,7 +12,7 @@ <groupId>org.eclipse.emf</groupId> <artifactId>org.eclipse.emf.edit.ui</artifactId> - <version>2.18.0-SNAPSHOT</version> + <version>2.19.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> </project> diff --git a/plugins/org.eclipse.emf.edit.ui/src/org/eclipse/emf/edit/ui/util/FindAndReplaceTarget.java b/plugins/org.eclipse.emf.edit.ui/src/org/eclipse/emf/edit/ui/util/FindAndReplaceTarget.java index f9e2eb08b..269d721fd 100644 --- a/plugins/org.eclipse.emf.edit.ui/src/org/eclipse/emf/edit/ui/util/FindAndReplaceTarget.java +++ b/plugins/org.eclipse.emf.edit.ui/src/org/eclipse/emf/edit/ui/util/FindAndReplaceTarget.java @@ -9,6 +9,7 @@ package org.eclipse.emf.edit.ui.util; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.text.Collator; import java.util.ArrayList; import java.util.Collection; @@ -21,7 +22,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; -import java.util.WeakHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -96,6 +96,7 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.IPartListener; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; @@ -141,7 +142,7 @@ public final class FindAndReplaceTarget implements IFindReplaceTarget, IFindRepl /** * A map for managing the association between a workbench part and it associated find and replace target. */ - private static final Map<IWorkbenchPart, FindAndReplaceTarget> FIND_AND_REPLACE_TARGETS = new WeakHashMap<IWorkbenchPart, FindAndReplaceTarget>(); + private static final Map<IWorkbenchPart, FindAndReplaceTarget> FIND_AND_REPLACE_TARGETS = new HashMap<IWorkbenchPart, FindAndReplaceTarget>(); /** * A styler for drawing a box around matching text. @@ -165,16 +166,25 @@ public final class FindAndReplaceTarget implements IFindReplaceTarget, IFindRepl */ private static final Field F_SELECTED_RANGE_RADIO_BUTTON_FIELD; + /** + * Provides access to the {@code fTarget} of a {@code org.eclipse.ui.texteditor.FindReplaceDialog}. + */ + private static final Field F_TARGET_FIELD; + static { Field fIsRegExCheckBoxField = null; Field fSelectedRangeRadioButtonField = null; + Field fTarget = null; try { Class<?> findReplaceDialogClass = CommonPlugin.loadClass("org.eclipse.ui.workbench.texteditor", "org.eclipse.ui.texteditor.FindReplaceDialog"); fIsRegExCheckBoxField = findReplaceDialogClass.getDeclaredField("fIsRegExCheckBox"); fIsRegExCheckBoxField.setAccessible(true); fSelectedRangeRadioButtonField = findReplaceDialogClass.getDeclaredField("fSelectedRangeRadioButton"); + fSelectedRangeRadioButtonField.setAccessible(true); + fTarget = findReplaceDialogClass.getDeclaredField("fTarget"); + fTarget.setAccessible(true); } catch (Throwable throwable) { @@ -182,6 +192,7 @@ public final class FindAndReplaceTarget implements IFindReplaceTarget, IFindRepl } F_IS_REGEX_CHECK_BOX_FIELD = fIsRegExCheckBoxField; F_SELECTED_RANGE_RADIO_BUTTON_FIELD = fSelectedRangeRadioButtonField; + F_TARGET_FIELD = fTarget; } /** @@ -191,6 +202,41 @@ public final class FindAndReplaceTarget implements IFindReplaceTarget, IFindRepl private static final Map<Font, Font> TINY_FONT = new HashMap<Font, Font>(); /** + * A listener for when parts are closed to clean up the {@link #FIND_AND_REPLACE_TARGETS}. + * @see #getAdapter(Class, IWorkbenchPart, AbstractUIPlugin) + */ + private static final IPartListener PART_LISTENER = new IPartListener() + { + public void partOpened(IWorkbenchPart part) + { + } + + public void partDeactivated(IWorkbenchPart part) + { + } + + public void partClosed(IWorkbenchPart part) + { + synchronized (FIND_AND_REPLACE_TARGETS) + { + FindAndReplaceTarget findAndReplaceTarget = FIND_AND_REPLACE_TARGETS.remove(part); + if (findAndReplaceTarget != null) + { + findAndReplaceTarget.dispose(); + } + } + } + + public void partBroughtToTop(IWorkbenchPart part) + { + } + + public void partActivated(IWorkbenchPart part) + { + } + }; + + /** * The workbench part of this find and replace target. */ private final IWorkbenchPart workbenchPart; @@ -222,6 +268,14 @@ public final class FindAndReplaceTarget implements IFindReplaceTarget, IFindRepl private Runnable sessionCleanup; /** + * A cleanup action for when the workbench part is disposed. + * + * @see #addSearchTypeControl() + * @see #dispose() + */ + private Runnable disposeCleanup; + + /** * If an advanced property needs to be displayed for search results and that action is currently not checked, * it will be checked and this cleanup action will be set to restore the state when the session ends. * @@ -323,6 +377,7 @@ public final class FindAndReplaceTarget implements IFindReplaceTarget, IFindRepl FindAndReplaceTarget findAndReplaceTarget = FindAndReplaceTarget.FIND_AND_REPLACE_TARGETS.get(workbenchPart); if (findAndReplaceTarget == null) { + workbenchPart.getSite().getPage().addPartListener(PART_LISTENER); findAndReplaceTarget = new FindAndReplaceTarget(workbenchPart, plugin); FindAndReplaceTarget.FIND_AND_REPLACE_TARGETS.put(workbenchPart, findAndReplaceTarget); } @@ -549,7 +604,7 @@ public final class FindAndReplaceTarget implements IFindReplaceTarget, IFindRepl if (data instanceof Dialog && "org.eclipse.ui.texteditor.FindReplaceDialog".equals(data.getClass().getName())) { // Find the last checkbox in the dialog. - Dialog dialog = (Dialog)data; + final Dialog dialog = (Dialog)data; Object checkBox = getFieldValue(dialog, F_IS_REGEX_CHECK_BOX_FIELD); if (checkBox instanceof Button) { @@ -689,6 +744,34 @@ public final class FindAndReplaceTarget implements IFindReplaceTarget, IFindRepl { categoriesChangeCleanup.run(); } + + sessionCleanup = null; + } + }; + + disposeCleanup = new Runnable() + { + public void run() + { + // It may be the case that the properties view has focus and the editor being closed is the last one. + // The find-and-replace target is not updated in this case. + // So set it to null to ensure that the + // + Object fieldValue = getFieldValue(dialog, F_TARGET_FIELD); + if (fieldValue == FindAndReplaceTarget.this) + { + try + { + Method method = dialog.getClass().getMethod("updateTarget", IFindReplaceTarget.class, boolean.class, boolean.class); + method.setAccessible(true); + method.invoke(dialog, null, false, false); + } + catch (Exception exception) + { + // Ignore. + } + } + disposeCleanup = null; } }; } @@ -697,6 +780,14 @@ public final class FindAndReplaceTarget implements IFindReplaceTarget, IFindRepl } } + private void dispose() + { + if (disposeCleanup != null) + { + disposeCleanup.run(); + } + } + public void endSession() { // When the session ends, we clean up or search-type control. @@ -811,7 +902,6 @@ public final class FindAndReplaceTarget implements IFindReplaceTarget, IFindRepl if (propertiesCleanup != null) { propertiesCleanup.run(); - propertiesCleanup = null; } } @@ -1227,6 +1317,7 @@ public final class FindAndReplaceTarget implements IFindReplaceTarget, IFindRepl { action.setChecked(false); action.run(); + filterChangeCleanup = null; } }; } @@ -1246,6 +1337,7 @@ public final class FindAndReplaceTarget implements IFindReplaceTarget, IFindRepl { categoriesAction.setChecked(false); categoriesAction.run(); + categoriesChangeCleanup = null; } }; } @@ -1363,6 +1455,8 @@ public final class FindAndReplaceTarget implements IFindReplaceTarget, IFindRepl // Refresh the view. propertySheetPage.refreshLabels(); + + propertiesCleanup = null; } }; |