or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdcore-generation.mdindex.mdmodel-system.mdutilities.mdvalidation.md

validation.mddocs/

0

# Validation Framework

1

2

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.

3

4

## Core Validation Interface

5

6

### IJsonSchemaValidationProperties

7

8

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

9

10

```java { .api }

11

interface IJsonSchemaValidationProperties {

12

// Type identification methods

13

boolean getIsModel(); // Is a custom model/object type

14

boolean getIsArray(); // Is an array/list type

15

boolean getIsMap(); // Is a map/dictionary type

16

boolean getIsString(); // Is a string type

17

boolean getIsNumber(); // Is any numeric type

18

boolean getIsInteger(); // Is an integer type

19

boolean getIsBoolean(); // Is a boolean type

20

boolean getIsDate(); // Is a date type

21

boolean getIsDateTime(); // Is a date-time type

22

boolean getIsPrimitiveType(); // Is a primitive type (string, number, boolean)

23

boolean getIsEnum(); // Is an enumeration type

24

25

// Validation constraint methods

26

String getPattern(); // Regular expression pattern

27

String getMinimum(); // Minimum value for numbers

28

String getMaximum(); // Maximum value for numbers

29

boolean getExclusiveMinimum(); // Exclusive minimum flag

30

boolean getExclusiveMaximum(); // Exclusive maximum flag

31

Integer getMinLength(); // Minimum string length

32

Integer getMaxLength(); // Maximum string length

33

Integer getMinItems(); // Minimum array items

34

Integer getMaxItems(); // Maximum array items

35

boolean getUniqueItems(); // Array items must be unique

36

Integer getMinProperties(); // Minimum object properties

37

Integer getMaxProperties(); // Maximum object properties

38

Number getMultipleOf(); // Number must be multiple of this value

39

40

// Schema relationship methods

41

CodegenProperty getItems(); // For arrays - item type

42

CodegenProperty getAdditionalProperties(); // For objects - additional props type

43

List<CodegenProperty> getVars(); // Object properties

44

List<CodegenProperty> getRequiredVars(); // Required object properties

45

CodegenComposedSchemas getComposedSchemas(); // oneOf/anyOf/allOf schemas

46

47

// Type processing methods

48

void setTypeProperties(Schema p, OpenAPI openAPI); // Set type properties from schema

49

String getBaseType(); // Get base type name

50

String getComplexType(); // Get full type with generics

51

Set<String> getImports(boolean importContainerType, boolean importBaseType, FeatureSet featureSet);

52

}

53

```

54

55

## Model Type Checking

56

57

### Schema Type Utilities

58

59

Static utilities for checking OpenAPI schema types.

60

61

```java { .api }

62

class ModelUtils {

63

// Schema type checking

64

public static boolean isObjectSchema(Schema schema);

65

public static boolean isComposedSchema(Schema schema); // oneOf/anyOf/allOf

66

public static boolean isMapSchema(Schema schema);

67

public static boolean isArraySchema(Schema schema);

68

public static boolean isStringSchema(Schema schema);

69

public static boolean isIntegerSchema(Schema schema);

70

public static boolean isNumberSchema(Schema schema);

71

public static boolean isBooleanSchema(Schema schema);

72

public static boolean isNullType(Schema schema);

73

public static boolean isAnyType(Schema schema);

74

75

// Format-specific type checking

76

public static boolean isDateSchema(Schema schema); // date format

77

public static boolean isDateTimeSchema(Schema schema); // date-time format

78

public static boolean isByteArraySchema(Schema schema); // byte format

79

public static boolean isBinarySchema(Schema schema); // binary format

80

public static boolean isFileSchema(Schema schema); // file type

81

public static boolean isUUIDSchema(Schema schema); // uuid format

82

public static boolean isEmailSchema(Schema schema); // email format

83

public static boolean isPasswordSchema(Schema schema); // password format

84

85

// Schema analysis

86

public static List<String> getAllUsedSchemas(OpenAPI openAPI); // Find all referenced schemas

87

public static List<String> getUnusedSchemas(OpenAPI openAPI); // Find unused schemas

88

public static String getSimpleRef(String ref); // Extract name from $ref

89

public static Schema unaliasSchema(Schema schema, OpenAPI openAPI); // Resolve schema aliases

90

91

// Model utilities

92

public static CodegenModel getModelByName(final String name, final Map<String, ModelsMap> models);

93

public static boolean isGenerateAliasAsModel();

94

public static void setGenerateAliasAsModel(boolean value);

95

}

96

```

97

98

## Exception Handling

99

100

### SpecValidationException

101

102

Exception thrown when OpenAPI specification validation fails.

103

104

```java { .api }

105

class SpecValidationException extends RuntimeException {

106

// Constructors

107

public SpecValidationException();

108

public SpecValidationException(String message);

109

public SpecValidationException(String message, Throwable cause);

110

public SpecValidationException(Throwable cause);

111

112

// Error and warning handling

113

public Set<String> getErrors(); // Get validation errors

114

public void setErrors(Set<String> errors);

115

public Set<String> getWarnings(); // Get validation warnings

116

public void setWarnings(Set<String> warnings);

117

118

// Overridden methods

119

public String getMessage(); // Get formatted error message

120

}

121

```

122

123

### GeneratorNotFoundException

124

125

Exception thrown when a specified generator cannot be found.

126

127

```java { .api }

128

class GeneratorNotFoundException extends RuntimeException {

129

// Inherits standard RuntimeException constructors

130

}

131

```

132

133

## Usage Examples

134

135

### Custom Validation in Generators

136

137

```java

138

public class ValidatingGenerator extends DefaultCodegen {

139

140

@Override

141

public CodegenModel fromModel(String name, Schema schema) {

142

CodegenModel model = super.fromModel(name, schema);

143

144

// Validate model properties

145

validateModelProperties(model);

146

147

return model;

148

}

149

150

private void validateModelProperties(CodegenModel model) {

151

for (CodegenProperty property : model.vars) {

152

validateProperty(property);

153

}

154

}

155

156

private void validateProperty(CodegenProperty property) {

157

// Check string length constraints

158

if (property.getIsString()) {

159

if (property.getMinLength() != null && property.getMaxLength() != null) {

160

if (property.getMinLength() > property.getMaxLength()) {

161

throw new SpecValidationException(

162

"Property " + property.name + " has minLength > maxLength");

163

}

164

}

165

}

166

167

// Check numeric constraints

168

if (property.getIsNumber()) {

169

if (property.getMinimum() != null && property.getMaximum() != null) {

170

try {

171

double min = Double.parseDouble(property.getMinimum());

172

double max = Double.parseDouble(property.getMaximum());

173

if (min > max) {

174

throw new SpecValidationException(

175

"Property " + property.name + " has minimum > maximum");

176

}

177

} catch (NumberFormatException e) {

178

throw new SpecValidationException(

179

"Invalid numeric constraint for property " + property.name, e);

180

}

181

}

182

}

183

184

// Check array constraints

185

if (property.getIsArray()) {

186

if (property.getMinItems() != null && property.getMaxItems() != null) {

187

if (property.getMinItems() > property.getMaxItems()) {

188

throw new SpecValidationException(

189

"Property " + property.name + " has minItems > maxItems");

190

}

191

}

192

}

193

}

194

}

195

```

196

197

### Type-Specific Processing

198

199

```java

200

public class TypeAwareGenerator extends DefaultCodegen {

201

202

@Override

203

public CodegenProperty fromProperty(String name, Schema propertySchema) {

204

CodegenProperty property = super.fromProperty(name, propertySchema);

205

206

// Add type-specific processing

207

if (property.getIsString()) {

208

processStringProperty(property);

209

} else if (property.getIsNumber()) {

210

processNumericProperty(property);

211

} else if (property.getIsArray()) {

212

processArrayProperty(property);

213

} else if (property.getIsMap()) {

214

processMapProperty(property);

215

} else if (property.getIsModel()) {

216

processModelProperty(property);

217

}

218

219

return property;

220

}

221

222

private void processStringProperty(CodegenProperty property) {

223

// Add string-specific validation and formatting

224

if (property.getPattern() != null) {

225

property.vendorExtensions.put("x-pattern-validation", true);

226

}

227

228

if (property.getMinLength() != null || property.getMaxLength() != null) {

229

property.vendorExtensions.put("x-length-validation", true);

230

}

231

232

// Check for specific formats

233

if ("email".equals(property.dataFormat)) {

234

property.vendorExtensions.put("x-email-validation", true);

235

} else if ("uuid".equals(property.dataFormat)) {

236

property.vendorExtensions.put("x-uuid-format", true);

237

}

238

}

239

240

private void processNumericProperty(CodegenProperty property) {

241

// Add numeric validation

242

if (property.getMinimum() != null || property.getMaximum() != null) {

243

property.vendorExtensions.put("x-range-validation", true);

244

}

245

246

if (property.getMultipleOf() != null) {

247

property.vendorExtensions.put("x-multiple-validation", true);

248

}

249

250

// Check for exclusive bounds

251

if (property.getExclusiveMinimum() || property.getExclusiveMaximum()) {

252

property.vendorExtensions.put("x-exclusive-bounds", true);

253

}

254

}

255

256

private void processArrayProperty(CodegenProperty property) {

257

// Process array constraints

258

if (property.getMinItems() != null || property.getMaxItems() != null) {

259

property.vendorExtensions.put("x-array-size-validation", true);

260

}

261

262

if (property.getUniqueItems()) {

263

property.vendorExtensions.put("x-unique-items", true);

264

}

265

266

// Process array item type

267

if (property.getItems() != null) {

268

CodegenProperty items = property.getItems();

269

property.vendorExtensions.put("x-item-type", items.dataType);

270

}

271

}

272

}

273

```

274

275

### Schema Analysis

276

277

```java

278

public class SchemaAnalyzer {

279

280

public void analyzeOpenAPISpec(OpenAPI openAPI) {

281

// Find all used schemas

282

List<String> usedSchemas = ModelUtils.getAllUsedSchemas(openAPI);

283

System.out.println("Used schemas: " + usedSchemas);

284

285

// Find unused schemas

286

List<String> unusedSchemas = ModelUtils.getUnusedSchemas(openAPI);

287

if (!unusedSchemas.isEmpty()) {

288

System.out.println("Warning: Unused schemas found: " + unusedSchemas);

289

}

290

291

// Analyze schemas by type

292

Map<String, Schema> schemas = openAPI.getComponents().getSchemas();

293

for (Map.Entry<String, Schema> entry : schemas.entrySet()) {

294

String name = entry.getKey();

295

Schema schema = entry.getValue();

296

297

analyzeSchema(name, schema);

298

}

299

}

300

301

private void analyzeSchema(String name, Schema schema) {

302

System.out.println("Analyzing schema: " + name);

303

304

if (ModelUtils.isObjectSchema(schema)) {

305

System.out.println(" Type: Object");

306

analyzeObjectSchema(schema);

307

} else if (ModelUtils.isArraySchema(schema)) {

308

System.out.println(" Type: Array");

309

analyzeArraySchema(schema);

310

} else if (ModelUtils.isStringSchema(schema)) {

311

System.out.println(" Type: String");

312

analyzeStringSchema(schema);

313

} else if (ModelUtils.isNumberSchema(schema)) {

314

System.out.println(" Type: Number");

315

analyzeNumericSchema(schema);

316

} else if (ModelUtils.isComposedSchema(schema)) {

317

System.out.println(" Type: Composed (oneOf/anyOf/allOf)");

318

analyzeComposedSchema(schema);

319

}

320

}

321

322

private void analyzeObjectSchema(Schema schema) {

323

Map<String, Schema> properties = schema.getProperties();

324

if (properties != null) {

325

System.out.println(" Properties: " + properties.keySet());

326

}

327

328

List<String> required = schema.getRequired();

329

if (required != null && !required.isEmpty()) {

330

System.out.println(" Required: " + required);

331

}

332

}

333

334

private void analyzeStringSchema(Schema schema) {

335

if (schema.getFormat() != null) {

336

System.out.println(" Format: " + schema.getFormat());

337

}

338

if (schema.getPattern() != null) {

339

System.out.println(" Pattern: " + schema.getPattern());

340

}

341

if (schema.getMinLength() != null) {

342

System.out.println(" MinLength: " + schema.getMinLength());

343

}

344

if (schema.getMaxLength() != null) {

345

System.out.println(" MaxLength: " + schema.getMaxLength());

346

}

347

}

348

}

349

```

350

351

### Exception Handling

352

353

```java

354

public class SafeGenerator extends DefaultGenerator {

355

356

@Override

357

public List<File> generate() {

358

try {

359

return super.generate();

360

} catch (SpecValidationException e) {

361

System.err.println("Specification validation failed:");

362

363

// Print validation errors

364

if (e.getErrors() != null && !e.getErrors().isEmpty()) {

365

System.err.println("Errors:");

366

for (String error : e.getErrors()) {

367

System.err.println(" - " + error);

368

}

369

}

370

371

// Print validation warnings

372

if (e.getWarnings() != null && !e.getWarnings().isEmpty()) {

373

System.err.println("Warnings:");

374

for (String warning : e.getWarnings()) {

375

System.err.println(" - " + warning);

376

}

377

}

378

379

throw e; // Re-throw to stop generation

380

} catch (GeneratorNotFoundException e) {

381

System.err.println("Generator not found: " + e.getMessage());

382

System.err.println("Available generators: " + getAvailableGenerators());

383

throw e;

384

}

385

}

386

387

private List<String> getAvailableGenerators() {

388

// Return list of available generator names

389

return Arrays.asList("java", "python", "javascript", "typescript", "go", "ruby");

390

}

391

}

392

```