Merge remote-tracking branch 'origin/main'
All checks were successful
Deploy to OCIWP / deploy (push) Successful in 6m9s
All checks were successful
Deploy to OCIWP / deploy (push) Successful in 6m9s
This commit is contained in:
@@ -45,10 +45,10 @@ public class ToolScaffolder {
|
||||
private static final String BASE_PACKAGE = "io.shinhanlife.dap.mcc";
|
||||
private static final String BASE_PACKAGE_PATH = "src/main/java/io/shinhanlife/dap/mcc";
|
||||
|
||||
public record FieldDefinition(String name, String type, String description, String example, boolean required,
|
||||
public record FieldDefinition(String name, String type, String description, List<String> examples, String pattern, boolean required,
|
||||
List<String> enumValues, String itemType, List<FieldDefinition> itemFields) {
|
||||
public FieldDefinition(String name, String type, String description, String example, boolean required) {
|
||||
this(name, type, description, example, required, List.of(), null, List.of());
|
||||
public FieldDefinition(String name, String type, String description, List<String> examples, String pattern, boolean required) {
|
||||
this(name, type, description, examples, pattern, required, List.of(), null, List.of());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,6 +340,10 @@ public class ToolScaffolder {
|
||||
implementation = addImport(implementation, "import " + integrationPackage + "." + baseName + "Client;");
|
||||
implementation = addImport(implementation, "import " + integrationPackage + ".io." + requestIo + ";");
|
||||
implementation = addImport(implementation, "import " + integrationPackage + ".io." + responseIo + ";");
|
||||
implementation = addImport(implementation, "import lombok.RequiredArgsConstructor;");
|
||||
if (!implementation.contains("@RequiredArgsConstructor")) {
|
||||
implementation = implementation.replaceFirst("public class ", "@RequiredArgsConstructor\npublic class ");
|
||||
}
|
||||
implementation = insertConstructorField(implementation, " private final " + baseName + "Client " + clientVariable + ";");
|
||||
implementation = insertConstructorField(implementation, " private final " + baseName + "Converter " + converterVariable + ";");
|
||||
String call = mci
|
||||
@@ -374,9 +378,17 @@ public class ToolScaffolder {
|
||||
|
||||
private static String insertConstructorField(String content, String field) {
|
||||
if (content.contains(field)) return content;
|
||||
int constructorField = content.indexOf("private final ");
|
||||
if (constructorField < 0) return insertBeforeLastBrace(content, "\n" + field + "\n");
|
||||
int constructorField = content.lastIndexOf("private final ");
|
||||
if (constructorField < 0) {
|
||||
int classDecl = content.indexOf("public class ");
|
||||
if (classDecl >= 0) {
|
||||
int brace = content.indexOf('{', classDecl);
|
||||
if (brace >= 0) return content.substring(0, brace + 1) + "\n" + field + content.substring(brace + 1);
|
||||
}
|
||||
return insertBeforeLastBrace(content, "\n" + field + "\n");
|
||||
}
|
||||
int lineEnd = content.indexOf('\n', constructorField);
|
||||
if (lineEnd < 0) return content + "\n" + field;
|
||||
return content.substring(0, lineEnd + 1) + field + "\n" + content.substring(lineEnd + 1);
|
||||
}
|
||||
|
||||
@@ -445,7 +457,7 @@ public class ToolScaffolder {
|
||||
String inputSchemaResource = useSchemaResource ? schemaResourceDirectory + toKebabCase(baseName) + "-resource-input-schema.json" : null;
|
||||
String outputSchemaResource = useSchemaResource ? schemaResourceDirectory + toKebabCase(baseName) + "-resource-output-schema.json" : null;
|
||||
|
||||
String result = scaffold(baseName, interfaceId, title, description, group, routingType, moduleName, author, createDate, false, null, inputSchemaResource, outputSchemaResource, List.of(new FieldDefinition("query", "String", "Search query", "example", false)), List.of());
|
||||
String result = scaffold(baseName, interfaceId, title, description, group, routingType, moduleName, author, createDate, false, null, inputSchemaResource, outputSchemaResource, List.of(new FieldDefinition("query", "String", "Search query", List.of("example"), "", false)), List.of());
|
||||
System.out.println(result);
|
||||
}
|
||||
|
||||
@@ -464,7 +476,7 @@ public class ToolScaffolder {
|
||||
public static String scaffold(String baseName, String interfaceId, String description, String group, String routingType, String moduleName, String author, String createDate, boolean register, String clientSystemCode, String inputSchemaResource, String outputSchemaResource) throws IOException {
|
||||
return scaffold(baseName, interfaceId, description, group, routingType, moduleName, author, createDate,
|
||||
register, clientSystemCode, inputSchemaResource, outputSchemaResource,
|
||||
List.of(new FieldDefinition("query", "String", "Search query", "example", false)), List.of());
|
||||
List.of(new FieldDefinition("query", "String", "Search query", List.of("example"), "", false)), List.of());
|
||||
}
|
||||
|
||||
public static String scaffold(String baseName, String interfaceId, String description, String group, String routingType, String moduleName, String author, String createDate, boolean register, String clientSystemCode, String inputSchemaResource, String outputSchemaResource, List<FieldDefinition> inputFields, List<FieldDefinition> outputFields) throws IOException {
|
||||
@@ -1429,7 +1441,7 @@ public class ToolScaffolder {
|
||||
private static void appendSchemaProperty(StringBuilder properties, FieldDefinition field) {
|
||||
properties.append(" ").append(field.name().trim()).append(":\n")
|
||||
.append(" type: ").append(jsonSchemaType(field.type())).append("\n")
|
||||
.append(" description: ").append(yamlText(field.description())).append("\n");
|
||||
.append(" description: ").append(yamlText(richDescription(field))).append("\n");
|
||||
if ("Enum".equals(field.type()) && field.enumValues() != null && !field.enumValues().isEmpty()) {
|
||||
properties.append(" enum: [").append(field.enumValues().stream()
|
||||
.filter(value -> value != null && !value.isBlank()).map(String::trim)
|
||||
@@ -1443,7 +1455,7 @@ public class ToolScaffolder {
|
||||
for (FieldDefinition itemField : field.itemFields()) {
|
||||
properties.append(" ").append(itemField.name()).append(":\n")
|
||||
.append(" type: ").append(jsonSchemaType(itemField.type())).append("\n")
|
||||
.append(" description: ").append(yamlText(itemField.description())).append("\n");
|
||||
.append(" description: ").append(yamlText(richDescription(itemField))).append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1523,35 +1535,37 @@ public class ToolScaffolder {
|
||||
body = " private String resultCode;\n\n private String resultMessage;\n" + body;
|
||||
}
|
||||
String listImport = hasListField(fields) ? "import java.util.List;\n" : "";
|
||||
String patternImport = hasPatternField(fields) ? "import jakarta.validation.constraints.Pattern;\n" : "";
|
||||
return """
|
||||
package %s;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
%s
|
||||
%s%s
|
||||
|
||||
@Data
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class %s {
|
||||
%s%s}
|
||||
""".formatted(packageName, listImport, className, body, innerObjectListClasses(fields));
|
||||
""".formatted(packageName, listImport, patternImport, className, body, innerObjectListClasses(fields));
|
||||
}
|
||||
|
||||
private static String mciIoContent(String packageSuffix, String className, List<FieldDefinition> fields,
|
||||
String author, String createDate) {
|
||||
String listImport = hasListField(fields) ? "import java.util.List;\n" : "";
|
||||
String patternImport = hasPatternField(fields) ? "import jakarta.validation.constraints.Pattern;\n" : "";
|
||||
return """
|
||||
package %s.%s.io;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
%s
|
||||
%s%s
|
||||
|
||||
@Data
|
||||
public class %s {
|
||||
%s%s}
|
||||
""".formatted(BASE_PACKAGE, packageSuffix, listImport, className, fieldLines(fields, Set.of(), className),
|
||||
""".formatted(BASE_PACKAGE, packageSuffix, listImport, patternImport, className, fieldLines(fields, Set.of(), className),
|
||||
innerObjectListClasses(fields));
|
||||
}
|
||||
|
||||
@@ -1559,6 +1573,18 @@ public class ToolScaffolder {
|
||||
return fields != null && fields.stream().anyMatch(field -> field != null && "List".equals(field.type()));
|
||||
}
|
||||
|
||||
private static boolean hasPatternField(List<FieldDefinition> fields) {
|
||||
if (fields == null) return false;
|
||||
return fields.stream().anyMatch(field -> {
|
||||
if (field == null) return false;
|
||||
if (field.pattern() != null && !field.pattern().isBlank()) return true;
|
||||
if ("List".equals(field.type()) && "Object".equals(field.itemType())) {
|
||||
return hasPatternField(field.itemFields());
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
private static void writeStructuredFieldTypes(Path directory, String packageName, String ownerClass,
|
||||
List<FieldDefinition> fields) throws IOException {
|
||||
for (FieldDefinition field : fields == null ? List.<FieldDefinition>of() : fields) {
|
||||
@@ -1820,18 +1846,38 @@ public class ToolScaffolder {
|
||||
continue;
|
||||
}
|
||||
String type = javaFieldType(field, ownerClass);
|
||||
String description = field.description() == null ? "" : field.description().replace("\"", "\\\"");
|
||||
String example = field.example() == null ? "" : field.example().replace("\"", "\\\"");
|
||||
source.append(" @Schema(description = \"").append(description).append("\", example = \"")
|
||||
.append(example).append("\"");
|
||||
String description = richDescription(field).replace("\"", "\\\"");
|
||||
String example = "";
|
||||
if (field.examples() != null && !field.examples().isEmpty()) {
|
||||
example = field.examples().get(0).replace("\"", "\\\"");
|
||||
}
|
||||
source.append(" @Schema(description = \"").append(description).append("\"");
|
||||
if (!example.isEmpty()) {
|
||||
source.append(", example = \"").append(example).append("\"");
|
||||
}
|
||||
if (field.required()) {
|
||||
source.append(", requiredMode = Schema.RequiredMode.REQUIRED");
|
||||
}
|
||||
source.append(")\n private ").append(type).append(' ').append(fieldName).append(";\n\n");
|
||||
source.append(")\n");
|
||||
if (field.pattern() != null && !field.pattern().isBlank()) {
|
||||
source.append(" @Pattern(regexp = \"").append(field.pattern().replace("\"", "\\\"")).append("\")\n");
|
||||
}
|
||||
source.append(" private ").append(type).append(' ').append(fieldName).append(";\n\n");
|
||||
}
|
||||
return source.toString();
|
||||
}
|
||||
|
||||
private static String richDescription(FieldDefinition field) {
|
||||
String desc = field.description() == null ? "" : field.description().trim();
|
||||
if (field.pattern() != null && !field.pattern().isBlank()) {
|
||||
desc += " (형식: " + field.pattern() + ")";
|
||||
}
|
||||
if (field.examples() != null && !field.examples().isEmpty()) {
|
||||
desc += " (예시: " + String.join(", ", field.examples()) + ")";
|
||||
}
|
||||
return desc.trim();
|
||||
}
|
||||
|
||||
private static String javaFieldType(FieldDefinition field, String ownerClass) {
|
||||
return switch (field.type() == null ? "String" : field.type()) {
|
||||
case "Enum" -> toPascalCase(field.name());
|
||||
@@ -1902,19 +1948,21 @@ public class ToolScaffolder {
|
||||
}
|
||||
return "[" + object + "]";
|
||||
}
|
||||
FieldDefinition item = new FieldDefinition("item", field.itemType(), "", field.example(), false);
|
||||
FieldDefinition item = new FieldDefinition("item", field.itemType(), "", field.examples(), field.pattern(), false);
|
||||
return "[" + mockValue(item) + "]";
|
||||
}
|
||||
if (field.example() == null || field.example().isBlank()) {
|
||||
|
||||
String exampleStr = (field.examples() != null && !field.examples().isEmpty()) ? field.examples().get(0) : null;
|
||||
if (exampleStr == null || exampleStr.isBlank()) {
|
||||
return "null";
|
||||
}
|
||||
if ("Enum".equals(field.type())) {
|
||||
return "\"" + jsonEscape(field.example()) + "\"";
|
||||
return "\"" + jsonEscape(exampleStr) + "\"";
|
||||
}
|
||||
return switch (supportedType(field.type())) {
|
||||
case "Integer", "Long", "Double", "BigDecimal" -> field.example();
|
||||
case "Boolean" -> Boolean.parseBoolean(field.example()) ? "true" : "false";
|
||||
default -> "\"" + jsonEscape(field.example()) + "\"";
|
||||
case "Integer", "Long", "Double", "BigDecimal" -> exampleStr;
|
||||
case "Boolean" -> Boolean.parseBoolean(exampleStr) ? "true" : "false";
|
||||
default -> "\"" + jsonEscape(exampleStr) + "\"";
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user