/**Copyright 2010 Research Studios Austria Forschungsgesellschaft mBH
*
* This file is part of easyrec.
*
* easyrec is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* easyrec is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with easyrec. If not, see <http://www.gnu.org/licenses/>.
*/
package org.easyrec.util.domain;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.easyrec.model.core.ActionVO;
import org.easyrec.model.core.RatingVO;
import org.easyrec.service.domain.TypeMappingService;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
/**
* Methods to convert a bunch of <code>Actions</code> into a single <code>Rating</code>.
* Provides various aggregation types.
* <p/>
* <p><b>Company: </b>
* SAT, Research Studios Austria</p>
* <p/>
* <p><b>Copyright: </b>
* (c) 2007</p>
* <p/>
* <p><b>last modified:</b><br/>
* $Author: dmann $<br/>
* $Date: 2011-12-20 15:22:22 +0100 (Di, 20 Dez 2011) $<br/>
* $Revision: 18685 $</p>
*
* @author Roman Cerny
*/
public class ActionToRatingAggregator {
// logging
private static final Log logger = LogFactory.getLog(ActionToRatingAggregator.class);
/**
* aggregates multiple <code>ActionVO</code>s to a single <code>RatingVO</code>.
* assumes (precondition) that all passed <code>ActionVO</code>s are from the same Tenant-User-Item triple.
*
* @param actionsForUserItemPair
* @param actionMapping
* @param aggregateType
* @return
*/
public static RatingVO<Integer, String> getRating(
Collection<ActionVO<Integer, String>> actionsForTenantUserItemTriple,
HashMap<String, Double> actionMapping, String aggregateType) {
Iterator<ActionVO<Integer, String>> actionsIterator = actionsForTenantUserItemTriple
.iterator();
ActionVO<Integer, String> action = null;
// check if collection is empty
if (actionsForTenantUserItemTriple.size() == 0) {
if (logger.isDebugEnabled()) {
logger.debug("could not create TypedRatingVO, the collection of Actions was empty");
}
return null;
}
if (TypeMappingService.AGGREGATE_TYPE_AVERAGE.equals(aggregateType)) {
Double sumCurrentRatingValues = new Double(0);
int countCurrentActions = 0;
for (ActionVO<Integer, String> currentAction : actionsForTenantUserItemTriple) {
// do mapping & accumulate ratings
sumCurrentRatingValues += actionMapping.get(currentAction.getActionType()).floatValue();
countCurrentActions++;
action = currentAction;
}
return new RatingVO<Integer, String>(action.getItem(),
((double) (sumCurrentRatingValues / (double) countCurrentActions)),
actionsForTenantUserItemTriple.size(), action.getActionTime(), action.getUser());
} else if (TypeMappingService.AGGREGATE_TYPE_FIRST.equals(aggregateType)) {
// simply return the first action found
if (actionsIterator.hasNext()) {
action = actionsIterator.next();
return new RatingVO<Integer, String>(action.getItem(),
actionMapping.get(action.getActionType()), actionsForTenantUserItemTriple.size(),
action.getActionTime(), action.getUser());
}
} else if (TypeMappingService.AGGREGATE_TYPE_MAXIMUM.equals(aggregateType)) {
Double maxRatingValue = Double.MAX_VALUE * (-1);
Double currentRatingValue;
for (ActionVO<Integer, String> currentAction : actionsForTenantUserItemTriple) {
currentRatingValue = actionMapping.get(currentAction.getActionType());
if (currentRatingValue > maxRatingValue) {
maxRatingValue = currentRatingValue;
action = currentAction;
}
}
return new RatingVO<Integer, String>(action.getItem(),
actionMapping.get(action.getActionType()), actionsForTenantUserItemTriple.size(),
action.getActionTime(), action.getUser());
} else if (TypeMappingService.AGGREGATE_TYPE_MOST_FREQUENT.equals(aggregateType)) {
// count different actionTypes
HashMap<String, Integer> actionCounter = new HashMap<String, Integer>();
for (ActionVO<Integer, String> currentAction : actionsForTenantUserItemTriple) {
Integer currentCounter = actionCounter.get(currentAction.getActionType());
if (currentCounter != null) {
currentCounter++;
} else {
currentCounter = 1;
}
actionCounter.put(currentAction.getActionType(), currentCounter);
}
// select most frequent ActionType
Integer maxCounter = Integer.MAX_VALUE * (-1);
String actionType = null;
for (String currentAction : actionCounter.keySet()) {
if (actionCounter.get(currentAction) > maxCounter) {
maxCounter = actionCounter.get(currentAction);
actionType = currentAction;
}
}
// return first action with corresponding ActionType
for (ActionVO<Integer, String> currentAction : actionsForTenantUserItemTriple) {
if (currentAction.getActionType() == actionType) {
return new RatingVO<Integer, String>(currentAction.getItem(),
actionMapping.get(currentAction.getActionType()), actionsForTenantUserItemTriple.size(),
action.getActionTime(), currentAction.getUser());
}
}
} else if (TypeMappingService.AGGREGATE_TYPE_NEWEST.equals(aggregateType)) {
// initialize with oldest possible date
Date newestActionTime = new Date(0);
for (ActionVO<Integer, String> currentAction : actionsForTenantUserItemTriple) {
if (currentAction.getActionTime().after(newestActionTime)) {
newestActionTime = currentAction.getActionTime();
action = currentAction;
}
}
return new RatingVO<Integer, String>(action.getItem(),
actionMapping.get(action.getActionType()), actionsForTenantUserItemTriple.size(),
action.getActionTime(), action.getUser());
} else if (TypeMappingService.AGGREGATE_TYPE_OLDEST.equals(aggregateType)) {
// initialize with now()
Date oldestActionTime = new Date(System.currentTimeMillis());
for (ActionVO<Integer, String> currentAction : actionsForTenantUserItemTriple) {
if (currentAction.getActionTime().before(oldestActionTime)) {
oldestActionTime = currentAction.getActionTime();
action = currentAction;
}
}
return new RatingVO<Integer, String>(action.getItem(),
actionMapping.get(action.getActionType()), actionsForTenantUserItemTriple.size(),
action.getActionTime(), action.getUser());
}
return null;
}
}