001/*
002 * Copyright 2008 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.ole.sys.document.validation.impl;
017
018import java.util.ArrayList;
019import java.util.List;
020
021import org.apache.commons.lang.StringUtils;
022import org.kuali.ole.sys.businessobject.AccountingLine;
023import org.kuali.ole.sys.document.AccountingDocument;
024import org.kuali.ole.sys.document.validation.Validation;
025import org.kuali.ole.sys.document.validation.event.AttributedDocumentEvent;
026import org.kuali.rice.krad.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 */
034public 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.ole.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.ole.sys.document.validation.Validation#stageValidation(org.kuali.ole.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.ole.sys.document.validation.Validation#validate(org.kuali.ole.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}