use of org.apache.tapestry5.plastic.LocalVariableCallback in project tapestry-5 by apache.
the class OnEventWorker method implementDispatchMethod.
private void implementDispatchMethod(final PlasticClass plasticClass, final boolean isRoot, final MutableComponentModel model, final Flow<EventHandlerMethod> eventHandlerMethods) {
plasticClass.introduceMethod(TransformConstants.DISPATCH_COMPONENT_EVENT_DESCRIPTION).changeImplementation(new InstructionBuilderCallback() {
public void doBuild(InstructionBuilder builder) {
builder.startVariable("boolean", new LocalVariableCallback() {
public void doBuild(LocalVariable resultVariable, InstructionBuilder builder) {
if (!isRoot) {
// As a subclass, there will be a base class implementation (possibly empty).
builder.loadThis().loadArguments().invokeSpecial(plasticClass.getSuperClassName(), TransformConstants.DISPATCH_COMPONENT_EVENT_DESCRIPTION);
// First store the result of the super() call into the variable.
builder.storeVariable(resultVariable);
builder.loadArgument(0).invoke(Event.class, boolean.class, "isAborted");
builder.when(Condition.NON_ZERO, RETURN_TRUE);
} else {
// No event handler method has yet been invoked.
builder.loadConstant(false).storeVariable(resultVariable);
}
boolean hasRestEndpointEventHandlerMethod = false;
JSONArray restEndpointEventHandlerMethods = null;
for (EventHandlerMethod method : eventHandlerMethods) {
method.buildMatchAndInvocation(builder, resultVariable);
model.addEventHandler(method.eventType);
if (method.handleActivationEventContext) {
model.doHandleActivationEventContext();
}
// We're collecting this info for all components, even considering REST
// events are only triggered in pages, because we can have REST event
// handler methods in base classes too, and we need this info
// for generating complete, correct OpenAPI documentation.
final OnEvent onEvent = method.method.getAnnotation(OnEvent.class);
final String methodName = method.method.getDescription().methodName;
if (isRestEndpointEventHandlerMethod(onEvent, methodName)) {
hasRestEndpointEventHandlerMethod = true;
if (restEndpointEventHandlerMethods == null) {
restEndpointEventHandlerMethods = new JSONArray();
}
JSONObject methodMeta = new JSONObject();
methodMeta.put("name", methodName);
JSONArray parameters = new JSONArray();
for (MethodParameter parameter : method.method.getParameters()) {
parameters.add(parameter.getType());
}
methodMeta.put("parameters", parameters);
restEndpointEventHandlerMethods.add(methodMeta);
}
}
// memory by not setting it to all component models.
if (model.isPage()) {
model.setMeta(InternalConstants.REST_ENDPOINT_EVENT_HANDLER_METHOD_PRESENT, hasRestEndpointEventHandlerMethod ? InternalConstants.TRUE : InternalConstants.FALSE);
}
// methods in components, something that would be ignored anyway.
if (restEndpointEventHandlerMethods != null) {
model.setMeta(InternalConstants.REST_ENDPOINT_EVENT_HANDLER_METHODS, restEndpointEventHandlerMethods.toCompactString());
}
builder.loadVariable(resultVariable).returnResult();
}
});
}
});
}
Aggregations