...
...
...
...
|
div |
---|
| Table of Contents |
---|
maxLevel | 2 |
---|
indent | 8px |
---|
style | none |
---|
|
|
|
Introduction: The Listener API
...
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 ids (meaning both the model for which code is generated and all its imports recursively).
Code Block |
---|
language | java |
---|
title | Pseudocode 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());
validateFieldIdsUnique(e.getModel(), e.getErrorAggregator(), new HashSet<Short>(), 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 validateFieldIdsUnique(AdmModel model, AdmSourceCodeErrorAggregator aggregator, Set<Short> 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 ids and the importing model doesn't if it defines the same id as in one of the imports.
for (AdmModelImport modelImport : model.getModelImports()) {
if (!modelsProcessed.contains(modelImport.getModel().getFullName())) {
validateFieldIdsUnique(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.getId())) {
// aggregator collects errors and they will be displayed at the end of code generation.
aggregator.add("Duplicate field id",
AdmSourceCodeErrorAggregator.Severity.ERROR,
field.getCodeSource(), null);
// 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.getId());
}
}
}
}
|
In pom.xml we may use this listener as follows:
Code Block |
---|
language | xml |
---|
title | Sample usage in pom.xml |
---|
|
<plugins>
<!-- Generates X model from XML model file -->
<plugin>
<groupId>com.neeve</groupId>
<artifactId>nvx-core-maven-plugin</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<id>Model</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<!-- The usual configuration params go here ... -->
<!-- The listener class that should be on the build classpath for this project -->
<codegenListenerClassName>mypackage.CodegenListener</codegenListenerClassName>
</configuration>
</execution>
</executions>
</plugin>
</plugins> |