diff --git a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/SchemaBuilder.java b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/SchemaBuilder.java
new file mode 100644
index 00000000..5ea0912b
--- /dev/null
+++ b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/SchemaBuilder.java
@@ -0,0 +1,300 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2024. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.middleware.javalin.schemabuilder;
+
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.stream.Collectors;
+import com.kingsrook.qqq.backend.core.exceptions.QRuntimeException;
+import com.kingsrook.qqq.backend.core.utils.StringUtils;
+import com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations.OpenAPIDescription;
+import com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations.OpenAPIExclude;
+import com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations.OpenAPIHasAdditionalProperties;
+import com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations.OpenAPIIncludeProperties;
+import com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations.OpenAPIListItems;
+import com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations.OpenAPIMapKnownEntries;
+import com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations.OpenAPIMapValueType;
+import com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations.OpenAPIOneOf;
+import com.kingsrook.qqq.openapi.model.Schema;
+import com.kingsrook.qqq.openapi.model.Type;
+
+
+/*******************************************************************************
+ ** This class facilitates generating OpenAPI Schema objects based on reflectively
+ ** reading classes and annotations
+ *******************************************************************************/
+public class SchemaBuilder
+{
+
+ /***************************************************************************
+ **
+ ***************************************************************************/
+ public Schema classToSchema(Class> c)
+ {
+ return classToSchema(c, c);
+ }
+
+
+
+ /***************************************************************************
+ **
+ ***************************************************************************/
+ private Schema classToSchema(Class> c, AnnotatedElement element)
+ {
+ Schema schema = new Schema();
+
+ if(c.isEnum())
+ {
+ schema.withType(Type.STRING);
+ schema.withEnumValues(Arrays.stream(c.getEnumConstants()).map(e -> String.valueOf(e)).collect(Collectors.toList()));
+ }
+ else if(c.equals(String.class))
+ {
+ schema.withType(Type.STRING);
+ }
+ else if(c.equals(Integer.class) || c.equals(BigDecimal.class))
+ {
+ schema.withType(Type.NUMBER);
+ }
+ else if(c.equals(Boolean.class))
+ {
+ schema.withType(Type.BOOLEAN);
+ }
+ else if(c.equals(List.class))
+ {
+ schema.withType(Type.ARRAY);
+ // Class> itemType = field.getType().getTypeParameters()[0].getBounds().getClass();
+
+ OpenAPIListItems openAPIListItemsAnnotation = element.getAnnotation(OpenAPIListItems.class);
+ if(openAPIListItemsAnnotation == null)
+ {
+ // todo - can this be allowed, to make a generic list? maybe.
+ // throw (new QRuntimeException("A List field [" + field.getName() + "] was missing its @OpenAPIItems annotation"));
+ }
+ else
+ {
+ if(openAPIListItemsAnnotation.useRef())
+ {
+ schema.withItems(new Schema().withRef("#/components/schemas/" + openAPIListItemsAnnotation.value().getSimpleName()));
+ }
+ else
+ {
+ Class> itemType = openAPIListItemsAnnotation.value();
+ schema.withItems(classToSchema(itemType));
+ }
+ }
+ }
+ else if(c.equals(Map.class))
+ {
+ schema.withType(Type.OBJECT);
+
+ OpenAPIMapKnownEntries openAPIMapKnownEntriesAnnotation = element.getAnnotation(OpenAPIMapKnownEntries.class);
+ if(openAPIMapKnownEntriesAnnotation != null)
+ {
+ schema.withRef("#/components/schemas/" + openAPIMapKnownEntriesAnnotation.value().getSimpleName());
+// if(openAPIMapKnownEntriesAnnotation.additionalProperties())
+// {
+// schema.withAdditionalProperties(true);
+// }
+ }
+
+ OpenAPIMapValueType openAPIMapValueTypeAnnotation = element.getAnnotation(OpenAPIMapValueType.class);
+ if(openAPIMapValueTypeAnnotation != null)
+ {
+ if(openAPIMapValueTypeAnnotation.useRef())
+ {
+ schema.withAdditionalProperties(new Schema().withRef("#/components/schemas/" + openAPIMapValueTypeAnnotation.value().getSimpleName()));
+ }
+ else
+ {
+ schema.withAdditionalProperties(classToSchema(openAPIMapValueTypeAnnotation.value()));
+ }
+ }
+ }
+ else
+ {
+ OpenAPIOneOf openAPIOneOfAnnotation = element.getAnnotation(OpenAPIOneOf.class);
+ if(openAPIOneOfAnnotation != null)
+ {
+ String description = "[" + element + "]";
+ List oneOfList = processOneOfAnnotation(openAPIOneOfAnnotation, c, description);
+ schema.withOneOf(oneOfList);
+ }
+ else
+ {
+ /////////////////////////////////////////////////////////////////////////////////////////////
+ // else, if not a one-of then assume the schema is an object, and build out its properties //
+ /////////////////////////////////////////////////////////////////////////////////////////////
+ schema.withType(Type.OBJECT);
+
+ Map properties = new TreeMap<>();
+ schema.withProperties(properties);
+
+ //////////////////////////////////////////////////////////////////////////////////////////
+ // if we're told to includeProperties (e.g., from ancestor classes), then go find those //
+ //////////////////////////////////////////////////////////////////////////////////////////
+ OpenAPIIncludeProperties openAPIIncludePropertiesAnnotation = c.getAnnotation(OpenAPIIncludeProperties.class);
+ if(openAPIIncludePropertiesAnnotation != null)
+ {
+ Set> ancestorClasses = Arrays.stream(openAPIIncludePropertiesAnnotation.ancestorClasses()).collect(Collectors.toSet());
+ Class> superClass = c.getSuperclass();
+ do
+ {
+ if(ancestorClasses.contains(superClass))
+ {
+ addDeclaredFieldsToProperties(superClass, properties);
+ addDeclaredMethodsToProperties(superClass, properties);
+ }
+ superClass = superClass.getSuperclass();
+ }
+ while(superClass != null);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // make all declared-fields and getters in the class into properties //
+ ///////////////////////////////////////////////////////////////////////
+ addDeclaredFieldsToProperties(c, properties);
+ addDeclaredMethodsToProperties(c, properties);
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+ // now (after schema may have been replaced, e.g., in a recursive call), add more details to it //
+ //////////////////////////////////////////////////////////////////////////////////////////////////
+ OpenAPIDescription openAPIDescriptionAnnotation = element.getAnnotation(OpenAPIDescription.class);
+ if(openAPIDescriptionAnnotation != null)
+ {
+ schema.setDescription(openAPIDescriptionAnnotation.value());
+ }
+
+ if(element.isAnnotationPresent(OpenAPIHasAdditionalProperties.class))
+ {
+ schema.withAdditionalProperties(true);
+ }
+
+ return (schema);
+ }
+
+
+
+ /***************************************************************************
+ ** Getter methods with an annotation
+ ***************************************************************************/
+ private void addDeclaredMethodsToProperties(Class> c, Map properties)
+ {
+ for(Method method : c.getDeclaredMethods())
+ {
+ OpenAPIDescription methodDescription = method.getAnnotation(OpenAPIDescription.class);
+ OpenAPIExclude openAPIExclude = method.getAnnotation(OpenAPIExclude.class);
+ if(method.getName().startsWith("get") && method.getParameterCount() == 0 && methodDescription != null && openAPIExclude == null)
+ {
+ String name = StringUtils.lcFirst(method.getName().substring(3));
+ properties.put(name, getMemberSchema(method));
+ }
+ }
+ }
+
+
+
+ /***************************************************************************
+ **
+ ***************************************************************************/
+ private void addDeclaredFieldsToProperties(Class> c, Map properties)
+ {
+ for(Field declaredField : c.getDeclaredFields())
+ {
+ OpenAPIExclude openAPIExclude = declaredField.getAnnotation(OpenAPIExclude.class);
+ if(openAPIExclude == null)
+ {
+ properties.put(declaredField.getName(), getMemberSchema(declaredField));
+ }
+ }
+ }
+
+
+
+ /***************************************************************************
+ **
+ ***************************************************************************/
+ private Schema getMemberSchema(AccessibleObject member)
+ {
+ Class> type;
+ if(member instanceof Field field)
+ {
+ type = field.getType();
+ }
+ else if(member instanceof Method method)
+ {
+ type = method.getReturnType();
+ }
+ else
+ {
+ throw (new IllegalArgumentException("Unsupported AccessibleObject: " + member));
+ }
+
+ return (classToSchema(type, member));
+ }
+
+
+
+ /***************************************************************************
+ **
+ ***************************************************************************/
+ private List processOneOfAnnotation(OpenAPIOneOf openAPIOneOfAnnotation, Class> type, String description)
+ {
+ List oneOfList = new ArrayList<>();
+
+ if(openAPIOneOfAnnotation.mode().equals(OpenAPIOneOf.Mode.PERMITTED_SUBCLASSES))
+ {
+ Class>[] permittedSubclasses = type.getPermittedSubclasses();
+ for(Class> permittedSubclass : permittedSubclasses)
+ {
+ oneOfList.add(classToSchema(permittedSubclass));
+ }
+ }
+ else if(openAPIOneOfAnnotation.mode().equals(OpenAPIOneOf.Mode.SPECIFIED_LIST))
+ {
+ for(Class> oneOfClass : openAPIOneOfAnnotation.options())
+ {
+ oneOfList.add(classToSchema(oneOfClass));
+ }
+ }
+
+ if(oneOfList.isEmpty())
+ {
+ throw (new QRuntimeException("Could not find any options to use for an @OpenAPIOneOf annotation on " + description));
+ }
+ return oneOfList;
+ }
+
+
+}
diff --git a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIDescription.java b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIDescription.java
new file mode 100644
index 00000000..7fc5aad4
--- /dev/null
+++ b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIDescription.java
@@ -0,0 +1,39 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2024. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/***************************************************************************
+ **
+ ***************************************************************************/
+@Target({ ElementType.FIELD, ElementType.TYPE, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OpenAPIDescription
+{
+ String value();
+}
diff --git a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIEnumSubSet.java b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIEnumSubSet.java
new file mode 100644
index 00000000..a7954b8d
--- /dev/null
+++ b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIEnumSubSet.java
@@ -0,0 +1,52 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2024. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.EnumSet;
+
+
+/*******************************************************************************
+ **
+ *******************************************************************************/
+@Target({ ElementType.FIELD, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OpenAPIEnumSubSet
+{
+ Class extends EnumSubSet>> value();
+
+
+ /***************************************************************************
+ **
+ ***************************************************************************/
+ interface EnumSubSet>
+ {
+ /***************************************************************************
+ **
+ ***************************************************************************/
+ EnumSet getSubSet();
+ }
+}
diff --git a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIExclude.java b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIExclude.java
new file mode 100644
index 00000000..de6d6039
--- /dev/null
+++ b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIExclude.java
@@ -0,0 +1,38 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2024. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/*******************************************************************************
+ **
+ *******************************************************************************/
+@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OpenAPIExclude
+{
+}
diff --git a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIHasAdditionalProperties.java b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIHasAdditionalProperties.java
new file mode 100644
index 00000000..a7a1fa19
--- /dev/null
+++ b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIHasAdditionalProperties.java
@@ -0,0 +1,38 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2024. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/*******************************************************************************
+ **
+ *******************************************************************************/
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OpenAPIHasAdditionalProperties
+{
+}
diff --git a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIIncludeProperties.java b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIIncludeProperties.java
new file mode 100644
index 00000000..956e9c1f
--- /dev/null
+++ b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIIncludeProperties.java
@@ -0,0 +1,39 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2024. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/***************************************************************************
+ **
+ ***************************************************************************/
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OpenAPIIncludeProperties
+{
+ Class>[] ancestorClasses() default { };
+}
diff --git a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIListItems.java b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIListItems.java
new file mode 100644
index 00000000..e496a415
--- /dev/null
+++ b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIListItems.java
@@ -0,0 +1,41 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2024. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/***************************************************************************
+ **
+ ***************************************************************************/
+@Target({ ElementType.FIELD, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OpenAPIListItems
+{
+ Class> value();
+
+ boolean useRef() default false;
+}
diff --git a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIMapKnownEntries.java b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIMapKnownEntries.java
new file mode 100644
index 00000000..41fd2cd2
--- /dev/null
+++ b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIMapKnownEntries.java
@@ -0,0 +1,41 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2024. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/***************************************************************************
+ **
+ ***************************************************************************/
+@Target({ ElementType.FIELD, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OpenAPIMapKnownEntries
+{
+ Class> value();
+
+ boolean useRef() default false;
+}
diff --git a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIMapValueType.java b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIMapValueType.java
new file mode 100644
index 00000000..af52a3e9
--- /dev/null
+++ b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIMapValueType.java
@@ -0,0 +1,41 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2024. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/***************************************************************************
+ **
+ ***************************************************************************/
+@Target({ ElementType.FIELD, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OpenAPIMapValueType
+{
+ Class> value();
+
+ boolean useRef() default false;
+}
diff --git a/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIOneOf.java b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIOneOf.java
new file mode 100644
index 00000000..3cc65bf1
--- /dev/null
+++ b/qqq-middleware-javalin/src/main/java/com/kingsrook/qqq/middleware/javalin/schemabuilder/annotations/OpenAPIOneOf.java
@@ -0,0 +1,51 @@
+/*
+ * QQQ - Low-code Application Framework for Engineers.
+ * Copyright (C) 2021-2024. Kingsrook, LLC
+ * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
+ * contact@kingsrook.com
+ * https://github.com/Kingsrook/
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.kingsrook.qqq.middleware.javalin.schemabuilder.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+
+/***************************************************************************
+ **
+ ***************************************************************************/
+@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OpenAPIOneOf
+{
+ Mode mode() default Mode.PERMITTED_SUBCLASSES;
+
+ Class>[] options() default { };
+
+
+ /***************************************************************************
+ **
+ ***************************************************************************/
+ enum Mode
+ {
+ PERMITTED_SUBCLASSES,
+ SPECIFIED_LIST
+ }
+}