The Talon Manual

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Developers may tap into listener mechanism to perform additional model validations as given in example below. The example demonstrates how to use the listener mechanism to enforce globally unique field names (meaning both the model for which code is generated and all its imports recursively).

Code Block
languagejava
titlePseudocode Demonstrating External Validation
package mypackage;
import java.util.HashSet;
import java.util.Set;
import com.neeve.adm.AdmField;
import com.neeve.adm.AdmModel;
import com.neeve.adm.AdmModelImport;
import com.neeve.adm.AdmSourceCodeErrorAggregator;
import com.neeve.tools.AdmCodeGenerator;
import com.neeve.tools.AdmCodeGenerator.CodeGenerateEvent;
public class CodegenListener implements AdmCodeGenerator.CodegenListener {
    @Override
    public void codeGenerateEvent(CodeGenerateEvent e) {
        switch (e.getEventType()) {
            case START:
                System.err.println("CodegenListener START");
                break;
            case SKIP:
                System.err.println("CodegenListener SKIP");
                break;
            case MODEL_PARSED:
                System.err.println("CodegenListener MODEL_PARSED " + e.getModel().getFullName());
                validateFieldNamesUnique(e.getModel(), e.getErrorAggregator(), new HashSet<String>(), new HashSet<String>());
                // e.getErrorAggregator().add("Test external error", AdmSourceCodeErrorAggregator.Severity.ERROR, e.getModel().getCodeSource());
                break;
            case END:
                System.err.println("CodegenListener END " + e.getModel().getFullName());
                // e.getErrorAggregator().add("Test external error", AdmSourceCodeErrorAggregator.Severity.ERROR, e.getModel().getCodeSource());
                break;
        }
    }
    private void validateFieldNamesUnique(AdmModel model, AdmSourceCodeErrorAggregator aggregator, Set<String> fields, Set<String> modelsProcessed) {
        // iterate imports and run validation for them if not already run. We will run bottom -> top validation so we assume that imported models have correct 
        // field names and the importing model doesn't if it defines the same name as in one of the imports.
        for (AdmModelImport modelImport : model.getModelImports()) {
            if (!modelsProcessed.contains(modelImport.getModel().getFullName())) {
                validateFieldNamesUnique(modelImport.getModel(), aggregator, fields, modelsProcessed);
                modelsProcessed.add(modelImport.getModel().getFullName());
            }
        }
        // now we check fields of current model
        for (AdmField field : model.getFields()) {
            if (fields.contains(field.getName())) {
                // aggregator collects errors and they will be displayed at the end of code generation.
                aggregator.add("Duplicate field name",
                               AdmSourceCodeErrorAggregator.Severity.ERROR,
                               field.getCodeSource());
                // note that classes derived from AdmModelElement 
                // usually have source code (error line) information retrieved through getCodeSource() 
                // pointing back to place in XML where their XML representation is.
            }
            else {
                fields.add(field.getName());
            }
        }
    }
}