package in.partake.controller.api.event;
import in.partake.app.PartakeApp;
import in.partake.base.PartakeException;
import in.partake.base.Util;
import in.partake.controller.api.AbstractPartakeAPI;
import in.partake.model.IPartakeDAOs;
import in.partake.model.access.DBAccess;
import in.partake.model.dao.DAOException;
import in.partake.model.dao.PartakeConnection;
import in.partake.model.dto.Event;
import in.partake.model.dto.auxiliary.EventCategory;
import in.partake.resource.UserErrorCode;
import in.partake.service.IEventSearchService;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.JsonNodeFactory;
import org.codehaus.jackson.node.ObjectNode;
import play.mvc.Result;
// search API can take
// 1) query (String)
// 2) category (String)
// 3) beforeDeadlineOnly (Boolean)
// 4) sortOrder (String)
// 5) maxNum (integer)
public class SearchAPI extends AbstractPartakeAPI {
private static final String DEFAULT_CATEGORY = EventCategory.getAllEventCategory();
private static final boolean DEFAULT_BEFORE_DEADLINE_ONLY = true;
private static final String DEFAULT_SORT_ORDER = "score";
private static final int DEFAULT_MAX_NUM = 10;
public static final int MAX_NUM = 100;
public static Result get() throws DAOException, PartakeException {
return new SearchAPI().execute();
}
public static Result post() throws DAOException, PartakeException {
return new SearchAPI().execute();
}
public Result doExecute() throws DAOException, PartakeException {
String query = getQuery();
String category = getCategory();
String sortOrder = getSortOrder();
if (sortOrder == null)
return renderInvalid(UserErrorCode.MISSING_SEARCH_ORDER);
boolean beforeDeadlineOnly =
optBooleanParameter("beforeDeadlineOnly", DEFAULT_BEFORE_DEADLINE_ONLY);
int offset = optIntegerParameter("offset", 0);
if (offset < 0)
return renderInvalid(UserErrorCode.INVALID_ARGUMENT);
int maxNum = optIntegerParameter("maxNum", DEFAULT_MAX_NUM);
maxNum = Util.ensureRange(maxNum, 0, MAX_NUM);
if (maxNum <= 0)
return renderInvalid(UserErrorCode.INVALID_ARGUMENT);
List<Event> events = new SearchTransaction(query, category, sortOrder, beforeDeadlineOnly, offset, maxNum).execute();
ObjectNode obj = new ObjectNode(JsonNodeFactory.instance);
ArrayNode jsonEventsArray = obj.putArray("events");
for (Event event : events) {
jsonEventsArray.add(event.toSafeJSON());
}
return renderOK(obj);
}
private String getQuery() {
String query = getParameter("query");
return StringUtils.trimToEmpty(query);
}
private String getCategory() {
String category = getParameter("category");
if (category == null)
return DEFAULT_CATEGORY;
category = category.trim();
if (EventCategory.getAllEventCategory().equals(category) || EventCategory.isValidCategoryName(category))
return category;
else
return DEFAULT_CATEGORY;
}
private String getSortOrder() {
String sortOrder = getParameter("sortOrder");
if (sortOrder == null)
return DEFAULT_SORT_ORDER;
sortOrder = sortOrder.trim();
if ("score".equalsIgnoreCase(sortOrder)) { return "score"; }
if ("createdAt".equalsIgnoreCase(sortOrder)) { return "createdAt"; }
if ("deadline".equalsIgnoreCase(sortOrder)) { return "deadline"; }
if ("deadline-r".equalsIgnoreCase(sortOrder)) { return "deadline-r"; }
if ("beginDate".equalsIgnoreCase(sortOrder)) { return "beginDate"; }
if ("beginDate-r".equalsIgnoreCase(sortOrder)) { return "beginDate-r"; }
return DEFAULT_SORT_ORDER;
}
}
class SearchTransaction extends DBAccess<List<Event>> {
private String query;
private String category;
private String sortOrder;
private boolean beforeDeadlineOnly;
private int offset;
private int maxNum;
public SearchTransaction(String query, String category, String sortOrder, boolean beforeDeadlineOnly, int offset, int maxNum) {
this.query = query;
this.category = category;
this.sortOrder = sortOrder;
this.beforeDeadlineOnly = beforeDeadlineOnly;
this.offset = offset;
this.maxNum = maxNum;
}
@Override
protected List<Event> doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
IEventSearchService searchService = PartakeApp.getEventSearchService();
List<String> eventIds = searchService.search(query, category, sortOrder, beforeDeadlineOnly, offset, maxNum);
List<Event> events = new ArrayList<Event>();
for (String eventId : eventIds) {
Event event = daos.getEventAccess().find(con, eventId);
if (event != null && event.isSearchable())
events.add(event);
}
return events;
}
}