diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/utils/collections/ListBuilder.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/utils/collections/ListBuilder.java index 6d7b3f7a..9e46aa42 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/utils/collections/ListBuilder.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/utils/collections/ListBuilder.java @@ -29,9 +29,60 @@ import java.util.List; /******************************************************************************* ** List.of is "great", but annoying because it makes unmodifiable lists... ** So, replace it with this, which returns ArrayLists, which "don't suck" + ** + ** Can use it 3 ways: + ** ListBuilder.of(value, value2, ...) => List (an ArrayList) + ** ListBuilder.of(SomeList::new).with(value).with(value2)...build() => SomeList (the type you specify) + ** new ListBuilder..with(value).with(value2)...build() => List (an ArrayList - for when you have more than 10 values...) *******************************************************************************/ -public class ListBuilder +public class ListBuilder { + private List list; + + + + /******************************************************************************* + ** Constructor + ** + *******************************************************************************/ + public ListBuilder() + { + this.list = new ArrayList<>(); + } + + + + /******************************************************************************* + ** Constructor + ** + *******************************************************************************/ + public ListBuilder(List list) + { + this.list = list; + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public ListBuilder with(E value) + { + list.add(value); + return (this); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public List build() + { + return (this.list); + } + + /******************************************************************************* ** diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/utils/collections/ListBuilderTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/utils/collections/ListBuilderTest.java index 23c44a78..f39be810 100644 --- a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/utils/collections/ListBuilderTest.java +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/utils/collections/ListBuilderTest.java @@ -22,6 +22,8 @@ package com.kingsrook.qqq.backend.core.utils.collections; +import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -69,4 +71,22 @@ class ListBuilderTest /////////////////////////////////////// list.add(4); } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testBuilderMode() + { + List builtList = new ListBuilder().with("A").with("B").build(); + assertEquals(List.of("A", "B"), builtList); + assertEquals(ArrayList.class, builtList.getClass()); + + List builtLinkedList = new ListBuilder(new LinkedList<>()).with("A").with("B").build(); + assertEquals(List.of("A", "B"), builtLinkedList); + assertEquals(LinkedList.class, builtLinkedList.getClass()); + } + } \ No newline at end of file diff --git a/qqq-middleware-api/src/main/java/com/kingsrook/qqq/api/javalin/QJavalinApiHandler.java b/qqq-middleware-api/src/main/java/com/kingsrook/qqq/api/javalin/QJavalinApiHandler.java index f7357b3a..e5fdfa5a 100644 --- a/qqq-middleware-api/src/main/java/com/kingsrook/qqq/api/javalin/QJavalinApiHandler.java +++ b/qqq-middleware-api/src/main/java/com/kingsrook/qqq/api/javalin/QJavalinApiHandler.java @@ -162,6 +162,8 @@ public class QJavalinApiHandler ApiBuilder.get("/api/docs/js/rapidoc.min.js", (context) -> QJavalinApiHandler.serveResource(context, "rapidoc/rapidoc-9.3.4.min.js", MapBuilder.of("Content-Type", ContentType.JAVASCRIPT))); ApiBuilder.get("/api/docs/css/qqq-api-styles.css", (context) -> QJavalinApiHandler.serveResource(context, "rapidoc/rapidoc-overrides.css", MapBuilder.of("Content-Type", ContentType.CSS))); + ApiBuilder.get("/apis.json", QJavalinApiHandler::doGetApisJson); + ApiInstanceMetaDataContainer apiInstanceMetaDataContainer = ApiInstanceMetaDataContainer.of(qInstance); for(Map.Entry entry : apiInstanceMetaDataContainer.getApis().entrySet()) { @@ -172,6 +174,7 @@ public class QJavalinApiHandler // default page is the current version spec // ////////////////////////////////////////////// ApiBuilder.get(rootPath, context -> doSpecHtml(context, apiInstanceMetaData)); + ApiBuilder.get(rootPath + "versions.json", context -> doVersions(context, apiInstanceMetaData)); ApiBuilder.path(rootPath + "{version}", () -> { @@ -248,7 +251,61 @@ public class QJavalinApiHandler /******************************************************************************* - ** + ** list the apis supported in this instance + *******************************************************************************/ + private static void doGetApisJson(Context context) + { + Map rs = new HashMap<>(); + List> apis = new ArrayList<>(); + rs.put("apis", apis); + + ApiInstanceMetaDataContainer apiInstanceMetaDataContainer = ApiInstanceMetaDataContainer.of(qInstance); + for(Map.Entry entry : apiInstanceMetaDataContainer.getApis().entrySet()) + { + Map thisApi = new HashMap<>(); + + ApiInstanceMetaData apiInstanceMetaData = entry.getValue(); + thisApi.put("name", apiInstanceMetaData.getName()); + thisApi.put("path", apiInstanceMetaData.getPath()); + thisApi.put("label", apiInstanceMetaData.getLabel()); + + String tableName = context.queryParam("tableName"); + if(tableName != null) + { + QTableMetaData table = qInstance.getTable(tableName); + + /////////////////////////////////////////////////////////////// + // look for reasons we might exclude this api for this table // + /////////////////////////////////////////////////////////////// + ApiTableMetaDataContainer apiTableMetaDataContainer = ApiTableMetaDataContainer.of(table); + if(apiTableMetaDataContainer == null) + { + continue; + } + + ApiTableMetaData apiTableMetaData = apiTableMetaDataContainer.getApiTableMetaData(apiInstanceMetaData.getName()); + if(apiTableMetaData == null) + { + continue; + } + + if(BooleanUtils.isTrue(apiTableMetaData.getIsExcluded())) + { + continue; + } + } + + apis.add(thisApi); + } + + context.contentType(ContentType.APPLICATION_JSON); + context.result(JsonUtils.toJson(rs)); + } + + + + /******************************************************************************* + ** list the versions in this api *******************************************************************************/ private static void doVersions(Context context, ApiInstanceMetaData apiInstanceMetaData) { @@ -527,6 +584,7 @@ public class QJavalinApiHandler ///////////////////////////////// // do replacements in the html // ///////////////////////////////// + html = html.replace("{spec-url}", apiInstanceMetaData.getPath() + version + "/openapi.json"); html = html.replace("{version}", version); html = html.replace("{primaryColor}", branding == null ? "#FF791A" : branding.getAccentColor()); @@ -539,7 +597,7 @@ public class QJavalinApiHandler html = html.replace("{navLogoImg}", ""); } - html = html.replace("{title}", apiInstanceMetaData.getName() + " - " + version); + html = html.replace("{title}", apiInstanceMetaData.getLabel() + " - " + version); StringBuilder otherVersionOptions = new StringBuilder(); for(APIVersion supportedVersion : apiInstanceMetaData.getSupportedVersions()) diff --git a/qqq-middleware-api/src/main/resources/rapidoc/rapidoc-container.html b/qqq-middleware-api/src/main/resources/rapidoc/rapidoc-container.html index fe4dc03a..38c0b4c5 100644 --- a/qqq-middleware-api/src/main/resources/rapidoc/rapidoc-container.html +++ b/qqq-middleware-api/src/main/resources/rapidoc/rapidoc-container.html @@ -31,7 +31,7 @@