View Javadoc

1   /*
2    * $Id: ValidatorFilter.java 269 2005-08-10 17:49:22Z josem $
3    *
4    * Tarsis
5    * Copyright (C) 2002 Talika Open Source Group
6    *
7    * This program is free software; you can redistribute it and/or modify
8    * it under the terms of the GNU General Public License as published by
9    * the Free Software Foundation; either version 2 of the License, or
10   * (at your option) any later version.
11   *
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with this program; if not, write to the Free Software
19   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20   *
21   */
22  
23  package org.talika.tarsis.filters.validator;
24  
25  import java.io.IOException;
26  import java.text.ParseException;
27  import java.util.Collections;
28  import java.util.HashMap;
29  import java.util.LinkedList;
30  
31  import javax.servlet.FilterChain;
32  import javax.servlet.ServletException;
33  import javax.servlet.ServletRequest;
34  import javax.servlet.ServletResponse;
35  import javax.servlet.http.HttpServletRequest;
36  
37  import org.talika.commons.util.ParseHelper;
38  import org.talika.tarsis.command.Command;
39  import org.talika.tarsis.command.CommandParameter;
40  import org.talika.tarsis.command.RequestImpl;
41  import org.talika.tarsis.command.action.Action;
42  import org.talika.tarsis.filters.CommandFilter;
43  
44  /**
45   * <code>ValidatorFilter</code> validates command parameters sent in client's request.
46   *
47   * @author  Jose M. Palomar
48   * @version $Revision: 269 $
49   */
50  
51  public class ValidatorFilter extends CommandFilter {
52  
53      // Fields
54      /**
55       * Parse helper.
56       */
57      private ParseHelper parser = ParseHelper.getInstance();
58  
59      // Methods
60      /**
61       * Validates command parameters sent in client's request.
62       *
63       * @param servletRequest ServletRequest the <code>ServletRequest</code> object
64       * that contains the client's request.
65       * @param servletResponse ServletResponse the <code>ServletResponse</code> object
66       * that contains the servlet's response.
67       * @param filterChain FilterChain invocation chain of filtered request.
68       * @throws IOException if an input or output exception occurs
69       * @throws ServletException if an exception has occurred that interferes with the
70       * filter's normal operation
71       * @see javax.servlet.Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
72       */
73      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
74      FilterChain filterChain)
75      throws IOException, ServletException {
76  
77          if (getLogger().isDebugEnabled()) {
78              getLogger().logDebug(getFilterConfig().getFilterName() + ": invoked");
79          }
80  
81          try {
82              Command cmd = findCommand(servletRequest);
83              if (cmd != null && cmd.isValidable()) {
84  
85                  // Generic parameter validation
86                  validate(cmd.getParameters(), servletRequest);
87  
88                  // Bussiness parameter validation
89                  Action action = cmd.getAction();
90                  action.validate(new RequestImpl((HttpServletRequest) servletRequest));
91              }
92          }
93          catch (Throwable t) {
94              throw new ServletException(t);
95          }
96  
97          filterChain.doFilter(servletRequest, servletResponse);
98  
99      }
100 
101     /**
102      * Validates command parameters sent in request.
103      *
104      * @param parameters CommandParameter[] array of parameters definitions.
105      * @param request ServletRequest the <code>ServletRequest</code> object
106      * that contains the client's request.
107      * @throws InvalidParametersException if a invalid parameter value was found.
108      */
109     protected final void validate(CommandParameter[] parameters, ServletRequest request)
110     throws InvalidParametersException {
111 
112         LinkedList missing = null;
113         HashMap invalid = null;
114 
115         for (int i = 0; i < parameters.length; i++) {
116 
117             try {
118 
119                 String value = request.getParameter(parameters[i].getName());
120 
121                 // Check if is required and present
122                 checkRequired(parameters[i], value);
123 
124                 // Get value/s
125                 Object parsedValue = null;
126                 if (parameters[i].isMultiple()) {
127                     parsedValue = getMultipleParameter(parameters[i],
128                                     request.getParameterValues(parameters[i].getName()));
129                 }
130                 else {
131                     parsedValue = getParameter(parameters[i], value);
132                 }
133 
134                 // Set attribute
135                 if (request.getAttribute(parameters[i].getName()) == null) {
136                     request.setAttribute(parameters[i].getName(), parsedValue);
137                 }
138 
139             }
140             catch (RequiredParameterException rpe) {
141                 if (missing == null) {
142                     missing = new LinkedList();
143                 }
144                 missing.add(rpe.getParameterName());
145             }
146             catch (InvalidValueException ive) {
147                 if (invalid == null) {
148                     invalid = new HashMap();
149                 }
150                 invalid.put(ive.getParameterName(), ive.getParameterValue());
151             }
152 
153         }
154 
155         if (missing != null || invalid != null) {
156             throw new InvalidParametersException("Invalid parameters in request", missing, invalid);
157         }
158 
159     }
160 
161     /**
162      * Checks if a parameter required was sent.
163      *
164      * @param parameter CommandParameter parameter definition.
165      * @param value String parameter value.
166      * @throws RequiredParameterException if parameter is required and was not sent.
167      */
168     protected final void checkRequired(CommandParameter parameter, String value)
169     throws RequiredParameterException {
170 
171         if ((value == null || value.length() == 0) && parameter.isRequired())  {
172             if (getLogger().isDebugEnabled()) {
173                 getLogger().logDebug("Validator Filter: Parameter " + parameter.getName() + " is required");
174             }
175             throw new RequiredParameterException(parameter.getName(), value);
176         }
177 
178     }
179 
180     /**
181      * Obtains parsed parameter value from string value.
182      *
183      * @param parameter CommandParameter parameter definition.
184      * @param value String parameter value.
185      * @return Object parsed parameter value.
186      * @throws InvalidValueException if parameter value can not be parsed.
187      */
188     protected final Object getParameter(CommandParameter parameter, String value)
189     throws InvalidValueException {
190 
191         if (value == null || value.length() == 0) {
192                 return parameter.defaultValue();
193         }
194         else {
195 
196              try {
197                 return parser.parseObject(parameter.getType(), value);
198              }
199              catch (ParseException pe) {
200                  if (getLogger().isDebugEnabled()) {
201                      getLogger().logDebug("Validator Filter: Invalid value \"" + value +
202                                             "\" for parameter " + parameter.getName());
203                  }
204                  throw new InvalidValueException(parameter.getName(), value);
205              }
206 
207         }
208     }
209 
210     /**
211      * Obtains parsed <code>Collection</code> of parameters values from array of
212      * string values.
213      *
214      * @param parameter CommandParameter parameter definition.
215      * @param values String[] array of parameter values.
216      * @return Object <code>Collection</code> of parsed parameters values.
217      * @throws InvalidValueException if parameters values can not be parsed.
218      */
219     protected final Object getMultipleParameter(CommandParameter parameter, String[] values)
220     throws InvalidValueException {
221 
222         if (values == null) {
223                 return parameter.defaultValue();
224         }
225         else {
226 
227             LinkedList parsedValues = new LinkedList();
228             for (int i = 0; i < values.length; i++) {
229                 try {
230                       parsedValues.add(parser.parseObject(parameter.getType(), values[i]));
231                  }
232                  catch (ParseException pe) {
233                      if (getLogger().isDebugEnabled()) {
234                          getLogger().logDebug("Validator Filter: Invalid value \"" + values[i] +
235                                     "\" for parameter " + parameter.getName());
236                      }
237                      throw new InvalidValueException(parameter.getName(), values[i]);
238                  }
239             }
240 
241             return Collections.unmodifiableList(parsedValues);
242 
243         }
244 
245     }
246 
247 }