/**
* Copyright (c) 2011 committers of YAKINDU and others.
* 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:
* committers of YAKINDU - initial API and implementation
*/
package org.yakindu.sct.generator.genmodel.validation;
import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.transform;
import java.util.List;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.validation.Check;
import org.yakindu.base.base.NamedElement;
import org.yakindu.sct.generator.core.extensions.GeneratorExtensions;
import org.yakindu.sct.generator.core.extensions.IGeneratorDescriptor;
import org.yakindu.sct.generator.core.extensions.ILibraryDescriptor;
import org.yakindu.sct.generator.core.extensions.LibraryExtensions;
import org.yakindu.sct.generator.core.library.IDefaultFeatureValueProvider;
import org.yakindu.sct.model.sgen.BoolLiteral;
import org.yakindu.sct.model.sgen.DeprecatableElement;
import org.yakindu.sct.model.sgen.FeatureConfiguration;
import org.yakindu.sct.model.sgen.FeatureParameter;
import org.yakindu.sct.model.sgen.FeatureParameterValue;
import org.yakindu.sct.model.sgen.FeatureType;
import org.yakindu.sct.model.sgen.FeatureTypeLibrary;
import org.yakindu.sct.model.sgen.GeneratorEntry;
import org.yakindu.sct.model.sgen.GeneratorModel;
import org.yakindu.sct.model.sgen.IntLiteral;
import org.yakindu.sct.model.sgen.Literal;
import org.yakindu.sct.model.sgen.ParameterTypes;
import org.yakindu.sct.model.sgen.RealLiteral;
import org.yakindu.sct.model.sgen.SGenPackage;
import org.yakindu.sct.model.sgen.StringLiteral;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Injector;
/**
*
* @author andreas muelder - Initial contribution and API
*
*/
public class SGenJavaValidator extends AbstractSGenJavaValidator {
// Error messages
public static final String MISSING_REQUIRED_PARAMETER = "Missing required Parameter";
public static final String MISSING_REQUIRED_FEATURE = "Missing required feature";
public static final String DUPLICATE_PARAMETER = "Duplicate parameter!";
public static final String DUPLICATE_FEATURE = "Duplicate feature!";
public static final String UNKOWN_GENERATOR = "Unkown Generator";
public static final String INCOMPATIBLE_TYPE_BOOLEAN_EXPECTED = "Incompatible type, Boolean expected";
public static final String INCOMPATIBLE_TYPE_INTEGER_EXPECTED = "Incompatible type, Integer expected";
public static final String INCOMPATIBLE_TYPE_FLOAT_EXPECTED = "Incompatible type, Float expected";
public static final String INCOMPATIBLE_TYPE_STRING_EXPECTED = "Incompatible type, String expected";
public static final String UNKNOWN_CONTENT_TYPE = "Unknown content type '";
public static final String DEPRECATED = "Element is depricated";
// Failure codes
public static final String CODE_REQUIRED_FEATURE = "code_req_feature";
@Inject
private Injector injector;
@Check
public void checkContentType(GeneratorEntry entry) {
GeneratorModel generatorModel = EcoreUtil2.getContainerOfType(entry, GeneratorModel.class);
IGeneratorDescriptor descriptor = GeneratorExtensions.getGeneratorDescriptor(generatorModel.getGeneratorId());
if (descriptor == null)
return;
String contentType = entry.getContentType();
if (contentType == null || contentType.trim().length() == 0) {
return;
}
if (!contentType.equals(descriptor.getContentType())) {
error(UNKNOWN_CONTENT_TYPE + contentType + "'", SGenPackage.Literals.GENERATOR_ENTRY__CONTENT_TYPE);
}
}
@Check
public void checkParameterValueType(final FeatureParameterValue parameterValue) {
if (parameterValue == null || parameterValue.getExpression() == null)
return;
Literal value = parameterValue.getExpression();
ParameterTypes parameterType = parameterValue.getParameter().getParameterType();
switch (parameterType) {
case BOOLEAN:
if (!(value instanceof BoolLiteral))
error(INCOMPATIBLE_TYPE_BOOLEAN_EXPECTED, SGenPackage.Literals.FEATURE_PARAMETER_VALUE__EXPRESSION);
break;
case INTEGER:
if (!(value instanceof IntLiteral))
error(INCOMPATIBLE_TYPE_INTEGER_EXPECTED, SGenPackage.Literals.FEATURE_PARAMETER_VALUE__EXPRESSION);
break;
case FLOAT:
if (!(value instanceof RealLiteral))
error(INCOMPATIBLE_TYPE_FLOAT_EXPECTED, SGenPackage.Literals.FEATURE_PARAMETER_VALUE__EXPRESSION);
break;
case STRING:
if (!(value instanceof StringLiteral))
error(INCOMPATIBLE_TYPE_STRING_EXPECTED, SGenPackage.Literals.FEATURE_PARAMETER_VALUE__EXPRESSION);
break;
}
}
@Check
public void checkParameterValue(final FeatureParameterValue value) {
if (value.getExpression() == null || value.getExpression() == null)
return;
GeneratorModel model = (GeneratorModel) EcoreUtil2.getRootContainer(value);
IGeneratorDescriptor generatorDescriptor = GeneratorExtensions.getGeneratorDescriptor(model.getGeneratorId());
IDefaultFeatureValueProvider provider = LibraryExtensions.getDefaultFeatureValueProvider(
generatorDescriptor.getLibraryIDs(), value.getParameter().getFeatureType().getLibrary());
injector.injectMembers(provider);
IStatus status = provider.validateParameterValue(value);
createMarker(status);
}
private void createMarker(IStatus status) {
switch (status.getSeverity()) {
case IStatus.ERROR:
super.error(status.getMessage(), SGenPackage.Literals.FEATURE_PARAMETER_VALUE__EXPRESSION);
break;
case IStatus.WARNING:
super.warning(status.getMessage(), SGenPackage.Literals.FEATURE_PARAMETER_VALUE__EXPRESSION);
}
}
@Check
public void checkGeneratorExists(GeneratorModel model) {
IGeneratorDescriptor descriptor = GeneratorExtensions.getGeneratorDescriptor(model.getGeneratorId());
if (descriptor == null) {
error(String.format(UNKOWN_GENERATOR + " %s!", model.getGeneratorId()),
SGenPackage.Literals.GENERATOR_MODEL__GENERATOR_ID);
}
}
@Check
public void checkDuplicateGeneratorEntryFeature(final FeatureConfiguration config) {
GeneratorEntry entry = (GeneratorEntry) config.eContainer();
Iterable<FeatureConfiguration> filter = Iterables.filter(entry.getFeatures(),
new Predicate<FeatureConfiguration>() {
public boolean apply(FeatureConfiguration input) {
return (input.getType().getName().equals(config.getType().getName()));
}
});
if (Iterables.size(filter) > 1) {
error(DUPLICATE_FEATURE, SGenPackage.Literals.FEATURE_CONFIGURATION__TYPE);
}
}
@Check
public void checkDuplicateFeatureParameter(final FeatureParameterValue value) {
FeatureConfiguration entry = (FeatureConfiguration) value.eContainer();
Iterable<FeatureParameterValue> filter = Iterables.filter(entry.getParameterValues(),
new Predicate<FeatureParameterValue>() {
public boolean apply(FeatureParameterValue input) {
return (input.getParameter().getName().equals(value.getParameter().getName()));
}
});
if (Iterables.size(filter) > 1) {
error(DUPLICATE_PARAMETER, SGenPackage.Literals.FEATURE_PARAMETER_VALUE__PARAMETER);
}
}
@Check
public void checkRequiredFeatures(GeneratorEntry entry) {
GeneratorModel model = (GeneratorModel) EcoreUtil2.getRootContainer(entry);
IGeneratorDescriptor generatorDescriptor = GeneratorExtensions.getGeneratorDescriptor(model.getGeneratorId());
Iterable<ILibraryDescriptor> libraryDescriptors = LibraryExtensions
.getLibraryDescriptors(generatorDescriptor.getLibraryIDs());
Iterable<FeatureType> requiredFeatures = filter(
concat(transform(transform(libraryDescriptors, getFeatureTypeLibrary()), getFeatureTypes())),
isRequired());
List<String> configuredTypes = Lists.newArrayList();
for (FeatureConfiguration featureConfiguration : entry.getFeatures()) {
configuredTypes.add(featureConfiguration.getType().getName());
}
for (FeatureType featureType : requiredFeatures) {
if (!configuredTypes.contains(featureType.getName()))
error(String.format(MISSING_REQUIRED_FEATURE + " %s", featureType.getName()),
SGenPackage.Literals.GENERATOR_ENTRY__ELEMENT_REF, CODE_REQUIRED_FEATURE,
featureType.getName());
}
}
@Check
public void checkDeprecatedFeatures(GeneratorEntry entry) {
Iterable<FeatureConfiguration> features = entry.getFeatures();
Iterable<FeatureType> deprecatedFeatures = filter(transform(features, getFeatureType()), isDeprecated());
for (FeatureType feature : deprecatedFeatures) {
warning(String.format(DEPRECATED + " %s : %s", feature.getName(), feature.getComment()),
SGenPackage.Literals.GENERATOR_ENTRY__ELEMENT_REF, feature.getName());
}
}
@Check
public void checkRequiredParameters(FeatureConfiguration configuration) {
GeneratorModel model = (GeneratorModel) EcoreUtil2.getRootContainer(configuration);
IGeneratorDescriptor generatorDescriptor = GeneratorExtensions.getGeneratorDescriptor(model.getGeneratorId());
Iterable<ILibraryDescriptor> libraryDescriptors = LibraryExtensions
.getLibraryDescriptors(generatorDescriptor.getLibraryIDs());
Iterable<String> requiredParameters = transform(
filter(concat(
transform(
filter(concat(transform(transform(libraryDescriptors, getFeatureTypeLibrary()),
getFeatureTypes())), hasName(configuration.getType().getName())),
getParmeter())),
isRequiredParamter()),
getName());
List<String> configuredParameters = Lists.newArrayList();
for (FeatureParameterValue featureParameterValue : configuration.getParameterValues()) {
configuredParameters.add(featureParameterValue.getParameter().getName());
}
for (String string : requiredParameters) {
if (!configuredParameters.contains(string))
error(String.format(MISSING_REQUIRED_PARAMETER + " %s", string),
SGenPackage.Literals.FEATURE_CONFIGURATION__TYPE);
}
}
@Check
public void checkDeprecatedParameters(GeneratorEntry entry) {
Iterable<FeatureParameter> deprecatedParameters = filter(
concat(transform(transform(entry.getFeatures(), getFeatureType()), getParmeter())), isDeprecated());
for (FeatureParameter parameter : deprecatedParameters) {
warning(String.format(DEPRECATED + " %s : %s", parameter.getName(), parameter.getComment()),
SGenPackage.Literals.GENERATOR_ENTRY__ELEMENT_REF, parameter.getName());
}
}
private Function<NamedElement, String> getName() {
return new Function<NamedElement, String>() {
public String apply(NamedElement from) {
return from.getName();
}
};
}
private Predicate<FeatureParameter> isRequiredParamter() {
return new Predicate<FeatureParameter>() {
public boolean apply(FeatureParameter input) {
return !input.isOptional();
}
};
}
private Predicate<DeprecatableElement> isDeprecated() {
return new Predicate<DeprecatableElement>() {
public boolean apply(DeprecatableElement input) {
return input.isDeprecated();
}
};
}
private Function<FeatureType, Iterable<FeatureParameter>> getParmeter() {
return new Function<FeatureType, Iterable<FeatureParameter>>() {
public Iterable<FeatureParameter> apply(FeatureType from) {
return from.getParameters();
}
};
}
private Predicate<NamedElement> hasName(final String name) {
return new Predicate<NamedElement>() {
public boolean apply(NamedElement input) {
if (name == null) {
return (input == null);
}
return name.equals(input.getName());
}
};
}
private static Predicate<FeatureType> isRequired() {
return new Predicate<FeatureType>() {
public boolean apply(FeatureType input) {
return !input.isOptional();
}
};
}
private static Function<FeatureTypeLibrary, Iterable<FeatureType>> getFeatureTypes() {
return new Function<FeatureTypeLibrary, Iterable<FeatureType>>() {
public Iterable<FeatureType> apply(FeatureTypeLibrary from) {
return from.getTypes();
}
};
}
private static Function<ILibraryDescriptor, FeatureTypeLibrary> getFeatureTypeLibrary() {
return new Function<ILibraryDescriptor, FeatureTypeLibrary>() {
public FeatureTypeLibrary apply(ILibraryDescriptor from) {
return (FeatureTypeLibrary) new ResourceSetImpl().getResource(from.getURI(), true).getContents().get(0);
}
};
}
private static Function<FeatureConfiguration, FeatureType> getFeatureType() {
return new Function<FeatureConfiguration, FeatureType>() {
public FeatureType apply(FeatureConfiguration input) {
return input.getType();
}
};
}
}