/*
* This file is part of gwap, an open platform for games with a purpose
*
* Copyright (C) 2013
* Project play4science
* Lehr- und Forschungseinheit für Programmier- und Modellierungssprachen
* Ludwig-Maximilians-Universität München
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gwap.tools;
import gwap.model.action.Characterization;
import gwap.model.resource.Resource;
import gwap.model.resource.Statement;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.log.Log;
/**
* Manages characterizations and the results of them. Holds a cache of the
* results to improve timing.
*
* @author Fabian Kneißl
*/
@AutoCreate
@Scope(ScopeType.CONVERSATION)
@Name("characterizationBean")
public class CharacterizationBean implements Serializable {
/**
* Consists of a list of results which are grouped by their value.
*
* @author Fabian Kneißl
*/
public class ResultForType {
private List<Pair<Integer, Integer>> result = new ArrayList<Pair<Integer,Integer>>();
private Integer total = 0;
/**
* Each pair is of the form (value, count) where count is the number
* of occurrences of value.
*
* @return list of pairs
*/
public List<Pair<Integer, Integer>> getResult() {
return result;
}
public Integer getResult(Integer value) {
for (Pair<Integer, Integer> p : result) {
if (p.a.equals(value))
return p.b;
}
return 0;
}
public Double getResultAsPercentage(Integer value) {
if (total == 0)
return 0.0;
else
return 100.0 * getResult(value).doubleValue() / total;
}
public Integer getTotal() {
return total;
}
public void addResult(Pair<Integer, Integer> addedResult) {
result.add(addedResult);
total += addedResult.b;
}
}
private static final long serialVersionUID = 6221630409445440605L;
@In
private EntityManager entityManager;
@Logger
private Log log;
// ResourceId -> { type -> { (value, count), ... } }
private Map<Long, Map<Characterization.Name, ResultForType>> resultsByResourceId =
new HashMap<Long, Map<Characterization.Name, ResultForType>>();
/**
* Clears the cache and forces a recomputation of results;
*/
public void clearCache() {
resultsByResourceId.clear();
}
/**
* Retrieves the characterization result for a given Resource and a Characterization Type
*
* @param resourceId
* @param type name of the characterization
* @return
*/
public ResultForType getResult(Long resourceId, Characterization.Name type) {
ResultForType resultForType = getResult(resourceId).get(type);
if (resultForType == null)
return new ResultForType();
else
return resultForType;
}
private Map<Characterization.Name, ResultForType> getResult(Long resourceId) {
if (resultsByResourceId.containsKey(resourceId)) {
return resultsByResourceId.get(resourceId);
} else {
log.info("Calculating characterization results for resource #0", resourceId);
Query q = entityManager.createNamedQuery("characterization.groupedResults");
q.setParameter("resourceId", resourceId);
Map<Characterization.Name, ResultForType> results = new HashMap<Characterization.Name, ResultForType>();
for (Object[] row : (List<Object[]>)q.getResultList()) {
Characterization.Name type = (Characterization.Name) row[0];
Pair<Integer, Integer> result = new Pair<Integer, Integer>((Integer)row[1], ((Long)row[2]).intValue());
if (!results.containsKey(type))
results.put(type, new ResultForType());
results.get(type).addResult(result);
}
resultsByResourceId.put(resourceId, results);
return results;
}
}
/**
* Builds a list of defined characterizations for the instance type of the resource.
*
* @param resource
* @return
*/
public static List<Characterization> getByResource(Resource resource) {
List<Characterization> dummies = new ArrayList<Characterization>();
if (resource instanceof Statement) {
dummies.add(new Characterization(Characterization.Name.gender));
dummies.add(new Characterization(Characterization.Name.maturity));
dummies.add(new Characterization(Characterization.Name.cultivation));
}
return dummies;
}
/**
* Checks if the Characterization has a value set. Also performs not-null checks.
*
* @param characterization
* @return true if the value is != null
*/
public static boolean isValueSet(Characterization characterization) {
return characterization != null && characterization.getValue() != null;
}
/**
* Checks if the Characterization has a value set and the value is 0.
*
* @param characterization
* @return
*/
public static boolean isValueUnknown(Characterization characterization) {
return isValueSet(characterization) && characterization.getValue() == 0;
}
/**
* Returns the order in which the items of a characterization are displayed.
*
* @param characterizationName
* @return
*/
public Integer[] getAvailableItems(Characterization.Name characterizationName) {
return new Integer[] { 1, 2, 3, 0 };
}
/**
* Creates a list as defined in {@link #getByResource(Resource)}.
*
* @param resource
* @return
*/
public static Characterization[] createCharacterizations(Resource resource) {
List<Characterization> cList = getByResource(resource);
Characterization[] characterizations = cList.toArray(new Characterization[cList.size()]);
return characterizations;
}
/**
* Creates a list as defined in {@link #getByResource(Resource)} and
* initializes all values with 0.
*
* @param resource
* @return
*/
public static Characterization[] createAndInitializeCharacterizations(Resource resource) {
Characterization[] characterizations = createCharacterizations(resource);
for (Characterization c : characterizations)
c.setValue(0);
return characterizations;
}
}