Search in sources :

Example 1 with LocalVariableCallback

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();
                }
            });
        }
    });
}
Also used : LocalVariableCallback(org.apache.tapestry5.plastic.LocalVariableCallback) InstructionBuilder(org.apache.tapestry5.plastic.InstructionBuilder) JSONObject(org.apache.tapestry5.json.JSONObject) LocalVariable(org.apache.tapestry5.plastic.LocalVariable) JSONArray(org.apache.tapestry5.json.JSONArray) MethodParameter(org.apache.tapestry5.plastic.MethodParameter) InstructionBuilderCallback(org.apache.tapestry5.plastic.InstructionBuilderCallback) OnEvent(org.apache.tapestry5.annotations.OnEvent)

Aggregations

OnEvent (org.apache.tapestry5.annotations.OnEvent)1 JSONArray (org.apache.tapestry5.json.JSONArray)1 JSONObject (org.apache.tapestry5.json.JSONObject)1 InstructionBuilder (org.apache.tapestry5.plastic.InstructionBuilder)1 InstructionBuilderCallback (org.apache.tapestry5.plastic.InstructionBuilderCallback)1 LocalVariable (org.apache.tapestry5.plastic.LocalVariable)1 LocalVariableCallback (org.apache.tapestry5.plastic.LocalVariableCallback)1 MethodParameter (org.apache.tapestry5.plastic.MethodParameter)1