Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCamille Letavernier2015-01-22 12:59:36 +0000
committerCamille Letavernier2015-01-22 12:59:36 +0000
commit8e0e1b8761a9790cd4c54d5d4cd2fd24c6931cfc (patch)
tree6dc05686861834c28a633c5e0c2fe87bcad28faa
parent237cb0265bc39d65635ba071d99aa220ff7bf7cc (diff)
downloadorg.eclipse.papyrus-8e0e1b8761a9790cd4c54d5d4cd2fd24c6931cfc.tar.gz
org.eclipse.papyrus-8e0e1b8761a9790cd4c54d5d4cd2fd24c6931cfc.tar.xz
org.eclipse.papyrus-8e0e1b8761a9790cd4c54d5d4cd2fd24c6931cfc.zip
457341: [Model Import] Identify and fix performances bottlenecks
https://bugs.eclipse.org/bugs/show_bug.cgi?id=457341 - Tentative fix for the Phase 2 of Model Migration - Repair Dependencies: run all repair operations in a single pass, to avoid browsing the same model multiple times
-rw-r--r--extraplugins/migration/org.eclipse.papyrus.migration.rsa/src/org/eclipse/papyrus/migration/rsa/transformation/ImportTransformationLauncher.java43
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/DependencyManagementHelper.java118
2 files changed, 140 insertions, 21 deletions
diff --git a/extraplugins/migration/org.eclipse.papyrus.migration.rsa/src/org/eclipse/papyrus/migration/rsa/transformation/ImportTransformationLauncher.java b/extraplugins/migration/org.eclipse.papyrus.migration.rsa/src/org/eclipse/papyrus/migration/rsa/transformation/ImportTransformationLauncher.java
index 5d42fd71ca8..8383df284f5 100644
--- a/extraplugins/migration/org.eclipse.papyrus.migration.rsa/src/org/eclipse/papyrus/migration/rsa/transformation/ImportTransformationLauncher.java
+++ b/extraplugins/migration/org.eclipse.papyrus.migration.rsa/src/org/eclipse/papyrus/migration/rsa/transformation/ImportTransformationLauncher.java
@@ -421,6 +421,7 @@ public class ImportTransformationLauncher {
populateURIMap(parameters.getProfileUriMappings(), profileUrisToReplace);
}
+ removeEmptyMappings(urisToReplace);
List<Schedulable> tasks = new LinkedList<Schedulable>();
for (final ImportTransformation transformation : transformations) {
@@ -449,6 +450,16 @@ public class ImportTransformationLauncher {
ownExecutionTime = end - begin - timeToIgnore;
}
+ protected void removeEmptyMappings(Map<URI, URI> urisToReplace) {
+ Iterator<Map.Entry<URI, URI>> iterator = urisToReplace.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry<URI, URI> entry = iterator.next();
+ if (entry.getKey().equals(entry.getValue())) {
+ iterator.remove();
+ }
+ }
+ }
+
final protected Map<ImportTransformation, Long> loadingTimeV2 = new HashMap<ImportTransformation, Long>();
final protected Map<ImportTransformation, Long> proxiesTime = new HashMap<ImportTransformation, Long>();
@@ -593,29 +604,19 @@ public class ImportTransformationLauncher {
final TransactionalEditingDomain domain = modelSet.getTransactionalEditingDomain();
- for (final Map.Entry<URI, URI> entry : urisToReplace.entrySet()) {
- if (monitor.isCanceled()) {
- return;
- }
+ InternalTransactionalEditingDomain internalDomain = (InternalTransactionalEditingDomain) domain;
- if (entry.getKey().equals(entry.getValue())) {
- continue;
- }
-
- InternalTransactionalEditingDomain internalDomain = (InternalTransactionalEditingDomain) domain;
+ Map<String, Object> options = new HashMap<String, Object>();
+ options.put(Transaction.OPTION_NO_UNDO, true);
+ options.put(Transaction.OPTION_NO_VALIDATION, true);
+ options.put(Transaction.OPTION_NO_TRIGGERS, true);
- Map<String, Object> options = new HashMap<String, Object>();
- options.put(Transaction.OPTION_NO_UNDO, true);
- options.put(Transaction.OPTION_NO_VALIDATION, true);
- options.put(Transaction.OPTION_NO_TRIGGERS, true);
-
- // We're in a batch environment, with no undo/redo support. Run a vanilla transaction to improve performances
- Transaction fastTransaction = internalDomain.startTransaction(false, options);
- try {
- DependencyManagementHelper.updateDependencies(entry.getKey(), entry.getValue(), resourcesToRepair, domain);
- } finally {
- fastTransaction.commit();
- }
+ // We're in a batch environment, with no undo/redo support. Run a vanilla transaction to improve performances
+ Transaction fastTransaction = internalDomain.startTransaction(false, options);
+ try {
+ DependencyManagementHelper.updateDependencies(urisToReplace, resourcesToRepair, domain);
+ } finally {
+ fastTransaction.commit();
}
}
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/DependencyManagementHelper.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/DependencyManagementHelper.java
index 2bd33a691c0..254fcf98e6e 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/DependencyManagementHelper.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/DependencyManagementHelper.java
@@ -350,4 +350,122 @@ public class DependencyManagementHelper {
return updateDependencies(uriToReplace, targetURI, resourcesToEdit, null);
}
+ /**
+ * Batch operation for replacing a set of resource URIs with another set of URIs, for a Collection of resources
+ *
+ * @param urisToReplace
+ * The mapping of Resource URIs to replace (Key = SourceURI, Value = TargetURI)
+ * @param resourcesToRepair
+ * The list of resources to edit. Only the objects of these resources will be modified.
+ * @param editingDomain
+ * The editing domain. May be null.
+ */
+ public static void updateDependencies(Map<URI, URI> urisToReplace, Collection<Resource> resourcesToRepair, EditingDomain editingDomain) {
+ for (Resource resource : resourcesToRepair) {
+ if (EMFHelper.isReadOnly(resource, editingDomain)) {
+ continue;
+ }
+
+ updateDependencies(urisToReplace, resource, editingDomain);
+ }
+ }
+
+ /**
+ * Batch operation for replacing a set of resource URIs with another set of URIs, for a single resource
+ *
+ * @param urisToReplace
+ * The mapping of Resource URIs to replace (Key = SourceURI, Value = TargetURI)
+ * @param resourcesToRepair
+ * The list of resources to edit. Only the objects of these resources will be modified.
+ * @param editingDomain
+ * The editing domain. May be null.
+ */
+ public static void updateDependencies(Map<URI, URI> urisToReplace, Resource fromResource, EditingDomain editingDomain) {
+ Iterator<EObject> allContentsIterator = fromResource.getAllContents();
+
+ while (allContentsIterator.hasNext()) {
+ EObject eObject = allContentsIterator.next();
+
+ for (EReference reference : eObject.eClass().getEAllReferences()) {
+ if (reference.isContainer() || reference.isContainment()) {
+ continue;
+ }
+
+ // Attempts to modify a changeable + derived feature (e.g. Class#general in UML)
+ // will rely in reverse-derivation algorithms, which may recreate some existing elements
+ // (Instead of modifying them). This can result in loss of information. Don't change derived values.
+ if (reference.isDerived() || !reference.isChangeable()) {
+ continue;
+ }
+
+ Object value = eObject.eGet(reference);
+ if (value instanceof EObject) {
+ EObject eObjectToReplace = (EObject) value;
+
+ EObject newEObject = checkAndReplace(eObjectToReplace, urisToReplace);
+ if (newEObject == null) {
+ continue;
+ }
+
+ try {
+ eObject.eSet(reference, newEObject);
+ } catch (Exception ex) {
+ Activator.log.error(ex);
+ }
+
+ } else if (value instanceof Collection<?>) {
+ Map<EObject, EObject> previousToNewValue = new HashMap<EObject, EObject>();
+
+ Collection<?> collection = (Collection<?>) value;
+
+ for (Object collectionElement : (Collection<?>) value) {
+ if (collectionElement instanceof EObject) {
+ EObject eObjectToReplace = (EObject) collectionElement;
+ EObject newEObject = checkAndReplace(eObjectToReplace, urisToReplace);
+ if (newEObject == null) {
+ continue;
+ }
+
+ previousToNewValue.put(eObjectToReplace, newEObject);
+ }
+ }
+
+ if (previousToNewValue.isEmpty()) {
+ continue;
+ }
+
+ if (collection instanceof EStructuralFeature.Setting) {
+ EStructuralFeature.Setting setting = (EStructuralFeature.Setting) collection;
+ for (Map.Entry<EObject, EObject> entry : previousToNewValue.entrySet()) {
+ EcoreUtil.replace(setting, entry.getKey(), entry.getValue());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Replaces the EObject (Which may be a proxy) by its equivalent in the given Resource's URI.
+ * Returns null if the "currentValueToReplace" doesn't belong to the resource represented by "urisToReplace".
+ *
+ * @param currentValueToReplace
+ * The current value, to be replaced. May be a proxy
+ * @param urisToReplace
+ * The mapping of Resource URIs to replace (Key = SourceURI, Value = TargetURI)
+ * @return
+ * The EObject equivalent to the replaced EObject, in the target resource.
+ */
+ private static EObject checkAndReplace(EObject currentValueToReplace, Map<URI, URI> urisToReplace) {
+ URI eObjectURIToReplace = EcoreUtil.getURI(currentValueToReplace);
+ URI resourceURI = eObjectURIToReplace.trimFragment();
+
+ URI targetURI = urisToReplace.get(resourceURI);
+ if (targetURI == null) {
+ return null;
+ }
+
+ return replace(currentValueToReplace, targetURI);
+ }
+
}

Back to the top