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.Iterator;
018
019import org.apache.hivemind.ApplicationRuntimeException;
020import org.apache.tapestry.IActionListener;
021import org.apache.tapestry.IForm;
022import org.apache.tapestry.IMarkupWriter;
023import org.apache.tapestry.IRequestCycle;
024import org.apache.tapestry.Tapestry;
025import org.apache.tapestry.coerce.ValueConverter;
026import org.apache.tapestry.components.ForBean;
027import org.apache.tapestry.listener.ListenerInvoker;
028import org.apache.tapestry.services.DataSqueezer;
029
030/**
031 * A specialized component used to edit a list of items within a form; it is similar to a
032 * {@link org.apache.tapestry.components.Foreach}but leverages hidden inputs within the
033 * &lt;form&gt; to store the items in the list. [ <a
034 * href="../../../../../ComponentReference/ListEdit.html">Component Reference </a>]
035 * 
036 * @author Howard Lewis Ship
037 * @since 1.0.2
038 * @deprecated As of release 4.0, replaced by {@link ForBean}
039 */
040
041public abstract class ListEdit extends AbstractFormComponent
042{
043    /**
044     * @see org.apache.tapestry.form.AbstractFormComponent#renderFormComponent(org.apache.tapestry.IMarkupWriter,
045     *      org.apache.tapestry.IRequestCycle)
046     */
047    protected void renderFormComponent(IMarkupWriter writer, IRequestCycle cycle)
048    {
049        this.render(writer, cycle, getSource());
050    }
051
052    /**
053     * @see org.apache.tapestry.form.AbstractFormComponent#rewindFormComponent(org.apache.tapestry.IMarkupWriter,
054     *      org.apache.tapestry.IRequestCycle)
055     */
056    protected void rewindFormComponent(IMarkupWriter writer, IRequestCycle cycle)
057    {
058        String[] values = cycle.getParameters(getName());
059
060        this.render(writer, cycle, (Iterator) getValueConverter().coerceValue(
061                values,
062                Iterator.class));
063    }
064
065    protected void render(IMarkupWriter writer, IRequestCycle cycle, Iterator i)
066    {
067        // If the source (when rendering), or the submitted values (on submit)
068        // are null, then skip the remainder (nothing to update, nothing to
069        // render).
070
071        if (i == null)
072            return;
073
074        int index = 0;
075
076        String element = getElement();
077
078        boolean indexBound = isParameterBound("index");
079
080        while (i.hasNext())
081        {
082            Object value = null;
083
084            if (indexBound)
085                setIndex(index++);
086
087            if (cycle.isRewinding())
088                value = convertValue((String) i.next());
089            else
090            {
091                value = i.next();
092                writeValue(getForm(), getName(), value);
093            }
094
095            setValue(value);
096
097            getListenerInvoker().invokeListener(getListener(), this, cycle);
098
099            if (element != null)
100            {
101                writer.begin(element);
102                renderInformalParameters(writer, cycle);
103            }
104
105            renderBody(writer, cycle);
106
107            if (element != null)
108                writer.end();
109        }
110    }
111
112    private void writeValue(IForm form, String name, Object value)
113    {
114        String externalValue;
115
116        try
117        {
118            externalValue = getDataSqueezer().squeeze(value);
119        }
120        catch (Exception ex)
121        {
122            throw new ApplicationRuntimeException(Tapestry.format(
123                    "ListEdit.unable-to-convert-value",
124                    value), this, null, ex);
125        }
126
127        form.addHiddenValue(name, externalValue);
128    }
129
130    private Object convertValue(String value)
131    {
132        try
133        {
134            return getDataSqueezer().unsqueeze(value);
135        }
136        catch (Exception ex)
137        {
138            throw new ApplicationRuntimeException(Tapestry.format(
139                    "ListEdit.unable-to-convert-string",
140                    value), this, null, ex);
141        }
142    }
143
144    public abstract String getElement();
145
146    /** @since 2.2 * */
147
148    public abstract IActionListener getListener();
149
150    /** @since 3.0 * */
151
152    public boolean isDisabled()
153    {
154        return false;
155    }
156
157    /** @since 4.0 */
158
159    public abstract Iterator getSource();
160
161    /** @since 4.0 */
162
163    public abstract void setValue(Object value);
164
165    /** @since 4.0 */
166
167    public abstract void setIndex(int index);
168
169    /** @since 4.0 */
170
171    public abstract DataSqueezer getDataSqueezer();
172
173    /** @since 4.0 */
174
175    public abstract ValueConverter getValueConverter();
176
177    /**
178     * Injected.
179     * 
180     * @since 4.0
181     */
182
183    public abstract ListenerInvoker getListenerInvoker();
184
185    /**
186     * Returns false; ListEdit components can't take focus.
187     * 
188     * @since 4.0
189     */
190    protected boolean getCanTakeFocus()
191    {
192        return false;
193    }
194
195    public String getClientId()
196    {
197        // TODO Auto-generated method stub
198        return null;
199    }
200
201    public String getDisplayName()
202    {
203        // TODO Auto-generated method stub
204        return null;
205    }
206
207}