summaryrefslogtreecommitdiffstats
path: root/rba.tool.editor/src/rba/tool/editor/validation/UniqueNameValidationHelper.xtend
diff options
context:
space:
mode:
Diffstat (limited to 'rba.tool.editor/src/rba/tool/editor/validation/UniqueNameValidationHelper.xtend')
-rw-r--r--rba.tool.editor/src/rba/tool/editor/validation/UniqueNameValidationHelper.xtend211
1 files changed, 211 insertions, 0 deletions
diff --git a/rba.tool.editor/src/rba/tool/editor/validation/UniqueNameValidationHelper.xtend b/rba.tool.editor/src/rba/tool/editor/validation/UniqueNameValidationHelper.xtend
new file mode 100644
index 0000000..dc5ef18
--- /dev/null
+++ b/rba.tool.editor/src/rba/tool/editor/validation/UniqueNameValidationHelper.xtend
@@ -0,0 +1,211 @@
+package rba.tool.editor.validation
+
+import com.google.common.collect.Maps
+import com.google.inject.Inject
+import java.util.Map
+import org.eclipse.emf.ecore.EClass
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.emf.ecore.EStructuralFeature
+import org.eclipse.emf.ecore.resource.Resource
+import org.eclipse.xtext.naming.QualifiedName
+import org.eclipse.xtext.resource.IEObjectDescription
+import org.eclipse.xtext.resource.IResourceDescriptionsProvider
+import org.eclipse.xtext.resource.IResourceServiceProvider
+import org.eclipse.xtext.service.OperationCanceledManager
+import org.eclipse.xtext.util.CancelIndicator
+import org.eclipse.xtext.util.SimpleAttributeResolver
+import org.eclipse.xtext.validation.ValidationMessageAcceptor
+import rba.core.RBACorePackage
+import rba.tool.editor.messages.Messages
+import rba.tool.editor.rbaEditorModel.RbaEditorModelPackage
+import java.util.List
+import java.util.Arrays
+import rba.core.impl.ProjectImpl
+
+class UniqueNameValidationHelper {
+
+ @Inject
+ private IResourceServiceProvider.Registry resourceServiceProviderRegistry = IResourceServiceProvider.Registry.INSTANCE;
+
+ @Inject
+ private IResourceDescriptionsProvider resourceDescriptionsProvider;
+
+ @Inject
+ private OperationCanceledManager operationCanceledManager = new OperationCanceledManager();
+
+ private static final List<String> RESTRICTED_NAMES = Arrays.asList(
+ "AnyAreasOfContent",
+ "AnyContentsOfArea",
+ "NullExpression"
+ );
+
+ private String NAMEDELEMENT_NAME_DUPLICATE = Messages.NAMEDELEMENT_NAME_DUPLICATE;
+
+ def public void checkUniqueNames(Resource resource, CancelIndicator cancelIndicator, ValidationMessageAcceptor acceptor) {
+ val resourceServiceProvider = resourceServiceProviderRegistry.getResourceServiceProvider(resource.getURI());
+ if(resourceServiceProvider === null) {
+ return;
+ }
+
+ val manager = resourceServiceProvider.getResourceDescriptionManager();
+ if(manager !== null) {
+ val description = manager.getResourceDescription(resource);
+ if(description !== null) {
+ val descriptions = description.getExportedObjects();
+ val currentIter = descriptions.iterator();
+ if(!currentIter.hasNext()) {
+ return;
+ }
+ val clusterToNames = Maps.newHashMap();
+
+ val containerManager = resourceServiceProvider.getContainerManager();
+ val resourceDescriptions = resourceDescriptionsProvider.getResourceDescriptions(resource.getResourceSet());
+ for (container : containerManager.getVisibleContainers(description, resourceDescriptions)) {
+ val siblingsResourceDescriptions = container.resourceDescriptions.filter(r|r.URI.toString !== description.URI.toString);
+ val siblingsObjectDescriptions = siblingsResourceDescriptions.map(srd|srd.exportedObjects.filter[obj|
+ obj.EClass !== RBACorePackage.Literals.TAG && obj.EClass !== RbaEditorModelPackage.Literals.CTAG
+ ]).flatten;
+ for (siblingsObjectDescription : siblingsObjectDescriptions) {
+ initDescriptionForDuplicatedName(siblingsObjectDescription, clusterToNames, acceptor);
+ }
+ }
+
+ while(currentIter.hasNext()) {
+ val objectDescription = currentIter.next();
+ checkDescriptionForDuplicatedName(objectDescription, clusterToNames, acceptor);
+ operationCanceledManager.checkCanceled(cancelIndicator);
+ }
+ }
+ }
+ }
+
+ def protected void initDescriptionForDuplicatedName(IEObjectDescription description, Map<EClass, Map<QualifiedName, IEObjectDescription>> clusterTypeToName, ValidationMessageAcceptor acceptor) {
+ val object = description.getEObjectOrProxy();
+ val eClass = object.eClass();
+ val qualifiedName = description.getName();
+ val clusterType = getAssociatedClusterType(eClass);
+ if(clusterType === null) {
+ return;
+ }
+
+ val nameToDescription = clusterTypeToName.get(clusterType);
+ if(nameToDescription === null) {
+ val newNameToDescription = Maps.newHashMap();
+ newNameToDescription.put(qualifiedName, description);
+ clusterTypeToName.put(clusterType, newNameToDescription);
+ } else if(!nameToDescription.containsKey(qualifiedName)) {
+ nameToDescription.put(qualifiedName, description);
+ }
+ }
+
+ def protected void checkDescriptionForDuplicatedName(IEObjectDescription description, Map<EClass, Map<QualifiedName, IEObjectDescription>> clusterTypeToName, ValidationMessageAcceptor acceptor) {
+ val object = description.getEObjectOrProxy();
+ val eClass = object.eClass();
+ if(eClass === RBACorePackage.Literals.VARIABLE) {
+ return;
+ }
+
+ if(eClass === RBACorePackage.Literals.TAG || eClass === RbaEditorModelPackage.Literals.CTAG) {
+ return;
+ }
+
+ val qualifiedName = description.getName();
+ val clusterType = getAssociatedClusterType(eClass);
+ if(clusterType === null) {
+ return;
+ }
+
+ val nameToDescription = clusterTypeToName.get(clusterType);
+ if(nameToDescription === null) {
+ val newNameToDescription = Maps.newHashMap();
+ newNameToDescription.put(qualifiedName, description);
+ clusterTypeToName.put(clusterType, newNameToDescription);
+ } else {
+ if(nameToDescription.containsKey(qualifiedName)) {
+ val prevDescription = nameToDescription.get(qualifiedName);
+
+ if(prevDescription !== null && !(prevDescription.getEObjectOrProxy() instanceof ProjectImpl)) {
+ createDuplicateNameError(prevDescription, clusterType, acceptor);
+ nameToDescription.put(qualifiedName, null);
+ }
+ createDuplicateNameError(description, clusterType, acceptor);
+ } else if(isNamingRestricted(qualifiedName)){
+ createNamingRestrictionError(description, clusterType, acceptor, qualifiedName)
+ } else {
+ nameToDescription.put(qualifiedName, description);
+ }
+ }
+ }
+
+ def protected void createDuplicateNameError(IEObjectDescription description, EClass clusterType, ValidationMessageAcceptor acceptor) {
+ val object = description.getEObjectOrProxy();
+ if(object.eIsProxy) {
+ return;
+ }
+
+ val feature = getNameFeature(object);
+ acceptor.acceptError(getDuplicateNameErrorMessage(description), object, feature, ValidationMessageAcceptor.INSIGNIFICANT_INDEX, getErrorCode());
+ }
+
+ def String getDuplicateNameErrorMessage(IEObjectDescription description) {
+ val qualifiedName = description.getQualifiedName().toString();
+ val shortName = String.valueOf(if(qualifiedName !== null && qualifiedName !== "") qualifiedName else "<unnamed>");
+ return String.format(NAMEDELEMENT_NAME_DUPLICATE, shortName);
+ }
+
+ def protected boolean isContainerInformationHelpful(IEObjectDescription description, EObject container, String containerTypeLabel, EStructuralFeature containerNameFeature) {
+ return containerTypeLabel !== null && containerNameFeature !== null;
+ }
+
+ def protected boolean isContainerInformationHelpful(IEObjectDescription description, String shortName) {
+ return true;
+ }
+
+ def protected EObject getContainerForErrorMessage(EObject object) {
+ return object.eContainer();
+ }
+
+ def protected String getTypeLabel(EClass eClass) {
+ return eClass.getName();
+ }
+
+ def protected EStructuralFeature getNameFeature(EObject object) {
+ return SimpleAttributeResolver.NAME_RESOLVER.getAttribute(object);
+ }
+
+ def protected EClass getAssociatedClusterType(EClass eClass) {
+ val superTypes = eClass.getESuperTypes();
+ if(superTypes.isEmpty()) {
+ return null;
+ }
+ if(superTypes.contains(RBACorePackage.Literals.NAMED_ELEMENT)) {
+ return RBACorePackage.Literals.NAMED_ELEMENT;
+ }
+ return getAssociatedClusterType(superTypes.get(0));
+ }
+
+ def protected String getErrorCode() {
+ return null;
+ }
+
+ def protected boolean isNamingRestricted(QualifiedName qualifiedName){
+ if ( qualifiedName.getSegments().size() > 0 ) {
+ val i = qualifiedName.getSegments().size() - 1;
+ if( RESTRICTED_NAMES.contains(qualifiedName.getSegments().get(i).toString) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ def protected void createNamingRestrictionError(IEObjectDescription description, EClass clusterType,
+ ValidationMessageAcceptor acceptor, QualifiedName qualifiedName) {
+ val object = description.getEObjectOrProxy();
+ if (object.eIsProxy) {
+ return;
+ }
+ val feature = getNameFeature(object);
+ val errorMessage = String.format(Messages.NAME_RESTRICTION, object.eClass.name, qualifiedName.toString)
+ acceptor.acceptError(errorMessage, object, feature, ValidationMessageAcceptor.INSIGNIFICANT_INDEX,getErrorCode());
+ }
+}