diff --git a/.github/workflows/test-other.yml b/.github/workflows/test-other.yml index d2fc21c3..3caad844 100644 --- a/.github/workflows/test-other.yml +++ b/.github/workflows/test-other.yml @@ -63,4 +63,8 @@ jobs: - name: Run tests ${{ inputs.test-name }} working-directory: tests/ run: - ./${{ inputs.test-name }} \ No newline at end of file + ./${{ inputs.test-name }} + + - name: Run tests cobj-api + run: + make test-cobj-api \ No newline at end of file diff --git a/Makefile.am b/Makefile.am index 904184dd..618535b7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -75,3 +75,6 @@ defaults.h: Makefile.am $(top_builddir)/config.status echo "#define COB_MODULE_EXT \"$(COB_MODULE_EXT)\""; \ echo "#define LOCALEDIR \"$(datadir)/locale\""; \ } > defaults.h + +test-cobj-api: + $(MAKE) -C libcobj test \ No newline at end of file diff --git a/Makefile.in b/Makefile.in index 93117cd9..fbe138e1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1025,6 +1025,9 @@ defaults.h: Makefile.am $(top_builddir)/config.status echo "#define LOCALEDIR \"$(datadir)/locale\""; \ } > defaults.h +test-cobj-api: + $(MAKE) -C libcobj test + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/libcobj/Makefile.am b/libcobj/Makefile.am index 60a21ef4..96776448 100644 --- a/libcobj/Makefile.am +++ b/libcobj/Makefile.am @@ -1,5 +1,6 @@ TARGET_JAR = app/build/libs/libcobj.jar COBJ_IDX = bin/cobj-idx +COBJ_API = bin/cobj-api SRC_FILES = \ settings.gradle.kts \ @@ -71,7 +72,7 @@ SRC_FILES = \ ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/ui/CobolCallResult.java \ ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/ui/CobolResultInt.java \ ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/ui/CobolResultString.java \ - ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/ui/CobolResultDouble.java \ + ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/ui/CobolResultDouble.java \ ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/indexed_file/IndexedFileUtilMain.java \ ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/indexed_file/ErrorLib.java \ ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/indexed_file/LoadResult.java \ @@ -80,7 +81,12 @@ SRC_FILES = \ ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/indexed_file/RecordWriter.java \ ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/indexed_file/StdinRecordReader.java \ ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/indexed_file/FileSeqRecordReader.java \ - ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/indexed_file/FileLineSeqRecordReader.java + ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/indexed_file/FileLineSeqRecordReader.java\ + ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/ApiFiles.java \ + ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/ApiFilesOptions.java + +TEST_FILE = \ + ./app/src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/ApiFilesTest.java all: $(TARGET_JAR) @@ -90,7 +96,12 @@ $(TARGET_JAR): $(SRC_FILES) clean: rm -rf $(TARGET_JAR) -install: $(TARGET_JAR) $(COBJ_IDX) +install: $(TARGET_JAR) $(COBJ_IDX) $(COBJ_API) mkdir -p $(DESTDIR)$(prefix)/lib/opensourcecobol4j/ install $(TARGET_JAR) $(DESTDIR)$(prefix)/lib/opensourcecobol4j/ install $(COBJ_IDX) $(DESTDIR)$(prefix)/bin/ + install $(COBJ_API) $(DESTDIR)$(prefix)/bin/ + +test: + ./gradlew test + rm -f ./app/testController.java ./app/testRecord.java \ No newline at end of file diff --git a/libcobj/Makefile.in b/libcobj/Makefile.in index 6290111c..dd8d9dc5 100644 --- a/libcobj/Makefile.in +++ b/libcobj/Makefile.in @@ -281,6 +281,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ TARGET_JAR = app/build/libs/libcobj.jar COBJ_IDX = bin/cobj-idx +COBJ_API = bin/cobj-api SRC_FILES = \ settings.gradle.kts \ ./app/build.gradle.kts \ @@ -360,7 +361,12 @@ SRC_FILES = \ ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/indexed_file/RecordWriter.java \ ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/indexed_file/StdinRecordReader.java \ ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/indexed_file/FileSeqRecordReader.java \ - ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/indexed_file/FileLineSeqRecordReader.java + ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/indexed_file/FileLineSeqRecordReader.java\ + ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/ApiFiles.java \ + ./app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/ApiFilesOptions.java + +TEST_FILE = \ + ./app/src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/ApiFilesTest.java all: all-am @@ -561,10 +567,15 @@ $(TARGET_JAR): $(SRC_FILES) clean: rm -rf $(TARGET_JAR) -install: $(TARGET_JAR) $(COBJ_IDX) +install: $(TARGET_JAR) $(COBJ_IDX) $(COBJ_API) mkdir -p $(DESTDIR)$(prefix)/lib/opensourcecobol4j/ install $(TARGET_JAR) $(DESTDIR)$(prefix)/lib/opensourcecobol4j/ install $(COBJ_IDX) $(DESTDIR)$(prefix)/bin/ + install $(COBJ_API) $(DESTDIR)$(prefix)/bin/ + +test: + ./gradlew test + rm -f ./app/testController.java ./app/testRecord.java # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/libcobj/app/build.gradle.kts b/libcobj/app/build.gradle.kts index 92d241d9..7c34ed08 100644 --- a/libcobj/app/build.gradle.kts +++ b/libcobj/app/build.gradle.kts @@ -30,6 +30,9 @@ dependencies { implementation("com.google.guava:guava:31.1-jre") implementation("org.xerial:sqlite-jdbc:3.30.1") implementation("commons-cli:commons-cli:1.6.0") + testImplementation("org.junit.jupiter:junit-jupiter:5.9.3") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") + implementation("org.json:json:20231013") spotbugs("com.github.spotbugs:spotbugs:4.8.0") } @@ -81,3 +84,16 @@ tasks.withType().configureEach { tasks.withType { archiveClassifier.set("") } + +tasks.test { + useJUnitPlatform() + testLogging { + events("passed", "skipped", "failed") + } +} + +tasks.named("test") { + // Use JUnit Platform for unit tests. + useJUnitPlatform() +} + diff --git a/libcobj/app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/ApiFiles.java b/libcobj/app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/ApiFiles.java new file mode 100755 index 00000000..df39b751 --- /dev/null +++ b/libcobj/app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/ApiFiles.java @@ -0,0 +1,213 @@ +/* + * This Java source file was generated by the Gradle 'init' task. + */ +package jp.osscons.opensourcecobol.libcobj.user_util.cobj_api; + +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Paths; +import org.json.JSONArray; +import org.json.JSONObject; + +public class ApiFiles { + public static void main(String[] args) { + ApiFilesOptions.getOptions(args); + + if (args.length == 0) { + System.out.println("No json file is specified."); + System.exit(1); + } + + String filePath; + try { + filePath = args[1]; + } catch (ArrayIndexOutOfBoundsException e) { + filePath = args[0]; + } + + javaCreate(filePath); + } + + public static void javaCreate(String filePath) { + try { + String json = new String(Files.readAllBytes(Paths.get(filePath))); + JSONObject obj = new JSONObject(json); + String programId = obj.getString("program_id"); + JSONArray params = obj.getJSONArray("procedure_division_using_parameters"); + + String outputDir; + FileWriter ctlFile; + FileWriter rcdFile; + + if (ApiFilesOptions.outputDir != null) { + outputDir = ApiFilesOptions.outputDir + "/"; + ctlFile = new FileWriter(outputDir + programId + "Controller.java"); + rcdFile = new FileWriter(outputDir + programId + "Record.java"); + } else { + ctlFile = new FileWriter(programId + "Controller.java"); + rcdFile = new FileWriter(programId + "Record.java"); + } + + writeController(ctlFile, programId, params); + writeRecord(rcdFile, programId, params); + + } catch (IOException e) { + e.printStackTrace(); + System.err.println("Error reading file: " + e.getMessage()); + System.exit(1); + } + } + + public static void writeController(FileWriter ctlFile, String programId, JSONArray params) { + PrintWriter ctlWriter = new PrintWriter(ctlFile); + JSONObject param; + String name; + String type; + String defaultValue; + String methodName; + String nameController = programId + "Controller"; + String nameRecord = programId + "Record"; + int i; + + if (ApiFilesOptions.packageName != null) { + ctlWriter.println("package " + ApiFilesOptions.packageName + ";"); + } else { + ctlWriter.println("package com.example.restservice;"); + } + + ctlWriter.println( + "import java.util.concurrent.atomic.AtomicLong;\n" + + "import org.springframework.web.bind.annotation.GetMapping;\n" + + "import org.springframework.web.bind.annotation.RequestParam;\n" + + "import org.springframework.web.bind.annotation.RestController;\n" + + "import jp.osscons.opensourcecobol.libcobj.ui.*;\n"); + + ctlWriter.println( + "@RestController\n" + + "public class " + + nameController + + " {\n" + + " @GetMapping(\"/" + + programId + + "\")\n" + + " public " + + nameRecord + + " " + + nameController + + "("); + + for (i = 0; i < params.length(); ++i) { + param = params.getJSONObject(i); + name = param.getString("variable_name"); + type = param.getString("java_type"); + if ("String".equals(type)) { + defaultValue = "\"\""; + } else { + defaultValue = "\"0\""; + } + + ctlWriter.print( + " @RequestParam(value = " + + "\"" + + name + + "\", defaultValue = " + + defaultValue + + ") " + + type + + " " + + name); + + if (i < params.length() - 1) { + ctlWriter.println(","); + } else { + ctlWriter.println(); + } + } + + ctlWriter.print( + " ) {\n" + + " int statuscode = 200;\n" + + " " + + programId + + " " + + programId + + "Cobol = new " + + programId + + "();\n" + + " CobolResultSet result = " + + programId + + "Cobol.execute("); + + for (i = 0; i < params.length(); ++i) { + param = params.getJSONObject(i); + name = param.getString("variable_name"); + ctlWriter.print(name); + + if (i < params.length() - 1) { + ctlWriter.print(", "); + } + } + ctlWriter.println(");\n" + " try {"); + + for (i = 0; i < params.length(); ++i) { + param = params.getJSONObject(i); + name = param.getString("variable_name"); + type = param.getString("java_type"); + if ("String".equals(type)) { + methodName = "getString"; + } else if ("int".equals(type)) { + methodName = "getInt"; + } else { + methodName = "getDouble"; + } + ctlWriter.println(" " + name + " = result." + methodName + "(" + (i + 1) + ");"); + } + + ctlWriter.print( + " } catch (Exception e) {\n" + + " statuscode = 500;\n" + + " }\n" + + " return new " + + programId + + "Record(statuscode, "); + + for (i = 0; i < params.length(); ++i) { + param = params.getJSONObject(i); + name = param.getString("variable_name"); + ctlWriter.print(name); + if (i < params.length() - 1) { + ctlWriter.print(", "); + } + } + ctlWriter.println(");\n" + " }\n" + "}"); + ctlWriter.close(); + } + + public static void writeRecord(FileWriter rcdFile, String programId, JSONArray params) { + PrintWriter rcdWriter = new PrintWriter(rcdFile); + JSONObject param; + String name; + String type; + int i; + + rcdWriter.print( + "package com.example.restservice;\n" + + "public record " + + programId + + "Record(int statuscode, "); + + for (i = 0; i < params.length(); ++i) { + param = params.getJSONObject(i); + name = param.getString("variable_name"); + type = param.getString("java_type"); + rcdWriter.print(type + " " + name); + if (i < params.length() - 1) { + rcdWriter.print(", "); + } + } + rcdWriter.println(") {}"); + rcdWriter.close(); + } +} diff --git a/libcobj/app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/ApiFilesOptions.java b/libcobj/app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/ApiFilesOptions.java new file mode 100644 index 00000000..6da0f55a --- /dev/null +++ b/libcobj/app/src/main/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/ApiFilesOptions.java @@ -0,0 +1,72 @@ +package jp.osscons.opensourcecobol.libcobj.user_util.cobj_api; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; + +public class ApiFilesOptions { + public static String packageName; + public static String outputDir; + + public static void getOptions(String[] args) { + Options options = new Options(); + options.addOption("h", "help", false, "Prints the help message"); + options.addOption( + "jp", "java-package", true, "Specify the package name of the generated source code"); + options.addOption( + "o", + "output-dir", + true, + "Set the output destination of the java file to an arbitrary destination"); + options.addOption("v", "version", false, "Prints the version of the cobj-api"); + CommandLineParser parser = new DefaultParser(); + CommandLine cmd; + + try { + cmd = parser.parse(options, args); + } catch (ParseException e) { + printHelpMessage(); + System.exit(1); + return; + } + + if (cmd.hasOption("h")) { + printHelpMessage(); + System.exit(0); + return; + } else if (cmd.hasOption("v")) { + System.out.println("1.0.21"); + System.exit(0); + return; + } else if (cmd.getOptionValue("java-package") != null) { + String packageName = cmd.getOptionValue("java-package"); + setJavaPackage(packageName); + return; + } else if (cmd.getOptionValue("output-dir") != null) { + String outputDir = cmd.getOptionValue("output-dir"); + setOutputDir(outputDir); + return; + } + } + + private static void printHelpMessage() { + System.out.println("Usage: cobj-api [options] "); + System.out.println("Options:"); + System.out.println(" -h, --help\t\t\t\tDisplay this message"); + System.out.println( + " -java-package=\t\tSpecify the package name of the generated source code"); + System.out.println( + " -o=, --output-dir=\t\tSet the output destination of the java file to an arbitrary destination"); + System.out.println(" -v, --version\t\t\t\tPrints the version of the cobj-api"); + } + + public static void setJavaPackage(String packageName) { + ApiFilesOptions.packageName = packageName; + } + + public static void setOutputDir(String outputDir) { + ApiFilesOptions.outputDir = outputDir; + } +} diff --git a/libcobj/app/src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/ApiFilesTest.java b/libcobj/app/src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/ApiFilesTest.java new file mode 100644 index 00000000..5612c709 --- /dev/null +++ b/libcobj/app/src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/ApiFilesTest.java @@ -0,0 +1,41 @@ +/* + * This Java source file was generated by the Gradle 'init' task. + */ +package jp.osscons.opensourcecobol.libcobj.user_util.cobj_api; + +import static org.junit.jupiter.api.Assertions.*; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +class ApiFilesTest { + + boolean compOutputFiles(String fileName) { + ApiFiles.javaCreate(fileName); + try { + return Arrays.equals( + Files.readAllBytes( + Paths.get( + "src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/testController.txt")), + Files.readAllBytes(Paths.get("testController.java"))) + && Arrays.equals( + Files.readAllBytes( + Paths.get( + "src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/testRecord.txt")), + Files.readAllBytes(Paths.get("testRecord.java"))); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + + @Test + void checkOutputFiles() { + String fileName = + "src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/test.json"; + assertTrue(compOutputFiles(fileName)); + } +} diff --git a/libcobj/app/src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/test.json b/libcobj/app/src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/test.json new file mode 100644 index 00000000..c039d09c --- /dev/null +++ b/libcobj/app/src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/test.json @@ -0,0 +1,18 @@ +{ + "opensourcecobol4j_version": "1.0.21", + "program_id": "test", + "procedure_division_using_parameters": [ + { + "variable_name": "param1", + "java_type": "int" + }, + { + "variable_name": "param2", + "java_type": "double" + }, + { + "variable_name": "param3", + "java_type": "String" + } + ] +} diff --git a/libcobj/app/src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/testController.txt b/libcobj/app/src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/testController.txt new file mode 100755 index 00000000..34ff22df --- /dev/null +++ b/libcobj/app/src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/testController.txt @@ -0,0 +1,28 @@ +package com.example.restservice; +import java.util.concurrent.atomic.AtomicLong; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import jp.osscons.opensourcecobol.libcobj.ui.*; + +@RestController +public class testController { + @GetMapping("/test") + public testRecord testController( + @RequestParam(value = "param1", defaultValue = "0") int param1, + @RequestParam(value = "param2", defaultValue = "0") double param2, + @RequestParam(value = "param3", defaultValue = "") String param3 + ) { + int statuscode = 200; + test testCobol = new test(); + CobolResultSet result = testCobol.execute(param1, param2, param3); + try { + param1 = result.getInt(1); + param2 = result.getDouble(2); + param3 = result.getString(3); + } catch (Exception e) { + statuscode = 500; + } + return new testRecord(statuscode, param1, param2, param3); + } +} diff --git a/libcobj/app/src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/testRecord.txt b/libcobj/app/src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/testRecord.txt new file mode 100644 index 00000000..93bfe2f0 --- /dev/null +++ b/libcobj/app/src/test/java/jp/osscons/opensourcecobol/libcobj/user_util/cobj_api/testRecord.txt @@ -0,0 +1,2 @@ +package com.example.restservice; +public record testRecord(int statuscode, int param1, double param2, String param3) {} diff --git a/libcobj/bin/cobj-api b/libcobj/bin/cobj-api new file mode 100644 index 00000000..15916733 --- /dev/null +++ b/libcobj/bin/cobj-api @@ -0,0 +1,3 @@ +#!/bin/bash + +java jp.osscons.opensourcecobol.libcobj.user_util.cobj_api.ApiFiles $@ \ No newline at end of file diff --git a/libcobj/settings.gradle.kts b/libcobj/settings.gradle.kts index 33b2d4d6..6bf139b3 100644 --- a/libcobj/settings.gradle.kts +++ b/libcobj/settings.gradle.kts @@ -4,3 +4,4 @@ plugins { rootProject.name = "opensourcecobol4j" include("app") +include("cobj-api")