View Javadoc

1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krad.service.impl;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.kuali.rice.core.api.datetime.DateTimeService;
20  import org.kuali.rice.krad.bo.BusinessObject;
21  import org.kuali.rice.krad.bo.InactivatableFromTo;
22  import org.kuali.rice.krad.service.DataDictionaryService;
23  import org.kuali.rice.krad.service.InactivateableFromToService;
24  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
25  import org.kuali.rice.krad.service.LookupService;
26  import org.kuali.rice.krad.util.BeanPropertyComparator;
27  import org.kuali.rice.krad.util.KRADPropertyConstants;
28  import org.kuali.rice.krad.util.ObjectUtils;
29  
30  import java.util.ArrayList;
31  import java.util.Collections;
32  import java.util.Date;
33  import java.util.List;
34  import java.util.Map;
35  
36  /**
37   * Implementation of InactivateableFromToService that uses the lookup service for query implementation
38   * 
39   * @see org.kuali.rice.krad.service.InactivateableFromToService
40   */
41  public class InactivateableFromToServiceImpl implements InactivateableFromToService {
42  
43  	protected DateTimeService dateTimeService;
44  	protected LookupService lookupService;
45      protected DataDictionaryService dataDictionaryService;
46  
47  	/**
48  	 * Uses lookup service which will convert the active criteria to active begin/to field criteria
49  	 * 
50  	 * @see org.kuali.rice.krad.service.InactivateableFromToService#findMatchingActive(java.lang.Class, java.util.Map)
51  	 */
52  	public List<InactivatableFromTo> findMatchingActive(Class<? extends InactivatableFromTo> clazz, Map fieldValues) {
53  		fieldValues.put(KRADPropertyConstants.ACTIVE, "true");
54  
55  		return (List<InactivatableFromTo>) lookupService.findCollectionBySearchUnbounded(clazz, fieldValues);
56  	}
57  
58  	/**
59  	 * Uses lookup service which will convert the active criteria to active begin/to field criteria
60  	 * 
61  	 * @see org.kuali.rice.krad.service.InactivateableFromToService#findMatchingActiveAsOfDate(java.lang.Class, java.util.Map,
62  	 *      java.util.Date)
63  	 */
64  	public List<InactivatableFromTo> findMatchingActiveAsOfDate(Class<? extends InactivatableFromTo> clazz,
65  			Map fieldValues, Date activeAsOfDate) {
66  		fieldValues.put(KRADPropertyConstants.ACTIVE, "true");
67  		fieldValues.put(KRADPropertyConstants.ACTIVE_AS_OF_DATE, dateTimeService.toDateString(activeAsOfDate));
68  
69  		return (List<InactivatableFromTo>) lookupService.findCollectionBySearchUnbounded(clazz, fieldValues);
70  	}
71  
72  	/**
73  	 * @see org.kuali.rice.krad.service.InactivateableFromToService#filterOutNonActive(java.util.List)
74  	 */
75  	public List<InactivatableFromTo> filterOutNonActive(List<InactivatableFromTo> filterList) {
76  		return filterOutNonActive(filterList, dateTimeService.getCurrentDate());
77  	}
78  
79  	/**
80  	 * @see org.kuali.rice.krad.service.InactivateableFromToService#filterOutNonActive(java.util.List, java.util.Date)
81  	 */
82  	public List<InactivatableFromTo> filterOutNonActive(List<InactivatableFromTo> filterList, Date activeAsOfDate) {
83  		List<InactivatableFromTo> filteredList = new ArrayList<InactivatableFromTo>();
84  
85  		for (InactivatableFromTo inactivateable : filterList) {
86  			inactivateable.setActiveAsOfDate(new java.sql.Timestamp(activeAsOfDate.getTime()));
87  			if (inactivateable.isActive()) {
88  				filteredList.add(inactivateable);
89  			}
90  		}
91  
92  		return filteredList;
93  	}
94  
95  	/**
96  	 * Uses lookup service which will convert the active and current criteria to active begin/to field criteria
97  	 * 
98  	 * @see org.kuali.rice.krad.service.InactivateableFromToService#findMatchingCurrent(java.lang.Class, java.util.Map)
99  	 */
100 	public List<InactivatableFromTo> findMatchingCurrent(Class<? extends InactivatableFromTo> clazz,
101 			Map fieldValues) {
102 		fieldValues.put(KRADPropertyConstants.ACTIVE, "true");
103 		fieldValues.put(KRADPropertyConstants.CURRENT, "true");
104 
105 		return (List<InactivatableFromTo>) lookupService.findCollectionBySearchUnbounded(clazz, fieldValues);
106 	}
107 
108 	/**
109 	 * Uses lookup service which will convert the active and current criteria to active begin/to field criteria
110 	 * 
111 	 * @see org.kuali.rice.krad.service.InactivateableFromToService#findMatchingCurrent(java.lang.Class, java.util.Map, java.util.Date)
112 	 */
113 	public List<InactivatableFromTo> findMatchingCurrent(Class<? extends InactivatableFromTo> clazz,
114 			Map fieldValues, Date currentAsOfDate) {
115 		fieldValues.put(KRADPropertyConstants.ACTIVE, "true");
116 		fieldValues.put(KRADPropertyConstants.CURRENT, "true");
117 		fieldValues.put(KRADPropertyConstants.ACTIVE_AS_OF_DATE, dateTimeService.toDateString(currentAsOfDate));
118 
119 		return (List<InactivatableFromTo>) lookupService.findCollectionBySearchUnbounded(clazz, fieldValues);
120 	}
121 
122 	/**
123 	 * @see org.kuali.rice.krad.service.InactivateableFromToService#filterOutNonCurrent(java.util.List)
124 	 */
125 	public List<InactivatableFromTo> filterOutNonCurrent(List<InactivatableFromTo> filterList) {
126 		return filterOutNonCurrent(filterList, dateTimeService.getCurrentDate());
127 	}
128 
129 	/**
130 	 * @see org.kuali.rice.krad.service.InactivateableFromToService#filterOutNonCurrent(java.util.List, java.util.Date)
131 	 */
132 	public List<InactivatableFromTo> filterOutNonCurrent(List<InactivatableFromTo> filterList, Date currentAsOfDate) {
133 		List<InactivatableFromTo> activeList = filterOutNonActive(filterList, currentAsOfDate);
134 
135 		if (activeList.isEmpty()) {
136 			return activeList;
137 		}
138 
139 		List<InactivatableFromTo> currentList = new ArrayList<InactivatableFromTo>();
140 
141 		List<String> groupByList = getDataDictionaryService().getGroupByAttributesForEffectiveDating(
142                 activeList.get(0).getClass());
143 		if (groupByList != null) {
144 			List<String> sortByList = new ArrayList<String>(groupByList);
145 			sortByList.add(KRADPropertyConstants.ACTIVE_FROM_DATE);
146 
147 			// sort list so we get records together with same group by
148 			Collections.sort(activeList, new BeanPropertyComparator(sortByList, true));
149 
150 			// reverse so we get max active begin date first within the group by
151 			Collections.reverse(activeList);
152 
153 			String previousGroupByString = "";
154 			Date previousActiveFromDate = null;
155 			for (InactivatableFromTo inactivateable : activeList) {
156 				String groupByString = buildGroupByValueString((BusinessObject) inactivateable, groupByList);
157 				if (!StringUtils.equals(groupByString, previousGroupByString)) {
158 					// always add first record of new group by since list is sorted by active begin date descending
159 					currentList.add(inactivateable);
160 				}
161 				// active from date should not be null here since we are dealing with only active records
162 				else if (inactivateable.getActiveFromDate().equals(previousActiveFromDate)) {
163 					// have more than one record for the group by key with same active begin date, so they both are current
164 					currentList.add(inactivateable);
165 				}
166 
167 				previousGroupByString = groupByString;
168 				previousActiveFromDate = inactivateable.getActiveFromDate();
169 			}
170 		} else {
171 			currentList = activeList;
172 		}
173 
174 		return currentList;
175 	}
176 
177 	/**
178 	 * Builds a string containing the values from the given business object for the fields in the given list, concatenated together using a
179 	 * bar. Null values are treated as an empty string
180 	 * 
181 	 * @param businessObject
182 	 *            - business object instance to get values from
183 	 * @param groupByList
184 	 *            - list of fields to get values for
185 	 * @return String
186 	 */
187 	protected String buildGroupByValueString(BusinessObject businessObject, List<String> groupByList) {
188 		String groupByValueString = "";
189 
190 		for (String groupByField : groupByList) {
191 			Object fieldValue = ObjectUtils.getPropertyValue(businessObject, groupByField);
192 			groupByValueString += "|";
193 			if (fieldValue != null) {
194 				groupByValueString += fieldValue;
195 			}
196 		}
197 
198 		return groupByValueString;
199 	}
200 
201 	public void setDateTimeService(DateTimeService dateTimeService) {
202 		this.dateTimeService = dateTimeService;
203 	}
204 
205 	public void setLookupService(LookupService lookupService) {
206 		this.lookupService = lookupService;
207 	}
208 
209     protected DataDictionaryService getDataDictionaryService() {
210         if (dataDictionaryService == null) {
211             this.dataDictionaryService = KRADServiceLocatorWeb.getDataDictionaryService();
212         }
213         return dataDictionaryService;
214     }
215 
216     public void setDataDictionaryService(DataDictionaryService dataDictionaryService) {
217         this.dataDictionaryService = dataDictionaryService;
218     }
219 }