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