mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-20 06:00:44 +00:00
Initial checkin of QBits, mostly.
This commit is contained in:
@ -24,6 +24,7 @@ package com.kingsrook.qqq.backend.core.model.metadata;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.qbits.SourceQBitAware;
|
||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||
|
||||
|
||||
@ -31,10 +32,12 @@ import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||
** Output object for a MetaDataProducer, which contains multiple meta-data
|
||||
** objects.
|
||||
*******************************************************************************/
|
||||
public class MetaDataProducerMultiOutput implements MetaDataProducerOutput
|
||||
public class MetaDataProducerMultiOutput implements MetaDataProducerOutput, SourceQBitAware
|
||||
{
|
||||
private List<MetaDataProducerOutput> contents;
|
||||
|
||||
private String sourceQBitName;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -98,4 +101,48 @@ public class MetaDataProducerMultiOutput implements MetaDataProducerOutput
|
||||
return (rs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public String getSourceQBitName()
|
||||
{
|
||||
return (this.sourceQBitName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public void setSourceQBitName(String sourceQBitName)
|
||||
{
|
||||
this.sourceQBitName = sourceQBitName;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// propagate the name down to the children //
|
||||
/////////////////////////////////////////////
|
||||
for(MetaDataProducerOutput content : contents)
|
||||
{
|
||||
if(content instanceof SourceQBitAware aware)
|
||||
{
|
||||
aware.setSourceQBitName(sourceQBitName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public MetaDataProducerMultiOutput withSourceQBitName(String sourceQBitName)
|
||||
{
|
||||
setSourceQBitName(sourceQBitName);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.permissions.QPermissionRule
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.QPossibleValueSource;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.processes.QStepMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.qbits.QBitMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.queues.QQueueMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.queues.QQueueProviderMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.reporting.QReportMetaData;
|
||||
@ -89,6 +90,7 @@ public class QInstance
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Important to use LinkedHashmap here, to preserve the order in which entries are added. //
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
private Map<String, QBitMetaData> qBits = new LinkedHashMap<>();
|
||||
private Map<String, QTableMetaData> tables = new LinkedHashMap<>();
|
||||
private Map<String, QJoinMetaData> joins = new LinkedHashMap<>();
|
||||
private Map<String, QPossibleValueSource> possibleValueSources = new LinkedHashMap<>();
|
||||
@ -1489,6 +1491,7 @@ public class QInstance
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for metaDataFilter
|
||||
*******************************************************************************/
|
||||
@ -1519,4 +1522,68 @@ public class QInstance
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addQBit(QBitMetaData qBitMetaData)
|
||||
{
|
||||
List<String> missingParts = new ArrayList<>();
|
||||
if(!StringUtils.hasContent(qBitMetaData.getGroupId()))
|
||||
{
|
||||
missingParts.add("groupId");
|
||||
}
|
||||
if(!StringUtils.hasContent(qBitMetaData.getArtifactId()))
|
||||
{
|
||||
missingParts.add("artifactId");
|
||||
}
|
||||
if(!StringUtils.hasContent(qBitMetaData.getVersion()))
|
||||
{
|
||||
missingParts.add("version");
|
||||
|
||||
}
|
||||
if(!missingParts.isEmpty())
|
||||
{
|
||||
throw (new IllegalArgumentException("Attempted to add a qBit without a " + StringUtils.joinWithCommasAndAnd(missingParts)));
|
||||
}
|
||||
|
||||
String name = qBitMetaData.getName();
|
||||
if(this.qBits.containsKey(name))
|
||||
{
|
||||
throw (new IllegalArgumentException("Attempted to add a second qBit with name (formed from 'groupId:artifactId:version[:namespace]'): " + name));
|
||||
}
|
||||
this.qBits.put(name, qBitMetaData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for qBits
|
||||
*******************************************************************************/
|
||||
public Map<String, QBitMetaData> getQBits()
|
||||
{
|
||||
return (this.qBits);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for qBits
|
||||
*******************************************************************************/
|
||||
public void setQBits(Map<String, QBitMetaData> qBits)
|
||||
{
|
||||
this.qBits = qBits;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for qBits
|
||||
*******************************************************************************/
|
||||
public QInstance withQBits(Map<String, QBitMetaData> qBits)
|
||||
{
|
||||
this.qBits = qBits;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppChildMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.permissions.MetaDataWithPermissionRules;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.permissions.QPermissionRules;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.qbits.SourceQBitAware;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.scheduleing.QScheduleMetaData;
|
||||
import com.kingsrook.qqq.backend.core.processes.implementations.basepull.BasepullConfiguration;
|
||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||
@ -46,11 +47,14 @@ import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||
** Meta-Data to define a process in a QQQ instance.
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QProcessMetaData implements QAppChildMetaData, MetaDataWithPermissionRules, TopLevelMetaDataInterface
|
||||
public class QProcessMetaData implements QAppChildMetaData, MetaDataWithPermissionRules, TopLevelMetaDataInterface, SourceQBitAware
|
||||
{
|
||||
private String name;
|
||||
private String label;
|
||||
private String tableName;
|
||||
private String name;
|
||||
private String label;
|
||||
private String tableName;
|
||||
|
||||
private String sourceQBitName;
|
||||
|
||||
private boolean isHidden = false;
|
||||
private BasepullConfiguration basepullConfiguration;
|
||||
private QPermissionRules permissionRules;
|
||||
@ -870,6 +874,7 @@ public class QProcessMetaData implements QAppChildMetaData, MetaDataWithPermissi
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for processTracerCodeReference
|
||||
*******************************************************************************/
|
||||
@ -900,4 +905,37 @@ public class QProcessMetaData implements QAppChildMetaData, MetaDataWithPermissi
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for sourceQBitName
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public String getSourceQBitName()
|
||||
{
|
||||
return (this.sourceQBitName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for sourceQBitName
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void setSourceQBitName(String sourceQBitName)
|
||||
{
|
||||
this.sourceQBitName = sourceQBitName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for sourceQBitName
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public QProcessMetaData withSourceQBitName(String sourceQBitName)
|
||||
{
|
||||
this.sourceQBitName = sourceQBitName;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2025. 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.qbits;
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
** Common (maybe)? qbit config pattern, where the qbit may be able to provide
|
||||
** a particular table, or, the application may supply it itself.
|
||||
**
|
||||
** If the qbit provides it, then we need to be told (by the application)
|
||||
** what backendName to use for the table.
|
||||
**
|
||||
** Else if the application supplies it, it needs to tell the qBit what the
|
||||
** tableName is.
|
||||
***************************************************************************/
|
||||
public class ProvidedOrSuppliedTableConfig
|
||||
{
|
||||
private boolean doProvideTable;
|
||||
private String backendName;
|
||||
private String tableName;
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
public ProvidedOrSuppliedTableConfig(boolean doProvideTable, String backendName, String tableName)
|
||||
{
|
||||
this.doProvideTable = doProvideTable;
|
||||
this.backendName = backendName;
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
public static ProvidedOrSuppliedTableConfig provideTableUsingBackendNamed(String backendName)
|
||||
{
|
||||
return (new ProvidedOrSuppliedTableConfig(true, backendName, null));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
public static ProvidedOrSuppliedTableConfig useSuppliedTaleNamed(String tableName)
|
||||
{
|
||||
return (new ProvidedOrSuppliedTableConfig(false, null, tableName));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
public String getEffectiveTableName(String tableNameIfProviding)
|
||||
{
|
||||
if (getDoProvideTable())
|
||||
{
|
||||
return tableNameIfProviding;
|
||||
}
|
||||
else
|
||||
{
|
||||
return getTableName();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for tableName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getTableName()
|
||||
{
|
||||
return tableName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for doProvideTable
|
||||
**
|
||||
*******************************************************************************/
|
||||
public boolean getDoProvideTable()
|
||||
{
|
||||
return doProvideTable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for backendName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getBackendName()
|
||||
{
|
||||
return backendName;
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2025. 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.qbits;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerOutput;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** extension of MetaDataProducerInterface, designed for producing meta data
|
||||
** within a (java-defined, at this time) QBit.
|
||||
**
|
||||
** Specifically exists to accept the QBitConfig as a type parameter and a value,
|
||||
** easily accessed in the producer's methods as getQBitConfig()
|
||||
*******************************************************************************/
|
||||
public abstract class QBitComponentMetaDataProducer<T extends MetaDataProducerOutput, C extends QBitConfig> implements MetaDataProducerInterface<T>
|
||||
{
|
||||
private C qBitConfig = null;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for qBitConfig
|
||||
*******************************************************************************/
|
||||
public C getQBitConfig()
|
||||
{
|
||||
return (this.qBitConfig);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for qBitConfig
|
||||
*******************************************************************************/
|
||||
public void setQBitConfig(C qBitConfig)
|
||||
{
|
||||
this.qBitConfig = qBitConfig;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for qBitConfig
|
||||
*******************************************************************************/
|
||||
public QBitComponentMetaDataProducer<T, C> withQBitConfig(C qBitConfig)
|
||||
{
|
||||
this.qBitConfig = qBitConfig;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2025. 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.qbits;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
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.producers.MetaDataCustomizerInterface;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Interface for configuration settings used both in the production of meta-data
|
||||
** for a QBit, but also at runtime, e.g., to be aware of exactly how the qbit
|
||||
** has been incorporated into an application.
|
||||
**
|
||||
** For example:
|
||||
** - should the QBit define certain tables, or will they be supplied by the application?
|
||||
** - what other meta-data names should the qbit reference (backends, schedulers)
|
||||
** - what meta-data-customizer(s) should be used?
|
||||
**
|
||||
** When implementing a QBit, you'll implement this interface - adding whatever
|
||||
** (if any) properties you need, and if you have any rules, then overriding
|
||||
** the validate method (ideally the one that takes the List-of-String errors)
|
||||
**
|
||||
** When using a QBit, you'll create an instance of the QBit's config object,
|
||||
** and pass it through to the QBit producer.
|
||||
*******************************************************************************/
|
||||
public interface QBitConfig extends Serializable
|
||||
{
|
||||
QLogger LOG = QLogger.getLogger(QBitConfig.class);
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
default void validate(QInstance qInstance) throws QBitConfigValidationException
|
||||
{
|
||||
List<String> errors = new ArrayList<>();
|
||||
|
||||
try
|
||||
{
|
||||
validate(qInstance, errors);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
LOG.warn("Error validating QBitConfig: " + this.getClass().getName(), e);
|
||||
}
|
||||
|
||||
if(!errors.isEmpty())
|
||||
{
|
||||
throw (new QBitConfigValidationException(this, errors));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
default void validate(QInstance qInstance, List<String> errors)
|
||||
{
|
||||
/////////////////////////////////////
|
||||
// nothing to validate by default! //
|
||||
/////////////////////////////////////
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
default boolean assertCondition(boolean condition, String message, List<String> errors)
|
||||
{
|
||||
if(!condition)
|
||||
{
|
||||
errors.add(message);
|
||||
}
|
||||
return (condition);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
default MetaDataCustomizerInterface<QTableMetaData> getTableMetaDataCustomizer()
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2025. 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.qbits;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** thrown by QBitConfig.validate() if there's an issue.
|
||||
*******************************************************************************/
|
||||
public class QBitConfigValidationException extends QException
|
||||
{
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
public QBitConfigValidationException(QBitConfig qBitConfig, List<String> errors)
|
||||
{
|
||||
super("Validation failed for QBitConfig: " + qBitConfig.getClass().getName() + ":\n" + StringUtils.join("\n", errors));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,237 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2025. 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.qbits;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.TopLevelMetaDataInterface;
|
||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Meta-data to define an active QBit in a QQQ Instance.
|
||||
**
|
||||
** The unique "name" for the QBit is composed of its groupId and artifactId
|
||||
** (maven style). There is also a version - but it is not part of the unique
|
||||
** name. But - there is also a namespace attribute, which IS part of the
|
||||
** unique name. This will (eventually?) allow us to have multiple instances
|
||||
** of the same qbit in a qInstance at the same time (e.g., 2 versions of some
|
||||
** table, which should be namespace-prefixed);
|
||||
**
|
||||
** QBitMetaData also retains the QBitConfig that was used to produce the QBit.
|
||||
**
|
||||
** Some meta-data objects are aware of the fact that they may have come from a
|
||||
** QBit - see SourceQBitAware interface. These objects can get their source
|
||||
** QBitMetaData (this object) and its config,via that interface.
|
||||
*******************************************************************************/
|
||||
public class QBitMetaData implements TopLevelMetaDataInterface
|
||||
{
|
||||
private String groupId;
|
||||
private String artifactId;
|
||||
private String version;
|
||||
private String namespace;
|
||||
|
||||
private QBitConfig config;
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
String name = groupId + ":" + artifactId;
|
||||
if(StringUtils.hasContent(namespace))
|
||||
{
|
||||
name += ":" + namespace;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
@Override
|
||||
public void addSelfToInstance(QInstance qInstance)
|
||||
{
|
||||
qInstance.addQBit(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for config
|
||||
*******************************************************************************/
|
||||
public QBitConfig getConfig()
|
||||
{
|
||||
return (this.config);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for config
|
||||
*******************************************************************************/
|
||||
public void setConfig(QBitConfig config)
|
||||
{
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for config
|
||||
*******************************************************************************/
|
||||
public QBitMetaData withConfig(QBitConfig config)
|
||||
{
|
||||
this.config = config;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for groupId
|
||||
*******************************************************************************/
|
||||
public String getGroupId()
|
||||
{
|
||||
return (this.groupId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for groupId
|
||||
*******************************************************************************/
|
||||
public void setGroupId(String groupId)
|
||||
{
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for groupId
|
||||
*******************************************************************************/
|
||||
public QBitMetaData withGroupId(String groupId)
|
||||
{
|
||||
this.groupId = groupId;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for artifactId
|
||||
*******************************************************************************/
|
||||
public String getArtifactId()
|
||||
{
|
||||
return (this.artifactId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for artifactId
|
||||
*******************************************************************************/
|
||||
public void setArtifactId(String artifactId)
|
||||
{
|
||||
this.artifactId = artifactId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for artifactId
|
||||
*******************************************************************************/
|
||||
public QBitMetaData withArtifactId(String artifactId)
|
||||
{
|
||||
this.artifactId = artifactId;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for version
|
||||
*******************************************************************************/
|
||||
public String getVersion()
|
||||
{
|
||||
return (this.version);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for version
|
||||
*******************************************************************************/
|
||||
public void setVersion(String version)
|
||||
{
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for version
|
||||
*******************************************************************************/
|
||||
public QBitMetaData withVersion(String version)
|
||||
{
|
||||
this.version = version;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for namespace
|
||||
*******************************************************************************/
|
||||
public String getNamespace()
|
||||
{
|
||||
return (this.namespace);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for namespace
|
||||
*******************************************************************************/
|
||||
public void setNamespace(String namespace)
|
||||
{
|
||||
this.namespace = namespace;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for namespace
|
||||
*******************************************************************************/
|
||||
public QBitMetaData withNamespace(String namespace)
|
||||
{
|
||||
this.namespace = namespace;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2025. 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.qbits;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerOutput;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData;
|
||||
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** interface for how a QBit's meta-data gets produced and added to a QInstance.
|
||||
**
|
||||
** When implementing a QBit, you'll implement this interface:
|
||||
** - adding a QBitConfig subclass as a property
|
||||
** - overriding the produce(qInstance, namespace) method - where you'll:
|
||||
** -- create and add your QBitMetaData
|
||||
** -- call MetaDataProducerHelper.findProducers
|
||||
** -- hand off to finishProducing() in this interface
|
||||
**
|
||||
** When using a QBit, you'll create an instance of the QBit's config object,
|
||||
** pass it in to the producer, then call produce, ala:
|
||||
**
|
||||
** new SomeQBitProducer()
|
||||
** .withQBitConfig(someQBitConfig)
|
||||
** .produce(qInstance);
|
||||
**
|
||||
*******************************************************************************/
|
||||
public interface QBitProducer
|
||||
{
|
||||
QLogger LOG = QLogger.getLogger(QBitProducer.class);
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
default void produce(QInstance qInstance) throws QException
|
||||
{
|
||||
produce(qInstance, null);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
void produce(QInstance qInstance, String namespace) throws QException;
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
***************************************************************************/
|
||||
default <C extends QBitConfig> void finishProducing(QInstance qInstance, QBitMetaData qBitMetaData, C qBitConfig, List<MetaDataProducerInterface<?>> producers) throws QException
|
||||
{
|
||||
qBitConfig.validate(qInstance);
|
||||
|
||||
///////////////////////////////
|
||||
// todo - move to base class //
|
||||
///////////////////////////////
|
||||
for(MetaDataProducerInterface<?> producer : producers)
|
||||
{
|
||||
if(producer instanceof QBitComponentMetaDataProducer<?, ?>)
|
||||
{
|
||||
QBitComponentMetaDataProducer<?, C> qBitComponentMetaDataProducer = (QBitComponentMetaDataProducer<?, C>) producer;
|
||||
qBitComponentMetaDataProducer.setQBitConfig(qBitConfig);
|
||||
}
|
||||
|
||||
if(!producer.isEnabled())
|
||||
{
|
||||
LOG.debug("Not using producer which is not enabled", logPair("producer", producer.getClass().getSimpleName()));
|
||||
continue;
|
||||
}
|
||||
|
||||
MetaDataProducerOutput output = producer.produce(qInstance);
|
||||
|
||||
/////////////////////////////////////////
|
||||
// apply table customizer, if provided //
|
||||
/////////////////////////////////////////
|
||||
if(qBitConfig.getTableMetaDataCustomizer() != null && output instanceof QTableMetaData table)
|
||||
{
|
||||
output = qBitConfig.getTableMetaDataCustomizer().customizeMetaData(qInstance, table);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// set source qbit, if output is aware of such //
|
||||
/////////////////////////////////////////////////
|
||||
if(output instanceof SourceQBitAware sourceQBitAware)
|
||||
{
|
||||
sourceQBitAware.setSourceQBitName(qBitMetaData.getName());
|
||||
}
|
||||
|
||||
output.addSelfToInstance(qInstance);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2025. 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.qbits;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.context.QContext;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** interface for meta data objects that may have come from a qbit, and where we
|
||||
** might want to get data about that qbit (e.g., config or meta-data).
|
||||
*******************************************************************************/
|
||||
public interface SourceQBitAware
|
||||
{
|
||||
/*******************************************************************************
|
||||
** Getter for sourceQBitName
|
||||
*******************************************************************************/
|
||||
String getSourceQBitName();
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for sourceQBitName
|
||||
*******************************************************************************/
|
||||
void setSourceQBitName(String sourceQBitName);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for sourceQBitName
|
||||
*******************************************************************************/
|
||||
Object withSourceQBitName(String sourceQBitName);
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
default QBitMetaData getSourceQBit()
|
||||
{
|
||||
String qbitName = getSourceQBitName();
|
||||
return (QContext.getQInstance().getQBits().get(qbitName));
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
***************************************************************************/
|
||||
default QBitConfig getSourceQBitConfig()
|
||||
{
|
||||
QBitMetaData sourceQBit = getSourceQBit();
|
||||
if(sourceQBit == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return sourceQBit.getConfig();
|
||||
}
|
||||
}
|
||||
}
|
@ -50,6 +50,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.layout.QAppChildMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.permissions.MetaDataWithPermissionRules;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.permissions.QPermissionRules;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.qbits.SourceQBitAware;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.security.RecordSecurityLock;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.sharing.ShareableTableMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.tables.automation.QTableAutomationDetails;
|
||||
@ -62,7 +63,7 @@ import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
|
||||
** Meta-Data to define a table in a QQQ instance.
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QTableMetaData implements QAppChildMetaData, Serializable, MetaDataWithPermissionRules, TopLevelMetaDataInterface
|
||||
public class QTableMetaData implements QAppChildMetaData, Serializable, MetaDataWithPermissionRules, TopLevelMetaDataInterface, SourceQBitAware
|
||||
{
|
||||
private static final QLogger LOG = QLogger.getLogger(QTableMetaData.class);
|
||||
|
||||
@ -73,6 +74,8 @@ public class QTableMetaData implements QAppChildMetaData, Serializable, MetaData
|
||||
private String primaryKeyField;
|
||||
private boolean isHidden = false;
|
||||
|
||||
private String sourceQBitName;
|
||||
|
||||
private Map<String, QFieldMetaData> fields;
|
||||
private List<UniqueKey> uniqueKeys;
|
||||
private List<Association> associations;
|
||||
@ -1554,4 +1557,38 @@ public class QTableMetaData implements QAppChildMetaData, Serializable, MetaData
|
||||
QInstanceHelpContentManager.removeHelpContentByRoleSetFromList(roles, listForSlot);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for sourceQBitName
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public String getSourceQBitName()
|
||||
{
|
||||
return (this.sourceQBitName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for sourceQBitName
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public void setSourceQBitName(String sourceQBitName)
|
||||
{
|
||||
this.sourceQBitName = sourceQBitName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for sourceQBitName
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public QTableMetaData withSourceQBitName(String sourceQBitName)
|
||||
{
|
||||
this.sourceQBitName = sourceQBitName;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user