blob: 156b4c3aff958aa2a7b4a3933ec26c4881ce7b08 [file] [log] [blame]
/**
* Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
* 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:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.dsl.common.xtext.validation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.osbp.dsl.common.xtext.extensions.ModelExtensions;
import org.eclipse.osbp.dsl.semantic.common.types.LAttribute;
import org.eclipse.osbp.dsl.semantic.common.types.LDataType;
import org.eclipse.osbp.dsl.semantic.common.types.LFeature;
import org.eclipse.osbp.dsl.semantic.common.types.LFeaturesHolder;
import org.eclipse.osbp.dsl.semantic.common.types.LPackage;
import org.eclipse.osbp.dsl.semantic.common.types.LReference;
import org.eclipse.osbp.dsl.semantic.common.types.LType;
import org.eclipse.osbp.dsl.semantic.common.types.LTypedPackage;
import org.eclipse.osbp.dsl.semantic.common.types.OSBPTypesPackage;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.resource.IContainer;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.IResourceDescription;
import org.eclipse.xtext.resource.IResourceDescriptions;
import org.eclipse.xtext.resource.impl.ResourceDescriptionsProvider;
import org.eclipse.xtext.validation.Check;
import org.eclipse.xtext.validation.CheckType;
import org.eclipse.xtext.validation.NamesAreUniqueValidator;
import org.eclipse.xtext.validation.ValidationMessageAcceptor;
import com.google.inject.Inject;
// TODO: Auto-generated Javadoc
/**
* Custom validation rules.
*
* see http://www.eclipse.org/Xtext/documentation.html#validation
*/
public class CommonGrammarValidator
extends org.eclipse.osbp.dsl.common.xtext.validation.AbstractCommonGrammarValidator {
/** The Constant CODE__DUPLICATE_LPACKAGE_IN_PROJECT. */
public static final String CODE__DUPLICATE_LPACKAGE_IN_PROJECT = "0_100";
/** The Constant CODE__DUPLICATE_LTYPE_IN_PROJECT. */
public static final String CODE__DUPLICATE_LTYPE_IN_PROJECT = "0_101";
/** The Constant CODE__DUPLICATE_LPACKAGE_IN_FILE. */
public static final String CODE__DUPLICATE_LPACKAGE_IN_FILE = "0_102";
/** The Constant CODE__MANY_TO_MANY__NOT_SUPPORTED. */
public static final String CODE__MANY_TO_MANY__NOT_SUPPORTED = "0_103";
/** The Constant CODE__NOT_A_VALID_PRIMITIVE. */
public static final String CODE__NOT_A_VALID_PRIMITIVE = "0_104";
/** The Constant CODE__FORBIDDEN_JAVA_KEYWORD. */
public static final String CODE__FORBIDDEN_JAVA_KEYWORD = "0_105";
/** The Constant CODE__DUPLICATE_LDATATYPE_IN_PACKAGE. */
public static final String CODE__DUPLICATE_LDATATYPE_IN_PACKAGE = "0_106";
/** The Constant CODE__MISSING__JAVAX_PERSISTENCE. */
public static final String CODE__MISSING__JAVAX_PERSISTENCE = "0_107";
/** The Constant CODE__MISSING__L_RUNTIME_COMMON. */
public static final String CODE__MISSING__L_RUNTIME_COMMON = "0_108";
/** The Constant CODE__MISSING__DATATYPE_LIB. */
public static final String CODE__MISSING__DATATYPE_LIB = "0_109";
/** The Constant CODE__MISSING__DTO_LIB. */
public static final String CODE__MISSING__DTO_LIB = "0_110";
/** The Constant CODE__MISSING__XBASE_LIB. */
public static final String CODE__MISSING__XBASE_LIB = "0_111";
/** The Constant CODE__MISSING__JDK_1_5. */
public static final String CODE__MISSING__JDK_1_5 = "0_112";
/** The Constant CODE__FEATURE_LOWERCASE. */
public static final String CODE__FEATURE_LOWERCASE = "0_113";
public static final String CODE__DUPLICATE_FEATURE_NAME = "0_114";
/** The qnp. */
@Inject
private IQualifiedNameProvider qnp;
/** The extensions. */
@Inject
private ModelExtensions extensions;
/** The unique validator. */
@Inject
private NamesAreUniqueValidator uniqueValidator;
/** The containermanager. */
@Inject
private IContainer.Manager containermanager;
/** The resource descriptions provider. */
@Inject
private ResourceDescriptionsProvider resourceDescriptionsProvider;
/** The Constant javakeywords. */
public static final Set<String> javakeywords = new HashSet<String>();
static {
javakeywords.add("abstract");
javakeywords.add("assert");
javakeywords.add("boolean");
javakeywords.add("break");
javakeywords.add("byte");
javakeywords.add("case");
javakeywords.add("catch");
javakeywords.add("char");
javakeywords.add("class");
javakeywords.add("const");
javakeywords.add("continue");
javakeywords.add("default");
javakeywords.add("double");
javakeywords.add("do");
javakeywords.add("else");
javakeywords.add("enum");
javakeywords.add("extends");
javakeywords.add("false");
javakeywords.add("final");
javakeywords.add("finally");
javakeywords.add("float");
javakeywords.add("for");
javakeywords.add("goto");
javakeywords.add("if");
javakeywords.add("implements");
javakeywords.add("import");
javakeywords.add("instanceof");
javakeywords.add("int");
javakeywords.add("interface");
javakeywords.add("native");
javakeywords.add("new");
javakeywords.add("null");
javakeywords.add("package");
javakeywords.add("private");
javakeywords.add("protected");
javakeywords.add("public");
javakeywords.add("return");
javakeywords.add("short");
javakeywords.add("static");
javakeywords.add("strictfp");
javakeywords.add("super");
javakeywords.add("switch");
javakeywords.add("synchronized");
javakeywords.add("this");
javakeywords.add("throw");
javakeywords.add("throws");
javakeywords.add("transient");
javakeywords.add("true");
javakeywords.add("try");
javakeywords.add("void");
javakeywords.add("volatile");
javakeywords.add("while");
}
/** The Constant primitiveWrappers. */
private static final Set<String> primitiveWrappers = new HashSet<String>();
static {
primitiveWrappers.add("java.lang.Integer");
primitiveWrappers.add("java.lang.Long");
primitiveWrappers.add("java.lang.Short");
primitiveWrappers.add("java.lang.Double");
primitiveWrappers.add("java.lang.Float");
primitiveWrappers.add("java.lang.Character");
primitiveWrappers.add("java.lang.Byte");
primitiveWrappers.add("java.lang.Boolean");
}
/**
* Gets the keywords.
*
* @return the keywords
*/
public Set<String> getKeywords() {
return Collections.unmodifiableSet(javakeywords);
}
/**
* Check datatype_as primitive.
*
* @param dt
* the dt
*/
public void checkDatatype_asPrimitive(LDataType dt) {
if (dt.isAsPrimitive()) {
if (!primitiveWrappers.contains(dt.getJvmTypeReference().getQualifiedName())) {
error("The type is not a wrapper from a primitive type!", dt,
OSBPTypesPackage.Literals.LDATA_TYPE__AS_PRIMITIVE,
ValidationMessageAcceptor.INSIGNIFICANT_INDEX, CODE__NOT_A_VALID_PRIMITIVE, (String[]) null);
}
}
}
/**
* Check properties_ java key word.
*
* @param lprop
* the lprop
*/
public void checkProperties_JavaKeyWord(LFeature lprop) {
if (lprop.getName() == null) {
return;
}
if (javakeywords.contains(lprop.getName())) {
error("The name of the property is a java keyword and not allowed!",
OSBPTypesPackage.Literals.LFEATURE__NAME, ValidationMessageAcceptor.INSIGNIFICANT_INDEX,
CODE__FORBIDDEN_JAVA_KEYWORD, (String[]) null);
}
}
/**
* Check duplicate type_ in project.
*
* @param type
* the type
*/
public void checkDuplicateType_InProject(LType type) {
Map<IContainer, List<LType>> lTypes = getAllFor(type);
for (Map.Entry<IContainer, List<LType>> temp : lTypes.entrySet())
if (temp.getValue().size() > 1) {
error(String.format("Duplicate type %s in container", qnp.getFullyQualifiedName(type).toString()), type,
OSBPTypesPackage.Literals.LTYPE__NAME, ValidationMessageAcceptor.INSIGNIFICANT_INDEX,
CODE__DUPLICATE_LTYPE_IN_PROJECT, (String[]) null);
}
}
@Check
public void checkDuplicateFeatures(LFeaturesHolder type) {
Set<String> names = new HashSet<>();
for (LFeature feature : type.getAllFeatures()) {
if(feature.getName() == null) {
// annotation support features have no name
continue;
}
if(names.contains(feature.getName())) {
error(String.format("Duplicate feature %s in type", feature.getName()), feature,
OSBPTypesPackage.Literals.LFEATURE__NAME, ValidationMessageAcceptor.INSIGNIFICANT_INDEX,
CODE__DUPLICATE_FEATURE_NAME, (String[]) null);
}
names.add(feature.getName());
}
}
/**
* Returns a map with the container (class path entry) as key and a
* collection with the found types.
*
* @param lType
* the l type
* @return the all for
*/
public Map<IContainer, List<LType>> getAllFor(LType lType) {
Map<IContainer, List<LType>> allEntities = new HashMap<IContainer, List<LType>>();
IResourceDescriptions resourceDescriptions = resourceDescriptionsProvider
.getResourceDescriptions(lType.eResource());
IResourceDescription resourceDescription = resourceDescriptions
.getResourceDescription(lType.eResource().getURI());
List<IContainer> visiblecontainers = containermanager.getVisibleContainers(resourceDescription,
resourceDescriptions);
for (IContainer container : visiblecontainers) {
List<LType> types = new ArrayList<LType>();
allEntities.put(container, types);
if (lType.getName() == null) {
continue;
}
for (IEObjectDescription eobjectDescription : container.getExportedObjects(OSBPTypesPackage.Literals.LTYPE,
qnp.getFullyQualifiedName(lType), false)) {
types.add((LType) eobjectDescription.getEObjectOrProxy());
}
}
return allEntities;
}
/**
* Check duplicate package_ in project.
*
* @param lPackage
* the l package
*/
public void checkDuplicatePackage_InProject(LPackage lPackage) {
Map<IContainer, List<LPackage>> packages = getAllFor(lPackage);
for (Map.Entry<IContainer, List<LPackage>> temp : packages.entrySet())
if (temp.getValue().size() > 1) {
warning(String.format("Duplicate package %s in container ",
qnp.getFullyQualifiedName(lPackage).toString()), lPackage,
OSBPTypesPackage.Literals.LPACKAGE__NAME, CODE__DUPLICATE_LPACKAGE_IN_PROJECT, (String[]) null);
}
}
/**
* Returns a map with the container (class path entry) as key and a
* collection with the found packages.
*
* @param lPackage
* the l package
* @return the all for
*/
public Map<IContainer, List<LPackage>> getAllFor(LPackage lPackage) {
Map<IContainer, List<LPackage>> allEntities = new HashMap<IContainer, List<LPackage>>();
IResourceDescriptions resourceDescriptions = resourceDescriptionsProvider
.getResourceDescriptions(lPackage.eResource());
IResourceDescription resourceDescription = resourceDescriptions
.getResourceDescription(lPackage.eResource().getURI());
List<IContainer> visiblecontainers = containermanager.getVisibleContainers(resourceDescription,
resourceDescriptions);
for (IContainer container : visiblecontainers) {
List<LPackage> packages = new ArrayList<LPackage>();
allEntities.put(container, packages);
for (IEObjectDescription eobjectDescription : container.getExportedObjects(
OSBPTypesPackage.Literals.LPACKAGE, qnp.getFullyQualifiedName(lPackage), false)) {
packages.add((LPackage) eobjectDescription.getEObjectOrProxy());
}
}
return allEntities;
}
/**
* Check duplicate datatype in package.
*
* @param pkg
* the pkg
*/
public void checkDuplicateDatatypeInPackage(LTypedPackage pkg) {
Set<String> names = new HashSet<String>();
int counter = 0;
for (LType type : pkg.getTypes()) {
if (type instanceof LDataType) {
String name = ((LDataType) type).getName();
if (!names.add(name)) {
error(String.format("Datatype %s must be unique in package %s!", name, pkg.getName()),
OSBPTypesPackage.Literals.LTYPED_PACKAGE__TYPES, counter,
CODE__DUPLICATE_LDATATYPE_IN_PACKAGE, (String[]) null);
break;
}
}
counter++;
}
}
/**
* Check feature has name.
*
* @param feature
* the feature
*/
@Check(CheckType.FAST)
public void checkFeatureHasName(LFeature feature) {
if (feature.eContainingFeature() != OSBPTypesPackage.Literals.LFEATURE__ANNOTATION_INFO) {
if (feature.getName() == null || feature.getName().trim().equals("")) {
error("Feature needs a name!", feature, OSBPTypesPackage.Literals.LFEATURE__NAME, "", (String[]) null);
}
}
}
/**
* Check feature is lowercase.
*
* @param feature
* the feature
*/
@Check(CheckType.FAST)
public void checkFeatureIsLowercase(LFeature feature) {
if (feature instanceof LAttribute) {
LAttribute att = (LAttribute) feature;
if (att.getName() != null && !att.getName().trim().equals("")) {
char character = att.getName().charAt(0);
if (Character.isUpperCase(character)) {
warning("Attribute should start with lower case! Strange behaviour might occur...", feature,
OSBPTypesPackage.Literals.LFEATURE__NAME, CODE__FEATURE_LOWERCASE, (String[]) null);
}
}
} else if (feature instanceof LReference) {
LReference ref = (LReference) feature;
if (ref.getName() != null && !ref.getName().trim().equals("")) {
char character = ref.getName().charAt(0);
if (Character.isUpperCase(character)) {
warning("Reference should start with lower case! Strange behaviour might occur...", feature,
OSBPTypesPackage.Literals.LFEATURE__NAME, CODE__FEATURE_LOWERCASE, (String[]) null);
}
}
}
}
}