| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.camel.karavan.generator; |
| |
| import io.vertx.core.json.JsonObject; |
| |
| import java.util.*; |
| import java.util.stream.Collectors; |
| |
| import static java.util.stream.Collectors.toList; |
| |
| public final class CamelDefinitionApiGenerator extends AbstractGenerator { |
| |
| final static String modelHeader = "karavan-generator/src/main/resources/CamelDefinitionApi.header.ts"; |
| final static String modelFooter = "karavan-generator/src/main/resources/CamelDefinitionApi.footer.ts"; |
| final static String modelTemplate = "karavan-generator/src/main/resources/CamelDefinitionApi.ts"; |
| final static String targetModel = "karavan-core/src/core/api/CamelDefinitionApi.ts"; |
| |
| public static void main(String[] args) throws Exception { |
| CamelDefinitionApiGenerator.generate(); |
| System.exit(0); |
| } |
| |
| public static void generate() throws Exception { |
| CamelDefinitionApiGenerator g = new CamelDefinitionApiGenerator(); |
| g.createCamelDefinitions(); |
| } |
| |
| private void createCamelDefinitions() throws Exception { |
| StringBuilder camelModel = new StringBuilder(); |
| camelModel.append(readFileText(modelHeader)); |
| |
| String camelYamlDSL = getCamelYamlDSL(); |
| JsonObject definitions = new JsonObject(camelYamlDSL).getJsonObject("items").getJsonObject("definitions"); |
| |
| List<String> modelList = getClasses(definitions, "org.apache.camel"); |
| modelList.forEach(classFullName -> { |
| String className = classSimple(classFullName); |
| camelModel.append(" ").append(className).append(",\n"); |
| }); |
| camelModel.append("} from '../model/CamelDefinition';\n"); |
| camelModel.append("import {CamelUtil} from './CamelUtil';\n\n"); |
| |
| |
| camelModel.append("export class CamelDefinitionApi { \n\n"); |
| |
| // generate create functions for Definitions |
| modelList.forEach(classFullName -> { |
| String model = generateModelApi(classFullName, definitions.getJsonObject(classFullName)); |
| camelModel.append(model).append(System.lineSeparator()); |
| }); |
| |
| // generate createStep function |
| Map<String, String> stepNames = getProcessorStepName(new JsonObject(camelYamlDSL).getJsonObject("items").getJsonObject("properties")); |
| stepNames.putAll(getProcessorStepName(definitions.getJsonObject("org.apache.camel.model.ProcessorDefinition").getJsonObject("properties"))); |
| StringBuilder cs = new StringBuilder( |
| " static createStep = (name: string, body: any, clone: boolean = false): CamelElement => {\n" + |
| " const newBody = CamelUtil.camelizeBody(name, body, clone);\n" + |
| " switch (name) { \n" |
| ); |
| getClasses(definitions, "org.apache.camel") |
| .forEach(className -> { |
| String code = String.format(" case '%1$s': return CamelDefinitionApi.create%1$s(newBody);\n", classSimple(className)); |
| cs.append(code); |
| }); |
| cs.append( |
| " default: return new CamelElement('');\n" + |
| " }\n" + |
| " }\n\n"); |
| camelModel.append(cs); |
| |
| // generate createExpression function |
| stepNames.clear(); |
| stepNames.putAll(getProcessorStepName(definitions.getJsonObject("org.apache.camel.model.language.ExpressionDefinition").getJsonObject("properties"))); |
| StringBuilder ce = new StringBuilder( |
| " static createExpression = (name: string, body: any): CamelElement => {\n" + |
| " const newBody = CamelUtil.camelizeBody(name, body, false);\n" + |
| " delete newBody.expressionName;\n" + |
| " delete newBody.dslName;\n" + |
| " switch (name) { \n" |
| ); |
| stepNames.forEach((className, stepName) -> { |
| String code = String.format(" case '%1$s': return CamelDefinitionApi.create%1$s(newBody);\n", className); |
| ce.append(code); |
| }); |
| ce.append( |
| " default: return new SimpleExpression(newBody);\n" + |
| " }\n" + |
| " }\n\n"); |
| camelModel.append(ce); |
| |
| // generate createDataFormat function |
| stepNames.clear(); |
| stepNames.putAll(getProcessorStepName(definitions.getJsonObject("org.apache.camel.model.dataformat.DataFormatsDefinition").getJsonObject("properties"))); |
| StringBuilder df = new StringBuilder( |
| " static createDataFormat = (name: string, body: any): CamelElement => {\n" + |
| " const newBody = CamelUtil.camelizeBody(name, body, false);\n" + |
| " delete newBody.dataFormatName;\n" + |
| " delete newBody.dslName;\n" + |
| " switch (name) { \n" |
| ); |
| stepNames.forEach((className, stepName) -> { |
| String code = String.format(" case '%1$s': return CamelDefinitionApi.create%1$s(newBody);\n", className); |
| df.append(code); |
| }); |
| df.append( |
| " default: return new JsonDataFormat(newBody);\n" + |
| " }\n" + |
| " }\n"); |
| camelModel.append(df); |
| |
| camelModel.append(readFileText(modelFooter)); |
| |
| camelModel.append("}\n"); |
| writeFileText(targetModel, camelModel.toString()); |
| } |
| |
| private String generateModelApi(String classFullName, JsonObject obj) { |
| String className = classSimple(classFullName); |
| |
| String s1 = getStringToRequired(obj, className); |
| |
| JsonObject properties = obj.containsKey("oneOf") |
| ? obj.getJsonArray("oneOf").getJsonObject(1).getJsonObject("properties") |
| : obj.getJsonObject("properties"); |
| |
| Map<String, String> attrs = new HashMap<>(); |
| if (properties != null) { |
| properties.getMap().keySet().forEach(name -> { |
| JsonObject aValue = properties.getJsonObject(name); |
| if (isAttributeRefArray(aValue) && name.equals("steps") && ! className.equals("ChoiceDefinition") && ! className.equals("SwitchDefinition") && ! className.equals("KameletDefinition")) { |
| attrs.put(name, " def.steps = CamelDefinitionApi.createSteps(element?.steps);\n"); |
| } else if (isAttributeRefArray(aValue) && !name.equals("steps")) { |
| String code = String.format( |
| " def.%1$s = element && element?.%1$s ? element?.%1$s.map((x:any) => CamelDefinitionApi.create%2$s(x)) :[]; \n" |
| , name, getAttributeArrayClass(aValue)); |
| attrs.put(name, code); |
| } else if (isAttributeRef(aValue) |
| && !getAttributeClass(aValue).equals("SagaActionUriDefinition") // SagaActionUriDefinition is exception |
| && !getAttributeClass(aValue).equals("ToDefinition") // exception for ToDefinition (in REST Methods) |
| && !getAttributeClass(aValue).equals("ToDynamicDefinition") // exception for ToDynamicDefinition (in REST Methods) |
| ) { |
| String attributeClass = getAttributeClass(aValue); |
| String template = attributeClass.equals("ExpressionDefinition") |
| ? " def.%1$s = CamelDefinitionApi.create%2$s(element.%1$s); \n" |
| : " if (element?.%1$s !== undefined) { \n" + |
| " def.%1$s = CamelDefinitionApi.create%2$s(element.%1$s); \n" + |
| " } \n"; |
| String code = String.format(template, name, getAttributeClass(aValue)); |
| attrs.put(name, code); |
| } else { |
| |
| } |
| }); |
| } |
| return String.format(readFileText(modelTemplate), className, s1, attrs.values().stream().collect(Collectors.joining(""))); |
| } |
| |
| private String getStringToRequired(JsonObject obj, String className) { |
| if (className.equals("FromDefinition")) { |
| return "if (element && typeof element === 'string') element = { uri: element};"; |
| } else if (obj.containsKey("oneOf") && obj.containsKey("required")) { |
| List<String> list = obj.getJsonArray("required").getList(); |
| list = list.stream().filter(o -> !o.equals("steps")).collect(toList()); |
| return "if (element && typeof element === 'string') element = {" + list.get(0) + ": element};"; |
| } else { |
| return ""; |
| } |
| } |
| |
| private boolean isAttributeRefArray(JsonObject attribute) { |
| if (attribute.containsKey("type") && attribute.getString("type").equals("array")) { |
| JsonObject items = attribute.getJsonObject("items"); |
| return items.containsKey("$ref"); |
| } else { |
| return false; |
| } |
| } |
| } |