Introduce annotations that can be found by MetaDataProducerHelper, to make more meta-data, with less code. Specifically:

- PVS from PossibleValueEnum
- PVS from RecordEntity
- Joins from a parent-entity to child-entities
- ChildRecordList Widgets from a parent-entity to child-entities
This commit is contained in:
2024-12-13 11:23:38 -06:00
parent 16f931cd5c
commit ec74649c96
15 changed files with 1175 additions and 14 deletions

View File

@ -23,14 +23,26 @@ package com.kingsrook.qqq.backend.core.model.metadata;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.dashboard.widgets.WidgetType;
import com.kingsrook.qqq.backend.core.model.metadata.dashboard.QWidgetMetaDataInterface;
import com.kingsrook.qqq.backend.core.model.metadata.joins.JoinType;
import com.kingsrook.qqq.backend.core.model.metadata.joins.QJoinMetaData;
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValue;
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSourceType;
import com.kingsrook.qqq.backend.core.model.metadata.producers.TestAbstractMetaDataProducer;
import com.kingsrook.qqq.backend.core.model.metadata.producers.TestDisabledMetaDataProducer;
import com.kingsrook.qqq.backend.core.model.metadata.producers.TestImplementsMetaDataProducer;
import com.kingsrook.qqq.backend.core.model.metadata.producers.TestMetaDataProducer;
import com.kingsrook.qqq.backend.core.model.metadata.producers.TestMetaDataProducingChildEntity;
import com.kingsrook.qqq.backend.core.model.metadata.producers.TestMetaDataProducingEntity;
import com.kingsrook.qqq.backend.core.model.metadata.producers.TestMetaDataProducingPossibleValueEnum;
import com.kingsrook.qqq.backend.core.model.metadata.producers.TestNoInterfacesExtendsObject;
import com.kingsrook.qqq.backend.core.model.metadata.producers.TestNoValidConstructorMetaDataProducer;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ -54,6 +66,48 @@ class MetaDataProducerHelperTest
assertFalse(qInstance.getTables().containsKey(TestNoInterfacesExtendsObject.NAME));
assertFalse(qInstance.getTables().containsKey(TestAbstractMetaDataProducer.NAME));
assertFalse(qInstance.getTables().containsKey(TestDisabledMetaDataProducer.NAME));
/////////////////////////////////////////////
// annotation on PVS enum -> PVS meta data //
/////////////////////////////////////////////
assertTrue(qInstance.getPossibleValueSources().containsKey(TestMetaDataProducingPossibleValueEnum.class.getSimpleName()));
QPossibleValueSource enumPVS = qInstance.getPossibleValueSource(TestMetaDataProducingPossibleValueEnum.class.getSimpleName());
assertEquals(QPossibleValueSourceType.ENUM, enumPVS.getType());
assertEquals(2, enumPVS.getEnumValues().size());
assertEquals(new QPossibleValue<>(1, "One"), enumPVS.getEnumValues().get(0));
//////////////////////////////////////////////
// annotation on PVS table -> PVS meta data //
//////////////////////////////////////////////
assertTrue(qInstance.getPossibleValueSources().containsKey(TestMetaDataProducingEntity.TABLE_NAME));
QPossibleValueSource tablePVS = qInstance.getPossibleValueSource(TestMetaDataProducingEntity.TABLE_NAME);
assertEquals(QPossibleValueSourceType.TABLE, tablePVS.getType());
assertEquals(TestMetaDataProducingEntity.TABLE_NAME, tablePVS.getTableName());
//////////////////////////////////////////////////////////////////
// annotation on parent table w/ joined child -> join meta data //
//////////////////////////////////////////////////////////////////
String joinName = QJoinMetaData.makeInferredJoinName(TestMetaDataProducingEntity.TABLE_NAME, TestMetaDataProducingChildEntity.TABLE_NAME);
assertTrue(qInstance.getJoins().containsKey(joinName));
QJoinMetaData join = qInstance.getJoin(joinName);
assertEquals(TestMetaDataProducingEntity.TABLE_NAME, join.getLeftTable());
assertEquals(TestMetaDataProducingChildEntity.TABLE_NAME, join.getRightTable());
assertEquals(JoinType.ONE_TO_MANY, join.getType());
assertEquals("id", join.getJoinOns().get(0).getLeftField());
assertEquals("parentId", join.getJoinOns().get(0).getRightField());
//////////////////////////////////////////////////////////////////////////////////////
// annotation on parent table w/ joined child -> child record list widget meta data //
//////////////////////////////////////////////////////////////////////////////////////
assertTrue(qInstance.getWidgets().containsKey(joinName));
QWidgetMetaDataInterface widget = qInstance.getWidget(joinName);
assertEquals(WidgetType.CHILD_RECORD_LIST.getType(), widget.getType());
assertEquals("Test Children", widget.getLabel());
assertEquals(joinName, widget.getDefaultValues().get("joinName"));
assertEquals(false, widget.getDefaultValues().get("canAddChildRecord"));
assertNull(widget.getDefaultValues().get("manageAssociationName"));
assertEquals(15, widget.getDefaultValues().get("maxRows"));
}
}

View File

@ -0,0 +1,140 @@
/*
* 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.model.metadata.producers;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.data.QField;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.data.QRecordEntity;
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
/*******************************************************************************
** QRecord Entity for TestMetaDataProducingEntity table
*******************************************************************************/
public class TestMetaDataProducingChildEntity extends QRecordEntity implements MetaDataProducerInterface<QTableMetaData>
{
public static final String TABLE_NAME = "testMetaDataProducingChildEntity";
@QField(isEditable = false, isPrimaryKey = true)
private Integer id;
@QField(possibleValueSourceName = TestMetaDataProducingEntity.TABLE_NAME)
private Integer parentId;
/***************************************************************************
**
***************************************************************************/
@Override
public QTableMetaData produce(QInstance qInstance) throws QException
{
return new QTableMetaData()
.withName(TABLE_NAME)
.withFieldsFromEntity(TestMetaDataProducingChildEntity.class);
}
/*******************************************************************************
** Default constructor
*******************************************************************************/
public TestMetaDataProducingChildEntity()
{
}
/*******************************************************************************
** Constructor that takes a QRecord
*******************************************************************************/
public TestMetaDataProducingChildEntity(QRecord record)
{
populateFromQRecord(record);
}
/*******************************************************************************
** Getter for id
*******************************************************************************/
public Integer getId()
{
return (this.id);
}
/*******************************************************************************
** Setter for id
*******************************************************************************/
public void setId(Integer id)
{
this.id = id;
}
/*******************************************************************************
** Fluent setter for id
*******************************************************************************/
public TestMetaDataProducingChildEntity withId(Integer id)
{
this.id = id;
return (this);
}
/*******************************************************************************
** Getter for parentId
*******************************************************************************/
public Integer getParentId()
{
return (this.parentId);
}
/*******************************************************************************
** Setter for parentId
*******************************************************************************/
public void setParentId(Integer parentId)
{
this.parentId = parentId;
}
/*******************************************************************************
** Fluent setter for parentId
*******************************************************************************/
public TestMetaDataProducingChildEntity withParentId(Integer parentId)
{
this.parentId = parentId;
return (this);
}
}

View File

@ -0,0 +1,119 @@
/*
* 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.model.metadata.producers;
import com.kingsrook.qqq.backend.core.exceptions.QException;
import com.kingsrook.qqq.backend.core.model.data.QField;
import com.kingsrook.qqq.backend.core.model.data.QRecord;
import com.kingsrook.qqq.backend.core.model.data.QRecordEntity;
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.ChildJoin;
import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.ChildRecordListWidget;
import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.ChildTable;
import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity;
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
/*******************************************************************************
** QRecord Entity for TestMetaDataProducingEntity table
*******************************************************************************/
@QMetaDataProducingEntity(producePossibleValueSource = true,
childTables =
{
@ChildTable(childTableEntityClass = TestMetaDataProducingChildEntity.class,
childJoin = @ChildJoin(enabled = true),
childRecordListWidget = @ChildRecordListWidget(enabled = true, label = "Test Children", maxRows = 15))
}
)
public class TestMetaDataProducingEntity extends QRecordEntity implements MetaDataProducerInterface<QTableMetaData>
{
public static final String TABLE_NAME = "testMetaDataProducingEntity";
@QField(isEditable = false, isPrimaryKey = true)
private Integer id;
/***************************************************************************
**
***************************************************************************/
@Override
public QTableMetaData produce(QInstance qInstance) throws QException
{
return new QTableMetaData()
.withName(TABLE_NAME)
.withFieldsFromEntity(TestMetaDataProducingEntity.class);
}
/*******************************************************************************
** Default constructor
*******************************************************************************/
public TestMetaDataProducingEntity()
{
}
/*******************************************************************************
** Constructor that takes a QRecord
*******************************************************************************/
public TestMetaDataProducingEntity(QRecord record)
{
populateFromQRecord(record);
}
/*******************************************************************************
** Getter for id
*******************************************************************************/
public Integer getId()
{
return (this.id);
}
/*******************************************************************************
** Setter for id
*******************************************************************************/
public void setId(Integer id)
{
this.id = id;
}
/*******************************************************************************
** Fluent setter for id
*******************************************************************************/
public TestMetaDataProducingEntity withId(Integer id)
{
this.id = id;
return (this);
}
}

View File

@ -0,0 +1,74 @@
/*
* 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.model.metadata.producers;
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.PossibleValueEnum;
import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingPossibleValueEnum;
/*******************************************************************************
**
*******************************************************************************/
@QMetaDataProducingPossibleValueEnum(producePossibleValueSource = true)
public enum TestMetaDataProducingPossibleValueEnum implements PossibleValueEnum<Integer>
{
ONE(1, "One"),
TWO(2, "Two");
private final int id;
private final String label;
/***************************************************************************
**
***************************************************************************/
TestMetaDataProducingPossibleValueEnum(int id, String label)
{
this.id = id;
this.label = label;
}
/***************************************************************************
**
***************************************************************************/
@Override
public String getPossibleValueLabel()
{
return label;
}
/***************************************************************************
**
***************************************************************************/
@Override
public Integer getPossibleValueId()
{
return id;
}
}