001    // Copyright 2006 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.binding;
016    
017    import org.apache.hivemind.ApplicationRuntimeException;
018    import org.apache.hivemind.Location;
019    import org.apache.hivemind.util.Defense;
020    import org.apache.tapestry.IBinding;
021    import org.apache.tapestry.IComponent;
022    import org.apache.tapestry.coerce.ValueConverter;
023    
024    /**
025     * An implementation of Tapestry {@link IBinding} that simplifies 
026     * access to a component's clientId.<br/>
027     * You can use this binding in order to safely find out the 
028     * client-side id that was (or will be) generated for a given 
029     * component.
030     * 
031     * <p/>
032     * Here's an example of how to get the client id of a Tapestry component:
033     * <code>
034     * &lt;span jwcid="@Any" dojoType="myDojoComponent" contentId="clientId:content" /&gt;
035     * </code>
036     * <p/>
037     * The previous code can also be written using the ognl binding:
038     * <code>
039     * &lt;span jwcid="@Any" dojoType="myDojoComponent" contentId="ognl:components.content.clientId" /&gt;
040     * </code>
041     * but the clientId binding is more compact and performs much faster.
042     */
043    public class ClientIdBinding extends AbstractBinding
044    {
045        private final IComponent _component;
046    
047        private final String _componentId;
048    
049        public ClientIdBinding(String description, ValueConverter valueConverter, Location location,
050                IComponent component, String componentId)
051        {
052            super(description, valueConverter, location);
053    
054            Defense.notNull(component, "component");
055            Defense.notNull(componentId, "componentId");
056    
057            _component = component;
058            _componentId = componentId;
059        }
060    
061        public Object getObject()
062        {
063            try
064            {
065                return _component.getComponent(_componentId).getClientId();
066            }
067            catch (Exception ex)
068            {
069                throw new ApplicationRuntimeException(ex.getMessage(), getLocation(), ex);
070            }
071        }
072    
073        public Object getComponent()
074        {
075            return _component;
076        }
077            
078        public boolean isInvariant()
079        {
080            // clientId can change even for the same component, so ...
081            return false;
082        }
083    
084    }