diff options
author | Camille Letavernier | 2015-01-22 12:59:36 +0000 |
---|---|---|
committer | Camille Letavernier | 2015-01-22 12:59:36 +0000 |
commit | 8e0e1b8761a9790cd4c54d5d4cd2fd24c6931cfc (patch) | |
tree | 6dc05686861834c28a633c5e0c2fe87bcad28faa | |
parent | 237cb0265bc39d65635ba071d99aa220ff7bf7cc (diff) | |
download | org.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
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); + } + } |