/******************************************************************************* * Copyright (c) 2015, 2019 itemis AG (http://www.itemis.eu) and others. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. * * SPDX-License-Identifier: EPL-2.0 *******************************************************************************/ package org.eclipse.xtext.web.example.entities.validation; import org.eclipse.xtext.common.types.JvmGenericType; import org.eclipse.xtext.common.types.JvmOperation; import org.eclipse.xtext.util.Strings; import org.eclipse.xtext.validation.Check; import org.eclipse.xtext.validation.ValidationMessageAcceptor; import org.eclipse.xtext.web.example.entities.domainmodel.DomainmodelPackage; import org.eclipse.xtext.web.example.entities.domainmodel.Entity; import org.eclipse.xtext.web.example.entities.domainmodel.Feature; import org.eclipse.xtext.web.example.entities.domainmodel.Operation; import org.eclipse.xtext.web.example.entities.domainmodel.PackageDeclaration; import org.eclipse.xtext.web.example.entities.domainmodel.Property; import org.eclipse.xtext.xbase.jvmmodel.IJvmModelAssociations; import org.eclipse.xtext.xbase.lib.IterableExtensions; import org.eclipse.xtext.xbase.lib.StringExtensions; import org.eclipse.xtext.xbase.typesystem.override.OverrideHelper; import com.google.common.collect.HashMultimap; import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; import com.google.inject.Inject; /** * This class contains custom validation rules. * * See * https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation */ public class EntitiesValidator extends AbstractEntitiesValidator { @Inject private IJvmModelAssociations jvmModelAssociations; @Inject private OverrideHelper overrideHelper; @Check public void checkTypeNameStartsWithCapital(Entity entity) { if (!Character.isUpperCase(entity.getName().charAt(0))) { warning("Name should start with a capital", DomainmodelPackage.Literals.ABSTRACT_ELEMENT__NAME, ValidationMessageAcceptor.INSIGNIFICANT_INDEX, IssueCodes.INVALID_TYPE_NAME, entity.getName()); } } @Check public void checkFeatureNameStartsWithLowercase(Feature feature) { if (!Character.isLowerCase(feature.getName().charAt(0))) { warning("Name should start with a lowercase", DomainmodelPackage.Literals.FEATURE__NAME, ValidationMessageAcceptor.INSIGNIFICANT_INDEX, IssueCodes.INVALID_FEATURE_NAME, feature.getName()); } } @Check public void checkPackage(PackageDeclaration packages) { if (Strings.isEmpty(packages.getName())) { error("Name cannot be empty", DomainmodelPackage.Literals.ABSTRACT_ELEMENT__NAME); } if ("java".equals(packages.getName())) { error("Invalid package name", DomainmodelPackage.Literals.ABSTRACT_ELEMENT__NAME); } } @Check public void checkPropertyNamesAreUnique(Entity entity) { Multimap<String, Property> name2properties = HashMultimap.create(); IterableExtensions .filter(Iterables.filter(entity.getFeatures(), Property.class), (f) -> !StringExtensions.isNullOrEmpty(f.getName())) .forEach((p) -> name2properties.put(p.getName(), p)); name2properties.asMap().values().forEach((properties) -> { if (properties.size() > 1) { properties.forEach((p) -> { error("Duplicate property " + p.getName(), p, DomainmodelPackage.Literals.FEATURE__NAME, IssueCodes.DUPLICATE_PROPERTY); }); } }); } @Check public void checkOperationNamesAreUnique(Entity entity) { JvmGenericType inferredJavaClass = IterableExtensions .head(Iterables.filter(jvmModelAssociations.getJvmElements(entity), JvmGenericType.class)); Multimap<String, JvmOperation> signature2Declarations = HashMultimap.create(); overrideHelper.getResolvedFeatures(inferredJavaClass).getDeclaredOperations().forEach((it) -> { signature2Declarations.put(it.getResolvedErasureSignature(), it.getDeclaration()); }); signature2Declarations.asMap().values().forEach((jvmOperations) -> { if (jvmOperations.size() > 1) { Iterables .filter(IterableExtensions.map(jvmOperations, (op) -> jvmModelAssociations.getPrimarySourceElement(op)), Operation.class) .forEach((op) -> { error("Duplicate operation " + op.getName(), op, DomainmodelPackage.Literals.FEATURE__NAME, IssueCodes.DUPLICATE_OPERATION); }); } }); } }