Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2014-03-27 17:25:20 -0400
committerChristian W. Damus2014-03-27 17:25:20 -0400
commit536ce430e29c6a5e4c50a01536131b50a532a366 (patch)
treeb5b178cc7a10710834b3d2e91b23aae2f5ebfbb7 /plugins
parentfc4dd812a5fd0ed7ade3f30bb0a8569bb81ec031 (diff)
downloadorg.eclipse.papyrus-536ce430e29c6a5e4c50a01536131b50a532a366.tar.gz
org.eclipse.papyrus-536ce430e29c6a5e4c50a01536131b50a532a366.tar.xz
org.eclipse.papyrus-536ce430e29c6a5e4c50a01536131b50a532a366.zip
410346: Sudden performance degradation e.g. of the Outline View update.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=410346 More fixes for undisposed ComposedAdapterFactory instances. Also fix the diagram exporter to not leak the entire model in the CacheAdapter.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/infra/org.eclipse.papyrus.infra.export/src/org/eclipse/papyrus/infra/export/ExportAllDiagrams.java149
-rw-r--r--plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.wizards/src/org/eclipse/papyrus/uml/diagram/wizards/pages/SelectRootElementPage.java19
2 files changed, 101 insertions, 67 deletions
diff --git a/plugins/infra/org.eclipse.papyrus.infra.export/src/org/eclipse/papyrus/infra/export/ExportAllDiagrams.java b/plugins/infra/org.eclipse.papyrus.infra.export/src/org/eclipse/papyrus/infra/export/ExportAllDiagrams.java
index d6758195975..7bd85f8a708 100644
--- a/plugins/infra/org.eclipse.papyrus.infra.export/src/org/eclipse/papyrus/infra/export/ExportAllDiagrams.java
+++ b/plugins/infra/org.eclipse.papyrus.infra.export/src/org/eclipse/papyrus/infra/export/ExportAllDiagrams.java
@@ -9,6 +9,7 @@
* Alexia Allanic (Atos Origin) - Add margin to not truncate images
* Anass Radouani (AtoS) - add use GMF exporting tool and remove manual extraction
* Christian W. Damus (CEA) - bug 431411
+ * Christian W. Damus (CEA) - bug 410346
*
******************************************************************************/
package org.eclipse.papyrus.infra.export;
@@ -52,8 +53,6 @@ import org.eclipse.emf.transaction.RollbackException;
import org.eclipse.emf.transaction.Transaction;
import org.eclipse.emf.transaction.TransactionalCommandStack;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
-import org.eclipse.emf.transaction.TransactionalEditingDomain.Factory;
-import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
import org.eclipse.gmf.runtime.diagram.ui.image.ImageFileFormat;
@@ -165,79 +164,93 @@ public class ExportAllDiagrams {
newMonitor.subTask(Messages.ExportAllDiagrams_2);
if(file != null) {
final ResourceSetImpl resourceSet = new ResourceSetImpl();
- resourceSet.getLoadOptions().put(XMLResource.OPTION_DEFER_IDREF_RESOLUTION, true);
- resourceSet.getLoadOptions().put(XMLResource.OPTION_DEFER_ATTACHMENT, true);
-
- // Since the *.di file is empty as of Luna, we cannot rely on it to find all diagrams by resolving cross-references
- IPapyrusFile logical = PapyrusModelHelper.getPapyrusModelFactory().createIPapyrusFile(file);
- if(logical != null) {
- for(IResource component : logical.getAssociatedResources()) {
- if(component.getType() == IResource.FILE) {
- resourceSet.getResource(URI.createPlatformResourceURI(component.getFullPath().toString(), true), true);
+ TransactionalEditingDomain editingDomain = null;
+ try {
+ resourceSet.getLoadOptions().put(XMLResource.OPTION_DEFER_IDREF_RESOLUTION, true);
+ resourceSet.getLoadOptions().put(XMLResource.OPTION_DEFER_ATTACHMENT, true);
+
+ // Since the *.di file is empty as of Luna, we cannot rely on it to find all diagrams by resolving cross-references
+ IPapyrusFile logical = PapyrusModelHelper.getPapyrusModelFactory().createIPapyrusFile(file);
+ if(logical != null) {
+ for(IResource component : logical.getAssociatedResources()) {
+ if(component.getType() == IResource.FILE) {
+ resourceSet.getResource(URI.createPlatformResourceURI(component.getFullPath().toString(), true), true);
+ }
}
}
- }
-
- // create transactional editing domain
-
- TransactionalEditingDomain editingDomain = TransactionUtil.getEditingDomain(resourceSet);
- if(editingDomain == null) {
- Factory factory = TransactionalEditingDomain.Factory.INSTANCE;
- editingDomain = factory.createEditingDomain(resourceSet);
- }
-
- AbstractTransactionalCommand com = new AbstractTransactionalCommand(editingDomain, "Resolve", Collections.emptyList()) {
-
- @Override
- protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
- EcoreUtil.resolveAll(resourceSet);
- return null;
+
+ // create transactional editing domain
+ editingDomain = TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain(resourceSet);
+
+ AbstractTransactionalCommand com = new AbstractTransactionalCommand(editingDomain, "Resolve", Collections.emptyList()) {
+
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ EcoreUtil.resolveAll(resourceSet);
+ return null;
+ }
+ };
+
+ // bypass all the transaction/validate/notification mechanisms, it is a lot faster and it has no impact
+ // since we do not modify the model
+ CommandStack commandStack = editingDomain.getCommandStack();
+ if(commandStack instanceof TransactionalCommandStack) {
+ TransactionalCommandStack stack = (TransactionalCommandStack)commandStack;
+ Map<Object, Object> options = new HashMap<Object, Object>();
+ options.put(Transaction.OPTION_NO_NOTIFICATIONS, Boolean.TRUE);
+ options.put(Transaction.OPTION_NO_UNDO, Boolean.TRUE);
+ options.put(Transaction.OPTION_UNPROTECTED, Boolean.TRUE);
+ options.put(Transaction.OPTION_IS_UNDO_REDO_TRANSACTION, Boolean.FALSE);
+ options.put(Transaction.OPTION_NO_TRIGGERS, Boolean.TRUE);
+ options.put(Transaction.OPTION_VALIDATE_EDIT, Boolean.FALSE);
+ options.put(Transaction.OPTION_VALIDATE_EDIT_CONTEXT, Boolean.FALSE);
+ try {
+ stack.execute(new GMFtoEMFCommandWrapper(com), options);
+ } catch (InterruptedException e) {
+ } catch (RollbackException e) {
+ }
+ } else {
+ Activator.log.warn("no transactional editing domain found");
}
- };
-
- // bypass all the transaction/validate/notification mechanisms, it is a lot faster and it has no impact
- // since we do not modify the model
- CommandStack commandStack = editingDomain.getCommandStack();
- if(commandStack instanceof TransactionalCommandStack) {
- TransactionalCommandStack stack = (TransactionalCommandStack)commandStack;
- Map<Object, Object> options = new HashMap<Object, Object>();
- options.put(Transaction.OPTION_NO_NOTIFICATIONS, Boolean.TRUE);
- options.put(Transaction.OPTION_NO_UNDO, Boolean.TRUE);
- options.put(Transaction.OPTION_UNPROTECTED, Boolean.TRUE);
- options.put(Transaction.OPTION_IS_UNDO_REDO_TRANSACTION, Boolean.FALSE);
- options.put(Transaction.OPTION_NO_TRIGGERS, Boolean.TRUE);
- options.put(Transaction.OPTION_VALIDATE_EDIT, Boolean.FALSE);
- options.put(Transaction.OPTION_VALIDATE_EDIT_CONTEXT, Boolean.FALSE);
- try {
- stack.execute(new GMFtoEMFCommandWrapper(com), options);
- } catch (InterruptedException e) {
- } catch (RollbackException e) {
+
+ List<Diagram> diagrams = new ArrayList<Diagram>();
+ if(newMonitor.isCanceled()) {
+ return;
}
- } else {
- Activator.log.warn("no transactional editing domain found");
- }
-
- List<Diagram> diagrams = new ArrayList<Diagram>();
- if(newMonitor.isCanceled()) {
- return;
- }
- for(Iterator<Notifier> i = resourceSet.getAllContents(); i.hasNext();) {
- Notifier n = i.next();
- if(n instanceof Diagram) {
- diagrams.add((Diagram)n);
+ for(Iterator<Notifier> i = resourceSet.getAllContents(); i.hasNext();) {
+ Notifier n = i.next();
+ if(n instanceof Diagram) {
+ diagrams.add((Diagram)n);
+ }
+ }
+ if(newMonitor.isCanceled()) {
+ return;
+ }
+ newMonitor.worked(1);
+ export(new SubProgressMonitor(newMonitor, 9), diagrams);
+ } finally {
+ // Unload the resource set so that we don't leak loads of UML content in the CacheAdapter
+ unload(resourceSet);
+ if(editingDomain != null) {
+ editingDomain.dispose();
}
}
- if(newMonitor.isCanceled()) {
- return;
- }
- newMonitor.worked(1);
- export(new SubProgressMonitor(newMonitor, 9), diagrams);
} else {
Activator.log.warn(Messages.ExportAllDiagrams_3);
}
}
+ private void unload(ResourceSet resourceSet) {
+ for (Resource next : resourceSet.getResources()) {
+ next.unload();
+ next.eAdapters().clear();
+ }
+
+ resourceSet.getResources().clear();
+ resourceSet.eAdapters().clear();
+ }
+
/**
* export all the diagrams in image
*
@@ -317,8 +330,14 @@ public class ExportAllDiagrams {
if(qualifiedName) {
ComposedAdapterFactory composedAdapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
composedAdapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory());
- IItemLabelProvider itemLabelFactory = (IItemLabelProvider)composedAdapterFactory.adapt(diagram.getElement(), IItemLabelProvider.class);
- label = itemLabelFactory.getText(diagram.getElement()).replace(Messages.ExportAllDiagrams_16, "") + "_"; //$NON-NLS-1$//$NON-NLS-2$
+
+ try {
+ IItemLabelProvider itemLabelFactory = (IItemLabelProvider)composedAdapterFactory.adapt(diagram.getElement(), IItemLabelProvider.class);
+ label = itemLabelFactory.getText(diagram.getElement()).replace(Messages.ExportAllDiagrams_16, "") + "_"; //$NON-NLS-1$//$NON-NLS-2$
+ } finally {
+ // Don't leak the adapters created by this factory
+ composedAdapterFactory.dispose();
+ }
}
String uniqueFileName = encodeFileName(label + diagram.getName());
if(uniqueFileName.length() > 150) {
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.wizards/src/org/eclipse/papyrus/uml/diagram/wizards/pages/SelectRootElementPage.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.wizards/src/org/eclipse/papyrus/uml/diagram/wizards/pages/SelectRootElementPage.java
index 540df8ed6cb..a8796595be8 100644
--- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.wizards/src/org/eclipse/papyrus/uml/diagram/wizards/pages/SelectRootElementPage.java
+++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.wizards/src/org/eclipse/papyrus/uml/diagram/wizards/pages/SelectRootElementPage.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 Obeo.
+ * Copyright (c) 2008, 2014 Obeo, CEA, 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
@@ -7,6 +7,8 @@
*
* Contributors:
* Obeo - initial API and implementation
+ * Christian W. Damus (CEA) - bug 410346
+ *
*******************************************************************************/
package org.eclipse.papyrus.uml.diagram.wizards.pages;
@@ -25,6 +27,7 @@ import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.Resource.Diagnostic;
import org.eclipse.emf.ecore.util.FeatureMap;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.edit.provider.IDisposable;
import org.eclipse.emf.edit.provider.IWrapperItemProvider;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
@@ -42,6 +45,8 @@ import org.eclipse.papyrus.infra.widgets.toolbox.notification.Type;
import org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.NotificationBuilder;
import org.eclipse.papyrus.uml.diagram.wizards.Messages;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
@@ -127,7 +132,7 @@ public class SelectRootElementPage extends WizardPage {
layoutData.heightHint = 300;
layoutData.widthHint = 300;
modelViewer.getTree().setLayoutData(layoutData);
- AdapterFactory adapterFactory = createAdapterFactory();
+ final AdapterFactory adapterFactory = createAdapterFactory();
modelViewer.setContentProvider(new AdapterFactoryContentProvider(adapterFactory));
modelViewer.setLabelProvider(new AdapterFactoryLabelProvider(adapterFactory));
@@ -143,6 +148,16 @@ public class SelectRootElementPage extends WizardPage {
}
});
+ modelViewer.getControl().addDisposeListener(new DisposeListener() {
+
+ public void widgetDisposed(DisposeEvent e) {
+ // Dispose the adapter factory that we created to avoid leaking its adapters
+ if(adapterFactory instanceof IDisposable) {
+ ((IDisposable)adapterFactory).dispose();
+ }
+ }
+ });
+
setPageComplete(validatePage());
}

Back to the top