diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/loaders/AbstractMetaDataLoader.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/loaders/AbstractMetaDataLoader.java index 3539bca5..dc4df863 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/loaders/AbstractMetaDataLoader.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/loaders/AbstractMetaDataLoader.java @@ -31,21 +31,17 @@ import java.lang.reflect.Type; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import com.fasterxml.jackson.core.type.TypeReference; -import com.kingsrook.qqq.backend.core.instances.loaders.implementations.QTableMetaDataLoader; import com.kingsrook.qqq.backend.core.logging.QLogger; import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.core.model.metadata.QMetaDataObject; -import com.kingsrook.qqq.backend.core.utils.ClassPathUtils; import com.kingsrook.qqq.backend.core.utils.JsonUtils; import com.kingsrook.qqq.backend.core.utils.StringUtils; -import com.kingsrook.qqq.backend.core.utils.ValueUtils; import com.kingsrook.qqq.backend.core.utils.YamlUtils; import org.apache.commons.io.IOUtils; import static com.kingsrook.qqq.backend.core.utils.ValueUtils.getValueAsBoolean; @@ -61,33 +57,6 @@ public abstract class AbstractMetaDataLoader { private static final QLogger LOG = QLogger.getLogger(AbstractMetaDataLoader.class); - private static Map, Class>> registeredLoaders = new HashMap<>(); - - static - { - try - { - List> classesInPackage = ClassPathUtils.getClassesInPackage(QTableMetaDataLoader.class.getPackageName()); - for(Class loaderClass : classesInPackage) - { - Type superClass = loaderClass.getGenericSuperclass(); - if(superClass.getTypeName().startsWith(AbstractMetaDataLoader.class.getName() + "<")) - // if(superClass instanceof Class c && AbstractMetaDataLoader.class.isAssignableFrom(c)) - { - Type actualTypeArgument = ((ParameterizedType) superClass).getActualTypeArguments()[0]; - Class metaDataObjectType = Class.forName(actualTypeArgument.getTypeName()); - registeredLoaders.put(metaDataObjectType, (Class>) loaderClass); - } - } - - System.out.println("Registered loaders: " + registeredLoaders); - } - catch(Exception e) - { - LOG.error("Error in static init block for AbstractMetaDataLoader", e); - } - } - private String fileName; @@ -185,7 +154,7 @@ public abstract class AbstractMetaDataLoader /*************************************************************************** * ***************************************************************************/ - private Object reflectivelyMapValue(QInstance qInstance, Method method, Class parameterType, Object rawValue) throws Exception + public Object reflectivelyMapValue(QInstance qInstance, Method method, Class parameterType, Object rawValue) throws Exception { if(parameterType.equals(String.class)) { @@ -212,8 +181,7 @@ public abstract class AbstractMetaDataLoader Type actualTypeArgument = ((ParameterizedType) method.getGenericParameterTypes()[0]).getActualTypeArguments()[0]; Class actualTypeClass = Class.forName(actualTypeArgument.getTypeName()); - Object value = rawValue; - if(value instanceof List valueList) + if(rawValue instanceof @SuppressWarnings("rawtypes")List valueList) { List mappedValueList = new ArrayList<>(); for(Object o : valueList) @@ -233,11 +201,10 @@ public abstract class AbstractMetaDataLoader } else if(parameterType.equals(Set.class)) { - Type actualTypeArgument = ((ParameterizedType) method.getGenericParameterTypes()[0]).getActualTypeArguments()[0]; - Class actualTypeClass = Class.forName(actualTypeArgument.getTypeName()); + Type actualTypeArgument = ((ParameterizedType) method.getGenericParameterTypes()[0]).getActualTypeArguments()[0]; + Class actualTypeClass = Class.forName(actualTypeArgument.getTypeName()); - Object value = rawValue; - if(value instanceof List valueList) + if(rawValue instanceof @SuppressWarnings("rawtypes")List valueList) { Set mappedValueSet = new LinkedHashSet<>(); for(Object o : valueList) @@ -268,16 +235,16 @@ public abstract class AbstractMetaDataLoader Type actualTypeArgument = ((ParameterizedType) method.getGenericParameterTypes()[0]).getActualTypeArguments()[1]; Class actualTypeClass = Class.forName(actualTypeArgument.getTypeName()); - Object value = rawValue; - if(value instanceof Map valueMap) + if(rawValue instanceof @SuppressWarnings("rawtypes")Map valueMap) { Map mappedValueMap = new LinkedHashMap<>(); for(Object o : valueMap.entrySet()) { try { - Map.Entry entry = (Map.Entry) o; - Object mappedValue = reflectivelyMapValue(qInstance, null, actualTypeClass, entry.getValue()); + @SuppressWarnings("unchecked") + Map.Entry entry = (Map.Entry) o; + Object mappedValue = reflectivelyMapValue(qInstance, null, actualTypeClass, entry.getValue()); mappedValueMap.put(entry.getKey(), mappedValue); } catch(NoValueException nve) @@ -299,23 +266,22 @@ public abstract class AbstractMetaDataLoader } } } - else if(registeredLoaders.containsKey(parameterType)) + else if(MetaDataLoaderRegistry.hasLoaderForClass(parameterType)) { - Object value = rawValue; - if(value instanceof Map valueMap) + if(rawValue instanceof @SuppressWarnings("rawtypes")Map valueMap) { - Class> loaderClass = registeredLoaders.get(parameterType); + Class> loaderClass = MetaDataLoaderRegistry.getLoaderForClass(parameterType); AbstractMetaDataLoader loader = loaderClass.getConstructor().newInstance(); - QMetaDataObject loadedValue = loader.mapToMetaDataObject(qInstance, valueMap); - return (loadedValue); + //noinspection unchecked + return (loader.mapToMetaDataObject(qInstance, valueMap)); } } else if(QMetaDataObject.class.isAssignableFrom(parameterType)) { - Object value = rawValue; - if(value instanceof Map valueMap) + if(rawValue instanceof @SuppressWarnings("rawtypes")Map valueMap) { QMetaDataObject childObject = (QMetaDataObject) parameterType.getConstructor().newInstance(); + //noinspection unchecked reflectivelyMap(qInstance, childObject, valueMap); return (childObject); } @@ -340,117 +306,96 @@ public abstract class AbstractMetaDataLoader throw new NoValueException(); } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // unclear if the below is needed. if so, useful to not re-write, but is hurting test coverage, so zombie until used // + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ///*************************************************************************** + // * + // ***************************************************************************/ + //protected ListOfMapOrMapOfMap getListOfMapOrMapOfMap(Map map, String key) + //{ + // if(map.containsKey(key)) + // { + // if(map.get(key) instanceof List) + // { + // return (new ListOfMapOrMapOfMap((List>) map.get(key))); + // } + // else if(map.get(key) instanceof Map) + // { + // return (new ListOfMapOrMapOfMap((Map>) map.get(key))); + // } + // else + // { + // LOG.warn("Expected list or map under key [" + key + "] while processing [" + getClass().getSimpleName() + "] from [" + fileName + "], but found: " + (map.get(key) == null ? "null" : map.get(key).getClass().getSimpleName())); + // } + // } + // return (null); + //} - /*************************************************************************** - * - ***************************************************************************/ - protected ListOfMapOrMapOfMap getListOfMapOrMapOfMap(Map map, String key) - { - if(map.containsKey(key)) - { - if(map.get(key) instanceof List) - { - return (new ListOfMapOrMapOfMap((List>) map.get(key))); - } - else if(map.get(key) instanceof Map) - { - return (new ListOfMapOrMapOfMap((Map>) map.get(key))); - } - else - { - LOG.warn("Expected list or map under key [" + key + "] while processing [" + getClass().getSimpleName() + "] from [" + fileName + "], but found: " + (map.get(key) == null ? "null" : map.get(key).getClass().getSimpleName())); - } - } + ///*************************************************************************** + // * + // ***************************************************************************/ + //protected List> getListOfMap(Map map, String key) + //{ + // if(map.containsKey(key)) + // { + // if(map.get(key) instanceof List) + // { + // return (List>) map.get(key); + // } + // else + // { + // LOG.warn("Expected list under key [" + key + "] while processing [" + getClass().getSimpleName() + "] from [" + fileName + "], but found: " + (map.get(key) == null ? "null" : map.get(key).getClass().getSimpleName())); + // } + // } - return (null); - } + // return (null); + //} + ///*************************************************************************** + // * + // ***************************************************************************/ + //protected Map> getMapOfMap(Map map, String key) + //{ + // if(map.containsKey(key)) + // { + // if(map.get(key) instanceof Map) + // { + // return (Map>) map.get(key); + // } + // else + // { + // LOG.warn("Expected map under key [" + key + "] while processing [" + getClass().getSimpleName() + "] from [" + fileName + "], but found: " + (map.get(key) == null ? "null" : map.get(key).getClass().getSimpleName())); + // } + // } + // return (null); + //} - /*************************************************************************** - * - ***************************************************************************/ - protected List> getListOfMap(Map map, String key) - { - if(map.containsKey(key)) - { - if(map.get(key) instanceof List) - { - return (List>) map.get(key); - } - else - { - LOG.warn("Expected list under key [" + key + "] while processing [" + getClass().getSimpleName() + "] from [" + fileName + "], but found: " + (map.get(key) == null ? "null" : map.get(key).getClass().getSimpleName())); - } - } + ///*************************************************************************** + // ** + // ***************************************************************************/ + //protected record ListOfMapOrMapOfMap(List> listOf, Map> mapOf) + //{ + // /******************************************************************************* + // ** Constructor + // ** + // *******************************************************************************/ + // public ListOfMapOrMapOfMap(List> listOf) + // { + // this(listOf, null); + // } - return (null); - } - - - - /*************************************************************************** - * - ***************************************************************************/ - protected Map> getMapOfMap(Map map, String key) - { - if(map.containsKey(key)) - { - if(map.get(key) instanceof Map) - { - return (Map>) map.get(key); - } - else - { - LOG.warn("Expected map under key [" + key + "] while processing [" + getClass().getSimpleName() + "] from [" + fileName + "], but found: " + (map.get(key) == null ? "null" : map.get(key).getClass().getSimpleName())); - } - } - - return (null); - } - - - - /*************************************************************************** - ** - ***************************************************************************/ - protected record ListOfMapOrMapOfMap(List> listOf, Map> mapOf) - { - /******************************************************************************* - ** Constructor - ** - *******************************************************************************/ - public ListOfMapOrMapOfMap(List> listOf) - { - this(listOf, null); - } - - - - /******************************************************************************* - ** Constructor - ** - *******************************************************************************/ - public ListOfMapOrMapOfMap(Map> mapOf) - { - this(null, mapOf); - } - - } - - - - /*************************************************************************** - ** - ***************************************************************************/ - protected void warnNotImplemented(Map map, String key) - { - if(StringUtils.hasContent(ValueUtils.getValueAsString(map.get(key)))) - { - LOG.warn("Unsupported meta-data attribute [" + key + "] found while processing [" + getClass().getSimpleName() + "] from [" + fileName + "]"); - } - } + // /******************************************************************************* + // ** Constructor + // ** + // *******************************************************************************/ + // public ListOfMapOrMapOfMap(Map> mapOf) + // { + // this(null, mapOf); + // } + //} diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/loaders/ClassDetectingMetaDataLoader.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/loaders/ClassDetectingMetaDataLoader.java index 8418b7eb..f5621bc3 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/loaders/ClassDetectingMetaDataLoader.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/loaders/ClassDetectingMetaDataLoader.java @@ -23,10 +23,12 @@ package com.kingsrook.qqq.backend.core.instances.loaders; import java.io.InputStream; +import java.util.List; import java.util.Map; -import com.kingsrook.qqq.backend.core.instances.loaders.implementations.QTableMetaDataLoader; +import com.kingsrook.qqq.backend.core.instances.loaders.implementations.GenericMetaDataLoader; import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.core.model.metadata.QMetaDataObject; +import com.kingsrook.qqq.backend.core.utils.ClassPathUtils; import com.kingsrook.qqq.backend.core.utils.ValueUtils; @@ -57,17 +59,42 @@ public class ClassDetectingMetaDataLoader extends AbstractMetaDataLoader loader = switch(classProperty) + try { - case "QTableMetaData" -> new QTableMetaDataLoader(); - // todo!! case "QTableMetaData" -> new QTableMetaDataLoader(); - default -> throw new QMetaDataLoaderException("Unexpected class [" + classProperty + "] specified in " + getFileName()); - }; - return (loader); + if(MetaDataLoaderRegistry.hasLoaderForSimpleName(classProperty)) + { + Class> loaderClass = MetaDataLoaderRegistry.getLoaderForSimpleName(classProperty); + return (loaderClass.getConstructor().newInstance()); + } + else + { + List> classesInPackage = ClassPathUtils.getClassesInPackage("com.kingsrook.qqq.backend.core.model"); + for(Class c : classesInPackage) + { + if(c.getSimpleName().equals(classProperty) && QMetaDataObject.class.isAssignableFrom(c)) + { + @SuppressWarnings("unchecked") + Class metaDataClass = (Class) c; + return new GenericMetaDataLoader<>(metaDataClass); + } + } + } + throw new QMetaDataLoaderException("Unexpected class [" + classProperty + "] (not a QMetaDataObject; doesn't have a registered MetaDataLoader) specified in " + getFileName()); + } + catch(QMetaDataLoaderException qmdle) + { + throw (qmdle); + } + catch(Exception e) + { + throw new QMetaDataLoaderException("Error handling class [" + classProperty + "] specified in " + getFileName(), e); + } + } + else + { + throw new QMetaDataLoaderException("Cannot detect meta-data type, because [class] attribute was not specified in file: " + getFileName()); } - - throw new QMetaDataLoaderException("Cannot detect meta-data type, because [class] attribute was not specified in file: " + getFileName()); } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/loaders/MetaDataLoaderRegistry.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/loaders/MetaDataLoaderRegistry.java new file mode 100644 index 00000000..ece2d6ed --- /dev/null +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/loaders/MetaDataLoaderRegistry.java @@ -0,0 +1,99 @@ +package com.kingsrook.qqq.backend.core.instances.loaders; + + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import com.kingsrook.qqq.backend.core.instances.loaders.implementations.QTableMetaDataLoader; +import com.kingsrook.qqq.backend.core.logging.QLogger; +import com.kingsrook.qqq.backend.core.utils.ClassPathUtils; + + +/******************************************************************************* + ** + *******************************************************************************/ +public class MetaDataLoaderRegistry +{ + private static final QLogger LOG = QLogger.getLogger(AbstractMetaDataLoader.class); + + private static final Map, Class>> registeredLoaders = new HashMap<>(); + private static final Map>> registeredLoadersByTargetSimpleName = new HashMap<>(); + + static + { + try + { + List> classesInPackage = ClassPathUtils.getClassesInPackage(QTableMetaDataLoader.class.getPackageName()); + for(Class possibleLoaderClass : classesInPackage) + { + try + { + Type superClass = possibleLoaderClass.getGenericSuperclass(); + if(superClass.getTypeName().startsWith(AbstractMetaDataLoader.class.getName() + "<")) + { + Type actualTypeArgument = ((ParameterizedType) superClass).getActualTypeArguments()[0]; + if(actualTypeArgument instanceof Class) + { + //noinspection unchecked + Class> loaderClass = (Class>) possibleLoaderClass; + + Class metaDataObjectType = Class.forName(actualTypeArgument.getTypeName()); + registeredLoaders.put(metaDataObjectType, loaderClass); + registeredLoadersByTargetSimpleName.put(metaDataObjectType.getSimpleName(), loaderClass); + } + } + } + catch(Exception e) + { + LOG.info("Error on class: " + possibleLoaderClass, e); + } + } + + System.out.println("Registered loaders: " + registeredLoadersByTargetSimpleName); + } + catch(Exception e) + { + LOG.error("Error in static init block for MetaDataLoaderRegistry", e); + } + } + + /*************************************************************************** + ** + ***************************************************************************/ + public static boolean hasLoaderForClass(Class metaDataClass) + { + return registeredLoaders.containsKey(metaDataClass); + } + + + + /*************************************************************************** + ** + ***************************************************************************/ + public static Class> getLoaderForClass(Class metaDataClass) + { + return registeredLoaders.get(metaDataClass); + } + + + + /*************************************************************************** + ** + ***************************************************************************/ + public static boolean hasLoaderForSimpleName(String targetSimpleName) + { + return registeredLoadersByTargetSimpleName.containsKey(targetSimpleName); + } + + + + /*************************************************************************** + ** + ***************************************************************************/ + public static Class> getLoaderForSimpleName(String targetSimpleName) + { + return registeredLoadersByTargetSimpleName.get(targetSimpleName); + } +} diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/loaders/implementations/GenericMetaDataLoader.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/loaders/implementations/GenericMetaDataLoader.java new file mode 100644 index 00000000..20440c9a --- /dev/null +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/instances/loaders/implementations/GenericMetaDataLoader.java @@ -0,0 +1,70 @@ +/* + * 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.backend.core.instances.loaders.implementations; + + +import java.util.Map; +import com.kingsrook.qqq.backend.core.instances.loaders.AbstractMetaDataLoader; +import com.kingsrook.qqq.backend.core.instances.loaders.QMetaDataLoaderException; +import com.kingsrook.qqq.backend.core.model.metadata.QInstance; +import com.kingsrook.qqq.backend.core.model.metadata.QMetaDataObject; + + +/******************************************************************************* + ** + *******************************************************************************/ +public class GenericMetaDataLoader extends AbstractMetaDataLoader +{ + private final Class metaDataClass; + + + + /******************************************************************************* + ** Constructor + ** + *******************************************************************************/ + public GenericMetaDataLoader(Class metaDataClass) + { + this.metaDataClass = metaDataClass; + } + + + + /*************************************************************************** + ** + ***************************************************************************/ + @Override + public T mapToMetaDataObject(QInstance qInstance, Map map) throws QMetaDataLoaderException + { + try + { + T object = metaDataClass.getConstructor().newInstance(); + reflectivelyMap(qInstance, object, map); + return (object); + } + catch(Exception e) + { + throw (new QMetaDataLoaderException("Error loading metaData object of type " + metaDataClass.getSimpleName(), e)); + } + } + +} diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/instances/loaders/ClassDetectingMetaDataLoaderTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/instances/loaders/ClassDetectingMetaDataLoaderTest.java index 7eaceb68..ea6cc23b 100644 --- a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/instances/loaders/ClassDetectingMetaDataLoaderTest.java +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/instances/loaders/ClassDetectingMetaDataLoaderTest.java @@ -26,6 +26,7 @@ import java.nio.charset.StandardCharsets; import com.kingsrook.qqq.backend.core.BaseTest; import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.core.model.metadata.QMetaDataObject; +import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.Test; @@ -50,11 +51,33 @@ class ClassDetectingMetaDataLoaderTest extends BaseTest class: QTableMetaData version: 1 name: myTable + backendName: someBackend """, StandardCharsets.UTF_8), "myTable.yaml"); assertThat(qMetaDataObject).isInstanceOf(QTableMetaData.class); QTableMetaData qTableMetaData = (QTableMetaData) qMetaDataObject; assertEquals("myTable", qTableMetaData.getName()); + assertEquals("someBackend", qTableMetaData.getBackendName()); + } + + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testProcess() throws QMetaDataLoaderException + { + QMetaDataObject qMetaDataObject = new ClassDetectingMetaDataLoader().fileToMetaDataObject(new QInstance(), IOUtils.toInputStream(""" + class: QProcessMetaData + version: 1 + name: myProcess + tableName: someTable + """, StandardCharsets.UTF_8), "myProcess.yaml"); + + assertThat(qMetaDataObject).isInstanceOf(QProcessMetaData.class); + QProcessMetaData qProcessMetaData = (QProcessMetaData) qMetaDataObject; + assertEquals("myProcess", qProcessMetaData.getName()); + assertEquals("someTable", qProcessMetaData.getTableName()); } diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/instances/loaders/QTableMetaDataLoaderTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/instances/loaders/QTableMetaDataLoaderTest.java index 40ecc39d..7c6aa370 100644 --- a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/instances/loaders/QTableMetaDataLoaderTest.java +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/instances/loaders/QTableMetaDataLoaderTest.java @@ -24,6 +24,7 @@ package com.kingsrook.qqq.backend.core.instances.loaders; import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.Set; import com.kingsrook.qqq.backend.core.BaseTest; import com.kingsrook.qqq.backend.core.actions.customizers.TableCustomizers; import com.kingsrook.qqq.backend.core.context.QContext; @@ -33,6 +34,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeType; import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldType; import com.kingsrook.qqq.backend.core.model.metadata.permissions.DenyBehavior; import com.kingsrook.qqq.backend.core.model.metadata.permissions.PermissionLevel; +import com.kingsrook.qqq.backend.core.model.metadata.tables.Capability; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.utils.TestUtils; import com.kingsrook.qqq.backend.core.utils.YamlUtils; @@ -113,6 +115,9 @@ class QTableMetaDataLoaderTest extends BaseTest preDeleteRecord: name: com.kingsrook.SomePreDelete codeType: JAVA + disabledCapabilities: + - TABLE_COUNT + - QUERY_STATS """, StandardCharsets.UTF_8), "myTable.yaml"); assertEquals("myTable", table.getName()); @@ -145,6 +150,8 @@ class QTableMetaDataLoaderTest extends BaseTest assertEquals(2, table.getCustomizers().size()); assertEquals("com.kingsrook.SomePostQuery", table.getCustomizers().get(TableCustomizers.POST_QUERY_RECORD.getRole()).getName()); assertEquals("com.kingsrook.SomePreDelete", table.getCustomizers().get(TableCustomizers.PRE_DELETE_RECORD.getRole()).getName()); + + assertEquals(Set.of(Capability.TABLE_COUNT, Capability.QUERY_STATS), table.getDisabledCapabilities()); } diff --git a/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/instances/loaders/implementations/GenericMetaDataLoaderTest.java b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/instances/loaders/implementations/GenericMetaDataLoaderTest.java new file mode 100644 index 00000000..e4d3b4e7 --- /dev/null +++ b/qqq-backend-core/src/test/java/com/kingsrook/qqq/backend/core/instances/loaders/implementations/GenericMetaDataLoaderTest.java @@ -0,0 +1,59 @@ +package com.kingsrook.qqq.backend.core.instances.loaders.implementations; + + +import java.nio.charset.StandardCharsets; +import com.kingsrook.qqq.backend.core.BaseTest; +import com.kingsrook.qqq.backend.core.instances.loaders.QMetaDataLoaderException; +import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.QInstance; +import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + + +/******************************************************************************* + ** Unit test for GenericMetaDataLoader - providing coverage for AbstractMetaDataLoader. + *******************************************************************************/ +class GenericMetaDataLoaderTest extends BaseTest +{ + + /******************************************************************************* + ** + *******************************************************************************/ + @Test + void testProcess() throws QMetaDataLoaderException + { + //////////////////////////////////////////////////////////////////////////////// + // trying to get some coverage of various types in here (for Abstract loader) // + //////////////////////////////////////////////////////////////////////////////// + QProcessMetaData process = new GenericMetaDataLoader<>(QProcessMetaData.class).fileToMetaDataObject(new QInstance(), IOUtils.toInputStream(""" + class: QProcessMetaData + version: 1 + name: myProcess + tableName: someTable + maxInputRecords: 1 + isHidden: true + """, StandardCharsets.UTF_8), "myProcess.yaml"); + + assertEquals("myProcess", process.getName()); + assertEquals("someTable", process.getTableName()); + assertEquals(1, process.getMaxInputRecords()); + assertTrue(process.getIsHidden()); + } + + + + /******************************************************************************* + ** just here for coverage of this class, as we're failing to hit it otherwise. + *******************************************************************************/ + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Test + void testNoValueException() + { + assertThatThrownBy(() -> new GenericMetaDataLoader(QBackendMetaData.class).reflectivelyMapValue(new QInstance(), null, GenericMetaDataLoaderTest.class, "rawValue")); + } + +} \ No newline at end of file