001/*
002 *  Copyright 2010 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.cms.form;
017
018import java.util.Arrays;
019import java.util.Date;
020import java.util.LinkedHashMap;
021import java.util.Map;
022import java.util.Set;
023
024import org.ametys.cms.repository.Content;
025import org.ametys.core.user.UserIdentity;
026import org.ametys.plugins.repository.metadata.MetadataComment;
027import org.ametys.plugins.repository.metadata.MultilingualString;
028
029/**
030 * Abstraction of the form submitted by the client.
031 */
032public class Form
033{
034    private final Map<String, Object> _fields = new LinkedHashMap<>();
035    private final Map<String, MetadataComment[]> _comments = new LinkedHashMap<>();
036
037    /**
038     * Returns an array containing field names.
039     * @return an array containing field names.
040     */
041    public Set<String> getFieldNames()
042    {
043        return _fields.keySet();
044    }
045    
046    /**
047     * Returns the named field's value as {@link Form}.
048     * @param fieldName the field name.
049     * @return the field value as {@link Form}.
050     */
051    public Form getCompositeField(String fieldName)
052    {
053        Object value = _fields.get(fieldName);
054        
055        if (value == null)
056        {
057            return null;
058        }
059        
060        return (Form) value;
061    }
062    
063    /**
064     * Set a composite field.
065     * @param fieldName the field name.
066     * @param compositeField the composite field.
067     */
068    public void setCompositeField(String fieldName, Form compositeField)
069    {
070        _fields.put(fieldName, compositeField);
071    }
072    
073    /**
074     * Returns the named field's value as {@link RepeaterField}.
075     * @param fieldName the field name.
076     * @return the field value as {@link RepeaterField}.
077     */
078    public RepeaterField getRepeaterField(String fieldName)
079    {
080        Object value = _fields.get(fieldName);
081        
082        if (value == null)
083        {
084            return null;
085        }
086        
087        return (RepeaterField) value;
088    }
089    
090    /**
091     * Returns the named field's value as {@link RichTextField}.
092     * @param fieldName the field name.
093     * @return the field value as RichText.
094     */
095    public RichTextField getRichTextField(String fieldName)
096    {
097        Object value = _fields.get(fieldName);
098        
099        if (value == null)
100        {
101            return null;
102        }
103        
104        if (value instanceof ExternalizableField)
105        {
106            return (RichTextField) ((ExternalizableField) value).getLocalField();
107        }
108        else
109        {
110            return (RichTextField) value;
111        }
112    }
113    
114    /**
115     * Returns the named field's value as {@link BinaryField}.
116     * @param fieldName the field name.
117     * @return the field value as a BinaryField.
118     */
119    public BinaryField getBinaryField(String fieldName)
120    {
121        Object value = _fields.get(fieldName);
122        
123        if (value == null)
124        {
125            return null;
126        }
127        
128        if (value instanceof ExternalizableField)
129        {
130            return (BinaryField) ((ExternalizableField) value).getLocalField();
131        }
132        else
133        {
134            return (BinaryField) value;
135        }
136    }
137    
138    /**
139     * Returns the named field's value as {@link SubContentField}.
140     * @param fieldName the field name.
141     * @return the field value as a SubContentField.
142     */
143    public SubContentField getSubContentField(String fieldName)
144    {
145        Object value = _fields.get(fieldName);
146        
147        if (value == null)
148        {
149            return null;
150        }
151        
152        if (value instanceof ExternalizableField)
153        {
154            return (SubContentField) ((ExternalizableField) value).getLocalField();
155        }
156        else
157        {
158            return (SubContentField) value;
159        }
160    }
161    
162    /**
163     * Returns the named field's value as {@link ReferenceField}.
164     * @param fieldName the field name.
165     * @return the field value as a ReferenceField.
166     */
167    public ReferenceField getReferenceField(String fieldName)
168    {
169        Object value = _fields.get(fieldName);
170        
171        if (value == null)
172        {
173            return null;
174        }
175        
176        if (value instanceof ExternalizableField)
177        {
178            return (ReferenceField) ((ExternalizableField) value).getLocalField();
179        }
180        else
181        {
182            return (ReferenceField) value;
183        }
184    }
185    
186    /**
187     * Returns the named field's value as String array.
188     * @param fieldName the field name.
189     * @return field value as String array.
190     */
191    @SuppressWarnings("unchecked")
192    public SimpleField<String> getStringArray(String fieldName)
193    {
194        Object value = _fields.get(fieldName);
195        
196        if (value == null)
197        {
198            return null;
199        }
200        
201        if (value instanceof ExternalizableField)
202        {
203            return (SimpleField<String>) ((ExternalizableField) value).getLocalField();
204        }
205        else
206        {
207            return (SimpleField<String>) value;
208        }
209    }
210
211    /**
212     * Returns the named field's value as Date array.
213     * @param fieldName the field name.
214     * @return field value as Date array.
215     */
216    @SuppressWarnings("unchecked")
217    public SimpleField<Date> getDateArray(String fieldName)
218    {
219        Object value = _fields.get(fieldName);
220        
221        if (value == null)
222        {
223            return null;
224        }
225        
226        if (value instanceof ExternalizableField)
227        {
228            return (SimpleField<Date>) ((ExternalizableField) value).getLocalField();
229        }
230        else
231        {
232            return (SimpleField<Date>) value;
233        }
234    }
235
236    /**
237     * Returns the named field's value as long array.
238     * @param fieldName the field name.
239     * @return field value as long array.
240     */
241    @SuppressWarnings("unchecked")
242    public SimpleField<Long> getLongArray(String fieldName)
243    {
244        Object value = _fields.get(fieldName);
245        
246        if (value == null)
247        {
248            return null;
249        }
250        
251        if (value instanceof ExternalizableField)
252        {
253            return (SimpleField<Long>) ((ExternalizableField) value).getLocalField();
254        }
255        else
256        {
257            return (SimpleField<Long>) value;
258        }
259    }
260
261    /**
262     * Returns the named field's value as double array.
263     * @param fieldName the field name.
264     * @return field value as double array.
265     */
266    @SuppressWarnings("unchecked")
267    public SimpleField<Double> getDoubleArray(String fieldName)
268    {
269        Object value = _fields.get(fieldName);
270        
271        if (value == null)
272        {
273            return null;
274        }
275        
276        if (value instanceof ExternalizableField)
277        {
278            return (SimpleField<Double>) ((ExternalizableField) value).getLocalField();
279        }
280        else
281        {
282            return (SimpleField<Double>) value;
283        }
284    }
285
286    /**
287     * Returns the named field's value as boolean array.
288     * @param fieldName the field name.
289     * @return field value as boolean array.
290     */
291    @SuppressWarnings("unchecked")
292    public SimpleField<Boolean> getBooleanArray(String fieldName)
293    {
294        Object value = _fields.get(fieldName);
295        
296        if (value == null)
297        {
298            return null;
299        }
300        
301        if (value instanceof ExternalizableField)
302        {
303            return (SimpleField<Boolean>) ((ExternalizableField) value).getLocalField();
304        }
305        else
306        {
307            return (SimpleField<Boolean>) value;
308        }
309    }
310    
311    /**
312     * Returns the named field's value as UserIdentity array.
313     * @param fieldName the field name.
314     * @return field value as UserIdentity array.
315     */
316    @SuppressWarnings("unchecked")
317    public SimpleField<UserIdentity> getUserArray(String fieldName)
318    {
319        Object value = _fields.get(fieldName);
320        
321        if (value == null)
322        {
323            return null;
324        }
325        
326        if (value instanceof ExternalizableField)
327        {
328            return (SimpleField<UserIdentity>) ((ExternalizableField) value).getLocalField();
329        }
330        else
331        {
332            return (SimpleField<UserIdentity>) value;
333        }
334    }
335    
336    /**
337     * Returns the named field's value as MultilingualString array.
338     * @param fieldName the field name.
339     * @return field value as UserIdentity array.
340     */
341    @SuppressWarnings("unchecked")
342    public SimpleField<MultilingualString> getMultilingualStringArray(String fieldName)
343    {
344        Object value = _fields.get(fieldName);
345        
346        if (value == null)
347        {
348            return null;
349        }
350        
351        if (value instanceof ExternalizableField)
352        {
353            return (SimpleField<MultilingualString>) ((ExternalizableField) value).getLocalField();
354        }
355        else
356        {
357            return (SimpleField<MultilingualString>) value;
358        }
359    }
360
361    /**
362     * Returns the named field's value as a content array.
363     * @param fieldName the field name.
364     * @return the field value as a content array.
365     */
366    @SuppressWarnings("unchecked")
367    public SimpleField<Content> getContentArray(String fieldName)
368    {
369        Object value = _fields.get(fieldName);
370        
371        if (value == null)
372        {
373            return null;
374        }
375        
376        if (value instanceof ExternalizableField)
377        {
378            return (SimpleField<Content>) ((ExternalizableField) value).getLocalField();
379        }
380        else
381        {
382            return (SimpleField<Content>) value;
383        }
384    }
385    
386    /**
387     * Returns the named field's value as a {@link ExternalizableField}
388     * @param fieldName the field name.
389     * @return the externalizable field
390     */
391    public ExternalizableField getExternalizableField(String fieldName)
392    {
393        Object value = _fields.get(fieldName);
394        
395        if (value == null)
396        {
397            return null;
398        }
399        
400        return (ExternalizableField) value;
401    }
402    
403    /**
404     * Set a multi-valued date field.
405     * @param fieldName the field name.
406     * @param values the Date array containing values of this field.
407     */
408    public void setField(String fieldName, AbstractField values)
409    {
410        _fields.put(fieldName, values);
411    }
412    
413    /**
414     * Get a non-typed field.
415     * @param fieldName The name of the field
416     * @return The desired field or null
417     */
418    public AbstractField getField(String fieldName)
419    {
420        return (AbstractField) _fields.get(fieldName);
421    }
422        
423    /**
424     * Return the array of comments for the named field.
425     * @param metadataName the field name.
426     * @return the array of comments
427     */
428    public MetadataComment[] getCommentArray(String metadataName)
429    {
430        return _comments.get(metadataName);
431    }
432    
433    /**
434     * Set the comment of a field
435     * @param fieldName The field name
436     * @param comments The array of metadata comments
437     */
438    public void setCommentsField(String fieldName, MetadataComment[] comments)
439    {
440        _comments.put(fieldName, comments);
441    }
442    
443    @Override
444    public String toString()
445    {
446        StringBuilder fields = new StringBuilder();
447        
448        if (_fields.isEmpty())
449        {
450            fields.append("EMPTY");
451            fields.append(System.getProperty("line.separator"));
452        }
453        
454        for (Map.Entry<String, Object> entry : _fields.entrySet())
455        {
456            fields.append(entry.getKey());
457            fields.append(": ");
458            
459            fields.append(entry.getValue());
460            
461            fields.append(System.getProperty("line.separator"));
462        }
463        
464        for (Map.Entry<String, MetadataComment[]> entry : _comments.entrySet())
465        {
466            MetadataComment[] comments = entry.getValue();
467            
468            fields.append(entry.getKey() + " (comments)");
469            fields.append(": ");
470            fields.append(Arrays.asList(comments));
471            fields.append(System.getProperty("line.separator"));
472        }
473
474        return fields.toString();
475    }
476}