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.lang.reflect.InvocationTargetException;
019    import java.lang.reflect.Method;
020    import java.util.List;
021    
022    import org.kuali.kfs.sys.document.AccountingDocument;
023    import org.kuali.kfs.sys.document.validation.GenericValidation;
024    import org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent;
025    import org.kuali.rice.kns.util.GlobalVariables;
026    import org.kuali.rice.kns.util.ObjectUtils;
027    
028    /**
029     * GenericValidation to check if the required number of accounting lines in a given accounting line group has been met
030     */
031    public class RequiredAccountingLinesCountValidation extends GenericValidation {
032        private String accountingLineGroupName;
033        private int minimumNumber;
034        protected String accountingLineGroupPropertyName;
035        protected String errorMessageName;
036        private AccountingDocument accountingDocumentForValidation;
037        
038        private static final String ACCOUNTING_LINES_GROUP_PROPERTY_SUFFIX = "AccountingLines";
039    
040        /**
041         * Checks that the number of accounting lines in the accounting line group (named by the accountingLineGroupPropertyName property)
042         * is greater than the set minimum number of accounting lines.
043         * <strong>This validation expects the document to be sent in as a property.</strong>
044         * @see org.kuali.kfs.sys.document.validation.GenericValidation#validate(java.lang.Object[])
045         */
046        public boolean validate(AttributedDocumentEvent event) {
047            List accountingLineGroup = (List)ObjectUtils.getPropertyValue(accountingDocumentForValidation, accountingLineGroupPropertyName);
048            if (accountingLineGroup.size() < minimumNumber) {
049                GlobalVariables.getMessageMap().putError(accountingLineGroupPropertyName, errorMessageName, new String[] { discoverGroupTitle(accountingDocumentForValidation) });
050                return false;
051            }
052            return true;
053        }
054        
055        /**
056         * Returns the title of the given accounting line group on the document
057         * @return an accounting line group title
058         */
059        protected String discoverGroupTitle(AccountingDocument document) {
060            String title = accountingLineGroupName;
061            Method groupTitleMethod = discoverGroupTitleMethod(document);
062            if (groupTitleMethod != null) {
063                try {
064                    title = (String)groupTitleMethod.invoke(document, new Object[0]);
065                }
066                catch (IllegalAccessException iae) {
067                    throw new RuntimeException(iae);
068                }
069                catch (InvocationTargetException ite) {
070                    throw new RuntimeException(ite);
071                }
072            }
073            return title;
074        }
075        
076        /**
077         * Looks up what should be the method on the AccountingDocument class that returns the group title
078         * @return
079         */
080        protected Method discoverGroupTitleMethod(AccountingDocument document) {
081            Method groupTitleMethod = null;
082            try {
083                String methodName = new StringBuilder().append("get").append(accountingLineGroupPropertyName.substring(0, 1).toUpperCase()).append(accountingLineGroupPropertyName.substring(1)).append("SectionTitle").toString();
084                groupTitleMethod = document.getClass().getMethod(methodName, new Class[0]);
085            }
086            catch (SecurityException se) {
087                throw new RuntimeException(se);
088            }
089            catch (NoSuchMethodException nsme) {
090                throw new RuntimeException(nsme);
091            }
092            
093            return groupTitleMethod;
094        }
095        
096        /**
097         * Gets the accountingLineGroupName attribute. 
098         * @return Returns the accountingLineGroupName.
099         */
100        public String getAccountingLineGroupName() {
101            return accountingLineGroupName;
102        }
103    
104        /**
105         * Sets the accountingLineGroupName attribute value.
106         * @param accountingLineGroupName The accountingLineGroupName to set.
107         */
108        public void setAccountingLineGroupName(String accountingLineGroupName) {
109            this.accountingLineGroupName = accountingLineGroupName;
110            this.accountingLineGroupPropertyName = new StringBuilder().append(this.accountingLineGroupName).append(RequiredAccountingLinesCountValidation.ACCOUNTING_LINES_GROUP_PROPERTY_SUFFIX).toString();
111            this.errorMessageName = new StringBuilder().append("error.document.").append(accountingLineGroupName).append("SectionNoAccountingLines").toString();
112        }
113    
114        /**
115         * Gets the minimumNumber attribute. 
116         * @return Returns the minimumNumber.
117         */
118        public int getMinimumNumber() {
119            return minimumNumber;
120        }
121    
122        /**
123         * Sets the minimumNumber attribute value.
124         * @param minimumNumber The minimumNumber to set.
125         */
126        public void setMinimumNumber(int minimumNumber) {
127            this.minimumNumber = minimumNumber;
128        }
129    
130        /**
131         * Gets the accountingDocumentForValidation attribute. 
132         * @return Returns the accountingDocumentForValidation.
133         */
134        public AccountingDocument getAccountingDocumentForValidation() {
135            return accountingDocumentForValidation;
136        }
137    
138        /**
139         * Sets the accountingDocumentForValidation attribute value.
140         * @param accountingDocumentForValidation The accountingDocumentForValidation to set.
141         */
142        public void setAccountingDocumentForValidation(AccountingDocument accountingDocumentForValidation) {
143            this.accountingDocumentForValidation = accountingDocumentForValidation;
144        }
145    }