001    /*
002     * Copyright 2011 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.kfs.sys.document.validation.impl;
017    
018    import java.util.ArrayList;
019    import java.util.List;
020    
021    import org.apache.commons.lang.StringUtils;
022    import org.kuali.kfs.sys.businessobject.AccountingLine;
023    import org.kuali.kfs.sys.document.AccountingDocument;
024    import org.kuali.kfs.sys.document.validation.Validation;
025    import org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent;
026    import org.kuali.rice.kns.util.ObjectUtils;
027    
028    /**
029     * A cleaner way to conglomerate closely related rules together, this validation checks that
030     * all of the values on the accounting line are allowed by a given document.  The advantage of this hutch
031     * over normal composites is that the hutch has "named slots" for given validations, which makes it a bit easier to keep track
032     * of everything.
033     */
034    public class AccountingLineValuesAllowedValidationHutch implements Validation {
035        protected Validation objectCodeAllowedValidation;
036        protected Validation objectTypeAllowedValidation;
037        protected Validation fundGroupAllowedValidation;
038        protected Validation subFundGroupAllowedValidation;
039        protected Validation objectSubTypeAllowedValidation;
040        protected Validation objectLevelAllowedValidation;
041        protected Validation objectConsolidationAllowedValidation;
042        
043        protected String accountingDocumentParameterPropertyName;
044        protected String accountingLineParameterPropertyName;
045        protected AccountingDocument accountingDocumentForValidation;
046        protected AccountingLine accountingLineForValidation;
047        
048        protected boolean quitOnFail;
049        
050        /**
051         * @see org.kuali.kfs.sys.document.validation.Validation#shouldQuitOnFail()
052         */
053        public boolean shouldQuitOnFail() {
054            return quitOnFail;
055        }
056        
057        /**
058         * Sets whether the validation hutch should quit on the failure of the entire validation case failing.
059         * @param b
060         */
061        public void setQuitOnFail(boolean b) {
062            quitOnFail = b;
063        }
064    
065        /**
066         * @see org.kuali.kfs.sys.document.validation.Validation#stageValidation(org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent)
067         */
068        public boolean stageValidation(AttributedDocumentEvent event) {
069            grabDocumentAndLineForValidationFromEvent(event);
070            updateValidationsWithParameters();
071            return validate(event);
072        }
073        
074        /**
075         * Returns a list of all the validations the hutch has to pass in order to pass as a whole.
076         * @return a List of Validations
077         */
078        protected List<Validation> getValidationGauntlet() {
079            List<Validation> gauntlet = new ArrayList<Validation>();
080            if (objectCodeAllowedValidation != null) {
081                gauntlet.add(objectCodeAllowedValidation);
082            }
083            if (objectTypeAllowedValidation != null) {
084                gauntlet.add(objectTypeAllowedValidation);
085            }
086            if (fundGroupAllowedValidation != null) {
087                gauntlet.add(fundGroupAllowedValidation);
088            }
089            if (subFundGroupAllowedValidation != null) {
090                gauntlet.add(subFundGroupAllowedValidation);
091            }
092            if (objectSubTypeAllowedValidation != null) {
093                gauntlet.add(objectSubTypeAllowedValidation);
094            }
095            if (objectLevelAllowedValidation != null) {
096                gauntlet.add(objectLevelAllowedValidation);
097            }
098            if (objectConsolidationAllowedValidation != null) {
099                gauntlet.add(objectConsolidationAllowedValidation);
100            }
101            return gauntlet;
102        }
103        
104        /**
105         * Using the parameter property names set, finds the accounting document and accounting line to be validate
106         * from the property, like an anteater getting tasty termites from a hill.  Yummy.
107         * @param event the event to take properties from
108         */
109        protected void grabDocumentAndLineForValidationFromEvent(AttributedDocumentEvent event) {
110            if (StringUtils.isNotBlank(accountingDocumentParameterPropertyName)) {
111                accountingDocumentForValidation = (AccountingDocument)ObjectUtils.getPropertyValue(event, accountingDocumentParameterPropertyName);
112            }
113            if (StringUtils.isNotBlank(accountingLineParameterPropertyName)) {
114                accountingLineForValidation = (AccountingLine)ObjectUtils.getPropertyValue(event, accountingLineParameterPropertyName);
115            }
116        }
117        
118        /**
119         * Goes through each of the validations in the hutch, making sure each has the accounting document and accounting line to validate
120         */
121        protected void updateValidationsWithParameters() { 
122            for (Validation v: getValidationGauntlet()) {
123                if (v instanceof AccountingLineValueAllowedValidation) {
124                    addParametersToValidation((AccountingLineValueAllowedValidation)v);
125                } else if (v instanceof CompositeValidation) {
126                    addParametersToValidation((CompositeValidation)v);
127                } else {
128                    throw new IllegalStateException("Validations in the AccountingLineValuesAllowedValidationHutch must either extend AccountingLineValueAllowedValidation or be a CompositeValidation made up of AccountingLineValueAllowedValidation instances");
129                }
130            }
131        }
132        
133        /**
134         * Adds the parameter properties to an instance of the AccountingLinevAlueAllowedValidation
135         * @param validation the validation to add the correct properties to
136         */
137        protected void addParametersToValidation(AccountingLineValueAllowedValidation validation) {
138            validation.setAccountingDocumentForValidation(accountingDocumentForValidation);
139            validation.setAccountingLineForValidation(accountingLineForValidation);
140        }
141        
142        /**
143         * Adds the parameter properties to the children validations of a CompositeValidation
144         * @param validation the validation to add the correct parameters to
145         */
146        protected void addParametersToValidation(CompositeValidation validation) {
147            for (Validation val : validation.getValidations()) {
148                if (val instanceof CompositeValidation) {
149                    addParametersToValidation((CompositeValidation)val);
150                } else if (val instanceof AccountingLineValueAllowedValidation) {
151                    addParametersToValidation((AccountingLineValueAllowedValidation)val);
152                } else {
153                    throw new IllegalStateException("Validations in the AccountingLineValuesAllowedValidationHutch must either extend AccountingLineValueAllowedValidation or be a CompositeValidation made up of AccountingLineValueAllowedValidation instances");
154                }
155            }
156        }
157    
158        /**
159         * 
160         * @see org.kuali.kfs.sys.document.validation.Validation#validate(org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent)
161         */
162        public boolean validate(AttributedDocumentEvent event) {
163            boolean result = true;
164            for (Validation validation : getValidationGauntlet()) {
165                result &= validation.validate(event);
166            }
167            return result;
168        }
169    
170        /**
171         * Gets the fundGroupAllowedValidation attribute. 
172         * @return Returns the fundGroupAllowedValidation.
173         */
174        public Validation getFundGroupAllowedValidation() {
175            return fundGroupAllowedValidation;
176        }
177    
178        /**
179         * Sets the fundGroupAllowedValidation attribute value.
180         * @param fundGroupAllowedValidation The fundGroupAllowedValidation to set.
181         */
182        public void setFundGroupAllowedValidation(Validation fundGroupAllowedValidation) {
183            this.fundGroupAllowedValidation = fundGroupAllowedValidation;
184        }
185    
186        /**
187         * Gets the objectCodeAllowedValidation attribute. 
188         * @return Returns the objectCodeAllowedValidation.
189         */
190        public Validation getObjectCodeAllowedValidation() {
191            return objectCodeAllowedValidation;
192        }
193    
194        /**
195         * Sets the objectCodeAllowedValidation attribute value.
196         * @param objectCodeAllowedValidation The objectCodeAllowedValidation to set.
197         */
198        public void setObjectCodeAllowedValidation(Validation objectCodeAllowedValidation) {
199            this.objectCodeAllowedValidation = objectCodeAllowedValidation;
200        }
201    
202        /**
203         * Gets the objectConsolidationAllowedValidation attribute. 
204         * @return Returns the objectConsolidationAllowedValidation.
205         */
206        public Validation getObjectConsolidationAllowedValidation() {
207            return objectConsolidationAllowedValidation;
208        }
209    
210        /**
211         * Sets the objectConsolidationAllowedValidation attribute value.
212         * @param objectConsolidationAllowedValidation The objectConsolidationAllowedValidation to set.
213         */
214        public void setObjectConsolidationAllowedValidation(Validation objectConsolidationAllowedValidation) {
215            this.objectConsolidationAllowedValidation = objectConsolidationAllowedValidation;
216        }
217    
218        /**
219         * Gets the objectLevelAllowedValidation attribute. 
220         * @return Returns the objectLevelAllowedValidation.
221         */
222        public Validation getObjectLevelAllowedValidation() {
223            return objectLevelAllowedValidation;
224        }
225    
226        /**
227         * Sets the objectLevelAllowedValidation attribute value.
228         * @param objectLevelAllowedValidation The objectLevelAllowedValidation to set.
229         */
230        public void setObjectLevelAllowedValidation(Validation objectLevelAllowedValidation) {
231            this.objectLevelAllowedValidation = objectLevelAllowedValidation;
232        }
233    
234        /**
235         * Gets the objectSubTypeAllowedValidation attribute. 
236         * @return Returns the objectSubTypeAllowedValidation.
237         */
238        public Validation getObjectSubTypeAllowedValidation() {
239            return objectSubTypeAllowedValidation;
240        }
241    
242        /**
243         * Sets the objectSubTypeAllowedValidation attribute value.
244         * @param objectSubTypeAllowedValidation The objectSubTypeAllowedValidation to set.
245         */
246        public void setObjectSubTypeAllowedValidation(Validation objectSubTypeAllowedValidation) {
247            this.objectSubTypeAllowedValidation = objectSubTypeAllowedValidation;
248        }
249    
250        /**
251         * Gets the objectTypeAllowedValidation attribute. 
252         * @return Returns the objectTypeAllowedValidation.
253         */
254        public Validation getObjectTypeAllowedValidation() {
255            return objectTypeAllowedValidation;
256        }
257    
258        /**
259         * Sets the objectTypeAllowedValidation attribute value.
260         * @param objectTypeAllowedValidation The objectTypeAllowedValidation to set.
261         */
262        public void setObjectTypeAllowedValidation(Validation objectTypeAllowedValidation) {
263            this.objectTypeAllowedValidation = objectTypeAllowedValidation;
264        }
265    
266        /**
267         * Gets the subFundGroupAllowedValidation attribute. 
268         * @return Returns the subFundGroupAllowedValidation.
269         */
270        public Validation getSubFundGroupAllowedValidation() {
271            return subFundGroupAllowedValidation;
272        }
273    
274        /**
275         * Sets the subFundGroupAllowedValidation attribute value.
276         * @param subFundGroupAllowedValidation The subFundGroupAllowedValidation to set.
277         */
278        public void setSubFundGroupAllowedValidation(Validation subFundGroupAllowedValidation) {
279            this.subFundGroupAllowedValidation = subFundGroupAllowedValidation;
280        }
281    
282        /**
283         * Gets the accountingDocumentParameterPropertyName attribute. 
284         * @return Returns the accountingDocumentParameterPropertyName.
285         */
286        public String getAccountingDocumentParameterPropertyName() {
287            return accountingDocumentParameterPropertyName;
288        }
289    
290        /**
291         * Sets the accountingDocumentParameterPropertyName attribute value.
292         * @param accountingDocumentParameterPropertyName The accountingDocumentParameterPropertyName to set.
293         */
294        public void setAccountingDocumentParameterPropertyName(String accountingDocumentParameterPropertyName) {
295            this.accountingDocumentParameterPropertyName = accountingDocumentParameterPropertyName;
296        }
297    
298        /**
299         * Gets the accountingLineParameterPropertyName attribute. 
300         * @return Returns the accountingLineParameterPropertyName.
301         */
302        public String getAccountingLineParameterPropertyName() {
303            return accountingLineParameterPropertyName;
304        }
305    
306        /**
307         * Sets the accountingLineParameterPropertyName attribute value.
308         * @param accountingLineParameterPropertyName The accountingLineParameterPropertyName to set.
309         */
310        public void setAccountingLineParameterPropertyName(String accountingLineParameterPropertyName) {
311            this.accountingLineParameterPropertyName = accountingLineParameterPropertyName;
312        }
313    
314        public void setAccountingDocumentForValidation(AccountingDocument accountingDocumentForValidation) {
315            this.accountingDocumentForValidation = accountingDocumentForValidation;
316        }
317    
318        public void setAccountingLineForValidation(AccountingLine accountingLineForValidation) {
319            this.accountingLineForValidation = accountingLineForValidation;
320        }
321    
322        public AccountingDocument getAccountingDocumentForValidation() {
323            return accountingDocumentForValidation;
324        }
325    
326        public AccountingLine getAccountingLineForValidation() {
327            return accountingLineForValidation;
328        }
329    }