View Javadoc
1   /**
2    * Copyright 2005-2016 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.kns.lookup;
17  
18  import java.sql.Timestamp;
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.HashMap;
22  import java.util.List;
23  import java.util.Map;
24  import java.util.Set;
25  
26  import org.apache.commons.codec.binary.Base64;
27  import org.kuali.rice.core.api.CoreApiServiceLocator;
28  import org.kuali.rice.kns.web.ui.ResultRow;
29  import org.kuali.rice.krad.bo.BusinessObject;
30  import org.kuali.rice.krad.dao.PersistedLookupMetadataDao;
31  import org.kuali.rice.krad.exception.AuthorizationException;
32  import org.kuali.rice.krad.service.BusinessObjectService;
33  import org.kuali.rice.krad.util.KRADConstants;
34  import org.kuali.rice.krad.util.ObjectUtils;
35  
36  /**
37   * @deprecated Only used by KNS classes, use KRAD.
38   */
39  @Deprecated
40  public class LookupResultsServiceImpl implements LookupResultsService {
41      private BusinessObjectService businessObjectService;
42      private PersistedLookupMetadataDao persistedLookupMetadataDao;
43      private LookupResultsSupportStrategyService persistableBusinessObjectSupportStrategy;
44      private LookupResultsSupportStrategyService dataDictionarySupportStrategy;
45      private LookupResultsSupportStrategyService dataObjectBaseSupportStrategy;
46  
47      public LookupResultsServiceImpl() {
48          dataObjectBaseSupportStrategy = new DataObjectBaseLookupResultsSupportStrategyImpl();
49      }
50  
51      /**
52       * @see org.kuali.rice.krad.lookup.LookupResultsService#persistResultsTable(java.lang.String, java.util.List, java.lang.String)
53       */
54      @Override
55      public void persistResultsTable(String lookupResultsSequenceNumber, List<ResultRow> resultTable, String personId) throws Exception {
56          String resultTableString = new String(Base64.encodeBase64(ObjectUtils.toByteArray(resultTable)));
57  
58          Timestamp now = CoreApiServiceLocator.getDateTimeService().getCurrentTimestamp();
59  
60          LookupResults lookupResults = retrieveLookupResults(lookupResultsSequenceNumber);
61          if (lookupResults == null) {
62              lookupResults = new LookupResults();
63              lookupResults.setLookupResultsSequenceNumber(lookupResultsSequenceNumber);
64          }
65          lookupResults.setLookupResultsSequenceNumber(lookupResultsSequenceNumber);
66          lookupResults.setLookupPersonId(personId);
67          lookupResults.setSerializedLookupResults(resultTableString);
68          lookupResults.setLookupDate(now);
69          businessObjectService.save(lookupResults);
70      }
71  
72      /**
73       * @see org.kuali.rice.krad.lookup.LookupResultsService#persistSelectedObjectIds(java.lang.String, java.util.Set, java.lang.String)
74       */
75      @Override
76      public void persistSelectedObjectIds(String lookupResultsSequenceNumber, Set<String> selectedObjectIds, String personId) throws Exception {
77          SelectedObjectIds selectedObjectIdsBO = retrieveSelectedObjectIds(lookupResultsSequenceNumber);
78          if (selectedObjectIdsBO == null) {
79              selectedObjectIdsBO = new SelectedObjectIds();
80              selectedObjectIdsBO.setLookupResultsSequenceNumber(lookupResultsSequenceNumber);
81          }
82          selectedObjectIdsBO.setLookupResultsSequenceNumber(lookupResultsSequenceNumber);
83          selectedObjectIdsBO.setLookupPersonId(personId);
84          selectedObjectIdsBO.setSelectedObjectIds(
85                  LookupUtils.convertSetOfObjectIdsToString(selectedObjectIds));
86          selectedObjectIdsBO.setLookupDate(CoreApiServiceLocator.getDateTimeService().getCurrentTimestamp());
87          businessObjectService.save(selectedObjectIdsBO);
88      }
89  
90      /**
91       * Retrieves the LookupResults BO with the given sequence number.  Does not check authentication.
92       * @param lookupResultsSequenceNumber
93       * @return
94       * @throws Exception
95       */
96      protected LookupResults retrieveLookupResults(String lookupResultsSequenceNumber) throws Exception {
97          Map<String, String> queryCriteria = new HashMap<String, String>();
98          queryCriteria.put(KRADConstants.LOOKUP_RESULTS_SEQUENCE_NUMBER, lookupResultsSequenceNumber);
99          LookupResults lookupResults = businessObjectService.findByPrimaryKey(LookupResults.class, queryCriteria);
100 
101         return lookupResults;
102     }
103 
104     /**
105      * Retrieves the SelectedObjectIds BO with the given sequence number.  Does not check authentication.
106      * @param lookupResultsSequenceNumber
107      * @return
108      * @throws Exception
109      */
110     protected SelectedObjectIds retrieveSelectedObjectIds(String lookupResultsSequenceNumber) throws Exception {
111         Map<String, String> queryCriteria = new HashMap<String, String>();
112         queryCriteria.put(KRADConstants.LOOKUP_RESULTS_SEQUENCE_NUMBER, lookupResultsSequenceNumber);
113         SelectedObjectIds selectedObjectIds = businessObjectService.findByPrimaryKey(SelectedObjectIds.class, queryCriteria);
114 
115         return selectedObjectIds;
116     }
117 
118     /**
119      * @see org.kuali.rice.krad.lookup.LookupResultsService#isAuthorizedToAccessLookupResults(java.lang.String, java.lang.String)
120      */
121     @Override
122     public boolean isAuthorizedToAccessLookupResults(String lookupResultsSequenceNumber, String personId) {
123         try {
124             LookupResults lookupResults = retrieveLookupResults(lookupResultsSequenceNumber);
125             return isAuthorizedToAccessLookupResults(lookupResults, personId);
126         }
127         catch (Exception e) {
128             return false;
129         }
130     }
131 
132     /**
133      * Returns whether the user ID parameter is allowed to view the results.
134      *
135      * @param lookupResults
136      * @param personId
137      * @return
138      */
139     protected boolean isAuthorizedToAccessLookupResults(LookupResults lookupResults, String personId) {
140         return isAuthorizedToAccessMultipleValueLookupMetadata(lookupResults, personId);
141     }
142 
143     /**
144      * @see org.kuali.rice.krad.lookup.LookupResultsService#isAuthorizedToAccessSelectedObjectIds(java.lang.String, java.lang.String)
145      */
146     @Override
147     public boolean isAuthorizedToAccessSelectedObjectIds(String lookupResultsSequenceNumber, String personId) {
148         try {
149             SelectedObjectIds selectedObjectIds = retrieveSelectedObjectIds(lookupResultsSequenceNumber);
150             return isAuthorizedToAccessSelectedObjectIds(selectedObjectIds, personId);
151         }
152         catch (Exception e) {
153             return false;
154         }
155     }
156 
157     /**
158      * Returns whether the user ID parameter is allowed to view the selected object IDs
159      *
160      * @param selectedObjectIds
161      * @param personId
162      * @return
163      */
164     protected boolean isAuthorizedToAccessSelectedObjectIds(SelectedObjectIds selectedObjectIds, String personId) {
165         return isAuthorizedToAccessMultipleValueLookupMetadata(selectedObjectIds, personId);
166     }
167 
168 
169     /**
170      * @see org.kuali.rice.krad.lookup.LookupResultsService#retrieveResultsTable(java.lang.String, java.lang.String)
171      */
172     @Override
173     public List<ResultRow> retrieveResultsTable(String lookupResultsSequenceNumber, String personId) throws Exception {
174         LookupResults lookupResults = retrieveLookupResults(lookupResultsSequenceNumber);
175         if (!isAuthorizedToAccessLookupResults(lookupResults, personId)) {
176             // TODO: use the other identifier
177             throw new AuthorizationException(personId, "retrieve lookup results", "lookup sequence number " + lookupResultsSequenceNumber);
178         }
179         List<ResultRow> resultTable = (List<ResultRow>) ObjectUtils.fromByteArray(Base64.decodeBase64(lookupResults.getSerializedLookupResults().getBytes()));
180         return resultTable;
181     }
182 
183     /**
184      * Figures out which support strategy to defer to and uses that service to retrieve the results; if the bo class doesn't qualify with any support strategy, an exception is thrown.  A nasty one, too.
185      *
186      * @see org.kuali.rice.krad.lookup.LookupResultsService#retrieveSelectedResultBOs(java.lang.String, java.lang.Class, java.lang.String)
187      */
188     @Override
189     public <T extends BusinessObject> Collection<T> retrieveSelectedResultBOs(String lookupResultsSequenceNumber, Class<T> boClass, String personId) throws Exception {
190     	final LookupResultsSupportStrategyService supportService = getQualifingSupportStrategy(boClass);
191     	if (supportService == null) {
192     		throw new RuntimeException("BusinessObject class "+boClass.getName()+" cannot be used within a multiple value lookup; it either needs to be a PersistableBusinessObject or have both its primary keys and a lookupable defined in its data dictionary entry");
193     	}
194 
195     	SelectedObjectIds selectedObjectIds = retrieveSelectedObjectIds(lookupResultsSequenceNumber);
196 
197         if (!isAuthorizedToAccessSelectedObjectIds(selectedObjectIds, personId)) {
198             // TODO: use the other identifier
199             throw new AuthorizationException(personId, "retrieve lookup results", "lookup sequence number " + lookupResultsSequenceNumber);
200         }
201 
202         Set<String> setOfSelectedObjIds = LookupUtils
203                 .convertStringOfObjectIdsToSet(selectedObjectIds.getSelectedObjectIds());
204 
205         if (setOfSelectedObjIds.isEmpty()) {
206             // OJB throws exception if querying on empty set
207             return new ArrayList<T>();
208         }
209 
210     	return supportService.retrieveSelectedResultBOs(boClass, setOfSelectedObjIds);
211     }
212 
213     /**
214      * Given the business object class, determines the best qualifying LookupResultsSupportStrategyService to use
215      *
216      * @param boClass a business object class
217      * @return an LookupResultsSupportStrategyService implementation, or null if no qualifying strategies could be found
218      */
219     protected LookupResultsSupportStrategyService getQualifingSupportStrategy(Class boClass) {
220     	if (getPersistableBusinessObjectSupportStrategy().qualifiesForStrategy(boClass)) {
221     		return getPersistableBusinessObjectSupportStrategy();
222         } else if ( dataObjectBaseSupportStrategy.qualifiesForStrategy(boClass) ) {
223             return dataObjectBaseSupportStrategy;
224     	} else if (getDataDictionarySupportStrategy().qualifiesForStrategy(boClass)) {
225     		return getDataDictionarySupportStrategy();
226     	}
227     	return null;
228     }
229 
230     /**
231      * @see org.kuali.rice.krad.lookup.LookupResultsService#clearPersistedLookupResults(java.lang.String)
232      */
233     @Override
234     public void clearPersistedLookupResults(String lookupResultsSequenceNumber) throws Exception {
235         LookupResults lookupResults = retrieveLookupResults(lookupResultsSequenceNumber);
236         if (lookupResults != null) {
237             businessObjectService.delete(lookupResults);
238         }
239     }
240 
241     /**
242      * @see org.kuali.rice.krad.lookup.LookupResultsService#clearPersistedSelectedObjectIds(java.lang.String)
243      */
244     @Override
245     public void clearPersistedSelectedObjectIds(String lookupResultsSequenceNumber) throws Exception {
246         SelectedObjectIds selectedObjectIds = retrieveSelectedObjectIds(lookupResultsSequenceNumber);
247         if (selectedObjectIds != null) {
248             businessObjectService.delete(selectedObjectIds);
249         }
250     }
251 
252     /**
253 	 * Figures out which LookupResultsServiceSupportStrategy to defer to, and uses that to get the lookup id
254 	 * @see org.kuali.rice.krad.lookup.LookupResultsService#getLookupId(org.kuali.rice.krad.bo.BusinessObject)
255 	 */
256 	@Override
257     public String getLookupId(BusinessObject businessObject) {
258 		final LookupResultsSupportStrategyService supportService = getQualifingSupportStrategy(businessObject.getClass());
259 		if (supportService == null) {
260 			return null; // this may happen quite often, so let's just return null - no exception here
261 		}
262 		return supportService.getLookupIdForBusinessObject(businessObject);
263 	}
264 
265 	public BusinessObjectService getBusinessObjectService() {
266         return businessObjectService;
267     }
268 
269     public void setBusinessObjectService(BusinessObjectService businessObjectService) {
270         this.businessObjectService = businessObjectService;
271     }
272 
273     /**
274      * Determines whether the passed in user ID is allowed to view the lookup metadata (object IDs or results table)
275      * @param mvlm
276      * @param personId
277      * @return
278      */
279     protected boolean isAuthorizedToAccessMultipleValueLookupMetadata(MultipleValueLookupMetadata mvlm, String personId) {
280         return personId.equals(mvlm.getLookupPersonId());
281     }
282 
283 
284     @Override
285     public void deleteOldLookupResults(Timestamp expirationDate) {
286         persistedLookupMetadataDao.deleteOldLookupResults(expirationDate);
287 
288     }
289 
290     @Override
291     public void deleteOldSelectedObjectIds(Timestamp expirationDate) {
292         persistedLookupMetadataDao.deleteOldSelectedObjectIds(expirationDate);
293     }
294 
295     public PersistedLookupMetadataDao getPersistedLookupMetadataDao() {
296         return persistedLookupMetadataDao;
297     }
298 
299     public void setPersistedLookupMetadataDao(PersistedLookupMetadataDao persistedLookupMetadataDao) {
300         this.persistedLookupMetadataDao = persistedLookupMetadataDao;
301     }
302 
303 	/**
304 	 * @return the persistableBusinessObjectSupportStrategy
305 	 */
306 	public LookupResultsSupportStrategyService getPersistableBusinessObjectSupportStrategy() {
307 		return this.persistableBusinessObjectSupportStrategy;
308 	}
309 
310 	/**
311 	 * @return the dataDictionarySupportStrategy
312 	 */
313 	public LookupResultsSupportStrategyService getDataDictionarySupportStrategy() {
314 		return this.dataDictionarySupportStrategy;
315 	}
316 
317 	/**
318 	 * @param persistableBusinessObjectSupportStrategy the persistableBusinessObjectSupportStrategy to set
319 	 */
320 	public void setPersistableBusinessObjectSupportStrategy(
321 			LookupResultsSupportStrategyService persistableBusinessObjectSupportStrategy) {
322 		this.persistableBusinessObjectSupportStrategy = persistableBusinessObjectSupportStrategy;
323 	}
324 
325 	/**
326 	 * @param dataDictionarySupportStrategy the dataDictionarySupportStrategy to set
327 	 */
328 	public void setDataDictionarySupportStrategy(
329 			LookupResultsSupportStrategyService dataDictionarySupportStrategy) {
330 		this.dataDictionarySupportStrategy = dataDictionarySupportStrategy;
331 	}
332 
333 }
334