Add sourceClass attribute to MetaDataProducerInterface

This commit is contained in:
2025-02-28 19:41:57 -06:00
parent 9fb53af0ba
commit 99e282fcdf
8 changed files with 266 additions and 27 deletions

View File

@ -29,5 +29,40 @@ package com.kingsrook.qqq.backend.core.model.metadata;
*******************************************************************************/ *******************************************************************************/
public abstract class MetaDataProducer<T extends MetaDataProducerOutput> implements MetaDataProducerInterface<T> public abstract class MetaDataProducer<T extends MetaDataProducerOutput> implements MetaDataProducerInterface<T>
{ {
private Class<?> sourceClass;
/*******************************************************************************
** Getter for sourceClass
**
*******************************************************************************/
@Override
public Class<?> getSourceClass()
{
return sourceClass;
}
/*******************************************************************************
** Setter for sourceClass
**
*******************************************************************************/
@Override
public void setSourceClass(Class<?> sourceClass)
{
this.sourceClass = sourceClass;
}
/*******************************************************************************
** Fluent setter for sourceClass
**
*******************************************************************************/
public MetaDataProducer<T> withSourceClass(Class<?> sourceClass)
{
this.sourceClass = sourceClass;
return (this);
}
} }

View File

@ -239,17 +239,19 @@ public class MetaDataProducerHelper
** **
***************************************************************************/ ***************************************************************************/
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static <T extends Serializable & PossibleValueEnum<T>> MetaDataProducerInterface<?> processMetaDataProducingPossibleValueEnum(Class<?> aClass) private static <T extends Serializable & PossibleValueEnum<T>> MetaDataProducerInterface<?> processMetaDataProducingPossibleValueEnum(Class<?> sourceClass)
{ {
String warningPrefix = "Found a class annotated as @" + QMetaDataProducingPossibleValueEnum.class.getSimpleName(); String warningPrefix = "Found a class annotated as @" + QMetaDataProducingPossibleValueEnum.class.getSimpleName();
if(!PossibleValueEnum.class.isAssignableFrom(aClass)) if(!PossibleValueEnum.class.isAssignableFrom(sourceClass))
{ {
LOG.warn(warningPrefix + ", but which is not a " + PossibleValueEnum.class.getSimpleName() + ", so it will not be used.", logPair("class", aClass.getSimpleName())); LOG.warn(warningPrefix + ", but which is not a " + PossibleValueEnum.class.getSimpleName() + ", so it will not be used.", logPair("class", sourceClass.getSimpleName()));
return null; return null;
} }
PossibleValueEnum<?>[] values = (PossibleValueEnum<?>[]) aClass.getEnumConstants(); PossibleValueEnum<?>[] values = (PossibleValueEnum<?>[]) sourceClass.getEnumConstants();
return (new PossibleValueSourceOfEnumGenericMetaDataProducer<T>(aClass.getSimpleName(), (PossibleValueEnum<T>[]) values)); PossibleValueSourceOfEnumGenericMetaDataProducer<T> producer = new PossibleValueSourceOfEnumGenericMetaDataProducer<>(sourceClass.getSimpleName(), (PossibleValueEnum<T>[]) values);
producer.setSourceClass(sourceClass);
return producer;
} }
@ -257,32 +259,32 @@ public class MetaDataProducerHelper
/*************************************************************************** /***************************************************************************
** **
***************************************************************************/ ***************************************************************************/
private static List<MetaDataProducerInterface<?>> processMetaDataProducingEntity(Class<?> aClass) throws Exception private static List<MetaDataProducerInterface<?>> processMetaDataProducingEntity(Class<?> sourceClass) throws Exception
{ {
List<MetaDataProducerInterface<?>> rs = new ArrayList<>(); List<MetaDataProducerInterface<?>> rs = new ArrayList<>();
QMetaDataProducingEntity qMetaDataProducingEntity = aClass.getAnnotation(QMetaDataProducingEntity.class); QMetaDataProducingEntity qMetaDataProducingEntity = sourceClass.getAnnotation(QMetaDataProducingEntity.class);
String warningPrefix = "Found a class annotated as @" + QMetaDataProducingEntity.class.getSimpleName(); String warningPrefix = "Found a class annotated as @" + QMetaDataProducingEntity.class.getSimpleName();
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// make sures class is QRecordEntity and cast it as such // // make sures class is QRecordEntity and cast it as such //
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
if(!QRecordEntity.class.isAssignableFrom(aClass)) if(!QRecordEntity.class.isAssignableFrom(sourceClass))
{ {
LOG.warn(warningPrefix + ", but which is not a " + QRecordEntity.class.getSimpleName() + ", so it will not be used.", logPair("class", aClass.getSimpleName())); LOG.warn(warningPrefix + ", but which is not a " + QRecordEntity.class.getSimpleName() + ", so it will not be used.", logPair("class", sourceClass.getSimpleName()));
return (rs); return (rs);
} }
@SuppressWarnings("unchecked") // safe per the check above. @SuppressWarnings("unchecked") // safe per the check above.
Class<? extends QRecordEntity> recordEntityClass = (Class<? extends QRecordEntity>) aClass; Class<? extends QRecordEntity> recordEntityClass = (Class<? extends QRecordEntity>) sourceClass;
//////////////////////////////////////////////// ////////////////////////////////////////////////
// get TABLE_NAME static field from the class // // get TABLE_NAME static field from the class //
//////////////////////////////////////////////// ////////////////////////////////////////////////
Field tableNameField = aClass.getDeclaredField("TABLE_NAME"); Field tableNameField = recordEntityClass.getDeclaredField("TABLE_NAME");
if(!tableNameField.getType().equals(String.class)) if(!tableNameField.getType().equals(String.class))
{ {
LOG.warn(warningPrefix + ", but whose TABLE_NAME field is not a String, so it will not be used.", logPair("class", aClass.getSimpleName())); LOG.warn(warningPrefix + ", but whose TABLE_NAME field is not a String, so it will not be used.", logPair("class", recordEntityClass.getSimpleName()));
return (rs); return (rs);
} }
@ -303,6 +305,7 @@ public class MetaDataProducerHelper
} }
RecordEntityToTableGenericMetaDataProducer producer = new RecordEntityToTableGenericMetaDataProducer(tableNameValue, recordEntityClass, tableMetaDataProductionCustomizer); RecordEntityToTableGenericMetaDataProducer producer = new RecordEntityToTableGenericMetaDataProducer(tableNameValue, recordEntityClass, tableMetaDataProductionCustomizer);
producer.setSourceClass(recordEntityClass);
if(tableMetaDataCustomizer != null) if(tableMetaDataCustomizer != null)
{ {
@ -322,7 +325,9 @@ public class MetaDataProducerHelper
//////////////////////////////////////// ////////////////////////////////////////
if(qMetaDataProducingEntity.producePossibleValueSource()) if(qMetaDataProducingEntity.producePossibleValueSource())
{ {
rs.add(new PossibleValueSourceOfTableGenericMetaDataProducer(tableNameValue)); PossibleValueSourceOfTableGenericMetaDataProducer producer = new PossibleValueSourceOfTableGenericMetaDataProducer(tableNameValue);
producer.setSourceClass(recordEntityClass);
rs.add(producer);
} }
////////////////////////// //////////////////////////
@ -333,11 +338,11 @@ public class MetaDataProducerHelper
Class<? extends QRecordEntity> childEntityClass = childTable.childTableEntityClass(); Class<? extends QRecordEntity> childEntityClass = childTable.childTableEntityClass();
if(childTable.childJoin().enabled()) if(childTable.childJoin().enabled())
{ {
CollectionUtils.addIfNotNull(rs, processChildJoin(aClass, childTable)); CollectionUtils.addIfNotNull(rs, processChildJoin(recordEntityClass, childTable));
if(childTable.childRecordListWidget().enabled()) if(childTable.childRecordListWidget().enabled())
{ {
CollectionUtils.addIfNotNull(rs, processChildRecordListWidget(aClass, childTable)); CollectionUtils.addIfNotNull(rs, processChildRecordListWidget(recordEntityClass, childTable));
} }
} }
else else
@ -347,7 +352,7 @@ public class MetaDataProducerHelper
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// if not doing the join, can't do the child-widget, so warn about that // // if not doing the join, can't do the child-widget, so warn about that //
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
LOG.warn(warningPrefix + " requested to produce a ChildRecordListWidget, but not produce a Join - which is not allowed (must do join to do widget). ", logPair("class", aClass.getSimpleName()), logPair("childEntityClass", childEntityClass.getSimpleName())); LOG.warn(warningPrefix + " requested to produce a ChildRecordListWidget, but not produce a Join - which is not allowed (must do join to do widget). ", logPair("class", recordEntityClass.getSimpleName()), logPair("childEntityClass", childEntityClass.getSimpleName()));
} }
} }
} }
@ -360,14 +365,16 @@ public class MetaDataProducerHelper
/*************************************************************************** /***************************************************************************
** **
***************************************************************************/ ***************************************************************************/
private static MetaDataProducerInterface<?> processChildRecordListWidget(Class<?> aClass, ChildTable childTable) throws Exception private static MetaDataProducerInterface<?> processChildRecordListWidget(Class<? extends QRecordEntity> sourceClass, ChildTable childTable) throws Exception
{ {
Class<? extends QRecordEntity> childEntityClass = childTable.childTableEntityClass(); Class<? extends QRecordEntity> childEntityClass = childTable.childTableEntityClass();
String parentTableName = getTableNameStaticFieldValue(aClass); String parentTableName = getTableNameStaticFieldValue(sourceClass);
String childTableName = getTableNameStaticFieldValue(childEntityClass); String childTableName = getTableNameStaticFieldValue(childEntityClass);
ChildRecordListWidget childRecordListWidget = childTable.childRecordListWidget(); ChildRecordListWidget childRecordListWidget = childTable.childRecordListWidget();
return (new ChildRecordListWidgetFromRecordEntityGenericMetaDataProducer(childTableName, parentTableName, childRecordListWidget)); ChildRecordListWidgetFromRecordEntityGenericMetaDataProducer producer = new ChildRecordListWidgetFromRecordEntityGenericMetaDataProducer(childTableName, parentTableName, childRecordListWidget);
producer.setSourceClass(sourceClass);
return producer;
} }
@ -397,20 +404,22 @@ public class MetaDataProducerHelper
/*************************************************************************** /***************************************************************************
** **
***************************************************************************/ ***************************************************************************/
private static MetaDataProducerInterface<?> processChildJoin(Class<?> aClass, ChildTable childTable) throws Exception private static MetaDataProducerInterface<?> processChildJoin(Class<? extends QRecordEntity> entityClass, ChildTable childTable) throws Exception
{ {
Class<? extends QRecordEntity> childEntityClass = childTable.childTableEntityClass(); Class<? extends QRecordEntity> childEntityClass = childTable.childTableEntityClass();
String parentTableName = getTableNameStaticFieldValue(aClass); String parentTableName = getTableNameStaticFieldValue(entityClass);
String childTableName = getTableNameStaticFieldValue(childEntityClass); String childTableName = getTableNameStaticFieldValue(childEntityClass);
String possibleValueFieldName = findPossibleValueField(childEntityClass, parentTableName); String possibleValueFieldName = findPossibleValueField(childEntityClass, parentTableName);
if(!StringUtils.hasContent(possibleValueFieldName)) if(!StringUtils.hasContent(possibleValueFieldName))
{ {
LOG.warn("Could not find field in [" + childEntityClass.getSimpleName() + "] with possibleValueSource referencing table [" + aClass.getSimpleName() + "]"); LOG.warn("Could not find field in [" + childEntityClass.getSimpleName() + "] with possibleValueSource referencing table [" + entityClass.getSimpleName() + "]");
return (null); return (null);
} }
return (new ChildJoinFromRecordEntityGenericMetaDataProducer(childTableName, parentTableName, possibleValueFieldName)); ChildJoinFromRecordEntityGenericMetaDataProducer producer = new ChildJoinFromRecordEntityGenericMetaDataProducer(childTableName, parentTableName, possibleValueFieldName);
producer.setSourceClass(entityClass);
return producer;
} }
@ -418,18 +427,20 @@ public class MetaDataProducerHelper
/*************************************************************************** /***************************************************************************
** **
***************************************************************************/ ***************************************************************************/
private static MetaDataProducerInterface<?> processMetaDataProducer(Class<?> aClass) throws Exception private static MetaDataProducerInterface<?> processMetaDataProducer(Class<?> sourceCClass) throws Exception
{ {
for(Constructor<?> constructor : aClass.getConstructors()) for(Constructor<?> constructor : sourceCClass.getConstructors())
{ {
if(constructor.getParameterCount() == 0) if(constructor.getParameterCount() == 0)
{ {
Object o = constructor.newInstance(); Object o = constructor.newInstance();
return (MetaDataProducerInterface<?>) o; MetaDataProducerInterface<?> producer = (MetaDataProducerInterface<?>) o;
producer.setSourceClass(sourceCClass);
return producer;
} }
} }
LOG.warn("Found a class which implements MetaDataProducerInterface, but it does not have a no-arg constructor, so it cannot be used.", logPair("class", aClass.getSimpleName())); LOG.warn("Found a class which implements MetaDataProducerInterface, but it does not have a no-arg constructor, so it cannot be used.", logPair("class", sourceCClass.getSimpleName()));
return null; return null;
} }

View File

@ -73,4 +73,23 @@ public interface MetaDataProducerInterface<T extends MetaDataProducerOutput>
return (true); return (true);
} }
/***************************************************************************
*
***************************************************************************/
default void setSourceClass(Class<?> sourceClass)
{
//////////
// noop //
//////////
}
/***************************************************************************
**
***************************************************************************/
default Class<?> getSourceClass()
{
return null;
}
} }

View File

@ -62,6 +62,7 @@ public class ChildJoinFromRecordEntityGenericMetaDataProducer implements MetaDat
private String parentTableName; // e.g., order private String parentTableName; // e.g., order
private String foreignKeyFieldName; // e.g., orderId private String foreignKeyFieldName; // e.g., orderId
private Class<?> sourceClass;
/*************************************************************************** /***************************************************************************
@ -102,4 +103,37 @@ public class ChildJoinFromRecordEntityGenericMetaDataProducer implements MetaDat
return (join); return (join);
} }
/*******************************************************************************
** Getter for sourceClass
**
*******************************************************************************/
public Class<?> getSourceClass()
{
return sourceClass;
}
/*******************************************************************************
** Setter for sourceClass
**
*******************************************************************************/
public void setSourceClass(Class<?> sourceClass)
{
this.sourceClass = sourceClass;
}
/*******************************************************************************
** Fluent setter for sourceClass
**
*******************************************************************************/
public ChildJoinFromRecordEntityGenericMetaDataProducer withSourceClass(Class<?> sourceClass)
{
this.sourceClass = sourceClass;
return (this);
}
} }

View File

@ -57,6 +57,8 @@ public class ChildRecordListWidgetFromRecordEntityGenericMetaDataProducer implem
private ChildRecordListWidget childRecordListWidget; private ChildRecordListWidget childRecordListWidget;
private Class<?> sourceClass;
/*************************************************************************** /***************************************************************************
@ -111,4 +113,36 @@ public class ChildRecordListWidgetFromRecordEntityGenericMetaDataProducer implem
return (widget); return (widget);
} }
/*******************************************************************************
** Getter for sourceClass
**
*******************************************************************************/
public Class<?> getSourceClass()
{
return sourceClass;
}
/*******************************************************************************
** Setter for sourceClass
**
*******************************************************************************/
public void setSourceClass(Class<?> sourceClass)
{
this.sourceClass = sourceClass;
}
/*******************************************************************************
** Fluent setter for sourceClass
**
*******************************************************************************/
public ChildRecordListWidgetFromRecordEntityGenericMetaDataProducer withSourceClass(Class<?> sourceClass)
{
this.sourceClass = sourceClass;
return (this);
}
} }

View File

@ -40,6 +40,10 @@ public class PossibleValueSourceOfEnumGenericMetaDataProducer<T extends Serializ
private final String name; private final String name;
private final PossibleValueEnum<T>[] values; private final PossibleValueEnum<T>[] values;
private Class<?> sourceClass;
/******************************************************************************* /*******************************************************************************
@ -62,4 +66,37 @@ public class PossibleValueSourceOfEnumGenericMetaDataProducer<T extends Serializ
{ {
return (QPossibleValueSource.newForEnum(name, values)); return (QPossibleValueSource.newForEnum(name, values));
} }
/*******************************************************************************
** Getter for sourceClass
**
*******************************************************************************/
public Class<?> getSourceClass()
{
return sourceClass;
}
/*******************************************************************************
** Setter for sourceClass
**
*******************************************************************************/
public void setSourceClass(Class<?> sourceClass)
{
this.sourceClass = sourceClass;
}
/*******************************************************************************
** Fluent setter for sourceClass
**
*******************************************************************************/
public PossibleValueSourceOfEnumGenericMetaDataProducer<T> withSourceClass(Class<?> sourceClass)
{
this.sourceClass = sourceClass;
return (this);
}
} }

View File

@ -37,6 +37,7 @@ public class PossibleValueSourceOfTableGenericMetaDataProducer implements MetaDa
{ {
private final String tableName; private final String tableName;
private Class<?> sourceClass;
/******************************************************************************* /*******************************************************************************
@ -58,4 +59,38 @@ public class PossibleValueSourceOfTableGenericMetaDataProducer implements MetaDa
{ {
return (QPossibleValueSource.newForTable(tableName)); return (QPossibleValueSource.newForTable(tableName));
} }
/*******************************************************************************
** Getter for sourceClass
**
*******************************************************************************/
public Class<?> getSourceClass()
{
return sourceClass;
}
/*******************************************************************************
** Setter for sourceClass
**
*******************************************************************************/
public void setSourceClass(Class<?> sourceClass)
{
this.sourceClass = sourceClass;
}
/*******************************************************************************
** Fluent setter for sourceClass
**
*******************************************************************************/
public PossibleValueSourceOfTableGenericMetaDataProducer withSourceClass(Class<?> sourceClass)
{
this.sourceClass = sourceClass;
return (this);
}
} }

View File

@ -48,6 +48,7 @@ public class RecordEntityToTableGenericMetaDataProducer implements MetaDataProdu
private static MetaDataCustomizerInterface<QTableMetaData> defaultMetaDataCustomizer = null; private static MetaDataCustomizerInterface<QTableMetaData> defaultMetaDataCustomizer = null;
private Class<?> sourceClass;
/******************************************************************************* /*******************************************************************************
@ -154,4 +155,37 @@ public class RecordEntityToTableGenericMetaDataProducer implements MetaDataProdu
RecordEntityToTableGenericMetaDataProducer.defaultMetaDataCustomizer = defaultMetaDataCustomizer; RecordEntityToTableGenericMetaDataProducer.defaultMetaDataCustomizer = defaultMetaDataCustomizer;
} }
/*******************************************************************************
** Getter for sourceClass
**
*******************************************************************************/
public Class<?> getSourceClass()
{
return sourceClass;
}
/*******************************************************************************
** Setter for sourceClass
**
*******************************************************************************/
public void setSourceClass(Class<?> sourceClass)
{
this.sourceClass = sourceClass;
}
/*******************************************************************************
** Fluent setter for sourceClass
**
*******************************************************************************/
public RecordEntityToTableGenericMetaDataProducer withSourceClass(Class<?> sourceClass)
{
this.sourceClass = sourceClass;
return (this);
}
} }