package karma; import java.util.Collection; import karma.model.Impact; import karma.model.ImpactIdentifier; import karma.model.ImpactStore; import karma.model.Reputable; import karma.model.ReputationEntry; import karma.model.ReputationEntryStore; import karma.model.ReputationHolder; import karma.model.ReputationHolderStore; import play.Logger; import play.Logger.ALogger; public abstract class AbstractImpactEvaluation<C, E extends ReputationEntry, R extends Reputable, RH extends ReputationHolder> implements ImpactEvaluation<C, R, RH> { private static ALogger log = Logger.of(AbstractImpactEvaluation.class); ReputationEntryStore<?, E> reputationEntryStore; ReputationHolderStore<R, RH> reputationHolderStore; ImpactStore impactStore; ImpactIdentifier impactId; public AbstractImpactEvaluation( ReputationEntryStore<?, E> reputationEntryStore, ImpactStore impactStore, ReputationHolderStore<R, RH> reputationHolderStore, ImpactIdentifier impactId) { super(); this.reputationEntryStore = reputationEntryStore; this.impactStore = impactStore; this.reputationHolderStore = reputationHolderStore; this.impactId = impactId; } @Override public RH evaluate(C ctx) { try { R subject = subject(ctx); Impact impact = impact(impactId); E entry = createReputationEntry(subject, impact); return updateReputationHolder(impact, entry, subject); } catch (Exception e) { log.error("error evaluating reputation", e); e.printStackTrace(); return null; } } @Override public RH reevaluate(R subject, RH holder) { try { Impact impact = impact(impactId); Collection<E> entries = findReputationEntries(subject, impact); holder = updateReputationHolder(impact, entries, holder); return holder; } catch (Exception e) { log.error("error reevaluating reputation", e); e.printStackTrace(); return null; } } protected Collection<E> findReputationEntries(R subject, Impact impact) { return reputationEntryStore.findFor(subject, impact); } protected Impact impact(ImpactIdentifier impactIdentifier) { if (log.isDebugEnabled()) log.debug("impactIdentifier : " + impactIdentifier); return impactStore.get(impactIdentifier); } protected E createReputationEntry(Reputable subject, Impact impact) { if (log.isDebugEnabled()) log.debug("createReputationEntry <-"); E rep = createReputationEntry(); rep.setOwner(subject); rep.setImpact(impact); reputationEntryStore.create(rep); if (log.isDebugEnabled()) log.debug("rep : " + rep); return rep; } protected RH updateReputationHolder(Impact impact, E entry, R subject) { if (log.isDebugEnabled()) log.debug("updateReputationHolder <-"); RH rh = getReputationHolder(subject); if (log.isDebugEnabled()) log.debug("rh : " + rh); return updateReputationHolder(impact, entry, rh, true); } protected RH updateReputationHolder(Impact impact, Collection<E> entries, RH holder) { for (E e : entries) { updateReputationHolder(impact, e, holder, false); } return holder; } protected RH updateReputationHolder(Impact impact, E entry, RH rh, boolean persist) { Number v = impact.getNumberValue(); rh.increase(v); if (persist) reputationHolderStore.update(rh); return rh; } public RH getReputationHolder(R subject) { if (log.isDebugEnabled()) log.debug("getReputationHolder <-"); if (log.isDebugEnabled()) log.debug("subject : " + subject); RH rh = reputationHolderStore.get(subject); if (log.isDebugEnabled()) log.debug("rh : " + rh); if (rh == null) { rh = reputationHolderStore.create(subject); } return rh; } /** * Creates a new Reputation Entry * * @return a newly created Reputation Entry */ protected abstract E createReputationEntry(); /** * Extracts the subject from the given context * * @param ctx * the evaluation context * @return subject from the context */ protected abstract R subject(C ctx); }