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
015package org.apache.tapestry.form;
016
017import java.util.HashMap;
018import java.util.Map;
019
020import org.apache.hivemind.ApplicationRuntimeException;
021import org.apache.tapestry.IComponent;
022import org.apache.tapestry.IForm;
023import org.apache.tapestry.IMarkupWriter;
024import org.apache.tapestry.IRequestCycle;
025import org.apache.tapestry.IScript;
026import org.apache.tapestry.PageRenderSupport;
027import 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
036public 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}