1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springmodules.validation.valang.parser;
18
19 import java.util.HashMap;
20 import java.util.Map;
21
22 import org.springframework.beans.BeansException;
23 import org.springframework.context.ApplicationContext;
24 import org.springframework.context.ApplicationContextAware;
25 import org.springframework.util.StringUtils;
26 import org.springmodules.validation.valang.functions.FunctionDefinition;
27 import org.springmodules.validation.valang.functions.FunctionWrapper;
28
29 /**
30 * A simple implementation of {@link ValangBased}.
31 *
32 * @author Uri Boness
33 */
34 public class SimpleValangBased implements ApplicationContextAware, ValangBased {
35
36 private ApplicationContext applicationContext = null;
37 private Map<String, Object> hCustomFunctions = new HashMap<String, Object>();
38 private Map dateParsers = new HashMap();
39
40 /**
41 * Implementation of <code>ApplicationContextAware</code>.
42 */
43 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
44 this.applicationContext = applicationContext;
45 }
46
47 /**
48 * @see ValangBased#setCustomFunctions(java.util.Map)
49 */
50 public void setCustomFunctions(Map<String, Object> hCustomFunctions) {
51 this.hCustomFunctions = hCustomFunctions;
52 }
53
54 /**
55 * @see ValangBased#addCustomFunction(String, String)
56 */
57 public void addCustomFunction(String functionName, String functionClassName) {
58 hCustomFunctions.put(functionName, functionClassName);
59 }
60
61 /**
62 * @see ValangBased#setDateParsers(java.util.Map)
63 */
64 public void setDateParsers(Map parserByRegexp) {
65 dateParsers = (parserByRegexp != null) ? parserByRegexp : new HashMap();
66 }
67
68 public Map<String, Object> getCustomFunctions() {
69 return hCustomFunctions;
70 }
71
72 public Map getDateParsers() {
73 return dateParsers;
74 }
75
76 /**
77 * Creates a new {@link ValangParser} that is already configured with the proper custom functions and date
78 * parsers.
79 *
80 * @param expression Valang language validation expression.
81 *
82 * @return A new {@link ValangParser}.
83 */
84 public ValangParser createValangParser(String expression) {
85 return createValangParser(expression, null);
86 }
87
88 /**
89 * Creates a new {@link ValangParser} that is already configured with the proper custom functions and date
90 * parsers and uses the class name to perform bytecode generation to avoid reflection.
91 *
92 * @param expression Valang language validation expression.
93 * @param className Name of the <code>Class</code> to generated
94 * a <code>Function</code> to retrieve a property.
95 *
96 * @return A new {@link ValangParser}.
97 */
98 public ValangParser createValangParser(String expression, String className) {
99 ValangParser parser = new ValangParser(expression, className, getAllCustomFunctions(), dateParsers);
100
101
102 if (parser.getVisitor() instanceof ApplicationContextAware) {
103 ((ApplicationContextAware)parser.getVisitor()).setApplicationContext(applicationContext);
104 }
105
106 return parser;
107 }
108
109 public void initValang(Object object) {
110 if (object instanceof ValangBased) {
111 ((ValangBased) object).setCustomFunctions(hCustomFunctions);
112 ((ValangBased) object).setDateParsers(dateParsers);
113 }
114 }
115
116 /**
117 * Returns all the custom functions that can be found. This method returns all the custom functions
118 * that were explicitly registered with this instance and all custom functions that can be found in the
119 * application context (if one is set) by looking for {@link org.springmodules.validation.valang.functions.FunctionDefinition}
120 * beans.
121 *
122 * @return All the custom function that can be found.
123 */
124 public Map<String, Object> getAllCustomFunctions() {
125 Map<String, Object> functionByName = new HashMap<String, Object>();
126
127 functionByName.putAll(findAllCustomFunctionsInApplicationContext());
128
129
130 functionByName.putAll(hCustomFunctions);
131
132 return functionByName;
133 }
134
135 /**
136 * Finds all <code>FunctionDefinition</code> and <code>FunctionWrapper</code> beans
137 * in the Spring context.
138 */
139 protected Map<String, Object> findAllCustomFunctionsInApplicationContext() {
140 Map<String, Object> hFunctions = new HashMap<String, Object>();
141
142 if (applicationContext != null) {
143
144 String[] beanNames = applicationContext.getBeanNamesForType(FunctionDefinition.class);
145
146 if (beanNames != null) {
147 for (int i = 0; i < beanNames.length; i++) {
148 FunctionDefinition functionDefinition = (FunctionDefinition) applicationContext.getBean(beanNames[i]);
149
150 hFunctions.put(functionDefinition.getName(), functionDefinition.getClassName());
151 }
152 }
153
154
155 beanNames = applicationContext.getBeanNamesForType(FunctionWrapper.class);
156
157 if (beanNames != null) {
158 for (int i = 0; i < beanNames.length; i++) {
159 String beanName = beanNames[i];
160
161 FunctionWrapper functionWrapper = (FunctionWrapper) applicationContext.getBean(beanName);
162
163 String key = functionWrapper.getFunctionName();
164
165 if (!StringUtils.hasText(key)) {
166 key = beanName;
167 }
168
169 hFunctions.put(key, functionWrapper);
170 }
171 }
172 }
173
174 return hFunctions;
175 }
176
177 }