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 */ 016package org.kuali.rice.krad.service.impl; 017 018import org.apache.commons.lang.StringUtils; 019import org.kuali.rice.krad.datadictionary.state.StateMapping; 020import org.kuali.rice.krad.datadictionary.validation.ViewAttributeValueReader; 021import org.kuali.rice.krad.datadictionary.validation.result.DictionaryValidationResult; 022import org.kuali.rice.krad.service.DictionaryValidationService; 023import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 024import org.kuali.rice.krad.service.ViewValidationService; 025import org.kuali.rice.krad.uif.UifConstants; 026import org.kuali.rice.krad.uif.util.ObjectPropertyUtils; 027import org.kuali.rice.krad.uif.view.View; 028import org.kuali.rice.krad.uif.view.ViewModel; 029import org.kuali.rice.krad.util.GlobalVariables; 030 031/** 032 * Implementation of Validation service for views, uses the same validation mechanisms as DictionaryValidationService 033 * but uses a different AttributeValueReader to get the correct information from InputFields - which 034 * include any AttributeDefinition defined attributes, if defined and not overriden 035 * 036 * @see ViewValidationService 037 */ 038public class ViewValidationServiceImpl implements ViewValidationService { 039 040 protected DictionaryValidationService dictionaryValidationService; 041 042 /** 043 * @see ViewValidationService#validateView(org.kuali.rice.krad.uif.view.ViewModel) 044 */ 045 @Override 046 public DictionaryValidationResult validateView(ViewModel model) { 047 return validateView(model, null); 048 } 049 050 /** 051 * @see ViewValidationService#validateViewSimulation(ViewModel) 052 */ 053 @Override 054 public void validateViewSimulation(ViewModel model) { 055 validateViewSimulation(model, null); 056 } 057 058 /** 059 * @see ViewValidationService#validateViewSimulation(ViewModel, String) 060 */ 061 @Override 062 public void validateViewSimulation(ViewModel model, String untilState) { 063 // Get state mapping for view from post data 064 Object stateMappingObject = model.getViewPostMetadata().getComponentPostData( 065 model.getViewPostMetadata().getId(), UifConstants.PostMetadata.STATE_MAPPING); 066 067 StateMapping stateMapping = null; 068 if (stateMappingObject != null) { 069 stateMapping = (StateMapping) stateMappingObject; 070 } 071 072 // Get state object path from post data 073 Object statePathObject = model.getViewPostMetadata().getComponentPostData( 074 model.getViewPostMetadata().getId(), UifConstants.PostMetadata.STATE_OBJECT_BINDING_PATH); 075 076 String path = null; 077 if (statePathObject != null) { 078 path = (String) statePathObject; 079 } 080 081 Object object; 082 if (StringUtils.isNotBlank(path)) { 083 object = ObjectPropertyUtils.getPropertyValue(model, path); 084 } else { 085 object = model; 086 } 087 088 if (stateMapping != null && !stateMapping.getStates().isEmpty()) { 089 int startIndex = stateMapping.getStates().indexOf(stateMapping.getNextState(object)); 090 if (startIndex == -1) { 091 //Assume checking against all states that exist 092 startIndex = 0; 093 } 094 095 for (int i = startIndex; i < stateMapping.getStates().size(); i++) { 096 String state = stateMapping.getStates().get(i); 097 098 validateView(model, state); 099 GlobalVariables.getMessageMap().merge(GlobalVariables.getMessageMap().getErrorMessages(), 100 GlobalVariables.getMessageMap().getWarningMessages()); 101 GlobalVariables.getMessageMap().clearErrorMessages(); 102 103 if (untilState != null && untilState.equals(state)) { 104 break; 105 } 106 } 107 validateView(model, stateMapping.getCurrentState(object)); 108 } else { 109 validateView(model, null); 110 } 111 112 } 113 114 /** 115 * @see ViewValidationService#validateView(ViewModel, String) 116 */ 117 @Override 118 public DictionaryValidationResult validateView(ViewModel model, String forcedValidationState) { 119 // Get state object path from post data 120 Object statePathObject = model.getViewPostMetadata().getComponentPostData(model.getViewPostMetadata().getId(), 121 UifConstants.PostMetadata.STATE_OBJECT_BINDING_PATH); 122 123 String path = null; 124 if (statePathObject != null) { 125 path = (String) statePathObject; 126 } 127 128 Object object; 129 130 if (StringUtils.isNotBlank(path)) { 131 object = ObjectPropertyUtils.getPropertyValue(model, path); 132 } else { 133 object = model; 134 } 135 136 String validationState = null; 137 138 // Get state mapping for view from post data 139 Object stateMappingObject = model.getViewPostMetadata().getComponentPostData( 140 model.getViewPostMetadata().getId(), UifConstants.PostMetadata.STATE_MAPPING); 141 142 StateMapping stateMapping = null; 143 if (stateMappingObject != null) { 144 stateMapping = (StateMapping) stateMappingObject; 145 } 146 147 if (StringUtils.isNotBlank(forcedValidationState)) { 148 //use forced selected state if passed in 149 validationState = forcedValidationState; 150 } else if (stateMapping != null) { 151 //default is current state 152 validationState = stateMapping.getCurrentState(object); 153 154 } 155 156 return getDictionaryValidationService().validate(new ViewAttributeValueReader(model), true, 157 validationState, stateMapping); 158 } 159 160 /** 161 * @see ViewValidationService#validateViewAgainstNextState(ViewModel) 162 */ 163 @Override 164 public DictionaryValidationResult validateViewAgainstNextState(ViewModel model) { 165 // Get state object path from post data 166 Object statePathObject = model.getViewPostMetadata().getComponentPostData(model.getViewPostMetadata().getId(), 167 UifConstants.PostMetadata.STATE_OBJECT_BINDING_PATH); 168 169 String path = null; 170 if (statePathObject != null) { 171 path = (String) statePathObject; 172 } 173 174 Object object; 175 176 if (StringUtils.isNotBlank(path)) { 177 object = ObjectPropertyUtils.getPropertyValue(model, path); 178 } else { 179 object = model; 180 } 181 182 String validationState = null; 183 184 // Get state mapping for view from post data 185 Object stateMappingObject = model.getViewPostMetadata().getComponentPostData( 186 model.getViewPostMetadata().getId(), UifConstants.PostMetadata.STATE_MAPPING); 187 188 StateMapping stateMapping = null; 189 if (stateMappingObject != null) { 190 stateMapping = (StateMapping) stateMappingObject; 191 } 192 193 if (stateMapping != null) { 194 //validation state is the next state for this call 195 validationState = stateMapping.getNextState(object); 196 } 197 return getDictionaryValidationService().validate(new ViewAttributeValueReader(model), true, 198 validationState, stateMapping); 199 } 200 201 /** 202 * Gets the DictionaryValidationService to use for View validation 203 * 204 * @return DictionaryValidationService 205 */ 206 public DictionaryValidationService getDictionaryValidationService() { 207 if (dictionaryValidationService == null) { 208 this.dictionaryValidationService = KRADServiceLocatorWeb.getDictionaryValidationService(); 209 } 210 return dictionaryValidationService; 211 } 212 213 /** 214 * Set the DictionaryValidationService 215 * 216 * @param dictionaryValidationService 217 */ 218 public void setDictionaryValidationService(DictionaryValidationService dictionaryValidationService) { 219 this.dictionaryValidationService = dictionaryValidationService; 220 } 221}