mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
Checkpoint - class-detecting loader handling generic loaders; generic loader created & working; Loader registry moved to its own class;
This commit is contained in:
@ -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<T extends QMetaDataObject>
|
||||
{
|
||||
private static final QLogger LOG = QLogger.getLogger(AbstractMetaDataLoader.class);
|
||||
|
||||
private static Map<Class<?>, Class<? extends AbstractMetaDataLoader<?>>> registeredLoaders = new HashMap<>();
|
||||
|
||||
static
|
||||
{
|
||||
try
|
||||
{
|
||||
List<Class<?>> 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<? extends AbstractMetaDataLoader<?>>) 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<T extends QMetaDataObject>
|
||||
/***************************************************************************
|
||||
*
|
||||
***************************************************************************/
|
||||
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<T extends QMetaDataObject>
|
||||
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<Object> mappedValueList = new ArrayList<>();
|
||||
for(Object o : valueList)
|
||||
@ -233,11 +201,10 @@ public abstract class AbstractMetaDataLoader<T extends QMetaDataObject>
|
||||
}
|
||||
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<Object> mappedValueSet = new LinkedHashSet<>();
|
||||
for(Object o : valueList)
|
||||
@ -268,16 +235,16 @@ public abstract class AbstractMetaDataLoader<T extends QMetaDataObject>
|
||||
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<String, Object> mappedValueMap = new LinkedHashMap<>();
|
||||
for(Object o : valueMap.entrySet())
|
||||
{
|
||||
try
|
||||
{
|
||||
Map.Entry<String, Object> entry = (Map.Entry<String, Object>) o;
|
||||
Object mappedValue = reflectivelyMapValue(qInstance, null, actualTypeClass, entry.getValue());
|
||||
@SuppressWarnings("unchecked")
|
||||
Map.Entry<String, Object> entry = (Map.Entry<String, Object>) 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<T extends QMetaDataObject>
|
||||
}
|
||||
}
|
||||
}
|
||||
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<? extends AbstractMetaDataLoader<?>> loaderClass = registeredLoaders.get(parameterType);
|
||||
Class<? extends AbstractMetaDataLoader<?>> 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<T extends QMetaDataObject>
|
||||
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<String, Object> map, String key)
|
||||
//{
|
||||
// if(map.containsKey(key))
|
||||
// {
|
||||
// if(map.get(key) instanceof List)
|
||||
// {
|
||||
// return (new ListOfMapOrMapOfMap((List<Map<String, Object>>) map.get(key)));
|
||||
// }
|
||||
// else if(map.get(key) instanceof Map)
|
||||
// {
|
||||
// return (new ListOfMapOrMapOfMap((Map<String, Map<String, Object>>) 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<String, Object> map, String key)
|
||||
{
|
||||
if(map.containsKey(key))
|
||||
{
|
||||
if(map.get(key) instanceof List)
|
||||
{
|
||||
return (new ListOfMapOrMapOfMap((List<Map<String, Object>>) map.get(key)));
|
||||
}
|
||||
else if(map.get(key) instanceof Map)
|
||||
{
|
||||
return (new ListOfMapOrMapOfMap((Map<String, Map<String, Object>>) 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<Map<String, Object>> getListOfMap(Map<String, Object> map, String key)
|
||||
//{
|
||||
// if(map.containsKey(key))
|
||||
// {
|
||||
// if(map.get(key) instanceof List)
|
||||
// {
|
||||
// return (List<Map<String, Object>>) 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<String, Map<String, Object>> getMapOfMap(Map<String, Object> map, String key)
|
||||
//{
|
||||
// if(map.containsKey(key))
|
||||
// {
|
||||
// if(map.get(key) instanceof Map)
|
||||
// {
|
||||
// return (Map<String, Map<String, Object>>) 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<Map<String, Object>> getListOfMap(Map<String, Object> map, String key)
|
||||
{
|
||||
if(map.containsKey(key))
|
||||
{
|
||||
if(map.get(key) instanceof List)
|
||||
{
|
||||
return (List<Map<String, Object>>) 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<Map<String, Object>> listOf, Map<String, Map<String, Object>> mapOf)
|
||||
//{
|
||||
// /*******************************************************************************
|
||||
// ** Constructor
|
||||
// **
|
||||
// *******************************************************************************/
|
||||
// public ListOfMapOrMapOfMap(List<Map<String, Object>> listOf)
|
||||
// {
|
||||
// this(listOf, null);
|
||||
// }
|
||||
|
||||
return (null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
***************************************************************************/
|
||||
protected Map<String, Map<String, Object>> getMapOfMap(Map<String, Object> map, String key)
|
||||
{
|
||||
if(map.containsKey(key))
|
||||
{
|
||||
if(map.get(key) instanceof Map)
|
||||
{
|
||||
return (Map<String, Map<String, Object>>) 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<Map<String, Object>> listOf, Map<String, Map<String, Object>> mapOf)
|
||||
{
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public ListOfMapOrMapOfMap(List<Map<String, Object>> listOf)
|
||||
{
|
||||
this(listOf, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public ListOfMapOrMapOfMap(Map<String, Map<String, Object>> mapOf)
|
||||
{
|
||||
this(null, mapOf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
protected void warnNotImplemented(Map<String, Object> 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<String, Map<String, Object>> mapOf)
|
||||
// {
|
||||
// this(null, mapOf);
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
@ -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<QMetaDa
|
||||
if(map.containsKey("class"))
|
||||
{
|
||||
String classProperty = ValueUtils.getValueAsString(map.get("class"));
|
||||
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<? extends AbstractMetaDataLoader<?>> loaderClass = MetaDataLoaderRegistry.getLoaderForSimpleName(classProperty);
|
||||
return (loaderClass.getConstructor().newInstance());
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Class<?>> 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<? extends QMetaDataObject> metaDataClass = (Class<? extends QMetaDataObject>) 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());
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<?>, Class<? extends AbstractMetaDataLoader<?>>> registeredLoaders = new HashMap<>();
|
||||
private static final Map<String, Class<? extends AbstractMetaDataLoader<?>>> registeredLoadersByTargetSimpleName = new HashMap<>();
|
||||
|
||||
static
|
||||
{
|
||||
try
|
||||
{
|
||||
List<Class<?>> 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<? extends AbstractMetaDataLoader<?>> loaderClass = (Class<? extends AbstractMetaDataLoader<?>>) 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<? extends AbstractMetaDataLoader<?>> getLoaderForClass(Class<?> metaDataClass)
|
||||
{
|
||||
return registeredLoaders.get(metaDataClass);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
public static boolean hasLoaderForSimpleName(String targetSimpleName)
|
||||
{
|
||||
return registeredLoadersByTargetSimpleName.containsKey(targetSimpleName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
public static Class<? extends AbstractMetaDataLoader<?>> getLoaderForSimpleName(String targetSimpleName)
|
||||
{
|
||||
return registeredLoadersByTargetSimpleName.get(targetSimpleName);
|
||||
}
|
||||
}
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<T extends QMetaDataObject> extends AbstractMetaDataLoader<T>
|
||||
{
|
||||
private final Class<T> metaDataClass;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public GenericMetaDataLoader(Class<T> metaDataClass)
|
||||
{
|
||||
this.metaDataClass = metaDataClass;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public T mapToMetaDataObject(QInstance qInstance, Map<String, Object> 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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
@ -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"));
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user