Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Belle2018-10-11 10:15:37 +0000
committerJan Belle2019-03-08 16:12:05 +0000
commitd47fab84d8d7df4b9d2270d8d153ee57b92f4a83 (patch)
tree58f0001cf31425426070eca41913be8b62a7ad0f
parentc511bcf1062cc5d8af65be5092a164d62cc017f3 (diff)
downloadorg.eclipse.etrice-d47fab84d8d7df4b9d2270d8d153ee57b92f4a83.tar.gz
org.eclipse.etrice-d47fab84d8d7df4b9d2270d8d153ee57b92f4a83.tar.xz
org.eclipse.etrice-d47fab84d8d7df4b9d2270d8d153ee57b92f4a83.zip
[core] Implement uri independent import system
-rw-r--r--plugins/org.eclipse.etrice.core.common.ui/META-INF/MANIFEST.MF8
-rw-r--r--plugins/org.eclipse.etrice.core.common.ui/plugin.xml6
-rw-r--r--plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/ETriceCoreCommonActivator.java23
-rw-r--r--plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/SharedContributionModule.java37
-rw-r--r--plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/hover/KeywordHoverProvider.java4
-rw-r--r--plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/linking/ImportAwareHyperlinkHelper.java38
-rw-r--r--plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathChangeListener.java68
-rw-r--r--plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathDescription.java171
-rw-r--r--plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathManager.java246
-rw-r--r--plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathResourceSetInitializer.java57
-rw-r--r--plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/WorkspaceModelPath.java141
-rw-r--r--plugins/org.eclipse.etrice.core.common/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.etrice.core.common/build.gradle2
-rw-r--r--plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/CompoundGlobalScopeProvider.java46
-rw-r--r--plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/ModelLocator.java37
-rw-r--r--plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/ModelPathFileExtensionFilter.java48
-rw-r--r--plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/ModelPathGlobalScopeProvider.java215
-rw-r--r--plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/StandardModelLocator.java3
-rw-r--r--plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/validation/BaseJavaValidator.java37
-rw-r--r--plugins/org.eclipse.etrice.core.config/src-gen/org/eclipse/etrice/core/AbstractConfigRuntimeModule.java4
-rw-r--r--plugins/org.eclipse.etrice.core.config/src/org/eclipse/etrice/core/ConfigRuntimeModule.java24
-rw-r--r--plugins/org.eclipse.etrice.core.config/src/org/eclipse/etrice/core/GenerateConfig.mwe24
-rw-r--r--plugins/org.eclipse.etrice.core.etmap/src-gen/org/eclipse/etrice/core/etmap/AbstractETMapRuntimeModule.java4
-rw-r--r--plugins/org.eclipse.etrice.core.etmap/src/org/eclipse/etrice/core/etmap/ETMapRuntimeModule.java18
-rw-r--r--plugins/org.eclipse.etrice.core.etmap/src/org/eclipse/etrice/core/etmap/GenerateETMap.mwe22
-rw-r--r--plugins/org.eclipse.etrice.core.etphys/src-gen/org/eclipse/etrice/core/etphys/AbstractETPhysRuntimeModule.java4
-rw-r--r--plugins/org.eclipse.etrice.core.etphys/src/org/eclipse/etrice/core/etphys/ETPhysRuntimeModule.java8
-rw-r--r--plugins/org.eclipse.etrice.core.etphys/src/org/eclipse/etrice/core/etphys/GenerateETPhys.mwe24
-rw-r--r--plugins/org.eclipse.etrice.core.fsm/src-gen/org/eclipse/etrice/core/fsm/AbstractFSMRuntimeModule.java4
-rw-r--r--plugins/org.eclipse.etrice.core.fsm/src/org/eclipse/etrice/core/fsm/GenerateFSM.mwe22
-rw-r--r--plugins/org.eclipse.etrice.core.room/src-gen/org/eclipse/etrice/core/AbstractRoomRuntimeModule.java4
-rw-r--r--plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/GenerateRoom.mwe22
-rw-r--r--plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/RoomRuntimeModule.java22
-rw-r--r--plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/GeneratorApplication.java3
-rw-r--r--plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/args/Arguments.java21
-rw-r--r--plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/FileSystemModelPath.java139
-rw-r--r--plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/GeneratorResourceLoader.java98
-rw-r--r--plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/IGeneratorResourceLoader.java3
-rw-r--r--plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/IModelPath.java54
-rw-r--r--plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/IModelPathProvider.java33
-rw-r--r--plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/ResourceSetModelPathProvider.java38
-rw-r--r--plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/setup/GeneratorApplicationOptions.java8
-rw-r--r--plugins/org.eclipse.etrice.generator.launch/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.etrice.generator.launch/src/org/eclipse/etrice/generator/launch/GeneratorLaunchConfigurationDelegate.java23
-rw-r--r--plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/ModelLoader.java6
-rw-r--r--plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMDiagramBehavior.java3
-rw-r--r--plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/CustomResourceSetProvider.java126
-rw-r--r--plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/CustomUpdateBehavior.java6
48 files changed, 1609 insertions, 251 deletions
diff --git a/plugins/org.eclipse.etrice.core.common.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.etrice.core.common.ui/META-INF/MANIFEST.MF
index 629ea41bc..e193bc06a 100644
--- a/plugins/org.eclipse.etrice.core.common.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.etrice.core.common.ui/META-INF/MANIFEST.MF
@@ -4,7 +4,6 @@ Bundle-Name: Common eTrice DSL UI classes
Bundle-Vendor: Eclipse eTrice
Bundle-Version: 2.0.0.qualifier
Bundle-SymbolicName: org.eclipse.etrice.core.common.ui; singleton:=true
-Bundle-ActivationPolicy: lazy
Require-Bundle: org.eclipse.etrice.core.common;visibility:=reexport,
org.eclipse.xtext.ui;bundle-version="2.6.0",
org.eclipse.ui.editors;bundle-version="3.5.0",
@@ -18,7 +17,8 @@ Require-Bundle: org.eclipse.etrice.core.common;visibility:=reexport,
org.eclipse.compare,
org.eclipse.core.filesystem;bundle-version="1.3.0",
org.eclipse.help,
- org.eclipse.xtext.xbase.lib
+ org.eclipse.xtext.xbase.lib,
+ org.eclipse.etrice.generator.base
Import-Package: org.apache.log4j,
org.eclipse.xtext.xbase.lib
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
@@ -34,6 +34,8 @@ Export-Package: org.eclipse.etrice.core.common.ui.autoedit,
org.eclipse.etrice.core.common.ui.internal,
org.eclipse.etrice.core.common.ui.labeling,
org.eclipse.etrice.core.common.ui.linking,
+ org.eclipse.etrice.core.common.ui.modelpath,
org.eclipse.etrice.core.common.ui.quickfix
-Bundle-Activator: org.eclipse.etrice.core.common.ui.ETriceCoreCommonActivator
+Bundle-Activator: org.eclipse.etrice.core.common.ui.internal.BaseActivator
Automatic-Module-Name: org.eclipse.etrice.core.common.ui
+Bundle-ActivationPolicy: lazy
diff --git a/plugins/org.eclipse.etrice.core.common.ui/plugin.xml b/plugins/org.eclipse.etrice.core.common.ui/plugin.xml
index f91ef7aac..e4deda339 100644
--- a/plugins/org.eclipse.etrice.core.common.ui/plugin.xml
+++ b/plugins/org.eclipse.etrice.core.common.ui/plugin.xml
@@ -392,5 +392,11 @@
extensions="etbase">
</provider>
</extension>
+ <extension
+ point="org.eclipse.xtext.ui.shared.sharedStateContributingModule">
+ <module
+ class="org.eclipse.etrice.core.common.ui.SharedContributionModule">
+ </module>
+ org.eclipse.etrice.core.common.ui.SharedContributionModule </extension>
</plugin>
diff --git a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/ETriceCoreCommonActivator.java b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/ETriceCoreCommonActivator.java
deleted file mode 100644
index fb8e463ab..000000000
--- a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/ETriceCoreCommonActivator.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.eclipse.etrice.core.common.ui;
-
-import org.eclipse.etrice.core.common.scoping.ModelLocator;
-import org.eclipse.etrice.core.common.ui.internal.BaseActivator;
-import org.osgi.framework.BundleContext;
-
-import com.google.inject.Injector;
-
-public class ETriceCoreCommonActivator extends BaseActivator {
-
- /* (non-Javadoc)
- * @see org.franca.core.dsl.ui.internal.FrancaIDLActivator#start(org.osgi.framework.BundleContext)
- */
- @Override
- public void start(BundleContext context) throws Exception {
- super.start(context);
-
- Injector injector = getInjector(ORG_ECLIPSE_ETRICE_CORE_COMMON_BASE);
- ModelLocator ml = injector.getInstance(ModelLocator.class);
- ml.loadExtensions();
- }
-
-}
diff --git a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/SharedContributionModule.java b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/SharedContributionModule.java
new file mode 100644
index 000000000..508b8c698
--- /dev/null
+++ b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/SharedContributionModule.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+* Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+* All rights reserved.
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+*
+* SPDX-License-Identifier: EPL-2.0
+*
+* CONTRIBUTORS:
+* Jan Belle (initial contribution)
+*
+ *******************************************************************************/
+
+package org.eclipse.etrice.core.common.ui;
+
+import org.eclipse.etrice.core.common.ui.modelpath.ModelPathChangeListener;
+import org.eclipse.etrice.core.common.ui.modelpath.ModelPathResourceSetInitializer;
+import org.eclipse.xtext.ui.resource.IResourceSetInitializer;
+import org.eclipse.xtext.ui.shared.contribution.IEagerContribution;
+
+import com.google.inject.Binder;
+import com.google.inject.Module;
+
+/**
+ * @see org.eclipse.xtext.ui.shared.sharedStateContributingModule
+ */
+public class SharedContributionModule implements Module {
+
+ @Override
+ public void configure(Binder binder) {
+ binder.bind(IEagerContribution.class).to(ModelPathChangeListener.class);
+ binder.bind(IResourceSetInitializer.class).to(ModelPathResourceSetInitializer.class);
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/hover/KeywordHoverProvider.java b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/hover/KeywordHoverProvider.java
index 4df362c36..36f6bcc9f 100644
--- a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/hover/KeywordHoverProvider.java
+++ b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/hover/KeywordHoverProvider.java
@@ -19,7 +19,7 @@ import java.io.IOException;
import java.net.URL;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.etrice.core.common.ui.ETriceCoreCommonActivator;
+import org.eclipse.etrice.core.common.ui.internal.BaseActivator;
import org.eclipse.jface.internal.text.html.HTMLPrinter;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.viewers.ILabelProvider;
@@ -78,7 +78,7 @@ public class KeywordHoverProvider extends DefaultEObjectHoverProvider {
url = plugin.getBundle().getEntry(styleSheetFileName);
}
else {
- url = ETriceCoreCommonActivator.getInstance().getBundle().getEntry("/eTriceKeywordHoverStyle.css");
+ url = BaseActivator.getInstance().getBundle().getEntry("/eTriceKeywordHoverStyle.css");
}
styleSheet = Files.readStreamIntoString(url.openStream());
}
diff --git a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/linking/ImportAwareHyperlinkHelper.java b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/linking/ImportAwareHyperlinkHelper.java
index 3b0a5d99c..a96071feb 100644
--- a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/linking/ImportAwareHyperlinkHelper.java
+++ b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/linking/ImportAwareHyperlinkHelper.java
@@ -17,21 +17,30 @@ package org.eclipse.etrice.core.common.ui.linking;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.etrice.core.common.base.Import;
import org.eclipse.etrice.core.common.scoping.ModelLocatorUriResolver;
import org.eclipse.jface.text.Region;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.RuleCall;
+import org.eclipse.xtext.naming.IQualifiedNameConverter;
+import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.parser.IParseResult;
import org.eclipse.xtext.resource.EObjectAtOffsetHelper;
+import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.scoping.IGlobalScopeProvider;
+import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.ui.editor.hyperlinking.HyperlinkHelper;
import org.eclipse.xtext.ui.editor.hyperlinking.IHyperlinkAcceptor;
import org.eclipse.xtext.ui.editor.hyperlinking.XtextHyperlink;
+import com.google.common.base.Predicates;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -49,6 +58,12 @@ public class ImportAwareHyperlinkHelper extends HyperlinkHelper {
@Inject
protected EObjectAtOffsetHelper eObjectAtOffsetHelper;
+
+ @Inject
+ protected IGlobalScopeProvider globalScopeProvider;
+
+ @Inject
+ protected IQualifiedNameConverter nameConverter;
/*
* (non-Javadoc)
@@ -74,6 +89,29 @@ public class ImportAwareHyperlinkHelper extends HyperlinkHelper {
return null;
Import importObj = (Import) eObject;
+
+ // Create hyperlink based on the qualified name of the import using the global scope provider
+ String name = importObj.getImportedNamespace();
+ if(name != null) {
+ QualifiedName qualifiedName = nameConverter.toQualifiedName(name);
+ if(!qualifiedName.getLastSegment().equals("*")) {
+ EReference reference = EcoreFactory.eINSTANCE.createEReference();
+ reference.setEType(EcorePackage.eINSTANCE.getEObject());
+ IScope scope = globalScopeProvider.getScope(resource, reference, Predicates.alwaysTrue());
+ IEObjectDescription eod = scope.getSingleElement(qualifiedName);
+ if(eod != null) {
+ URI uri = eod.getEObjectURI();
+ INode node = NodeModelUtils.getNode(importObj);
+ XtextHyperlink result = hyperlinkProvider.get();
+ result.setHyperlinkText(eod.getName().toString());
+ result.setURI(uri);
+ result.setHyperlinkRegion(new Region(node.getOffset(), node.getLength())); // whole import statement
+ return result;
+ }
+ }
+ }
+
+ // Create hyperlink using the import uri
if (importObj.getImportURI() == null)
return null;
diff --git a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathChangeListener.java b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathChangeListener.java
new file mode 100644
index 000000000..5cc5a1d66
--- /dev/null
+++ b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathChangeListener.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2019 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * CONTRIBUTORS:
+ * Jan Belle (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.core.common.ui.modelpath;
+
+import java.util.Collection;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.etrice.core.common.ui.modelpath.ModelPathManager.IModelPathListener;
+import org.eclipse.xtext.builder.impl.BuildScheduler;
+import org.eclipse.xtext.builder.impl.IBuildFlag;
+import org.eclipse.xtext.resource.impl.CoarseGrainedChangeEvent;
+import org.eclipse.xtext.ui.editor.IDirtyStateManager;
+import org.eclipse.xtext.ui.shared.contribution.IEagerContribution;
+
+import com.google.inject.Inject;
+
+/**
+ * Listens for modelpath changes and triggers a rebuild if necessary.
+ */
+@SuppressWarnings("restriction")
+public class ModelPathChangeListener implements IEagerContribution, IModelPathListener {
+
+ private BuildScheduler buildScheduler;
+ private IDirtyStateManager dirtyStateManager;
+
+ @Inject
+ public ModelPathChangeListener(BuildScheduler buildScheduler, IDirtyStateManager dirtyStateManager) {
+ this.buildScheduler = buildScheduler;
+ this.dirtyStateManager = dirtyStateManager;
+ }
+
+ @Override
+ public void onChange(Collection<IProject> projects) {
+ // Notify xtext of modelpath changes
+ dirtyStateManager.notifyListeners(new CoarseGrainedChangeEvent());
+
+ // Trigger build for all projects if auto build is enabled
+ if(ResourcesPlugin.getWorkspace().isAutoBuilding()) {
+ buildScheduler.scheduleBuildIfNecessary(projects, IBuildFlag.FORGET_BUILD_STATE_ONLY);
+ }
+ }
+
+ @Override
+ public void initialize() {
+ ModelPathManager.INSTANCE.addListener(this);
+ ModelPathManager.INSTANCE.startListening();
+ }
+
+ @Override
+ public void discard() {
+ ModelPathManager.INSTANCE.stopListening();
+ ModelPathManager.INSTANCE.removeListener(this);
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathDescription.java b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathDescription.java
new file mode 100644
index 000000000..380365055
--- /dev/null
+++ b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathDescription.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2019 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * CONTRIBUTORS:
+ * Jan Belle (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.core.common.ui.modelpath;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UncheckedIOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+
+/**
+ * Represent a modelpath description.
+ */
+public class ModelPathDescription {
+
+ private final List<IFolder> sourceDirectories;
+ private final List<IProject> projectDependencies;
+
+ private ModelPathDescription(List<IFolder> sourceDirectories, List<IProject> projectDependencies) {
+ this.sourceDirectories = sourceDirectories;
+ this.projectDependencies = projectDependencies;
+ }
+
+ /**
+ * @return the list of source directories
+ */
+ public List<IFolder> getSourceDirectories() {
+ return sourceDirectories;
+ }
+
+ /**
+ * @return the list of project dependencies
+ */
+ public List<IProject> getProjectDependencies() {
+ return projectDependencies;
+ }
+
+ /**
+ * Loads the modelpath description from a file.
+ *
+ * @param file the file to load from
+ * @return the loaded modelpath description
+ *
+ * @throws CoreException if the file doesn't exist or is out of sync
+ * @throws UncheckedIOException if an io exception occurs
+ */
+ public static ModelPathDescription load(IFile file) throws CoreException {
+ try {
+ return new ModelPathDescriptionLoader(file).load();
+ }
+ catch(IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ /**
+ * Helper class to parse and validate modelpath description files.
+ */
+ private static class ModelPathDescriptionLoader {
+
+ private static final String KEYWORD_SRCDIR = "srcDir";
+ private static final String KEYWORD_PROJECT = "project";
+ private static final Pattern KEYWORD_PATTERN = Pattern.compile("\\S+");
+
+ private IFile file;
+ private IProject project;
+ private IWorkspaceRoot root;
+ private List<IFolder> srcDirs;
+ private List<IProject> projects;
+ private int lineNumber;
+
+ public ModelPathDescriptionLoader(IFile file) {
+ this.file = file;
+ project = file.getProject();
+ root = ResourcesPlugin.getWorkspace().getRoot();
+ srcDirs = new ArrayList<>();
+ projects = new ArrayList<>();
+ lineNumber = 0;
+ }
+
+ public ModelPathDescription load() throws CoreException, IOException {
+ file.deleteMarkers(IMarker.PROBLEM, false, IResource.DEPTH_ZERO);
+
+ try(BufferedReader reader = new BufferedReader(new InputStreamReader(file.getContents()))) {
+ for(String line = reader.readLine(); line != null; line = reader.readLine(), lineNumber++) {
+ parseLine(line);
+ }
+ }
+
+ return new ModelPathDescription(Collections.unmodifiableList(srcDirs), Collections.unmodifiableList(projects));
+ }
+
+ private void parseLine(String line) throws CoreException {
+ Matcher matcher = KEYWORD_PATTERN.matcher(line);
+ if(matcher.find()) {
+ String keyword = matcher.group();
+ String str = line.substring(matcher.end()).trim();
+
+ switch(keyword) {
+ case KEYWORD_SRCDIR:
+ parseSrcDir(str);
+ break;
+ case KEYWORD_PROJECT:
+ parseProject(str);
+ break;
+ default:
+ createProblemMarker(IMarker.SEVERITY_ERROR, "unexpected keyword " + keyword);
+ }
+ }
+ }
+
+ private void parseSrcDir(String str) throws CoreException {
+ if(Path.EMPTY.isValidPath(str)) {
+ IFolder dir = project.getFolder(str);
+ if(!dir.exists()) {
+ createProblemMarker(IMarker.SEVERITY_WARNING, "directory " + dir.getFullPath() + " doesn't exist");
+ }
+ srcDirs.add(dir);
+ }
+ else {
+ createProblemMarker(IMarker.SEVERITY_ERROR, str + " isn't a valid path");
+ }
+ }
+
+ private void parseProject(String str) throws CoreException {
+ if(Path.EMPTY.isValidSegment(str)) {
+ IProject project = root.getProject(str);
+ if(!project.isAccessible()) {
+ createProblemMarker(IMarker.SEVERITY_WARNING, "project " + project.getName() + " doesn't exist");
+ }
+ projects.add(project);
+ }
+ else {
+ createProblemMarker(IMarker.SEVERITY_ERROR, str + " isn't a valid project name");
+ }
+ }
+
+ private void createProblemMarker(int severity, String message) throws CoreException {
+ IMarker marker = file.createMarker(IMarker.PROBLEM);
+ marker.setAttribute(IMarker.SEVERITY, severity);
+ marker.setAttribute(IMarker.LINE_NUMBER, lineNumber + 1);
+ marker.setAttribute(IMarker.MESSAGE, message);
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathManager.java b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathManager.java
new file mode 100644
index 000000000..590bd32b0
--- /dev/null
+++ b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathManager.java
@@ -0,0 +1,246 @@
+/*******************************************************************************
+ * Copyright (c) 2019 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * CONTRIBUTORS:
+ * Jan Belle (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.core.common.ui.modelpath;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+
+/**
+ * Maintains the modelpaths for all eclipse projects.
+ */
+public class ModelPathManager implements IResourceChangeListener {
+
+ public static final ModelPathManager INSTANCE = new ModelPathManager();
+
+ public static final Path MODELPATH_FILE = new Path(".modelpath");
+
+ private HashMap<IProject, ModelPathDescription> descriptionCache;
+ private HashMap<IProject, WorkspaceModelPath> modelpathCache;
+ private List<IModelPathListener> listeners;
+
+ @FunctionalInterface
+ public interface IModelPathListener {
+
+ /**
+ * Notifies of a change in the modelpath description file.
+ *
+ * @param projects whose modelpath description has been changed
+ */
+ void onChange(Collection<IProject> projects);
+ }
+
+ private ModelPathManager() {
+ descriptionCache = new HashMap<>();
+ modelpathCache = new HashMap<>();
+ listeners = new ArrayList<>();
+ }
+
+ /**
+ * Retrieves the modelpath for the specified project.
+ *
+ * @param project a project of the workspace
+ * @return the modelpath of project
+ */
+ public synchronized WorkspaceModelPath getModelPath(IProject project) {
+ return modelpathCache.computeIfAbsent(project, this::computeModelPath);
+ }
+
+ /**
+ * Adds a modelpath listener.
+ *
+ * @param listener the listener to add
+ */
+ public synchronized void addListener(IModelPathListener listener) {
+ listeners.add(listener);
+ }
+
+ /**
+ * Removes a modelpath listener.
+ *
+ * @param listener the listener to remove
+ */
+ public synchronized void removeListener(IModelPathListener listener) {
+ listeners.remove(listener);
+ }
+
+ /**
+ * Starts listening for changes in modelpath description files.
+ */
+ public void startListening() {
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
+ }
+
+ /**
+ * Stops listening for changes in modelpath description files.
+ */
+ public void stopListening() {
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
+ }
+
+ @Override
+ public void resourceChanged(IResourceChangeEvent event) {
+ // Check for changes in the modelpath description files
+ IResourceDelta rootDelta = event.getDelta();
+ IResourceDelta[] projectDeltas = rootDelta.getAffectedChildren();
+ ArrayList<IProject> projects = new ArrayList<>();
+ for(IResourceDelta projectDelta: projectDeltas) {
+ IResourceDelta modelpathDelta = projectDelta.findMember(MODELPATH_FILE);
+ if(modelpathDelta != null &&
+ ((modelpathDelta.getFlags() & IResourceDelta.CONTENT) != 0
+ || modelpathDelta.getKind() == IResourceDelta.ADDED
+ || modelpathDelta.getKind() == IResourceDelta.REMOVED)) {
+ IProject project = (IProject) projectDelta.getResource();
+ projects.add(project);
+ }
+ }
+
+ // Schedule update of modelpath if changes were detected
+ if(!projects.isEmpty()) {
+ new ModelPathUpdateJob(projects).schedule();
+ }
+ }
+
+ /**
+ * Computes a workspace modelpath for the specified project.
+ *
+ * @param project a project
+ * @return the workspace modelpath for the project
+ */
+ private WorkspaceModelPath computeModelPath(IProject project) {
+ Set<IProject> dependencies = new HashSet<>();
+ addAllProjectDependencies(project, dependencies);
+ List<IContainer> paths = dependencies.stream()
+ .flatMap(p -> getSourceDirectories(p).stream())
+ .collect(Collectors.toList());
+ return new WorkspaceModelPath(paths);
+ }
+
+ /**
+ * Recursively adds all (including transitive) project dependencies of a project to the set of dependencies.
+ *
+ * @param project a project
+ * @param dependencies a set to add the project dependencies
+ */
+ private void addAllProjectDependencies(IProject project, Set<IProject> dependencies) {
+ if(dependencies.add(project)) {
+ getProjectDependencies(project).forEach(p -> addAllProjectDependencies(p, dependencies));
+ }
+ }
+
+ /**
+ * Returns the modelpath description project dependencies of a project.
+ *
+ * @param project a project
+ * @return a list of projects
+ */
+ private List<IProject> getProjectDependencies(IProject project) {
+ return getModelPathDescription(project)
+ .map(ModelPathDescription::getProjectDependencies)
+ .orElse(Collections.emptyList());
+ }
+
+ /**
+ * Return the modelpath description source directories of a project.
+ *
+ * @param project a project
+ * @return a list of source directories
+ */
+ private List<IFolder> getSourceDirectories(IProject project) {
+ return getModelPathDescription(project)
+ .map(ModelPathDescription::getSourceDirectories)
+ .orElse(Collections.emptyList());
+ }
+
+ /**
+ * Retrieves a modelpath description for a project from the cache.
+ * If the description is not in the cache yet, it is loaded and added to the cache.
+ *
+ * @param project a project
+ * @return the modelpath description of the project or nothing if the modelpath description file does not exist
+ */
+ private Optional<ModelPathDescription> getModelPathDescription(IProject project) {
+ return Optional.ofNullable(descriptionCache.computeIfAbsent(project, this::loadModelPathDescription));
+ }
+
+ /**
+ * Loads the modelpath description file of a project.
+ *
+ * @param project a project
+ * @return the modelpath description or null if the file does not exist
+ */
+ private ModelPathDescription loadModelPathDescription(IProject project) {
+ IFile file = project.getFile(MODELPATH_FILE);
+ if(file.exists()) {
+ try {
+ return ModelPathDescription.load(file);
+ }
+ catch(CoreException e) {
+ try {
+ file.refreshLocal(IResource.DEPTH_ZERO, null);
+ }
+ catch(CoreException ex) {}
+ }
+ }
+ return null;
+ }
+
+ private class ModelPathUpdateJob extends WorkspaceJob {
+
+ private Collection<IProject> projects;
+
+ public ModelPathUpdateJob(Collection<IProject> projects) {
+ super("modelpath updater");
+ this.projects = projects;
+ }
+
+ @Override
+ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
+ synchronized(ModelPathManager.this) {
+ // Reload changed modelpath description files
+ projects.forEach(project -> descriptionCache.compute(project, (p, d) -> loadModelPathDescription(p)));
+
+ // Clear modelpath cache
+ modelpathCache.clear();
+
+ // Notify listeners of change
+ listeners.forEach(listener -> listener.onChange(projects));
+ }
+
+ return Status.OK_STATUS;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathResourceSetInitializer.java b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathResourceSetInitializer.java
new file mode 100644
index 000000000..3d7c87124
--- /dev/null
+++ b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/ModelPathResourceSetInitializer.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+* Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+* All rights reserved.
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+*
+* SPDX-License-Identifier: EPL-2.0
+*
+* CONTRIBUTORS:
+* Jan Belle (initial contribution)
+*
+ *******************************************************************************/
+
+package org.eclipse.etrice.core.common.ui.modelpath;
+
+import java.util.stream.Stream;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.etrice.generator.base.io.IModelPath;
+import org.eclipse.etrice.generator.base.io.ResourceSetModelPathProvider;
+import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.ui.resource.IResourceSetInitializer;
+
+/**
+ * Adds the modelpath to the resource set load options.
+ */
+public class ModelPathResourceSetInitializer implements IResourceSetInitializer {
+
+ @Override
+ public void initialize(ResourceSet resourceSet, IProject project) {
+ ModelPathDelegate modelPath = new ModelPathDelegate(project);
+ resourceSet.getLoadOptions().put(ResourceSetModelPathProvider.LOAD_OPTION_MODELPATH, modelPath);
+ }
+
+ private class ModelPathDelegate implements IModelPath {
+
+ private IProject project;
+
+ public ModelPathDelegate(IProject project) {
+ this.project = project;
+ }
+
+ @Override
+ public Stream<URI> getFiles(QualifiedName name) {
+ return ModelPathManager.INSTANCE.getModelPath(project).getFiles(name);
+ }
+
+ @Override
+ public Stream<URI> getAllFiles() {
+ return ModelPathManager.INSTANCE.getModelPath(project).getAllFiles();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/WorkspaceModelPath.java b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/WorkspaceModelPath.java
new file mode 100644
index 000000000..5daf25a4d
--- /dev/null
+++ b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/modelpath/WorkspaceModelPath.java
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2019 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * CONTRIBUTORS:
+ * Jan Belle (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.core.common.ui.modelpath;
+
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.etrice.generator.base.io.IModelPath;
+import org.eclipse.xtext.naming.QualifiedName;
+
+/**
+ * Modelpath implementation based on the eclipse workspace.
+ */
+public class WorkspaceModelPath implements IModelPath {
+
+ private List<IContainer> paths;
+
+ /**
+ * Constructs a new modelpath.
+ *
+ * @param paths the paths to seach for model files
+ */
+ public WorkspaceModelPath(List<IContainer> paths) {
+ this.paths = paths;
+ }
+
+ @Override
+ public Stream<URI> getFiles(QualifiedName name) {
+ Stream<URI> stream = Stream.empty();
+ while(!name.isEmpty()) {
+ name = name.skipLast(1);
+ stream = Stream.concat(stream, getPackage(name));
+ }
+ return stream;
+ }
+
+ @Override
+ public Stream<URI> getAllFiles() {
+ return paths.stream()
+ .filter(container -> container.isAccessible())
+ .flatMap(container -> getAllFiles(container));
+ }
+
+ public List<IContainer> getPaths() {
+ return paths;
+ }
+
+ @Override
+ public String toString() {
+ return paths.toString();
+ }
+
+ /**
+ * Constructrs a stream of file contained in the specified package.
+ *
+ * @param name the fully qualified name of the package
+ * @return a stream of file uris
+ */
+ private Stream<URI> getPackage(QualifiedName name) {
+ String pathStr = name.toString().replace('.', '/');
+ Path path = new Path(pathStr);
+ return paths.stream()
+ .map(container -> container.getFolder(path))
+ .filter(folder -> folder.exists())
+ .flatMap(folder -> getFiles(folder));
+ }
+
+ /**
+ * Constructs a stream of files contained in the specified container.
+ *
+ * @param container the container to be searched for files
+ * @return a stream of file uris
+ */
+ private Stream<URI> getFiles(IContainer container) {
+ return getMembers(container)
+ .filter(resource -> resource.getType() == IResource.FILE)
+ .map(IFile.class::cast)
+ .map(file -> createURI(file));
+ }
+
+ /**
+ * Constructs a stream that contains all files in the container including files of subfolders.
+ *
+ * @param container the container to be searched for files
+ * @return a stream of file uris
+ */
+ private Stream<URI> getAllFiles(IContainer container) {
+ return getMembers(container)
+ .flatMap(resource -> {
+ if(resource.getType() == IResource.FILE) {
+ IFile file = (IFile) resource;
+ URI uri = createURI(file);
+ return Stream.of(uri);
+ }
+ else if(resource.getType() == IResource.FOLDER) {
+ IFolder subfolder = (IFolder) resource;
+ return getAllFiles(subfolder);
+ }
+ return Stream.empty();
+ });
+ }
+
+ /**
+ * Creates an uri for the passed file.
+ */
+ private URI createURI(IFile file) {
+ return URI.createPlatformResourceURI(file.getFullPath().toString(), true);
+ }
+
+ /**
+ * Returns a stream of resources contained in the passed container.
+ */
+ private Stream<IResource> getMembers(IContainer container) {
+ try {
+ return Stream.of(container.members());
+ }
+ catch(CoreException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.core.common/META-INF/MANIFEST.MF b/plugins/org.eclipse.etrice.core.common/META-INF/MANIFEST.MF
index 9f854a089..fa63d005d 100644
--- a/plugins/org.eclipse.etrice.core.common/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.etrice.core.common/META-INF/MANIFEST.MF
@@ -20,7 +20,8 @@ Require-Bundle: org.eclipse.xtext;bundle-version="2.6.0";visibility:=reexport,
org.antlr.runtime,
org.eclipse.core.runtime,
org.eclipse.core.resources,
- org.eclipse.xtext.xbase.lib
+ org.eclipse.xtext.xbase.lib,
+ org.eclipse.etrice.generator.base
Import-Package: org.apache.log4j,
org.eclipse.xtext.xbase.lib
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/plugins/org.eclipse.etrice.core.common/build.gradle b/plugins/org.eclipse.etrice.core.common/build.gradle
index 38c3c557b..628c56fb7 100644
--- a/plugins/org.eclipse.etrice.core.common/build.gradle
+++ b/plugins/org.eclipse.etrice.core.common/build.gradle
@@ -4,4 +4,6 @@ dependencies {
compile "org.eclipse.platform:org.eclipse.core.resources:$versions.core_resources"
compile "org.eclipse.xtext:org.eclipse.xtext:$versions.xtext"
compile "com.google.guava:guava:$versions.guava"
+
+ compile project(':plugins:org.eclipse.etrice.generator.base')
} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/CompoundGlobalScopeProvider.java b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/CompoundGlobalScopeProvider.java
new file mode 100644
index 000000000..b24ebe198
--- /dev/null
+++ b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/CompoundGlobalScopeProvider.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+* Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+* All rights reserved.
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+*
+* SPDX-License-Identifier: EPL-2.0
+*
+* CONTRIBUTORS:
+* Jan Belle (initial contribution)
+*
+ *******************************************************************************/
+
+package org.eclipse.etrice.core.common.scoping;
+
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.xtext.resource.IEObjectDescription;
+import org.eclipse.xtext.scoping.IGlobalScopeProvider;
+import org.eclipse.xtext.scoping.IScope;
+import org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider;
+
+import com.google.common.base.Predicate;
+import com.google.inject.Inject;
+
+/**
+ * Global scope provider that combines the {@link ImportUriGlobalScopeProvider} and {@link ModelPathGlobalScopeProvider}.
+ */
+public class CompoundGlobalScopeProvider implements IGlobalScopeProvider {
+
+ @Inject
+ ModelPathGlobalScopeProvider modelPathGlobalScopeProvider;
+
+ @Inject
+ ImportUriGlobalScopeProvider importURIGlobalSopeProvider;
+
+ @Override
+ public IScope getScope(Resource context, EReference reference, Predicate<IEObjectDescription> filter) {
+ IScope uriScope = importURIGlobalSopeProvider.getScope(context, reference, filter);
+ IScope combinedScope = modelPathGlobalScopeProvider.getScope(uriScope, context, reference, filter);
+
+ return combinedScope;
+ }
+}
diff --git a/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/ModelLocator.java b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/ModelLocator.java
index 706d92587..ea185c076 100644
--- a/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/ModelLocator.java
+++ b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/ModelLocator.java
@@ -16,12 +16,14 @@ package org.eclipse.etrice.core.common.scoping;
import java.util.ArrayList;
-import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
+import org.eclipse.emf.common.EMFPlugin;
import org.eclipse.emf.ecore.resource.Resource;
+import org.osgi.framework.Bundle;
import com.google.inject.Inject;
+import com.google.inject.Injector;
import com.google.inject.Singleton;
/**
@@ -39,20 +41,27 @@ public class ModelLocator {
addLocator(defaultLocator);
}
- public void loadExtensions() {
- IConfigurationElement[] config = Platform.getExtensionRegistry()
- .getConfigurationElementsFor(IMODEL_LOCATOR_ID);
-
- for (IConfigurationElement e : config) {
- try {
- final Object ext = e.createExecutableExtension("class");
- if (ext instanceof IModelLocator) {
- IModelLocator locator = (IModelLocator) ext;
- locators.add(locator);
+ @Inject
+ public void loadExtensions(Injector injector) {
+ if(EMFPlugin.IS_ECLIPSE_RUNNING && Platform.getExtensionRegistry() != null) {
+ IConfigurationElement[] config = Platform.getExtensionRegistry()
+ .getConfigurationElementsFor(IMODEL_LOCATOR_ID);
+
+ for (IConfigurationElement e : config) {
+ try {
+ final String extContributor = e.getContributor().getName();
+ final Bundle extBundle = Platform.getBundle(extContributor);
+ final String extClassName = e.getAttribute("class");
+ final Class<?> extClass = extBundle.loadClass(extClassName);
+ final Object ext = injector.getInstance(extClass);
+ if (ext instanceof IModelLocator) {
+ IModelLocator locator = (IModelLocator) ext;
+ locators.add(locator);
+ }
+ }
+ catch (ClassNotFoundException ex) {
+ System.out.println(ex.getMessage());
}
- }
- catch (CoreException ex) {
- System.out.println(ex.getMessage());
}
}
}
diff --git a/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/ModelPathFileExtensionFilter.java b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/ModelPathFileExtensionFilter.java
new file mode 100644
index 000000000..b6899729d
--- /dev/null
+++ b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/ModelPathFileExtensionFilter.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2019 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * CONTRIBUTORS:
+ * Jan Belle (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.core.common.scoping;
+
+import java.util.Arrays;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.etrice.core.common.scoping.ModelPathGlobalScopeProvider.IModelPathFileFilter;
+
+/**
+ * Filters the model path by file extension.
+ */
+public class ModelPathFileExtensionFilter implements IModelPathFileFilter {
+
+ private final String[] legalFileExtensions;
+
+ /**
+ * Constructs new model path filter that only allows files with specific file extenions.
+ *
+ * @param legalFileExtensions an array of permitted file extensions
+ */
+ public ModelPathFileExtensionFilter(String... legalFileExtensions) {
+ this.legalFileExtensions = legalFileExtensions;
+ Arrays.sort(this.legalFileExtensions);
+ }
+
+ @Override
+ public boolean apply(URI uri) {
+ String fileExtension = uri.fileExtension();
+ if(fileExtension != null) {
+ return Arrays.binarySearch(legalFileExtensions, fileExtension) >= 0;
+ }
+ return false;
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/ModelPathGlobalScopeProvider.java b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/ModelPathGlobalScopeProvider.java
new file mode 100644
index 000000000..c2555c368
--- /dev/null
+++ b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/ModelPathGlobalScopeProvider.java
@@ -0,0 +1,215 @@
+/*******************************************************************************
+* Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+* All rights reserved.
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+*
+* SPDX-License-Identifier: EPL-2.0
+*
+* CONTRIBUTORS:
+* Jan Belle (initial contribution)
+*
+ *******************************************************************************/
+
+package org.eclipse.etrice.core.common.scoping;
+
+import java.util.Optional;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.etrice.generator.base.io.IModelPath;
+import org.eclipse.etrice.generator.base.io.IModelPathProvider;
+import org.eclipse.xtext.naming.IQualifiedNameProvider;
+import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.resource.IEObjectDescription;
+import org.eclipse.xtext.resource.IResourceDescription;
+import org.eclipse.xtext.resource.IResourceDescriptions;
+import org.eclipse.xtext.resource.IResourceServiceProvider;
+import org.eclipse.xtext.scoping.IScope;
+import org.eclipse.xtext.scoping.impl.AbstractGlobalScopeProvider;
+import org.eclipse.xtext.scoping.impl.AbstractScope;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.inject.Inject;
+
+/**
+ * Provides scopes based on a {@link IModelPath}.
+ */
+public class ModelPathGlobalScopeProvider extends AbstractGlobalScopeProvider {
+
+ /**
+ * Filters the model files.
+ */
+ @FunctionalInterface
+ public static interface IModelPathFileFilter extends Predicate<URI> {}
+
+ private IModelPathProvider modelPathProvider;
+ private IQualifiedNameProvider qualifiedNameProvider;
+ private IResourceServiceProvider.Registry resourceServiceProviderRegistry;
+ private IModelPathFileFilter modelPathFileFilter;
+ private ModelLocatorUriResolver uriResolver;
+
+ @Inject
+ public ModelPathGlobalScopeProvider(IModelPathProvider modelPathProvider, IQualifiedNameProvider qualifiedNameProvider,
+ IResourceServiceProvider.Registry resourceServiceProviderRegistry, IModelPathFileFilter modelPathFileFilter, ModelLocatorUriResolver uriResolver) {
+ this.modelPathProvider = modelPathProvider;
+ this.qualifiedNameProvider = qualifiedNameProvider;
+ this.resourceServiceProviderRegistry = resourceServiceProviderRegistry;
+ this.modelPathFileFilter = modelPathFileFilter;
+ this.uriResolver = uriResolver;
+ }
+
+ @Override
+ protected IScope getScope(Resource context, boolean ignoreCase, EClass type, Predicate<IEObjectDescription> filter) {
+ return new ModelPathGlobalScope(ignoreCase, context, type, filter);
+ }
+
+ public AbstractScope getScope(IScope parent, Resource context, EReference reference, Predicate<IEObjectDescription> filter) {
+ return new ModelPathGlobalScope(parent, isIgnoreCase(reference), context, reference.getEReferenceType(), filter);
+ }
+
+ private class ModelPathGlobalScope extends AbstractScope {
+
+ private Resource context;
+ private EClass type;
+ private Predicate<IEObjectDescription> filter;
+
+ public ModelPathGlobalScope(boolean ignoreCase, Resource context, EClass type, Predicate<IEObjectDescription> filter) {
+ this(IScope.NULLSCOPE, ignoreCase, context, type, filter);
+ }
+
+ public ModelPathGlobalScope(IScope parent, boolean ignoreCase,
+ Resource context, EClass type, Predicate<IEObjectDescription> filter) {
+ super(parent, ignoreCase);
+
+ this.context = context;
+ this.type = type;
+ this.filter = filter == null ? Predicates.alwaysTrue() : filter;
+ }
+
+ @Override
+ protected IEObjectDescription getSingleLocalElementByName(QualifiedName name) {
+ Stream<IResourceDescription> resourceDescriptions = getResourceDescriptionsByName(name);
+ return getExportedObjectsByName(resourceDescriptions, name).findFirst().orElse(null);
+ }
+
+ @Override
+ protected Iterable<IEObjectDescription> getLocalElementsByName(final QualifiedName name) {
+ Stream<IResourceDescription> resourceDescriptions = getResourceDescriptionsByName(name);
+ return getExportedObjectsByName(resourceDescriptions, name).collect(Collectors.toList());
+ }
+
+// @Override
+// protected IEObjectDescription getSingleLocalElementByEObject(final EObject object, final URI uri) {
+// Stream<IResourceDescription> resourceDescriptions = getResourceDescriptionsByObject(object);
+// return getExportedObjectsByObject(resourceDescriptions, object).findFirst().orElse(null);
+// }
+
+ @Override
+ protected Iterable<IEObjectDescription> getLocalElementsByEObject(final EObject object, final URI uri) {
+ Stream<IResourceDescription> resourceDescriptions = getResourceDescriptionsByObject(object);
+ return getExportedObjectsByObject(resourceDescriptions, object).collect(Collectors.toList());
+ }
+
+ @Override
+ protected Iterable<IEObjectDescription> getAllLocalElements() {
+ Stream<IResourceDescription> resourceDescriptions = getAllResourceDescriptions();
+ return getExportedObjectsByType(resourceDescriptions, type).collect(Collectors.toList());
+ }
+
+ private Stream<IEObjectDescription> getExportedObjectsByName(Stream<IResourceDescription> resourceDescriptions, QualifiedName name) {
+ return resourceDescriptions.map(rd -> rd.getExportedObjects(type, name, isIgnoreCase()))
+ .flatMap(eods -> StreamSupport.stream(eods.spliterator(), false))
+ .filter(filter::apply);
+ }
+
+ private Stream<IEObjectDescription> getExportedObjectsByType(Stream<IResourceDescription> resourceDescriptions, EClass type) {
+ return resourceDescriptions.map(rd -> rd.getExportedObjectsByType(type))
+ .flatMap(eods -> StreamSupport.stream(eods.spliterator(), false))
+ .filter(filter::apply);
+ }
+
+ private Stream<IEObjectDescription> getExportedObjectsByObject(Stream<IResourceDescription> resourceDescriptions, EObject object) {
+ return resourceDescriptions.map(rd -> rd.getExportedObjectsByObject(object))
+ .flatMap(eods -> StreamSupport.stream(eods.spliterator(), false))
+ .filter(filter::apply);
+ }
+
+ private Stream<IResourceDescription> getResourceDescriptionsByObject(EObject object) {
+ QualifiedName name = qualifiedNameProvider.getFullyQualifiedName(object);
+ if(name != null) {
+ return getResourceDescriptionsByName(name);
+ }
+ return Stream.empty();
+ }
+
+ private Stream<IResourceDescription> getResourceDescriptionsByName(QualifiedName name) {
+ IModelPath modelPath = modelPathProvider.get(context);
+ Stream<URI> files = modelPath.getFiles(name);
+ return getResourceDescriptions(files);
+ }
+
+ private Stream<IResourceDescription> getAllResourceDescriptions() {
+ IModelPath modelPath = modelPathProvider.get(context);
+ Stream<URI> files = modelPath.getAllFiles();
+ return getResourceDescriptions(files);
+ }
+
+ private Stream<IResourceDescription> getResourceDescriptions(Stream<URI> files) {
+ IResourceDescriptions descriptions = ModelPathGlobalScopeProvider.this.getResourceDescriptions(context);
+ ResourceSet resourceSet = context.getResourceSet();
+ return files.filter(modelPathFileFilter)
+ .map(uri -> getResourceDescription(uri, descriptions, resourceSet))
+ .flatMap(rd -> streamOptional(rd));
+ }
+
+ /**
+ * Tries to retrieve a resource description for the specified resource.
+ * If the resource description is not present in the index, a new resource description is computed using the resource set.
+ *
+ * @param uri the uri of the resource
+ * @param descriptions the index
+ * @param resourceSet a resource set used to load the resource
+ * @return an optional of the requested resource descriptions
+ */
+ private Optional<IResourceDescription> getResourceDescription(URI uri, IResourceDescriptions descriptions, ResourceSet resourceSet) {
+ uri = resolveURI(uri);
+ IResourceDescription resourceDescription = descriptions.getResourceDescription(uri);
+ if(resourceDescription != null) {
+ return Optional.of(resourceDescription);
+ }
+ else {
+ IResourceServiceProvider resourceServiceProvider = resourceServiceProviderRegistry.getResourceServiceProvider(uri);
+ if(resourceServiceProvider != null) {
+ Resource resource = resourceSet.getResource(uri, true);
+ IResourceDescription.Manager descriptionManager = resourceServiceProvider.getResourceDescriptionManager();
+ resourceDescription = descriptionManager.getResourceDescription(resource);
+ return Optional.of(resourceDescription);
+ }
+ }
+ return Optional.empty();
+ }
+
+ private URI resolveURI(URI uri) {
+ String uriStr = uriResolver.resolve(uri.toString(), null);
+ return URI.createURI(uriStr);
+ }
+ }
+
+ /**
+ * This method for {@link Optional} is first introduced in Java 9 :(
+ */
+ private static <T> Stream<T> streamOptional(Optional<T> optional) {
+ return optional.isPresent() ? Stream.of(optional.get()) : Stream.empty();
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/StandardModelLocator.java b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/StandardModelLocator.java
index b19645b49..0f1c81acc 100644
--- a/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/StandardModelLocator.java
+++ b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/scoping/StandardModelLocator.java
@@ -85,7 +85,8 @@ public class StandardModelLocator implements IModelLocator {
private String resolve(String resolve, URI baseUri, Resource res) {
resolve = substituteEnvVars(resolve);
- // replace (double) slashes and backslashes with single slashes
+ // replace (double/triple) slashes and backslashes with single slashes
+ resolve = resolve.replaceAll("///", "/");
resolve = resolve.replaceAll("\\\\", "/");
resolve = resolve.replaceAll("//", "/");
diff --git a/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/validation/BaseJavaValidator.java b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/validation/BaseJavaValidator.java
index d8601c8c8..2e29cf4a7 100644
--- a/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/validation/BaseJavaValidator.java
+++ b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/validation/BaseJavaValidator.java
@@ -18,6 +18,9 @@ import java.util.HashSet;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.etrice.core.common.base.Annotation;
@@ -33,9 +36,15 @@ import org.eclipse.etrice.core.common.base.KeyValue;
import org.eclipse.etrice.core.common.base.RealLiteral;
import org.eclipse.etrice.core.common.base.SimpleAnnotationAttribute;
import org.eclipse.etrice.core.common.base.StringLiteral;
+import org.eclipse.xtext.naming.IQualifiedNameConverter;
+import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.resource.IEObjectDescription;
+import org.eclipse.xtext.scoping.IGlobalScopeProvider;
+import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.ImportUriResolver;
import org.eclipse.xtext.validation.Check;
+import com.google.common.base.Predicates;
import com.google.inject.Inject;
/**
@@ -52,6 +61,8 @@ public class BaseJavaValidator extends org.eclipse.etrice.core.common.validation
public static final String DUPLICATE_ANNOTATION_ATTRIBUTE = "BaseJavaValidator.DuplicateAnnotationAttribute";
@Inject ImportUriResolver importUriResolver;
+ @Inject IGlobalScopeProvider globalScopeProvider;
+ @Inject IQualifiedNameConverter nameConverter;
@Check
public void checkDocumentation(Documentation doc) {
@@ -183,6 +194,10 @@ public class BaseJavaValidator extends org.eclipse.etrice.core.common.validation
@Check
public void checkImportedURI(Import imp) {
+ if(imp.getImportURI() == null) {
+ return;
+ }
+
String uriString = importUriResolver.resolve(imp);
if (uriString == null) {
warning("could not load referenced model", BasePackage.Literals.IMPORT__IMPORT_URI);
@@ -214,4 +229,26 @@ public class BaseJavaValidator extends org.eclipse.etrice.core.common.validation
}
}
+ /**
+ * Check that the imported namespace can be found by the global scope provider.
+ *
+ * @param imp the import to check
+ */
+ @Check
+ public void checkImportedNamespace(Import imp) {
+ String name = imp.getImportedNamespace();
+ if(name != null) {
+ QualifiedName importedNamespace = nameConverter.toQualifiedName(name);
+ if(!importedNamespace.getLastSegment().equals("*")) {
+ Resource context = imp.eResource();
+ EReference reference = EcoreFactory.eINSTANCE.createEReference();
+ reference.setEType(EcorePackage.eINSTANCE.getEObject());
+ IScope scope = globalScopeProvider.getScope(context, reference, Predicates.alwaysTrue());
+ IEObjectDescription eod = scope.getSingleElement(importedNamespace);
+ if(eod == null) {
+ error("could not find imported namespace " + importedNamespace, BasePackage.Literals.IMPORT__IMPORTED_NAMESPACE);
+ }
+ }
+ }
+ }
}
diff --git a/plugins/org.eclipse.etrice.core.config/src-gen/org/eclipse/etrice/core/AbstractConfigRuntimeModule.java b/plugins/org.eclipse.etrice.core.config/src-gen/org/eclipse/etrice/core/AbstractConfigRuntimeModule.java
index 9dfe87b6f..536bfef77 100644
--- a/plugins/org.eclipse.etrice.core.config/src-gen/org/eclipse/etrice/core/AbstractConfigRuntimeModule.java
+++ b/plugins/org.eclipse.etrice.core.config/src-gen/org/eclipse/etrice/core/AbstractConfigRuntimeModule.java
@@ -110,12 +110,12 @@ public abstract class AbstractConfigRuntimeModule extends org.eclipse.xtext.serv
// contributed by org.eclipse.xtext.generator.scoping.AbstractScopingFragment
public void configureIScopeProviderDelegate(com.google.inject.Binder binder) {
- binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class).annotatedWith(com.google.inject.name.Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(org.eclipse.xtext.scoping.impl.SimpleLocalScopeProvider.class);
+ binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class).annotatedWith(com.google.inject.name.Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider.class);
}
// contributed by org.eclipse.xtext.generator.scoping.AbstractScopingFragment
public Class<? extends org.eclipse.xtext.scoping.IGlobalScopeProvider> bindIGlobalScopeProvider() {
- return org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider.class;
+ return org.eclipse.xtext.scoping.impl.DefaultGlobalScopeProvider.class;
}
// contributed by org.eclipse.xtext.generator.scoping.AbstractScopingFragment
diff --git a/plugins/org.eclipse.etrice.core.config/src/org/eclipse/etrice/core/ConfigRuntimeModule.java b/plugins/org.eclipse.etrice.core.config/src/org/eclipse/etrice/core/ConfigRuntimeModule.java
index 300f1f721..b2e9e3a80 100644
--- a/plugins/org.eclipse.etrice.core.config/src/org/eclipse/etrice/core/ConfigRuntimeModule.java
+++ b/plugins/org.eclipse.etrice.core.config/src/org/eclipse/etrice/core/ConfigRuntimeModule.java
@@ -14,13 +14,15 @@
package org.eclipse.etrice.core;
+import org.eclipse.etrice.core.common.scoping.CompoundGlobalScopeProvider;
import org.eclipse.etrice.core.common.scoping.ModelLocatorUriResolver;
+import org.eclipse.etrice.core.common.scoping.ModelPathFileExtensionFilter;
+import org.eclipse.etrice.core.common.scoping.ModelPathGlobalScopeProvider.IModelPathFileFilter;
import org.eclipse.etrice.core.converter.ConfigValueConverterService;
import org.eclipse.xtext.conversion.IValueConverterService;
+import org.eclipse.xtext.scoping.IGlobalScopeProvider;
import org.eclipse.xtext.scoping.impl.ImportUriResolver;
-import com.google.inject.Binder;
-
/**
* Use this class to register components to be used at runtime / without the
* Equinox extension registry.
@@ -28,19 +30,13 @@ import com.google.inject.Binder;
public class ConfigRuntimeModule extends
org.eclipse.etrice.core.AbstractConfigRuntimeModule {
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.etrice.core.AbstractRoomRuntimeModule#
- * configureIScopeProviderDelegate(com.google.inject.Binder)
- */
@Override
- public void configureIScopeProviderDelegate(Binder binder) {
- binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class)
- .annotatedWith(
- com.google.inject.name.Names
- .named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE))
- .to(org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider.class);
+ public Class<? extends IGlobalScopeProvider> bindIGlobalScopeProvider() {
+ return CompoundGlobalScopeProvider.class;
+ }
+
+ public IModelPathFileFilter bindIModelPathFileFilter() {
+ return new ModelPathFileExtensionFilter("room");
}
// HOWTO: use URI imports - need special URI resolver
diff --git a/plugins/org.eclipse.etrice.core.config/src/org/eclipse/etrice/core/GenerateConfig.mwe2 b/plugins/org.eclipse.etrice.core.config/src/org/eclipse/etrice/core/GenerateConfig.mwe2
index 758adc438..c36c68645 100644
--- a/plugins/org.eclipse.etrice.core.config/src/org/eclipse/etrice/core/GenerateConfig.mwe2
+++ b/plugins/org.eclipse.etrice.core.config/src/org/eclipse/etrice/core/GenerateConfig.mwe2
@@ -98,8 +98,8 @@ Workflow {
// fragment = exporting.SimpleNamesFragment {}
// scoping and exporting API
- fragment = scoping.ImportURIScopingFragment {}
- // fragment = scoping.ImportNamespacesScopingFragment {}
+ // fragment = scoping.ImportURIScopingFragment {}
+ fragment = scoping.ImportNamespacesScopingFragment {}
fragment = exporting.QualifiedNamesFragment {}
fragment = builder.BuilderIntegrationFragment {}
diff --git a/plugins/org.eclipse.etrice.core.etmap/src-gen/org/eclipse/etrice/core/etmap/AbstractETMapRuntimeModule.java b/plugins/org.eclipse.etrice.core.etmap/src-gen/org/eclipse/etrice/core/etmap/AbstractETMapRuntimeModule.java
index a8809359c..66c75f680 100644
--- a/plugins/org.eclipse.etrice.core.etmap/src-gen/org/eclipse/etrice/core/etmap/AbstractETMapRuntimeModule.java
+++ b/plugins/org.eclipse.etrice.core.etmap/src-gen/org/eclipse/etrice/core/etmap/AbstractETMapRuntimeModule.java
@@ -105,12 +105,12 @@ public abstract class AbstractETMapRuntimeModule extends org.eclipse.xtext.servi
// contributed by org.eclipse.xtext.generator.scoping.AbstractScopingFragment
public void configureIScopeProviderDelegate(com.google.inject.Binder binder) {
- binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class).annotatedWith(com.google.inject.name.Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(org.eclipse.xtext.scoping.impl.SimpleLocalScopeProvider.class);
+ binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class).annotatedWith(com.google.inject.name.Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider.class);
}
// contributed by org.eclipse.xtext.generator.scoping.AbstractScopingFragment
public Class<? extends org.eclipse.xtext.scoping.IGlobalScopeProvider> bindIGlobalScopeProvider() {
- return org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider.class;
+ return org.eclipse.xtext.scoping.impl.DefaultGlobalScopeProvider.class;
}
// contributed by org.eclipse.xtext.generator.scoping.AbstractScopingFragment
diff --git a/plugins/org.eclipse.etrice.core.etmap/src/org/eclipse/etrice/core/etmap/ETMapRuntimeModule.java b/plugins/org.eclipse.etrice.core.etmap/src/org/eclipse/etrice/core/etmap/ETMapRuntimeModule.java
index f2e853aae..35fa20333 100644
--- a/plugins/org.eclipse.etrice.core.etmap/src/org/eclipse/etrice/core/etmap/ETMapRuntimeModule.java
+++ b/plugins/org.eclipse.etrice.core.etmap/src/org/eclipse/etrice/core/etmap/ETMapRuntimeModule.java
@@ -14,23 +14,25 @@
package org.eclipse.etrice.core.etmap;
+import org.eclipse.etrice.core.common.scoping.CompoundGlobalScopeProvider;
import org.eclipse.etrice.core.common.scoping.ModelLocatorUriResolver;
+import org.eclipse.etrice.core.common.scoping.ModelPathFileExtensionFilter;
+import org.eclipse.etrice.core.common.scoping.ModelPathGlobalScopeProvider.IModelPathFileFilter;
+import org.eclipse.xtext.scoping.IGlobalScopeProvider;
import org.eclipse.xtext.scoping.impl.ImportUriResolver;
-import com.google.inject.Binder;
-
/**
* Use this class to register components to be used at runtime / without the Equinox extension registry.
*/
public class ETMapRuntimeModule extends org.eclipse.etrice.core.etmap.AbstractETMapRuntimeModule {
@Override
- public void configureIScopeProviderDelegate(Binder binder) {
- binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class)
- .annotatedWith(
- com.google.inject.name.Names
- .named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE))
- .to(org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider.class);
+ public Class<? extends IGlobalScopeProvider> bindIGlobalScopeProvider() {
+ return CompoundGlobalScopeProvider.class;
+ }
+
+ public IModelPathFileFilter bindIModelPathFileFilter() {
+ return new ModelPathFileExtensionFilter("room", "etphys");
}
// HOWTO: use URI imports - need special URI resolver
diff --git a/plugins/org.eclipse.etrice.core.etmap/src/org/eclipse/etrice/core/etmap/GenerateETMap.mwe2 b/plugins/org.eclipse.etrice.core.etmap/src/org/eclipse/etrice/core/etmap/GenerateETMap.mwe2
index bdae5cd6c..7f153a7c2 100644
--- a/plugins/org.eclipse.etrice.core.etmap/src/org/eclipse/etrice/core/etmap/GenerateETMap.mwe2
+++ b/plugins/org.eclipse.etrice.core.etmap/src/org/eclipse/etrice/core/etmap/GenerateETMap.mwe2
@@ -95,7 +95,7 @@ Workflow {
// fragment = exporting.SimpleNamesFragment {}
// scoping and exporting API
- fragment = scoping.ImportURIScopingFragment {}
+ fragment = scoping.ImportNamespacesScopingFragment {}
fragment = exporting.QualifiedNamesFragment {}
fragment = builder.BuilderIntegrationFragment {}
diff --git a/plugins/org.eclipse.etrice.core.etphys/src-gen/org/eclipse/etrice/core/etphys/AbstractETPhysRuntimeModule.java b/plugins/org.eclipse.etrice.core.etphys/src-gen/org/eclipse/etrice/core/etphys/AbstractETPhysRuntimeModule.java
index fbf7a87bf..a38ab7982 100644
--- a/plugins/org.eclipse.etrice.core.etphys/src-gen/org/eclipse/etrice/core/etphys/AbstractETPhysRuntimeModule.java
+++ b/plugins/org.eclipse.etrice.core.etphys/src-gen/org/eclipse/etrice/core/etphys/AbstractETPhysRuntimeModule.java
@@ -110,12 +110,12 @@ public abstract class AbstractETPhysRuntimeModule extends org.eclipse.xtext.serv
// contributed by org.eclipse.xtext.generator.scoping.AbstractScopingFragment
public void configureIScopeProviderDelegate(com.google.inject.Binder binder) {
- binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class).annotatedWith(com.google.inject.name.Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(org.eclipse.xtext.scoping.impl.SimpleLocalScopeProvider.class);
+ binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class).annotatedWith(com.google.inject.name.Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider.class);
}
// contributed by org.eclipse.xtext.generator.scoping.AbstractScopingFragment
public Class<? extends org.eclipse.xtext.scoping.IGlobalScopeProvider> bindIGlobalScopeProvider() {
- return org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider.class;
+ return org.eclipse.xtext.scoping.impl.DefaultGlobalScopeProvider.class;
}
// contributed by org.eclipse.xtext.generator.scoping.AbstractScopingFragment
diff --git a/plugins/org.eclipse.etrice.core.etphys/src/org/eclipse/etrice/core/etphys/ETPhysRuntimeModule.java b/plugins/org.eclipse.etrice.core.etphys/src/org/eclipse/etrice/core/etphys/ETPhysRuntimeModule.java
index 26fd1961b..d9e982a36 100644
--- a/plugins/org.eclipse.etrice.core.etphys/src/org/eclipse/etrice/core/etphys/ETPhysRuntimeModule.java
+++ b/plugins/org.eclipse.etrice.core.etphys/src/org/eclipse/etrice/core/etphys/ETPhysRuntimeModule.java
@@ -29,13 +29,7 @@ import com.google.inject.Binder;
public class ETPhysRuntimeModule extends org.eclipse.etrice.core.etphys.AbstractETPhysRuntimeModule {
@SuppressWarnings("restriction")
- @Override
- public void configureIScopeProviderDelegate(Binder binder) {
- binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class)
- .annotatedWith(
- com.google.inject.name.Names
- .named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE))
- .to(org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider.class);
+ public void configureITransientValueService(Binder binder) {
binder.bind(org.eclipse.xtext.serializer.sequencer.ITransientValueService.class).to(
ETPhysTransientValueService.class);
}
diff --git a/plugins/org.eclipse.etrice.core.etphys/src/org/eclipse/etrice/core/etphys/GenerateETPhys.mwe2 b/plugins/org.eclipse.etrice.core.etphys/src/org/eclipse/etrice/core/etphys/GenerateETPhys.mwe2
index d219db5bd..de7e3a62c 100644
--- a/plugins/org.eclipse.etrice.core.etphys/src/org/eclipse/etrice/core/etphys/GenerateETPhys.mwe2
+++ b/plugins/org.eclipse.etrice.core.etphys/src/org/eclipse/etrice/core/etphys/GenerateETPhys.mwe2
@@ -91,8 +91,8 @@ Workflow {
// fragment = exporting.SimpleNamesFragment {}
// scoping and exporting API
- fragment = scoping.ImportURIScopingFragment {}
- //fragment = scoping.ImportNamespacesScopingFragment {}
+ // fragment = scoping.ImportURIScopingFragment {}
+ fragment = scoping.ImportNamespacesScopingFragment {}
fragment = exporting.QualifiedNamesFragment {}
//fragment = builder.BuilderIntegrationFragment {}
diff --git a/plugins/org.eclipse.etrice.core.fsm/src-gen/org/eclipse/etrice/core/fsm/AbstractFSMRuntimeModule.java b/plugins/org.eclipse.etrice.core.fsm/src-gen/org/eclipse/etrice/core/fsm/AbstractFSMRuntimeModule.java
index d9ad7cf06..47bc8104f 100644
--- a/plugins/org.eclipse.etrice.core.fsm/src-gen/org/eclipse/etrice/core/fsm/AbstractFSMRuntimeModule.java
+++ b/plugins/org.eclipse.etrice.core.fsm/src-gen/org/eclipse/etrice/core/fsm/AbstractFSMRuntimeModule.java
@@ -110,12 +110,12 @@ public abstract class AbstractFSMRuntimeModule extends org.eclipse.xtext.service
// contributed by org.eclipse.xtext.generator.scoping.AbstractScopingFragment
public void configureIScopeProviderDelegate(com.google.inject.Binder binder) {
- binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class).annotatedWith(com.google.inject.name.Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(org.eclipse.xtext.scoping.impl.SimpleLocalScopeProvider.class);
+ binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class).annotatedWith(com.google.inject.name.Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider.class);
}
// contributed by org.eclipse.xtext.generator.scoping.AbstractScopingFragment
public Class<? extends org.eclipse.xtext.scoping.IGlobalScopeProvider> bindIGlobalScopeProvider() {
- return org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider.class;
+ return org.eclipse.xtext.scoping.impl.DefaultGlobalScopeProvider.class;
}
// contributed by org.eclipse.xtext.generator.scoping.AbstractScopingFragment
diff --git a/plugins/org.eclipse.etrice.core.fsm/src/org/eclipse/etrice/core/fsm/GenerateFSM.mwe2 b/plugins/org.eclipse.etrice.core.fsm/src/org/eclipse/etrice/core/fsm/GenerateFSM.mwe2
index 3360b0453..00fae1a4c 100644
--- a/plugins/org.eclipse.etrice.core.fsm/src/org/eclipse/etrice/core/fsm/GenerateFSM.mwe2
+++ b/plugins/org.eclipse.etrice.core.fsm/src/org/eclipse/etrice/core/fsm/GenerateFSM.mwe2
@@ -96,7 +96,7 @@ Workflow {
// fragment = exporting.SimpleNamesFragment auto-inject {}
// scoping and exporting API
- fragment = scoping.ImportURIScopingFragment auto-inject {}
+ fragment = scoping.ImportNamespacesScopingFragment auto-inject {}
fragment = exporting.QualifiedNamesFragment auto-inject {}
fragment = builder.BuilderIntegrationFragment auto-inject {}
diff --git a/plugins/org.eclipse.etrice.core.room/src-gen/org/eclipse/etrice/core/AbstractRoomRuntimeModule.java b/plugins/org.eclipse.etrice.core.room/src-gen/org/eclipse/etrice/core/AbstractRoomRuntimeModule.java
index 6d84646be..2d1125d68 100644
--- a/plugins/org.eclipse.etrice.core.room/src-gen/org/eclipse/etrice/core/AbstractRoomRuntimeModule.java
+++ b/plugins/org.eclipse.etrice.core.room/src-gen/org/eclipse/etrice/core/AbstractRoomRuntimeModule.java
@@ -110,12 +110,12 @@ public abstract class AbstractRoomRuntimeModule extends org.eclipse.xtext.servic
// contributed by org.eclipse.xtext.generator.scoping.AbstractScopingFragment
public void configureIScopeProviderDelegate(com.google.inject.Binder binder) {
- binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class).annotatedWith(com.google.inject.name.Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(org.eclipse.xtext.scoping.impl.SimpleLocalScopeProvider.class);
+ binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class).annotatedWith(com.google.inject.name.Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider.class);
}
// contributed by org.eclipse.xtext.generator.scoping.AbstractScopingFragment
public Class<? extends org.eclipse.xtext.scoping.IGlobalScopeProvider> bindIGlobalScopeProvider() {
- return org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider.class;
+ return org.eclipse.xtext.scoping.impl.DefaultGlobalScopeProvider.class;
}
// contributed by org.eclipse.xtext.generator.scoping.AbstractScopingFragment
diff --git a/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/GenerateRoom.mwe2 b/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/GenerateRoom.mwe2
index 793ff9ca7..000c851d5 100644
--- a/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/GenerateRoom.mwe2
+++ b/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/GenerateRoom.mwe2
@@ -112,7 +112,7 @@ Workflow {
*/
// scoping and exporting API
- fragment = scoping.ImportURIScopingFragment {}
+ fragment = scoping.ImportNamespacesScopingFragment {}
fragment = exporting.QualifiedNamesFragment {}
fragment = builder.BuilderIntegrationFragment {}
diff --git a/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/RoomRuntimeModule.java b/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/RoomRuntimeModule.java
index 515378aa1..5cd4d0400 100644
--- a/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/RoomRuntimeModule.java
+++ b/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/RoomRuntimeModule.java
@@ -14,7 +14,10 @@
package org.eclipse.etrice.core;
+import org.eclipse.etrice.core.common.scoping.CompoundGlobalScopeProvider;
import org.eclipse.etrice.core.common.scoping.ModelLocatorUriResolver;
+import org.eclipse.etrice.core.common.scoping.ModelPathFileExtensionFilter;
+import org.eclipse.etrice.core.common.scoping.ModelPathGlobalScopeProvider.IModelPathFileFilter;
import org.eclipse.etrice.core.common.validation.CustomValidatorManager.StandaloneValidatorExtension;
import org.eclipse.etrice.core.converter.RoomValueConverterService;
import org.eclipse.etrice.core.genmodel.fsm.ICommonDataCalculator;
@@ -27,6 +30,7 @@ import org.eclipse.etrice.core.validation.ValidatorExtensionManager;
import org.eclipse.xtext.conversion.IValueConverterService;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.resource.IFragmentProvider;
+import org.eclipse.xtext.scoping.IGlobalScopeProvider;
import org.eclipse.xtext.scoping.impl.ImportUriResolver;
import org.eclipse.xtext.validation.INamesAreUniqueValidationHelper;
@@ -74,20 +78,18 @@ public class RoomRuntimeModule extends org.eclipse.etrice.core.AbstractRoomRunti
return RoomFragmentProvider.class;
}
- /* (non-Javadoc)
- * @see org.eclipse.etrice.core.AbstractRoomRuntimeModule#configureIScopeProviderDelegate(com.google.inject.Binder)
- */
- @Override
- public void configureIScopeProviderDelegate(Binder binder) {
- binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class).annotatedWith(
- com.google.inject.name.Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(
- org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider.class);
- }
-
// HOWTO: use URI imports - need special URI resolver
public Class<? extends ImportUriResolver> bindImportUriResolver() {
return ModelLocatorUriResolver.class;
}
+
+ public Class<? extends IGlobalScopeProvider> bindIGlobalScopeProvider() {
+ return CompoundGlobalScopeProvider.class;
+ }
+
+ public IModelPathFileFilter bindIModelPathFileFilter() {
+ return new ModelPathFileExtensionFilter("room", "cage", "actortest");
+ }
// HOWTO: add a value converter
@Override
diff --git a/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/GeneratorApplication.java b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/GeneratorApplication.java
index 4d17fe86e..bc705bc0f 100644
--- a/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/GeneratorApplication.java
+++ b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/GeneratorApplication.java
@@ -207,7 +207,8 @@ public class GeneratorApplication {
private List<Resource> load(Arguments arguments, Logger logger) {
List<String> files = Arrays.asList(arguments.get(GeneratorApplicationOptions.FILES));
- return resourceLoader.load(files, arguments, logger);
+ List<String> modelpath = Arrays.asList(arguments.get(GeneratorApplicationOptions.MODELPATH));
+ return resourceLoader.load(files, modelpath, arguments, logger);
}
private void validate(List<Resource> models, Arguments arguments, Logger logger) {
diff --git a/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/args/Arguments.java b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/args/Arguments.java
index 4557d3731..56a0aca60 100644
--- a/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/args/Arguments.java
+++ b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/args/Arguments.java
@@ -15,7 +15,9 @@
package org.eclipse.etrice.generator.base.args;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.StringJoiner;
/**
* Encapsulates a set of arguments.
@@ -98,6 +100,23 @@ public class Arguments {
@Override
public String toString() {
- return option2Arg.toString();
+ StringJoiner joiner = new StringJoiner(", ");
+ for(Option<?> opt: options) {
+ joiner.add(argToString(opt));
+ }
+ return joiner.toString();
+ }
+
+ private String argToString(Option<?> opt) {
+ String result = opt.getName() + "=";
+ Object obj = option2Arg.get(opt.getName());
+ if(opt.getType().isArray()) {
+ Object[] objArr = (Object[]) obj;
+ result += Arrays.toString(objArr);
+ }
+ else {
+ result += obj.toString();
+ }
+ return result;
}
}
diff --git a/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/FileSystemModelPath.java b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/FileSystemModelPath.java
new file mode 100644
index 000000000..995027399
--- /dev/null
+++ b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/FileSystemModelPath.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+* Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+* All rights reserved.
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+*
+* SPDX-License-Identifier: EPL-2.0
+*
+* CONTRIBUTORS:
+* Jan Belle (initial contribution)
+*
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.base.io;
+
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.Path;
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.xtext.naming.QualifiedName;
+
+/**
+ * Modelpath implementation based on the file system.
+ */
+public class FileSystemModelPath implements IModelPath {
+
+ private List<Path> paths;
+ private HashMap<QualifiedName, List<URI>> packages;
+
+ /**
+ * Creates a new modelpath that contains all files in the passed paths.
+ *
+ * @param paths the paths to search for files
+ */
+ public FileSystemModelPath(List<Path> paths) {
+ this.paths = paths;
+ this.packages = new HashMap<>();
+ }
+
+ @Override
+ public Stream<URI> getFiles(QualifiedName name) {
+ Stream<URI> stream = Stream.empty();
+ while(!name.isEmpty()) {
+ name = name.skipLast(1);
+ stream = Stream.concat(stream, getPackage(name));
+ }
+ return stream;
+ }
+
+ @Override
+ public Stream<URI> getAllFiles() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String toString() {
+ return packages.toString();
+ }
+
+ /**
+ * Returns all files that are contained in the package with the specified name.
+ *
+ * @param name the fully qualified name of the package
+ * @return a stream of all file uris
+ */
+ private Stream<URI> getPackage(QualifiedName name) {
+ List<URI> pkg = packages.computeIfAbsent(name, n -> createPackage(n));
+ return pkg.stream();
+ }
+
+ /**
+ * Searches for all files that are contained in the package with the specified name.
+ *
+ * @param name the fully qualified name of the package
+ * @return a list of all file uris
+ */
+ private List<URI> createPackage(QualifiedName name) {
+ return paths.stream()
+ .map(path -> createPackagePath(name, path))
+ .filter(path -> Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS))
+ .flatMap(dir -> collectFiles(dir))
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * Lists all files of the passed directory.
+ *
+ * @param dir the path of a folder
+ * @return a stream of file uris
+ */
+ private Stream<URI> collectFiles(Path dir) {
+ try {
+ return Files.list(dir)
+ .filter(path -> Files.isRegularFile(path))
+ .map(file -> createURI(file));
+ }
+ catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ /**
+ * Creates an uri for a given path.
+ */
+ private URI createURI(Path path) {
+ return URI.createURI(path.toUri().toString());
+ }
+
+ /**
+ * Creates the path of a specific package within the passed directory.
+ *
+ * @param name the fully qualified name of the package
+ * @param dir the folder which the package path is based on
+ * @return the path of the package
+ */
+ private Path createPackagePath(QualifiedName name, Path dir) {
+ if(!name.isEmpty()) {
+ String firstSegment = name.getFirstSegment();
+ String[] segments = new String[name.getSegmentCount() - 1];
+ for(int i = 0; i < segments.length; ++i) {
+ segments[i] = name.getSegment(i + 1);
+ }
+ Path relativePackagePath = dir.getFileSystem().getPath(firstSegment, segments);
+ Path packagePath = dir.resolve(relativePackagePath);
+ return packagePath;
+ }
+ return dir;
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/GeneratorResourceLoader.java b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/GeneratorResourceLoader.java
index 0a59f8bed..73768ee7b 100644
--- a/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/GeneratorResourceLoader.java
+++ b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/GeneratorResourceLoader.java
@@ -16,7 +16,14 @@
package org.eclipse.etrice.generator.base.io;
import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.Path;
import java.nio.file.Paths;
+import java.nio.file.ProviderNotFoundException;
import java.util.ArrayList;
import java.util.List;
@@ -55,18 +62,17 @@ public class GeneratorResourceLoader implements IGeneratorResourceLoader {
}
@Override
- public List<Resource> load(List<String> files, Arguments arguments, ILogger logger) throws GeneratorException {
+ public List<Resource> load(List<String> files, List<String> modelpath, Arguments arguments, ILogger logger) throws GeneratorException {
doEMFRegistration();
- List<Resource> resources = new ArrayList<>(files.size());
ResourceSet resourceSet = resourceSetProvider.get();
Adapter resourceAddedAdapter = new ResourceAddedAdapter(logger);
resourceSet.eAdapters().add(resourceAddedAdapter);
-
- for(String f: files) {
- Resource r = loadResource(f, resourceSet, logger);
- resources.add(r);
- }
+
+ IModelPath mp = createModelPath(modelpath, logger);
+ resourceSet.getLoadOptions().putIfAbsent(ResourceSetModelPathProvider.LOAD_OPTION_MODELPATH, mp);
+
+ List<Resource> resources = loadResources(files, resourceSet, logger);
EcoreUtil.resolveAll(resourceSet);
@@ -80,21 +86,83 @@ public class GeneratorResourceLoader implements IGeneratorResourceLoader {
}
}
+ private List<Resource> loadResources(List<String> files, ResourceSet resourceSet, ILogger logger) {
+ List<Resource> resources = new ArrayList<>(files.size());
+ for(String f: files) {
+ Resource r = loadResource(f, resourceSet, logger);
+ resources.add(r);
+ }
+ return resources;
+ }
+
private Resource loadResource(String file, ResourceSet rs, ILogger logger) {
+ Path normalizedPath = Paths.get(file).normalize();
+ if(Files.exists(normalizedPath)) {
+ Path realPath = toRealPath(normalizedPath);
+ URI uri = createURI(realPath);
+ try {
+ return rs.getResource(uri, true);
+ }
+ catch(RuntimeException e) {
+ logger.logError("could not load file " + file + "; " + e.getMessage());
+ throw new GeneratorException(e);
+ }
+ }
+ else {
+ logger.logError("could not find file " + file);
+ throw new GeneratorException();
+ }
+ }
+
+ private IModelPath createModelPath(List<String> pathStrings, ILogger logger) {
+ ArrayList<Path> paths = new ArrayList<>(pathStrings.size());
+ for(String pathString: pathStrings) {
+ Path path = Paths.get(pathString).normalize();
+ if(Files.exists(path)) {
+ Path realPath = toRealPath(path);
+ if(Files.isDirectory(realPath)) {
+ paths.add(realPath);
+ }
+ else if(Files.isRegularFile(realPath)) {
+ FileSystem fileSystem = getFileSystem(realPath, logger);
+ for(Path rootDir: fileSystem.getRootDirectories()) {
+ paths.add(rootDir);
+ }
+ }
+ }
+ else {
+ logger.logWarning("could not find modelpath entry " + pathString);
+ }
+ }
+
+ FileSystemModelPath modelpath = new FileSystemModelPath(paths);
+ return modelpath;
+ }
+
+ private FileSystem getFileSystem(Path path, ILogger logger) {
try {
- URI uri = createURI(file);
- return rs.getResource(uri, true);
+ return FileSystems.newFileSystem(path, null);
}
- catch(RuntimeException | IOException e) {
- logger.logError("couldn't load file " + file + "; " + e.getMessage());
+ catch(ProviderNotFoundException e) {
+ logger.logError("could not read modelpath entry " + path.toString());
throw new GeneratorException(e);
}
+ catch(IOException e) {
+ throw new UncheckedIOException(e);
+ }
}
- protected URI createURI(String file) throws IOException {
- String realPath = Paths.get(file).toRealPath().toString();
- URI uri = URI.createFileURI(realPath);
- return uri;
+ protected URI createURI(Path path) {
+ return URI.createURI(path.toUri().toString());
+ }
+
+ private Path toRealPath(Path path, LinkOption... options) {
+ try {
+ return path.toRealPath(options);
+ }
+ catch(IOException e) {
+ throw new UncheckedIOException(e);
+ }
}
private class ResourceAddedAdapter extends AdapterImpl {
diff --git a/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/IGeneratorResourceLoader.java b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/IGeneratorResourceLoader.java
index 3fbf77169..3b0d54398 100644
--- a/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/IGeneratorResourceLoader.java
+++ b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/IGeneratorResourceLoader.java
@@ -34,10 +34,11 @@ public interface IGeneratorResourceLoader {
* Loads the specified files.
*
* @param files the files to load
+ * @param modelpath the modelpath entries
* @param arguments the generator arguments
* @param logger the logger
* @return the loaded resources
*/
- List<Resource> load(List<String> files, Arguments arguments, ILogger logger) throws GeneratorException;
+ List<Resource> load(List<String> files, List<String> modelpath, Arguments arguments, ILogger logger) throws GeneratorException;
}
diff --git a/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/IModelPath.java b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/IModelPath.java
new file mode 100644
index 000000000..7ad76417d
--- /dev/null
+++ b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/IModelPath.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+* Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+* All rights reserved.
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+*
+* SPDX-License-Identifier: EPL-2.0
+*
+* CONTRIBUTORS:
+* Jan Belle (initial contribution)
+*
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.base.io;
+
+import java.util.stream.Stream;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.xtext.naming.QualifiedName;
+
+public interface IModelPath {
+
+ public static final IModelPath EMPTY = new EmptyModelPath();
+
+ /**
+ * Returns all files that could contain the object with the specified name.
+ *
+ * @param name the fully qualified name of the object
+ * @return a stream of file uris
+ */
+ public Stream<URI> getFiles(QualifiedName name);
+
+ /**
+ * Returns all files on this modelpath.
+ *
+ * @return a stream of file uris
+ */
+ public Stream<URI> getAllFiles();
+
+ static class EmptyModelPath implements IModelPath {
+
+ @Override
+ public Stream<URI> getFiles(QualifiedName name) {
+ return Stream.empty();
+ }
+
+ @Override
+ public Stream<URI> getAllFiles() {
+ return Stream.empty();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/IModelPathProvider.java b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/IModelPathProvider.java
new file mode 100644
index 000000000..a6b091172
--- /dev/null
+++ b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/IModelPathProvider.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+* Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+* All rights reserved.
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+*
+* SPDX-License-Identifier: EPL-2.0
+*
+* CONTRIBUTORS:
+* Jan Belle (initial contribution)
+*
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.base.io;
+
+import org.eclipse.emf.ecore.resource.Resource;
+
+import com.google.inject.ImplementedBy;
+
+@ImplementedBy(ResourceSetModelPathProvider.class)
+public interface IModelPathProvider {
+
+ /**
+ * Requests the modelpath for the specified resource.
+ *
+ * @param resource the resource that requested modelpath is for
+ * @return the modelpath for the resource
+ */
+ public IModelPath get(Resource resource);
+
+}
diff --git a/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/ResourceSetModelPathProvider.java b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/ResourceSetModelPathProvider.java
new file mode 100644
index 000000000..0bc4fc72c
--- /dev/null
+++ b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/io/ResourceSetModelPathProvider.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+* Copyright (c) 2018 protos software gmbh (http://www.protos.de).
+* All rights reserved.
+*
+* This program and the accompanying materials are made
+* available under the terms of the Eclipse Public License 2.0
+* which is available at https://www.eclipse.org/legal/epl-2.0/
+*
+* SPDX-License-Identifier: EPL-2.0
+*
+* CONTRIBUTORS:
+* Jan Belle (initial contribution)
+*
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.base.io;
+
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+
+/**
+ * Retrieves the modelpath from the load options of the underlying resource set.
+ */
+public class ResourceSetModelPathProvider implements IModelPathProvider {
+
+ public static final String LOAD_OPTION_MODELPATH = "org.eclipse.etrice.generator.base.modelpath";
+
+ @Override
+ public IModelPath get(Resource resource) {
+ ResourceSet resourceSet = resource.getResourceSet();
+ Object modelpath = resourceSet.getLoadOptions().get(LOAD_OPTION_MODELPATH);
+ if(modelpath != null && modelpath instanceof IModelPath) {
+ return (IModelPath) modelpath;
+ }
+ return IModelPath.EMPTY;
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/setup/GeneratorApplicationOptions.java b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/setup/GeneratorApplicationOptions.java
index b77ac3042..31e1f0882 100644
--- a/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/setup/GeneratorApplicationOptions.java
+++ b/plugins/org.eclipse.etrice.generator.base/src/org/eclipse/etrice/generator/base/setup/GeneratorApplicationOptions.java
@@ -39,6 +39,13 @@ public class GeneratorApplicationOptions implements IOptionModule {
"input files for the generator",
new String[0]);
+ public static final StringArrayOption MODELPATH = new StringArrayOption(
+ GROUP_APPLICATION,
+ "modelpath",
+ "paths",
+ "model imported paths separated by ';'",
+ new String[0]);
+
public static final BooleanOption HELP = new BooleanOption(
GROUP_APPLICATION,
"help",
@@ -87,6 +94,7 @@ public class GeneratorApplicationOptions implements IOptionModule {
@Override
public void configure(List<Option<?>> options) {
options.add(FILES);
+ options.add(MODELPATH);
options.add(HELP);
options.add(GEN_INCREMENTAL);
options.add(GEN_DIR);
diff --git a/plugins/org.eclipse.etrice.generator.launch/META-INF/MANIFEST.MF b/plugins/org.eclipse.etrice.generator.launch/META-INF/MANIFEST.MF
index 2daa273f8..2c496aafc 100644
--- a/plugins/org.eclipse.etrice.generator.launch/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.etrice.generator.launch/META-INF/MANIFEST.MF
@@ -19,7 +19,8 @@ Require-Bundle: org.eclipse.etrice.generator;bundle-version="2.0.0",
org.eclipse.core.variables,
org.eclipse.jdt.launching,
org.eclipse.ui.ide,
- org.eclipse.etrice.generator.base;bundle-version="2.0.0"
+ org.eclipse.etrice.generator.base;bundle-version="2.0.0",
+ org.eclipse.etrice.core.common.ui
Import-Package: org.eclipse.xtext.xbase.lib
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
diff --git a/plugins/org.eclipse.etrice.generator.launch/src/org/eclipse/etrice/generator/launch/GeneratorLaunchConfigurationDelegate.java b/plugins/org.eclipse.etrice.generator.launch/src/org/eclipse/etrice/generator/launch/GeneratorLaunchConfigurationDelegate.java
index 0fe8edf3d..96adb23a3 100644
--- a/plugins/org.eclipse.etrice.generator.launch/src/org/eclipse/etrice/generator/launch/GeneratorLaunchConfigurationDelegate.java
+++ b/plugins/org.eclipse.etrice.generator.launch/src/org/eclipse/etrice/generator/launch/GeneratorLaunchConfigurationDelegate.java
@@ -20,6 +20,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Objects;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
@@ -36,6 +37,8 @@ import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.ui.RefreshTab;
+import org.eclipse.etrice.core.common.ui.modelpath.ModelPathManager;
+import org.eclipse.etrice.core.common.ui.modelpath.WorkspaceModelPath;
import org.eclipse.etrice.generator.base.AbstractGeneratorOptions;
import org.eclipse.etrice.generator.base.io.ILineOutput;
import org.eclipse.etrice.generator.base.setup.GeneratorApplicationOptions;
@@ -88,9 +91,10 @@ public abstract class GeneratorLaunchConfigurationDelegate extends AbstractJavaL
StringBuffer argString = new StringBuffer();
addModels(configuration, entry.getValue(), argString);
addArguments(configuration, entry.getKey(), argString);
+ addModelpath(entry.getKey(), argString);
String[] args = splitCommandLine(argString.toString());
- output.println("\n*** generating project " + entry.getKey().getName() + " ***");
+ output.println("\n*** generating project " + entry.getKey().getName() + " ***\n");
runGenerator(args, output);
// check for cancellation
@@ -246,6 +250,23 @@ public abstract class GeneratorLaunchConfigurationDelegate extends AbstractJavaL
}
/**
+ * Parses the modelpath of the specified project and appends it to the generator arguments.
+ */
+ protected void addModelpath(IProject project, StringBuffer argString) throws CoreException {
+ WorkspaceModelPath modelpath = ModelPathManager.INSTANCE.getModelPath(project);
+ String[] paths = modelpath.getPaths().stream()
+ .map(container -> container.getLocation())
+ .filter(Objects::nonNull)
+ .map(path -> path.toOSString())
+ .toArray(size -> new String[size]);
+
+ if(paths.length > 0) {
+ String modelpathArg = String.join(";", paths);
+ argString.append(" -modelpath \"").append(modelpathArg).append('"');
+ }
+ }
+
+ /**
* split at single spaces but keep strings in double quotes as single argument
* (with double quotes removed)
*/
diff --git a/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/ModelLoader.java b/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/ModelLoader.java
index 556410078..1e7735a8c 100644
--- a/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/ModelLoader.java
+++ b/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/base/ModelLoader.java
@@ -14,6 +14,8 @@
package org.eclipse.etrice.generator.base;
+import java.nio.file.Path;
+
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.etrice.core.common.scoping.ModelLocatorUriResolver;
@@ -38,8 +40,8 @@ public class ModelLoader extends GeneratorResourceLoader {
}
@Override
- protected URI createURI(String file) {
- String uri = uriResolver.resolve(file, null);
+ protected URI createURI(Path path) {
+ String uri = uriResolver.resolve(path.toString(), null);
return URI.createURI(uri);
}
}
diff --git a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMDiagramBehavior.java b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMDiagramBehavior.java
index 92b90188e..e71e8e8c4 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMDiagramBehavior.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.fsm/src/org/eclipse/etrice/ui/behavior/fsm/editor/AbstractFSMDiagramBehavior.java
@@ -15,6 +15,7 @@
package org.eclipse.etrice.ui.behavior.fsm.editor;
import org.eclipse.etrice.ui.common.base.editor.CustomDiagramBehavior;
+import org.eclipse.etrice.ui.common.base.editor.CustomUpdateBehavior;
import org.eclipse.gef.EditPart;
import org.eclipse.graphiti.ui.editor.DefaultRefreshBehavior;
import org.eclipse.graphiti.ui.editor.DefaultUpdateBehavior;
@@ -75,7 +76,7 @@ public class AbstractFSMDiagramBehavior extends CustomDiagramBehavior {
return new RefreshBehavior(this);
}
- static class UpdateBehavior extends DefaultUpdateBehavior {
+ static class UpdateBehavior extends CustomUpdateBehavior {
public UpdateBehavior(DiagramBehavior diagramBehavior) {
super(diagramBehavior);
}
diff --git a/plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/CustomResourceSetProvider.java b/plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/CustomResourceSetProvider.java
deleted file mode 100644
index 5df3a897b..000000000
--- a/plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/CustomResourceSetProvider.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2013 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License 2.0
- * which accompanies this distribution, and is available at
- * https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * CONTRIBUTORS:
- * Henrik Rentz-Reichert (initial contribution)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.ui.common.base.editor;
-
-import static com.google.common.collect.Maps.newHashMap;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.log4j.Logger;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IStorage;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.plugin.EcorePlugin;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.IPackageFragmentRoot;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.xtext.resource.XtextResourceSet;
-import org.eclipse.xtext.ui.resource.IResourceSetProvider;
-import org.eclipse.xtext.ui.resource.IStorage2UriMapperJdtExtensions;
-import org.eclipse.xtext.ui.util.JdtClasspathUriResolver;
-import org.eclipse.xtext.util.Pair;
-
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-
-/**
- * This class is copied from XtextResourceSetProvider with the only modification that we skip our own project in
- * the platform project mappings (marked with <b>[HRR]</b>)
- *
- * @author Henrik Rentz-Reichert
- */
-public class CustomResourceSetProvider implements IResourceSetProvider {
-
- private final static Logger LOG = Logger.getLogger(CustomResourceSetProvider.class);
-
- @Inject
- private Provider<XtextResourceSet> resourceSetProvider;
-
- @Inject
- private IStorage2UriMapperJdtExtensions storage2UriMapper;
-
- public ResourceSet get(IProject project) {
- XtextResourceSet set = resourceSetProvider.get();
- IJavaProject javaProject = JavaCore.create(project);
- if (javaProject != null && javaProject.exists()) {
- set.getURIConverter().getURIMap().putAll(computePlatformURIMap(javaProject));
- set.setClasspathURIContext(javaProject);
- set.setClasspathUriResolver(new JdtClasspathUriResolver());
- }
- return set;
- }
-
- protected Map<URI, URI> computePlatformURIMap(IJavaProject javaProject) {
- HashMap<URI, URI> hashMap = newHashMap();
- try {
- hashMap.putAll(EcorePlugin.computePlatformURIMap(false));
- } catch (Exception e) {
- LOG.error(e.getMessage(), e);
- }
- if (!javaProject.exists())
- return hashMap;
- try {
- IPackageFragmentRoot[] roots = javaProject.getAllPackageFragmentRoots();
- for (IPackageFragmentRoot root : roots) {
- Pair<URI, URI> uriMapping = storage2UriMapper.getURIMapping(root);
- if (uriMapping != null) {
-
- // we could just install the prefix mapping, i.e. platform:resource/my.project/ -> file:/my/path/to/my.project/
- // but then we wouldn't be able to load resources when using hosted bundles, because the target path points to the bin folder.
- // so instead we install qualified file mappings, which also makes normalization faster (i.e. just a lookup in a map instead of testing prefix URIs)
- //
- Map<URI, IStorage> mapping = storage2UriMapper.getAllEntries(root);
- for (URI key : mapping.keySet()) {
- IStorage storage = mapping.get(key);
- URI physicalURI = null;
- if (storage instanceof IFile) {
- physicalURI = URI.createPlatformResourceURI(storage.getFullPath().toString(), true);
- } else {
- physicalURI = key.replacePrefix(uriMapping.getFirst(), uriMapping.getSecond());
- }
- hashMap.put(key, physicalURI);
- if (key.isPlatformResource()) {
- URI pluginURI = URI.createPlatformPluginURI(key.toPlatformString(false), false);
- hashMap.put(pluginURI, physicalURI);
- }
- }
- }
- }
- /*
- */
- final IProject project = javaProject.getProject();
- for (IProject iProject : project.getWorkspace().getRoot().getProjects()) {
- // [HRR]: following line was:
- // if (iProject.isAccessible()) {
- if (iProject!=project && iProject.isAccessible()) {
- IPath location = iProject.getLocation();
- if (location != null) {
- // append a trailing slash so that URI.isPrefix is true.
- hashMap.put(URI.createPlatformResourceURI(iProject.getName()+"/", true), URI.createFileURI(location.toFile().getPath()+"/"));
- }
- }
- }
- } catch (JavaModelException e) {
- LOG.error(e.getMessage(), e);
- }
- return hashMap;
- }
-
- }
diff --git a/plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/CustomUpdateBehavior.java b/plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/CustomUpdateBehavior.java
index afca52e2b..ff82569c4 100644
--- a/plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/CustomUpdateBehavior.java
+++ b/plugins/org.eclipse.etrice.ui.common.base/src/org/eclipse/etrice/ui/common/base/editor/CustomUpdateBehavior.java
@@ -33,6 +33,7 @@ import org.eclipse.graphiti.ui.internal.editor.GFWorkspaceCommandStackImpl;
import org.eclipse.xtext.resource.XtextResourceSet;
import org.eclipse.xtext.ui.resource.IResourceSetProvider;
+import com.google.inject.Inject;
import com.google.inject.Injector;
/**
@@ -42,7 +43,8 @@ import com.google.inject.Injector;
@SuppressWarnings("restriction")
public class CustomUpdateBehavior extends DefaultUpdateBehavior {
- private IResourceSetProvider resourceSetProvider = new CustomResourceSetProvider();
+ @Inject
+ private IResourceSetProvider resourceSetProvider;
/**
* @param diagramBehavior
@@ -51,7 +53,7 @@ public class CustomUpdateBehavior extends DefaultUpdateBehavior {
super(diagramBehavior);
Injector injector = FSMUiModule.getInjector();
- injector.injectMembers(resourceSetProvider);
+ injector.injectMembers(this);
}
/* (non-Javadoc)

Back to the top