aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuergen Haug2018-01-21 09:03:05 -0500
committerJuergen Haug2018-01-26 09:21:09 -0500
commit0244feb1005edfc61a004d94220837dbc4a9bfa6 (patch)
treef47dbfa13fdff1342b527ee1df81c7cef373208c
parentd249d6d6fb49205b53c3bcf7552ab0d71720d9d1 (diff)
downloadorg.eclipse.etrice-0244feb1005edfc61a004d94220837dbc4a9bfa6.tar.gz
org.eclipse.etrice-0244feb1005edfc61a004d94220837dbc4a9bfa6.tar.xz
org.eclipse.etrice-0244feb1005edfc61a004d94220837dbc4a9bfa6.zip
[core] refactored import validation for reusability
-rw-r--r--plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/base/util/ImportHelpers.java95
-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.fsm.ui/src/org/eclipse/etrice/core/fsm/ui/quickfix/FSMQuickfixProvider.xtend6
-rw-r--r--plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/validation/RoomJavaValidator.java123
4 files changed, 182 insertions, 79 deletions
diff --git a/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/base/util/ImportHelpers.java b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/base/util/ImportHelpers.java
new file mode 100644
index 000000000..df0354686
--- /dev/null
+++ b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/base/util/ImportHelpers.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2011 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Juergen Haug (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.core.common.base.util;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.etrice.core.common.base.Import;
+import org.eclipse.xtext.naming.IQualifiedNameConverter;
+import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.resource.IEObjectDescription;
+import org.eclipse.xtext.resource.IResourceDescription;
+import org.eclipse.xtext.resource.IResourceServiceProvider;
+import org.eclipse.xtext.scoping.impl.ImportUriResolver;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Lists;
+
+public class ImportHelpers {
+
+ /**
+ * Returns a list of imported target eObjects for an import or absent if import is not computable.
+ * The list contains either a single exact match (name and quickFixCandidateMatcher) or candidates (name
+ * or quickFixCandidateMatcher) or empty.
+ */
+ public static Optional<List<IEObjectDescription>> getImportedObjectsFor(Import imp, ImportUriResolver importUriResolver,
+ Predicate<IEObjectDescription> quickFixCandidateMatcher) {
+
+ QualifiedName importedFQN = toFQN(imp);
+ if (importedFQN == null)
+ return Optional.empty();
+
+ // check in BaseJavaValidator.checkImportURI
+ String uriString = importUriResolver.resolve(imp);
+ if (uriString == null)
+ return Optional.empty();
+
+ URI uri = URI.createURI(uriString);
+ Resource importedResource = null;
+ try {
+ importedResource = imp.eResource().getResourceSet().getResource(uri, true);
+ } catch (RuntimeException re) {
+ return Optional.empty();
+ }
+ IResourceServiceProvider resourceServiceProvider = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(uri);
+ if (importedResource == null || resourceServiceProvider == null)
+ return Optional.empty();
+ IResourceDescription.Manager manager = resourceServiceProvider.getResourceDescriptionManager();
+ IResourceDescription description = manager.getResourceDescription(importedResource);
+
+ List<IEObjectDescription> candidates = Lists.newArrayList();
+ if (description != null) {
+ Iterator<IEObjectDescription> iter = description.getExportedObjects().iterator();
+ while (iter.hasNext()) {
+ IEObjectDescription eObjDesc = iter.next();
+ if (importedFQN.equals(eObjDesc.getQualifiedName())) {
+ if (quickFixCandidateMatcher.apply(eObjDesc)) {
+ // exact match -> early quit
+ return Optional.of(Lists.newArrayList(eObjDesc));
+ }
+ candidates.add(eObjDesc);
+ } else if (quickFixCandidateMatcher.apply(eObjDesc)) {
+ candidates.add(eObjDesc);
+ }
+ }
+ }
+
+ return Optional.of(candidates);
+ }
+
+ public static QualifiedName toFQN(Import imp) {
+ IQualifiedNameConverter nameConverter = new IQualifiedNameConverter.DefaultImpl();
+ boolean isWildcard = false;
+ try {
+ QualifiedName orig = nameConverter.toQualifiedName(imp.getImportedNamespace());
+ isWildcard = orig.getLastSegment().equals("*");
+ return (isWildcard) ? orig.skipLast(1) : orig;
+ } catch(IllegalArgumentException e){
+ return null;
+ }
+ }
+}
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 791cf77df..072e31342 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
@@ -15,6 +15,9 @@ package org.eclipse.etrice.core.common.validation;
import java.util.HashSet;
import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.etrice.core.common.base.Annotation;
import org.eclipse.etrice.core.common.base.AnnotationAttribute;
import org.eclipse.etrice.core.common.base.AnnotationType;
@@ -22,13 +25,17 @@ import org.eclipse.etrice.core.common.base.BasePackage;
import org.eclipse.etrice.core.common.base.BooleanLiteral;
import org.eclipse.etrice.core.common.base.Documentation;
import org.eclipse.etrice.core.common.base.EnumAnnotationAttribute;
+import org.eclipse.etrice.core.common.base.Import;
import org.eclipse.etrice.core.common.base.IntLiteral;
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.scoping.impl.ImportUriResolver;
import org.eclipse.xtext.validation.Check;
+import com.google.inject.Inject;
+
/**
* Custom validation rules.
*
@@ -42,6 +49,8 @@ public class BaseJavaValidator extends org.eclipse.etrice.core.common.validation
public static final String UNDEFINED_ANNOTATION_ATTRIBUTE_VALUE = "BaseJavaValidator.UndfinedAnnotationAttributeValue";
public static final String DUPLICATE_ANNOTATION_ATTRIBUTE = "BaseJavaValidator.DuplicateAnnotationAttribute";
+ @Inject ImportUriResolver importUriResolver;
+
@Check
public void checkDocumentation(Documentation doc) {
if (doc.getLines().isEmpty())
@@ -169,4 +178,32 @@ public class BaseJavaValidator extends org.eclipse.etrice.core.common.validation
}
}
}
+
+ @Check
+ public void checkImportedURI(Import imp) {
+ String uriString = importUriResolver.resolve(imp);
+ if (uriString == null) {
+ warning("could not load referenced model", BasePackage.Literals.IMPORT__IMPORT_URI);
+ return;
+ }
+
+ URI uri = URI.createURI(uriString);
+ ResourceSet rs = imp.eResource().getResourceSet();
+
+ try {
+ Resource importedResource = rs.getResource(uri, true);
+ if (importedResource == null)
+ return;
+
+ if (importedResource.getContents().isEmpty()) {
+ // importedResource is empty after being loaded the first time (<=> RuntimeException below)
+ warning("could not load referenced model", BasePackage.Literals.IMPORT__IMPORT_URI);
+ return;
+ }
+ } catch (RuntimeException re) {
+ warning("could not load referenced model", BasePackage.Literals.IMPORT__IMPORT_URI);
+ return;
+ }
+ }
+
}
diff --git a/plugins/org.eclipse.etrice.core.fsm.ui/src/org/eclipse/etrice/core/fsm/ui/quickfix/FSMQuickfixProvider.xtend b/plugins/org.eclipse.etrice.core.fsm.ui/src/org/eclipse/etrice/core/fsm/ui/quickfix/FSMQuickfixProvider.xtend
index 8b842d9d2..498bc4c68 100644
--- a/plugins/org.eclipse.etrice.core.fsm.ui/src/org/eclipse/etrice/core/fsm/ui/quickfix/FSMQuickfixProvider.xtend
+++ b/plugins/org.eclipse.etrice.core.fsm.ui/src/org/eclipse/etrice/core/fsm/ui/quickfix/FSMQuickfixProvider.xtend
@@ -4,22 +4,22 @@
package org.eclipse.etrice.core.fsm.ui.quickfix
import com.google.inject.Inject
+import org.eclipse.etrice.core.common.converter.BaseConverterService
+import org.eclipse.etrice.core.common.ui.quickfix.BaseQuickfixProvider
import org.eclipse.etrice.core.fsm.fSM.DetailCode
import org.eclipse.etrice.core.fsm.validation.FSMJavaValidator
import org.eclipse.xtext.formatting.IWhitespaceInformationProvider
import org.eclipse.xtext.nodemodel.util.NodeModelUtils
-import org.eclipse.xtext.ui.editor.quickfix.DefaultQuickfixProvider
import org.eclipse.xtext.ui.editor.quickfix.Fix
import org.eclipse.xtext.ui.editor.quickfix.IssueResolutionAcceptor
import org.eclipse.xtext.validation.Issue
-import org.eclipse.etrice.core.common.converter.BaseConverterService
/**
* Custom quickfixes.
*
* see http://www.eclipse.org/Xtext/documentation.html#quickfixes
*/
-class FSMQuickfixProvider extends DefaultQuickfixProvider {
+class FSMQuickfixProvider extends BaseQuickfixProvider {
@Inject
BaseConverterService converterService
diff --git a/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/validation/RoomJavaValidator.java b/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/validation/RoomJavaValidator.java
index cf6f2a6b5..0d5c04a5e 100644
--- a/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/validation/RoomJavaValidator.java
+++ b/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/validation/RoomJavaValidator.java
@@ -16,22 +16,20 @@ package org.eclipse.etrice.core.validation;
import java.util.ArrayList;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import org.eclipse.emf.common.util.EList;
-import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.etrice.core.common.base.Annotation;
import org.eclipse.etrice.core.common.base.BasePackage;
import org.eclipse.etrice.core.common.base.Import;
import org.eclipse.etrice.core.common.base.LiteralType;
+import org.eclipse.etrice.core.common.base.util.ImportHelpers;
import org.eclipse.etrice.core.common.validation.ValidationHelpers;
import org.eclipse.etrice.core.common.validation.ValidationHelpers.NamedObject;
import org.eclipse.etrice.core.common.validation.ValidationHelpers.NamedObjectList;
@@ -64,24 +62,22 @@ import org.eclipse.etrice.core.room.RefPath;
import org.eclipse.etrice.core.room.ReferenceType;
import org.eclipse.etrice.core.room.RoomAnnotationTargetEnum;
import org.eclipse.etrice.core.room.RoomClass;
-import org.eclipse.etrice.core.room.RoomModel;
import org.eclipse.etrice.core.room.RoomPackage;
import org.eclipse.etrice.core.room.ServiceImplementation;
import org.eclipse.etrice.core.room.StandardOperation;
import org.eclipse.etrice.core.room.StructureClass;
import org.eclipse.etrice.core.room.SubSystemClass;
import org.eclipse.etrice.core.room.util.RoomHelpers;
-import org.eclipse.xtext.naming.IQualifiedNameConverter;
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.IResourceServiceProvider;
import org.eclipse.xtext.scoping.impl.ImportUriResolver;
import org.eclipse.xtext.validation.Check;
import com.google.common.base.Function;
-import com.google.common.collect.Lists;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
@@ -95,6 +91,8 @@ public class RoomJavaValidator extends AbstractRoomJavaValidator {
@Inject protected ValidationUtil validationUtil;
@Inject protected IQualifiedNameProvider fqnProvider;
+
+ @Inject ImportUriResolver importUriResolver;
/* message strings */
public static final String OPTIONAL_REFS_HAVE_TO_HAVE_MULTIPLICITY_ANY = "optional refs have to have multiplicity any [*]";
@@ -104,94 +102,67 @@ public class RoomJavaValidator extends AbstractRoomJavaValidator {
/* tags for quick fixes */
public static final String THREAD_MISSING = "RoomJavaValidator.ThreadMissing";
public static final String DUPLICATE_ACTOR_INSTANCE_MAPPING = "RoomJavaValidator.DuplicateActorInstanceMapping";
- public static final String WRONG_NAMESPACE = "RoomJavaValidator.WrongNamespace";
public static final String CIRCULAR_CONTAINMENT = "RoomJavaValidator.CircularContainment";
public static final String ACTOR_REF_CHANGE_REF_TYPE_TO_FIXED_OR_MULT_TO_ANY = "RoomJavaValidator.ActorRefChangeRefTypeToFixed";
public static final String ACTOR_REF_CHANGE_REF_TYPE_TO_OPTIONAL = "RoomJavaValidator.ActorRefChangeRefTypeToOptional";
+ public static final String WRONG_NAMESPACE = "RoomJavaValidator.WrongNamespace";
public static final String CHANGE_DESTRUCTOR_NAME = "RoomJavaValidator.ChangeDestructorName";
public static final String CHANGE_CONSTRUCTOR_NAME = "RoomJavaValidator.ChangeConstructorName";
public static final String INVALID_ANNOTATION_TARGET = "RoomJavaValidator.InvalidAnnotationTarget";
public static final String OPERATION_MISSING_OVERRIDE = "RoomJavaValidator.OperationMissingOverride";
public static final String OPERATION_EXTRANEOUS_OVERRIDE = "RoomJavaValidator.OperationExtraneousOverride";
- public static final String INCONSISTENT_COMMUNICATION_TYPE = "RoomJavaValidator.InconsistentCommType";
-
- @Inject ImportUriResolver importUriResolver;
+ public static final String INCONSISTENT_COMMUNICATION_TYPE = "RoomJavaValidator.InconsistentCommType";
@Check
- public void checkImportedNamespace(Import imp) {
- if (imp.getImportURI()==null)
- return;
-
- IQualifiedNameConverter nameConverter = new IQualifiedNameConverter.DefaultImpl();
- QualifiedName importedFQN;
- boolean isWildcard = false;
- try {
- QualifiedName orig = nameConverter.toQualifiedName(imp.getImportedNamespace());
- isWildcard = orig.getLastSegment().equals("*");
- importedFQN = (isWildcard) ? orig.skipLast(1) : orig;
- } catch(IllegalArgumentException e){
+ public void checkRoomImportedNamespace(Import imp) {
+ QualifiedName importedFQN = ImportHelpers.toFQN(imp);
+ if(importedFQN == null)
return;
- }
-
- String uriString = importUriResolver.resolve(imp);
- if(uriString == null) {
- warning("could not load referenced model", BasePackage.Literals.IMPORT__IMPORT_URI);
- return;
- }
-
- URI uri = URI.createURI(uriString);
- ResourceSet rs = imp.eResource().getResourceSet();
-
- List<RoomModel> importedModels = Lists.newArrayList();
- try {
- Resource res = rs.getResource(uri, true);
- if (res==null)
- return;
+
+ Predicate<IEObjectDescription> nameMatcher = new Predicate<IEObjectDescription>() {
- if (res.getContents().isEmpty()) {
- error("referenced model is empty", BasePackage.Literals.IMPORT__IMPORT_URI);
- return;
+ @Override
+ public boolean apply(IEObjectDescription input) {
+ return importedFQN.equals(input.getQualifiedName());
}
+
+ };
+ Predicate<IEObjectDescription> candidateMatcher = new Predicate<IEObjectDescription>() {
- for(EObject content : res.getContents()) {
- if(content instanceof RoomModel) {
- importedModels.add((RoomModel) content);
- }
+ @Override
+ public boolean apply(IEObjectDescription input) {
+ return input.getEClass() == RoomPackage.Literals.ROOM_MODEL;
}
- if (importedModels.isEmpty()) {
- if (uri.fileExtension().equals("room"))
- error("referenced model is no ROOM model (but has .room extension)", BasePackage.Literals.IMPORT__IMPORT_URI);
- else
- warning("referenced model is no ROOM model", BasePackage.Literals.IMPORT__IMPORT_URI);
- return;
+ };
+ Predicate<IEObjectDescription> allowedClasses = new Predicate<IEObjectDescription>() {
+
+ @Override
+ public boolean apply(IEObjectDescription input) {
+ return input.getEClass() == RoomPackage.Literals.ROOM_MODEL ||
+ RoomPackage.Literals.ROOM_CLASS.isSuperTypeOf(input.getEClass());
}
- }
- catch (RuntimeException re) {
- warning("could not load referenced model", BasePackage.Literals.IMPORT__IMPORT_URI);
+
+ };
+ Optional<List<IEObjectDescription>> importCandidates = ImportHelpers.getImportedObjectsFor(imp, importUriResolver, candidateMatcher);
+ if(!importCandidates.isPresent())
return;
- }
-
- final IResourceServiceProvider resourceServiceProvider = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(uri);
- if (resourceServiceProvider==null)
+
+ List<IEObjectDescription> candidates = importCandidates.get();
+ if(Iterables.any(candidates, Predicates.and(nameMatcher, candidateMatcher)))
return;
- IResourceDescription.Manager manager = resourceServiceProvider.getResourceDescriptionManager();
- IResourceDescription description = manager.getResourceDescription(importedModels.get(0).eResource());
-
- // TODO check for empty namespace
- boolean exportedNameMatch = false;
- if (description != null) {
- Iterator<IEObjectDescription> iter = description.getExportedObjects().iterator();
- while(iter.hasNext()){
- QualifiedName exportedFQN = iter.next().getQualifiedName();
- if(exportedNameMatch |= importedFQN.equals(exportedFQN))
- break;
- }
- }
- if(!exportedNameMatch) {
- error("no match for imported namespace", BasePackage.Literals.IMPORT__IMPORTED_NAMESPACE, WRONG_NAMESPACE, importedModels.get(0).getName()+".*");
+
+ Set<String> candidatesNames = Sets.newLinkedHashSet();
+ for(IEObjectDescription eObjDesc : candidates) {
+ candidatesNames.add(eObjDesc.getQualifiedName().toString() + ".*");
}
+
+ if(!Iterables.any(candidates, nameMatcher))
+ error("no match for imported namespace", BasePackage.Literals.IMPORT__IMPORTED_NAMESPACE, WRONG_NAMESPACE, candidatesNames.toArray(new String[0]));
+ else if(!Iterables.any(Iterables.filter(candidates, nameMatcher), allowedClasses))
+ error("referenced model is not supported", BasePackage.Literals.IMPORT__IMPORTED_NAMESPACE, WRONG_NAMESPACE, candidatesNames.toArray(new String[0]));
}
+
@Check
public void checkActorRef(ActorRef ar) {