mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
provide default implementation in handleOutput;
update newObjectFromTypeArgument to support class hierarchies of depth > 1 add AbstractMiddlewareVersion as argument to some methods add pre-execute method add getRequestBodyAsJsonObject
This commit is contained in:
@ -36,6 +36,7 @@ import com.kingsrook.qqq.backend.core.exceptions.QRuntimeException;
|
|||||||
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||||
import com.kingsrook.qqq.backend.javalin.QJavalinUtils;
|
import com.kingsrook.qqq.backend.javalin.QJavalinUtils;
|
||||||
import com.kingsrook.qqq.middleware.javalin.executors.AbstractMiddlewareExecutor;
|
import com.kingsrook.qqq.middleware.javalin.executors.AbstractMiddlewareExecutor;
|
||||||
@ -81,11 +82,15 @@ public abstract class AbstractEndpointSpec<
|
|||||||
public abstract INPUT buildInput(Context context) throws Exception;
|
public abstract INPUT buildInput(Context context) throws Exception;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
** build the endpoint's http response (written to the javalin context) from
|
** build the endpoint's http response (written to the javalin context) from
|
||||||
** an execution output object
|
** an execution output object
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
public abstract void handleOutput(Context context, OUTPUT output) throws Exception;
|
public void handleOutput(Context context, OUTPUT output) throws Exception
|
||||||
|
{
|
||||||
|
context.result(JsonUtils.toJson(output));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -120,7 +125,16 @@ public abstract class AbstractEndpointSpec<
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Type superClass = getClass().getGenericSuperclass();
|
/////////////////////////////////////////////////
|
||||||
|
// moving up type hierarchy to find this class //
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
Class<?> s = getClass();
|
||||||
|
while(!s.getSuperclass().equals(AbstractEndpointSpec.class))
|
||||||
|
{
|
||||||
|
s = s.getSuperclass();
|
||||||
|
}
|
||||||
|
|
||||||
|
Type superClass = s.getGenericSuperclass();
|
||||||
Type actualTypeArgument = ((ParameterizedType) superClass).getActualTypeArguments()[argumentIndex];
|
Type actualTypeArgument = ((ParameterizedType) superClass).getActualTypeArguments()[argumentIndex];
|
||||||
String className = actualTypeArgument.getTypeName().replaceAll("<.*", "");
|
String className = actualTypeArgument.getTypeName().replaceAll("<.*", "");
|
||||||
Class<?> aClass = Class.forName(className);
|
Class<?> aClass = Class.forName(className);
|
||||||
@ -137,14 +151,14 @@ public abstract class AbstractEndpointSpec<
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
** define a javalin route for the spec
|
** define a javalin route for the spec
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
public void defineRoute(String versionBasePath)
|
public void defineRoute(AbstractMiddlewareVersion abstractMiddlewareVersion, String versionBasePath)
|
||||||
{
|
{
|
||||||
CompleteOperation completeOperation = defineCompleteOperation();
|
CompleteOperation completeOperation = defineCompleteOperation();
|
||||||
|
|
||||||
String fullPath = "/qqq/" + versionBasePath + completeOperation.getPath();
|
String fullPath = "/qqq/" + versionBasePath + completeOperation.getPath();
|
||||||
fullPath = fullPath.replaceAll("/+", "/");
|
fullPath = fullPath.replaceAll("/+", "/");
|
||||||
|
|
||||||
final Handler handler = context -> serveRequest(context);
|
final Handler handler = context -> serveRequest(abstractMiddlewareVersion, context);
|
||||||
|
|
||||||
switch(completeOperation.getHttpMethod())
|
switch(completeOperation.getHttpMethod())
|
||||||
{
|
{
|
||||||
@ -162,7 +176,7 @@ public abstract class AbstractEndpointSpec<
|
|||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
**
|
**
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
public OUTPUT serveRequest(Context context) throws Exception
|
public OUTPUT serveRequest(AbstractMiddlewareVersion abstractMiddlewareVersion, Context context) throws Exception
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -175,6 +189,8 @@ public abstract class AbstractEndpointSpec<
|
|||||||
QContext.setQInstance(qInstance);
|
QContext.setQInstance(qInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstractMiddlewareVersion.preExecute(context);
|
||||||
|
|
||||||
INPUT input = buildInput(context);
|
INPUT input = buildInput(context);
|
||||||
EXECUTOR executor = newExecutor();
|
EXECUTOR executor = newExecutor();
|
||||||
OUTPUT output = newOutput();
|
OUTPUT output = newOutput();
|
||||||
@ -360,6 +376,53 @@ public abstract class AbstractEndpointSpec<
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
**
|
||||||
|
***************************************************************************/
|
||||||
|
protected JSONObject getRequestBodyAsJsonObject(Context context)
|
||||||
|
{
|
||||||
|
RequestBody requestBody = getMemoizedRequestBody();
|
||||||
|
if(requestBody != null)
|
||||||
|
{
|
||||||
|
String requestContentType = context.contentType();
|
||||||
|
if(requestContentType != null)
|
||||||
|
{
|
||||||
|
requestContentType = requestContentType.toLowerCase().replaceAll(" *;.*", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
Content contentSpec = requestContentType == null ? null : requestBody.getContent().get(requestContentType);
|
||||||
|
if(contentSpec != null && "object".equals(contentSpec.getSchema().getType()))
|
||||||
|
{
|
||||||
|
if(ContentType.APPLICATION_JSON.getMimeType().equals(requestContentType))
|
||||||
|
{
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// avoid re-parsing the JSON object if getting multiple attributes from it //
|
||||||
|
// by stashing it in a (request) attribute. //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
Object jsonBodyAttribute = context.attribute("jsonBody");
|
||||||
|
JSONObject jsonObject = null;
|
||||||
|
|
||||||
|
if(jsonBodyAttribute instanceof JSONObject jo)
|
||||||
|
{
|
||||||
|
jsonObject = jo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(jsonObject == null)
|
||||||
|
{
|
||||||
|
jsonObject = new JSONObject(context.body());
|
||||||
|
context.attribute("jsonBody", jsonObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (jsonObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
**
|
**
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@ -404,24 +467,7 @@ public abstract class AbstractEndpointSpec<
|
|||||||
}
|
}
|
||||||
else if(ContentType.APPLICATION_JSON.getMimeType().equals(requestContentType))
|
else if(ContentType.APPLICATION_JSON.getMimeType().equals(requestContentType))
|
||||||
{
|
{
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
JSONObject jsonObject = getRequestBodyAsJsonObject(context);
|
||||||
// avoid re-parsing the JSON object if getting multiple attributes from it //
|
|
||||||
// by stashing it in a (request) attribute. //
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
Object jsonBodyAttribute = context.attribute("jsonBody");
|
|
||||||
JSONObject jsonObject = null;
|
|
||||||
|
|
||||||
if(jsonBodyAttribute instanceof JSONObject jo)
|
|
||||||
{
|
|
||||||
jsonObject = jo;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(jsonObject == null)
|
|
||||||
{
|
|
||||||
jsonObject = new JSONObject(context.body());
|
|
||||||
context.attribute("jsonBody", jsonObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(jsonObject.has(name))
|
if(jsonObject.has(name))
|
||||||
{
|
{
|
||||||
value = jsonObject.getString(name);
|
value = jsonObject.getString(name);
|
||||||
|
Reference in New Issue
Block a user