001    package 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    
024    import java.util.Hashtable;
025    import java.util.Iterator;
026    import java.util.List;
027    import 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 1073174 2011-02-21 22:18:45Z tv $
036     */
037    public 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 fields = getValues(forms_fields, formName);
202            for (Iterator iter = fields.iterator(); iter.hasNext();)
203            {
204                if (fieldName.equals(iter.next().toString()))
205                {
206                    return true;
207                }
208            }
209            return false;
210        }
211    }