/*
* Copyright (c) 2010 Lockheed Martin Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.eurekastreams.server.persistence.mappers.cache;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.eurekastreams.server.persistence.mappers.DomainMapper;
import org.eurekastreams.server.persistence.mappers.chained.PartialMapperResponse;
import org.eurekastreams.server.persistence.mappers.stream.CachedDomainMapper;
/**
* Generic cache mapper that returns the results and a partial mapper response with a new request.
*
* @param <KeySuffixType>
* the type of key suffix to find in cache
* @param <CachedValueType>
* the type of value stored in cache
*/
public class PartialCacheResultsMapper<KeySuffixType, CachedValueType> extends CachedDomainMapper implements
DomainMapper<List<KeySuffixType>,
// line break
PartialMapperResponse<List<KeySuffixType>, List<CachedValueType>>>
{
/**
* Cache key suffix transformer.
*/
private Transformer<KeySuffixType, String> keySuffixTransformer;
/**
* Cache key prefix.
*/
private String cacheKeyPrefix;
/**
* True if the return type is a list of lists.
*/
private Boolean listOfLists;
/**
* Constructor.
*
* @param inKeySuffixTransformer
* the key suffix transformer
* @param inCacheKeyPrefix
* the cache key prefix
* @param isListOfLists
* if the mapper is returning a list of lists.
*/
public PartialCacheResultsMapper(final Transformer<KeySuffixType, String> inKeySuffixTransformer,
final String inCacheKeyPrefix, final Boolean isListOfLists)
{
keySuffixTransformer = inKeySuffixTransformer;
cacheKeyPrefix = inCacheKeyPrefix;
listOfLists = isListOfLists;
}
/**
* Constructor.
*
* @param inKeySuffixes
* suffixes to look for in cache
* @return a partial mapper response containing the data found and a new request of the key suffixes not found
*/
public PartialMapperResponse<List<KeySuffixType>, List<CachedValueType>> execute(
final List<KeySuffixType> inKeySuffixes)
{
// Don't do any work for null
if (null == inKeySuffixes)
{
return new PartialMapperResponse<List<KeySuffixType>, List<CachedValueType>>(
new ArrayList<CachedValueType>());
}
// build a list of all cache keys and a map to help find which are missing
List<String> keys = new ArrayList<String>();
Map<KeySuffixType, String> suffixToCacheKeyMap = new HashMap<KeySuffixType, String>();
for (KeySuffixType suffix : inKeySuffixes)
{
String cacheKey = cacheKeyPrefix + keySuffixTransformer.transform(suffix);
suffixToCacheKeyMap.put(suffix, cacheKey);
keys.add(cacheKey);
}
// get the results from cache
Map<String, CachedValueType> cachedResults = null;
if (listOfLists)
{
cachedResults = (Map<String, CachedValueType>) getCache().multiGetList(keys);
}
else
{
cachedResults = (Map<String, CachedValueType>) getCache().multiGet(keys);
}
List<CachedValueType> foundResults = new LinkedList<CachedValueType>();
List<KeySuffixType> suffixesNotFound = new LinkedList<KeySuffixType>();
// interpret the results - building a list of results and new requests from those missing
for (KeySuffixType suffix : inKeySuffixes)
{
if (!cachedResults.containsKey(suffixToCacheKeyMap.get(suffix))
|| cachedResults.get(suffixToCacheKeyMap.get(suffix)) == null)
{
// missing result - add the suffix to the new request
suffixesNotFound.add(suffix);
}
else
{
// found the result - add it to the results
foundResults.add(cachedResults.get(suffixToCacheKeyMap.get(suffix)));
}
}
if (suffixesNotFound.size() == 0)
{
// complete response
return new PartialMapperResponse<List<KeySuffixType>, List<CachedValueType>>(foundResults);
}
else
{
// partial response
return new PartialMapperResponse<List<KeySuffixType>, //
List<CachedValueType>>(foundResults, suffixesNotFound);
}
}
}