|
| 1 | +package dev.cdevents.generator; |
| 2 | + |
| 3 | +import com.fasterxml.jackson.databind.JsonNode; |
| 4 | +import com.fasterxml.jackson.databind.ObjectMapper; |
| 5 | +import com.github.mustachejava.DefaultMustacheFactory; |
| 6 | +import com.github.mustachejava.Mustache; |
| 7 | +import com.github.mustachejava.MustacheFactory; |
| 8 | +import org.apache.commons.lang3.StringUtils; |
| 9 | +import org.slf4j.Logger; |
| 10 | +import org.slf4j.LoggerFactory; |
| 11 | +import java.io.BufferedWriter; |
| 12 | +import java.io.File; |
| 13 | +import java.io.FileWriter; |
| 14 | +import java.io.IOException; |
| 15 | +import java.util.ArrayList; |
| 16 | +import java.util.Iterator; |
| 17 | +import java.util.List; |
| 18 | +import java.util.Map; |
| 19 | + |
| 20 | +public final class CDEventsGenerator { |
| 21 | + |
| 22 | + private CDEventsGenerator() { |
| 23 | + } |
| 24 | + |
| 25 | + private static ObjectMapper objectMapper = new ObjectMapper(); |
| 26 | + private static Logger log = LoggerFactory.getLogger(CDEventsGenerator.class); |
| 27 | + |
| 28 | + private static final int SUBJECT_INDEX = 2; |
| 29 | + private static final int PREDICATE_INDEX = 3; |
| 30 | + private static final int VERSION_INDEX = 4; |
| 31 | + private static final int SUBSTRING_PIPELINE_INDEX = 8; |
| 32 | + |
| 33 | + private static final String TARGET_PACKAGE = "src/main/java/dev/cdevents/events"; |
| 34 | + |
| 35 | + /** |
| 36 | + * Event JsonSchema files location. |
| 37 | + */ |
| 38 | + private static final String RESOURCES_DIR = "src/main/resources/"; |
| 39 | + /** |
| 40 | + * Mustache generic event template file. |
| 41 | + */ |
| 42 | + private static final String EVENT_TEMPLATE_MUSTACHE = RESOURCES_DIR + "template/event-template.mustache"; |
| 43 | + |
| 44 | + /** |
| 45 | + * Main method to generate CDEvents from Json schema files. |
| 46 | + * @param args [0] - base directory for the cdevents-java-sdk-generator module |
| 47 | + * [1] - base directory for the cdevents-java-sdk module |
| 48 | + */ |
| 49 | + public static void main(String[] args) { |
| 50 | + if (args == null || args.length < 2) { |
| 51 | + throw new IllegalArgumentException("Insufficient arguments passed to CDEventsGenerator"); |
| 52 | + } |
| 53 | + String generatorBaseDir = args[0]; |
| 54 | + String sdkBaseDir = args[1]; |
| 55 | + String targetPackageDir = sdkBaseDir + File.separator + "src/main/java/dev/cdevents/events"; |
| 56 | + File folder = new File(sdkBaseDir + File.separator + RESOURCES_DIR + "schema"); |
| 57 | + System.out.println(folder.toPath().toAbsolutePath()); |
| 58 | + if (folder.isDirectory()) { |
| 59 | + File[] files = folder.listFiles((dir, name) -> name.toLowerCase().endsWith(".json")); |
| 60 | + if (files != null) { |
| 61 | + //Create Mustache factory and compile event-template.mustache template |
| 62 | + MustacheFactory mf = new DefaultMustacheFactory(); |
| 63 | + Mustache mustache = mf.compile(generatorBaseDir + File.separator + EVENT_TEMPLATE_MUSTACHE); |
| 64 | + |
| 65 | + //Generate a class file for each Json schema file using a mustache template |
| 66 | + |
| 67 | + for (File file : files) { |
| 68 | + SchemaData schemaData = buildCDEventDataFromJsonSchema(file); |
| 69 | + generateClassFileFromSchemaData(mustache, schemaData, targetPackageDir); |
| 70 | + } |
| 71 | + } |
| 72 | + } |
| 73 | + } |
| 74 | + |
| 75 | + private static void generateClassFileFromSchemaData(Mustache mustache, SchemaData schemaData, String targetPackageDir) { |
| 76 | + String classFileName = StringUtils.join(new String[]{schemaData.getCapitalizedSubject(), schemaData.getCapitalizedPredicate(), "CDEvent", ".java"}); |
| 77 | + File classFile = new File(targetPackageDir, classFileName); |
| 78 | + try { |
| 79 | + FileWriter fileWriter = new FileWriter(classFile); |
| 80 | + BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); |
| 81 | + mustache.execute(bufferedWriter, schemaData).flush(); |
| 82 | + fileWriter.close(); |
| 83 | + } catch (IOException e) { |
| 84 | + log.error("Exception occurred while generating class file from Json schema {}", e.getMessage()); |
| 85 | + throw new IllegalStateException("Exception occurred while generating class file from Json schema ", e); |
| 86 | + } |
| 87 | + log.info("Rendered event-template has been written to file - {}", classFile.getAbsolutePath()); |
| 88 | + } |
| 89 | + |
| 90 | + private static SchemaData buildCDEventDataFromJsonSchema(File file) { |
| 91 | + SchemaData schemaData = new SchemaData(); |
| 92 | + |
| 93 | + log.info("Processing event JsonSchema file: {}", file.getAbsolutePath()); |
| 94 | + try { |
| 95 | + JsonNode rootNode = objectMapper.readTree(file); |
| 96 | + JsonNode contextNode = rootNode.get("properties").get("context").get("properties"); |
| 97 | + |
| 98 | + String eventType = contextNode.get("type").get("enum").get(0).asText(); |
| 99 | + log.info("eventType: {}", eventType); |
| 100 | + String[] type = eventType.split("\\."); |
| 101 | + String subject = type[SUBJECT_INDEX]; |
| 102 | + String predicate = type[PREDICATE_INDEX]; |
| 103 | + String capitalizedSubject = StringUtils.capitalize(subject); |
| 104 | + if (subject.equals("pipelinerun")) { |
| 105 | + capitalizedSubject = capitalizedSubject.substring(0, SUBSTRING_PIPELINE_INDEX) |
| 106 | + + StringUtils.capitalize(subject.substring(SUBSTRING_PIPELINE_INDEX)); |
| 107 | + } |
| 108 | + String capitalizedPredicate = StringUtils.capitalize(predicate); |
| 109 | + String version = type[VERSION_INDEX]; |
| 110 | + |
| 111 | + //set the Schema JsonNode required values to schemaData |
| 112 | + schemaData.setSubject(subject); |
| 113 | + schemaData.setPredicate(predicate); |
| 114 | + schemaData.setCapitalizedSubject(capitalizedSubject); |
| 115 | + schemaData.setCapitalizedPredicate(capitalizedPredicate); |
| 116 | + schemaData.setSchemaFileName(file.getName()); |
| 117 | + schemaData.setUpperCaseSubject(subject.toUpperCase()); |
| 118 | + schemaData.setVersion(version); |
| 119 | + |
| 120 | + JsonNode subjectNode = rootNode.get("properties").get("subject").get("properties"); |
| 121 | + JsonNode subjectContentNode = subjectNode.get("content").get("properties"); |
| 122 | + updateSubjectContentProperties(schemaData, subjectContentNode); |
| 123 | + } catch (IOException e) { |
| 124 | + log.error("Exception occurred while building schema data from Json schema {}", e.getMessage()); |
| 125 | + throw new IllegalStateException("Exception occurred while building schema data from Json schema ", e); |
| 126 | + } |
| 127 | + return schemaData; |
| 128 | + } |
| 129 | + |
| 130 | + private static void updateSubjectContentProperties(SchemaData schemaData, JsonNode subjectContentNode) { |
| 131 | + Iterator<Map.Entry<String, JsonNode>> contentProps = subjectContentNode.fields(); |
| 132 | + List<SchemaData.ContentField> contentFields = new ArrayList<>(); |
| 133 | + List<SchemaData.ContentObjectField> contentObjectFields = new ArrayList<>(); |
| 134 | + while (contentProps.hasNext()) { |
| 135 | + Map.Entry<String, JsonNode> contentMap = contentProps.next(); |
| 136 | + String contentField = contentMap.getKey(); |
| 137 | + String capitalizedContentField = StringUtils.capitalize(contentField); |
| 138 | + JsonNode contentNode = contentMap.getValue(); |
| 139 | + if (!contentNode.get("type").asText().equals("object")) { |
| 140 | + contentFields.add(new SchemaData.ContentField(contentField, capitalizedContentField, "String")); |
| 141 | + } else { |
| 142 | + schemaData.setObjectName(contentField); |
| 143 | + schemaData.setCapitalizedObjectName(capitalizedContentField); |
| 144 | + JsonNode contentObjectNode = contentNode.get("properties"); |
| 145 | + Iterator<String> contentObjectProps = contentObjectNode.fieldNames(); |
| 146 | + while (contentObjectProps.hasNext()) { |
| 147 | + String contentObjField = contentObjectProps.next(); |
| 148 | + String capitalizedContentObjField = StringUtils.capitalize(contentObjField); |
| 149 | + contentObjectFields.add(new SchemaData.ContentObjectField(contentObjField, |
| 150 | + capitalizedContentObjField, contentField, capitalizedContentField, "String")); |
| 151 | + } |
| 152 | + } |
| 153 | + } |
| 154 | + schemaData.setContentFields(contentFields); |
| 155 | + schemaData.setContentObjectFields(contentObjectFields); |
| 156 | + } |
| 157 | + |
| 158 | + private static String getFieldsDataType(String fieldName) { |
| 159 | + if (fieldName.equalsIgnoreCase("url")) { |
| 160 | + return "URI"; |
| 161 | + } else { |
| 162 | + return "String"; |
| 163 | + } |
| 164 | + } |
| 165 | +} |
0 commit comments