CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-openapitools--openapi-generator

OpenAPI Generator allows generation of API client libraries (SDK generation), server stubs, documentation and configuration automatically given an OpenAPI Spec

Pending
Overview
Eval results
Files

validation.mddocs/

Validation Framework

The validation framework provides JSON Schema validation properties and type checking utilities for ensuring proper data handling and constraint validation throughout the code generation process.

Core Validation Interface

IJsonSchemaValidationProperties

Defines JSON Schema validation properties implemented by models, properties, parameters, and responses.

interface IJsonSchemaValidationProperties {
    // Type identification methods
    boolean getIsModel();             // Is a custom model/object type
    boolean getIsArray();             // Is an array/list type
    boolean getIsMap();               // Is a map/dictionary type
    boolean getIsString();            // Is a string type
    boolean getIsNumber();            // Is any numeric type
    boolean getIsInteger();           // Is an integer type
    boolean getIsBoolean();           // Is a boolean type
    boolean getIsDate();              // Is a date type
    boolean getIsDateTime();          // Is a date-time type
    boolean getIsPrimitiveType();     // Is a primitive type (string, number, boolean)
    boolean getIsEnum();              // Is an enumeration type
    
    // Validation constraint methods
    String getPattern();              // Regular expression pattern
    String getMinimum();              // Minimum value for numbers
    String getMaximum();              // Maximum value for numbers
    boolean getExclusiveMinimum();    // Exclusive minimum flag
    boolean getExclusiveMaximum();    // Exclusive maximum flag
    Integer getMinLength();           // Minimum string length
    Integer getMaxLength();           // Maximum string length
    Integer getMinItems();            // Minimum array items
    Integer getMaxItems();            // Maximum array items
    boolean getUniqueItems();         // Array items must be unique
    Integer getMinProperties();       // Minimum object properties
    Integer getMaxProperties();       // Maximum object properties
    Number getMultipleOf();           // Number must be multiple of this value
    
    // Schema relationship methods
    CodegenProperty getItems();                    // For arrays - item type
    CodegenProperty getAdditionalProperties();     // For objects - additional props type
    List<CodegenProperty> getVars();               // Object properties
    List<CodegenProperty> getRequiredVars();       // Required object properties
    CodegenComposedSchemas getComposedSchemas();   // oneOf/anyOf/allOf schemas
    
    // Type processing methods
    void setTypeProperties(Schema p, OpenAPI openAPI);  // Set type properties from schema
    String getBaseType();                                // Get base type name
    String getComplexType();                            // Get full type with generics
    Set<String> getImports(boolean importContainerType, boolean importBaseType, FeatureSet featureSet);
}

Model Type Checking

Schema Type Utilities

Static utilities for checking OpenAPI schema types.

class ModelUtils {
    // Schema type checking
    public static boolean isObjectSchema(Schema schema);
    public static boolean isComposedSchema(Schema schema);    // oneOf/anyOf/allOf
    public static boolean isMapSchema(Schema schema);
    public static boolean isArraySchema(Schema schema);
    public static boolean isStringSchema(Schema schema);
    public static boolean isIntegerSchema(Schema schema);
    public static boolean isNumberSchema(Schema schema);
    public static boolean isBooleanSchema(Schema schema);
    public static boolean isNullType(Schema schema);
    public static boolean isAnyType(Schema schema);
    
    // Format-specific type checking
    public static boolean isDateSchema(Schema schema);        // date format
    public static boolean isDateTimeSchema(Schema schema);    // date-time format
    public static boolean isByteArraySchema(Schema schema);   // byte format
    public static boolean isBinarySchema(Schema schema);      // binary format
    public static boolean isFileSchema(Schema schema);        // file type
    public static boolean isUUIDSchema(Schema schema);        // uuid format
    public static boolean isEmailSchema(Schema schema);       // email format
    public static boolean isPasswordSchema(Schema schema);    // password format
    
    // Schema analysis
    public static List<String> getAllUsedSchemas(OpenAPI openAPI);    // Find all referenced schemas
    public static List<String> getUnusedSchemas(OpenAPI openAPI);     // Find unused schemas
    public static String getSimpleRef(String ref);                    // Extract name from $ref
    public static Schema unaliasSchema(Schema schema, OpenAPI openAPI); // Resolve schema aliases
    
    // Model utilities
    public static CodegenModel getModelByName(final String name, final Map<String, ModelsMap> models);
    public static boolean isGenerateAliasAsModel();
    public static void setGenerateAliasAsModel(boolean value);
}

Exception Handling

SpecValidationException

Exception thrown when OpenAPI specification validation fails.

class SpecValidationException extends RuntimeException {
    // Constructors
    public SpecValidationException();
    public SpecValidationException(String message);
    public SpecValidationException(String message, Throwable cause);
    public SpecValidationException(Throwable cause);
    
    // Error and warning handling
    public Set<String> getErrors();           // Get validation errors
    public void setErrors(Set<String> errors);
    public Set<String> getWarnings();         // Get validation warnings
    public void setWarnings(Set<String> warnings);
    
    // Overridden methods
    public String getMessage();               // Get formatted error message
}

GeneratorNotFoundException

Exception thrown when a specified generator cannot be found.

class GeneratorNotFoundException extends RuntimeException {
    // Inherits standard RuntimeException constructors
}

Usage Examples

Custom Validation in Generators

public class ValidatingGenerator extends DefaultCodegen {
    
    @Override
    public CodegenModel fromModel(String name, Schema schema) {
        CodegenModel model = super.fromModel(name, schema);
        
        // Validate model properties
        validateModelProperties(model);
        
        return model;
    }
    
    private void validateModelProperties(CodegenModel model) {
        for (CodegenProperty property : model.vars) {
            validateProperty(property);
        }
    }
    
    private void validateProperty(CodegenProperty property) {
        // Check string length constraints
        if (property.getIsString()) {
            if (property.getMinLength() != null && property.getMaxLength() != null) {
                if (property.getMinLength() > property.getMaxLength()) {
                    throw new SpecValidationException(
                        "Property " + property.name + " has minLength > maxLength");
                }
            }
        }
        
        // Check numeric constraints
        if (property.getIsNumber()) {
            if (property.getMinimum() != null && property.getMaximum() != null) {
                try {
                    double min = Double.parseDouble(property.getMinimum());
                    double max = Double.parseDouble(property.getMaximum());
                    if (min > max) {
                        throw new SpecValidationException(
                            "Property " + property.name + " has minimum > maximum");
                    }
                } catch (NumberFormatException e) {
                    throw new SpecValidationException(
                        "Invalid numeric constraint for property " + property.name, e);
                }
            }
        }
        
        // Check array constraints
        if (property.getIsArray()) {
            if (property.getMinItems() != null && property.getMaxItems() != null) {
                if (property.getMinItems() > property.getMaxItems()) {
                    throw new SpecValidationException(
                        "Property " + property.name + " has minItems > maxItems");
                }
            }
        }
    }
}

Type-Specific Processing

public class TypeAwareGenerator extends DefaultCodegen {
    
    @Override
    public CodegenProperty fromProperty(String name, Schema propertySchema) {
        CodegenProperty property = super.fromProperty(name, propertySchema);
        
        // Add type-specific processing
        if (property.getIsString()) {
            processStringProperty(property);
        } else if (property.getIsNumber()) {
            processNumericProperty(property);
        } else if (property.getIsArray()) {
            processArrayProperty(property);
        } else if (property.getIsMap()) {
            processMapProperty(property);
        } else if (property.getIsModel()) {
            processModelProperty(property);
        }
        
        return property;
    }
    
    private void processStringProperty(CodegenProperty property) {
        // Add string-specific validation and formatting
        if (property.getPattern() != null) {
            property.vendorExtensions.put("x-pattern-validation", true);
        }
        
        if (property.getMinLength() != null || property.getMaxLength() != null) {
            property.vendorExtensions.put("x-length-validation", true);
        }
        
        // Check for specific formats
        if ("email".equals(property.dataFormat)) {
            property.vendorExtensions.put("x-email-validation", true);
        } else if ("uuid".equals(property.dataFormat)) {
            property.vendorExtensions.put("x-uuid-format", true);
        }
    }
    
    private void processNumericProperty(CodegenProperty property) {
        // Add numeric validation
        if (property.getMinimum() != null || property.getMaximum() != null) {
            property.vendorExtensions.put("x-range-validation", true);
        }
        
        if (property.getMultipleOf() != null) {
            property.vendorExtensions.put("x-multiple-validation", true);
        }
        
        // Check for exclusive bounds
        if (property.getExclusiveMinimum() || property.getExclusiveMaximum()) {
            property.vendorExtensions.put("x-exclusive-bounds", true);
        }
    }
    
    private void processArrayProperty(CodegenProperty property) {
        // Process array constraints
        if (property.getMinItems() != null || property.getMaxItems() != null) {
            property.vendorExtensions.put("x-array-size-validation", true);
        }
        
        if (property.getUniqueItems()) {
            property.vendorExtensions.put("x-unique-items", true);
        }
        
        // Process array item type
        if (property.getItems() != null) {
            CodegenProperty items = property.getItems();
            property.vendorExtensions.put("x-item-type", items.dataType);
        }
    }
}

Schema Analysis

public class SchemaAnalyzer {
    
    public void analyzeOpenAPISpec(OpenAPI openAPI) {
        // Find all used schemas
        List<String> usedSchemas = ModelUtils.getAllUsedSchemas(openAPI);
        System.out.println("Used schemas: " + usedSchemas);
        
        // Find unused schemas
        List<String> unusedSchemas = ModelUtils.getUnusedSchemas(openAPI);
        if (!unusedSchemas.isEmpty()) {
            System.out.println("Warning: Unused schemas found: " + unusedSchemas);
        }
        
        // Analyze schemas by type
        Map<String, Schema> schemas = openAPI.getComponents().getSchemas();
        for (Map.Entry<String, Schema> entry : schemas.entrySet()) {
            String name = entry.getKey();
            Schema schema = entry.getValue();
            
            analyzeSchema(name, schema);
        }
    }
    
    private void analyzeSchema(String name, Schema schema) {
        System.out.println("Analyzing schema: " + name);
        
        if (ModelUtils.isObjectSchema(schema)) {
            System.out.println("  Type: Object");
            analyzeObjectSchema(schema);
        } else if (ModelUtils.isArraySchema(schema)) {
            System.out.println("  Type: Array");
            analyzeArraySchema(schema);
        } else if (ModelUtils.isStringSchema(schema)) {
            System.out.println("  Type: String");
            analyzeStringSchema(schema);
        } else if (ModelUtils.isNumberSchema(schema)) {
            System.out.println("  Type: Number");
            analyzeNumericSchema(schema);
        } else if (ModelUtils.isComposedSchema(schema)) {
            System.out.println("  Type: Composed (oneOf/anyOf/allOf)");
            analyzeComposedSchema(schema);
        }
    }
    
    private void analyzeObjectSchema(Schema schema) {
        Map<String, Schema> properties = schema.getProperties();
        if (properties != null) {
            System.out.println("    Properties: " + properties.keySet());
        }
        
        List<String> required = schema.getRequired();
        if (required != null && !required.isEmpty()) {
            System.out.println("    Required: " + required);
        }
    }
    
    private void analyzeStringSchema(Schema schema) {
        if (schema.getFormat() != null) {
            System.out.println("    Format: " + schema.getFormat());
        }
        if (schema.getPattern() != null) {
            System.out.println("    Pattern: " + schema.getPattern());
        }
        if (schema.getMinLength() != null) {
            System.out.println("    MinLength: " + schema.getMinLength());
        }
        if (schema.getMaxLength() != null) {
            System.out.println("    MaxLength: " + schema.getMaxLength());
        }
    }
}

Exception Handling

public class SafeGenerator extends DefaultGenerator {
    
    @Override
    public List<File> generate() {
        try {
            return super.generate();
        } catch (SpecValidationException e) {
            System.err.println("Specification validation failed:");
            
            // Print validation errors
            if (e.getErrors() != null && !e.getErrors().isEmpty()) {
                System.err.println("Errors:");
                for (String error : e.getErrors()) {
                    System.err.println("  - " + error);
                }
            }
            
            // Print validation warnings
            if (e.getWarnings() != null && !e.getWarnings().isEmpty()) {
                System.err.println("Warnings:");
                for (String warning : e.getWarnings()) {
                    System.err.println("  - " + warning);
                }
            }
            
            throw e; // Re-throw to stop generation
        } catch (GeneratorNotFoundException e) {
            System.err.println("Generator not found: " + e.getMessage());
            System.err.println("Available generators: " + getAvailableGenerators());
            throw e;
        }
    }
    
    private List<String> getAvailableGenerators() {
        // Return list of available generator names
        return Arrays.asList("java", "python", "javascript", "typescript", "go", "ruby");
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-openapitools--openapi-generator

docs

configuration.md

core-generation.md

index.md

model-system.md

utilities.md

validation.md

tile.json