View Javadoc

1   /*
2    * Copyright 2004-2009 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springmodules.validation.bean.conf.loader.xml;
18  
19  import java.beans.PropertyDescriptor;
20  import java.util.ArrayList;
21  import java.util.Iterator;
22  import java.util.List;
23  
24  import org.slf4j.Logger;
25  import org.slf4j.LoggerFactory;
26  import org.springframework.beans.factory.InitializingBean;
27  import org.springmodules.validation.bean.conf.loader.xml.handler.ClassValidationElementHandler;
28  import org.springmodules.validation.bean.conf.loader.xml.handler.PropertyValidationElementHandler;
29  import org.springmodules.validation.util.cel.ConditionExpressionBased;
30  import org.springmodules.validation.util.cel.ConditionExpressionParser;
31  import org.springmodules.validation.util.cel.valang.ValangConditionExpressionParser;
32  import org.springmodules.validation.util.context.BasicContextAware;
33  import org.springmodules.validation.util.fel.FunctionExpressionBased;
34  import org.springmodules.validation.util.fel.FunctionExpressionParser;
35  import org.springmodules.validation.util.fel.parser.ValangFunctionExpressionParser;
36  import org.w3c.dom.Element;
37  
38  /**
39   * A simple implementation of {@link ValidationRuleElementHandlerRegistry} that enables registration of element
40   * handlers.
41   *
42   * @author Uri Boness
43   */
44  public class SimpleValidationRuleElementHandlerRegistry extends BasicContextAware
45      implements ValidationRuleElementHandlerRegistry, InitializingBean, ConditionExpressionBased, FunctionExpressionBased {
46  
47      private final static Logger logger = LoggerFactory.getLogger(SimpleValidationRuleElementHandlerRegistry.class);
48  
49      private List classHandlers;
50  
51      private List propertyHandlers;
52  
53      private boolean functoinExpressionParserSet = false;
54  
55      private FunctionExpressionParser functionExpressionParser;
56  
57      private boolean conditionExpressionParserSet = false;
58  
59      private ConditionExpressionParser conditionExpressionParser;
60  
61      /**
62       * Constructs a new DefaultValidationRuleElementHandlerRegistry with the default handlers.
63       */
64      public SimpleValidationRuleElementHandlerRegistry() {
65          classHandlers = new ArrayList();
66          propertyHandlers = new ArrayList();
67          functionExpressionParser = new ValangFunctionExpressionParser();
68          conditionExpressionParser = new ValangConditionExpressionParser();
69      }
70  
71      /**
72       * Registers the given class handler with this registry. The registered handler is registered in such a way that it will
73       * be checked first for support (LIFC - Last In First Checked).
74       */
75      public void registerClassHandler(ClassValidationElementHandler handler) {
76          classHandlers.add(0, handler);
77      }
78  
79      /**
80       * @see org.springmodules.validation.bean.conf.loader.xml.ValidationRuleElementHandlerRegistry#findClassHandler(org.w3c.dom.Element, Class)
81       */
82      public ClassValidationElementHandler findClassHandler(Element element, Class clazz) {
83          for (Iterator iter = classHandlers.iterator(); iter.hasNext();) {
84              ClassValidationElementHandler handler = (ClassValidationElementHandler) iter.next();
85              if (handler.supports(element, clazz)) {
86                  return handler;
87              }
88          }
89          return null;
90      }
91  
92      /**
93       * Registers the given property handler with this registry. The registered handler is registered in such a way that
94       * it will be checked first for support. (LIFC - Last In First Checked).
95       */
96      public void registerPropertyHandler(PropertyValidationElementHandler handler) {
97          propertyHandlers.add(0, handler);
98      }
99  
100     /**
101      * @see org.springmodules.validation.bean.conf.loader.xml.ValidationRuleElementHandlerRegistry#findPropertyHandler(org.w3c.dom.Element, Class, java.beans.PropertyDescriptor)
102      */
103     public PropertyValidationElementHandler findPropertyHandler(Element element, Class clazz, PropertyDescriptor descriptor) {
104         for (Iterator iter = propertyHandlers.iterator(); iter.hasNext();) {
105             PropertyValidationElementHandler handler = (PropertyValidationElementHandler) iter.next();
106             if (handler.supports(element, clazz, descriptor)) {
107                 return handler;
108             }
109         }
110         return null;
111     }
112 
113     public void afterPropertiesSet() throws Exception {
114 
115         findConditionExpressionParserInApplicationContext();
116         findFunctionExpressionParserInApplicationContext();
117 
118         for (Iterator iter = classHandlers.iterator(); iter.hasNext();) {
119             ClassValidationElementHandler handler = (ClassValidationElementHandler) iter.next();
120             setExpressionParsers(handler);
121             initLifecycle(handler);
122         }
123 
124         for (Iterator iter = propertyHandlers.iterator(); iter.hasNext();) {
125             PropertyValidationElementHandler handler = (PropertyValidationElementHandler) iter.next();
126             setExpressionParsers(handler);
127             initLifecycle(handler);
128         }
129     }
130 
131     //=============================================== Setter/Getter ====================================================
132 
133     /**
134      * Registeres the given class handlers with this registry.
135      *
136      * @param handlers The handlers to register with this registry.
137      */
138     public void setExtraClassHandlers(ClassValidationElementHandler[] handlers) {
139         for (int i = handlers.length - 1; i >= 0; i--) {
140             registerClassHandler(handlers[i]);
141         }
142     }
143 
144     /**
145      * Resets the class handlers in this registry with the given ones.
146      *
147      * @param handlers The class handlers to be registered with this registry.
148      */
149     public void setClassHandlers(ClassValidationElementHandler[] handlers) {
150         classHandlers.clear();
151         setExtraClassHandlers(handlers);
152     }
153 
154     /**
155      * Registeres the given property handlers with this registry.
156      *
157      * @param handlers The handlers to register with this registry.
158      */
159     public void setExtraPropertyHandlers(PropertyValidationElementHandler[] handlers) {
160         for (int i = handlers.length - 1; i >= 0; i--) {
161             registerPropertyHandler(handlers[i]);
162         }
163     }
164 
165     /**
166      * Resets the property handlers in this registry to the given ones (overriding the existing ones).
167      *
168      * @param handlers The property handlers to register with this registry.
169      */
170     public void setPropertyHandlers(PropertyValidationElementHandler[] handlers) {
171         propertyHandlers.clear();
172         setExtraPropertyHandlers(handlers);
173     }
174 
175     /**
176      * Return all class handlers that are registered with this registry.
177      *
178      * @return All class handlers that are registered with this registry.
179      */
180     public ClassValidationElementHandler[] getClassHandlers() {
181         return (ClassValidationElementHandler[]) classHandlers.toArray(new ClassValidationElementHandler[classHandlers.size()]);
182     }
183 
184     /**
185      * Return all property handlers that are registered with this registry.
186      *
187      * @return All property handlers that are registered with this registry.
188      */
189     public PropertyValidationElementHandler[] getPropertyHandlers() {
190         return (PropertyValidationElementHandler[]) propertyHandlers.toArray(new PropertyValidationElementHandler[propertyHandlers.size()]);
191     }
192 
193     /**
194      * @see org.springmodules.validation.util.fel.FunctionExpressionBased#setFunctionExpressionParser(org.springmodules.validation.util.fel.FunctionExpressionParser)
195      */
196     public void setFunctionExpressionParser(FunctionExpressionParser functionExpressionParser) {
197         this.functoinExpressionParserSet = true;
198         this.functionExpressionParser = functionExpressionParser;
199     }
200 
201     /**
202      * @see org.springmodules.validation.util.cel.ConditionExpressionBased#setConditionExpressionParser(org.springmodules.validation.util.cel.ConditionExpressionParser)
203      */
204     public void setConditionExpressionParser(ConditionExpressionParser conditionExpressionParser) {
205         this.conditionExpressionParserSet = true;
206         this.conditionExpressionParser = conditionExpressionParser;
207     }
208 
209     //=============================================== Helper Methods ===================================================
210 
211     protected void setExpressionParsers(Object object) {
212         if (ConditionExpressionBased.class.isInstance(object) && conditionExpressionParser != null) {
213             ((ConditionExpressionBased) object).setConditionExpressionParser(conditionExpressionParser);
214         }
215         if (FunctionExpressionBased.class.isInstance(object) && functionExpressionParser != null) {
216             ((FunctionExpressionBased) object).setFunctionExpressionParser(functionExpressionParser);
217         }
218     }
219 
220     protected void findConditionExpressionParserInApplicationContext() {
221         if (conditionExpressionParserSet) {
222             return;
223         }
224         ConditionExpressionParser parser = (ConditionExpressionParser) findObjectInApplicationContext(ConditionExpressionParser.class);
225         if (parser == null) {
226             return;
227         }
228         conditionExpressionParser = parser;
229     }
230 
231     protected void findFunctionExpressionParserInApplicationContext() {
232         if (functoinExpressionParserSet) {
233             return;
234         }
235         FunctionExpressionParser parser = (FunctionExpressionParser) findObjectInApplicationContext(FunctionExpressionParser.class);
236         if (parser == null) {
237             return;
238         }
239         functionExpressionParser = parser;
240     }
241 
242     protected Object findObjectInApplicationContext(Class clazz) {
243         if (applicationContext == null) {
244             return null;
245         }
246         String[] names = applicationContext.getBeanNamesForType(clazz);
247         if (names.length == 0) {
248             return null;
249         }
250         if (names.length > 1) {
251             logger.warn("Multiple bean of type '" + clazz.getName() + "' are defined in the application context." +
252                 "Only the first encountered one will be used");
253         }
254         return applicationContext.getBean(names[0]);
255     }
256 
257 }