001 /**
002 * Copyright 2005-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.rice.krad.datadictionary.validation;
017
018 import org.apache.commons.lang.StringUtils;
019 import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException;
020 import org.kuali.rice.krad.datadictionary.validation.capability.CaseConstrainable;
021 import org.kuali.rice.krad.datadictionary.validation.capability.Constrainable;
022 import org.kuali.rice.krad.datadictionary.validation.capability.MustOccurConstrainable;
023 import org.kuali.rice.krad.datadictionary.validation.capability.PrerequisiteConstrainable;
024 import org.kuali.rice.krad.datadictionary.validation.capability.SimpleConstrainable;
025 import org.kuali.rice.krad.datadictionary.validation.capability.ValidCharactersConstrainable;
026 import org.kuali.rice.krad.datadictionary.validation.constraint.CaseConstraint;
027 import org.kuali.rice.krad.datadictionary.validation.constraint.MustOccurConstraint;
028 import org.kuali.rice.krad.datadictionary.validation.constraint.PrerequisiteConstraint;
029 import org.kuali.rice.krad.datadictionary.validation.constraint.SimpleConstraint;
030 import org.kuali.rice.krad.datadictionary.validation.constraint.ValidCharactersConstraint;
031 import org.kuali.rice.krad.uif.UifConstants;
032 import org.kuali.rice.krad.uif.UifPropertyPaths;
033 import org.kuali.rice.krad.uif.lifecycle.ViewPostMetadata;
034 import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
035 import org.kuali.rice.krad.uif.view.ViewModel;
036
037 import java.util.ArrayList;
038 import java.util.HashMap;
039 import java.util.List;
040 import java.util.Map;
041
042 /**
043 * AttributeValueReader which can read the correct values from all InputFields which exist on the View
044 *
045 * @author Kuali Rice Team (rice.collab@kuali.org)
046 */
047 public class ViewAttributeValueReader extends BaseAttributeValueReader {
048 private ViewModel form;
049
050 private List<Constrainable> inputFields = new ArrayList<Constrainable>();
051 private Map<String, InputFieldConstrainableInfo> inputFieldMap = new HashMap<String, InputFieldConstrainableInfo>();
052
053 /**
054 * Constructor for ViewAttributeValueReader, the View must already be indexed and
055 * the InputFields must have already be initialized for this reader to work properly
056 *
057 * @param form model object representing the View's form data
058 */
059 public ViewAttributeValueReader(ViewModel form) {
060 this.form = form;
061
062 ViewPostMetadata viewPostMetadata = form.getViewPostMetadata();
063
064 // Copying information stored about InputField in the post metadata to info objects for use by this reader
065 for (String id : viewPostMetadata.getInputFieldIds()) {
066 InputFieldConstrainableInfo info = new InputFieldConstrainableInfo();
067
068 Object label = viewPostMetadata.getComponentPostData(id, UifConstants.PostMetadata.LABEL);
069 if (label != null) {
070 info.setLabel((String) label);
071 }
072
073 Object name = viewPostMetadata.getComponentPostData(id, UifConstants.PostMetadata.PATH);
074 if (name != null) {
075 info.setName((String) name);
076 }
077
078 Object validCharactersConstraint = viewPostMetadata.getComponentPostData(id,
079 UifConstants.PostMetadata.VALID_CHARACTER_CONSTRAINT);
080 if (validCharactersConstraint != null) {
081 info.setValidCharactersConstraint((ValidCharactersConstraint) validCharactersConstraint);
082 }
083
084 Object caseConstraint = viewPostMetadata.getComponentPostData(id,
085 UifConstants.PostMetadata.CASE_CONSTRAINT);
086 if (caseConstraint != null) {
087 info.setCaseConstraint((CaseConstraint) caseConstraint);
088 }
089
090 Object prerequisiteConstraints = viewPostMetadata.getComponentPostData(id,
091 UifConstants.PostMetadata.PREREQ_CONSTSTRAINTS);
092 if (prerequisiteConstraints != null) {
093 info.setPrerequisiteConstraints((List<PrerequisiteConstraint>) prerequisiteConstraints);
094 }
095
096 Object mustOccurConstraints = viewPostMetadata.getComponentPostData(id,
097 UifConstants.PostMetadata.MUST_OCCUR_CONSTRAINTS);
098 if (mustOccurConstraints != null) {
099 info.setMustOccurConstraints((List<MustOccurConstraint>) mustOccurConstraints);
100 }
101
102 Object simpleConstraint = viewPostMetadata.getComponentPostData(id,
103 UifConstants.PostMetadata.SIMPLE_CONSTRAINT);
104 if (simpleConstraint != null) {
105 info.setSimpleConstraint((SimpleConstraint) simpleConstraint);
106 }
107
108 inputFields.add(info);
109 inputFieldMap.put(info.getName(), info);
110 }
111 }
112
113 /**
114 * Gets the definition which is an InputField on the View/Page
115 */
116 @Override
117 public Constrainable getDefinition(String attributeName) {
118 InputFieldConstrainableInfo field = inputFieldMap.get(attributeName);
119 if (field != null) {
120 return field;
121 } else {
122 return null;
123 }
124 }
125
126 /**
127 * Gets all InputFields (which extend Constrainable)
128 *
129 * @return constrainable input fields
130 */
131 @Override
132 public List<Constrainable> getDefinitions() {
133 return inputFields;
134 }
135
136 /**
137 * Returns the label associated with the InputField which has that AttributeName
138 *
139 * @param attributeName attribute name
140 * @return label associated with the named attribute
141 */
142 @Override
143 public String getLabel(String attributeName) {
144 InputFieldConstrainableInfo field = inputFieldMap.get(attributeName);
145 if (field != null) {
146 return field.getLabel();
147 } else {
148 return "";
149 }
150 }
151
152 /**
153 * Returns the Form object
154 *
155 * @return form set in the constructor
156 */
157 @Override
158 public Object getObject() {
159 return form;
160 }
161
162 /**
163 * Not used for this reader, returns null
164 *
165 * @return null
166 */
167 @Override
168 public Constrainable getEntry() {
169 return null;
170 }
171
172 /**
173 * Returns current attributeName which represents the path
174 *
175 * @return attributeName set on this reader
176 */
177 @Override
178 public String getPath() {
179 return this.attributeName;
180 }
181
182 /**
183 * Gets the type of value for this AttributeName as represented on the Form
184 *
185 * @param attributeName
186 * @return attribute type
187 */
188 @Override
189 public Class<?> getType(String attributeName) {
190 Object fieldValue = ObjectPropertyUtils.getPropertyValue(form, attributeName);
191 return fieldValue.getClass();
192 }
193
194 /**
195 * If the current attribute being evaluated is a field of an addLine return false because it should not
196 * be evaluated during Validation.
197 *
198 * @return false if InputField is part of an addLine for a collection, true otherwise
199 */
200 @Override
201 public boolean isReadable() {
202 if (attributeName != null && attributeName.contains(UifPropertyPaths.NEW_COLLECTION_LINES)) {
203 return false;
204 }
205 return true;
206 }
207
208 /**
209 * Return value of the field for the attributeName currently set on this reader
210 *
211 * @param <X> return type
212 * @return value of the field for the attributeName currently set on this reader
213 * @throws AttributeValidationException
214 */
215 @Override
216 public <X> X getValue() throws AttributeValidationException {
217 X fieldValue = null;
218 if (StringUtils.isNotBlank(this.attributeName)) {
219 fieldValue = ObjectPropertyUtils.<X>getPropertyValue(form, this.attributeName);
220 }
221 return fieldValue;
222 }
223
224 /**
225 * Return value of the field for the attributeName passed in
226 *
227 * @param attributeName name (which represents a path) of the value to be retrieved on the Form
228 * @param <X> return type
229 * @return value of that attributeName represents on the form
230 * @throws AttributeValidationException
231 */
232 @Override
233 public <X> X getValue(String attributeName) throws AttributeValidationException {
234 X fieldValue = null;
235 if (StringUtils.isNotBlank(attributeName)) {
236 fieldValue = ObjectPropertyUtils.<X>getPropertyValue(form, this.attributeName);
237 }
238 return fieldValue;
239 }
240
241 /**
242 * Cones this AttributeValueReader
243 *
244 * @return AttributeValueReader
245 */
246 @Override
247 public AttributeValueReader clone() {
248 ViewAttributeValueReader clone = new ViewAttributeValueReader(form);
249 clone.setAttributeName(this.attributeName);
250 return clone;
251 }
252
253 /**
254 * This is a simple object used to contain information about InputFields that are being evaluated and used by
255 * this ViewAttributeValueReader.
256 *
257 * <p>For full documentation refer to the {@link org.kuali.rice.krad.uif.field.InputField} class.</p>
258 */
259 public class InputFieldConstrainableInfo implements SimpleConstrainable, CaseConstrainable, PrerequisiteConstrainable, MustOccurConstrainable, ValidCharactersConstrainable {
260
261 private String label;
262 private String name;
263 private ValidCharactersConstraint validCharactersConstraint;
264 private CaseConstraint caseConstraint;
265 private List<PrerequisiteConstraint> prerequisiteConstraints;
266 private List<MustOccurConstraint> mustOccurConstraints;
267 private SimpleConstraint simpleConstraint;
268
269 /**
270 * Get the field's label
271 *
272 * @return the label
273 */
274 public String getLabel() {
275 return label;
276 }
277
278 /**
279 * @see org.kuali.rice.krad.datadictionary.validation.ViewAttributeValueReader.InputFieldConstrainableInfo#getLabel()
280 */
281 public void setLabel(String label) {
282 this.label = label;
283 }
284
285 /**
286 * {@inheritDoc}
287 */
288 @Override
289 public String getName() {
290 return name;
291 }
292
293 /**
294 * @see org.kuali.rice.krad.datadictionary.validation.ViewAttributeValueReader.InputFieldConstrainableInfo#getName()
295 */
296 public void setName(String name) {
297 this.name = name;
298 }
299
300 /**
301 * {@inheritDoc}
302 */
303 @Override
304 public ValidCharactersConstraint getValidCharactersConstraint() {
305 return validCharactersConstraint;
306 }
307
308 /**
309 * @see org.kuali.rice.krad.datadictionary.validation.ViewAttributeValueReader.InputFieldConstrainableInfo#getValidCharactersConstraint()
310 */
311 public void setValidCharactersConstraint(ValidCharactersConstraint validCharactersConstraint) {
312 this.validCharactersConstraint = validCharactersConstraint;
313 }
314
315 /**
316 * {@inheritDoc}
317 */
318 @Override
319 public CaseConstraint getCaseConstraint() {
320 return caseConstraint;
321 }
322
323 /**
324 * @see org.kuali.rice.krad.datadictionary.validation.ViewAttributeValueReader.InputFieldConstrainableInfo#getCaseConstraint()
325 */
326 public void setCaseConstraint(CaseConstraint caseConstraint) {
327 this.caseConstraint = caseConstraint;
328 }
329
330 /**
331 * {@inheritDoc}
332 */
333 @Override
334 public List<PrerequisiteConstraint> getPrerequisiteConstraints() {
335 return prerequisiteConstraints;
336 }
337
338 /**
339 * @see org.kuali.rice.krad.datadictionary.validation.ViewAttributeValueReader.InputFieldConstrainableInfo#getPrerequisiteConstraints()
340 */
341 public void setPrerequisiteConstraints(List<PrerequisiteConstraint> prerequisiteConstraints) {
342 this.prerequisiteConstraints = prerequisiteConstraints;
343 }
344
345 /**
346 * {@inheritDoc}
347 */
348 @Override
349 public List<MustOccurConstraint> getMustOccurConstraints() {
350 return mustOccurConstraints;
351 }
352
353 /**
354 * @see org.kuali.rice.krad.datadictionary.validation.ViewAttributeValueReader.InputFieldConstrainableInfo#getMustOccurConstraints()
355 */
356 public void setMustOccurConstraints(List<MustOccurConstraint> mustOccurConstraints) {
357 this.mustOccurConstraints = mustOccurConstraints;
358 }
359
360 /**
361 * {@inheritDoc}
362 */
363 @Override
364 public SimpleConstraint getSimpleConstraint() {
365 return simpleConstraint;
366 }
367
368 /**
369 * @see org.kuali.rice.krad.datadictionary.validation.ViewAttributeValueReader.InputFieldConstrainableInfo#getSimpleConstraint()
370 */
371 public void setSimpleConstraint(SimpleConstraint simpleConstraint) {
372 this.simpleConstraint = simpleConstraint;
373 }
374 }
375
376 }