diff options
Diffstat (limited to 'rba.tool.editor.ui/src/rba/tool')
54 files changed, 3618 insertions, 0 deletions
diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/RBAModelUiModule.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/RBAModelUiModule.xtend new file mode 100644 index 0000000..5458f5d --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/RBAModelUiModule.xtend @@ -0,0 +1,101 @@ +/* + * generated by Xtext 2.12.0 + */ +package rba.tool.editor.ui + +import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor +import org.eclipse.xtext.ui.editor.IURIEditorOpener +import org.eclipse.xtext.ui.editor.contentassist.FQNPrefixMatcher.LastSegmentFinder +import org.eclipse.xtext.ui.editor.syntaxcoloring.AbstractAntlrTokenToAttributeIdMapper +import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightingConfiguration +import org.eclipse.xtext.ui.editor.validation.MarkerCreator +import org.eclipse.xtext.ui.validation.DefaultResourceUIValidatorExtension +import rba.tool.editor.resource.IRBAModelResourceLoader +import rba.tool.editor.ui.builder.RBAModelBuilderParticipant +import rba.tool.editor.ui.builder.resourceloader.RBAModelResourceLoader +import rba.tool.editor.ui.contentassist.RBAModelExpressionScopeCreator +import rba.tool.editor.ui.contentassist.RBAModelLastSegmentFinder +import rba.tool.editor.ui.editor.model.edit.refactoring.RBAModelRenameRefactoringController +import rba.tool.editor.ui.editor.model.edit.refactoring.RBAModelSyncUtil +import rba.tool.editor.ui.editor.templates.RBAModelTemplateRegistry +import rba.tool.editor.ui.editor.templates.RBAModelTemplateStore +import rba.tool.editor.ui.editor.templates.TemplateRegistry +import rba.tool.editor.ui.marker.RBAModelMarkerCreator +import rba.tool.editor.ui.marker.RBAModelResourceUIValidatorExtension +import rba.tool.editor.ui.opener.RBAModelURIEditorOpener +import rba.tool.editor.ui.resource.RBADocumentResourceSetProvider +import rba.tool.editor.ui.resource.RBAModelResourceSetProvider +import rba.tool.editor.ui.syntaxcoloring.RBAModelAntlrTokenToAttributeIdMapper +import rba.tool.editor.ui.syntaxcoloring.RBAModelHighlightingConfiguration +import rba.tool.editor.ui.wizard.ExtendRBAModelProjectCreator + +/** + * Use this class to register components to be used within the Eclipse IDE. + */ +@FinalFieldsConstructor +class RBAModelUiModule extends AbstractRBAModelUiModule { + + def public Class<? extends IHighlightingConfiguration> bindILexicalHighlightingConfiguration() { + return RBAModelHighlightingConfiguration; + } + + def Class<? extends AbstractAntlrTokenToAttributeIdMapper> bindAbstractAntlrTokenToAttributeIdMapper() { + return RBAModelAntlrTokenToAttributeIdMapper; + } + + def public Class<? extends RBAModelRenameRefactoringController> bindRenameRefactoringController() { + return RBAModelRenameRefactoringController; + } + + override bindIProjectCreator() { + return ExtendRBAModelProjectCreator; + } + + override bindIXtextBuilderParticipant() { + return RBAModelBuilderParticipant; + } + + override bindIResourceSetProvider() { + return RBADocumentResourceSetProvider; + } + + def public Class<? extends RBAModelResourceSetProvider> bindRBAModelResourceSetProvider() { + return RBAModelResourceSetProvider; + } + + def public Class<? extends RBAModelSyncUtil> bindRBAModelSyncUtil() { + return RBAModelSyncUtil; + } + + def public Class<? extends LastSegmentFinder> bindILastSegmentFinder() { + return RBAModelLastSegmentFinder; + } + + def public Class<? extends RBAModelExpressionScopeCreator> bindRBAModelExpressionScopeCreator() { + return RBAModelExpressionScopeCreator; + } + + def public Class<? extends TemplateRegistry> bindTemplateRegistry() { + return RBAModelTemplateRegistry; + } + + override bindTemplateStore() { + return RBAModelTemplateStore; + } + + def public Class<? extends IRBAModelResourceLoader> bindIRBAModelResourceLoader() { + return RBAModelResourceLoader; + } + + def public Class<? extends DefaultResourceUIValidatorExtension> bindDefaultResourceUIValidatorExtension() { + return RBAModelResourceUIValidatorExtension; + } + + def public Class<? extends MarkerCreator> bindMarkerCreator() { + return RBAModelMarkerCreator + } + + def public Class<? extends IURIEditorOpener> bindIURIEditorOpener() { + return RBAModelURIEditorOpener + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/activator/ExtensionEditorActivator.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/activator/ExtensionEditorActivator.xtend new file mode 100644 index 0000000..aa974ca --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/activator/ExtensionEditorActivator.xtend @@ -0,0 +1,41 @@ +package rba.tool.editor.ui.activator + +import com.google.inject.Guice +import com.google.inject.Module +import org.apache.log4j.Logger +import org.eclipse.xtext.util.Modules2 +import rba.tool.editor.ui.internal.EditorActivator +import rba.tool.editor.util.ExtensionModuleManager + +class ExtensionEditorActivator extends EditorActivator { + + private static final Logger logger = Logger.getLogger(ExtensionEditorActivator); + + override createInjector(String language) { + try { + val runtimeModule = getRuntimeModule(language); + val sharedStateModule = getSharedStateModule(); + val uiModule = getUiModule(language); + val extensionModule = getExtensionModule(); + val mergedModule = Modules2.mixin(runtimeModule, sharedStateModule, uiModule, extensionModule); + return Guice.createInjector(mergedModule); + } catch(Exception e) { + logger.error("Failed to create injector for " + language); + logger.error(e.getMessage(), e); + throw new RuntimeException("Failed to create injector for " + language, e); + } + } + + def public static ExtensionEditorActivator getInstance() { + return EditorActivator.getInstance() as ExtensionEditorActivator; + } + + def public injectMembers(Object object) { + getInjector(EditorActivator.RBA_TOOL_EDITOR_RBAMODEL).injectMembers(object); + } + + def protected Module getExtensionModule() { + val modules = ExtensionModuleManager.INSTANCE.getExtensionModules(); + return Modules2.mixin(modules); + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/builder/RBAModelBuilderParticipant.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/builder/RBAModelBuilderParticipant.xtend new file mode 100644 index 0000000..e146f43 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/builder/RBAModelBuilderParticipant.xtend @@ -0,0 +1,253 @@ +package rba.tool.editor.ui.builder + +import com.google.common.base.Function +import com.google.inject.Inject +import com.google.inject.Provider +import java.util.ArrayList +import java.util.List +import java.util.Map +import java.util.Set +import java.util.concurrent.atomic.AtomicInteger +import org.eclipse.core.resources.IMarker +import org.eclipse.core.runtime.CoreException +import org.eclipse.core.runtime.IProgressMonitor +import org.eclipse.core.runtime.NullProgressMonitor +import org.eclipse.core.runtime.OperationCanceledException +import org.eclipse.core.runtime.SubMonitor +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.ecore.resource.ResourceSet +import org.eclipse.xtext.builder.BuilderParticipant +import org.eclipse.xtext.builder.EclipseResourceFileSystemAccess2 +import org.eclipse.xtext.builder.IXtextBuilderParticipant.IBuildContext +import org.eclipse.xtext.builder.MonitorBasedCancelIndicator +import org.eclipse.xtext.builder.builderState.IMarkerUpdater +import org.eclipse.xtext.generator.GeneratorContext +import org.eclipse.xtext.generator.IFileSystemAccess +import org.eclipse.xtext.generator.OutputConfiguration +import org.eclipse.xtext.resource.IResourceDescription.Delta +import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionDelta +import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider +import org.eclipse.xtext.util.internal.Stopwatches +import org.eclipse.xtext.xbase.lib.util.ReflectExtensions +import rba.core.Tag +import rba.tool.editor.generator.RBAModelGeneratorDelegate +import rba.tool.editor.ui.editor.model.manager.ResourceManagerUI +import rba.tool.editor.ui.resource.RBAModelResourceSetProvider + +import static com.google.common.collect.Maps.uniqueIndex + +class RBAModelBuilderParticipant extends BuilderParticipant { + + @Inject extension ReflectExtensions + + @Inject private ResourceDescriptionsProvider resourceDescriptionsProvider; + + @Inject private Provider<EclipseResourceFileSystemAccess2> fileSystemAccessProvider; + + @Inject private RBAModelGeneratorDelegate generatorDelegate; + + @Inject private RBAModelResourceSetProvider resourceSetProvider; + + @Inject private IMarkerUpdater markerUpdater; + + override build(IBuildContext context, IProgressMonitor monitor) throws CoreException { + if(!isEnabled(context)) { + return; + } + val deltas = getRelevantDeltas(context); + if(deltas.isEmpty()) { + return; + } + + val task = Stopwatches.forTask("org.eclipse.xtext.builder.BuilderParticipant.build(IBuildContext, IProgressMonitor)"); + try { + task.start(); + + val builtProject = context.getBuiltProject(); + if(!ResourceManagerUI.INSTANCE.isCurrentProject(builtProject)) { + return; + } + + // monitor handling + if(monitor.isCanceled()) { + throw new OperationCanceledException(); + } + val subMonitor = SubMonitor.convert(monitor, if(context.getBuildType() == BuildType.RECOVERY) 5 else 3); + val access = fileSystemAccessProvider.get(); + access.setProject(builtProject); + val outputConfigurations = getOutputConfigurations(context); + refreshOutputFolders(context, outputConfigurations, subMonitor.newChild(1)); + if(subMonitor.isCanceled()) { + throw new OperationCanceledException(); + } + access.setOutputConfigurations(outputConfigurations); + if(context.getBuildType() == BuildType.CLEAN || context.getBuildType() == BuildType.RECOVERY) { + val cleanMonitor = SubMonitor.convert(subMonitor.newChild(2), outputConfigurations.size()); + for (config : outputConfigurations.values()) { + cleanOutput(context, config, access, cleanMonitor.newChild(1)); + } + if(context.getBuildType() == BuildType.CLEAN) + return; + } + val generatorMarkers = getGeneratorMarkers(builtProject, outputConfigurations.values()); + if(subMonitor.isCanceled()) { + throw new OperationCanceledException(); + } + + doBuild(deltas, outputConfigurations, generatorMarkers, context, access, subMonitor.newChild(2)); + } finally { + task.stop(); + } + } + + override protected getOutputConfigurations(IBuildContext context) { + val Set<OutputConfiguration> configurations = outputConfigurationProvider.getOutputConfigurations(context.getBuiltProject()); + configurations.addAll(generatorDelegate.RBAModelGeneratorOutputConfigurations); + return uniqueIndex(configurations, new Function<OutputConfiguration, String>() { + override apply(OutputConfiguration from) { + return from.getName(); + } + }); + } + + override protected doBuild(List<Delta> deltas, Map<String, OutputConfiguration> outputConfigurations, Map<OutputConfiguration, Iterable<IMarker>> generatorMarkers, IBuildContext context, + EclipseResourceFileSystemAccess2 access, IProgressMonitor progressMonitor) throws CoreException { + if(generatorDelegate !== null) { + generatorDelegate.setRBAModelInBuilding(false); + super.doBuild(deltas, outputConfigurations, generatorMarkers, context, access, progressMonitor) + } + } + + override protected doGenerate(Delta delta, IBuildContext context, IFileSystemAccess access) { + if(delta.getNew() !== null) { + try { + handleChangedContents(delta, context, access); + } catch(OperationCanceledException e) { + throw e; + } catch(Exception e) { + addMarkerAndLogError(delta.getUri(), e); + } + return true; + } else { + try { + handleDeletedContents(delta, context, access); + } catch(OperationCanceledException e) { + throw e; + } catch(Exception e) { + // do nothing + } + return true; + } + } + + def protected void handleDeletedContents(Delta delta, IBuildContext context, IFileSystemAccess access) throws CoreException { + handleDeletedContents(delta, context, access as EclipseResourceFileSystemAccess2); + } + + override protected handleChangedContents(Delta delta, IBuildContext context, EclipseResourceFileSystemAccess2 fileSystemAccess) throws CoreException { + if(generatorDelegate.isRBAModelInBuilding()) + return; + val URI uri = delta.getUri(); + if(!getResourceServiceProvider().canHandle(uri)) + return; + var resourceSet = context.getResourceSet(); + val resource = resourceSet.getResource(uri, true); + registerCurrentSourceFolder(context, delta, fileSystemAccess); + saveResourceStorage(resource, fileSystemAccess); + demandGetResources(uri, resourceSet); + if(shouldGenerate(resourceSet, context)) { + try { + val monitor = fileSystemAccess.invoke("getMonitor") ?: new NullProgressMonitor(); + val cancelIndicator = new MonitorBasedCancelIndicator(monitor as IProgressMonitor); + val generatorContext = new GeneratorContext(); + generatorContext.setCancelIndicator(cancelIndicator); + generatorDelegate.generate(resourceSet, fileSystemAccess, generatorContext); + } catch(OperationCanceledException e) { + // don't look into the cause for OCE + throw e; + } catch(RuntimeException e) { + if(e.getCause() instanceof CoreException) { + throw e.getCause() as CoreException; + } + throw e; + } + } + } + + def protected boolean shouldGenerate(ResourceSet resourceSet, IBuildContext context) { + for (resource : resourceSet.resources) { + if(!super.shouldGenerate(resource, context)) { + return false; + } + } + return true; + } + + def protected void handleDeletedContents(Delta delta, IBuildContext context, EclipseResourceFileSystemAccess2 fileSystemAccess) throws CoreException { + if(generatorDelegate.isRBAModelInBuilding()) + return; + val URI uri = delta.getUri(); + if(!getResourceServiceProvider().canHandle(uri)) + return; + val resourceSet = context.getResourceSet(); + demandGetResources(uri, resourceSet); + if(shouldGenerate(resourceSet, context)) { + try { + val monitor = fileSystemAccess.invoke("getMonitor") ?: new NullProgressMonitor(); + val cancelIndicator = new MonitorBasedCancelIndicator(monitor as IProgressMonitor); + val generatorContext = new GeneratorContext(); + generatorContext.setCancelIndicator(cancelIndicator); + generatorDelegate.generate(resourceSet, fileSystemAccess, generatorContext); + } catch(OperationCanceledException e) { + // don't look into the cause for OCE + throw e; + } catch(RuntimeException e) { + if(e.getCause() instanceof CoreException) { + throw e.getCause() as CoreException; + } + throw e; + } + } + } + + @Deprecated + override getGenerator() { + return generatorDelegate; + } + + override getGenerator2() { + return generatorDelegate; + } + + def private demandGetResources(URI uri, ResourceSet resourceSet) { + val projectName = if(uri.segmentCount > 2) URI.decode(uri.segment(1)) else ""; + val resourceDescriptions = resourceDescriptionsProvider.createResourceDescriptions(); + val URIs = resourceDescriptions.allResourceDescriptions.map(d|d.URI).filter(u|projectName.equals(if(u.segmentCount > 2) URI.decode(u.segment(1)) else null)); + ResourceManagerUI.INSTANCE.loadAndResolveResource(resourceSet, URIs, ResourceManagerUI.INSTANCE.currentProject); + resourceSet.reloadAllStereotypes; + for (description : resourceDescriptions.allResourceDescriptions) { + if(projectName.equals(if(description.URI.segmentCount > 2) URI.decode(description.URI.segment(1)) else null)) { + markerUpdater.updateMarkers(new DefaultResourceDescriptionDelta(null, description), resourceSet, new NullProgressMonitor()); + } + } + } + + def private reloadAllStereotypes(ResourceSet resourceSet) { + val appliedCounter = new AtomicInteger(0); + val List<URI> URIs = new ArrayList<URI>(); + resourceSet.resources.forEach [ resource | + val tags = resource.allContents.toIterable.filter(Tag); + if(tags.empty) { + URIs.add(URI.createURI(resource.URI.toString)); + } else { + appliedCounter.incrementAndGet; + URIs.add(URI.createURI(resource.URI.toString.replace("/model/", "/.applied/"))); + } + ] + if(appliedCounter.get == 0) + return; + + resourceSet.clearResourceSet; + ResourceManagerUI.INSTANCE.loadAndResolveResource(resourceSet, URIs, ResourceManagerUI.INSTANCE.currentProject); + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/builder/resourceloader/RBAModelResourceLoader.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/builder/resourceloader/RBAModelResourceLoader.xtend new file mode 100644 index 0000000..74010b7 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/builder/resourceloader/RBAModelResourceLoader.xtend @@ -0,0 +1,183 @@ +package rba.tool.editor.ui.builder.resourceloader + +import com.google.common.collect.Iterators +import com.google.inject.Inject +import java.util.AbstractQueue +import java.util.HashSet +import java.util.LinkedList +import java.util.Queue +import java.util.Set +import org.eclipse.core.resources.IProject +import org.eclipse.core.runtime.NullProgressMonitor +import org.eclipse.core.runtime.SubMonitor +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.common.util.WrappedException +import org.eclipse.emf.ecore.resource.Resource +import org.eclipse.emf.ecore.resource.ResourceSet +import org.eclipse.emf.ecore.util.EcoreUtil +import org.eclipse.xtext.EcoreUtil2 +import org.eclipse.xtext.builder.builderState.IBuilderState +import org.eclipse.xtext.builder.impl.QueuedBuildData +import org.eclipse.xtext.builder.impl.ToBeBuiltComputer +import org.eclipse.xtext.builder.resourceloader.IResourceLoader +import org.eclipse.xtext.builder.resourceloader.IResourceLoader.LoadOperation +import org.eclipse.xtext.builder.resourceloader.IResourceLoader.LoadResult +import org.eclipse.xtext.builder.resourceloader.IResourceLoader.Sorter +import org.eclipse.xtext.builder.resourceloader.SerialResourceLoader +import org.eclipse.xtext.ui.resource.IResourceSetProvider +import org.eclipse.xtext.util.CancelIndicator +import rba.tool.editor.resource.IRBAModelResourceLoader +import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider +import org.eclipse.xtext.builder.impl.BuildData + +class RBAModelResourceLoader implements IRBAModelResourceLoader { + + @Inject + private ToBeBuiltComputer toBeBuiltComputer; + + @Inject + private QueuedBuildData queuedBuildData; + + @Inject + private IBuilderState builderState; + + @Inject + private IResourceSetProvider resourceSetProvider; + + @Inject + private Sorter resourceSorter; + + private IResourceLoader globalIndexResourceLoader; + + private IResourceLoader crossLinkingResourceLoader; + + public new() { + } + + override synchronized loadAndResolveResource(ResourceSet resourceSet, URI[] URIs, IProject project) { + globalIndexResourceLoader = new SerialResourceLoader(resourceSetProvider, resourceSorter); + crossLinkingResourceLoader = new SerialResourceLoader(resourceSetProvider, resourceSorter); + loadResource(resourceSet, project, URIs); + crossLinkingResource(resourceSet, project, URIs); + EcoreUtil.resolveAll(resourceSet); + + resourceSet.getLoadOptions().put(ResourceDescriptionsProvider.NAMED_BUILDER_SCOPE, Boolean.TRUE); + val progress = SubMonitor.convert(new NullProgressMonitor, 3); + val toBeBuilt = toBeBuiltComputer.updateProject(project, progress.newChild(2)); + val buildData = new BuildData(project.getName(), resourceSet, toBeBuilt, queuedBuildData, false); + builderState.update(buildData, progress.newChild(1)); + } + + def synchronized protected void loadResource(ResourceSet resourceSet, IProject project, URI[] URIs) { + val Set<URI> toBeUpdated = new HashSet<URI>(URIs); + var LoadOperation loadOperation = null; + + try { + loadOperation = globalIndexResourceLoader.create(resourceSet, project); + loadOperation.load(toBeUpdated); + + while(loadOperation.hasNext()) { + var URI uri = null; + var Resource resource = null; + try { + val LoadResult loadResult = loadOperation.next(); + uri = loadResult.getUri(); + resource = addResource(loadResult.getResource(), resourceSet); + } catch(RuntimeException ex) { + if(resource !== null) { + resourceSet.getResources().remove(resource); + } + } + } + } finally { + if(loadOperation !== null) loadOperation.cancel(); + } + } + + def synchronized protected void crossLinkingResource(ResourceSet resourceSet, IProject project, URI[] URIs) { + val Queue<URI> queue = getQueue(URIs); + var LoadOperation loadOperation = null; + + try { + loadOperation = crossLinkingResourceLoader.create(resourceSet, project); + loadOperation.load(queue); + while(!queue.isEmpty()) { + var URI uri = null; + var Resource resource = null; + try { + val LoadResult loadResult = loadOperation.next(); + uri = loadResult.getUri(); + resource = addResource(loadResult.getResource(), resourceSet); + queue.remove(uri); + EcoreUtil2.resolveLazyCrossReferences(resource, CancelIndicator.NullImpl); + } catch(WrappedException ex) { + if(resource !== null) { + resourceSet.getResources().remove(resource); + } + } + } + + loadOperation.cancel(); + if(queue.size() > 0) { + loadOperation = crossLinkingResourceLoader.create(resourceSet, project); + loadOperation.load(queue); + } + + if(!queue.isEmpty()) { + // clearResourceSet(resourceSet); + } + } finally { + if(loadOperation !== null) loadOperation.cancel(); + } + } + + def protected void clearResourceSet(ResourceSet resourceSet) { + val boolean wasDeliver = resourceSet.eDeliver(); + try { + resourceSet.eSetDeliver(false); + resourceSet.getResources().clear(); + } finally { + resourceSet.eSetDeliver(wasDeliver); + } + } + + def protected Resource addResource(Resource resource, ResourceSet resourceSet) { + val URI uri = resource.getURI(); + val Resource r = resourceSet.getResource(uri, false); + if(r === null) { + resourceSet.getResources().add(resource); + return resource; + } else { + return r; + } + } + + def protected Queue<URI> getQueue(URI[] URIs) { + val LinkedList<URI> list = new LinkedList<URI>(URIs); + return new AbstractQueue<URI>() { + override offer(URI o) { + return list.offer(o); + } + + override poll() { + if(list.isEmpty()) + return list.poll(); + return list.poll(); + } + + override peek() { + if(list.isEmpty()) + return list.peek(); + return list.peek(); + } + + override iterator() { + return Iterators.concat(list.iterator(), list.iterator()); + } + + override size() { + return list.size() + list.size(); + } + }; + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/contentassist/RBAModelExpressionScopeCreator.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/contentassist/RBAModelExpressionScopeCreator.xtend new file mode 100644 index 0000000..16d8122 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/contentassist/RBAModelExpressionScopeCreator.xtend @@ -0,0 +1,74 @@ +package rba.tool.editor.ui.contentassist + +import com.google.inject.Inject +import java.util.List +import org.apache.commons.lang.StringUtils +import org.eclipse.emf.ecore.EObject +import org.eclipse.xtext.EcoreUtil2 +import org.eclipse.xtext.Keyword +import org.eclipse.xtext.nodemodel.INode +import org.eclipse.xtext.nodemodel.util.NodeModelUtils +import org.eclipse.xtext.scoping.IScope +import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext +import rba.core.Constraint +import rba.core.ObjectReference +import rba.core.Operator +import rba.core.PreviousModifier +import rba.tool.editor.rbaEditorModel.MemberFeatureReference +import rba.tool.editor.scoping.IExpressionScope + +class RBAModelExpressionScopeCreator { + + @Inject(optional=true) IExpressionScope expressionScope; + + def public IScope getExpressionScope(EObject model, ContentAssistContext contentAssistContext) { + if (contentAssistContext.lastCompleteNode !== null) { + val EObject grammarElement = contentAssistContext.lastCompleteNode.grammarElement; + if (grammarElement instanceof Keyword && ".".equals((grammarElement as Keyword).value)) { + val INode lastCompleteNodeParent = contentAssistContext.lastCompleteNode.parent; + val semanticObject = NodeModelUtils.findActualSemanticObjectFor(lastCompleteNodeParent); + val boolean inner = isInnerPrefix(lastCompleteNodeParent.text, contentAssistContext.offset, lastCompleteNodeParent.endOffset); + val EObject eObject = getTargetObject(semanticObject, inner); + return expressionScope.getFeatureScope(eObject, getOwnerAnchorType(model)); + } + } + return null; + } + + def private EObject getTargetObject(EObject eObject, boolean inner) { + if (eObject instanceof Operator) { + return eObject; + } + + var ObjectReference objectReference; + if (eObject instanceof MemberFeatureReference) { + val MemberFeatureReference reference = eObject as MemberFeatureReference; + objectReference = ( if (reference.refObject === null) reference.operand.get(0) else reference) as ObjectReference; + } else if (eObject instanceof ObjectReference) { + objectReference = eObject; + } else if (eObject instanceof PreviousModifier) { + val List<ObjectReference> objectReferences = EcoreUtil2.getAllContentsOfType(eObject, ObjectReference); + objectReference = if (objectReferences.size > 0) objectReferences.last else null; + } + + if (inner && objectReference instanceof MemberFeatureReference) { + val operand0 = (objectReference as MemberFeatureReference).operand.get(0); + objectReference = if(operand0 instanceof ObjectReference) operand0 as ObjectReference else null; + } + return if (objectReference !== null) objectReference.refObject else null; + } + + def private boolean isInnerPrefix(String text, int offset, int endOffset) { + val boolean isInnerOffset = offset <= endOffset; + val boolean isInnerPrefix = !StringUtils.endsWith(text, "."); + return (isInnerOffset && isInnerPrefix); + } + + def private IExpressionScope.Anchor getOwnerAnchorType(EObject model) { + var EObject owner = EcoreUtil2.getContainerOfType(model, Constraint); + if (owner !== null) { + return IExpressionScope.Anchor.CONSTRAINT; + } + return IExpressionScope.Anchor.UNKNOWN; + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/contentassist/RBAModelLastSegmentFinder.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/contentassist/RBAModelLastSegmentFinder.xtend new file mode 100644 index 0000000..e844018 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/contentassist/RBAModelLastSegmentFinder.xtend @@ -0,0 +1,31 @@ +package rba.tool.editor.ui.contentassist + +import org.eclipse.xtext.ui.editor.contentassist.FQNPrefixMatcher.LastSegmentFinder + +class RBAModelLastSegmentFinder implements LastSegmentFinder { + + override String getLastSegment(String fqn, char delimiter) { + if(fqn === null || fqn.length() == 0) { + return null; + } + + var lookForUppercase = false; + var lastDelimiterIndex = -1; + for (var int i = 0; i < fqn.length(); i.operator_plusPlus()) { + if(lookForUppercase) { + if(Character.isUpperCase(fqn.charAt(i))) { + return fqn.substring(i); + } + } + lookForUppercase = delimiter == fqn.charAt(i); + if(lookForUppercase) { + lastDelimiterIndex = i; + } + } + if(lastDelimiterIndex >= 0 && lastDelimiterIndex < fqn.length() - 1) { + return fqn.substring(lastDelimiterIndex + 1); + } + return null; + } + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/contentassist/RBAModelProposalProvider.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/contentassist/RBAModelProposalProvider.xtend new file mode 100644 index 0000000..c3af655 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/contentassist/RBAModelProposalProvider.xtend @@ -0,0 +1,250 @@ +/* + * generated by Xtext 2.12.0 + */ +package rba.tool.editor.ui.contentassist + +import com.google.common.base.Predicate +import com.google.common.base.Predicates +import com.google.inject.Inject +import org.apache.log4j.Logger +import org.eclipse.emf.ecore.EObject +import org.eclipse.emf.ecore.util.EcoreUtil +import org.eclipse.jface.text.contentassist.ICompletionProposal +import org.eclipse.jface.viewers.StyledString +import org.eclipse.swt.graphics.Image +import org.eclipse.xtext.Assignment +import org.eclipse.xtext.CrossReference +import org.eclipse.xtext.Keyword +import org.eclipse.xtext.RuleCall +import org.eclipse.xtext.conversion.ValueConverterException +import org.eclipse.xtext.resource.IEObjectDescription +import org.eclipse.xtext.scoping.IScope +import org.eclipse.xtext.ui.editor.contentassist.AbstractJavaBasedContentProposalProvider.DefaultProposalCreator +import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal +import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext +import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor +import rba.core.Content +import rba.core.LambdaExpression +import rba.core.RBACorePackage +import rba.core.Variable +import rba.sound.SoundContent +import rba.sound.SoundContentSet +import rba.sound.Zone +import rba.sound.ZoneSet +import rba.tool.editor.resource.RBAModelEObjectDescription +import rba.tool.editor.ui.util.CharacterUtil +import rba.view.Area +import rba.view.AreaSet +import rba.view.Display +import rba.view.Size +import rba.view.ViewContent +import rba.view.ViewContentSet + +/** + * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#content-assist + * on how to customize the content assistant. + */ +class RBAModelProposalProvider extends AbstractRBAModelProposalProvider { + + private final static Logger log = Logger.getLogger(RBAModelProposalProvider); + + @Inject RBAModelExpressionScopeCreator expressionScopeCreator; + + override completeKeyword(Keyword keyword, ContentAssistContext contentAssistContext, ICompletionProposalAcceptor acceptor) { + if (!CharacterUtil.isKeywordWorthyToPropose(keyword)) { + super.completeKeyword(keyword, contentAssistContext, acceptor) + } + } + + override lookupCrossReference(CrossReference crossReference, ContentAssistContext contentAssistContext, ICompletionProposalAcceptor acceptor) { + lookupCrossReference(crossReference, contentAssistContext, acceptor, getFeatureDescriptionPredicate(crossReference, contentAssistContext)); + } + + def protected Predicate<IEObjectDescription> getFeatureDescriptionPredicate(CrossReference crossReference, ContentAssistContext contentAssistContext) { + return Predicates.and(new Predicate<IEObjectDescription>() { + override public boolean apply(IEObjectDescription input) { + if (input.EObjectOrProxy instanceof Variable) { + return contentAssistContext.currentModel.internalLambdaExpression(input.EObjectOrProxy); + } + + if (input.EObjectOrProxy instanceof Size) { + return isValidSizeModel(input.EObjectOrProxy, crossReference) + } + + return true; + } + }); + } + + def private boolean isValidSizeModel(EObject objectOrProxy, CrossReference crossReference) { + var EObject tmpObj + if (objectOrProxy.eIsProxy) { + // resolve proxy object with crossReference + tmpObj = EcoreUtil.resolve(objectOrProxy, crossReference); + } else { + tmpObj = objectOrProxy + } + // get the container of the real object + if (tmpObj instanceof Size) { + if (!(tmpObj.eContainer instanceof Area) && !(tmpObj.eContainer instanceof Content) && !(tmpObj.eContainer instanceof Display)) { + return true; + } + } + return false; + } + + def protected boolean internalLambdaExpression(EObject eObj1, EObject eObj2) { + if (eObj1 === null || !(eObj2 instanceof Variable)) { + return false; + } + + if (eObj1 instanceof LambdaExpression && (eObj1 as LambdaExpression).x === eObj2) { + return true; + } + + return internalLambdaExpression(eObj1.eContainer, eObj2); + } + + override protected getProposalFactory(String ruleName, ContentAssistContext contentAssistContext) { + return new DefaultProposalCreator(contentAssistContext, ruleName, getQualifiedNameConverter()) { + override apply(IEObjectDescription candidate) { + if (candidate === null) + return null; + var ICompletionProposal result = null; + var String proposal = qualifiedNameConverter.toString(candidate.getName()); + if (valueConverter !== null) { + try { + proposal = valueConverter.toString(proposal); + } catch (ValueConverterException e) { + log.debug(e.getMessage(), e); + return null; + } + } else if (ruleName !== null) { + try { + proposal = getValueConverter().toString(proposal, ruleName); + } catch (ValueConverterException e) { + log.debug(e.getMessage(), e); + return null; + } + } + val EObject objectOrProxy = candidate.getEObjectOrProxy(); + val StyledString displayString = getStyledDisplayString(candidate); + val Image image = getImage(candidate); + result = createCompletionProposal(proposal, displayString, image, contentAssistContext); + if (result instanceof ConfigurableCompletionProposal) { + (result as ConfigurableCompletionProposal).setProposalContextResource(contentAssistContext.getResource()); + (result as ConfigurableCompletionProposal).setAdditionalProposalInfo(objectOrProxy); + (result as ConfigurableCompletionProposal).setHover(hover); + + if (candidate instanceof RBAModelEObjectDescription) { + (result as ConfigurableCompletionProposal).setCursorPosition((result as ConfigurableCompletionProposal).cursorPosition + + (candidate as RBAModelEObjectDescription).getAdditionalInfo().get(0)); + (result as ConfigurableCompletionProposal).setPriority((result as ConfigurableCompletionProposal).priority + + (candidate as RBAModelEObjectDescription).getAdditionalInfo().get(1)); + } + } + getPriorityHelper().adjustCrossReferencePriority(result, contentAssistContext.getPrefix()); + return result; + } + }; + } + + override completeAreaSet_Target(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + val Predicate<IEObjectDescription> filter = Predicates.and(new Predicate<IEObjectDescription>() { + override public boolean apply(IEObjectDescription input) { + return (input.EObjectOrProxy instanceof Area || input.EObjectOrProxy instanceof AreaSet); + } + }); + lookupCrossReference((assignment.getTerminal() as CrossReference), context, acceptor, filter); + } + + override completeViewContentSet_Target(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + val Predicate<IEObjectDescription> filter = Predicates.and(new Predicate<IEObjectDescription>() { + override public boolean apply(IEObjectDescription input) { + return (input.EObjectOrProxy instanceof ViewContent || input.EObjectOrProxy instanceof ViewContentSet); + } + }); + lookupCrossReference((assignment.getTerminal() as CrossReference), context, acceptor, filter); + } + + override completeViewContentSet_Allocatable(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + val Predicate<IEObjectDescription> filter = Predicates.and(new Predicate<IEObjectDescription>() { + override public boolean apply(IEObjectDescription input) { + return (input.EObjectOrProxy instanceof Area || input.EObjectOrProxy instanceof AreaSet); + } + }); + lookupCrossReference((assignment.getTerminal() as CrossReference), context, acceptor, filter); + } + + override completeZoneSet_Target(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + val Predicate<IEObjectDescription> filter = Predicates.and(new Predicate<IEObjectDescription>() { + override public boolean apply(IEObjectDescription input) { + return (input.EObjectOrProxy instanceof Zone || input.EObjectOrProxy instanceof ZoneSet); + } + }); + lookupCrossReference((assignment.getTerminal() as CrossReference), context, acceptor, filter); + } + + override completeSoundContentSet_Target(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + val Predicate<IEObjectDescription> filter = Predicates.and(new Predicate<IEObjectDescription>() { + override public boolean apply(IEObjectDescription input) { + return (input.EObjectOrProxy instanceof SoundContent || input.EObjectOrProxy instanceof SoundContentSet); + } + }); + lookupCrossReference((assignment.getTerminal() as CrossReference), context, acceptor, filter); + } + + override completeSoundContentSet_Allocatable(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + val Predicate<IEObjectDescription> filter = Predicates.and(new Predicate<IEObjectDescription>() { + override public boolean apply(IEObjectDescription input) { + return (input.EObjectOrProxy instanceof Zone || input.EObjectOrProxy instanceof ZoneSet); + } + }); + lookupCrossReference((assignment.getTerminal() as CrossReference), context, acceptor, filter); + } + + override completeViewContent_Allocatable(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + val Predicate<IEObjectDescription> filter = Predicates.and(new Predicate<IEObjectDescription>() { + override public boolean apply(IEObjectDescription input) { + return (input.EObjectOrProxy instanceof Area || input.EObjectOrProxy instanceof AreaSet); + } + }); + lookupCrossReference((assignment.getTerminal() as CrossReference), context, acceptor, filter); + } + + override completeSoundContent_Allocatable(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + val Predicate<IEObjectDescription> filter = Predicates.and(new Predicate<IEObjectDescription>() { + override public boolean apply(IEObjectDescription input) { + return (input.EObjectOrProxy instanceof Zone || input.EObjectOrProxy instanceof ZoneSet); + } + }); + lookupCrossReference((assignment.getTerminal() as CrossReference), context, acceptor, filter); + } + + override completeCMemberFeatureReference_RefObject(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + createMemberAndOperatorProposals(model, assignment, context, acceptor); + } + + override completeVMemberFeatureReference_RefObject(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + createMemberAndOperatorProposals(model, assignment, context, acceptor); + } + + def protected void createMemberAndOperatorProposals(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + val IScope scope = expressionScopeCreator.getExpressionScope(model, context); + if (scope === null) { + lookupCrossReference((assignment.getTerminal() as CrossReference), context, acceptor); + } else { + getCrossReferenceProposalCreator().lookupCrossReference(scope, model, RBACorePackage.Literals.OBJECT_REFERENCE__REF_OBJECT, acceptor, + getFeatureDescriptionPredicate((assignment.getTerminal() as CrossReference), context), getProposalFactory("ValidID", context)); + } + } + + override complete_OpGetProperty(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + val IScope scope = expressionScopeCreator.getExpressionScope(model, context); + if (scope !== null) { + getCrossReferenceProposalCreator().lookupCrossReference(scope, model, RBACorePackage.Literals.OPERATOR__OPERAND, acceptor, Predicates.<IEObjectDescription>alwaysTrue(), + getProposalFactory(null, context)); + } + } + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/coverage/TCLogFormatPreferencePage.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/coverage/TCLogFormatPreferencePage.java new file mode 100644 index 0000000..fd6afdf --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/coverage/TCLogFormatPreferencePage.java @@ -0,0 +1,83 @@ +package rba.tool.editor.ui.coverage; + +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.RadioGroupFieldEditor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.preferences.ScopedPreferenceStore; + +public class TCLogFormatPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { + + private IPreferenceStore preferenceStore; + + private RadioGroupFieldEditor tclogFileFormat; + + private static final String DESCRIPTION = "tclog File Format"; + + private static final String TEXT_FORMAT = "text"; + + private static final String ZIP_FORMAT = "zip"; + + private String selectedFormat = TEXT_FORMAT; + + private TCLogFormatSettingManager manager = TCLogFormatSettingManager.INSTANCE; + + public TCLogFormatPreferencePage() { + super(GRID); + } + + @Override + public void init(IWorkbench workbench) { + if (!getPreferenceStore().getString("FileFormat").isEmpty()) { + selectedFormat = getPreferenceStore().getString("FileFormat"); + } + } + + @Override + protected void createFieldEditors() { + + String[][] btnArr = new String[][] { { "&Text", TEXT_FORMAT }, { "&Zip", ZIP_FORMAT } }; + tclogFileFormat = new RadioGroupFieldEditor("FileFormat", DESCRIPTION, 2, btnArr, getFieldEditorParent(), true); + + Composite composite = tclogFileFormat.getRadioBoxControl(getFieldEditorParent()); + Control[] controls = composite.getChildren(); + + for (Control control : controls) { + control.addListener(SWT.Selection, new Listener() { + + @Override + public void handleEvent(Event event) { + + Button btn = (Button) event.widget; + selectedFormat = (String) btn.getData(); + } + }); + } + + addField(tclogFileFormat); + } + + @Override + public boolean performOk() { + + manager.saveTCLogFileFormat(selectedFormat); + return super.performOk(); + } + + @Override + public IPreferenceStore getPreferenceStore() { + if (preferenceStore == null) { + preferenceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE, manager.ID_PREFERENCE_NODE); + } + return preferenceStore; + } + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/coverage/TCLogFormatSettingManager.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/coverage/TCLogFormatSettingManager.java new file mode 100644 index 0000000..c8bed99 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/coverage/TCLogFormatSettingManager.java @@ -0,0 +1,42 @@ +package rba.tool.editor.ui.coverage; + +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; + +public class TCLogFormatSettingManager { + + public static final TCLogFormatSettingManager INSTANCE = new TCLogFormatSettingManager(); + + public static final String ID_PREFERENCE_NODE = "rba.model.tool"; //$NON-NLS-1$ + + private static final String ID_PREFERENCES = "rba.model.tool.coverage.tclogFormat"; //$NON-NLS-1$ + + private static final String ID_TCLOG_FORMAT = "TCLogFormat"; //$NON-NLS-1$ + + public void saveTCLogFileFormat(final String format) { + final String oldFormat = TCLogFormatSettingManager.INSTANCE.getTCLogFileFormat(); + if (!oldFormat.equals(format)) { + IEclipsePreferences preferences = getPreferences(); + Preferences sub = preferences.node(ID_PREFERENCES); + sub.put(ID_TCLOG_FORMAT, format); + try { + // forces the application to save the preferences + preferences.flush(); + } catch (BackingStoreException e) { + e.printStackTrace(); + } + } + } + + public String getTCLogFileFormat() { + IEclipsePreferences preferences = getPreferences(); + Preferences sub = preferences.node(ID_PREFERENCES); + return sub.get(ID_TCLOG_FORMAT, "text"); + } + + private IEclipsePreferences getPreferences() { + return InstanceScope.INSTANCE.getNode(ID_PREFERENCE_NODE); + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/model/edit/processor/RBAModelProcessorUtil.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/model/edit/processor/RBAModelProcessorUtil.xtend new file mode 100644 index 0000000..5eebb92 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/model/edit/processor/RBAModelProcessorUtil.xtend @@ -0,0 +1,177 @@ +package rba.tool.editor.ui.editor.model.edit.processor + +import java.util.ArrayList +import java.util.Collection +import java.util.Collections +import java.util.List +import java.util.ListIterator +import org.eclipse.emf.common.util.BasicEList +import org.eclipse.emf.common.util.EList +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.common.util.WrappedException +import org.eclipse.emf.ecore.EObject +import org.eclipse.emf.ecore.EStructuralFeature +import org.eclipse.emf.ecore.util.EcoreUtil +import org.eclipse.xtext.resource.XtextResource +import org.eclipse.xtext.util.concurrent.IUnitOfWork +import rba.tool.editor.ui.editor.model.edit.refactoring.RBAModelRenameElementUtil + +class RBAModelProcessorUtil { + + public static final int NO_INDEX = -1; + public static final Object UNSET_VALUE = new Object(); + + def public static IUnitOfWork.Void<XtextResource> getAddProcessor(EObject owner, EStructuralFeature feature, Object object, int index) { + return new IUnitOfWork.Void<XtextResource>() { + override process(XtextResource xtextResource) throws Exception { + val allOwners = xtextResource.allContents.toIterable.filter[it === owner].toList(); + if(!allOwners.isEmpty()) { + doAddProcess(allOwners.get(0), feature, object, index); + } + } + }; + } + + def public static IUnitOfWork.Void<XtextResource> getRemoveProcessor(EObject owner, EStructuralFeature feature, Collection<Object> collection) { + return new IUnitOfWork.Void<XtextResource>() { + override process(XtextResource xtextResource) throws Exception { + val allOwners = xtextResource.allContents.toIterable.filter[it === owner].toList(); + if(!allOwners.isEmpty()) { + doRemoveProcess(allOwners.get(0), feature, collection); + } + } + }; + } + + def public static IUnitOfWork.Void<XtextResource> getSetProcessor(EObject owner, EStructuralFeature feature, Object value) { + return new IUnitOfWork.Void<XtextResource>() { + override process(XtextResource xtextResource) throws Exception { + val EObject docOwner = RBAModelProcessorUtil.findEObjectByURI(owner, xtextResource); + if(docOwner !== null && !docOwner.eIsProxy) { + doSetProcess(docOwner, feature, value); + } + } + }; + } + + def public static void doSetNameProcess(String value) { + RBAModelRenameElementUtil.INSTANCE.execute(value); + } + + def public static IUnitOfWork.Void<XtextResource> getUnexecutableProcessor() { + return new IUnitOfWork.Void<XtextResource>() { + override process(XtextResource xtextResource) throws Exception { + return; + } + }; + } + + def public static void doAddProcess(EObject owner, EStructuralFeature feature, Object object, int index) { + if(feature.isMany()) { + val sibling = owner.eGet(feature) as List<Object>; + if(!sibling.contains(object)) { + sibling.add(if(index === NO_INDEX || index > sibling.size()) sibling.size() else index, object); + } + } else { + owner.eSet(feature, object); + } + } + + def public static void doRemoveProcess(EObject owner, EStructuralFeature feature, Collection<Object> collection) { + if(feature.isMany()) { + val List<Object> objects = new ArrayList<Object>(collection); + val List<Object> sibling = owner.eGet(feature) as List<Object>; + for (obj : objects) { + if(sibling.contains(obj)) { + sibling.remove(obj); + } + } + } else { + if(feature.isUnsettable()) { + owner.eUnset(feature); + } + } + } + + def public static void doSetProcess(EObject owner, EStructuralFeature feature, Object value) { + if(feature.isMany()) { + val List<Object> values = if(value == UNSET_VALUE) Collections.EMPTY_LIST else value as List<Object>; + val EList<Object> oldValues = owner.eGet(feature) as EList<Object>; + + if(!oldValues.isEmpty()) { + if(!values.isEmpty()) { + val List<Object> removedValues = new BasicEList.FastCompare<Object>(oldValues); + removedValues.removeAll(values); + + // If we aren't simply removing all the old values... + if(!removedValues.equals(oldValues)) { + // If there are values to remove, append a command for them. + if(!removedValues.isEmpty()) { + oldValues.removeAll(removedValues); + } + + // Determine the values that will remain and move them into the right order, if necessary. + val EList<Object> remainingValues = new BasicEList.FastCompare<Object>(oldValues); + var count = -1; + for (object : values) { + val position = remainingValues.indexOf(object); + if(position != -1 && position != count.operator_plusPlus()) { + oldValues.move(count, position); + remainingValues.move(count, position); + } + } + + // Determine the values to be added and add them at the right position. + val List<Object> addedValues = new BasicEList.FastCompare<Object>(values); + addedValues.removeAll(remainingValues); + if(!addedValues.isEmpty()) { + var addIndex = remainingValues.size(); + for (val ListIterator<?> i = values.listIterator(values.size()); i.hasPrevious();) { + val Object object = i.previous(); + if(addedValues.contains(object)) { + doAddProcess(owner, feature, object, addIndex); + } else { + addIndex.operator_minusMinus(); + } + } + } + return; + } + } + oldValues.clear(); + } + + if(!values.isEmpty()) { + oldValues.addAll(values); + } else if(value == UNSET_VALUE && feature.isUnsettable()) { + owner.eUnset(feature); + } + } else { + if(value == UNSET_VALUE && feature.isUnsettable()) { + owner.eUnset(feature); + } else { + owner.eSet(feature, value); + } + } + } + + def public static EObject findEObjectByURI(EObject object, XtextResource resource) { + val URI uri = EcoreUtil.getURI(object); + if(uri !== null) { + return findEObjectByURI(uri, resource); + } + return null; + } + + def public static EObject findEObjectByURI(URI uri, XtextResource resource) { + if(uri.fragment() !== null) { + try { + val EObject result = resource.getEObject(uri.fragment()); + return result; + } catch(IllegalArgumentException e) { + } catch(WrappedException e) { + } + } + return null; + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/model/edit/refactoring/RBAModelRenameElementUtil.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/model/edit/refactoring/RBAModelRenameElementUtil.java new file mode 100644 index 0000000..cd84388 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/model/edit/refactoring/RBAModelRenameElementUtil.java @@ -0,0 +1,143 @@ +package rba.tool.editor.ui.editor.model.edit.refactoring; + +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.text.ITextSelection; +import org.eclipse.swt.widgets.Display; +import org.eclipse.xtext.ide.refactoring.IRenameStrategy2; +import org.eclipse.xtext.nodemodel.INode; +import org.eclipse.xtext.resource.EObjectAtOffsetHelper; +import org.eclipse.xtext.resource.IGlobalServiceProvider; +import org.eclipse.xtext.resource.ILocationInFileProvider; +import org.eclipse.xtext.resource.XtextResource; +import org.eclipse.xtext.ui.editor.XtextEditor; +import org.eclipse.xtext.ui.editor.utils.EditorUtils; +import org.eclipse.xtext.ui.refactoring.IRenameStrategy; +import org.eclipse.xtext.ui.refactoring.IRenameStrategy.Provider.NoSuchStrategyException; +import org.eclipse.xtext.ui.refactoring.ui.IRenameContextFactory; +import org.eclipse.xtext.ui.refactoring.ui.IRenameElementContext; +import org.eclipse.xtext.ui.refactoring.ui.RefactoringPreferences; +import org.eclipse.xtext.ui.refactoring.ui.RefactoringType; +import org.eclipse.xtext.ui.refactoring2.rename.ISimpleNameProvider; +import org.eclipse.xtext.util.ITextRegion; +import org.eclipse.xtext.util.TextRegion; +import org.eclipse.xtext.util.concurrent.IUnitOfWork; + +import com.google.inject.Inject; + +import rba.tool.editor.ui.activator.ExtensionEditorActivator; + +public class RBAModelRenameElementUtil { + + public static RBAModelRenameElementUtil INSTANCE = new RBAModelRenameElementUtil(); + + @Inject + private EObjectAtOffsetHelper eObjectAtOffsetHelper; + + @Inject + private ILocationInFileProvider locationInFileProvider; + + @Inject + protected RBAModelRenameRefactoringController renameRefactoringController; + + @Inject + protected IGlobalServiceProvider globalServiceProvider; + + @Inject + protected RefactoringPreferences preferences; + + @Inject + protected IRenameContextFactory renameContextFactory; + + @Inject + protected RBAModelSyncUtil syncUtil; + + private RBAModelRenameElementUtil() { + ExtensionEditorActivator.getInstance().injectMembers(this); + } + + public void execute(String value) { + try { + final XtextEditor editor = EditorUtils.getActiveXtextEditor(); + if (editor != null) { + syncUtil.totalSync(preferences.isSaveAllBeforeRefactoring(), renameRefactoringController.getActiveLinkedMode() == null); + final ITextSelection selection = (ITextSelection) editor.getSelectionProvider().getSelection(); + IRenameElementContext renameElementContext = editor.getDocument().priorityReadOnly(new IUnitOfWork<IRenameElementContext, XtextResource>() { + @Override + public IRenameElementContext exec(XtextResource resource) throws Exception { + EObject selectedElement = eObjectAtOffsetHelper.resolveElementAt(resource, selection.getOffset()); + if (selectedElement != null) { + IRenameElementContext renameElementContext = renameContextFactory.createRenameElementContext(selectedElement, editor, selection, resource); + if (isRefactoringEnabled(renameElementContext, resource)) + return renameElementContext; + } + return null; + } + }); + if (renameElementContext != null) { + startRenameElement(renameElementContext, value); + } + } + } catch (OperationCanceledException e) { + MessageDialog.openError(Display.getCurrent().getActiveShell(), "Error initializing refactoring 1", "\nSee log for details"); + // cancelled by user, ok + return; + } catch (InterruptedException e) { + MessageDialog.openError(Display.getCurrent().getActiveShell(), "Error initializing refactoring 2", "\nSee log for details"); + // cancelled by user, ok + return; + } catch (Exception exc) { + exc.printStackTrace(); + MessageDialog.openError(Display.getCurrent().getActiveShell(), "Error initializing refactoring", exc.getMessage() + "\nSee log for details"); + } + } + + public IRenameElementContext createRenameElementContext(EObject targetElement, final XtextEditor triggeringEditor, final ITextSelection selection, + XtextResource triggeringResource) { + return renameContextFactory.createRenameElementContext(targetElement, triggeringEditor, selection, triggeringResource); + } + + protected boolean isRefactoringEnabled(IRenameElementContext renameElementContext, XtextResource resource) { + ResourceSet resourceSet = resource.getResourceSet(); + if (renameElementContext != null && resourceSet != null) { + EObject targetElement = resourceSet.getEObject(renameElementContext.getTargetElementURI(), true); + if (targetElement != null && !targetElement.eIsProxy()) { + if (targetElement.eResource() == resource && renameElementContext.getTriggeringEditorSelection() instanceof ITextSelection) { + ITextSelection textSelection = (ITextSelection) renameElementContext.getTriggeringEditorSelection(); + ITextRegion selectedRegion = new TextRegion(textSelection.getOffset(), textSelection.getLength()); + INode crossReferenceNode = eObjectAtOffsetHelper.getCrossReferenceNode(resource, selectedRegion); + if (crossReferenceNode == null) { + // selection is on the declaration. make sure it's the name + ITextRegion significantRegion = locationInFileProvider.getSignificantTextRegion(targetElement); + if (!significantRegion.contains(selectedRegion)) + return false; + } + } + IRenameStrategy.Provider renameStrategyProvider = globalServiceProvider.findService(targetElement, IRenameStrategy.Provider.class); + try { + if (renameStrategyProvider.get(targetElement, renameElementContext) != null) { + return true; + } else { + IRenameStrategy2 strategy2 = globalServiceProvider.findService(targetElement, IRenameStrategy2.class); + ISimpleNameProvider simpleNameProvider = globalServiceProvider.findService(targetElement, ISimpleNameProvider.class); + return strategy2 != null && simpleNameProvider.canRename(targetElement); + } + + } catch (NoSuchStrategyException e) { + MessageDialog.openInformation(Display.getCurrent().getActiveShell(), "Cannot rename element", e.getMessage()); + } + } + } + return false; + } + + protected void startRenameElement(IRenameElementContext renameElementContext, String value) throws InterruptedException { + // renameRefactoringController.startRefactoring(renameElementContext); + // renameRefactoringController.startRefactoring(RefactoringType.REFACTORING_DIALOG); + renameRefactoringController.initialize(renameElementContext); + renameRefactoringController.setNewNameText(value); + renameRefactoringController.startRefactoring(RefactoringType.REFACTORING_DIALOG); + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/model/edit/refactoring/RBAModelRenameRefactoringController.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/model/edit/refactoring/RBAModelRenameRefactoringController.xtend new file mode 100644 index 0000000..737d004 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/model/edit/refactoring/RBAModelRenameRefactoringController.xtend @@ -0,0 +1,24 @@ +package rba.tool.editor.ui.editor.model.edit.refactoring + +import com.google.inject.Singleton +import org.eclipse.xtext.ui.editor.XtextEditor +import org.eclipse.xtext.ui.refactoring.ui.RenameRefactoringController + +@Singleton +class RBAModelRenameRefactoringController extends RenameRefactoringController { + + private String newNameText; + + override protected getOriginalName(XtextEditor xtextEditor) { + if(this instanceof RBAModelRenameRefactoringController) { + return newNameText; + } else { + super.getOriginalName(xtextEditor); + } + } + + def public void setNewNameText(String name) { + this.newNameText = name; + } + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/model/edit/refactoring/RBAModelSyncUtil.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/model/edit/refactoring/RBAModelSyncUtil.java new file mode 100644 index 0000000..ae6cfb3 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/model/edit/refactoring/RBAModelSyncUtil.java @@ -0,0 +1,175 @@ +package rba.tool.editor.ui.editor.model.edit.refactoring; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IncrementalProjectBuilder; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.SubMonitor; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.operation.IRunnableWithProgress; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.xtext.resource.XtextResource; +import org.eclipse.xtext.service.OperationCanceledError; +import org.eclipse.xtext.ui.editor.XtextEditor; +import org.eclipse.xtext.ui.editor.model.XtextDocument; +import org.eclipse.xtext.util.concurrent.IUnitOfWork; + +import com.google.inject.Inject; + +public class RBAModelSyncUtil { + + @Inject(optional = true) + private IWorkbench workbench; + + @Inject(optional = true) + private IWorkspace workspace; + + public void totalSync(final boolean saveAll, boolean useProgressDialog) throws InvocationTargetException, InterruptedException { + totalSync(saveAll, useProgressDialog, true); + } + + public void totalSync(final boolean saveAll, boolean useProgressDialog, boolean fork) throws InvocationTargetException, InterruptedException { + if (Display.getCurrent() != null && workbench != null) { + if (useProgressDialog) { + workbench.getProgressService().run(fork, true, new IRunnableWithProgress() { + @Override + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + doReconcileAndBuild(saveAll, monitor); + } + }); + } else { + doReconcileAndBuild(saveAll, null); + } + } + } + + private void doReconcileAndBuild(final boolean saveAll, IProgressMonitor monitor) throws InterruptedException { + try { + SubMonitor progress = SubMonitor.convert(monitor, 10); + reconcileAllEditors(workbench, saveAll, progress.newChild(1)); + if (progress.isCanceled()) { + throw new InterruptedException(); + } + waitForBuild(progress.newChild(4)); + if (progress.isCanceled()) { + throw new InterruptedException(); + } + yieldToQueuedDisplayJobs(progress.newChild(1)); + if (progress.isCanceled()) { + throw new InterruptedException(); + } + waitForAutoBuild(progress.newChild(4)); + } catch (OperationCanceledException e) { + throw new InterruptedException(); + } + } + + public void totalSync(final boolean saveAll) throws InvocationTargetException, InterruptedException { + totalSync(saveAll, true); + } + + public void reconcileAllEditors(IWorkbench workbench, final boolean saveAll, final IProgressMonitor monitor) { + for (IWorkbenchWindow window : workbench.getWorkbenchWindows()) { + for (IWorkbenchPage page : window.getPages()) { + for (IEditorReference editorReference : page.getEditorReferences()) { + if (monitor.isCanceled()) + return; + final IEditorPart editor = editorReference.getEditor(false); + if (editor != null) { + if (editor instanceof XtextEditor) { + waitForReconciler((XtextEditor) editor); + } + if (saveAll) { + Display display = workbench.getDisplay(); + display.syncExec(new Runnable() { + @Override + public void run() { + if (editor.isDirty()) { + editor.doSave(monitor); + } + } + }); + } + } + } + } + } + } + + /** + * this methods blocks until the following jobs have finished, - the reconciler - the editor validation job - the dirty + * state editor updater job + */ + public void waitForReconciler(XtextEditor editor) { + try { + editor.getDocument().readOnly(new IUnitOfWork.Void<XtextResource>() { + @Override + public void process(XtextResource state) throws Exception { + // this doesn't execute before the reconciler has finished + } + }); + // reconciling schedules both, validation and dirty state + Job validationJob = ((XtextDocument) editor.getDocument()).getValidationJob(); + validationJob.join(); + editor.getDirtyStateEditorSupport().waitForUpdateEditorJob(); + } catch (OperationCanceledException e) { + } catch (OperationCanceledError e) { + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public void waitForBuild(IProgressMonitor monitor) { + try { + workspace.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, monitor); + } catch (CoreException e) { + throw new OperationCanceledException(e.getMessage()); + } + } + + /** + * @deprecated we should not rely on auto build to be triggered. Use {@link #waitForBuild(IProgressMonitor)} instead. + */ + @Deprecated + public void waitForAutoBuild(IProgressMonitor monitor) { + boolean wasInterrupted = false; + do { + try { + Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, monitor); + wasInterrupted = false; + } catch (OperationCanceledException e) { + throw e; + } catch (InterruptedException e) { + wasInterrupted = true; + } + } while (wasInterrupted); + } + + public void yieldToQueuedDisplayJobs(IProgressMonitor monitor) { + yieldToQueuedDisplayJobs(monitor, 50000); + } + + public void yieldToQueuedDisplayJobs(IProgressMonitor monitor, int maxJobsToYieldTo) { + int count = 0; + if (Display.getCurrent() != null) { + while (count < maxJobsToYieldTo && Display.getCurrent().readAndDispatch()) { + if (monitor.isCanceled()) + throw new OperationCanceledException(); + ++count; + } + if (count == maxJobsToYieldTo) { + System.out.println("maxJobsToYieldTo probably exceeded. Worked: " + count); + } + } + } + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/model/manager/ResourceManagerUI.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/model/manager/ResourceManagerUI.xtend new file mode 100644 index 0000000..105d9de --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/model/manager/ResourceManagerUI.xtend @@ -0,0 +1,428 @@ +package rba.tool.editor.ui.editor.model.manager + +import com.google.inject.Inject +import java.util.ArrayList +import java.util.Collection +import java.util.Collections +import java.util.List +import org.eclipse.core.resources.IProject +import org.eclipse.core.resources.IncrementalProjectBuilder +import org.eclipse.core.resources.ResourcesPlugin +import org.eclipse.core.runtime.IProgressMonitor +import org.eclipse.core.runtime.OperationCanceledException +import org.eclipse.core.runtime.SubMonitor +import org.eclipse.core.runtime.jobs.Job +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.ecore.EAttribute +import org.eclipse.emf.ecore.EObject +import org.eclipse.emf.ecore.EReference +import org.eclipse.emf.ecore.EStructuralFeature +import org.eclipse.emf.ecore.resource.ResourceSet +import org.eclipse.emf.ecore.util.EcoreUtil +import org.eclipse.emf.edit.provider.ComposeableAdapterFactory +import org.eclipse.emf.edit.provider.IEditingDomainItemProvider +import org.eclipse.jface.dialogs.MessageDialog +import org.eclipse.swt.widgets.Display +import org.eclipse.ui.IEditorPart +import org.eclipse.xtext.resource.ILocationInFileProvider +import org.eclipse.xtext.resource.XtextResource +import org.eclipse.xtext.serializer.ISerializer +import org.eclipse.xtext.service.OperationCanceledError +import org.eclipse.xtext.ui.editor.LanguageSpecificURIEditorOpener +import org.eclipse.xtext.ui.editor.XtextEditor +import org.eclipse.xtext.ui.editor.model.IXtextDocument +import org.eclipse.xtext.ui.editor.utils.EditorUtils +import org.eclipse.xtext.util.ITextRegion +import org.eclipse.xtext.util.concurrent.IUnitOfWork +import rba.core.provider.RBACoreItemProviderAdapterFactory +import rba.sound.provider.RBASoundItemProviderAdapterFactory +import rba.tool.editor.resource.IRBAModelResourceLoader +import rba.tool.editor.ui.activator.ExtensionEditorActivator +import rba.tool.editor.ui.editor.model.edit.processor.RBAModelProcessorUtil +import rba.tool.editor.ui.resource.RBAModelResourceSetProvider +import rba.view.provider.RBAViewItemProviderAdapterFactory + +class ResourceManagerUI { + + public static ResourceManagerUI INSTANCE = new ResourceManagerUI(); + + @Inject private RBAModelResourceSetProvider resourceSetProvider; + + @Inject private LanguageSpecificURIEditorOpener editorOpener ; + + @Inject private ILocationInFileProvider locationProvider; + + @Inject private ISerializer serializer; + + @Inject IRBAModelResourceLoader resourceLoader; + + private List<ComposeableAdapterFactory> adapterFactorys = new ArrayList<ComposeableAdapterFactory>; + + private IProject currentProject; + + private new() { + ExtensionEditorActivator.getInstance().injectMembers(this); + adapterFactorys.add(new RBACoreItemProviderAdapterFactory()); + adapterFactorys.add(new RBAViewItemProviderAdapterFactory()); + adapterFactorys.add(new RBASoundItemProviderAdapterFactory()); + } + + def public IProject getCurrentProject() { + return currentProject; + } + + def public void setCurrentProject(IProject project) { + currentProject = project; + } + + def public boolean isCurrentProject(IProject project) { + if (project === null || !project.isOpen()) { + return false; + } + + if (project.equals(currentProject)) { + return true; + } + + return false; + } + + def public ResourceSet getCurrentResourceSet() { + return resourceSetProvider.getResourceSet(currentProject); + } + + def public void setCurrentResourceSet(ResourceSet resourceSet) { + resourceSetProvider.setResourceSet(currentProject, resourceSet); + } + + def public IXtextDocument getXtextDocument(IEditorPart openEditor) { + val XtextEditor xtextEditor = EditorUtils.getXtextEditor(openEditor); + if (xtextEditor !== null) { + return xtextEditor.getDocument(); + } + return null; + } + + def public void add(EObject owner, EStructuralFeature feature, Object object, int index) { + val Object outerOwner = owner ?: getParent(object); + if (outerOwner === null) { + return; + } + if (!(outerOwner instanceof EObject)) { + return; + } + + if (feature === null || object === null) { + return; + } + + if (!isValid(outerOwner as EObject, feature)) { + return; + } + + val editorPart = open(outerOwner as EObject, false); + var IXtextDocument document = getXtextDocument(editorPart); + + if (document !== null) { + document.modify(RBAModelProcessorUtil.getAddProcessor(outerOwner as EObject, feature, object, if (index < 0) RBAModelProcessorUtil.NO_INDEX else index)); + } + } + + def public void remove(EObject owner, EStructuralFeature feature, Object object) { + val Object outerOwner = owner ?: getParent(object); + if (outerOwner === null) { + return; + } + if (!(outerOwner instanceof EObject)) { + return; + } + + remove(outerOwner as EObject, feature, Collections.singleton(object)); + } + + def public void remove(EObject owner, EStructuralFeature feature, Collection<Object> collection) { + if (owner !== null) { + if (feature === null || collection === null || collection.isEmpty()) { + return; + } + + if (!isValid(owner, feature)) { + return; + } + + val editorPart = open(owner as EObject, false); + var IXtextDocument document = getXtextDocument(editorPart); + + if (document !== null) { + document.modify(RBAModelProcessorUtil.getRemoveProcessor(owner as EObject, feature, collection)); + } + } else { + remove(feature, collection); + } + } + + def public void remove(EStructuralFeature feature, Collection<Object> collection) { + if (feature === null || collection === null || collection.isEmpty()) { + return; + } + + val List<Object> objects = new ArrayList<Object>(collection); + while (!objects.isEmpty()) { + // We will iterate over the whole collection, removing some as we go. + val remainingObjects = objects.listIterator(); + + // Take the first object, and remove it. + val object = remainingObjects.next(); + remainingObjects.remove(); + + // Determine the object's parent. + val parent = getParent(object); + if (parent instanceof EObject) { + // Now we want to find all the other objects with this same parent. + // So we can collection siblings together and give the parent control over their removal. + val List<Object> siblings = new ArrayList<Object>(); + siblings.add(object); + + while (remainingObjects.hasNext()) { + // Get the next object and check if it has the same parent. + val otherObject = remainingObjects.next(); + val otherParent = getParent(otherObject); + if (otherParent == parent) { + // Remove the object and add it as a sibling. + remainingObjects.remove(); + siblings.add(otherObject); + } + } + remove(parent as EObject, feature, siblings); + } + } + } + + def public void set(EObject owner, EStructuralFeature feature, Object value) { + val Object outerOwner = owner ?: getParent(value); + if (outerOwner === null) { + return; + } + if (!(outerOwner instanceof EObject)) { + return; + } + + if (feature === null) { + return; + } + + if (!isValid(owner, feature)) { + return; + } + + val innerValue = value ?: RBAModelProcessorUtil.UNSET_VALUE; + val editorPart = open(outerOwner as EObject, false); + var IXtextDocument document = getXtextDocument(editorPart); + + if (document !== null) { + document.modify(RBAModelProcessorUtil.getSetProcessor(outerOwner as EObject, feature, innerValue)); + selectAndReveal(editorPart, EcoreUtil.getURI(outerOwner as EObject), feature, true); + } + } + + def public void unset(EObject owner, EStructuralFeature feature) { + if (owner === null || feature === null) { + return; + } + + if (!isValid(owner, feature)) { + return; + } + + val editorPart = open(owner as EObject, false); + var IXtextDocument document = getXtextDocument(editorPart); + + if (document !== null) { + document.modify(RBAModelProcessorUtil.getSetProcessor(owner, feature, RBAModelProcessorUtil.UNSET_VALUE)); + } + } + + def public void setName(EObject owner, EStructuralFeature feature, Object value) { + val Object outerOwner = owner ?: getParent(value); + if (outerOwner === null) { + return; + } + if (!(outerOwner instanceof EObject)) { + return; + } + + val XtextEditor editor = open(outerOwner as EObject, true); + if (editor === null) { + return; + } + + if (feature === null) { + return; + } + + if (!isValid(owner, feature)) { + return; + } + + if (!(value instanceof String)) { + return; + } + val innerValue = value as String; + + RBAModelProcessorUtil.doSetNameProcess(innerValue) + } + + def public void waitForBuildProgress(Object family, IProgressMonitor monitor) { + var boolean wasInterrupted = false; + do { + try { + Job.getJobManager().join(family, monitor); + wasInterrupted = false; + } catch (OperationCanceledException e) { + throw e; + } catch (InterruptedException e) { + wasInterrupted = true; + } + } while (wasInterrupted); + } + + def public XtextEditor open(EObject eObject, boolean select) { + val resource = eObject.eResource(); + if (resource === null) { + return null; + } + + val editorPart = editorOpener.open(EcoreUtil.getURI(eObject), select); + if (!(editorPart instanceof XtextEditor)) { + return null; + } + + return (editorPart as XtextEditor); + } + + def public XtextEditor open(URI uri, boolean select) { + if (uri === null || uri.isEmpty()) { + return null + } + + val editorPart = editorOpener.open(uri, select); + if (!(editorPart instanceof XtextEditor)) { + return null; + } + + return (editorPart as XtextEditor); + } + + def private Object getParent(Object object) { + for (adapterFactory : adapterFactorys) { + val IEditingDomainItemProvider editingDomainItemProvider = adapterFactory.adapt(object, IEditingDomainItemProvider) as IEditingDomainItemProvider; + if (editingDomainItemProvider !== null) { + return editingDomainItemProvider.getParent(object); + } + } + return null; + } + + def private static isValid(EObject owner, EStructuralFeature feature) { + if (feature instanceof EReference && owner.eClass().getEAllReferences().contains(feature)) { + return true; + } + if (feature instanceof EAttribute && owner.eClass().getEAllAttributes().contains(feature)) { + return true; + } + return false; + } + + def public void switchToProject(IProject project, IProgressMonitor monitor) throws InterruptedException { + if (project === null) { + return; + } + + try { + val SubMonitor progress = SubMonitor.convert(monitor, 10); + doSwitch(project, progress.newChild(2)); + if (progress.isCanceled()) { + throw new InterruptedException(); + } + doBuild(project, progress.newChild(6)); + if (progress.isCanceled()) { + throw new InterruptedException(); + } + waitForBuildProgress(ResourcesPlugin.FAMILY_MANUAL_BUILD, progress.newChild(2)); + } catch (Exception e) { + throw new InterruptedException(e.getMessage()); + } + } + + def public boolean doConfirm(IProject project, boolean showConfirmDialog) throws InterruptedException { + if (project === null || !project.isOpen()) { + throw new InterruptedException(); + } + if (isCurrentProject(project)) { + return true; + } + + val boolean confirm = if (showConfirmDialog) + MessageDialog.openConfirm(Display.getCurrent().getActiveShell(), "Switch Project", "Do you want to switch to [" + project.getName() + "] project?") + else + true; + + return confirm; + } + + def private void doSwitch(IProject project, IProgressMonitor monitor) { + try { + setCurrentProject(project); + } catch (Exception e) { + throw new InterruptedException(e.getMessage()); + } + } + + def private void doBuild(IProject project, IProgressMonitor monitor) { + try { + project.build(IncrementalProjectBuilder.FULL_BUILD, monitor); + } catch (Exception e) { + throw new InterruptedException(e.getMessage()); + } + } + + def private void selectAndReveal(IEditorPart openEditor, URI uri, EStructuralFeature feature, boolean select) { + if (openEditor instanceof XtextEditor && select) { + val xtextEditor = openEditor as XtextEditor; + var boolean success = false; + var int tries = 0; + while (!success || tries >= 5) { + try { + xtextEditor.getDocument().readOnly(new IUnitOfWork.Void<XtextResource>() { + override process(XtextResource resource) throws Exception { + if (resource !== null) { + val EObject object = RBAModelProcessorUtil.findEObjectByURI(uri, resource); + if (object !== null) { + val ITextRegion location = if (feature !== null) + locationProvider.getSignificantTextRegion(object, feature, 0) + else + locationProvider.getSignificantTextRegion(object); + xtextEditor.selectAndReveal(location.getOffset(), location.getLength()); + } + } + } + }); + xtextEditor.doSave(null) + success = true; + } catch (OperationCanceledException e) { + } catch (OperationCanceledError e) { + } finally { + tries++; + } + } + } + } + + def public String serialize(EObject object) { + return serializer.serialize(object) + } + + def public void loadAndResolveResource(ResourceSet resourceSet, URI[] URIs, IProject project) { + resourceLoader.loadAndResolveResource(resourceSet, URIs, project); + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/templates/RBAModelTemplateRegistry.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/templates/RBAModelTemplateRegistry.xtend new file mode 100644 index 0000000..0b1126c --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/templates/RBAModelTemplateRegistry.xtend @@ -0,0 +1,99 @@ +package rba.tool.editor.ui.editor.templates + +import com.google.common.collect.Lists +import com.google.inject.Inject +import com.google.inject.Singleton +import java.util.List +import java.util.Map +import org.apache.commons.lang.StringUtils +import org.eclipse.jface.text.templates.Template +import org.eclipse.xtext.EcoreUtil2 +import org.eclipse.xtext.GrammarUtil +import org.eclipse.xtext.IGrammarAccess +import org.eclipse.xtext.Keyword +import org.eclipse.xtext.ui.editor.templates.ContextTypeIdHelper +import rba.tool.editor.ui.util.CharacterUtil + +@Singleton +class RBAModelTemplateRegistry extends TemplateRegistry { + + private final Map<String, String> PATTERNS = newLinkedHashMap( + "rba.tool.editor.RBAModel.kw_runtime:" -> "${true}", + "rba.tool.editor.RBAModel.kw_global:" -> "${false}", + "rba.tool.editor.RBAModel.kw_description:" -> "\"${}\"", + "rba.tool.editor.RBAModel.kw_width:" -> "${0}", + "rba.tool.editor.RBAModel.kw_height:" -> "${0}", + "rba.tool.editor.RBAModel.kw_x:" -> "${0}", + "rba.tool.editor.RBAModel.kw_y:" -> "${0}", + "rba.tool.editor.RBAModel.kw_attenuateValue:" -> "${0}", + "rba.tool.editor.RBAModel.kw_loserType:" -> "${NEVER_GIVEUP}", + "rba.tool.editor.RBAModel.kw_arbitrationPolicy:" -> "${DEFAULT}", + "rba.tool.editor.RBAModel.kw_basePoint:" -> "${LEFT_TOP}", + "rba.tool.editor.RBAModel.kw_type:" -> "${DEFAULT}", + "rba.tool.editor.RBAModel.kw_allocatable:" -> "[${cursor}]", + "rba.tool.editor.RBAModel.kw_subarea:" -> "[${cursor}]", + "rba.tool.editor.RBAModel.kw_sizeReference:" -> "${size_id}", + "rba.tool.editor.RBAModel.kw_layout:" -> "", + "rba.tool.editor.RBAModel.kw_visibility:" -> "${STANDARD_VALUE}", + "rba.tool.editor.RBAModel.kw_priority:" -> "${STANDARD_VALUE}", + "rba.tool.editor.RBAModel.kw_value:" -> "${STANDARD_VALUE}", + "rba.tool.editor.RBAModel.kw_zorder:" -> "${STANDARD_VALUE}", + "rba.tool.editor.RBAModel.kw_contentStateRef:" -> "${contentState_id}", + "rba.tool.editor.RBAModel.kw_areaReference:" -> "${area_id}", + "rba.tool.editor.RBAModel.kw_condition:" -> "", + "rba.tool.editor.RBAModel.kw_area:" -> "${area_id}", + "rba.tool.editor.RBAModel.kw_content:" -> "${content_id}" + ) ; + + private final ContextTypeIdHelper helper; + + @Inject + public new(IGrammarAccess grammarAccess, ContextTypeIdHelper helper) { + this.helper = helper; + registerTemplates(grammarAccess); + } + + def protected void registerTemplates(IGrammarAccess grammarAccess) { + val List<Template> allTemplates = Lists.newArrayList(); + for (parserRule : GrammarUtil.allParserRules(grammarAccess.getGrammar())) { + var Template template; + for (keyword : EcoreUtil2.getAllContentsOfType(parserRule, Keyword)) { + if (CharacterUtil.isKeywordWorthyToPropose(keyword)) { + val name = keyword.value; + if (!StringUtils.isEmpty(name)) { + if (StringUtils.endsWith(name, ":")) { + template = new Template(name, "", getId(keyword), getPattern(keyword), true); + } else { + template = new Template(name, "", getId(keyword), name, true); + } + allTemplates.add(template); + } + } + } + } + for (enumRule : GrammarUtil.allEnumRules(grammarAccess.getGrammar())) { + var Template template; + for (keyword : EcoreUtil2.getAllContentsOfType(enumRule, Keyword)) { + if (CharacterUtil.isKeywordWorthyToPropose(keyword)) { + val name = keyword.value; + if (!StringUtils.isEmpty(name)) { + template = new Template(name, "", getId(keyword), name, true); + allTemplates.add(template); + } + } + } + } + + for (template : allTemplates) { + addTemplate(template); + } + } + + def public String getId(Keyword k) { + return helper.getId(k); + } + + def private String getPattern(Keyword k) { + return StringUtils.join(#[k.value, " ", PATTERNS.get(getId(k)) ?: ""]); + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/templates/RBAModelTemplateStore.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/templates/RBAModelTemplateStore.xtend new file mode 100644 index 0000000..7330f91 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/templates/RBAModelTemplateStore.xtend @@ -0,0 +1,30 @@ +package rba.tool.editor.ui.editor.templates + +import com.google.inject.Inject +import com.google.inject.Singleton +import java.util.ArrayList +import java.util.List +import org.eclipse.jface.preference.IPreferenceStore +import org.eclipse.jface.text.templates.ContextTypeRegistry +import org.eclipse.jface.text.templates.Template +import org.eclipse.ui.plugin.AbstractUIPlugin +import org.eclipse.xtext.ui.editor.templates.XtextTemplateStore + +@Singleton +class RBAModelTemplateStore extends XtextTemplateStore { + + private TemplateRegistry templateRegistry; + + @Inject + new(TemplateRegistry templateRegistry, ContextTypeRegistry registry, IPreferenceStore store, String key, AbstractUIPlugin plugin) { + super(registry, store, key, plugin); + this.templateRegistry = templateRegistry; + } + + override getTemplates(String contextTypeId) { + val List<Template> templates = new ArrayList<Template>(super.getTemplates(contextTypeId)); + val template = templateRegistry.getTemplate(contextTypeId); + if (template !== null) templates.add(template); + return templates.toArray(newArrayOfSize(templates.size())); + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/templates/TemplateRegistry.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/templates/TemplateRegistry.xtend new file mode 100644 index 0000000..edba477 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/editor/templates/TemplateRegistry.xtend @@ -0,0 +1,23 @@ +package rba.tool.editor.ui.editor.templates + +import java.util.Iterator +import java.util.LinkedHashMap +import java.util.Map +import org.eclipse.jface.text.templates.Template + +class TemplateRegistry { + + private final Map<String, Template> fTemplates = new LinkedHashMap<String, Template>(); + + def public void addTemplate(Template template) { + fTemplates.put(template.contextTypeId, template); + } + + def public Template getTemplate(String id) { + return fTemplates.get(id); + } + + def public Iterator<Template> templates() { + return fTemplates.values().iterator(); + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/labeling/RBAModelDescriptionLabelProvider.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/labeling/RBAModelDescriptionLabelProvider.xtend new file mode 100644 index 0000000..c1660a7 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/labeling/RBAModelDescriptionLabelProvider.xtend @@ -0,0 +1,24 @@ +/* + * generated by Xtext 2.12.0 + */ +package rba.tool.editor.ui.labeling + +import org.eclipse.xtext.ui.label.DefaultDescriptionLabelProvider + +/** + * Provides labels for IEObjectDescriptions and IResourceDescriptions. + * + * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#label-provider + */ +class RBAModelDescriptionLabelProvider extends DefaultDescriptionLabelProvider { + + // Labels and icons can be computed like this: + +// override text(IEObjectDescription ele) { +// ele.name.toString +// } +// +// override image(IEObjectDescription ele) { +// ele.EClass.name + '.gif' +// } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/labeling/RBAModelLabelProvider.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/labeling/RBAModelLabelProvider.xtend new file mode 100644 index 0000000..0f55a06 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/labeling/RBAModelLabelProvider.xtend @@ -0,0 +1,31 @@ +/* + * generated by Xtext 2.12.0 + */ +package rba.tool.editor.ui.labeling + +import com.google.inject.Inject +import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider +import org.eclipse.xtext.ui.label.DefaultEObjectLabelProvider + +/** + * Provides labels for EObjects. + * + * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#label-provider + */ +class RBAModelLabelProvider extends DefaultEObjectLabelProvider { + + @Inject + new(AdapterFactoryLabelProvider delegate) { + super(delegate); + } + + // Labels and icons can be computed like this: + +// def text(Greeting ele) { +// 'A greeting to ' + ele.name +// } +// +// def image(Greeting ele) { +// 'Greeting.gif' +// } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/labeling/RBATemplateModelDescriptionLabelProvider.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/labeling/RBATemplateModelDescriptionLabelProvider.xtend new file mode 100644 index 0000000..5f722d3 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/labeling/RBATemplateModelDescriptionLabelProvider.xtend @@ -0,0 +1,24 @@ +/* + * generated by Xtext 2.13.0 + */ +package rba.tool.editor.ui.labeling + +import org.eclipse.xtext.ui.label.DefaultDescriptionLabelProvider + +/** + * Provides labels for IEObjectDescriptions and IResourceDescriptions. + * + * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#label-provider + */ +class RBATemplateModelDescriptionLabelProvider extends DefaultDescriptionLabelProvider { + + // Labels and icons can be computed like this: + +// override text(IEObjectDescription ele) { +// ele.name.toString +// } +// +// override image(IEObjectDescription ele) { +// ele.EClass.name + '.gif' +// } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/labeling/RBATemplateModelLabelProvider.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/labeling/RBATemplateModelLabelProvider.xtend new file mode 100644 index 0000000..cc8d296 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/labeling/RBATemplateModelLabelProvider.xtend @@ -0,0 +1,31 @@ +/* + * generated by Xtext 2.13.0 + */ +package rba.tool.editor.ui.labeling + +import com.google.inject.Inject +import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider +import org.eclipse.xtext.ui.label.DefaultEObjectLabelProvider + +/** + * Provides labels for EObjects. + * + * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#label-provider + */ +class RBATemplateModelLabelProvider extends DefaultEObjectLabelProvider { + + @Inject + new(AdapterFactoryLabelProvider delegate) { + super(delegate); + } + + // Labels and icons can be computed like this: + +// def text(Greeting ele) { +// 'A greeting to ' + ele.name +// } +// +// def image(Greeting ele) { +// 'Greeting.gif' +// } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/marker/PositionInfo.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/marker/PositionInfo.xtend new file mode 100644 index 0000000..a43191a --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/marker/PositionInfo.xtend @@ -0,0 +1,76 @@ +package rba.tool.editor.ui.marker + +class PositionInfo { + private int beforeStartLine + private int beforeOffset + private int beforeCharCount + private int beforeEndLine + private int afterStartLine + private int afterOffset + private int afterCharCount + private int afterExpendedLine + + def void setBeforeStartLine(int start) { + this.beforeStartLine = start + } + + def void setBeforeOffset(int offset) { + this.beforeOffset = offset + } + + def void setBeforeCharCount(int charCount) { + this.beforeCharCount = charCount + } + + def void setBeforeEndLine(int end) { + this.beforeEndLine = end + } + + def void setAfterStartLine(int start) { + this.afterStartLine = start + } + + def void setAfterOffset(int offset) { + this.afterOffset = offset + } + + def void setAfterCharCount(int charCount) { + this.afterCharCount = charCount + } + + def void setAfterExpendedLine(int expendLine) { + this.afterExpendedLine = expendLine + } + + def int getBeforeStartLine() { + return this.beforeStartLine + } + + def int getBeforeOffset() { + return this.beforeOffset + } + + def int getBeforeCharCount() { + return this.beforeCharCount + } + + def int getBeforeEndLine() { + return this.beforeEndLine + } + + def int getAfterStartLine() { + return this.afterStartLine + } + + def int getAfterOffset() { + return this.afterOffset + } + + def int getAfterCharCount() { + return this.afterCharCount + } + + def int getAfterExpendedLine() { + return this.afterExpendedLine + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/marker/RBAModelMarkerCreator.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/marker/RBAModelMarkerCreator.xtend new file mode 100644 index 0000000..c982375 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/marker/RBAModelMarkerCreator.xtend @@ -0,0 +1,34 @@ +package rba.tool.editor.ui.marker + +import org.eclipse.core.resources.IMarker +import org.eclipse.core.resources.IResource +import org.eclipse.core.runtime.CoreException +import org.eclipse.xtext.ui.editor.validation.MarkerCreator +import org.eclipse.xtext.validation.Issue +import rba.tool.editor.util.RBAModelEditorNameUtil + +class RBAModelMarkerCreator extends MarkerCreator { + + override protected setMarkerAttributes(Issue issue, IResource resource, IMarker marker) throws CoreException { + super.setMarkerAttributes(issue, resource, marker) + var isInModelFolder = false + var isInBuildFolder = false + var uri = issue.uriToProblem + if (uri !== null) { + for (seg : uri.segments) { + if (seg.equals(RBAModelEditorNameUtil.BUILD_FOLDER_NAME)) { + isInBuildFolder = true + } + } + } + var path = marker.resource.fullPath + if (path !== null) { + for (seg : path.segments) { + if (seg.equals(RBAModelEditorNameUtil.MODEL_FOLDER_NAME)) { + isInModelFolder = true + } + } + } + } + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/marker/RBAModelResourceUIValidatorExtension.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/marker/RBAModelResourceUIValidatorExtension.xtend new file mode 100644 index 0000000..cbb9b51 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/marker/RBAModelResourceUIValidatorExtension.xtend @@ -0,0 +1,67 @@ +package rba.tool.editor.ui.marker + +import org.eclipse.core.resources.IFile +import org.eclipse.core.resources.IFolder +import org.eclipse.core.resources.IMarker +import org.eclipse.core.resources.IResource +import org.eclipse.core.runtime.CoreException +import org.eclipse.core.runtime.IProgressMonitor +import org.eclipse.core.runtime.OperationCanceledException +import org.eclipse.emf.ecore.resource.Resource +import org.eclipse.xtext.ui.validation.DefaultResourceUIValidatorExtension +import org.eclipse.xtext.validation.CheckMode +import rba.tool.editor.util.RBAModelEditorNameUtil + +class RBAModelResourceUIValidatorExtension extends DefaultResourceUIValidatorExtension { + + private var path = new String + + override updateValidationMarkers(IFile file, Resource resource, CheckMode mode, + IProgressMonitor monitor) throws OperationCanceledException { + path = new String + var exist = existInBuildFolder(file.parent) + if (exist) { + if (!path.equals("")) { + path = "model" + "//" + path + } else { + path = "model" + } + val p = file.project + val d = p.getFolder(path) + val f = d.getFile(file.name) + super.updateValidationMarkers(f, resource, mode, monitor) + } + } + + def boolean existInBuildFolder(IResource res) { + if (res instanceof IFolder) { + if (res.name.equals(RBAModelEditorNameUtil.BUILD_FOLDER_NAME)) { + return true + } else { + if (!path.equals("")) { + path = res.name + "//" + path + } else { + path = res.name + } + return existInBuildFolder(res.parent) + } + } + return false + } + + override deleteValidationMarkers(IFile file, CheckMode checkMode, IProgressMonitor monitor) { + path = new String + var exist = existInBuildFolder(file.parent) + if (exist) { + if (!path.equals("")) { + path += "model" + "//" + path + } else { + path = "model" + } + val p = file.project + val d = p.getFolder(path) + val f = d.getFile(file.name) + super.deleteValidationMarkers(f, checkMode, monitor) + } + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/messages/Messages.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/messages/Messages.java new file mode 100644 index 0000000..aaebbb9 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/messages/Messages.java @@ -0,0 +1,29 @@ +package rba.tool.editor.ui.messages; + +import org.eclipse.osgi.util.NLS; + +public class Messages extends NLS { + public static final String BUNDLE_NAME = "rba.tool.editor.ui.messages.messages"; + + public static String PAGE_INFORMATION; + + public static String LBL_IPADDRESS; + + public static String LBL_PORT; + + public static String LBL_APPNAME; + + public static String ERR_EMPTY_IP; + + public static String ERR_EMPTY_PORT; + + public static String PORT_NUMERIC_ERR; + + public static String IP_FORMAT_ERR; + + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/messages/messages.properties b/rba.tool.editor.ui/src/rba/tool/editor/ui/messages/messages.properties new file mode 100644 index 0000000..7b4c196 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/messages/messages.properties @@ -0,0 +1,9 @@ +PAGE_INFORMATION=This page allows you to set settings for communicate other RBAModel Project +LBL_IPADDRESS=IP Address : +LBL_PORT=Port : +LBL_APPNAME=App Name : +#Error Message +ERR_EMPTY_IP=[IP Address] doesn't allow empty value. +ERR_EMPTY_PORT=[Port] doesn't allow empty value. +PORT_NUMERIC_ERR=[Port] must be number. +IP_FORMAT_ERR=[IP Address] is incorrect format. Enter 'localhost' or valid IP Address.
\ No newline at end of file diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/opener/RBAModelURIEditorOpener.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/opener/RBAModelURIEditorOpener.xtend new file mode 100644 index 0000000..6d017c4 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/opener/RBAModelURIEditorOpener.xtend @@ -0,0 +1,129 @@ +package rba.tool.editor.ui.opener + +import com.google.inject.Inject +import org.apache.log4j.Logger +import org.eclipse.core.resources.IFile +import org.eclipse.core.resources.IStorage +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.common.util.WrappedException +import org.eclipse.emf.ecore.EReference +import org.eclipse.ui.IEditorPart +import org.eclipse.ui.IWorkbench +import org.eclipse.ui.PartInitException +import org.eclipse.ui.PlatformUI +import org.eclipse.ui.ide.IDE +import org.eclipse.xtext.resource.ILocationInFileProvider +import org.eclipse.xtext.resource.IResourceServiceProvider +import org.eclipse.xtext.resource.XtextResource +import org.eclipse.xtext.ui.editor.IURIEditorOpener +import org.eclipse.xtext.ui.editor.utils.EditorUtils +import org.eclipse.xtext.ui.resource.IResourceUIServiceProvider +import org.eclipse.xtext.ui.resource.IStorage2UriMapper +import org.eclipse.xtext.util.concurrent.IUnitOfWork + +class RBAModelURIEditorOpener implements IURIEditorOpener { + + private static final Logger logger = Logger.getLogger(RBAModelURIEditorOpener); + + @Inject + private IResourceServiceProvider.Registry resourceServiceProviderRegistry; + + @Inject + private IStorage2UriMapper mapper; + + @Inject(optional=true) + private IWorkbench workbench; + + /** + * @since 2.2 + */ + def IEditorPart open(URI uri, Object context, boolean select) { + return open(uri, select); + } + + override open(URI uri, boolean select) { + val resourceServiceProvider = resourceServiceProviderRegistry.getResourceServiceProvider(uri.trimFragment()); + if(resourceServiceProvider instanceof IResourceUIServiceProvider) { + val editorOpener = ( resourceServiceProvider as IResourceUIServiceProvider).getURIEditorOpener(); + if(editorOpener !== null) { + return editorOpener.open(URI.createURI(uri.toString.replace("/.applied/", "/model/")), select); + } + } + return openDefaultEditor(URI.createURI(uri.toString.replace("/.applied/", "/model/")), null, -1, select); + } + + override open(URI referenceOwnerURI, EReference reference, int indexInList, boolean select) { + val resourceServiceProvider = resourceServiceProviderRegistry.getResourceServiceProvider(referenceOwnerURI.trimFragment()); + if(resourceServiceProvider instanceof IResourceUIServiceProvider) { + val editorOpener = (resourceServiceProvider as IResourceUIServiceProvider).getURIEditorOpener(); + if(editorOpener !== null) { + return editorOpener.open(referenceOwnerURI, reference, indexInList, select); + } + } + return openDefaultEditor(referenceOwnerURI, reference, indexInList, select); + } + + def protected IEditorPart openDefaultEditor(URI uri, EReference crossReference, int indexInList, boolean select) { + val storages = mapper.getStorages(uri.trimFragment()).iterator(); + if(storages !== null && storages.hasNext()) { + try { + val storage = storages.next().getFirst(); + var IEditorPart editor = null; + if(storage instanceof IFile) { + editor = openDefaultEditor(storage as IFile); + } else { + editor = openDefaultEditor(storage, uri); + } + selectAndReveal(editor, uri, crossReference, indexInList, select); + return editor; + } catch(WrappedException e) { + logger.error("Error while opening editor part for EMF URI '" + uri + "'", e.getCause()); + } catch(PartInitException partInitException) { + logger.error("Error while opening editor part for EMF URI '" + uri + "'", partInitException); + } + } + return null; + } + + def protected void selectAndReveal(IEditorPart openEditor, URI uri, EReference crossReference, int indexInList, boolean select) { + val xtextEditor = EditorUtils.getXtextEditor(openEditor); + if(xtextEditor !== null) { + if(uri.fragment() !== null) { + xtextEditor.getDocument().priorityReadOnly(new IUnitOfWork.Void<XtextResource>() { + override process(XtextResource resource) throws Exception { + if(resource !== null) { + val object = resource.getEObject(uri.fragment()); + val locationProvider = resource.getResourceServiceProvider().get(ILocationInFileProvider); + val location = if(crossReference !== null) + locationProvider.getSignificantTextRegion(object, crossReference, indexInList) + else + locationProvider.getSignificantTextRegion(object); + if(select) { + xtextEditor.selectAndReveal(location.getOffset(), location.getLength()); + } else { + xtextEditor.reveal(location.getOffset(), location.getLength()); + } + } + } + }); + } + } + } + + def protected IEditorPart openDefaultEditor(IFile file) throws PartInitException { + val page = getWorkbench().getActiveWorkbenchWindow().getActivePage(); + return IDE.openEditor(page, file); + } + + def protected IEditorPart openDefaultEditor(IStorage storage, URI uri) throws PartInitException { + val editorInput = EditorUtils.createEditorInput(storage); + val page = getWorkbench().getActiveWorkbenchWindow().getActivePage(); + return IDE.openEditor(page, editorInput, PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor(uri.lastSegment()).getId()); + } + + def protected IWorkbench getWorkbench() { + if(workbench === null) + throw new IllegalStateException("No workbench"); + return workbench; + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/outline/RBAModelOutlineTreeProvider.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/outline/RBAModelOutlineTreeProvider.xtend new file mode 100644 index 0000000..46aa0cd --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/outline/RBAModelOutlineTreeProvider.xtend @@ -0,0 +1,15 @@ +/* + * generated by Xtext 2.12.0 + */ +package rba.tool.editor.ui.outline + +import org.eclipse.xtext.ui.editor.outline.impl.DefaultOutlineTreeProvider + +/** + * Customization of the default outline structure. + * + * See https://www.eclipse.org/Xtext/documentation/310_eclipse_support.html#outline + */ +class RBAModelOutlineTreeProvider extends DefaultOutlineTreeProvider { + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/outline/RBATemplateModelOutlineTreeProvider.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/outline/RBATemplateModelOutlineTreeProvider.xtend new file mode 100644 index 0000000..d5da808 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/outline/RBATemplateModelOutlineTreeProvider.xtend @@ -0,0 +1,15 @@ +/* + * generated by Xtext 2.13.0 + */ +package rba.tool.editor.ui.outline + +import org.eclipse.xtext.ui.editor.outline.impl.DefaultOutlineTreeProvider + +/** + * Customization of the default outline structure. + * + * See https://www.eclipse.org/Xtext/documentation/310_eclipse_support.html#outline + */ +class RBATemplateModelOutlineTreeProvider extends DefaultOutlineTreeProvider { + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/properties/RBAServerPropertySettingPage.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/properties/RBAServerPropertySettingPage.java new file mode 100644 index 0000000..b2db925 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/properties/RBAServerPropertySettingPage.java @@ -0,0 +1,219 @@ +package rba.tool.editor.ui.properties; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang.StringUtils; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.Adapters; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbenchPropertyPage; +import org.eclipse.ui.dialogs.PropertyPage; +import rba.tool.editor.ui.messages.Messages; + +public class RBAServerPropertySettingPage extends PropertyPage implements IWorkbenchPropertyPage { + + private Text txt_IPAddress; + + private Text txt_AppName; + + private Text txt_Port; + + private static QualifiedName ID_IP_ADDRESS = new QualifiedName("IpAddress", "IpAddress"); + + private static QualifiedName ID_PORT = new QualifiedName("Port", "Port"); + + private static QualifiedName ID_APP_NAME = new QualifiedName("AppName", "AppName"); + + private static final String IPADDRESS_PATTERN = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"; + + private static final String DEF_IP = "localhost"; + + private static final String DEF_PORT = "65530"; + + private Pattern pattern; + + private Matcher matcher; + + public RBAServerPropertySettingPage() { + super(); + } + + protected Control createContents(Composite parent) { + Composite mComposite = new Composite(parent, SWT.NULL); + mComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true)); + mComposite.setLayout(new GridLayout()); + Label mylabel = new Label(mComposite, SWT.NONE); + mylabel.setLayoutData(new GridData()); + mylabel.setText(Messages.PAGE_INFORMATION); + + // Create a horizontal separator + Label separator = new Label(mComposite, SWT.HORIZONTAL | SWT.SEPARATOR); + separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Composite sComposite = new Composite(mComposite, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 4; + sComposite.setLayout(layout); + sComposite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); + + Label lbl_IPAddress = new Label(sComposite, SWT.NONE); + lbl_IPAddress.setLayoutData(new GridData()); + lbl_IPAddress.setText(Messages.LBL_IPADDRESS); + txt_IPAddress = new Text(sComposite, SWT.BORDER); + txt_IPAddress.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + txt_IPAddress.setText(getIP()); + + Label lbl_Port = new Label(sComposite, SWT.NONE); + lbl_Port.setLayoutData(new GridData()); + lbl_Port.setText(Messages.LBL_PORT); + txt_Port = new Text(sComposite, SWT.BORDER); + txt_Port.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + txt_Port.setText(getPort()); + + Label lbl_AppName = new Label(sComposite, SWT.NULL); + lbl_AppName.setLayoutData(new GridData(GridData.FILL)); + lbl_AppName.setText(Messages.LBL_APPNAME); + txt_AppName = new Text(sComposite, SWT.BORDER); + txt_AppName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + txt_AppName.setText(getName()); + return mComposite; + } + + protected String getIP() { + IResource resource = Adapters.adapt(getElement(), IResource.class); + try { + String value = resource.getPersistentProperty(ID_IP_ADDRESS); + if (value == null) + // Set Default IP Address. + return DEF_IP; + return value; + } catch (CoreException e) { + return e.getMessage(); + } + } + + protected void setIP(String ip) { + IResource resource = Adapters.adapt(getElement(), IResource.class); + String value = ip; + if (value.equals("")) + value = null; + try { + resource.setPersistentProperty(ID_IP_ADDRESS, value); + } catch (CoreException e) { + } + } + + protected String getPort() { + IResource resource = Adapters.adapt(getElement(), IResource.class); + try { + String value = resource.getPersistentProperty(ID_PORT); + if (value == null) + // Set Default Port Number. + return DEF_PORT; + return value; + } catch (CoreException e) { + return e.getMessage(); + } + } + + protected void setPort(String port) { + IResource resource = Adapters.adapt(getElement(), IResource.class); + String value = port; + if (value.equals("")) + value = null; + try { + resource.setPersistentProperty(ID_PORT, value); + } catch (CoreException e) { + } + } + + protected String getName() { + IResource resource = Adapters.adapt(getElement(), IResource.class); + try { + String value = resource.getPersistentProperty(ID_APP_NAME); + if (value == null) + return ""; + return value; + } catch (CoreException e) { + return e.getMessage(); + } + } + + protected void setName(String port) { + IResource resource = Adapters.adapt(getElement(), IResource.class); + String value = port; + if (value.equals("")) + value = null; + try { + resource.setPersistentProperty(ID_APP_NAME, value); + } catch (CoreException e) { + } + } + + @Override + public boolean performOk() { + IResource resource = Adapters.adapt(getElement(), IResource.class); + IProject project = resource.getProject(); + if (validate()) { + setIP(txt_IPAddress.getText()); + setPort(txt_Port.getText()); + // Set Default Project Name if txt_AppName is blank. + if (txt_AppName.getText().toString().equals("")) { + txt_AppName.setText(project.getName()); + } + setName(txt_AppName.getText()); + return super.performOk(); + } + return false; + } + + @Override + protected void performDefaults() { + super.performDefaults(); + txt_IPAddress.setText(DEF_IP); + txt_Port.setText(DEF_PORT); + txt_AppName.setText(""); + } + + // Check IP Address + public boolean validateIpAddress(final String ip) { + pattern = Pattern.compile(IPADDRESS_PATTERN); + matcher = pattern.matcher(ip); + return matcher.matches(); + } + + // Validation + protected boolean validate() { + if (StringUtils.isEmpty(txt_IPAddress.getText().toString())) { + setErrorMessage(Messages.ERR_EMPTY_IP); + return false; + } + if (!DEF_IP.equals(txt_IPAddress.getText().toString()) && !validateIpAddress(txt_IPAddress.getText())) { + setErrorMessage(Messages.IP_FORMAT_ERR); + return false; + } + if (StringUtils.isEmpty(txt_Port.getText().toString())) { + setErrorMessage(Messages.ERR_EMPTY_PORT); + return false; + } + if (!StringUtils.isNumeric(txt_Port.getText().toString())) { + setErrorMessage(Messages.PORT_NUMERIC_ERR); + return false; + } else { + setErrorMessage(null); + return true; + } + } + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/quickfix/RBAModelQuickfixProvider.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/quickfix/RBAModelQuickfixProvider.xtend new file mode 100644 index 0000000..2cd10e4 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/quickfix/RBAModelQuickfixProvider.xtend @@ -0,0 +1,24 @@ +/* + * generated by Xtext 2.12.0 + */ +package rba.tool.editor.ui.quickfix + +import org.eclipse.xtext.ui.editor.quickfix.DefaultQuickfixProvider + +/** + * Custom quickfixes. + * + * See https://www.eclipse.org/Xtext/documentation/310_eclipse_support.html#quick-fixes + */ +class RBAModelQuickfixProvider extends DefaultQuickfixProvider { + +// @Fix(RBAModelValidator.INVALID_NAME) +// def capitalizeName(Issue issue, IssueResolutionAcceptor acceptor) { +// acceptor.accept(issue, 'Capitalize name', 'Capitalize the name.', 'upcase.png') [ +// context | +// val xtextDocument = context.xtextDocument +// val firstLetter = xtextDocument.get(issue.offset, 1) +// xtextDocument.replace(issue.offset, 1, firstLetter.toUpperCase) +// ] +// } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/quickfix/RBATemplateModelQuickfixProvider.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/quickfix/RBATemplateModelQuickfixProvider.xtend new file mode 100644 index 0000000..900a53f --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/quickfix/RBATemplateModelQuickfixProvider.xtend @@ -0,0 +1,23 @@ +/* + * generated by Xtext 2.13.0 + */ +package rba.tool.editor.ui.quickfix + + +/** + * Custom quickfixes. + * + * See https://www.eclipse.org/Xtext/documentation/310_eclipse_support.html#quick-fixes + */ +class RBATemplateModelQuickfixProvider extends RBAModelQuickfixProvider { + +// @Fix(RBATemplateModelValidator.INVALID_NAME) +// def capitalizeName(Issue issue, IssueResolutionAcceptor acceptor) { +// acceptor.accept(issue, 'Capitalize name', 'Capitalize the name.', 'upcase.png') [ +// context | +// val xtextDocument = context.xtextDocument +// val firstLetter = xtextDocument.get(issue.offset, 1) +// xtextDocument.replace(issue.offset, 1, firstLetter.toUpperCase) +// ] +// } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/recordandplay/RBASimulationRecordPage.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/recordandplay/RBASimulationRecordPage.java new file mode 100644 index 0000000..c55581d --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/recordandplay/RBASimulationRecordPage.java @@ -0,0 +1,50 @@ +package rba.tool.editor.ui.recordandplay; + +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.preference.DirectoryFieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.preferences.ScopedPreferenceStore; + +public class RBASimulationRecordPage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { + + private DirectoryFieldEditor recordPathBrowser; + + private IPreferenceStore preferenceStore; + + private RBASimulationRecordSettingManager manager = RBASimulationRecordSettingManager.INSTANCE; + + private static final String DESCRIPTION = "RBA Simulation Record Path"; //$NON-NLS-1$ + + public RBASimulationRecordPage() { + super(GRID); + } + + @Override + protected void createFieldEditors() { + recordPathBrowser = new DirectoryFieldEditor("RbaToolRecordPath", "", getFieldEditorParent()); + addField(recordPathBrowser); + } + + @Override + public boolean performOk() { + manager.saveRecordFilePath(recordPathBrowser.getStringValue()); + return super.performOk(); + } + + @Override + public void init(IWorkbench workbench) { + setDescription(DESCRIPTION); + } + + @Override + public IPreferenceStore getPreferenceStore() { + if (preferenceStore == null) { + preferenceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE, manager.ID_PREFERENCE_NODE); + } + return preferenceStore; + } + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/recordandplay/RBASimulationRecordSettingManager.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/recordandplay/RBASimulationRecordSettingManager.java new file mode 100644 index 0000000..21ff588 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/recordandplay/RBASimulationRecordSettingManager.java @@ -0,0 +1,71 @@ +package rba.tool.editor.ui.recordandplay; + +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.osgi.service.prefs.Preferences; + + +public class RBASimulationRecordSettingManager { + + public static final RBASimulationRecordSettingManager INSTANCE = new RBASimulationRecordSettingManager(); + + public static final String ID_PREFERENCE_NODE = "rba.model.tool"; //$NON-NLS-1$ + + private static final String ID_PREFERENCES = "rba.model.tool.recordAndPlay"; //$NON-NLS-1$ + + private static final String ID_RECORD_PATH = "RecordFilePath"; //$NON-NLS-1$ + + /** + * Save record file path + * @param path + */ + public void saveRecordFilePath(final String path) { + final String oldPath = RBASimulationRecordSettingManager.INSTANCE.getRecordFilePath(); + if (!equals(oldPath, path)) { + IEclipsePreferences preferences = getPreferences(); + Preferences sub = preferences.node(ID_PREFERENCES); + sub.put(ID_RECORD_PATH, path); + } + } + + /** + * Get record file path + * @return path + */ + public String getRecordFilePath() { + IEclipsePreferences preferences = getPreferences(); + Preferences sub = preferences.node(ID_PREFERENCES); + return sub.get(ID_RECORD_PATH, ""); + } + + private IEclipsePreferences getPreferences() { + return InstanceScope.INSTANCE.getNode(ID_PREFERENCE_NODE); + } + + /** + * String equality check + * @param cs1 + * @param cs2 + * @return + */ + private boolean equals(String cs1, String cs2) { + + boolean result = false; + + if (cs1 == cs2) { + result = true; + } + if (cs1 == null || cs2 == null) { + result = false; + } + if (cs1.length() != cs2.length()) { + result = false; + } + if (cs1 instanceof String && cs2 instanceof String) { + result = cs1.equals(cs2); + } + + return result; + } + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/resource/RBADocumentResourceSetProvider.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/resource/RBADocumentResourceSetProvider.xtend new file mode 100644 index 0000000..33cd0dc --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/resource/RBADocumentResourceSetProvider.xtend @@ -0,0 +1,27 @@ +package rba.tool.editor.ui.resource + +import com.google.inject.Singleton +import org.eclipse.core.resources.IProject +import org.eclipse.emf.ecore.resource.ResourceSet +import org.eclipse.swt.widgets.Display +import org.eclipse.xtext.ui.resource.SimpleResourceSetProvider +import rba.tool.editor.ui.editor.model.manager.ResourceManagerUI +import rba.tool.editor.ui.util.UnitOfProgressUtil + +@Singleton +class RBADocumentResourceSetProvider extends SimpleResourceSetProvider { + + override get(IProject project) { + val ResourceSet result = super.get(project); + if(project !== null) { + Display.getDefault().asyncExec(new Runnable() { + override run() { + if(ResourceManagerUI.INSTANCE.currentProject === null) { + UnitOfProgressUtil.doProjectSwitchProgress(project, false); + } + } + }); + } + return result; + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/resource/RBAModelResourceSetProvider.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/resource/RBAModelResourceSetProvider.xtend new file mode 100644 index 0000000..5c4a6dd --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/resource/RBAModelResourceSetProvider.xtend @@ -0,0 +1,37 @@ +package rba.tool.editor.ui.resource + +import com.google.inject.Singleton +import java.util.concurrent.ConcurrentHashMap +import org.eclipse.core.resources.IProject +import org.eclipse.emf.ecore.resource.ResourceSet +import org.eclipse.xtext.ui.resource.SimpleResourceSetProvider + +@Singleton +class RBAModelResourceSetProvider extends SimpleResourceSetProvider { + + private ConcurrentHashMap<IProject, ResourceSet> projectXtextResourceSetMap = new ConcurrentHashMap<IProject, ResourceSet>(); + + override get(IProject project) { + val ResourceSet result = super.get(project); + if(project !== null) { + if(projectXtextResourceSetMap.containsKey(project)) { + projectXtextResourceSetMap.remove(project); + } + projectXtextResourceSetMap.put(project, result); + } + return result; + } + + def public ResourceSet getResourceSet(IProject project) { + if(project === null) { + return get(project); + } else { + return projectXtextResourceSetMap.get(project) ?: get(project); + } + } + + def public void setResourceSet(IProject project, ResourceSet resourceSet) { + projectXtextResourceSetMap.put(project, resourceSet); + } + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/resource/RBAModelResourceUIServiceProvider.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/resource/RBAModelResourceUIServiceProvider.xtend new file mode 100644 index 0000000..fb795a1 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/resource/RBAModelResourceUIServiceProvider.xtend @@ -0,0 +1,36 @@ +package rba.tool.editor.ui.resource + +import com.google.inject.Inject +import org.eclipse.core.resources.IFile +import org.eclipse.core.resources.IStorage +import org.eclipse.core.resources.IWorkspace +import org.eclipse.emf.common.util.URI +import org.eclipse.xtext.resource.IResourceServiceProvider +import org.eclipse.xtext.ui.resource.DefaultResourceUIServiceProvider +import rba.tool.editor.ui.wizard.ExtendRBAModelProjectCreator + +class RBAModelResourceUIServiceProvider extends DefaultResourceUIServiceProvider { + + @Inject private IWorkspace workspace; + + @Inject private ExtendRBAModelProjectCreator projectCreator; + + @Inject public new(IResourceServiceProvider delegate) { + super(delegate) + } + + override canHandle(URI uri, IStorage storage) { + if(!super.canHandle(uri, storage)) { + return false; + } + if(workspace !== null) { + if(storage instanceof IFile) { + val folderName = URI.decode(if(uri.segmentCount > 3) uri.segment(2) else null); + if(!projectCreator.modelFolderName.equals(folderName)) { + return false; + } + } + } + return true; + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/syntaxcoloring/RBAModelAntlrTokenToAttributeIdMapper.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/syntaxcoloring/RBAModelAntlrTokenToAttributeIdMapper.xtend new file mode 100644 index 0000000..f4118b9 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/syntaxcoloring/RBAModelAntlrTokenToAttributeIdMapper.xtend @@ -0,0 +1,14 @@ +package rba.tool.editor.ui.syntaxcoloring + +import org.eclipse.xtext.ui.editor.syntaxcoloring.DefaultAntlrTokenToAttributeIdMapper + +class RBAModelAntlrTokenToAttributeIdMapper extends DefaultAntlrTokenToAttributeIdMapper { + + override protected calculateId(String tokenName, int tokenType) { + if ("\'Area\'".equals(tokenName)) { + return RBAModelHighlightingConfiguration.AREA; + } + return super.calculateId(tokenName, tokenType); + } + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/syntaxcoloring/RBAModelHighlightingConfiguration.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/syntaxcoloring/RBAModelHighlightingConfiguration.xtend new file mode 100644 index 0000000..266be2a --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/syntaxcoloring/RBAModelHighlightingConfiguration.xtend @@ -0,0 +1,27 @@ +package rba.tool.editor.ui.syntaxcoloring + +import org.eclipse.swt.SWT +import org.eclipse.swt.graphics.RGB +import org.eclipse.xtext.ui.editor.syntaxcoloring.DefaultHighlightingConfiguration +import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightingConfigurationAcceptor +import org.eclipse.xtext.ui.editor.utils.TextStyle + +class RBAModelHighlightingConfiguration extends DefaultHighlightingConfiguration { + + public static final String AREA = "Area"; + + override public void configure(IHighlightingConfigurationAcceptor acceptor) { + super.configure(acceptor); + acceptor.acceptDefaultHighlighting(AREA, "Area", areaStyle()); + } + + def public TextStyle areaStyle() { + val textStyle = defaultTextStyle().copy(); + //val color = JFaceResources.getColorRegistry().getRGB(JFacePreferences.ACTIVE_HYPERLINK_COLOR); + textStyle.color = new RGB(0, 0, 255); + //val backgroundColor = JFaceResources.getColorRegistry().getRGB(JFacePreferences.CONTENT_ASSIST_FOREGROUND_COLOR); + //textStyle.backgroundColor = backgroundColor; + textStyle.setStyle(SWT.BOLD); + return textStyle; + } +}
\ No newline at end of file diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/template/RBATemplateApplyModule.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/template/RBATemplateApplyModule.xtend new file mode 100644 index 0000000..b2fc0fa --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/template/RBATemplateApplyModule.xtend @@ -0,0 +1,13 @@ +package rba.tool.editor.ui.template + +import com.google.inject.Module +import com.google.inject.Binder +import org.eclipse.xtext.builder.impl.ToBeBuiltComputer + +class RBATemplateApplyModule implements Module { + + override configure(Binder binder) { + binder.bind(ToBeBuiltComputer).to(RBATemplateApplyToBeBuiltComputer) + } + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/template/RBATemplateApplyToBeBuiltComputer.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/template/RBATemplateApplyToBeBuiltComputer.xtend new file mode 100644 index 0000000..133482d --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/template/RBATemplateApplyToBeBuiltComputer.xtend @@ -0,0 +1,23 @@ +package rba.tool.editor.ui.template + +import javax.inject.Inject +import org.eclipse.core.resources.IFile +import org.eclipse.core.resources.IStorage +import org.eclipse.emf.common.util.URI +import org.eclipse.xtext.builder.impl.ToBeBuiltComputer +import org.eclipse.xtext.ui.resource.IStorage2UriMapper +import rba.tool.editor.util.RBAModelEditorNameUtil + +class RBATemplateApplyToBeBuiltComputer extends ToBeBuiltComputer { + @Inject + private IStorage2UriMapper mapper; + + override protected getUri(IStorage file) { + var uri = mapper.getUri(file); + var IStorage f = file + if (uri !== null && !isValid(uri, f)) { + uri = null + } + return uri; + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/util/CharacterUtil.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/util/CharacterUtil.xtend new file mode 100644 index 0000000..28cbe08 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/util/CharacterUtil.xtend @@ -0,0 +1,10 @@ +package rba.tool.editor.ui.util + +import org.eclipse.xtext.Keyword + +class CharacterUtil { + + def public static boolean isKeywordWorthyToPropose(Keyword keyword) { + return keyword.getValue().length() > 1 && Character.isLetter(keyword.getValue().charAt(0)); + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/util/UnitOfProgressUtil.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/util/UnitOfProgressUtil.java new file mode 100644 index 0000000..3fd41b2 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/util/UnitOfProgressUtil.java @@ -0,0 +1,84 @@ +package rba.tool.editor.ui.util; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; + +import rba.tool.editor.ui.editor.model.manager.ResourceManagerUI; +import rba.tool.editor.ui.util.concurrent.IUnitOfProgress; + +public class UnitOfProgressUtil { + + public static void doProjectSwitchProgress(final IProject project, final boolean showConfirmDialog) throws Exception { + IUnitOfProgress.Void<IProject> progress = new IUnitOfProgress.Void<IProject>() { + @Override + public void process(IProject state) throws Exception { + Job projectSwitchJob = new Job("[RBA Tool]- Switch Project") { + @Override + protected IStatus run(IProgressMonitor monitor) { + monitor.beginTask("Switch Project...", 1); //$NON-NLS-1$ + try { + ResourceManagerUI.INSTANCE.switchToProject(state, monitor); + } catch (Exception e) { + e.printStackTrace(); + return Status.CANCEL_STATUS; + } finally { + monitor.done(); + } + return Status.OK_STATUS; + } + + @Override + public boolean belongsTo(Object family) { + return IUnitOfProgress.FAMILY_UNIT_OF_PROGRESS == family; + } + }; + projectSwitchJob.schedule(); + } + }; + + if (ResourceManagerUI.INSTANCE.doConfirm(project, showConfirmDialog)) { + progress.exec(project); + } + } + + public static void doProjectSwitchProgressWithRunnable(final IProject project, final boolean showConfirmDialog, final Runnable run) throws Exception { + IUnitOfProgress.Void<IProject> progress = new IUnitOfProgress.Void<IProject>() { + @Override + public void process(IProject state) throws Exception { + Job projectSwitchJob = new Job("[RBA Tool]- Switch Project") { + @Override + protected IStatus run(IProgressMonitor monitor) { + monitor.beginTask("Switch Project...", 1); //$NON-NLS-1$ + try { + ResourceManagerUI.INSTANCE.switchToProject(state, monitor); + if (monitor.isCanceled()) { + throw new InterruptedException(); + } + run.run(); + } catch (Exception e) { + e.printStackTrace(); + return Status.CANCEL_STATUS; + } finally { + monitor.done(); + } + return Status.OK_STATUS; + } + + @Override + public boolean belongsTo(Object family) { + return IUnitOfProgress.FAMILY_UNIT_OF_PROGRESS == family; + } + }; + projectSwitchJob.schedule(); + } + }; + + if (ResourceManagerUI.INSTANCE.doConfirm(project, showConfirmDialog)) { + progress.exec(project); + } + } + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/util/concurrent/AbstractSwitchProjectProgress.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/util/concurrent/AbstractSwitchProjectProgress.java new file mode 100644 index 0000000..2d640d3 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/util/concurrent/AbstractSwitchProjectProgress.java @@ -0,0 +1,40 @@ +package rba.tool.editor.ui.util.concurrent; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; + +import rba.tool.editor.ui.editor.model.manager.ResourceManagerUI; + +public abstract class AbstractSwitchProjectProgress<R, P> implements IUnitOfProgress<Object, IProject> { + + private final boolean showConfirmDialog; + + public AbstractSwitchProjectProgress() { + this(true); + } + + public AbstractSwitchProjectProgress(boolean showConfirmDialog) { + this.showConfirmDialog = showConfirmDialog; + } + + @Override + public R exec(IProject state) throws Exception { + SubMonitor progress = SubMonitor.convert(null, 6); + if (!ResourceManagerUI.INSTANCE.isCurrentProject(state)) { + if (ResourceManagerUI.INSTANCE.doConfirm(state, showConfirmDialog)) { + ResourceManagerUI.INSTANCE.switchToProject(state, progress.newChild(2)); + + if (progress.isCanceled()) { + throw new InterruptedException(); + } + return internalExec(state, progress.newChild(4)); + } else { + throw new InterruptedException(); + } + } + return internalExec(state, progress.newChild(4)); + } + + protected abstract R internalExec(IProject state, IProgressMonitor monitor); +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/util/concurrent/IUnitOfProgress.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/util/concurrent/IUnitOfProgress.java new file mode 100644 index 0000000..f7141b1 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/util/concurrent/IUnitOfProgress.java @@ -0,0 +1,18 @@ +package rba.tool.editor.ui.util.concurrent; + +public interface IUnitOfProgress<R, P> { + + public static final Object FAMILY_UNIT_OF_PROGRESS = new Object(); + + R exec(P state) throws Exception; + + public static abstract class Void<T> implements IUnitOfProgress<Object, T> { + @Override + public final Object exec(T state) throws Exception { + process(state); + return null; + } + + public abstract void process(T state) throws Exception; + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/ExtendRBAModelProjectCreator.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/ExtendRBAModelProjectCreator.xtend new file mode 100644 index 0000000..70114cc --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/ExtendRBAModelProjectCreator.xtend @@ -0,0 +1,12 @@ +package rba.tool.editor.ui.wizard + +import rba.tool.editor.ui.wizard.RBAModelProjectCreator +import rba.tool.editor.util.RBAModelEditorNameUtil + +class ExtendRBAModelProjectCreator extends RBAModelProjectCreator { + + override public getModelFolderName() { + return RBAModelEditorNameUtil.BUILD_FOLDER_NAME; + } + +}
\ No newline at end of file diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBAEmptyModelNewProjectWizardEx.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBAEmptyModelNewProjectWizardEx.java new file mode 100644 index 0000000..f845fa9 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBAEmptyModelNewProjectWizardEx.java @@ -0,0 +1,48 @@ +package rba.tool.editor.ui.wizard;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Paths;
+
+import org.apache.commons.io.FileUtils;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.xtext.ui.wizard.IProjectCreator;
+
+import com.google.inject.Inject;
+
+public class RBAEmptyModelNewProjectWizardEx extends RBAModelNewProjectWizardEx {
+
+ private static final String DEFAULT_TEMPLATE_PATH = "RBATool\\empty_project"; //$NON-NLS-1$
+
+ @Inject
+ public RBAEmptyModelNewProjectWizardEx(IProjectCreator projectCreator) {
+ super(projectCreator);
+ }
+
+ @Override
+ protected void copyResources(IProject project) throws IOException, URISyntaxException, CoreException {
+ URL installLocationUrl = Platform.getInstallLocation().getURL();
+ String installLocationPath = new File(installLocationUrl.getPath()).toString();
+
+ java.nio.file.Path runtimePath = Paths.get(installLocationPath, DEFAULT_TEMPLATE_PATH);
+
+ URI locationURI = project.getLocationURI();
+
+ File srcRuntime = new File(runtimePath.toString());
+ File dst = new File(locationURI.getPath());
+
+ if (srcRuntime.exists()) {
+ FileUtils.copyDirectory(srcRuntime, dst);
+ }
+
+ project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
+ }
+
+}
diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBAModelNewProjectWizardEx.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBAModelNewProjectWizardEx.java new file mode 100644 index 0000000..47cda5f --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBAModelNewProjectWizardEx.java @@ -0,0 +1,115 @@ +package rba.tool.editor.ui.wizard; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Paths; + +import org.apache.commons.io.FileUtils; +import org.eclipse.core.internal.events.BuildCommand; +import org.eclipse.core.resources.ICommand; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.ide.IDE; +import org.eclipse.xtext.ui.wizard.IProjectCreator; + +import com.google.inject.Inject; + +public class RBAModelNewProjectWizardEx extends RBAModelNewProjectWizard { + + private static final String DEFAULT_TEMPLATE_PATH = "RBATool\\Project"; //$NON-NLS-1$ + + @Inject + public RBAModelNewProjectWizardEx(IProjectCreator projectCreator) { + super(projectCreator); + } + + @Override + public boolean performFinish() { + + boolean performFinish = super.performFinish(); + + String projectName = getMainPage().getProjectName(); + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + + try { + setProjectSettings(project, projectName); + copyResources(project); + + String pathStr = project.getName() + "/model"; + IFolder ifolder = ResourcesPlugin.getWorkspace().getRoot().getFolder(new Path(pathStr)); + + if (ifolder.exists()) { + IResource[] members = ifolder.members(); + if (members.length > 0 && members[0] instanceof IFile) { + IFile ifile = (IFile) members[0]; + IWorkbench workbench = PlatformUI.getWorkbench(); + IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); + try { + IDE.openEditor(window.getActivePage(), ifile); + } catch (PartInitException e) { + e.printStackTrace(); + } + } + } + + } catch (IOException e) { + e.printStackTrace(); + } catch (URISyntaxException e) { + e.printStackTrace(); + } catch (CoreException e) { + e.printStackTrace(); + } + + return performFinish; + } + + @SuppressWarnings("restriction") + private void setProjectSettings(IProject project, String projectName) throws CoreException { + + IProjectDescription description = ResourcesPlugin.getWorkspace().getRoot().getWorkspace().newProjectDescription(projectName); + BuildCommand rbacommand = new BuildCommand(); + rbacommand.setBuilderName("rba.tool.RBAToolBuilder"); //$NON-NLS-1$ + BuildCommand xcommand = new BuildCommand(); + xcommand.setBuilderName("org.eclipse.xtext.ui.shared.xtextBuilder"); //$NON-NLS-1$ + ICommand[] commands = new BuildCommand[] { rbacommand, xcommand }; + description.setBuildSpec(commands); + + String[] natures = new String[] { "org.eclipse.xtext.ui.shared.xtextNature" }; //$NON-NLS-1$ //$NON-NLS-2$ + description.setNatureIds(natures); + + project.setDescription(description, new NullProgressMonitor()); + } + + protected void copyResources(IProject project) throws IOException, URISyntaxException, CoreException { + URL installLocationUrl = Platform.getInstallLocation().getURL(); + String installLocationPath = new File(installLocationUrl.getPath()).toString(); + + java.nio.file.Path runtimePath = Paths.get(installLocationPath, DEFAULT_TEMPLATE_PATH); + + URI locationURI = project.getLocationURI(); + + File srcRuntime = new File(runtimePath.toString()); + File dst = new File(locationURI.getPath()); + + if (srcRuntime.exists()) { + FileUtils.copyDirectory(srcRuntime, dst); + } + + project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBAModelNewProjectWizardInitialContents.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBAModelNewProjectWizardInitialContents.xtend new file mode 100644 index 0000000..61ded06 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBAModelNewProjectWizardInitialContents.xtend @@ -0,0 +1,12 @@ +/* + * generated by Xtext 2.13.0 + */ +package rba.tool.editor.ui.wizard + +import org.eclipse.xtext.generator.IFileSystemAccess2 + +class RBAModelNewProjectWizardInitialContents { + + def generateInitialContents(IFileSystemAccess2 fsa) { + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBAModelProjectInfo.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBAModelProjectInfo.java new file mode 100644 index 0000000..7d6894e --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBAModelProjectInfo.java @@ -0,0 +1,10 @@ +/* + * generated by Xtext 2.12.0 + */ +package rba.tool.editor.ui.wizard; + +import org.eclipse.xtext.ui.wizard.DefaultProjectInfo; + +public class RBAModelProjectInfo extends DefaultProjectInfo { + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBAModelWizardNewProjectCreationPage.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBAModelWizardNewProjectCreationPage.java new file mode 100644 index 0000000..f207276 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBAModelWizardNewProjectCreationPage.java @@ -0,0 +1,14 @@ +/* + * generated by Xtext 2.12.0 + */ +package rba.tool.editor.ui.wizard; + +import org.eclipse.ui.dialogs.WizardNewProjectCreationPage; + +public class RBAModelWizardNewProjectCreationPage extends WizardNewProjectCreationPage { + + public RBAModelWizardNewProjectCreationPage(String pageName) { + super(pageName); + } + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBATemplateModelNewProjectWizardInitialContents.xtend b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBATemplateModelNewProjectWizardInitialContents.xtend new file mode 100644 index 0000000..d2c9c92 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBATemplateModelNewProjectWizardInitialContents.xtend @@ -0,0 +1,26 @@ +/* + * generated by Xtext 2.13.0 + */ +package rba.tool.editor.ui.wizard + + +import com.google.inject.Inject +import org.eclipse.xtext.generator.IFileSystemAccess2 +import org.eclipse.xtext.resource.FileExtensionProvider + +class RBATemplateModelNewProjectWizardInitialContents { + @Inject + FileExtensionProvider fileExtensionProvider + + def generateInitialContents(IFileSystemAccess2 fsa) { + fsa.generateFile( + "src/model/Model." + fileExtensionProvider.primaryFileExtension, + ''' + /* + * This is an example model + */ + Hello Xtext! + ''' + ) + } +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBATemplateModelProjectInfo.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBATemplateModelProjectInfo.java new file mode 100644 index 0000000..c22d512 --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBATemplateModelProjectInfo.java @@ -0,0 +1,10 @@ +/* + * generated by Xtext 2.13.0 + */ +package rba.tool.editor.ui.wizard; + +import org.eclipse.xtext.ui.wizard.DefaultProjectInfo; + +public class RBATemplateModelProjectInfo extends DefaultProjectInfo { + +} diff --git a/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBATemplateModelWizardNewProjectCreationPage.java b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBATemplateModelWizardNewProjectCreationPage.java new file mode 100644 index 0000000..27da49b --- /dev/null +++ b/rba.tool.editor.ui/src/rba/tool/editor/ui/wizard/RBATemplateModelWizardNewProjectCreationPage.java @@ -0,0 +1,14 @@ +/* + * generated by Xtext 2.13.0 + */ +package rba.tool.editor.ui.wizard; + +import org.eclipse.ui.dialogs.WizardNewProjectCreationPage; + +public class RBATemplateModelWizardNewProjectCreationPage extends WizardNewProjectCreationPage { + + public RBATemplateModelWizardNewProjectCreationPage(String pageName) { + super(pageName); + } + +} |