001    // Copyright 2006, 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.EventContext;
019    import org.apache.tapestry5.internal.structure.ComponentPageElementResources;
020    import org.apache.tapestry5.runtime.ComponentEvent;
021    import org.slf4j.Logger;
022    
023    public class ComponentEventImpl extends EventImpl implements ComponentEvent
024    {
025        private final String eventType;
026    
027        private final String originatingComponentId;
028    
029        private final EventContext context;
030    
031        private final ComponentPageElementResources elementResources;
032    
033        /**
034         * @param eventType
035         *            non blank string used to identify the type of event that was triggered
036         * @param originatingComponentId
037         *            the id of the component that triggered the event
038         * @param context
039         *            provides access to parameter values
040         * @param handler
041         *            invoked when a non-null return value is obtained from an event handler method
042         * @param elementResources
043         *            provides access to common resources and services
044         * @param logger
045         *            used to log method invocations
046         */
047        public ComponentEventImpl(String eventType, String originatingComponentId, EventContext context,
048                ComponentEventCallback handler, ComponentPageElementResources elementResources, Logger logger)
049        {
050            super(handler, logger, elementResources);
051    
052            this.eventType = eventType;
053            this.originatingComponentId = originatingComponentId;
054            this.elementResources = elementResources;
055            this.context = context;
056        }
057    
058        @Override
059        public String toString()
060        {
061            return String.format("ComponentEvent[%s from %s]", eventType, originatingComponentId.length() == 0 ? "(self)"
062                    : originatingComponentId);
063        }
064    
065        public boolean matches(String eventType, String componentId, int parameterCount)
066        {
067            if (isAborted())
068                return false;
069    
070            return this.eventType.equalsIgnoreCase(eventType) && context.getCount() >= parameterCount
071                    && (originatingComponentId.equalsIgnoreCase(componentId) || componentId.equals(""));
072        }
073    
074        @SuppressWarnings("unchecked")
075        public Object coerceContext(int index, String desiredTypeName)
076        {
077            if (index >= context.getCount())
078                throw new IllegalArgumentException(ServicesMessages.contextIndexOutOfRange(getMethodDescription()));
079            try
080            {
081                Class desiredType = elementResources.toClass(desiredTypeName);
082    
083                return context.get(desiredType, index);
084            }
085            catch (Exception ex)
086            {
087                throw new IllegalArgumentException(ServicesMessages.exceptionInMethodParameter(getMethodDescription(),
088                        index, ex), ex);
089            }
090        }
091    
092        public Object[] getContext()
093        {
094            int count = context.getCount();
095    
096            Object[] result = new Object[count];
097    
098            for (int i = 0; i < count; i++)
099                result[i] = context.get(Object.class, i);
100    
101            return result;
102        }
103    
104        public EventContext getEventContext()
105        {
106            return context;
107        }
108    }