EditorLockingRestController.java
package sk.iway.iwcm.system.datatable.editorlocking;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import sk.iway.iwcm.Cache;
import sk.iway.iwcm.Identity;
import sk.iway.iwcm.Tools;
import sk.iway.iwcm.admin.layout.UserDto;
import sk.iway.iwcm.users.UsersDB;
/**
* RestCotroller pre prácu s editorLocking záznamami v Chache pamäti
*
* Pri editovaní záznamu sa uloží do Chache informácia o tom, kto upravuje aky záznam a v akej tabuľke.
* Súčasne sa vráti zoznam všetkých ostatných používateľov, ktorý práve edituju ten istý záznam.
* Po tom čo uživateľ uzavrie editor záznamu, jeho akcia sa vymaže z Cache pamäte.
*/
@RestController
@RequestMapping("/admin/rest/editorlocking")
@ResponseBody
public class EditorLockingRestController {
//nazov cachce objektu v pamäti
private static final String CACHE_PREFIX = "editor.locking";
//dlžka exspiracie v minutach, pre dany cache objekt
private static final int CACHE_EXPIRE_MINUTES = 2;
/**
* Ulozi novy zaznam (EditorLockingBean) o tom kto prave edituje aky zazanm a v akej tabulke
* do Chache objektu v pamäti.
*
* @param entityId
* @param tableUniqueId
* @param request
* @return zoznam všetkych použivateľov (List<UserDto>), ktory prave edituju ten isty zaznam
*/
@GetMapping({ "/open/{entityId}/{tableUniqueId}" })
public List<UserDto> addEdit(
@PathVariable("entityId") int entityId,
@PathVariable("tableUniqueId") String tableUniqueId,
HttpServletRequest request) {
Identity user = UsersDB.getCurrentUser(request);
if (user == null) return new ArrayList<>();
int userId = user.getUserId();
List<EditorLockingBean> editorLockingBeanList = getCacheList(tableUniqueId);
boolean actionExist = false;
//Zisti, či už existuje zaznam o tom, že aktualny použivateľ upravuje tento zaznam v tejto tabuľke
for(EditorLockingBean editAction : editorLockingBeanList) {
if(editAction.getEntityId() == entityId &&
editAction.getUserId() == userId) {
actionExist = true;
//Aktualizuj poslednu zmenu (musi byť aktualizovana PRED odstranenim editActions, ktore exspirovali)
editAction.setLastChange(new Date());
break;
}
}
//Tento editActions zaznam nie je v liste, takže ho pridaj
if(!actionExist) {
//Pridaj novo vytvoreny zaznam (EditorLockingBean) do listu
editorLockingBeanList.add(getNewEditRecord(entityId, userId));
}
//Odstran editActions, ktore exspirovali
removeExpiredEditActions(editorLockingBeanList);
//Vrať list ostatnych použivateľov, ktory upravuju rovnaky zaznam v rovnakej tabuľke (ako aktualny poživateľ)
return getListOfOtherUsers(editorLockingBeanList, entityId, userId);
}
/**
* Vymaže z Cache objektu v pamäti zaznam o tom, že daný použivateľ edituje
* konkretny zaznam v konkretnej tabuľke.
*
* @param entityId
* @param tableUniqueId
* @param request
* @return
*/
@GetMapping({ "/close/{entityId}/{tableUniqueId}" })
public void removeEdit(
@PathVariable("entityId") int entityId,
@PathVariable("tableUniqueId") String tableUniqueId,
HttpServletRequest request) {
List<EditorLockingBean> editorLockingBeanList = getCacheList(tableUniqueId);
Identity user = UsersDB.getCurrentUser(request);
if (user == null) return;
int userId = user.getUserId();
Iterator<EditorLockingBean> i = editorLockingBeanList.iterator();
while (i.hasNext()) {
EditorLockingBean next = i.next(); //Musi to byt zavolane pre akciou i.remove()
if(next.getEntityId() == entityId && next.getUserId()==userId) {
i.remove();
break;
}
}
}
/**
* Vytvor a nastav novy EditorLockingBean objekt podla vstupnych parametrov.
*
* @param entityId
* @param request
* @return vytvoreny a nastaveny objekt (EditorLockingBean)
*/
private EditorLockingBean getNewEditRecord(int entityId, int userId) {
EditorLockingBean newEdit = new EditorLockingBean();
newEdit.setEntityId(entityId);
newEdit.setLastChange(new Date());
newEdit.setUserId(userId);
return newEdit;
}
/**
* Prejdi zadany list (List<EditorLockingBean>), a dostran z neho EditorLockingBean objekty, ktore už exspirovali.
*
* @param entityId
* @param tableUniqueId
* @param request
* @return list (List<EditorLockingBean>) s objektami, ktore ešte neexspirovali
*/
private void removeExpiredEditActions(List<EditorLockingBean> editorLockingBeanList) {
//Aktualny datum a čas v millisekundach
long now = new Date().getTime();
Iterator<EditorLockingBean> i = editorLockingBeanList.iterator();
while (i.hasNext()) {
//Musi to byt zavolane pre akciou i.remove()
EditorLockingBean editAction = i.next();
//Dokedy validne
long validUntil = editAction.getLastChange().getTime() + (60000 * CACHE_EXPIRE_MINUTES);
//Ak editAction exspirovala, odstraň ju
if(now >= validUntil) {
i.remove();
}
}
}
/**
* Prejdi zadany list (List<EditorLockingBean>), a zisti kto každy upravuje ten isty zaznam v tej istej tabulke
*
* @param entityId
* @param userId
* @return list (List<UserDto>) s ostatnymi pouzivatelmi ktory tento zaznam prave upravuju
*/
private List<UserDto> getListOfOtherUsers(List<EditorLockingBean> editorLockingBeanList, int entityId, int userId) {
List<UserDto> otherUsers = new ArrayList<>();
for(EditorLockingBean editAction : editorLockingBeanList) {
if(editAction.getEntityId() == entityId && editAction.getUserId() != userId) {
UserDto otherUser = new UserDto(UsersDB.getUser(editAction.getUserId()));
otherUsers.add(otherUser);
}
}
return otherUsers;
}
/**
* Vrati z cache list EditorLockingBean pre zadane meno tabulky
* @param tableUniqueId
* @return
*/
private List<EditorLockingBean> getCacheList(String tableUniqueId) {
Cache cache = Cache.getInstance();
String cacheKey = CACHE_PREFIX+"-"+tableUniqueId;
//Ak editorlocking cacheBean už existuje, ziskaj lit zaznamov uprav (List<EditorLockingBean>)
@SuppressWarnings("unchecked")
List<EditorLockingBean> editorLockingBeanList = (List<EditorLockingBean>) cache.getObject(cacheKey);
if (editorLockingBeanList == null) {
editorLockingBeanList = new ArrayList<>();
cache.setObject(cacheKey, editorLockingBeanList, CACHE_EXPIRE_MINUTES+5);
} else {
//musime ho v cache obnovit, aby neexspiroval
cache.setObjectExpiryTime(cacheKey, Tools.getNow() + ((CACHE_EXPIRE_MINUTES+5)*60*1000));
}
return editorLockingBeanList;
}
}