001/*
002 * Copyright 2007 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
017package org.kuali.ole.sys.service.impl;
018
019import java.sql.Timestamp;
020import java.util.ArrayList;
021import java.util.Collection;
022import java.util.HashMap;
023import java.util.List;
024import java.util.Map;
025import java.util.Set;
026
027import org.apache.commons.codec.binary.Base64;
028import org.apache.commons.logging.Log;
029import org.apache.commons.logging.LogFactory;
030import org.kuali.ole.sys.OLEPropertyConstants;
031import org.kuali.ole.sys.service.SegmentedLookupResultsService;
032import org.kuali.rice.core.api.datetime.DateTimeService;
033import org.kuali.rice.kns.lookup.LookupResults;
034import org.kuali.rice.kns.lookup.LookupResultsServiceImpl;
035import org.kuali.rice.kns.lookup.LookupUtils;
036import org.kuali.rice.kns.lookup.SelectedObjectIds;
037import org.kuali.rice.kns.web.ui.ResultRow;
038import org.kuali.rice.krad.bo.PersistableBusinessObject;
039import org.kuali.rice.krad.exception.AuthorizationException;
040import org.kuali.rice.krad.util.ObjectUtils;
041import org.springframework.transaction.annotation.Transactional;
042
043/**
044 * Used for segemented lookup results
045 */
046@Transactional
047public class SegmentedLookupResultsServiceImpl extends LookupResultsServiceImpl implements SegmentedLookupResultsService {
048
049    private static final Log LOG = LogFactory.getLog(SegmentedLookupResultsServiceImpl.class);
050
051    private DateTimeService dateTimeService;
052
053    /**
054     * Retrieve the Date Time Service
055     * 
056     * @return Date Time Service
057     */
058    public DateTimeService getDateTimeService() {
059        return dateTimeService;
060    }
061
062    /**
063     * Assign the Date Time Service
064     * 
065     * @param dateTimeService
066     */
067    public void setDateTimeService(DateTimeService dateTimeService) {
068        this.dateTimeService = dateTimeService;
069    }
070
071    /**
072     * @see org.kuali.rice.kns.lookup.LookupResultsService#persistResultsTable(java.lang.String, java.util.List, java.lang.String)
073     */
074    public void persistResultsTable(String lookupResultsSequenceNumber, List<ResultRow> resultTable, String personId) throws Exception {
075        String resultTableString = new String(Base64.encodeBase64(ObjectUtils.toByteArray(resultTable)));
076
077        Timestamp now = getDateTimeService().getCurrentTimestamp();
078
079        LookupResults lookupResults = retrieveLookupResults(lookupResultsSequenceNumber);
080        if (lookupResults == null) {
081            lookupResults = new LookupResults();
082            lookupResults.setLookupResultsSequenceNumber(lookupResultsSequenceNumber);
083        }
084        lookupResults.setLookupResultsSequenceNumber(lookupResultsSequenceNumber);
085        lookupResults.setLookupPersonId(personId);
086        lookupResults.setSerializedLookupResults(resultTableString);
087        lookupResults.setLookupDate(now);
088        getBusinessObjectService().save(lookupResults);
089        if (LOG.isDebugEnabled()) {
090            LOG.debug("Wrote resultTable " + resultTable);
091        }
092    }
093
094    /**
095     * @see org.kuali.rice.kns.lookup.LookupResultsService#persistSelectedObjectIds(java.lang.String, java.util.Set, java.lang.String)
096     */
097    public void persistSelectedObjectIds(String lookupResultsSequenceNumber, Set<String> selectedObjectIds, String personId) throws Exception {
098        SelectedObjectIds selectedObjectIdsBO = retrieveSelectedObjectIds(lookupResultsSequenceNumber);
099        if (selectedObjectIdsBO == null) {
100            selectedObjectIdsBO = new SelectedObjectIds();
101            selectedObjectIdsBO.setLookupResultsSequenceNumber(lookupResultsSequenceNumber);
102        }
103        selectedObjectIdsBO.setLookupResultsSequenceNumber(lookupResultsSequenceNumber);
104        selectedObjectIdsBO.setLookupPersonId(personId);
105        selectedObjectIdsBO.setSelectedObjectIds(LookupUtils.convertSetOfObjectIdsToString(selectedObjectIds));
106        selectedObjectIdsBO.setLookupDate(getDateTimeService().getCurrentTimestamp());
107        getBusinessObjectService().save(selectedObjectIdsBO);
108    }
109
110    /**
111     * @see org.kuali.rice.kns.lookup.LookupResultsService#retrieveResultsTable(java.lang.String, java.lang.String)
112     */
113    public List<ResultRow> retrieveResultsTable(String lookupResultsSequenceNumber, String personId) throws Exception {
114        LookupResults lookupResults = retrieveLookupResults(lookupResultsSequenceNumber);
115        if (!isAuthorizedToAccessLookupResults(lookupResults, personId)) {
116            throw new AuthorizationException(personId, "retrieve lookup results", "lookup sequence number " + lookupResultsSequenceNumber);
117        }
118        List<ResultRow> resultTable = (List<ResultRow>) ObjectUtils.fromByteArray(Base64.decodeBase64(lookupResults.getSerializedLookupResults().getBytes()));
119        return resultTable;
120    }
121
122    /**
123     * Returns a list of BOs that were selected. This implementation makes an attempt to retrieve all BOs with the given object IDs,
124     * unless they have been deleted or the object ID changed. Since data may have changed since the search, the returned BOs may
125     * not match the criteria used to search.
126     * 
127     * @see org.kuali.rice.kns.lookup.LookupResultsService#retrieveSelectedResultBOs(java.lang.String, java.lang.Class,
128     *      java.lang.String)
129     */
130    public Collection<PersistableBusinessObject> retrieveSelectedResultBOs(String lookupResultsSequenceNumber, Class boClass, String personId) throws Exception {
131        Set<String> setOfSelectedObjIds = retrieveSetOfSelectedObjectIds(lookupResultsSequenceNumber, personId);
132        return retrieveSelectedResultBOs(lookupResultsSequenceNumber, setOfSelectedObjIds, boClass, personId);
133    }
134
135    /**
136     * @param lookupResultsSequenceNumber
137     * @param personId
138     * @return Set<String>
139     */
140    public Set<String> retrieveSetOfSelectedObjectIds(String lookupResultsSequenceNumber, String personId) throws Exception {
141        SelectedObjectIds selectedObjectIds = retrieveSelectedObjectIds(lookupResultsSequenceNumber);
142        if (!isAuthorizedToAccessSelectedObjectIds(selectedObjectIds, personId)) {
143            throw new AuthorizationException(personId, "retrieve lookup results", "lookup sequence number " + lookupResultsSequenceNumber);
144        }
145        Set<String> retval = LookupUtils.convertStringOfObjectIdsToSet(selectedObjectIds.getSelectedObjectIds());
146        return retval;
147    }
148
149    /**
150     * @param lookupResultsSequenceNumber
151     * @param setOfSelectedObjIds
152     * @param boClass
153     * @param personId
154     * @return Collection<PersistableBusinessObject>
155     */
156    public Collection<PersistableBusinessObject> retrieveSelectedResultBOs(String lookupResultsSequenceNumber, Set<String> setOfSelectedObjIds, Class boClass, String personId) throws Exception {
157        if (LOG.isDebugEnabled()) {
158            LOG.debug("Retrieving results for class " + boClass + " with objectIds " + setOfSelectedObjIds);
159        }
160        if (setOfSelectedObjIds.isEmpty()) {
161            // OJB throws exception if querying on empty set
162            return new ArrayList<PersistableBusinessObject>();
163        }
164        Map<String, Collection<String>> queryCriteria = new HashMap<String, Collection<String>>();
165        queryCriteria.put(OLEPropertyConstants.OBJECT_ID, setOfSelectedObjIds);
166        return getBusinessObjectService().findMatching(boClass, queryCriteria);
167    }
168
169}
170