package me.moodcat.backend.rooms;
import java.util.Map;
import java.util.concurrent.Future;
import lombok.extern.slf4j.Slf4j;
import me.moodcat.backend.UnitOfWorkSchedulingService;
import me.moodcat.database.controllers.RoomDAO;
import org.eclipse.jetty.util.component.AbstractLifeCycle.AbstractLifeCycleListener;
import org.eclipse.jetty.util.component.LifeCycle;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
/**
* The backend of rooms, initializes room instances and keeps track of time and messages.
*/
@Slf4j
@Singleton
public class RoomBackend extends AbstractLifeCycleListener {
/**
* UnitOfWorkSchedulingService.
*/
private final UnitOfWorkSchedulingService unitOfWorkSchedulingService;
/**
* RoomInstanceFactory for this roombackend.
*/
private final RoomInstanceFactory roomInstanceFactory;
/**
* The room DAO provider.
*/
private final Provider<RoomDAO> roomDAOProvider;
/**
* A map of room instances.
*/
private final Map<Integer, RoomInstance> roomInstances;
/**
* The constructor of the chat's backend, initializes fields and rooms.
*
* @param unitOfWorkSchedulingService
* UnitOfWorkSchedulingService to schedule tasks in a unit of work
* @param roomInstanceFactory
* RoomInstanceFactory to instantiate RoomInstances
* @param roomDAOProvider
* Provider to create RoomDAOs when in a unit of work
* @param lifeCycle
* The program lifecycle, to instantiate the initial rooms
* when the program has started
*/
@Inject
public RoomBackend(final UnitOfWorkSchedulingService unitOfWorkSchedulingService,
final RoomInstanceFactory roomInstanceFactory,
final Provider<RoomDAO> roomDAOProvider,
final LifeCycle lifeCycle) {
this(unitOfWorkSchedulingService, roomInstanceFactory, roomDAOProvider);
lifeCycle.addLifeCycleListener(this);
}
/**
* The constructor of the chat's backend, initializes fields and rooms.
*
* @param unitOfWorkSchedulingService
* UnitOfWorkSchedulingService to schedule tasks in a unit of work
* @param roomInstanceFactory
* RoomInstanceFactory to instantiate RoomInstances
* @param roomDAOProvider
* Provider to create RoomDAOs when in a unit of work
*/
public RoomBackend(final UnitOfWorkSchedulingService unitOfWorkSchedulingService,
final RoomInstanceFactory roomInstanceFactory,
final Provider<RoomDAO> roomDAOProvider) {
this.unitOfWorkSchedulingService = unitOfWorkSchedulingService;
this.roomInstanceFactory = roomInstanceFactory;
this.roomDAOProvider = roomDAOProvider;
this.roomInstances = Maps.newTreeMap();
}
/**
* Get a room instance by its id.
*
* @param id
* the room's id
* @return the room
*/
public RoomInstance getRoomInstance(final int id) {
return roomInstances.get(id);
}
/**
* Initialize the rooms from the db.
*/
public Future<?> initializeRooms() {
return unitOfWorkSchedulingService
.performInUnitOfWork(() -> {
final RoomDAO roomDAO = roomDAOProvider.get();
roomDAO.listRooms()
.stream()
.map(roomInstanceFactory::create)
.forEach(
roomInstance -> roomInstances.put(roomInstance.getId(),
roomInstance));
});
}
@Override
public void lifeCycleStarted(final LifeCycle event) {
super.lifeCycleStarted(event);
log.info("[Lifecycle started] Creating initial rooms for {}", this);
initializeRooms();
}
}