Wednesday, 2 November 2016

Multiple Validators for XText DSL

Xtext framework is equipped with robust syntax validators, which is in-built and works with the generated tokens. So for with Business/Semantic validators, xtext provides the mechanism to bind the validator through the RuntimeModule.

The default generated [MyDSL]Validator.java is attached to the framework in Abstract[MyDSL]RuntimeModule.java as shown below.

       // contributed by org.eclipse.xtext.generator.validation.ValidatorFragment
       @org.eclipse.xtext.service.SingletonBinding(eager=true)       public Class<? extends com.odcgroup.model.schema.validation.MyDSLValidator> bindMyDSLValidator() {
              return com.odcgroup.model.schema.validation.MyDSLValidator.class;
       }

However one can override this in MyDSLRuntimeModule.java. The MyDSLValidator.java is generated only once and is empty. All the business validation should be added here like as shown below.

    @Check
    def checkClassHierarchy(Entity e) {
        if (e.entityHierarchy.contains(e)) {
            error("cycle in hierarchy of entity '" + e.name + "'",
                SchemaPackage::eINSTANCE.entity_Parent,
                HIERARCHY_CYCLE,
                e.parent.name)
        }
    }

At times, there might be a need to have multiple validators attached to framework for various reasons like separation of concern, too many methods, etc. As shown above, we can attach only one validator in the RuntimeModule.java. The alternative way to attach multiple validators is through @ComposedChecks annotation. Add the annotation @ComposedChecks on the MyDSLValidator and specify the validators as shown below.

@ComposedChecks(validators = { MyDSLSchemaValidator1.class, MyDSLSchemaValidator2.class})
public class MyDSLSchemaValidator extends AbstractMyDSLValidator {
...
}

Note: The validators should extend  org.eclipse.xtext.validation.AbstractDeclarativeValidator, but i prefer the AbstractMyDSLValidator, as the validator will be aware of what EPackage it will deal with.

No comments:

Post a Comment