/*
Copyright 2012 Christian Prause and Fraunhofer FIT
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 net.sf.collabreview.reputation;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import prause.toolbox.hibernate.HibernateUtil;
import net.sf.collabreview.core.Artifact;
import net.sf.collabreview.core.users.Author;
import net.sf.collabreview.core.ArtifactIdentifier;
import net.sf.collabreview.core.Repository;
import net.sf.collabreview.core.configuration.ConfigurationData;
import net.sf.collabreview.hooks.Hook;
import net.sf.collabreview.hooks.PostAddHook;
public class MetricContributionsCount extends ReputationMetric {
private static final Log logger = LogFactory.getLog(MetricContributionsCount.class);
private List<Hook> registeredHooks = new LinkedList<Hook>();
/**
* Buffer for preparing the new data when an update is in progress.
*/
private Map<String, Float> newData;
@Override
protected void configure(ConfigurationData configuration) throws
Exception {
PostAddHook postAddHook = new PostAddHook() {
@Override
public int getPriority() {
// TODO Auto-generated method stub
return PRIORITY_MEDIUM;
}
@Override
public void artifactAdded(Repository repository, Artifact
artifact) {
assert repository == MetricContributionsCount.this.getRepository();
MetricContributionsCount.this.incrementCountersForArtifact(artifact);
setScores();
}
} ;
getRepository().registerPostAddHook(postAddHook);
registeredHooks.add(postAddHook);
}
@Override
protected void destroy() {
for (Hook hook : registeredHooks) {
getRepository().removeHook(hook);
}
}
@Override
protected void beginVisiting() {
newData = new HashMap<String, Float>();
}
@Override
protected void visit(Artifact artifact) {
incrementCountersForArtifactWhileVisiting(artifact);
}
/**
*
* Increments the contribution(at least 30% counter for a specific artifact)--while visiting
* @param artifact The artifact to be checked.
*/
private void incrementCountersForArtifactWhileVisiting(Artifact artifact) {
if (getFilter() != null && !getFilter().filter(artifact)) {
return;
}
int last_revision = artifact.getId().getRevision();
int increment=0;
String artifactName = artifact.getId().getName();
//Get Contribution for the latest artifact
NavigableMap<Author, Float> latest_contributions = getOwner().getCollabReview().getMeasurementsManager().getArtifactResponsibility().listResponsibilities(artifact);
//get previous artifact
ArtifactIdentifier ai = getPreviousArtifact(artifactName, last_revision-1);
for (Author docAuthor : latest_contributions.keySet()) {
String latest_name=docAuthor.getName();
int latest_contribution=(int)(latest_contributions.get(docAuthor)*100+0.5);
//check conditions for incrementing the counter
if(latest_contribution>=30)
increment= 1;
else
increment=0;
Float oldValue = newData.get(latest_name);
if (oldValue == null) {
newData.put(latest_name, (float) increment);
} else {
newData.put(latest_name, oldValue + increment);
}
}
}
@Override
protected Map<String, Float> endVisiting() {
return newData;
}
@Override
protected String getDefaultName() {
return "contribution";
}
private void setScores() {
setAuthorScores(new HashMap<String,Float>(newData));
}
private void incrementCountersForArtifact(Artifact artifact) {
manipulateCounterForArtifact(artifact, 0);
}
/**
*
* Increments the contribution(at least 30% counter for a specific artifact)
* @param artifact The artifact to be checked.
*/
private void manipulateCounterForArtifact(Artifact artifact, int
increment) {
if (getFilter() != null && !getFilter().filter(artifact)) {
return;
}
int last_revision = artifact.getId().getRevision();
String artifactName = artifact.getId().getName();
NavigableMap<Author, Float> latest_contributions = getOwner().getCollabReview().getMeasurementsManager().getArtifactResponsibility().listResponsibilities(artifact);
//get Artifact with Revision latest-1...
ArtifactIdentifier ai = getPreviousArtifact(artifactName, last_revision-1);
if (ai!=null) {
Artifact child = getRepository().getArtifact(ai);
NavigableMap<Author,Float> previous_contributions = getOwner().getCollabReview().getMeasurementsManager().getArtifactResponsibility().listResponsibilities(child);
for (Author docAuthor : latest_contributions.keySet()) {
String latest_name = docAuthor.getName();
int latest_contribution = (int)(latest_contributions.get(docAuthor)*100+0.5);
int previous_contribution = 0;
if (previous_contributions.get(docAuthor) == null)
previous_contribution=0;
else
previous_contribution= (int)(previous_contributions.get(docAuthor)*100+0.5);
//check conditions for incrementing the counter
if (latest_contribution >= 30 && previous_contribution < 30) {
increment = 1;
}
else if (latest_contribution >= 30 && previous_contribution >= 30) {
increment = 0;
}
else if (latest_contribution <30 && previous_contribution >= 30) {
increment = -1;
}
else {
increment = 0;
}
/*logger.debug("Latest contribution for user "+latest_name+" for artifact:"+ artifact.getId().getName()+" is= "+latest_contribution);
logger.debug("Previous contribution for user "+latest_name+" is= "+previous_contribution);
logger.debug("Increment for artifact:"+artifact.getId().getName() +" of latest revision "+artifact.getId().getRevision()+ " for user "+latest_name +" is="+increment);
*/
Float oldValue = newData.get(latest_name);
if (oldValue == null) {
newData.put(latest_name, (float) increment);
}
else {
newData.put(latest_name, oldValue + increment);
}
}
}
else {
//previous is null
for (Author docAuthor : latest_contributions.keySet()) {
String latest_name = docAuthor.getName();
int latest_contribution = (int)(latest_contributions.get(docAuthor)*100+0.5);
if(latest_contribution < 30)
increment = 0;
else
increment = 1;
//logger.debug("Increment for artifact:"+artifact.getId().getName() +" of latest revision "+artifact.getId().getRevision()+ " for user "+latest_name +" is="+increment);
Float oldValue = newData.get(latest_name);
if (oldValue == null) {
newData.put(latest_name, (float) increment);
}
else {
newData.put(latest_name, oldValue + increment);
}
}
}
}
/**
*
* Gets the previous Artifact Identifier
* @param revision the revision of the previous artifact identifier
*/
public ArtifactIdentifier getPreviousArtifact(String artifactName, int revision) {
Query query=HibernateUtil.getCurrentSession().createQuery("FROM ArtifactIdentifier Ai WHERE Ai.revision=:id AND Ai.name=:author");
query.setParameter("id",revision);
query.setParameter("author", artifactName);
query.setMaxResults(1);
ArtifactIdentifier ai = (ArtifactIdentifier) query.uniqueResult();
return ai;
}
}