001/**
002 * Copyright 2005-2016 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 */
016package org.kuali.rice.krad.datadictionary.validation;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.krad.datadictionary.DataDictionaryEntry;
020import org.kuali.rice.krad.datadictionary.exception.AttributeValidationException;
021import org.kuali.rice.krad.datadictionary.validation.capability.Constrainable;
022import org.kuali.rice.krad.uif.UifPropertyPaths;
023import org.kuali.rice.krad.uif.container.Group;
024import org.kuali.rice.krad.uif.field.DataField;
025import org.kuali.rice.krad.uif.field.InputField;
026import org.kuali.rice.krad.uif.util.ObjectPropertyUtils;
027import org.kuali.rice.krad.uif.view.View;
028import org.kuali.rice.krad.web.form.UifFormBase;
029import org.springframework.beans.BeanWrapperImpl;
030
031import java.util.ArrayList;
032import java.util.HashMap;
033import java.util.List;
034import java.util.Map;
035
036/**
037 * AttributeValueReader which can read the correct values from all InputFields which exist on the View
038 */
039public class ViewAttributeValueReader extends BaseAttributeValueReader {
040
041    private View view;
042    private Object form;
043    private List<Constrainable> inputFields = new ArrayList<Constrainable>();
044    private Map<String, InputField> inputFieldMap = new HashMap<String, InputField>();
045
046    /**
047     * Constructor for ViewAttributeValueReader, the View must already be indexed and
048     * the InputFields must have already be initialized for this reader to work properly
049     * @param view the View to validate
050     * @param form model object representing the View's form data
051     */
052    public ViewAttributeValueReader(View view, Object form) {
053        this.view = view;
054        this.form = form;
055
056        for (InputField field : view.getAllInputFields()) {
057            inputFields.add(field);
058            inputFieldMap.put(field.getName(), field);
059        }
060    }
061
062    /*  TODO allow it to be page specific only
063        public ViewAttributeValueReader(View view, Page page, UifFormBase form) {
064        this.view = view;
065        this.form = form;
066        for(DataField field: view.getViewIndex().getDataFieldIndex().values()){
067            if(field instanceof Constrainable){
068                inputFields.add((Constrainable)field);
069            }
070        }
071    }*/
072
073
074    /**
075     * Gets the definition which is an InputField on the View/Page
076     */
077    @Override
078    public Constrainable getDefinition(String attributeName) {
079        InputField field = inputFieldMap.get(attributeName);
080        if (field != null) {
081            return field;
082        }
083        else{
084            return null;
085        }
086    }
087
088    /**
089     * Gets all InputFields (which extend Constrainable)
090     * @return
091     */
092    @Override
093    public List<Constrainable> getDefinitions() {
094        return inputFields;
095    }
096
097    /**
098     * Returns the label associated with the InputField which has that AttributeName
099     * @param attributeName
100     * @return
101     */
102    @Override
103    public String getLabel(String attributeName) {
104        InputField field = inputFieldMap.get(attributeName);
105        if(field != null){
106            return field.getLabel();
107        }
108        else{
109            return null;
110        }
111    }
112
113    /**
114     * Returns the View object
115     * @return view set in the constructor
116     */
117    @Override
118    public Object getObject() {
119        return view;
120    }
121
122    /**
123     * Not used for this reader, returns null
124     * @return null
125     */
126    @Override
127    public Constrainable getEntry() {
128        return null;
129    }
130
131    /**
132     * Returns current attributeName which represents the path
133     * @return attributeName set on this reader
134     */
135    @Override
136    public String getPath() {
137        return this.attributeName;
138    }
139
140    /**
141     * Gets the type of value for this AttributeName as represented on the Form
142     * @param attributeName
143     * @return
144     */
145    @Override
146    public Class<?> getType(String attributeName) {
147        Object fieldValue = ObjectPropertyUtils.getPropertyValue(form, attributeName);
148        return fieldValue.getClass();
149    }
150
151    /**
152     * If the current attribute being evaluated is a field of an addLine return false because it should not
153     * be evaluated during Validation.
154     * @return false if InputField is part of an addLine for a collection, true otherwise
155     */
156    @Override
157    public boolean isReadable() {
158        if(attributeName != null && attributeName.contains(UifPropertyPaths.NEW_COLLECTION_LINES)){
159            return false;
160        }
161        return true;
162    }
163
164    /**
165     * Return value of the field for the attributeName currently set on this reader
166     * @param <X> return type
167     * @return value of the field for the attributeName currently set on this reader
168     * @throws AttributeValidationException
169     */
170    @Override
171    public <X> X getValue() throws AttributeValidationException {
172        X fieldValue = null;
173        if(StringUtils.isNotBlank(this.attributeName)){
174            fieldValue = ObjectPropertyUtils.<X>getPropertyValue(form, this.attributeName);
175        }
176        return fieldValue;
177    }
178
179    /**
180     * Return value of the field for the attributeName passed in
181     * @param attributeName name (which represents a path) of the value to be retrieved on the Form
182     * @param <X> return type
183     * @return value of that attributeName represents on the form
184     * @throws AttributeValidationException
185     */
186    @Override
187    public <X> X getValue(String attributeName) throws AttributeValidationException {
188        X fieldValue = null;
189        if(StringUtils.isNotBlank(attributeName)){
190            fieldValue = ObjectPropertyUtils.<X>getPropertyValue(form, this.attributeName);
191        }
192        return fieldValue;
193    }
194
195    /**
196     * Cones this AttributeValueReader
197     * @return AttributeValueReader
198     */
199    @Override
200    public AttributeValueReader clone(){
201        ViewAttributeValueReader clone = new ViewAttributeValueReader(view, form);
202        clone.setAttributeName(this.attributeName);
203        return clone;
204    }
205    
206}