mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 05:01:07 +00:00
Add optional additional validation to widget meta datas; implemented at least in part for ChildRecordListWidget
This commit is contained in:
@ -37,6 +37,8 @@ import com.kingsrook.qqq.backend.core.actions.values.QValueFormatter;
|
|||||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QNotFoundException;
|
import com.kingsrook.qqq.backend.core.exceptions.QNotFoundException;
|
||||||
|
import com.kingsrook.qqq.backend.core.instances.QInstanceValidator;
|
||||||
|
import com.kingsrook.qqq.backend.core.instances.validation.plugins.QInstanceValidatorPluginInterface;
|
||||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
import com.kingsrook.qqq.backend.core.model.actions.tables.get.GetInput;
|
||||||
@ -51,12 +53,15 @@ import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetOutput;
|
|||||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.ChildRecordListData;
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.ChildRecordListData;
|
||||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType;
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType;
|
||||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.AbstractWidgetMetaDataBuilder;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.AbstractWidgetMetaDataBuilder;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinOn;
|
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinOn;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||||
@ -83,7 +88,9 @@ public class ChildRecordListRenderer extends AbstractWidgetRenderer
|
|||||||
.withIsCard(true)
|
.withIsCard(true)
|
||||||
.withCodeReference(new QCodeReference(ChildRecordListRenderer.class))
|
.withCodeReference(new QCodeReference(ChildRecordListRenderer.class))
|
||||||
.withType(WidgetType.CHILD_RECORD_LIST.getType())
|
.withType(WidgetType.CHILD_RECORD_LIST.getType())
|
||||||
.withDefaultValue("joinName", join.getName())));
|
.withDefaultValue("joinName", join.getName())
|
||||||
|
.withValidatorPlugin(new ChildRecordListWidgetValidator())
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -165,10 +172,10 @@ public class ChildRecordListRenderer extends AbstractWidgetRenderer
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public Builder withManageAssociationName(String manageAssociationName)
|
public Builder withManageAssociationName(String manageAssociationName)
|
||||||
{
|
{
|
||||||
// todo - validate association name exists (on the table?)
|
|
||||||
widgetMetaData.withDefaultValue("manageAssociationName", manageAssociationName);
|
widgetMetaData.withDefaultValue("manageAssociationName", manageAssociationName);
|
||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -321,4 +328,68 @@ public class ChildRecordListRenderer extends AbstractWidgetRenderer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
private static class ChildRecordListWidgetValidator implements QInstanceValidatorPluginInterface<QWidgetMetaDataInterface>
|
||||||
|
{
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
@Override
|
||||||
|
public void validate(QWidgetMetaDataInterface widgetMetaData, QInstance qInstance, QInstanceValidator qInstanceValidator)
|
||||||
|
{
|
||||||
|
String prefix = "Widget " + widgetMetaData.getName() + ": ";
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// make sure join name is given //
|
||||||
|
//////////////////////////////////
|
||||||
|
String joinName = ValueUtils.getValueAsString(CollectionUtils.nonNullMap(widgetMetaData.getDefaultValues()).get("joinName"));
|
||||||
|
if(qInstanceValidator.assertCondition(StringUtils.hasContent(joinName), prefix + "defaultValue for joinName must be given"))
|
||||||
|
{
|
||||||
|
///////////////////////////
|
||||||
|
// make sure join exists //
|
||||||
|
///////////////////////////
|
||||||
|
QJoinMetaData join = qInstance.getJoin(joinName);
|
||||||
|
if(qInstanceValidator.assertCondition(join != null, prefix + "No join named " + joinName + " exists in the instance"))
|
||||||
|
{
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// if there's a manageAssociationName, make sure the table has that association //
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
String manageAssociationName = ValueUtils.getValueAsString(widgetMetaData.getDefaultValues().get("manageAssociationName"));
|
||||||
|
if(StringUtils.hasContent(manageAssociationName))
|
||||||
|
{
|
||||||
|
validateAssociationName(prefix, manageAssociationName, join, qInstance, qInstanceValidator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
private void validateAssociationName(String prefix, String manageAssociationName, QJoinMetaData join, QInstance qInstance, QInstanceValidator qInstanceValidator)
|
||||||
|
{
|
||||||
|
///////////////////////////////////
|
||||||
|
// make sure join's table exists //
|
||||||
|
///////////////////////////////////
|
||||||
|
QTableMetaData table = qInstance.getTable(join.getLeftTable());
|
||||||
|
if(table == null)
|
||||||
|
{
|
||||||
|
qInstanceValidator.getErrors().add(prefix + "Unable to validate manageAssociationName, as table [" + join.getLeftTable() + "] on left-side table of join [" + join.getName() + "] does not exist.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(CollectionUtils.nonNullList(table.getAssociations()).stream().noneMatch(a -> manageAssociationName.equals(a.getName())))
|
||||||
|
{
|
||||||
|
qInstanceValidator.getErrors().add(prefix + "an association named [" + manageAssociationName + "] does not exist on table [" + join.getLeftTable() + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2008,6 +2008,11 @@ public class QInstanceValidator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(widget.getValidatorPlugin() != null)
|
||||||
|
{
|
||||||
|
widget.getValidatorPlugin().validate(widget, qInstance, this);
|
||||||
|
}
|
||||||
|
|
||||||
runPlugins(QWidgetMetaDataInterface.class, widget, qInstance);
|
runPlugins(QWidgetMetaDataInterface.class, widget, qInstance);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -30,6 +30,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import com.kingsrook.qqq.backend.core.instances.QInstanceHelpContentManager;
|
import com.kingsrook.qqq.backend.core.instances.QInstanceHelpContentManager;
|
||||||
|
import com.kingsrook.qqq.backend.core.instances.validation.plugins.QInstanceValidatorPluginInterface;
|
||||||
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType;
|
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.help.HelpRole;
|
import com.kingsrook.qqq.backend.core.model.metadata.help.HelpRole;
|
||||||
@ -69,6 +70,7 @@ public class QWidgetMetaData implements QWidgetMetaDataInterface
|
|||||||
|
|
||||||
protected Map<String, Serializable> defaultValues = new LinkedHashMap<>();
|
protected Map<String, Serializable> defaultValues = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
protected QInstanceValidatorPluginInterface<QWidgetMetaDataInterface> validatorPlugin;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -764,4 +766,35 @@ public class QWidgetMetaData implements QWidgetMetaDataInterface
|
|||||||
QInstanceHelpContentManager.removeHelpContentByRoleSetFromList(roles, listForSlot);
|
QInstanceHelpContentManager.removeHelpContentByRoleSetFromList(roles, listForSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for validatorPlugin
|
||||||
|
*******************************************************************************/
|
||||||
|
public QInstanceValidatorPluginInterface<QWidgetMetaDataInterface> getValidatorPlugin()
|
||||||
|
{
|
||||||
|
return (this.validatorPlugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for validatorPlugin
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setValidatorPlugin(QInstanceValidatorPluginInterface<QWidgetMetaDataInterface> validatorPlugin)
|
||||||
|
{
|
||||||
|
this.validatorPlugin = validatorPlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for validatorPlugin
|
||||||
|
*******************************************************************************/
|
||||||
|
public QWidgetMetaData withValidatorPlugin(QInstanceValidatorPluginInterface<QWidgetMetaDataInterface> validatorPlugin)
|
||||||
|
{
|
||||||
|
this.validatorPlugin = validatorPlugin;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import java.io.Serializable;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import com.kingsrook.qqq.backend.core.instances.validation.plugins.QInstanceValidatorPluginInterface;
|
||||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
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.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.TopLevelMetaDataInterface;
|
import com.kingsrook.qqq.backend.core.model.metadata.TopLevelMetaDataInterface;
|
||||||
@ -277,5 +278,13 @@ public interface QWidgetMetaDataInterface extends MetaDataWithPermissionRules, T
|
|||||||
qInstance.addWidget(this);
|
qInstance.addWidget(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
** let the widget include an instance validator plugin
|
||||||
|
***************************************************************************/
|
||||||
|
default QInstanceValidatorPluginInterface<QWidgetMetaDataInterface> getValidatorPlugin()
|
||||||
|
{
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ public @interface ChildRecordListWidget
|
|||||||
{
|
{
|
||||||
boolean enabled();
|
boolean enabled();
|
||||||
|
|
||||||
String label() default "";
|
String label();
|
||||||
|
|
||||||
int maxRows() default 20;
|
int maxRows() default 20;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user