001package org.apache.turbine.util.template;
002
003import org.apache.ecs.html.Option;
004import org.apache.ecs.html.Select;
005
006
007/*
008 * Licensed to the Apache Software Foundation (ASF) under one
009 * or more contributor license agreements.  See the NOTICE file
010 * distributed with this work for additional information
011 * regarding copyright ownership.  The ASF licenses this file
012 * to you under the Apache License, Version 2.0 (the
013 * "License"); you may not use this file except in compliance
014 * with the License.  You may obtain a copy of the License at
015 *
016 *   http://www.apache.org/licenses/LICENSE-2.0
017 *
018 * Unless required by applicable law or agreed to in writing,
019 * software distributed under the License is distributed on an
020 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
021 * KIND, either express or implied.  See the License for the
022 * specific language governing permissions and limitations
023 * under the License.
024 */
025
026/**
027 * This class is for generating a SelectorBox. It is good when used
028 * with WM because you can stuff it into the context and then just
029 * call it to generate the HTML.  It can be used in other cases as
030 * well, but WM is the best case for it right now.
031 *
032 * <p>For example code showing the usage for this module, please see
033 * the toString() method below to see how it would be referred to from
034 * WM.
035 *
036 * <pre>
037 * // get the roles for a user
038 * RoleSet userRoles = new DefaultAccessControl().getRoles(loginid, null);
039 * if ( userRoles != null )
040 * {
041 *     context.put("hasRoleSet", Boolean.TRUE);
042 *
043 *     // get an array of the users roles
044 *     Role[] usersRoles = userRoles.getRolesArray();
045 *     // get an array of all the roles in the system
046 *     Role[] allRoles = ((RoleSet)RolePeer.retrieveSet()).getRolesArray();
047 *
048 *     Object[] names = new Object[allRoles.length];
049 *     Object[] values = new Object[allRoles.length];
050 *     for ( int i=0;i&lt;allRoles.length; i++ )
051 *     {
052 *         names[i] = Integer.valueOf(allRoles[i].getPrimaryKey()).toString();
053 *         values[i] = allRoles[i].getName();
054 *     }
055 *
056 *     SelectorBox sb = new SelectorBox("roleSetBox", names, values);
057 *     sb.buildBooleans(usersRoles, allRoles);
058 *     context.put("roleSetBox", sb);
059 * }
060 * else
061 * {
062 *     context.put("hasRoleSet", Boolean.FALSE);
063 * }
064 * </pre>
065 *
066 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
067 * @version $Id: SelectorBox.java 1726423 2016-01-23 17:55:09Z tv $
068 */
069public class SelectorBox
070{
071    /** This is the Select ECS element. */
072    private Select sel = null;
073
074    /** This is the size of the Select statement. */
075    private int size = 1;
076
077    /** This is the name= value. */
078    private String name = null;
079
080    /** This is the value= portion of the option element. */
081    private Object[] names = null;
082
083    /** This is the data after the option element. */
084    private Object[] values = null;
085
086    /** This is an array of which items are selected. */
087    private boolean[] selected = null;
088
089    /**
090     * Generic constructor, builds a select box with a default size of
091     * 1 and no selected items.
092     *
093     * @param name A String with the name for the select box.
094     * @param names An Object[] with the names.
095     * @param values An Object[] with the values.
096     */
097    public SelectorBox(String name, Object[] names, Object[] values)
098    {
099        this(name, names, values, 1, null);
100    }
101
102    /**
103     * Generic constructor builds a select box.
104     *
105     * @param name A String with the name for the select box.
106     * @param names An Object[] with the names.
107     * @param values An Object[] with the values.
108     * @param size An int specifying the size.
109     */
110    public SelectorBox(String name, Object[] names, Object[] values, int size)
111    {
112        this(name, names, values, size, null);
113    }
114
115    /**
116     * Generic constructor builds a select box.
117     *
118     * @param name A String with the name for the select box.
119     * @param names An Object[] with the names.
120     * @param values An Object[] with the values.
121     * @param selected A boolean[] with the selected items.
122     */
123    public SelectorBox(String name, Object[] names, Object[] values,
124                       boolean[] selected)
125    {
126        this(name, names, values, 1, selected);
127    }
128
129    /**
130     * Primary constructor for everything.
131     *
132     * @param name A String with the name for the select box.
133     * @param names An Object[] with the names.
134     * @param values An Object[] with the values.
135     * @param size An int specifying the size.
136     * @param selected A boolean[] with the selected items.
137     */
138    public SelectorBox(String name, Object[] names, Object[] values, int size,
139                       boolean[] selected)
140    {
141        this.name = name;
142        this.names = names;
143        this.values = values;
144        this.size = size;
145        this.selected = selected;
146
147        sel = new Select(name, size);
148        sel.setName(name);
149        sel.setSize(size);
150    }
151
152    /**
153     * Pass in an array of selected items and the entire set of items
154     * and it will determine which items in the selected set are also
155     * in the entire set and then build a boolean[] up that is the same
156     * size as the entireSet with markings to tell whether or not the
157     * items are marked or not.  It uses toString().equalsIgnoreCase()
158     * on the Object in the Object[] to determine if the items are
159     * equal.
160     *
161     * @param selectedSet An Object[].
162     * @param entireSet An Object[].
163     */
164    public void buildBooleans(Object[] selectedSet, Object[] entireSet)
165    {
166        selected = new boolean[entireSet.length];
167        for (int j = 0; j < entireSet.length; j++)
168        {
169            Object r2 = entireSet[j];
170            for (int i = 0; i < selectedSet.length; i++)
171            {
172                Object r1 = selectedSet[i];
173                if (r1 != null && r2 != null &&
174                        r1.toString().equalsIgnoreCase(r2.toString()))
175                {
176                    selected[j] = true;
177                }
178            }
179        }
180    }
181
182    /**
183     * This builds out the select box at a certain size.  To use this
184     * element in WM, you simply build this object in your java code,
185     * put it into the context and then call $selectBox.toString(5).
186     *
187     * @param size An int with the size.
188     * @return A String with the HTML code.
189     */
190    public String toString(int size)
191    {
192        sel.setSize(size);
193        sel.setName(name);
194        for (int f = 0; f < values.length; f++)
195        {
196            Option opt = new Option((String) values[f]);
197            opt.addElement((String) names[f]);
198            if (selected != null && selected[f] == true)
199            {
200                opt.setSelected(true);
201            }
202            sel.addElement(opt);
203        }
204        String output = sel.toString();
205        reset();
206        return output;
207    }
208
209    /**
210     * Resets the internal state of the SelectorBox.
211     */
212    public void reset()
213    {
214        sel = new Select(name, size);
215    }
216
217    /**
218     * This builds out the select box at a certain size.  To use this
219     * element in WM, you simply build this object in your java code,
220     * put it into the context and then call $selectBox and it will
221     * build it with the default size of 1.
222     *
223     * @return A String with the HTML code.
224     */
225    @Override
226    public String toString()
227    {
228        return this.toString(size);
229    }
230
231    /**
232     * This allows you to set the multiple attribute to the select
233     * element.  Example usage from within WM is like this:
234     *
235     * <p>
236     * $selectBox.setMultiple(true).toString(4)
237     *
238     * @param val True if multiple selection should be allowed.
239     * @return A SelectorBox (self).
240     */
241    public SelectorBox setMultiple(boolean val)
242    {
243        sel.setMultiple(val);
244        return this;
245    }
246
247    /**
248     * This allows one to set the name= attribute to the select
249     * element.
250     *
251     * @param name A String with the name.
252     * @return A SelectorBox (self).
253     */
254    public SelectorBox setName(String name)
255    {
256        this.name = name;
257        sel.setName(name);
258        return this;
259    }
260
261    /**
262     * This allows one to set the size of the select element.
263     *
264     * @param size An int with the size.
265     * @return A SelectorBox (self).
266     */
267    public SelectorBox setSize(int size)
268    {
269        this.size = size;
270        sel.setSize(size);
271        return this;
272    }
273
274    /**
275     * This allows one to set an onChange attribute on the select tag
276     *
277     * @param script A string with the script to put in onChange
278     * @return A SelectorBox (self).
279     */
280    public SelectorBox setOnChange(String script)
281    {
282        sel.setOnChange(script);
283        return this;
284    }
285
286    /**
287     * This allows one to set the array of selected booleans.
288     *
289     * @param bools an array of booleans
290     * @return A SelectorBox (self).
291     */
292    public SelectorBox setSelected(boolean[] bools)
293    {
294        this.selected = bools;
295        return this;
296    }
297
298    /**
299     * This will set all elements as unselected, except for the
300     * element(s) with the given name.
301     *
302     * @param name The name to appear as selected.
303     * @return A SelectorBox (self).
304     */
305    public SelectorBox setSelected(Object name)
306    {
307        if (name != null)
308        {
309            selected = new boolean[names.length];
310            for (int i = 0; i < names.length; i++)
311            {
312                Object o = names[i];
313                if (o != null && o.toString().equalsIgnoreCase(name.toString()))
314                {
315                    selected[i] = true;
316                }
317            }
318        }
319        return this;
320    }
321}