package org.karmaexchange.dao;
import java.util.Date;
import java.util.List;
import org.karmaexchange.resources.msg.ValidationErrorInfo;
import org.karmaexchange.resources.msg.ValidationErrorInfo.ValidationError;
import org.karmaexchange.resources.msg.ValidationErrorInfo.ValidationErrorType;
import org.karmaexchange.util.HtmlUtil;
import com.google.common.collect.Lists;
import com.googlecode.objectify.annotation.Index;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Data
@EqualsAndHashCode(callSuper=true)
@ToString(callSuper=true)
public abstract class BaseEvent<T extends BaseEvent<T>> extends IdBaseDao<T> {
public static final int MAX_EVENT_KARMA_POINTS = 500;
protected String title;
protected String description;
protected String descriptionHtml;
protected Location location;
@Index
protected Date startTime;
@Index
protected Date endTime;
/**
* The number of karma points earned by participating in the event. This is derived from the
* start and end time.
*/
protected int karmaPoints;
@Override
protected void preProcessInsert() {
super.preProcessInsert();
initDescription();
validateBaseEvent();
initKarmaPoints();
}
@Override
protected void processUpdate(T prevObj) {
super.processUpdate(prevObj);
initDescription();
validateBaseEvent();
initKarmaPoints();
}
private void initDescription() {
if ((descriptionHtml == null) || (description == null)) {
if (descriptionHtml != null) {
description = HtmlUtil.toPlainText(descriptionHtml);
} else if (description != null) {
descriptionHtml = HtmlUtil.toHtml(description);
}
}
}
private void initKarmaPoints() {
long eventDurationMins = (endTime.getTime() - startTime.getTime()) / (1000 * 60);
karmaPoints = (int) Math.min(eventDurationMins, MAX_EVENT_KARMA_POINTS);
}
/*
* Location is not validated.
* Start-time can equal end-time for non karma generating events.
*/
private void validateBaseEvent() {
List<ValidationError> validationErrors = Lists.newArrayList();
if ((null == title) || title.isEmpty()) {
validationErrors.add(new ResourceValidationError(
this, ValidationErrorType.RESOURCE_FIELD_VALUE_REQUIRED, "title"));
}
// TODO(avaliani): make sure the description has a minimum length. Avoiding this for now
// since we don't have auto event creation.
if (null == startTime) {
validationErrors.add(new ResourceValidationError(
this, ValidationErrorType.RESOURCE_FIELD_VALUE_REQUIRED, "startTime"));
}
if ( (startTime != null) && (endTime != null) && endTime.before(startTime)) {
validationErrors.add(new MultiFieldResourceValidationError(
this, ValidationErrorType.RESOURCE_FIELD_VALUE_MUST_BE_GTEQ_SPECIFIED_FIELD,
"endTime", "startTime"));
}
if (!validationErrors.isEmpty()) {
throw ValidationErrorInfo.createException(validationErrors);
}
}
}