blob: 5d8ee7816ad120feac27e906a025d73b4d0dd66b [file] [log] [blame]
/**
* Copyright (c) 2018 CEA.
* 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:
* CEA - initial API and implementation and/or initial documentation
*/
/*
* generated by Xtext 2.9.1
*/
package org.eclipse.sensinact.studio.language.validation
import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_AFTER
import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_BEFORE
import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_DURATION
import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_DURATION_MIN
import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_DURATION_SEC
import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_STATEMENT
import org.eclipse.sensinact.studio.language.sensinact.DSL_ListParam
import org.eclipse.sensinact.studio.language.sensinact.DSL_REF
import org.eclipse.sensinact.studio.language.sensinact.DSL_Resource
import org.eclipse.sensinact.studio.language.sensinact.DSL_ResourceAction
import org.eclipse.sensinact.studio.language.sensinact.DSL_SENSINACT
import org.eclipse.sensinact.studio.language.sensinact.SensinactPackage
import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor
import org.eclipse.sensinact.studio.resource.AccessMethodType
import java.math.BigDecimal
import org.eclipse.emf.ecore.EStructuralFeature
import org.eclipse.xtext.validation.Check
import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor
import org.eclipse.sensinact.studio.language.sensinact.impl.DSL_REFImpl
/**
* This class contains custom validation rules.
*
* See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation
*/
class SensinactValidator extends AbstractSensinactValidator {
def isConnected() {
return ModelEditor.getInstance().getGatewaysId.length != 0;
}
@Check
def checkGatewayIsConnected(DSL_SENSINACT eca) {
if (!isConnected())
warning("Please connect the studio to your gateway", SensinactPackage.Literals.DSL_SENSINACT__RESOURCES);
}
@Check
def void refNameIsUnique(DSL_REF ref) {
var nameOccurences = 0;
var name = ref.getName();
var superEntity = (ref.eContainer() as DSL_SENSINACT);
if (superEntity !== null) {
for (other : superEntity.resources) {
if (name.equals(other.getName())) {
nameOccurences++;
}
}
for (other : superEntity.cep) {
if (name.equals(other.getName())) {
nameOccurences++;
}
}
if (nameOccurences > 1) {
error("Reference names names have to be unique", SensinactPackage.Literals.DSL_REF__NAME, ref.getName());
}
}
}
@Check
def checkResourceExists(DSL_Resource dslResource) {
if (isConnected()) {
var gatewayID = dslResource.gatewayID;
var deviceID = dslResource.deviceID;
var serviceID = dslResource.serviceID;
var resourceID = dslResource.resourceID;
if (! ModelEditor.getInstance().existsGateway(gatewayID)) {
warning("The gateway " + gatewayID + " does not exist",
SensinactPackage.Literals.DSL_RESOURCE__GATEWAY_ID, 'INVALID_NAME');
} else if (! ModelEditor.getInstance().existsDevice(gatewayID, deviceID)) {
warning("The device " + deviceID + " does not exist in gateway " + gatewayID,
SensinactPackage.Literals.DSL_RESOURCE__DEVICE_ID, 'INVALID_NAME');
} else if (! ModelEditor.getInstance().existsService(gatewayID, deviceID, serviceID)) {
warning("The service " + serviceID + " does not exist in gateway " + gatewayID,
SensinactPackage.Literals.DSL_RESOURCE__SERVICE_ID, 'INVALID_NAME');
} else if (! ModelEditor.getInstance().existsResource(gatewayID, deviceID, serviceID, resourceID)) {
warning("The resource " + resourceID + " does not exist in gateway " + gatewayID,
SensinactPackage.Literals.DSL_RESOURCE__RESOURCE_ID, 'INVALID_NAME');
}
}
}
@Check
def checkActionAccessMethod(DSL_ResourceAction resourceAction) {
if (isConnected()) {
var ref = resourceAction.ref;
var AccessMethodType actionType = AccessMethodType.getByName(resourceAction.actiontype);
var nbParams = getNbParams(resourceAction.listParam);
checkParameters(ref, actionType, nbParams, SensinactPackage.Literals.DSL_RESOURCE_ACTION__ACTIONTYPE);
}
}
def getNbParams(DSL_ListParam params) {
if (params === null)
return 0;
if (params.param === null)
return 0;
return params.param.size;
}
def checkParameters(DSL_REF ref, AccessMethodType actionType, int nbParams, EStructuralFeature feature) {
if (ref instanceof DSL_Resource) {
var dslResource = ref as DSL_Resource;
var gatewayID = dslResource.gatewayID;
var deviceID = dslResource.deviceID;
var serviceID = dslResource.serviceID;
var resourceID = dslResource.resourceID;
var descriptor = new ResourceDescriptor(gatewayID, deviceID, serviceID, resourceID);
// finding method
if (descriptor !== null && actionType !== null) {
var method = ModelEditor.getInstance().getAccessMethodWithTypeNbParams(descriptor, actionType, nbParams);
if (method === null) {
var String msg = null;
if (nbParams == 0) {
msg = "This action type without parameters is not available for this resource";
} else if (nbParams == 1) {
msg = "This action type with one parameter is not available for this resource";
} else if (nbParams == 0) {
msg = "This action type with " + nbParams + " parameters is not available for this resource";
}
error(msg, feature);
}
}
} else if (ref instanceof DSL_CEP_STATEMENT) {
// no check
} else if (ref.class.equals(typeof(DSL_REFImpl))) {
// exact same class (no subclassing)
} else {
throw new RuntimeException("Should never happen");
}
}
@Check
def checkCepAfter(DSL_CEP_AFTER operation) {
var start = timestamp(operation.start);
var end = timestamp(operation.end);
if (start.compareTo(end) >= 0) {
var msg = "end must be after start";
error(msg, SensinactPackage.Literals.DSL_CEP_AFTER__END);
}
}
@Check
def checkCepBefore(DSL_CEP_BEFORE operation) {
var start = timestamp(operation.start);
var end = timestamp(operation.end);
if (start.compareTo(end) >= 0) {
var msg = "end must be after start";
error(msg, SensinactPackage.Literals.DSL_CEP_BEFORE__END);
}
}
def timestamp(DSL_CEP_DURATION duration) {
var retval = BigDecimal.ZERO;
if (duration !== null && duration.units !== null) {
for (unit : duration.units) {
if (unit instanceof DSL_CEP_DURATION_MIN) {
var min = unit as DSL_CEP_DURATION_MIN;
retval = retval.add(min.min.multiply(new BigDecimal("60")));
} else if (unit instanceof DSL_CEP_DURATION_SEC) {
var sec = unit as DSL_CEP_DURATION_SEC;
retval = retval.add(sec.sec);
}
}
}
return retval;
}
}