Commit cb32afc5 by Tuomas Riihimäki

Queue raw

1 parent 860a76c0
package fi.codecrew.moya.beans;
import javax.ejb.Local;
import fi.codecrew.moya.model.EventMap;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.map.MapReservationQueueEntry;
@Local
public interface QueueBeanLocal {
MapReservationQueueEntry enterQueue(EventMap map, EventUser user);
boolean isReserving(EventMap map, EventUser user);
}
package fi.codecrew.moya.beans;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Singleton;
import fi.codecrew.moya.model.EventMap;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.LanEventProperty;
import fi.codecrew.moya.model.LanEventPropertyKey;
import fi.codecrew.moya.model.map.MapReservationQueue;
import fi.codecrew.moya.model.map.MapReservationQueueEntry;
/**
* Session Bean implementation class QueueBean
*/
@Singleton
@LocalBean
public class QueueBean implements QueueBeanLocal {
/**
* Default constructor.
*/
public QueueBean() {
// TODO Auto-generated constructor stub
}
private final Map<EventMap, MapQueue> mapqueues = new HashMap<>();
private static class MapQueue {
private final Set<MapReservationQueueEntry> reserving = new HashSet<>();
private final List<MapReservationQueueEntry> queue = new ArrayList<>();
for (MapReservationQueueEntry r : reserving) {
if (new Date().after(r.getReservationTimeout())) {
reserving.remove(r);
}
}
public boolean isReserving(EventUser user) {
for(MapReservationQueueEntry r : reserving) {
if(r.getUser().equals(user)) {
return true;
}
}
return false;
}
public boolean enterReserving( EventUser user) {
timeoutReserving();
if (reserving.size() < 3 && !queue.isEmpty() && queue.get(0).equals(entry)) {
entry = queue.get(0);
entry.removeFromQueue();
}
}
private void timeoutReserving() {
}
}
public boolean enterReserving(EventMap map, EventUser user) {
}
@EJB
private EventBeanLocal eventbean;
public boolean isReserving(EventMap map, EventUser user) {
// If queue is not enabled, user can always reserve
if (!isQueueEnabled())
return true;
return getMapque(map).isReserving(user);
}
private MapQueue getMapque(EventMap map) {
MapQueue ret = mapqueues.get(map);
if(ret == null){
ret = new MapQueue();
mapqueues.put(map, ret);
}
return ret;
}
public boolean isQueueEnabled() {
boolean ret = false;
LanEventProperty mapque = eventbean.getProperty(LanEventPropertyKey.MAP_QUEUE);
if (mapque != null)
ret = mapque.isBooleanValue();
return ret;
}
@Override
public MapReservationQueueEntry enterQueue(EventMap map, EventUser user) {
if (!queue.containsKey(map)) {
queue.put(map, new ArrayList<MapReservationQueueEntry>());
}
List<MapReservationQueueEntry> quelist = queue.get(map);
MapReservationQueueEntry ret = null;
for (MapReservationQueueEntry qe : quelist) {
if (user.equals(qe.getUser())) {
ret = qe;
break;
}
}
if (ret == null) {
ret = new MapReservationQueueEntry();
ret.setCreated(new Date());
ret.setUser(user);
ret.addToQueue(quelist.get(quelist.size() - 1));
quelist.add(ret);
}
return ret;
}
}
......@@ -44,6 +44,7 @@ public enum LanEventPropertyKey {
TEMPLATE_PROPERTY5(Type.TEXT, null),
INVITE_ONLY_EVENT(Type.BOOL, null),
USE_ETICKET(Type.BOOL, null),
MAP_QUEUE(Type.BOOL, null),
;
......
......@@ -18,7 +18,6 @@
*/
package fi.codecrew.moya.model;
import java.awt.Color;
import java.util.Calendar;
import javax.persistence.CascadeType;
......
package fi.codecrew.moya.model.map;
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import fi.codecrew.moya.model.EventMap;
import fi.codecrew.moya.model.GenericEntity;
/**
*
*
*/
//mapQueGroup
//- queEnableTime
//- queDisableTime
//- maxSiultaneousPlaces
//- maxSimultaneoutUsers
//- minPlaces
//- maxPlaces
//- placecountWeight ( 1 = more places go first, 0 = fully random
//- queueTimeWeight ( 1 = fifo, 0 = fully random )
@Entity
@Table(name = "map_reservation_queue")
public class MapReservationQueue extends GenericEntity {
@ManyToOne
@JoinColumn(nullable = false)
private EventMap map;
private String name;
private String description;
@Temporal(TemporalType.TIMESTAMP)
private Date queueEnableTime;
@Temporal(TemporalType.TIMESTAMP)
private Date queueDisableTime;
// how many placeslots or users can be reserving places at the same time
private Integer simultaneousPlaceslots;
private Integer simultaneousUsers;
private Integer queMinPlaces;
private Integer queMaxPlaces;
// Bigger gets selected first if multiple queues apply to user
private Integer selectionPriority = 100;
// // 100 = more places go always first, 0 = fully random
// @Column(nullable = false, precision = 6, scale = 7)
// private Integer placeslotWeight;
//
// // ( 100 = fifo, 0 = fully random )
// private Integer queueTimeWeight;
// If there are multiple queues enabled, queueus with the same weight
// are evaluated against eachother. Queues with bigger priorities are always selected
// before queues with lower prorities
private Integer queueQuePriority = 10;
/**
*
*/
private static final long serialVersionUID = -6631083485543375943L;
public MapReservationQueue() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getQueueEnableTime() {
return queueEnableTime;
}
public void setQueueEnableTime(Date queueEnableTime) {
this.queueEnableTime = queueEnableTime;
}
public Date getQueueDisableTime() {
return queueDisableTime;
}
public void setQueueDisableTime(Date queueDisableTime) {
this.queueDisableTime = queueDisableTime;
}
public Integer getSimultaneousPlaceslots() {
return simultaneousPlaceslots;
}
public void setSimultaneousPlaceslots(Integer simultaneousPlaceslots) {
this.simultaneousPlaceslots = simultaneousPlaceslots;
}
public Integer getSimultaneousUsers() {
return simultaneousUsers;
}
public void setSimultaneousUsers(Integer simultaneousUsers) {
this.simultaneousUsers = simultaneousUsers;
}
public Integer getQueMinPlaces() {
return queMinPlaces;
}
public void setQueMinPlaces(Integer queMinPlaces) {
this.queMinPlaces = queMinPlaces;
}
public Integer getQueMaxPlaces() {
return queMaxPlaces;
}
public void setQueMaxPlaces(Integer queMaxPlaces) {
this.queMaxPlaces = queMaxPlaces;
}
public EventMap getMap() {
return map;
}
public void setMap(EventMap map) {
this.map = map;
}
public Integer getSelectionPriority() {
return selectionPriority;
}
public void setSelectionPriority(Integer selectionPriority) {
this.selectionPriority = selectionPriority;
}
public Integer getQueueQuePriority() {
return queueQuePriority;
}
public void setQueueQuePriority(Integer queueQuePriority) {
this.queueQuePriority = queueQuePriority;
}
}
package fi.codecrew.moya.model.map;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.GenericEntity;
//userque
//- user
//- enteredQueue
//- enteredSelection
@Entity
@Table(name = "map_reservation_queue_entry")
public class MapReservationQueueEntry extends GenericEntity {
/**
*
*/
private static final long serialVersionUID = -1529588850152306791L;
@Column()
@JoinColumn(nullable = false)
private MapReservationQueue queue;
@ManyToOne
private EventUser user;
@Temporal(TemporalType.TIMESTAMP)
private Date created;
@Temporal(TemporalType.TIMESTAMP)
private Date reservationTimeout;
@OneToOne()
@JoinColumn(nullable = true)
private MapReservationQueueEntry previous;
@OneToOne(mappedBy = "previous")
private MapReservationQueueEntry next;
private static final Logger logger = LoggerFactory.getLogger(MapReservationQueueEntry.class);
public void removeFromQueue() {
if (previous != null) {
if (!this.equals(previous.getNext())) {
logger.warn("WTF!! Previous entrys next value does not match this! This '{}', Previous '{}', Next of previous '{}'", this, getPrevious(), getPrevious().getNext());
}
previous.setNext(next);
previous = null;
next = null;
}
}
public void addToQueue(MapReservationQueueEntry previous) {
if (previous != null) {
next = previous.getNext();
previous.setNext(this);
if (next != null) {
next.setPrevious(this);
}
}
}
public MapReservationQueue getQueue() {
return queue;
}
public void setQueue(MapReservationQueue queue) {
this.queue = queue;
}
public EventUser getUser() {
return user;
}
public void setUser(EventUser user) {
this.user = user;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public MapReservationQueueEntry getPrevious() {
return previous;
}
public void setPrevious(MapReservationQueueEntry previous) {
this.previous = previous;
}
public MapReservationQueueEntry getNext() {
return next;
}
public void setNext(MapReservationQueueEntry next) {
this.next = next;
}
public Date getReservationTimeout() {
return reservationTimeout;
}
public void setReservationTimeout(Date reservationTimeout) {
this.reservationTimeout = reservationTimeout;
}
}
......@@ -35,6 +35,7 @@
<h:outputScript target="head" library="seatjs" name="d3-tip.js" />
<h:outputScript target="head" library="seatjs" name="seatmap.js" />
<h:outputStylesheet library="seatjs" name="placemap.css" />
<div style="margin: 5px;">
<h:form id="placeselectform">
<h:commandButton rendered="#{ajaxMapView.canUserBuy()}"
......
......@@ -15,6 +15,7 @@ import org.slf4j.LoggerFactory;
import fi.codecrew.moya.beans.EventBeanLocal;
import fi.codecrew.moya.beans.PermissionBeanLocal;
import fi.codecrew.moya.beans.PlaceBeanLocal;
import fi.codecrew.moya.beans.QueueBeanLocal;
import fi.codecrew.moya.enums.apps.MapPermission;
import fi.codecrew.moya.exceptions.BortalCatchableException;
import fi.codecrew.moya.model.EventMap;
......@@ -25,7 +26,7 @@ import fi.codecrew.moya.web.cdiview.GenericCDIView;
import fi.codecrew.moya.web.cdiview.user.UserView;
@Named
@ConversationScoped
@RequestScoped
public class AjaxMapView extends GenericCDIView {
/**
......@@ -53,6 +54,9 @@ public class AjaxMapView extends GenericCDIView {
@Inject
private UserView userview;
@EJB
private QueueBeanLocal quebean;
public void initReserveMap() {
initMap();
map = placebean.findMap(mapId);
......@@ -87,16 +91,20 @@ public class AjaxMapView extends GenericCDIView {
return ret;
}
public Long getAvailablePlaces() {
Long ret = placebean.availablePlaceCount(initMap());
// logger.debug("Got {} availbale places for map {}", ret, initMap());
// logger.debug("Got {} availbale places for map {}", ret, initMap());
return ret;
}
public boolean canUserBuy() {
return permbean.hasPermission(MapPermission.BUY_PLACES);
return permbean.hasPermission(MapPermission.BUY_PLACES) &&
(permbean.hasPermission(MapPermission.MANAGE_OTHERS) ||
quebean.isReserving(map, permbean.getCurrentUser())
);
}
public String buySelectedPlaces() {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!