001    // Copyright 2005 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.tapestry.listener;
016    
017    import java.util.Collection;
018    import java.util.Collections;
019    import java.util.HashMap;
020    import java.util.Map;
021    
022    import org.apache.hivemind.ApplicationRuntimeException;
023    import org.apache.hivemind.util.Defense;
024    import org.apache.tapestry.IActionListener;
025    import org.apache.tapestry.IComponent;
026    import org.apache.tapestry.TapestryUtils;
027    
028    /**
029     * @author Howard M. Lewis Ship
030     * @since 4.0
031     */
032    public class ListenerMapImpl implements ListenerMap
033    {
034    
035        private final Object _target;
036    
037        /**
038         * Keyed on String method name, value is
039         * {@link org.apache.tapestry.listener.ListenerMethodInvoker}.
040         */
041    
042        private final Map _invokers;
043    
044        private final Map _listeners = new HashMap();
045    
046        public ListenerMapImpl(Object target, Map invokers)
047        {
048            Defense.notNull(target, "target");
049            Defense.notNull(invokers, "invokers");
050    
051            _target = target;
052            _invokers = invokers;
053        }
054    
055        public boolean canProvideListener(String name)
056        {
057            return _invokers.containsKey(name);
058        }
059    
060        public synchronized IActionListener getListener(String name)
061        {
062            IActionListener result = (IActionListener) _listeners.get(name);
063    
064            if (result == null)
065            {
066                result = createListener(name);
067                _listeners.put(name, result);
068            }
069    
070            return result;
071        }
072    
073            public IActionListener getImplicitListener(IComponent component)
074            {
075                    IActionListener listener;
076                    String generatedName = "do" + TapestryUtils.capitalize(component.getId());
077                    try
078                    {
079                            listener = getListener(generatedName);
080                    }
081                    catch (ApplicationRuntimeException e)
082                    {
083                            throw new ApplicationRuntimeException(ListenerMessages.noImplicitListenerMethodFound(generatedName, component), component, null, e);
084                    }
085    
086                    return listener;
087            }
088    
089            private IActionListener createListener(String name)
090        {
091            ListenerMethodInvoker invoker = (ListenerMethodInvoker) _invokers.get(name);
092    
093            if (invoker == null)
094                throw new ApplicationRuntimeException(ListenerMessages.objectMissingMethod(_target, name),
095                                                      _target, null, null);
096    
097            return new SyntheticListener(_target, invoker);
098        }
099    
100        public Collection getListenerNames()
101        {
102            return Collections.unmodifiableCollection(_invokers.keySet());
103        }
104    }