mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
Add an eventCartridge (handler) for methods that throw; add template identifier (a name) to input
This commit is contained in:
@ -26,20 +26,30 @@ import java.io.StringWriter;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import com.kingsrook.qqq.backend.core.actions.AbstractQActionFunction;
|
import com.kingsrook.qqq.backend.core.actions.AbstractQActionFunction;
|
||||||
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
import com.kingsrook.qqq.backend.core.exceptions.QException;
|
||||||
|
import com.kingsrook.qqq.backend.core.logging.QLogger;
|
||||||
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionInput;
|
import com.kingsrook.qqq.backend.core.model.actions.AbstractActionInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.templates.RenderTemplateInput;
|
import com.kingsrook.qqq.backend.core.model.templates.RenderTemplateInput;
|
||||||
import com.kingsrook.qqq.backend.core.model.templates.RenderTemplateOutput;
|
import com.kingsrook.qqq.backend.core.model.templates.RenderTemplateOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.templates.TemplateType;
|
import com.kingsrook.qqq.backend.core.model.templates.TemplateType;
|
||||||
|
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||||
import org.apache.velocity.VelocityContext;
|
import org.apache.velocity.VelocityContext;
|
||||||
import org.apache.velocity.app.Velocity;
|
import org.apache.velocity.app.Velocity;
|
||||||
|
import org.apache.velocity.app.event.EventCartridge;
|
||||||
|
import org.apache.velocity.app.event.MethodExceptionEventHandler;
|
||||||
import org.apache.velocity.context.Context;
|
import org.apache.velocity.context.Context;
|
||||||
|
import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair;
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Basic action to render a template!
|
** Basic action to render a template!
|
||||||
|
**
|
||||||
|
** hard-coded built to only assume Velocity right now. could expand (and refactor) in future.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class RenderTemplateAction extends AbstractQActionFunction<RenderTemplateInput, RenderTemplateOutput>
|
public class RenderTemplateAction extends AbstractQActionFunction<RenderTemplateInput, RenderTemplateOutput>
|
||||||
{
|
{
|
||||||
|
private static final QLogger LOG = QLogger.getLogger(RenderTemplateAction.class);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
@ -53,8 +63,11 @@ public class RenderTemplateAction extends AbstractQActionFunction<RenderTemplate
|
|||||||
{
|
{
|
||||||
Velocity.init();
|
Velocity.init();
|
||||||
Context context = new VelocityContext(input.getContext());
|
Context context = new VelocityContext(input.getContext());
|
||||||
|
|
||||||
|
setupEventHandlers(context);
|
||||||
|
|
||||||
StringWriter stringWriter = new StringWriter();
|
StringWriter stringWriter = new StringWriter();
|
||||||
Velocity.evaluate(context, stringWriter, "logTag", input.getCode());
|
Velocity.evaluate(context, stringWriter, StringUtils.hasContent(input.getTemplateIdentifier()) ? input.getTemplateIdentifier() : "anonymous", input.getCode());
|
||||||
output.setResult(stringWriter.getBuffer().toString());
|
output.setResult(stringWriter.getBuffer().toString());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -67,12 +80,28 @@ public class RenderTemplateAction extends AbstractQActionFunction<RenderTemplate
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
private static void setupEventHandlers(Context context)
|
||||||
|
{
|
||||||
|
EventCartridge eventCartridge = new EventCartridge();
|
||||||
|
eventCartridge.addEventHandler((MethodExceptionEventHandler) (ctx, aClass, method, exception, info) ->
|
||||||
|
{
|
||||||
|
LOG.info("Exception in velocity template", exception, logPair("at", info.toString()));
|
||||||
|
return (null);
|
||||||
|
});
|
||||||
|
eventCartridge.attachToContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Most convenient static wrapper to render a Velocity template.
|
** Most convenient static wrapper to render a Velocity template.
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static String renderVelocity(AbstractActionInput parentActionInput, Map<String, Object> context, String code) throws QException
|
public static String renderVelocity(AbstractActionInput parentActionInput, Map<String, Object> context, String code) throws QException
|
||||||
{
|
{
|
||||||
return (render(parentActionInput, TemplateType.VELOCITY, context, code));
|
return (render(TemplateType.VELOCITY, context, code));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -80,7 +109,7 @@ public class RenderTemplateAction extends AbstractQActionFunction<RenderTemplate
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Convenient static wrapper to render a template of an arbitrary type (language).
|
** Convenient static wrapper to render a template of an arbitrary type (language).
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public static String render(AbstractActionInput parentActionInput, TemplateType templateType, Map<String, Object> context, String code) throws QException
|
public static String render(TemplateType templateType, Map<String, Object> context, String code) throws QException
|
||||||
{
|
{
|
||||||
RenderTemplateInput renderTemplateInput = new RenderTemplateInput();
|
RenderTemplateInput renderTemplateInput = new RenderTemplateInput();
|
||||||
renderTemplateInput.setCode(code);
|
renderTemplateInput.setCode(code);
|
||||||
|
@ -31,6 +31,7 @@ import com.kingsrook.qqq.backend.core.model.actions.AbstractActionInput;
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
public class RenderTemplateInput extends AbstractActionInput
|
public class RenderTemplateInput extends AbstractActionInput
|
||||||
{
|
{
|
||||||
|
private String templateIdentifier;
|
||||||
private String code; // todo - TemplateReference, like CodeReference??
|
private String code; // todo - TemplateReference, like CodeReference??
|
||||||
private TemplateType templateType;
|
private TemplateType templateType;
|
||||||
|
|
||||||
@ -147,4 +148,35 @@ public class RenderTemplateInput extends AbstractActionInput
|
|||||||
return (this);
|
return (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Getter for templateIdentifier
|
||||||
|
*******************************************************************************/
|
||||||
|
public String getTemplateIdentifier()
|
||||||
|
{
|
||||||
|
return (this.templateIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Setter for templateIdentifier
|
||||||
|
*******************************************************************************/
|
||||||
|
public void setTemplateIdentifier(String templateIdentifier)
|
||||||
|
{
|
||||||
|
this.templateIdentifier = templateIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
** Fluent setter for templateIdentifier
|
||||||
|
*******************************************************************************/
|
||||||
|
public RenderTemplateInput withTemplateIdentifier(String templateIdentifier)
|
||||||
|
{
|
||||||
|
this.templateIdentifier = templateIdentifier;
|
||||||
|
return (this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import com.kingsrook.qqq.backend.core.model.templates.RenderTemplateInput;
|
|||||||
import com.kingsrook.qqq.backend.core.model.templates.RenderTemplateOutput;
|
import com.kingsrook.qqq.backend.core.model.templates.RenderTemplateOutput;
|
||||||
import com.kingsrook.qqq.backend.core.model.templates.TemplateType;
|
import com.kingsrook.qqq.backend.core.model.templates.TemplateType;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
@ -36,8 +37,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
** Unit test for RenderTemplateAction
|
** Unit test for RenderTemplateAction
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
class RenderTemplateActionTest extends BaseTest
|
public class RenderTemplateActionTest extends BaseTest
|
||||||
{
|
{
|
||||||
|
private int doThrowCallCount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
**
|
**
|
||||||
@ -82,11 +86,46 @@ class RenderTemplateActionTest extends BaseTest
|
|||||||
@Test
|
@Test
|
||||||
void testMissingType()
|
void testMissingType()
|
||||||
{
|
{
|
||||||
RenderTemplateInput parentActionInput = new RenderTemplateInput();
|
assertThatThrownBy(() -> RenderTemplateAction.render(null, Map.of("name", "Darin"), "Hello, $name"))
|
||||||
|
|
||||||
assertThatThrownBy(() -> RenderTemplateAction.render(parentActionInput, null, Map.of("name", "Darin"), "Hello, $name"))
|
|
||||||
.isInstanceOf(QException.class)
|
.isInstanceOf(QException.class)
|
||||||
.hasMessageContaining("Unsupported Template Type");
|
.hasMessageContaining("Unsupported Template Type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
@Test
|
||||||
|
void testExceptionInVelocity() throws QException
|
||||||
|
{
|
||||||
|
RenderTemplateInput renderTemplateInput = new RenderTemplateInput();
|
||||||
|
renderTemplateInput.setCode("""
|
||||||
|
This should throw: $this.doThrow().
|
||||||
|
This should throw silently: $!this.doThrow().
|
||||||
|
""");
|
||||||
|
renderTemplateInput.setContext(Map.of("this", this));
|
||||||
|
renderTemplateInput.setTemplateType(TemplateType.VELOCITY);
|
||||||
|
RenderTemplateOutput output = new RenderTemplateAction().execute(renderTemplateInput);
|
||||||
|
assertThat(output.getResult())
|
||||||
|
.contains("throw: $this.doThrow().")
|
||||||
|
.contains("throw silently: .");
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////
|
||||||
|
// make sure our method got called twice as expected //
|
||||||
|
///////////////////////////////////////////////////////
|
||||||
|
assertEquals(2, doThrowCallCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
**
|
||||||
|
*******************************************************************************/
|
||||||
|
public String doThrow() throws Exception
|
||||||
|
{
|
||||||
|
doThrowCallCount++;
|
||||||
|
throw (new Exception("You asked to throw..."));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Reference in New Issue
Block a user