001    // Copyright 2004, 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.form;
016    
017    import java.util.HashMap;
018    import java.util.Map;
019    
020    import org.apache.hivemind.ApplicationRuntimeException;
021    import org.apache.tapestry.IComponent;
022    import org.apache.tapestry.IForm;
023    import org.apache.tapestry.IMarkupWriter;
024    import org.apache.tapestry.IRequestCycle;
025    import org.apache.tapestry.IScript;
026    import org.apache.tapestry.PageRenderSupport;
027    import org.apache.tapestry.TapestryUtils;
028    
029    /**
030     * Implements a component that submits its enclosing form via a JavaScript link. [ <a
031     * href="../../../../../ComponentReference/LinkSubmit.html">Component Reference </a>]
032     * 
033     * @author Richard Lewis-Shell
034     */
035    
036    public abstract class LinkSubmit extends AbstractSubmit
037    {
038    
039        /**
040         * The name of an {@link org.apache.tapestry.IRequestCycle} attribute in which the current
041         * submit link is stored. LinkSubmits do not nest.
042         */
043    
044        public static final String ATTRIBUTE_NAME = "org.apache.tapestry.form.LinkSubmit";
045    
046        /**
047         * Checks the submit name ({@link FormConstants#SUBMIT_NAME_PARAMETER}) to see if it matches
048         * this LinkSubmit's assigned element name.
049         */
050        protected boolean isClicked(IRequestCycle cycle, String name)
051        {
052            String value = cycle.getParameter(FormConstants.SUBMIT_NAME_PARAMETER);
053    
054            return name.equals(value);
055        }
056    
057        public abstract IScript getScript();
058    
059        /**
060         * @see org.apache.tapestry.form.AbstractFormComponent#renderFormComponent(org.apache.tapestry.IMarkupWriter,
061         *      org.apache.tapestry.IRequestCycle)
062         */
063        protected void renderFormComponent(IMarkupWriter writer, IRequestCycle cycle)
064        {
065            boolean disabled = isDisabled();
066    
067            IForm form = getForm();
068            String name = getName();
069    
070            if (!disabled)
071            {
072                PageRenderSupport pageRenderSupport = TapestryUtils.getPageRenderSupport(cycle, this);
073    
074                Map symbols = new HashMap();
075                symbols.put("form", form);
076                symbols.put("name", name);
077    
078                getScript().execute(cycle, pageRenderSupport, symbols);
079    
080                writer.begin("a");
081                writer.attribute("href", (String) symbols.get("href"));
082    
083                renderIdAttribute(writer, cycle);
084    
085                renderInformalParameters(writer, cycle);
086            }
087    
088            renderBody(writer, cycle);
089    
090            if (!disabled)
091                writer.end();
092    
093        }
094    
095        /**
096         * @see org.apache.tapestry.form.AbstractSubmit#rewindFormComponent(org.apache.tapestry.IMarkupWriter, org.apache.tapestry.IRequestCycle)
097         */
098        protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle)
099        {
100            super.rewindFormComponent(writer, cycle);
101    
102            renderBody(writer, cycle);
103        }
104    
105        /**
106         * @see org.apache.tapestry.AbstractComponent#prepareForRender(org.apache.tapestry.IRequestCycle)
107         */
108        protected void prepareForRender(IRequestCycle cycle)
109        {
110            IComponent outer = (IComponent) cycle.getAttribute(ATTRIBUTE_NAME);
111    
112            if (outer != null)
113                throw new ApplicationRuntimeException(FormMessages.linkSubmitMayNotNest(this, outer),
114                        this, getLocation(), null);
115    
116            cycle.setAttribute(ATTRIBUTE_NAME, this);
117        }
118    
119        /**
120         * @see org.apache.tapestry.AbstractComponent#cleanupAfterRender(org.apache.tapestry.IRequestCycle)
121         */
122        protected void cleanupAfterRender(IRequestCycle cycle)
123        {
124            cycle.removeAttribute(ATTRIBUTE_NAME);
125        }
126    
127        /**
128         * Links can not take focus, ever.
129         */
130        protected boolean getCanTakeFocus()
131        {
132            return false;
133        }
134    
135        /**
136         * Returns true; the LinkSubmit's body should render during a rewind, even if the component is
137         * itself disabled.
138         */
139        protected boolean getAlwaysRenderBodyOnRewind()
140        {
141            return true;
142        }
143    
144    }