View Javadoc

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