001    package org.apache.tapestry.binding;
002    
003    import org.apache.hivemind.ApplicationRuntimeException;
004    import org.apache.hivemind.Location;
005    import org.apache.hivemind.util.Defense;
006    import org.apache.tapestry.IComponent;
007    import org.apache.tapestry.coerce.ValueConverter;
008    
009    import java.util.ArrayList;
010    import java.util.List;
011    
012    /**
013     * Binding that is specifcially used to bind against components of type {@link org.apache.tapestry.IDynamicInvoker}
014     * and only for the parameter name "updateComponents".
015     *
016     * <p>
017     *  Will take a parameter specification of <code>updateComponents="componentA, componentB"</code> and turn it
018     * into the equivalent of a {@link List} containing the result of invoking {@link org.apache.tapestry.IComponent#getClientId()} on
019     * each component specified.
020     * </p>
021     */
022    public class ClientIdListBinding extends AbstractBinding {
023    
024        private final IComponent _target;
025    
026        private final String[] _componentIds;
027        private IComponent[] _targets;
028    
029        public ClientIdListBinding(String description, ValueConverter valueConverter,
030                                   Location location, IComponent component, String[] componentIds)
031        {
032            super(description, valueConverter, location);
033    
034            Defense.notNull(component, "component");
035            Defense.notNull(componentIds, "componentIds");
036    
037            _target = component;
038            _componentIds = componentIds;
039            _targets = new IComponent[_componentIds.length];
040        }
041    
042        public Object getObject()
043        {
044            try
045            {
046                List clientIds = new ArrayList(_componentIds.length);
047    
048                for (int i=0; i < _componentIds.length; i++)
049                {
050                    if (_targets[i] == null)
051                    {
052                        if (_target.getComponents().containsKey(_componentIds[i]))
053                        {
054                            _targets[i] = _target.getComponent(_componentIds[i]);
055                        } else if (_target.getPage() != null) {
056    
057                            _targets[i] = _target.getPage().getComponent(_componentIds[i]);
058                        }
059                        
060                        // if not found we're in trouble
061    
062                        if (_targets[i] == null)
063                            throw new ApplicationRuntimeException(BindingMessages.unknownComponent(_target, _componentIds[i]), getLocation(), null);
064                    }
065                    
066                    clientIds.add(_targets[i].getClientId());
067                }
068    
069                return clientIds;
070            }
071            catch (Exception ex)
072            {
073                throw new ApplicationRuntimeException(ex.getMessage(), getLocation(), ex);
074            }
075        }
076    
077        public Object getComponent()
078        {
079            return _target;
080        }
081    
082        public boolean isInvariant()
083        {
084            return false;
085        }
086    }