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.gl;
017    
018    import java.util.Collection;
019    import java.util.Iterator;
020    import java.util.LinkedHashMap;
021    import java.util.Map;
022    
023    import org.apache.commons.beanutils.DynaClass;
024    import org.apache.commons.beanutils.DynaProperty;
025    import org.apache.commons.beanutils.PropertyUtils;
026    import org.apache.commons.beanutils.WrapDynaClass;
027    import org.apache.commons.lang.StringUtils;
028    import org.apache.ojb.broker.query.Criteria;
029    import org.apache.ojb.broker.query.Query;
030    import org.kuali.kfs.sys.KFSConstants;
031    import org.kuali.kfs.sys.context.SpringContext;
032    import org.kuali.kfs.sys.service.impl.KfsParameterConstants;
033    import org.kuali.rice.kns.dao.LookupDao;
034    import org.kuali.rice.kns.datadictionary.BusinessObjectEntry;
035    import org.kuali.rice.kns.datadictionary.FieldDefinition;
036    import org.kuali.rice.kns.service.DataDictionaryService;
037    import org.kuali.rice.kns.service.ParameterService;
038    
039    /**
040     * This class provides a set of utilities that can handle common tasks related to business objects.
041     */
042    public class OJBUtility {
043        private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OJBUtility.class);
044    
045        public static final String LOOKUP_DAO = "lookupDao";
046    
047        /**
048         * This method builds a map of business object with its property names and values
049         * 
050         * @param businessObject the given business object
051         * @return the map of business object with its property names and values
052         */
053        public static LinkedHashMap buildPropertyMap(Object businessObject) {
054            DynaClass dynaClass = WrapDynaClass.createDynaClass(businessObject.getClass());
055            DynaProperty[] properties = dynaClass.getDynaProperties();
056            LinkedHashMap propertyMap = new LinkedHashMap();
057    
058            try {
059                for (int numOfProperty = 0; numOfProperty < properties.length; numOfProperty++) {
060                    String propertyName = properties[numOfProperty].getName();
061                    if (PropertyUtils.isWriteable(businessObject, propertyName)) {
062                        Object propertyValue = PropertyUtils.getProperty(businessObject, propertyName);
063                        propertyMap.put(propertyName, propertyValue);
064                    }
065                }
066            }
067            catch (Exception e) {
068                LOG.error("OJBUtility.buildPropertyMap()" + e);
069            }
070            return propertyMap;
071        }
072    
073        /**
074         * This method builds an OJB query criteria based on the input field map
075         * 
076         * @param fieldValues the input field map
077         * @param businessObject the given business object
078         * @return an OJB query criteria
079         */
080        public static Criteria buildCriteriaFromMap(Map fieldValues, Object businessObject) {
081    
082            Criteria criteria = new Criteria();
083            BusinessObjectEntry entry = SpringContext.getBean(DataDictionaryService.class).getDataDictionary().getBusinessObjectEntry(businessObject.getClass().getName());
084            //FieldDefinition lookupField = entry.getLookupDefinition().getLookupField(attributeName);
085            //System.out.println(entry.getTitleAttribute());
086            try {
087                Iterator propsIter = fieldValues.keySet().iterator();
088                while (propsIter.hasNext()) {
089                    String propertyName = (String) propsIter.next();
090                    Object propertyValueObject = fieldValues.get(propertyName);
091                    String propertyValue = "";
092                      
093                    FieldDefinition lookupField = (entry != null) ? entry.getLookupDefinition().getLookupField(propertyName) : null;
094                    if (lookupField != null && lookupField.isTreatWildcardsAndOperatorsAsLiteral()) {
095                        propertyValue = (propertyValueObject != null) ? StringUtils.replace(propertyValueObject.toString().trim(), "*", "\\*") : "";
096                    } else {
097                        //propertyValue = (propertyValueObject != null) ? propertyValueObject.toString().trim() : "";
098                        propertyValue = (propertyValueObject != null) ? StringUtils.replace(propertyValueObject.toString().trim(), "*", "%") : "";
099                    }
100    
101                    // if searchValue is empty and the key is not a valid property ignore
102                    boolean isCreated = createCriteria(businessObject, propertyValue, propertyName, criteria);
103                    if (!isCreated) {
104                        continue;
105                    }
106                }
107            }
108            catch (Exception e) {
109                LOG.error("OJBUtility.buildCriteriaFromMap()" + e);
110            }
111            return criteria;
112        }
113    
114        /**
115         * Limit the size of the result set from the given query operation
116         * 
117         * @param query the given query operation
118         */
119        public static void limitResultSize(Query query) {
120            int startingIndex = 1;
121            int endingIndex = getResultLimit().intValue();
122    
123            query.setStartAtIndex(startingIndex);
124            query.setEndAtIndex(endingIndex);
125        }
126    
127        /**
128         * This method calculates the actual size of given selection results
129         * 
130         * @param result the given selection results
131         * @param recordCount the possible number of the given results
132         * @param fieldValues the input field map
133         * @param businessObject the given business object
134         * @return the actual size of given selection results
135         */
136        public static Long getResultActualSize(Collection result, Integer recordCount, Map fieldValues, Object businessObject) {
137            int resultSize = result.size();
138            Integer limit = getResultLimit();
139            Long resultActualSize = new Long(resultSize);
140    
141            if (recordCount > limit) {
142                long actualCount = recordCount.longValue() + resultSize - limit.longValue();
143                resultActualSize = new Long(actualCount);
144            }
145            return resultActualSize;
146        }
147    
148        /**
149         * This method gets the size of a result set from the given search criteria
150         * 
151         * @param fieldValues the input field map
152         * @param businessObject the given business object
153         * @return the size of a result set from the given search criteria
154         */
155        public static Long getResultSizeFromMap(Map fieldValues, Object businessObject) {
156            LookupDao lookupDao = SpringContext.getBean(LookupDao.class);
157            return lookupDao.findCountByMap(businessObject, fieldValues);
158        }
159    
160        /**
161         * This method gets the limit of the selection results
162         * 
163         * @return the limit of the selection results
164         */
165        public static Integer getResultLimit() {
166            // get the result limit number from configuration
167            String limitConfig = SpringContext.getBean(ParameterService.class).getParameterValue(KfsParameterConstants.NERVOUS_SYSTEM_LOOKUP.class, KFSConstants.LOOKUP_RESULTS_LIMIT_URL_KEY);
168    
169            Integer limit = Integer.MAX_VALUE;
170            if (limitConfig != null) {
171                limit = Integer.valueOf(limitConfig);
172            }
173            return limit;
174        }
175    
176        /**
177         * This method build OJB criteria from the given property value and name
178         */
179        public static boolean createCriteria(Object businessObject, String propertyValue, String propertyName, Criteria criteria) {
180            LookupDao lookupDao = SpringContext.getBean(LookupDao.class);
181            return lookupDao.createCriteria(businessObject, propertyValue, propertyName, criteria);
182        }
183    }