Explorar el Código

combine UnitOfWork with Transactional Editing Domain (#2040)

* combine UnitOfWork with Transactional Editing Domain

* Added nullcheck for typesystemresource when executing the generator.
Removed synchronization from method signatur in DefaultValidationIssueStore to due workspace synchronization deadlocks.
Removed validationjob rule in LiveValidationListener to avoid sct file locks.
Andreas Mülder hace 7 años
padre
commit
bfcc67aa29

+ 7 - 3
plugins/org.yakindu.base.types/src/org/yakindu/base/types/typesystem/AbstractTypeSystem.java

@@ -59,7 +59,12 @@ public abstract class AbstractTypeSystem implements ITypeSystem {
 	protected TypeAnnotations typeAnnotations;
 
 	public AbstractTypeSystem() {
-		resource = new ResourceImpl(URI.createURI("types"));
+		resource = new ResourceImpl(URI.createURI("types")) {
+			@Override
+			protected void doUnload() {
+				// Unloading should not be performed for in memory resource
+			}
+		};
 		typeAnnotations = new TypeAnnotations();
 		initRegistries();
 	}
@@ -239,8 +244,7 @@ public abstract class AbstractTypeSystem implements ITypeSystem {
 
 		Set<Type> typehierachy1 = new LinkedHashSet<Type>();
 		collectSupertypes(type1, typehierachy1);
-		
-		
+
 		Set<Type> typehierachy2 = new LinkedHashSet<Type>();
 		collectSupertypes(type2, typehierachy2);
 

+ 11 - 7
plugins/org.yakindu.sct.generator.core/src/org/yakindu/sct/generator/core/execution/GeneratorExecutorLookup.java

@@ -11,6 +11,7 @@
 package org.yakindu.sct.generator.core.execution;
 
 import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.emf.ecore.resource.ResourceSet;
 import org.eclipse.emf.ecore.util.EcoreUtil;
 import org.yakindu.base.types.typesystem.AbstractTypeSystem;
@@ -68,14 +69,17 @@ public class GeneratorExecutorLookup {
 		}
 		if (typeSystem instanceof AbstractTypeSystem) {
 			ResourceSet set = entry.getElementRef().eResource().getResourceSet();
-			set.getResources().add(((AbstractTypeSystem) typeSystem).getResource());
+			Resource typeSystemResource = ((AbstractTypeSystem) typeSystem).getResource();
+			if (set != null && typeSystemResource != null && !set.getResources().contains(typeSystemResource)) {
+				set.getResources().add(typeSystemResource);
 
-			// XXX: avoid resolving the whole resource set, because there might
-			// be models with different domains, we have to ensure that just the
-			// models related to the current entry are resolved
-			EcoreUtil.resolveAll(entry);
-			EcoreUtil.resolveAll(entry.getElementRef());
-			EcoreUtil.resolveAll(((AbstractTypeSystem) typeSystem).getResource());
+				// XXX: avoid resolving the whole resource set, because there might
+				// be models with different domains, we have to ensure that just the
+				// models related to the current entry are resolved
+				EcoreUtil.resolveAll(entry);
+				EcoreUtil.resolveAll(entry.getElementRef());
+				EcoreUtil.resolveAll(typeSystemResource);
+			}
 		}
 
 		return executor;

+ 3 - 2
plugins/org.yakindu.sct.model.stext.ui/src/org/yakindu/sct/model/stext/ui/STextUiModule.java

@@ -35,10 +35,10 @@ import org.eclipse.xtext.ui.shared.Access;
 import org.eclipse.xtext.ui.tasks.TaskMarkerCreator;
 import org.eclipse.xtext.ui.tasks.TaskMarkerTypeProvider;
 import org.yakindu.base.utils.jface.help.CrossRefObjectTextHover;
-import org.yakindu.base.xtext.utils.jface.viewers.ParallelReadXtextDocument;
 import org.yakindu.sct.model.stext.ui.contentassist.AsyncContentAssistContextFactory;
 import org.yakindu.sct.model.stext.ui.contentassist.AsyncXtextContentAssistProcessor;
 import org.yakindu.sct.model.stext.ui.contentassist.STextStatefulFactory;
+import org.yakindu.sct.model.stext.ui.document.TransactionalXtextDocument;
 import org.yakindu.sct.model.stext.ui.help.CustomCSSHelpHoverProvider;
 import org.yakindu.sct.model.stext.ui.help.STextUserHelpDocumentationProvider;
 import org.yakindu.sct.model.stext.ui.highlighting.SCTHighlightingConfiguration;
@@ -87,7 +87,8 @@ public class STextUiModule extends org.yakindu.sct.model.stext.ui.AbstractSTextU
 	public void configure(Binder binder) {
 		super.configure(binder);
 		binder.bind(String.class).annotatedWith(Names.named("stylesheet")).toInstance("/StextHoverStyleSheet.css");
-		binder.bind(XtextDocument.class).to(ParallelReadXtextDocument.class);
+		binder.bind(String.class).annotatedWith(Names.named("domain.id")).toInstance("org.yakindu.sct.domain");
+		binder.bind(XtextDocument.class).to(TransactionalXtextDocument.class);
 		binder.bind(TaskMarkerCreator.class).to(SCTTaskMarkerCreator.class);
 		binder.bind(TaskMarkerTypeProvider.class).to(SCTTaskMarkerTypeProvider.class);
 	}

+ 85 - 0
plugins/org.yakindu.sct.model.stext.ui/src/org/yakindu/sct/model/stext/ui/document/TransactionalXtextDocument.java

@@ -0,0 +1,85 @@
+/** 
+ * Copyright (c) 2018 committers of YAKINDU 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:
+ * committers of YAKINDU - initial API and implementation
+ *
+*/
+package org.yakindu.sct.model.stext.ui.document;
+
+import org.eclipse.emf.transaction.RunnableWithResult;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.ui.editor.model.DocumentTokenSource;
+import org.eclipse.xtext.ui.editor.model.edit.ITextEditComposer;
+import org.eclipse.xtext.util.concurrent.IUnitOfWork;
+import org.yakindu.base.xtext.utils.jface.viewers.ParallelReadXtextDocument;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+@SuppressWarnings("unchecked")
+public class TransactionalXtextDocument extends ParallelReadXtextDocument {
+
+	@Inject
+	@Named("domain.id")
+	protected String domainId;
+
+	@Inject
+	public TransactionalXtextDocument(DocumentTokenSource tokenSource, ITextEditComposer composer) {
+		super(tokenSource, composer);
+	}
+
+	protected TransactionalEditingDomain getDomain() {
+		return TransactionalEditingDomain.Registry.INSTANCE.getEditingDomain(domainId);
+	}
+
+	@Override
+	public <T> T readOnly(IUnitOfWork<T, XtextResource> work) {
+		try {
+			return (T) getDomain().runExclusive(new RunnableWithResult.Impl<T>() {
+				@Override
+				public void run() {
+					setResult(TransactionalXtextDocument.super.readOnly(work));
+				}
+			});
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+	@Override
+	public <T> T priorityReadOnly(IUnitOfWork<T, XtextResource> work) {
+		try {
+			return (T) getDomain().runExclusive(new RunnableWithResult.Impl<T>() {
+				@Override
+				public void run() {
+					setResult(TransactionalXtextDocument.super.priorityReadOnly(work));
+				}
+			});
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+	@Override
+	public <T> T modify(IUnitOfWork<T, XtextResource> work) {
+		try {
+			return (T) getDomain().runExclusive(new RunnableWithResult.Impl<T>() {
+				@Override
+				public void run() {
+					setResult(TransactionalXtextDocument.super.modify(work));
+				}
+			});
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+}

+ 20 - 32
plugins/org.yakindu.sct.model.stext/src/org/yakindu/sct/model/stext/scoping/ImportedResourceCache.java

@@ -15,7 +15,6 @@ import java.util.Optional;
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.emf.transaction.RunnableWithResult;
 import org.eclipse.emf.transaction.TransactionalEditingDomain;
 import org.eclipse.emf.workspace.WorkspaceEditingDomainFactory;
 import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
@@ -56,41 +55,30 @@ public class ImportedResourceCache {
 	}
 
 	public IResourceDescription get(final URI uri) {
-		try {
-			return (IResourceDescription) getEditingDomain()
-					.runExclusive(new RunnableWithResult.Impl<IResourceDescription>() {
+
+		final ResourceSet set = getResourceSet();
+		final Resource resource = set.getResource(uri, true);
+		if (resource != null) {
+			Optional<IResourceDescription> optional = cache.get(ImportedResourceCache.class, resource,
+					new Provider<Optional<IResourceDescription>>() {
 						@Override
-						public void run() {
-							final ResourceSet set = getResourceSet();
-							final Resource resource = set.getResource(uri, true);
-							if (resource != null) {
-								Optional<IResourceDescription> optional = cache.get(ImportedResourceCache.class,
-										resource, new Provider<Optional<IResourceDescription>>() {
-											@Override
-											public Optional<IResourceDescription> get() {
-												IResourceServiceProvider serviceProvider = serviceProviderRegistry
-														.getResourceServiceProvider(uri);
-												if (serviceProvider == null)
-													return Optional.empty();
-												final Manager resourceDescriptionManager = serviceProvider
-														.getResourceDescriptionManager();
-												if (resourceDescriptionManager == null)
-													return Optional.empty();
-												IResourceDescription result = resourceDescriptionManager
-														.getResourceDescription(resource);
-												return Optional.of(result);
-											}
-										});
-								if (optional.isPresent()) {
-									setResult(optional.get());
-								}
-							}
+						public Optional<IResourceDescription> get() {
+							IResourceServiceProvider serviceProvider = serviceProviderRegistry
+									.getResourceServiceProvider(uri);
+							if (serviceProvider == null)
+								return Optional.empty();
+							final Manager resourceDescriptionManager = serviceProvider.getResourceDescriptionManager();
+							if (resourceDescriptionManager == null)
+								return Optional.empty();
+							IResourceDescription result = resourceDescriptionManager.getResourceDescription(resource);
+							return Optional.of(result);
 						}
 					});
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-			return null;
+			if (optional.isPresent()) {
+				return optional.get();
+			}
 		}
+		return null;
 	}
 
 	protected ResourceSet getResourceSet() {

+ 3 - 3
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/validation/DefaultValidationIssueStore.java

@@ -120,7 +120,7 @@ public class DefaultValidationIssueStore implements IValidationIssueStore, IReso
 		initFromPersistentMarkers();
 	}
 
-	protected synchronized void initFromPersistentMarkers() {
+	protected void initFromPersistentMarkers() {
 		Multimap<String, SCTIssue> newVisibleIssues = ArrayListMultimap.create();
 		List<IMarker> markers = getMarkersOfConnectedResource();
 		for (IMarker iMarker : markers) {
@@ -165,7 +165,7 @@ public class DefaultValidationIssueStore implements IValidationIssueStore, IReso
 	}
 
 	@Override
-	public synchronized void processIssues(List<Issue> issues, IProgressMonitor monitor) {
+	public void processIssues(List<Issue> issues, IProgressMonitor monitor) {
 
 		final Multimap<String, SCTIssue> newVisibleIssues = ArrayListMultimap.create();
 		for (Issue issue : issues) {
@@ -231,7 +231,7 @@ public class DefaultValidationIssueStore implements IValidationIssueStore, IReso
 	}
 
 	@Override
-	public synchronized List<SCTIssue> getIssues(String uri) {
+	public List<SCTIssue> getIssues(String uri) {
 		List<SCTIssue> result = Lists.newArrayList();
 		synchronized (visibleIssues) {
 			Iterables.addAll(result, visibleIssues.get(uri));

+ 0 - 2
plugins/org.yakindu.sct.ui.editor/src/org/yakindu/sct/ui/editor/validation/LiveValidationListener.java

@@ -16,7 +16,6 @@ import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.emf.transaction.ResourceSetChangeEvent;
 import org.eclipse.emf.transaction.ResourceSetListenerImpl;
-import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
 import org.eclipse.xtext.ui.editor.validation.IValidationIssueProcessor;
 import org.yakindu.sct.model.sgraph.SGraphPackage;
 import org.yakindu.sct.ui.editor.DiagramActivator;
@@ -82,7 +81,6 @@ public class LiveValidationListener extends ResourceSetListenerImpl {
 	public void setResource(Resource resource) {
 		this.resource = resource;
 		validationJob.setResource(resource);
-		validationJob.setRule(WorkspaceSynchronizer.getFile(resource));
 	}
 
 	public void setValidationIssueProcessor(IValidationIssueProcessor validationIssueProcessor) {