mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-19 21:50:45 +00:00
Importing initial codes / checkpoint
This commit is contained in:
@ -0,0 +1,32 @@
|
||||
package com.kingsrook.qqq.backend.core.actions;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.InsertRequest;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.InsertResult;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
||||
import com.kingsrook.qqq.backend.core.modules.QModuleDispatcher;
|
||||
import com.kingsrook.qqq.backend.core.modules.interfaces.QModuleInterface;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class InsertAction
|
||||
{
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public InsertResult execute(InsertRequest insertRequest) throws QException
|
||||
{
|
||||
QModuleDispatcher qModuleDispatcher = new QModuleDispatcher();
|
||||
|
||||
QBackendMetaData backend = insertRequest.getBackend();
|
||||
|
||||
QModuleInterface qModule = qModuleDispatcher.getQModule(backend);
|
||||
// todo pre-customization - just get to modify the request?
|
||||
InsertResult insertResult = qModule.getInsertInterface().execute(insertRequest);
|
||||
// todo post-customization - can do whatever w/ the result if you want
|
||||
return insertResult;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.kingsrook.qqq.backend.core.actions;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.QueryRequest;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.QueryResult;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
||||
import com.kingsrook.qqq.backend.core.modules.QModuleDispatcher;
|
||||
import com.kingsrook.qqq.backend.core.modules.interfaces.QModuleInterface;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QueryAction
|
||||
{
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QueryResult execute(QueryRequest queryRequest) throws QException
|
||||
{
|
||||
QModuleDispatcher qModuleDispatcher = new QModuleDispatcher();
|
||||
|
||||
QBackendMetaData backend = queryRequest.getBackend();
|
||||
|
||||
QModuleInterface qModule = qModuleDispatcher.getQModule(backend);
|
||||
// todo pre-customization - just get to modify the request?
|
||||
QueryResult queryResult = qModule.getQueryInterface().execute(queryRequest);
|
||||
// todo post-customization - can do whatever w/ the result if you want
|
||||
return queryResult;
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package com.kingsrook.qqq.backend.core.adapters;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractQFieldMapping;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.QKeyBasedFieldMapping;
|
||||
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class JsonToQFieldMappingAdapter
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public AbstractQFieldMapping<?> buildMappingFromJson(String json)
|
||||
{
|
||||
if(!StringUtils.hasContent(json))
|
||||
{
|
||||
throw (new IllegalArgumentException("Empty json value was provided."));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
JSONObject jsonObject = JsonUtils.toJSONObject(json);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// look at the keys in the mapping - if they're strings, then we're doing key-based mapping //
|
||||
// if they're numbers, then we're doing index based -- and if they're a mix, that's illegal //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
QKeyBasedFieldMapping mapping = new QKeyBasedFieldMapping();
|
||||
for(String key : jsonObject.keySet())
|
||||
{
|
||||
mapping.addMapping(key, jsonObject.getString(key));
|
||||
}
|
||||
return (mapping);
|
||||
}
|
||||
catch(JSONException je)
|
||||
{
|
||||
throw (new IllegalArgumentException("Malformed JSON value: " + je.getMessage(), je));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package com.kingsrook.qqq.backend.core.adapters;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class JsonToQRecordAdapter
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
** todo - meta-data validation, mapping, type handling
|
||||
*******************************************************************************/
|
||||
public List<QRecord> buildRecordsFromJson(String json)
|
||||
{
|
||||
if(!StringUtils.hasContent(json))
|
||||
{
|
||||
throw (new IllegalArgumentException("Empty json value was provided."));
|
||||
}
|
||||
|
||||
List<QRecord> rs = new ArrayList<>();
|
||||
try
|
||||
{
|
||||
if(JsonUtils.looksLikeObject(json))
|
||||
{
|
||||
JSONObject jsonObject = JsonUtils.toJSONObject(json);
|
||||
rs.add(buildRecordFromJsonObject(jsonObject));
|
||||
}
|
||||
else if(JsonUtils.looksLikeArray(json))
|
||||
{
|
||||
JSONArray jsonArray = JsonUtils.toJSONArray(json);
|
||||
for(Object object : jsonArray)
|
||||
{
|
||||
if(object instanceof JSONObject jsonObject)
|
||||
{
|
||||
rs.add(buildRecordFromJsonObject(jsonObject));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw (new IllegalArgumentException("Element at index " + rs.size() + " in json array was not a json object."));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw (new IllegalArgumentException("Malformed JSON value - did not start with '{' or '['."));
|
||||
}
|
||||
}
|
||||
catch(JSONException je)
|
||||
{
|
||||
throw (new IllegalArgumentException("Malformed JSON value: " + je.getMessage(), je));
|
||||
}
|
||||
|
||||
return (rs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** todo - meta-data validation, mapping, type handling
|
||||
*******************************************************************************/
|
||||
private QRecord buildRecordFromJsonObject(JSONObject jsonObject)
|
||||
{
|
||||
QRecord record = new QRecord();
|
||||
|
||||
for(String key : jsonObject.keySet())
|
||||
{
|
||||
record.setValue(key, (Serializable) jsonObject.get(key));
|
||||
}
|
||||
|
||||
return (record);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.kingsrook.qqq.backend.core.exceptions;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Base class for checked exceptions thrown in qqq.
|
||||
*
|
||||
*******************************************************************************/
|
||||
public class QException extends Exception
|
||||
{
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QException(String message, Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.kingsrook.qqq.backend.core.exceptions;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Base class for checked exceptions thrown in qqq.
|
||||
*
|
||||
*******************************************************************************/
|
||||
public class QModuleDispatchException extends QException
|
||||
{
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QModuleDispatchException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QModuleDispatchException(String message, Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
package com.kingsrook.qqq.backend.core.model;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QInstance
|
||||
{
|
||||
private Map<String, QBackendMetaData> backends = new HashMap<>();
|
||||
private Map<String, QTableMetaData> tables = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QBackendMetaData getBackendForTable(String tableName)
|
||||
{
|
||||
QTableMetaData table = tables.get(tableName);
|
||||
if(table == null)
|
||||
{
|
||||
throw (new IllegalArgumentException("No table with name [" + tableName + "] found in this instance."));
|
||||
}
|
||||
|
||||
QBackendMetaData backend = backends.get(table.getBackendName());
|
||||
if(backend == null)
|
||||
{
|
||||
throw (new IllegalArgumentException("Table [" + tableName + "] specified a backend name [" + table.getBackendName() + "] which was found in this instance."));
|
||||
}
|
||||
|
||||
return (backend);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addBackend(QBackendMetaData backend)
|
||||
{
|
||||
this.backends.put(backend.getName(), backend);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addBackend(String name, QBackendMetaData backend)
|
||||
{
|
||||
this.backends.put(name, backend);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QBackendMetaData getBackend(String name)
|
||||
{
|
||||
return (this.backends.get(name));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addTable(QTableMetaData table)
|
||||
{
|
||||
this.tables.put(table.getName(), table);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addTable(String name, QTableMetaData table)
|
||||
{
|
||||
this.tables.put(name, table);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QTableMetaData getTable(String name)
|
||||
{
|
||||
return (this.tables.get(name));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for backends
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Map<String, QBackendMetaData> getBackends()
|
||||
{
|
||||
return backends;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for backends
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setBackends(Map<String, QBackendMetaData> backends)
|
||||
{
|
||||
this.backends = backends;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for tables
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Map<String, QTableMetaData> getTables()
|
||||
{
|
||||
return tables;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for tables
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setTables(Map<String, QTableMetaData> tables)
|
||||
{
|
||||
this.tables = tables;
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.kingsrook.qqq.backend.core.model.actions;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public abstract class AbstractQFieldMapping<T>
|
||||
{
|
||||
/*******************************************************************************
|
||||
** Returns the fieldName for the input 'key' or 'index'.
|
||||
*******************************************************************************/
|
||||
public abstract String getMappedField(T t);
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.kingsrook.qqq.backend.core.model.actions;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.model.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public abstract class AbstractQRequest
|
||||
{
|
||||
protected QInstance instance;
|
||||
// todo session
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public abstract QBackendMetaData getBackend();
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public AbstractQRequest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public AbstractQRequest(QInstance instance)
|
||||
{
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for instance
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QInstance getInstance()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for instance
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setInstance(QInstance instance)
|
||||
{
|
||||
this.instance = instance;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.kingsrook.qqq.backend.core.model.actions;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public abstract class AbstractQResult
|
||||
{
|
||||
// todo - status codes?
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public AbstractQResult()
|
||||
{
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package com.kingsrook.qqq.backend.core.model.actions;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.model.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QTableMetaData;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public abstract class AbstractQTableRequest extends AbstractQRequest
|
||||
{
|
||||
private String tableName;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public QBackendMetaData getBackend()
|
||||
{
|
||||
return (instance.getBackendForTable(getTableName()));
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QTableMetaData getTable()
|
||||
{
|
||||
return (instance.getTable(getTableName()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public AbstractQTableRequest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public AbstractQTableRequest(QInstance instance)
|
||||
{
|
||||
super(instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for tableName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getTableName()
|
||||
{
|
||||
return tableName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for tableName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setTableName(String tableName)
|
||||
{
|
||||
this.tableName = tableName;
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.kingsrook.qqq.backend.core.model.actions;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.model.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class InsertRequest extends AbstractQTableRequest
|
||||
{
|
||||
private List<QRecord> records;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public InsertRequest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public InsertRequest(QInstance instance)
|
||||
{
|
||||
super(instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for records
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QRecord> getRecords()
|
||||
{
|
||||
return records;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for records
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setRecords(List<QRecord> records)
|
||||
{
|
||||
this.records = records;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.kingsrook.qqq.backend.core.model.actions;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecordWithStatus;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Result for a query action
|
||||
*
|
||||
*******************************************************************************/
|
||||
public class InsertResult extends AbstractQResult
|
||||
{
|
||||
List<QRecordWithStatus> records;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QRecordWithStatus> getRecords()
|
||||
{
|
||||
return records;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setRecords(List<QRecordWithStatus> records)
|
||||
{
|
||||
this.records = records;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.kingsrook.qqq.backend.core.model.actions;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public enum QCriteriaOperator
|
||||
{
|
||||
EQUALS,
|
||||
NOT_EQUALS,
|
||||
IN
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
package com.kingsrook.qqq.backend.core.model.actions;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Component of a Query
|
||||
*
|
||||
*******************************************************************************/
|
||||
public class QFilterCriteria
|
||||
{
|
||||
private String fieldName;
|
||||
private QCriteriaOperator operator;
|
||||
private List<Serializable> values;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for fieldName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getFieldName()
|
||||
{
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for fieldName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setFieldName(String fieldName)
|
||||
{
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for fieldName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QFilterCriteria withFieldName(String fieldName)
|
||||
{
|
||||
this.fieldName = fieldName;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for operator
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QCriteriaOperator getOperator()
|
||||
{
|
||||
return operator;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for operator
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setOperator(QCriteriaOperator operator)
|
||||
{
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for operator
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QFilterCriteria withOperator(QCriteriaOperator operator)
|
||||
{
|
||||
this.operator = operator;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for values
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<Serializable> getValues()
|
||||
{
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for values
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setValues(List<Serializable> values)
|
||||
{
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for values
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QFilterCriteria withValues(List<Serializable> values)
|
||||
{
|
||||
this.values = values;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package com.kingsrook.qqq.backend.core.model.actions;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QFilterOrderBy
|
||||
{
|
||||
private String fieldName;
|
||||
private boolean isAscending = true;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for fieldName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getFieldName()
|
||||
{
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for fieldName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setFieldName(String fieldName)
|
||||
{
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for isAscending
|
||||
**
|
||||
*******************************************************************************/
|
||||
public boolean getIsAscending()
|
||||
{
|
||||
return isAscending;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for isAscending
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setIsAscending(boolean ascending)
|
||||
{
|
||||
isAscending = ascending;
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package com.kingsrook.qqq.backend.core.model.actions;
|
||||
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Note; 1-based index!!
|
||||
*******************************************************************************/
|
||||
public class QIndexBasedFieldMapping extends AbstractQFieldMapping<Integer>
|
||||
{
|
||||
private Map<Integer, String> mapping;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public String getMappedField(Integer key)
|
||||
{
|
||||
if(mapping == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
return (mapping.get(key));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addMapping(Integer key, String fieldName)
|
||||
{
|
||||
if(mapping == null)
|
||||
{
|
||||
mapping = new LinkedHashMap<>();
|
||||
}
|
||||
mapping.put(key, fieldName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QIndexBasedFieldMapping withMapping(Integer key, String fieldName)
|
||||
{
|
||||
addMapping(key, fieldName);
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for mapping
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Map<Integer, String> getMapping()
|
||||
{
|
||||
return mapping;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for mapping
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setMapping(Map<Integer, String> mapping)
|
||||
{
|
||||
this.mapping = mapping;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package com.kingsrook.qqq.backend.core.model.actions;
|
||||
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QKeyBasedFieldMapping extends AbstractQFieldMapping<String>
|
||||
{
|
||||
private Map<String, String> mapping;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Override
|
||||
public String getMappedField(String key)
|
||||
{
|
||||
if(mapping == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
return (mapping.get(key));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addMapping(String key, String fieldName)
|
||||
{
|
||||
if(mapping == null)
|
||||
{
|
||||
mapping = new LinkedHashMap<>();
|
||||
}
|
||||
mapping.put(key, fieldName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QKeyBasedFieldMapping withMapping(String key, String fieldName)
|
||||
{
|
||||
addMapping(key, fieldName);
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for mapping
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Map<String, String> getMapping()
|
||||
{
|
||||
return mapping;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for mapping
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setMapping(Map<String, String> mapping)
|
||||
{
|
||||
this.mapping = mapping;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
package com.kingsrook.qqq.backend.core.model.actions;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Full "filter" for a query - a list of criteria and order-bys
|
||||
*
|
||||
*******************************************************************************/
|
||||
public class QQueryFilter
|
||||
{
|
||||
private List<QFilterCriteria> criteria = new ArrayList<>();
|
||||
private List<QFilterOrderBy> orderBys = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for criteria
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QFilterCriteria> getCriteria()
|
||||
{
|
||||
return criteria;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for criteria
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setCriteria(List<QFilterCriteria> criteria)
|
||||
{
|
||||
this.criteria = criteria;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for order
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QFilterOrderBy> getOrderBys()
|
||||
{
|
||||
return orderBys;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for order
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setOrderBys(List<QFilterOrderBy> orderBys)
|
||||
{
|
||||
this.orderBys = orderBys;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addCriteria(QFilterCriteria qFilterCriteria)
|
||||
{
|
||||
if(criteria == null)
|
||||
{
|
||||
criteria = new ArrayList<>();
|
||||
}
|
||||
criteria.add(qFilterCriteria);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QQueryFilter withCriteria(QFilterCriteria qFilterCriteria)
|
||||
{
|
||||
addCriteria(qFilterCriteria);
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addOrderBy(QFilterOrderBy qFilterOrderBy)
|
||||
{
|
||||
if(orderBys == null)
|
||||
{
|
||||
orderBys = new ArrayList<>();
|
||||
}
|
||||
orderBys.add(qFilterOrderBy);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QQueryFilter withOrderBy(QFilterOrderBy qFilterOrderBy)
|
||||
{
|
||||
addOrderBy(qFilterOrderBy);
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
package com.kingsrook.qqq.backend.core.model.actions;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.model.QInstance;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QueryRequest extends AbstractQTableRequest
|
||||
{
|
||||
private QQueryFilter filter;
|
||||
private Integer skip;
|
||||
private Integer limit;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QueryRequest()
|
||||
{
|
||||
System.out.println("In the Query Request void-constructor!");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QueryRequest(QInstance instance)
|
||||
{
|
||||
super(instance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for filter
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QQueryFilter getFilter()
|
||||
{
|
||||
return filter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for filter
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setFilter(QQueryFilter filter)
|
||||
{
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for skip
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Integer getSkip()
|
||||
{
|
||||
return skip;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for skip
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setSkip(Integer skip)
|
||||
{
|
||||
this.skip = skip;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for limit
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Integer getLimit()
|
||||
{
|
||||
return limit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for limit
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setLimit(Integer limit)
|
||||
{
|
||||
this.limit = limit;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.kingsrook.qqq.backend.core.model.actions;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
import com.kingsrook.qqq.backend.core.model.data.QRecord;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Result for a query action
|
||||
*
|
||||
*******************************************************************************/
|
||||
public class QueryResult extends AbstractQResult
|
||||
{
|
||||
List<QRecord> records;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QRecord> getRecords()
|
||||
{
|
||||
return records;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setRecords(List<QRecord> records)
|
||||
{
|
||||
this.records = records;
|
||||
}
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
package com.kingsrook.qqq.backend.core.model.data;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Data Record within qqq
|
||||
*
|
||||
*******************************************************************************/
|
||||
public class QRecord
|
||||
{
|
||||
private String tableName;
|
||||
private Serializable primaryKey;
|
||||
private Map<String, Serializable> values;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setValue(String fieldName, Serializable value)
|
||||
{
|
||||
if(values == null)
|
||||
{
|
||||
values = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
values.put(fieldName, value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for tableName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getTableName()
|
||||
{
|
||||
return tableName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for tableName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setTableName(String tableName)
|
||||
{
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for primaryKey
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Serializable getPrimaryKey()
|
||||
{
|
||||
return primaryKey;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for primaryKey
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setPrimaryKey(Serializable primaryKey)
|
||||
{
|
||||
this.primaryKey = primaryKey;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for values
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Map<String, Serializable> getValues()
|
||||
{
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for values
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setValues(Map<String, Serializable> values)
|
||||
{
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for a single field's value
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Serializable getValue(String fieldName)
|
||||
{
|
||||
return (values.get(fieldName));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for a single field's value
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getValueString(String fieldName)
|
||||
{
|
||||
return ((String) values.get(fieldName));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for a single field's value
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Integer getValueInteger(String fieldName)
|
||||
{
|
||||
return ((Integer) values.get(fieldName));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.kingsrook.qqq.backend.core.model.data;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QRecordWithStatus extends QRecord
|
||||
{
|
||||
private List<Exception> errors;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QRecordWithStatus()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QRecordWithStatus(QRecord record)
|
||||
{
|
||||
super.setTableName(record.getTableName());
|
||||
super.setPrimaryKey(record.getPrimaryKey());
|
||||
super.setValues(record.getValues());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for errors
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<Exception> getErrors()
|
||||
{
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for errors
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setErrors(List<Exception> errors)
|
||||
{
|
||||
this.errors = errors;
|
||||
}
|
||||
}
|
@ -0,0 +1,155 @@
|
||||
package com.kingsrook.qqq.backend.core.model.metadata;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QBackendMetaData
|
||||
{
|
||||
private String name;
|
||||
private String type;
|
||||
private Map<String, String> values;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getValue(String key)
|
||||
{
|
||||
if(values == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return values.get(key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setValue(String key, String value)
|
||||
{
|
||||
if(values == null)
|
||||
{
|
||||
values = new HashMap<>();
|
||||
}
|
||||
values.put(key, value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QBackendMetaData withValue(String key, String value)
|
||||
{
|
||||
if(values == null)
|
||||
{
|
||||
values = new HashMap<>();
|
||||
}
|
||||
values.put(key, value);
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QBackendMetaData withName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setType(String type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QBackendMetaData withType(String type)
|
||||
{
|
||||
this.type = type;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Map<String, String> getValues()
|
||||
{
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setValues(Map<String, String> values)
|
||||
{
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QBackendMetaData withVales(Map<String, String> values)
|
||||
{
|
||||
this.values = values;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
package com.kingsrook.qqq.backend.core.model.metadata;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QFieldMetaData
|
||||
{
|
||||
private String name;
|
||||
private String label;
|
||||
private String backendName;
|
||||
private QFieldType type;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QFieldMetaData()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QFieldMetaData(String name, QFieldType type)
|
||||
{
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QFieldMetaData withName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QFieldType getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for type
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setType(QFieldType type)
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QFieldMetaData withType(QFieldType type)
|
||||
{
|
||||
this.type = type;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for label
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getLabel()
|
||||
{
|
||||
return label;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for label
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setLabel(String label)
|
||||
{
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QFieldMetaData withLabel(String label)
|
||||
{
|
||||
this.label = label;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for backendName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getBackendName()
|
||||
{
|
||||
return backendName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for backendName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setBackendName(String backendName)
|
||||
{
|
||||
this.backendName = backendName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QFieldMetaData withBackendName(String backendName)
|
||||
{
|
||||
this.backendName = backendName;
|
||||
return (this);
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.kingsrook.qqq.backend.core.model.metadata;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public enum QFieldType
|
||||
{
|
||||
STRING,
|
||||
INTEGER,
|
||||
DECIMAL,
|
||||
DATE,
|
||||
TIME,
|
||||
DATE_TIME,
|
||||
TEXT,
|
||||
HTML,
|
||||
PASSWORD
|
||||
}
|
@ -0,0 +1,216 @@
|
||||
package com.kingsrook.qqq.backend.core.model.metadata;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QTableMetaData
|
||||
{
|
||||
private String name;
|
||||
private String backendName;
|
||||
private String primaryKeyField;
|
||||
private List<QFieldMetaData> fields;
|
||||
private Map<String, QFieldMetaData> _fieldMap;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QFieldMetaData getField(String fieldName)
|
||||
{
|
||||
if(fields == null)
|
||||
{
|
||||
throw (new IllegalArgumentException("Table [" + name + "] does not have its fields defined."));
|
||||
}
|
||||
|
||||
QFieldMetaData field = getFieldMap().get(fieldName);
|
||||
if(field == null)
|
||||
{
|
||||
throw (new IllegalArgumentException("Field [" + fieldName + "] was not found in table [" + name + "]."));
|
||||
}
|
||||
|
||||
return (field);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private Map<String, QFieldMetaData> getFieldMap()
|
||||
{
|
||||
if(_fieldMap == null)
|
||||
{
|
||||
_fieldMap = new LinkedHashMap<>();
|
||||
for(QFieldMetaData field : fields)
|
||||
{
|
||||
_fieldMap.put(field.getName(), field);
|
||||
}
|
||||
}
|
||||
|
||||
return (_fieldMap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QTableMetaData withName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for backendName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getBackendName()
|
||||
{
|
||||
return backendName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for backendName
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setBackendName(String backendName)
|
||||
{
|
||||
this.backendName = backendName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QTableMetaData withBackendName(String backendName)
|
||||
{
|
||||
this.backendName = backendName;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public String getPrimaryKeyField()
|
||||
{
|
||||
return primaryKeyField;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setPrimaryKeyField(String primaryKeyField)
|
||||
{
|
||||
this.primaryKeyField = primaryKeyField;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QTableMetaData withPrimaryKeyField(String primaryKeyField)
|
||||
{
|
||||
this.primaryKeyField = primaryKeyField;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<QFieldMetaData> getFields()
|
||||
{
|
||||
return fields;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void setFields(List<QFieldMetaData> fields)
|
||||
{
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QTableMetaData withFields(List<QFieldMetaData> fields)
|
||||
{
|
||||
this.fields = fields;
|
||||
return (this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addField(QFieldMetaData field)
|
||||
{
|
||||
if(this.fields == null)
|
||||
{
|
||||
this.fields = new ArrayList<>();
|
||||
}
|
||||
this.fields.add(field);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QTableMetaData withField(QFieldMetaData field)
|
||||
{
|
||||
if(this.fields == null)
|
||||
{
|
||||
this.fields = new ArrayList<>();
|
||||
}
|
||||
this.fields.add(field);
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.kingsrook.qqq.backend.core.modules;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QModuleDispatchException;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QBackendMetaData;
|
||||
import com.kingsrook.qqq.backend.core.modules.interfaces.QModuleInterface;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class QModuleDispatcher
|
||||
{
|
||||
private Map<String, String> backendTypeToModuleClassNameMap;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QModuleDispatcher()
|
||||
{
|
||||
backendTypeToModuleClassNameMap = new HashMap<>();
|
||||
backendTypeToModuleClassNameMap.put("rdbms", "com.kingsrook.qqq.backend.module.rdbms.RDBSMModule");
|
||||
backendTypeToModuleClassNameMap.put("nosql", "com.kingsrook.qqq.backend.module.nosql.NoSQLModule");
|
||||
// todo - let user define custom type -> classes
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public QModuleInterface getQModule(QBackendMetaData backend) throws QModuleDispatchException
|
||||
{
|
||||
try
|
||||
{
|
||||
String className = backendTypeToModuleClassNameMap.get(backend.getType());
|
||||
if (className == null)
|
||||
{
|
||||
throw (new QModuleDispatchException("Unrecognized backend type [" + backend.getType() + "] in dispatcher."));
|
||||
}
|
||||
|
||||
Class<?> moduleClass = Class.forName(className);
|
||||
return (QModuleInterface) moduleClass.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
catch(QModuleDispatchException qmde)
|
||||
{
|
||||
throw (qmde);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
throw (new QModuleDispatchException("Error getting module", e));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.kingsrook.qqq.backend.core.modules.interfaces;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.InsertRequest;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.InsertResult;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public interface InsertInterface
|
||||
{
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
InsertResult execute(InsertRequest insertRequest) throws QException;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.kingsrook.qqq.backend.core.modules.interfaces;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.actions.InsertAction;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public interface QModuleInterface
|
||||
{
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
QueryInterface getQueryInterface();
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
InsertInterface getInsertInterface();
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.kingsrook.qqq.backend.core.modules.interfaces;
|
||||
|
||||
|
||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.QueryRequest;
|
||||
import com.kingsrook.qqq.backend.core.model.actions.QueryResult;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public interface QueryInterface
|
||||
{
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
QueryResult execute(QueryRequest queryRequest) throws QException;
|
||||
}
|
257
src/main/java/com/kingsrook/qqq/backend/core/utils/CollectionUtils.java
Executable file
257
src/main/java/com/kingsrook/qqq/backend/core/utils/CollectionUtils.java
Executable file
@ -0,0 +1,257 @@
|
||||
package com.kingsrook.qqq.backend.core.utils;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class CollectionUtils
|
||||
{
|
||||
/*******************************************************************************
|
||||
** true if c is null or it's empty
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static boolean nullSafeIsEmpty(Collection c)
|
||||
{
|
||||
if(c == null || c.isEmpty())
|
||||
{
|
||||
return (true);
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** true if c is NOT null and it's not empty
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static boolean nullSafeHasContents(Collection c)
|
||||
{
|
||||
return (!nullSafeIsEmpty(c));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** 0 if c is empty, otherwise, its size.
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static int nullSafeSize(Collection c)
|
||||
{
|
||||
if(c == null)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (c.size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static <K, V> void addAllToMap(Map<K, V> addingTo, Map<K, V> addingFrom)
|
||||
{
|
||||
for(K key : addingFrom.keySet())
|
||||
{
|
||||
addingTo.put(key, addingFrom.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static <K, V> Map<K, V> listToMap(List<V> values, Function<V, ? extends K> keyFunction)
|
||||
{
|
||||
if(values == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
Map<K, V> rs = new HashMap<>();
|
||||
for(V value : values)
|
||||
{
|
||||
rs.put(keyFunction.apply(value), value);
|
||||
}
|
||||
|
||||
return (rs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static <E, K, V> Map<K, V> listToMap(List<E> elements, Function<E, ? extends K> keyFunction, Function<E, ? extends V> valueFunction)
|
||||
{
|
||||
if(elements == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
Map<K, V> rs = new HashMap<>();
|
||||
for(E element : elements)
|
||||
{
|
||||
rs.put(keyFunction.apply(element), valueFunction.apply(element));
|
||||
}
|
||||
|
||||
return (rs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static <K, V> ListingHash<K, V> listToListingHash(List<V> values, Function<V, ? extends K> keyFunction)
|
||||
{
|
||||
if(values == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
ListingHash<K, V> rs = new ListingHash<>();
|
||||
for(V value : values)
|
||||
{
|
||||
rs.add(keyFunction.apply(value), value);
|
||||
}
|
||||
|
||||
return (rs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* <p>Take a list of objects, and build a listing hash, using 2 lambdas to control
|
||||
* how keys in the listing hash are created (from the objects), and how values
|
||||
* are created.</p>
|
||||
*
|
||||
* <p>For example, given a list of Work records, if we want a Listing hash with
|
||||
* workStatusId as keys, and workId a values, we would call:</p>
|
||||
*
|
||||
* <code>listToListingHash(workList, Work::getWorkStatusId, Work::getId)</code>
|
||||
*
|
||||
* @param elements list of objects to be mapped
|
||||
* @param keyFunction function to map an object from elements list into keys
|
||||
* for the listing hash
|
||||
* @param valueFunction function to map an object from elements list into values
|
||||
* for the listing hash
|
||||
*
|
||||
* @return ListingHash that might look like:
|
||||
* 1 -> [ 73, 75, 68]
|
||||
* 2 -> [ 74 ]
|
||||
* 4 -> [ 76, 77, 79, 80, 81]
|
||||
*
|
||||
* end
|
||||
*******************************************************************************/
|
||||
public static <E, K, V> ListingHash<K, V> listToListingHash(List<E> elements, Function<E, ? extends K> keyFunction, Function<E, ? extends V> valueFunction)
|
||||
{
|
||||
if(elements == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
ListingHash<K, V> rs = new ListingHash<>();
|
||||
for(E element : elements)
|
||||
{
|
||||
rs.add(keyFunction.apply(element), valueFunction.apply(element));
|
||||
}
|
||||
|
||||
return (rs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static <K1, K2, V> Map<K1, Map<K2, V>> listTo2LevelMap(List<V> values, Function<V, ? extends K1> keyFunction1, Function<V, ? extends K2> keyFunction2)
|
||||
{
|
||||
if(values == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
Map<K1, Map<K2, V>> rs = new HashMap<>();
|
||||
for(V value : values)
|
||||
{
|
||||
K1 k1 = keyFunction1.apply(value);
|
||||
if(!rs.containsKey(k1))
|
||||
{
|
||||
rs.put(k1, new HashMap<>());
|
||||
}
|
||||
rs.get(k1).put(keyFunction2.apply(value), value);
|
||||
}
|
||||
|
||||
return (rs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** split a large collection into lists of lists, with specified pageSize
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static <T> List<List<T>> getPages(Collection<T> values, int pageSize)
|
||||
{
|
||||
List<List<T>> rs = new LinkedList<>();
|
||||
|
||||
if(values.isEmpty())
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// if there are no input values, return an empty list of lists. //
|
||||
//////////////////////////////////////////////////////////////////
|
||||
return (rs);
|
||||
}
|
||||
|
||||
List<T> currentPage = new LinkedList<T>();
|
||||
rs.add(currentPage);
|
||||
|
||||
for(T value : values)
|
||||
{
|
||||
if(currentPage.size() >= pageSize)
|
||||
{
|
||||
currentPage = new LinkedList<T>();
|
||||
rs.add(currentPage);
|
||||
}
|
||||
|
||||
currentPage.add(value);
|
||||
}
|
||||
|
||||
return (rs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static String getQuestionMarks(Collection<?> c)
|
||||
{
|
||||
if(CollectionUtils.nullSafeIsEmpty(c))
|
||||
{
|
||||
return ("");
|
||||
}
|
||||
|
||||
StringBuilder rs = new StringBuilder();
|
||||
for(int i = 0; i < c.size(); i++)
|
||||
{
|
||||
rs.append(i > 0 ? "," : "").append("?");
|
||||
}
|
||||
|
||||
return (rs.toString());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
package com.kingsrook.qqq.backend.core.utils;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** See: https://www.baeldung.com/jackson-vs-gson
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class JsonUtils
|
||||
{
|
||||
private static final Logger LOG = LogManager.getLogger(JsonUtils.class);
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static String toJson(Object object)
|
||||
{
|
||||
try
|
||||
{
|
||||
ObjectMapper mapper = newObjectMapper();
|
||||
String jsonResult = mapper.writeValueAsString(object);
|
||||
return (jsonResult);
|
||||
}
|
||||
catch(JsonProcessingException e)
|
||||
{
|
||||
LOG.error("Error serializing object of type [" + object.getClass().getSimpleName() + "] to json", e);
|
||||
throw new IllegalArgumentException("Error in JSON Serialization", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static String toPrettyJson(Object object)
|
||||
{
|
||||
try
|
||||
{
|
||||
ObjectMapper mapper = newObjectMapper();
|
||||
ObjectWriter objectWriter = mapper.writerWithDefaultPrettyPrinter();
|
||||
String jsonResult = objectWriter.writeValueAsString(object);
|
||||
return (jsonResult);
|
||||
}
|
||||
catch(JsonProcessingException e)
|
||||
{
|
||||
LOG.error("Error serializing object of type [" + object.getClass().getSimpleName() + "] to json", e);
|
||||
throw new IllegalArgumentException("Error in JSON Serialization", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static JSONObject toJSONObject(String json) throws JSONException
|
||||
{
|
||||
JSONObject jsonObject = new JSONObject(json);
|
||||
return (jsonObject);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static JSONArray toJSONArray(String json) throws JSONException
|
||||
{
|
||||
JSONArray jsonArray = new JSONArray(json);
|
||||
return (jsonArray);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static ObjectMapper newObjectMapper()
|
||||
{
|
||||
ObjectMapper mapper = new ObjectMapper()
|
||||
.registerModule(new JavaTimeModule())
|
||||
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
|
||||
return (mapper);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static boolean looksLikeObject(String json)
|
||||
{
|
||||
return (json != null && json.matches("(?s)\\s*\\{.*"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static boolean looksLikeArray(String json)
|
||||
{
|
||||
return (json != null && json.matches("(?s)\\s*\\[.*"));
|
||||
}
|
||||
}
|
267
src/main/java/com/kingsrook/qqq/backend/core/utils/ListingHash.java
Executable file
267
src/main/java/com/kingsrook/qqq/backend/core/utils/ListingHash.java
Executable file
@ -0,0 +1,267 @@
|
||||
package com.kingsrook.qqq.backend.core.utils;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Hash that provides "listing" capability -- keys map to lists of values that
|
||||
** are automatically/easily added to
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class ListingHash<K, V> implements Map<K, List<V>>, Serializable
|
||||
{
|
||||
public static final long serialVersionUID = 0L;
|
||||
|
||||
private HashMap<K, List<V>> hashMap = null;
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Default constructor
|
||||
**
|
||||
*******************************************************************************/
|
||||
public ListingHash()
|
||||
{
|
||||
this.hashMap = new HashMap<K, List<V>>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Add a value to the entry/list for this key
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<V> add(K key, V value)
|
||||
{
|
||||
List<V> list = getOrCreateListForKey(key);
|
||||
list.add(value);
|
||||
return (list);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Add all elements of the collection of v's to this listing hash, using keys
|
||||
** generated by passing each v to the supplied keyFunction (which return's K's)
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addAll(Collection<V> vs, Function<V, K> keyFunction)
|
||||
{
|
||||
if(vs == null || keyFunction == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(V v : vs)
|
||||
{
|
||||
add(keyFunction.apply(v), v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Add multiple values to the entry/list for this key
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<V> addAll(K key, Collection<V> values)
|
||||
{
|
||||
List<V> list = getOrCreateListForKey(key);
|
||||
list.addAll(values);
|
||||
return (list);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void addAll(ListingHash<K, V> that)
|
||||
{
|
||||
if(that == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(K key : that.keySet())
|
||||
{
|
||||
addAll(key, that.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private List<V> getOrCreateListForKey(K key)
|
||||
{
|
||||
List<V> list;
|
||||
|
||||
if(!this.hashMap.containsKey(key))
|
||||
{
|
||||
/////////////////////////////////
|
||||
// create list, place into map //
|
||||
/////////////////////////////////
|
||||
list = new LinkedList<V>();
|
||||
this.hashMap.put(key, list);
|
||||
}
|
||||
else
|
||||
{
|
||||
list = this.hashMap.get(key);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// wrappings of methods taken from the internal HashMap of this object //
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void clear()
|
||||
{
|
||||
this.hashMap.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public boolean containsKey(Object key)
|
||||
{
|
||||
return (this.hashMap.containsKey(key));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public boolean containsValue(Object value)
|
||||
{
|
||||
return (this.hashMap.containsValue(value));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Set<Entry<K, List<V>>> entrySet()
|
||||
{
|
||||
return (this.hashMap.entrySet());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
return (this.hashMap.equals(o));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<V> get(Object key)
|
||||
{
|
||||
return (this.hashMap.get(key));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public int hashCode()
|
||||
{
|
||||
return (this.hashMap.hashCode());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return (this.hashMap.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Set<K> keySet()
|
||||
{
|
||||
return (this.hashMap.keySet());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<V> put(K key, List<V> value)
|
||||
{
|
||||
return (this.hashMap.put(key, value));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public void putAll(Map<? extends K, ? extends List<V>> t)
|
||||
{
|
||||
this.hashMap.putAll(t);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public List<V> remove(Object key)
|
||||
{
|
||||
return (this.hashMap.remove(key));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public int size()
|
||||
{
|
||||
return (this.hashMap.size());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public Collection<List<V>> values()
|
||||
{
|
||||
return (this.hashMap.values());
|
||||
}
|
||||
}
|
373
src/main/java/com/kingsrook/qqq/backend/core/utils/StringUtils.java
Executable file
373
src/main/java/com/kingsrook/qqq/backend/core/utils/StringUtils.java
Executable file
@ -0,0 +1,373 @@
|
||||
package com.kingsrook.qqq.backend.core.utils;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public class StringUtils
|
||||
{
|
||||
/*******************************************************************************
|
||||
** test if string is not null and is not empty (after being trimmed).
|
||||
**
|
||||
** @param input the string to test
|
||||
** @return Boolean
|
||||
*******************************************************************************/
|
||||
public static Boolean hasContent(String input)
|
||||
{
|
||||
if(input != null && !input.trim().equals(""))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** returns input.toString() if not null, or nullOutput if input == null (as in SQL NVL)
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static String nvl(Object input, String nullOutput)
|
||||
{
|
||||
if(input == null)
|
||||
{
|
||||
return nullOutput;
|
||||
}
|
||||
return input.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** returns input if not null, or nullOutput if input == null (as in SQL NVL)
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static String nvl(String input, String nullOutput)
|
||||
{
|
||||
if(input == null)
|
||||
{
|
||||
return nullOutput;
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** allCapsToMixedCase - ie, UNIT CODE -> Unit Code
|
||||
**
|
||||
** @param input
|
||||
** @return
|
||||
*******************************************************************************/
|
||||
public static String allCapsToMixedCase(String input)
|
||||
{
|
||||
if(input == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
StringBuilder rs = new StringBuilder();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// match for 0 or more non-capitals (which will pass through as-is), //
|
||||
// then one capital (which will be kept uppercase), //
|
||||
// then 0 or more capitals (which will be lowercased), //
|
||||
// then 0 or more non-capitals (which will pass through as-is) //
|
||||
// //
|
||||
// Example matches are: //
|
||||
// "UNIT CODE" -> ()(U)(NIT)( ), then ()(C)(ODE)() -> (Unit )(Code) //
|
||||
// "UNITCODE" -> ()(U)(NITCODE)(), -> (Unitcode) //
|
||||
// "UnitCode" -> ()(U)()(nit), then ()(C)()(ode) -> (Unit)(Code) //
|
||||
// "UNIT0CODE" -> ()(U)(NIT)(0), then ()(C)(ODE)() -> (Unit0)(Code) //
|
||||
// "0UNITCODE" -> (0)(U)(NITCODE)() -> (0Unitcode) //
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
Pattern pattern = Pattern.compile("([^A-Z]*)([A-Z])([A-Z]*)([^A-Z]*)");
|
||||
Matcher matcher = pattern.matcher(input);
|
||||
while(matcher.find())
|
||||
{
|
||||
rs.append(matcher.group(1) != null ? matcher.group(1) : "");
|
||||
rs.append(matcher.group(2) != null ? matcher.group(2) : "");
|
||||
rs.append(matcher.group(3) != null ? matcher.group(3).toLowerCase() : "");
|
||||
rs.append(matcher.group(4) != null ? matcher.group(4) : "");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// just in case no match was found, return the original input string //
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
if(rs.length() == 0)
|
||||
{
|
||||
return (input);
|
||||
}
|
||||
|
||||
return (rs.toString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* truncate a string (null safely) at a max length.
|
||||
*
|
||||
*******************************************************************************/
|
||||
public static String safeTruncate(String input, int maxLength)
|
||||
{
|
||||
if(input == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
if(input.length() <= maxLength)
|
||||
{
|
||||
return (input);
|
||||
}
|
||||
|
||||
return (input.substring(0, maxLength));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
*******************************************************************************/
|
||||
public static String safeTruncate(String input, int maxLength, String suffix)
|
||||
{
|
||||
if(input == null)
|
||||
{
|
||||
return (null);
|
||||
}
|
||||
|
||||
if(input.length() <= maxLength)
|
||||
{
|
||||
return (input);
|
||||
}
|
||||
|
||||
return (input.substring(0, (maxLength - suffix.length())) + suffix);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** returns input if not null, or nullOutput if input == null (as in SQL NVL)
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static String safeTrim(String input)
|
||||
{
|
||||
if(input == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return input.trim();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Join a collection of objects into 1 string
|
||||
**
|
||||
** @param glue - String to insert between entries
|
||||
** @param collection - The collection of objects to join.
|
||||
** @return String
|
||||
*******************************************************************************/
|
||||
public static String join(String glue, Collection<? extends Object> collection)
|
||||
{
|
||||
StringBuffer rs = new StringBuffer();
|
||||
|
||||
int i = 0;
|
||||
for(Object s : collection)
|
||||
{
|
||||
if(i++ > 0)
|
||||
{
|
||||
rs.append(glue);
|
||||
}
|
||||
rs.append(String.valueOf(s));
|
||||
}
|
||||
|
||||
return (rs.toString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** joinWithCommasAndAnd
|
||||
**
|
||||
** [one] => [one]
|
||||
** [one, two] => [one and two]
|
||||
** [one, two, three] => [one, two, and three]
|
||||
** [one, two, three, four] => [one, two, three, and four]
|
||||
** etc.
|
||||
**
|
||||
** @param input
|
||||
** @return
|
||||
*******************************************************************************/
|
||||
public static String joinWithCommasAndAnd(List<String> input)
|
||||
{
|
||||
StringBuilder rs = new StringBuilder();
|
||||
int size = input.size();
|
||||
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
if(i > 0 && size == 2)
|
||||
{
|
||||
rs.append(" and ");
|
||||
}
|
||||
else if(i > 0 && i < size - 1)
|
||||
{
|
||||
rs.append(", ");
|
||||
}
|
||||
else if(i > 0 && i == size - 1)
|
||||
{
|
||||
rs.append(", and ");
|
||||
}
|
||||
rs.append(input.get(i));
|
||||
}
|
||||
|
||||
return (rs.toString());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** isNullOrEmptyString
|
||||
**
|
||||
** @param input
|
||||
*******************************************************************************/
|
||||
private static boolean isNullOrBlankString(Object input)
|
||||
{
|
||||
if(input == null)
|
||||
{
|
||||
return (true);
|
||||
}
|
||||
else if(input instanceof String && !StringUtils.hasContent((String) input))
|
||||
{
|
||||
return (true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Split a string into tokens, broken up around a given regular expression pattern.
|
||||
**
|
||||
** @param original the string to do the splitting to.
|
||||
** @param pattern the pattern to split on.
|
||||
** @return a LinkedList with the elements found in the original string
|
||||
*******************************************************************************/
|
||||
public static LinkedList<String> split(String original, String pattern)
|
||||
{
|
||||
return (new LinkedList<String>(Arrays.asList(original.split(pattern))));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Split a string into tokens, broken up around a given regular expression pattern.
|
||||
**
|
||||
** @param original the string to do the splitting to.
|
||||
** @param pattern the pattern to split on.
|
||||
** @param limit the max number of splits to make
|
||||
** @return a List with the elements found in the original string
|
||||
*******************************************************************************/
|
||||
public static LinkedList<String> split(String original, String pattern, Integer limit)
|
||||
{
|
||||
return (new LinkedList<String>(Arrays.asList(original.split(pattern, limit))));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Trims leading white spaces from a String. Returns a blank ("") value if NULL
|
||||
**
|
||||
** @param input
|
||||
** @return String
|
||||
*******************************************************************************/
|
||||
public static String ltrim(String input)
|
||||
{
|
||||
if(!hasContent(input))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
while(i < input.length() && Character.isWhitespace(input.charAt(i)))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
return (input.substring(i));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Trims trailing white spaces from a String. Returns a blank ("") value if NULL
|
||||
**
|
||||
** @param input
|
||||
** @return String
|
||||
*******************************************************************************/
|
||||
public static String rtrim(String input)
|
||||
{
|
||||
if(!hasContent(input))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
int i = input.length() - 1;
|
||||
while(i > 0 && Character.isWhitespace(input.charAt(i)))
|
||||
{
|
||||
i--;
|
||||
}
|
||||
return (input.substring(0, i + 1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static String plural(Collection<?> collection)
|
||||
{
|
||||
return (plural(collection == null ? 0 : collection.size()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static String plural(Integer size)
|
||||
{
|
||||
return (plural(size, "", "s"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static String plural(Collection<?> collection, String ifOne, String ifNotOne)
|
||||
{
|
||||
return (plural(collection.size(), ifOne, ifNotOne));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static String plural(Integer size, String ifOne, String ifNotOne)
|
||||
{
|
||||
return (size != null && size.equals(1) ? ifOne : ifNotOne);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user