    001package org.apache.turbine.util;
    002
    003
    004/*
    005 * Licensed to the Apache Software Foundation (ASF) under one
    006 * or more contributor license agreements.  See the NOTICE file
    007 * distributed with this work for additional information
    008 * regarding copyright ownership.  The ASF licenses this file
    009 * to you under the Apache License, Version 2.0 (the
    010 * "License"); you may not use this file except in compliance
    011 * with the License.  You may obtain a copy of the License at
    012 *
    013 *   http://www.apache.org/licenses/LICENSE-2.0
    014 *
    015 * Unless required by applicable law or agreed to in writing,
    016 * software distributed under the License is distributed on an
    017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    018 * KIND, either express or implied.  See the License for the
    019 * specific language governing permissions and limitations
    020 * under the License.
    021 */
    022
    023
    024import java.util.Hashtable;
    025import java.util.Iterator;
    026import java.util.List;
    027import java.util.Vector;
    028
    029/**
    030 * Used for adding and accessing messages that relate to a specific
    031 * form and field.  Allows to query for messages by form name and
    032 * field name.  Used together with FormMessage class.
    033 *
    034 * @author <a href="mailto:neeme@one.lv">Neeme Praks</a>
    035 * @version $Id: FormMessages.java 1152507 2011-07-30 20:14:38Z tv $
    036 */
    037public class FormMessages
    038{
    039    private final Hashtable<String, Vector<String>> forms_messages;
    040    private final Hashtable<String, Vector<String>> fields_messages;
    041    private final Hashtable<String, Vector<String>> messages_fields;
    042    private final Hashtable<String, Vector<String>> forms_fields;
    043
    044    /**
    045     * Constructor.
    046     */
    047    public FormMessages()
    048    {
    049        forms_messages = new Hashtable<String, Vector<String>>();
    050        fields_messages = new Hashtable<String, Vector<String>>();
    051        messages_fields = new Hashtable<String, Vector<String>>();
    052        forms_fields = new Hashtable<String, Vector<String>>();
    053    }
    054
    055    /**
    056     * Sets a message for a field of a form.  The message is given as
    057     * a long representing a return code.
    058     *
    059     * @param formName A String with the form name.
    060     * @param fieldName A String with the field name.
    061     * @param returnCode A long with the return code.
    062     */
    063    public void setMessage(String formName,
    064                           String fieldName,
    065                           long returnCode)
    066    {
    067        setMessage(formName, fieldName, String.valueOf(returnCode));
    068    }
    069
    070    /**
    071     * Sets a message for a field of a form.  The message is given as
    072     * a String.
    073     *
    074     * @param formName A String with the form name.
    075     * @param fieldName A String with the field name.
    076     * @param messageName A String with the message.
    077     */
    078    public void setMessage(String formName,
    079                           String fieldName,
    080                           String messageName)
    081    {
    082        fieldName = formName + "-" + fieldName;
    083        addValue(forms_messages, formName, messageName);
    084        addValue(fields_messages, fieldName, messageName);
    085        addValue(messages_fields, messageName, fieldName);
    086        addValue(forms_fields, formName, fieldName);
    087    }
    088
    089    /**
    090     * Adds a pair key/value to a table, making sure not to add
    091     * duplicate keys.
    092     *
    093     * @param table A Hashtable.
    094     * @param key A String with the key.
    095     * @param value A String with value.
    096     */
    097    private void addValue(Hashtable<String, Vector<String>> table,
    098                          String key,
    099                          String value)
    100    {
    101        Vector<String> values;
    102
    103        if (!table.containsKey(key))
    104        {
    105            values = new Vector<String>();
    106            values.addElement(value);
    107            table.put(key, values);
    108        }
    109        else
    110        {
    111            values = table.get(key);
    112            if (!values.contains(value))
    113                values.addElement(value);
    114        }
    115    }
    116
    117    /**
    118     * Gets a pair key/value from a table.
    119     *
    120     * @param table A Hashtable.
    121     * @param key A String with the key.
    122     * @return A Vector with the pair key/value, or null.
    123     */
    124    private final Vector<String> getValues(Hashtable<String, Vector<String>> table, String key)
    125    {
    126        return table.get(key);
    127    }
    128
    129    /**
    130     * Gets all form messages for a given form.
    131     *
    132     * @param formName A String with the form name.
    133     * @return A FormMessage[].
    134     */
    135    public FormMessage[] getFormMessages(String formName)
    136    {
    137        Vector<String> messages, fields;
    138        String messageName, fieldName;
    139        messages = getValues(forms_messages, formName);
    140        if (messages != null)
    141        {
    142            FormMessage[] result = new FormMessage[messages.size()];
    143            for (int i = 0; i < messages.size(); i++)
    144            {
    145                result[i] = new FormMessage(formName);
    146                messageName = messages.elementAt(i);
    147                result[i].setMessage(messageName);
    148                fields = getValues(messages_fields, messageName);
    149                for (int j = 0; j < fields.size(); j++)
    150                {
    151                    fieldName = fields.elementAt(j);
    152                    if (formHasField(formName, fieldName))
    153                    {
    154                        result[i].setFieldName(fieldName);
    155                    }
    156                }
    157            }
    158            return result;
    159        }
    160        return null;
    161    }
    162
    163    /**
    164     * Get form messages for a given form and field.
    165     *
    166     * @param formName A String with the form name.
    167     * @param fieldName A String with the field name.
    168     * @return A FormMessage[].
    169     */
    170    public FormMessage[] getFormMessages(String formName, String fieldName)
    171    {
    172        String key = formName + "-" + fieldName;
    173
    174        Vector<String> messages = getValues(fields_messages, key);
    175        String messageName;
    176
    177        if (messages != null)
    178        {
    179            FormMessage[] result = new FormMessage[messages.size()];
    180            for (int i = 0; i < messages.size(); i++)
    181            {
    182                result[i] = new FormMessage(formName, fieldName);
    183                messageName = messages.elementAt(i);
    184                result[i].setMessage(messageName);
    185            }
    186            return result;
    187        }
    188        return null;
    189    }
    190
    191    /**
    192     * Check whether a form as a field.
    193     *
    194     * @param formName A String with the form name.
    195     * @param fieldName A String with the field name.
    196     * @return True if form has the field.
    197     */
    198    private boolean formHasField(String formName,
    199                                 String fieldName)
    200    {
    201        List<String> fields = getValues(forms_fields, formName);
    202        for (Iterator<String> iter = fields.iterator(); iter.hasNext();)
    203        {
    204            if (fieldName.equals(iter.next().toString()))
    205            {
    206                return true;
    207            }
    208        }
    209        return false;
    210    }
    211}