    001    // Copyright 2007, 2008, 2010, 2011 The Apache Software Foundation
    002    //
    003    // Licensed under the Apache License, Version 2.0 (the "License");
    004    // you may not use this file except in compliance with the License.
    005    // You may obtain a copy of the License at
    006    //
    007    //     http://www.apache.org/licenses/LICENSE-2.0
    008    //
    009    // Unless required by applicable law or agreed to in writing, software
    010    // distributed under the License is distributed on an "AS IS" BASIS,
    011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    012    // See the License for the specific language governing permissions and
    013    // limitations under the License.
    014
    015    package org.apache.tapestry5.internal.services;
    016
    017    import org.apache.tapestry5.ComponentEventCallback;
    018    import org.apache.tapestry5.TapestryMarkers;
    019    import org.apache.tapestry5.ioc.Invokable;
    020    import org.apache.tapestry5.ioc.OperationTracker;
    021    import org.apache.tapestry5.runtime.Event;
    022    import org.slf4j.Logger;
    023
    024    @SuppressWarnings("all")
    025    public class EventImpl implements Event
    026    {
    027        private boolean aborted;
    028
    029        private String methodDescription;
    030
    031        private final ComponentEventCallback handler;
    032
    033        private final Logger logger;
    034
    035        private final boolean debugEnabled;
    036
    037        protected final OperationTracker tracker;
    038
    039        /**
    040         * @param handler informed of return values from methods, deems when the event is aborted
    041         * @param logger  used to log method invocations
    042         * @param tracker
    043         */
    044        public EventImpl(ComponentEventCallback handler, Logger logger, OperationTracker tracker)
    045        {
    046            this.tracker = tracker;
    047            assert handler != null;
    048            this.handler = handler;
    049            this.logger = logger;
    050
    051            // TAP5-471: Thousands of calls to isDebugEnabled() do add up
    052            debugEnabled = logger.isDebugEnabled();
    053        }
    054
    055        public boolean isAborted()
    056        {
    057            return aborted;
    058        }
    059
    060        public void setMethodDescription(String methodDescription)
    061        {
    062            if (debugEnabled)
    063                logger.debug(TapestryMarkers.EVENT_HANDLER_METHOD, "Invoking: " + methodDescription);
    064
    065            this.methodDescription = methodDescription;
    066        }
    067
    068        @SuppressWarnings("unchecked")
    069        public boolean storeResult(final Object result)
    070        {
    071            // Given that this method is *only* invoked from code
    072            // that is generated at runtime and proven to be correct,
    073            // this should never, ever happen. But what the hell,
    074            // let's check anyway.
    075
    076            if (aborted)
    077            {
    078                throw new IllegalStateException(ServicesMessages.componentEventIsAborted(methodDescription));
    079            }
    080
    081
    082            if (result != null)
    083            {
    084                boolean handleResult =
    085                        tracker.invoke(String.format("Handling result from method %s.", methodDescription), new Invokable<Boolean>()
    086                        {
    087                            public Boolean invoke()
    088                            {
    089                                return handler.handleResult(result);
    090                            }
    091                        });
    092
    093                aborted |= handleResult;
    094            }
    095
    096            return aborted;
    097        }
    098
    099        protected String getMethodDescription()
    100        {
    101            return methodDescription;
    102        }
    103    }