WebPagesListener.java
package sk.iway.iwcm.editor.rest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import org.springframework.ui.ModelMap;
import sk.iway.iwcm.*;
import sk.iway.iwcm.admin.ThymeleafEvent;
import sk.iway.iwcm.admin.jstree.JsTreeItem;
import sk.iway.iwcm.common.CloudToolsForCore;
import sk.iway.iwcm.common.UserTools;
import sk.iway.iwcm.doc.DocDB;
import sk.iway.iwcm.doc.DocDetails;
import sk.iway.iwcm.doc.DocDetailsRepository;
import sk.iway.iwcm.doc.DocHistory;
import sk.iway.iwcm.doc.DocHistoryRepository;
import sk.iway.iwcm.doc.DocumentsJsTreeItem;
import sk.iway.iwcm.doc.GroupDetails;
import sk.iway.iwcm.doc.GroupsDB;
import sk.iway.iwcm.doc.GroupsJsTreeItem;
import sk.iway.iwcm.doc.GroupsTreeService;
import sk.iway.iwcm.doc.attributes.jpa.DocAtrDefRepository;
import sk.iway.iwcm.editor.EditorDB;
import sk.iway.iwcm.editor.service.GroupsService;
import sk.iway.iwcm.editor.service.WebpagesService;
import sk.iway.iwcm.i18n.Prop;
import sk.iway.iwcm.system.datatable.DatatablePageImpl;
import sk.iway.iwcm.system.spring.events.WebjetEvent;
import sk.iway.iwcm.users.UsersDB;
/**
* Doplna data pre admin cast web stranky (pre prve nacitanie),
* aby nebolo potrebne volat REST sluzby pri inicializacii
* - optimalizacia rychlosti zobrazenia
*/
@Component
public class WebPagesListener {
@Autowired
private GroupsTreeService groupsTreeService;
@Autowired
private DocDetailsRepository docRepo;
@Autowired
private DocHistoryRepository docHistoryRepository;
@Autowired
private DocAtrDefRepository docAtrDefRepository;
@EventListener(condition = "#event.clazz eq 'sk.iway.iwcm.admin.ThymeleafEvent' && event.source.page=='webpages' && event.source.subpage=='web-pages-list'")
protected void setInitalData(final WebjetEvent<ThymeleafEvent> event) {
try {
ModelMap model = event.getSource().getModel();
HttpServletRequest request = event.getSource().getRequest();
Identity user = UsersDB.getCurrentUser(request);
String treeInitialJson = "null";
String groupsInitialJson = "null";
String webpagesInitialJson = "null";
Boolean hasPagesToApprove = Boolean.FALSE;
boolean hasSystemTab = true;
boolean hasTrashTab = true;
GroupsDB groupsDB = GroupsDB.getInstance();
GroupDetails system = GroupsService.getSystemGroupDetails();
GroupDetails trash = GroupsService.getTrashGroupDetails();
String showTab = "pills-folders-tab";
if (user.isEnabledItem("menuWebpages")) {
//ak je zadany docid ako parameter over/nastav korektne domenu
int docId = Tools.getIntValue(event.getSource().getRequest().getParameter("docid"), -1);
int groupId = Tools.getIntValue(event.getSource().getRequest().getParameter("groupid"), -1);
if (docId > 0 && EditorDB.isPageEditable(user, docId)) {
//DocDetails doc = DocDB.getInstance().getBasicDocDetails(docId, false);
Optional<DocDetails> doc = docRepo.findById(Long.valueOf(docId));
if (doc.isPresent()) {
//ak je zadane docId prepiseme groupId aj keby bolo zadane
groupId = doc.get().getGroupId();
}
}
if (groupId > 0) {
GroupDetails group = groupsDB.getGroup(groupId);
if (group != null && Tools.isNotEmpty(group.getDomainName())) {
event.getSource().getRequest().getSession().setAttribute("preview.editorDomainName", group.getDomainName());
RequestBean rb = SetCharacterEncodingFilter.getCurrentRequestBean();
if (rb != null) {
rb.setDomain(DocDB.getDomain(event.getSource().getRequest()));
}
}
}
//over nastavenie zobrazenia
String click = "dt-tree-group-filter-system-trash";
boolean showPages = WebpagesService.isTreeShowPages(user);
if (showPages) click = "dt-tree-filter-system-trash";
//root adresare stromovej struktury
int lastGroupId = getLastGroupId(request, groupId);
GroupDetails lastGroup = groupsDB.getGroup(lastGroupId);
int rootGroupId = 0;
if (lastGroup != null && lastGroup.getFullPath().contains("/System")) {
if (lastGroup.getFullPath().contains(trash.getFullPath())) {
//it's a trash folder
rootGroupId = trash.getGroupId();
showTab = "pills-trash-tab";
click = "dt-tree-group-trash";
} else {
rootGroupId = system.getGroupId();
showTab = "pills-system-tab";
click = "dt-tree-group-system";
}
}
List<JsTreeItem> rootGroups = groupsTreeService.getItems(user, rootGroupId, showPages, click, null, event.getSource().getRequest());
if ("pills-system-tab".equals(showTab)) {
rootGroups = rootGroups.stream().filter(g->{
if (g instanceof GroupsJsTreeItem) {
GroupsJsTreeItem gjs = (GroupsJsTreeItem) g;
if (gjs.getGroup().getFullPath().startsWith(trash.getFullPath())) return false;
}
return true;
}).collect(Collectors.toList());
}
List<JsTreeItem> expandedGroups = expandGroupsLastFolder(rootGroups, lastGroupId, user, showPages, click, request);
treeInitialJson = JsonTools.objectToJSON(expandedGroups);
//root group details
DatatablePageImpl<GroupDetails> rootGroupDetails = GroupsRestController.getAllItems(lastGroupId, event.getSource().getRequest());
if ("null".equals(groupsInitialJson) && rootGroups.isEmpty()==false && (rootGroupDetails==null || rootGroupDetails.getContent().isEmpty())) {
//use first group as rootGroupDetails
List<GroupDetails> onlyRootGroupList = new ArrayList<>();
if (lastGroup != null) onlyRootGroupList.add(lastGroup); //user doesnt' have edit rights to group, so it's null
else onlyRootGroupList.add(((GroupsJsTreeItem)rootGroups.get(0)).getGroup());
rootGroupDetails = new DatatablePageImpl<>(onlyRootGroupList);
WebpagesService ws = new WebpagesService(onlyRootGroupList.get(0).getGroupId(), user, Prop.getInstance(request), request);
GroupsRestController.addOptions(rootGroupDetails, ws, user, onlyRootGroupList.get(0), request);
}
groupsInitialJson = JsonTools.objectToJSON(rootGroupDetails);
GetAllItemsDocOptions options = new GetAllItemsDocOptions(event.getSource().getRequest());
//Set group id of first group in jstree (pre-loading)
if (rootGroupDetails!=null && rootGroupDetails.getContent().isEmpty()==false) options.setGroupId(rootGroupDetails.getContent().get(0).getGroupId());
else options.setGroupId(0);
//Set pageable as new instance from page 0 to page 25
options.setPageable(PageRequest.of(0, 25).withSort(Sort.by(Sort.Direction.ASC, "id")));
options.setDocDetailsRepository(docRepo);
options.setDocAtrDefRepository(docAtrDefRepository);
//Get all Doc Pages
DatatablePageImpl<DocDetails> pages = WebpagesService.getAllItems(options);
if (pages.getContent().isEmpty()==false) {
webpagesInitialJson = JsonTools.objectToJSON( pages );
}
//overenie, ci ma nieco na schvalenie
//List<DocHistory> pagesForApprove = WebApproveService.getAllItems(options, null);
try {
List<DocHistory> pagesForApprove = docHistoryRepository.findAll(WebApproveRestController.getToApproveConditions(options.getUserId()));
if (pagesForApprove.isEmpty()==false) hasPagesToApprove = Boolean.TRUE;
} catch (Exception ex) {
Logger.error(ex);
}
if (lastGroupId == 0) request.getSession().removeAttribute(Constants.SESSION_GROUP_ID);
}
model.addAttribute("treeInitialJson", fixJson(treeInitialJson));
model.addAttribute("groupsInitialJson", fixJson(groupsInitialJson));
model.addAttribute("webpagesInitialJson", fixJson(webpagesInitialJson));
model.addAttribute("hasPagesToApprove", hasPagesToApprove);
model.addAttribute("showTab", showTab);
//ak ma user specialne prava na priecinky automaticky system a kos vypni,
//povol len ak ma pravo na niektory priecinok
if (Tools.isNotEmpty(user.getEditableGroups()) || Tools.isNotEmpty(user.getEditablePages())) {
hasSystemTab = false;
hasTrashTab = false;
}
if (Tools.isNotEmpty(user.getEditableGroups())) {
if (GroupsDB.isGroupEditable(user, system.getGroupId()) || GroupsDB.isGroupViewable(user, system.getGroupId())) hasSystemTab = true;
if (GroupsDB.isGroupEditable(user, trash.getGroupId()) || GroupsDB.isGroupViewable(user, trash.getGroupId())) hasTrashTab = true;
}
if (Tools.isNotEmpty(user.getEditablePages())) {
//prejdi zoznam web stranok a over, ci tam nie je System alebo Kos
List<DocDetails> docs = UserTools.getEditablePages(user.getEditablePages());
for (DocDetails doc : docs) {
if (hasSystemTab==false && (","+groupsDB.getParents(doc.getGroupId())+",").contains(","+system.getGroupId()+",")) hasSystemTab = true;
if (hasTrashTab==false && (","+groupsDB.getParents(doc.getGroupId())+",").contains(","+trash.getGroupId()+",")) hasTrashTab = true;
}
}
model.addAttribute("hasSystemTab", Boolean.valueOf(hasSystemTab));
model.addAttribute("hasTrashTab", Boolean.valueOf(hasTrashTab));
request.getSession().setAttribute("userWasInWebpages", "true");
} catch (Exception ex) {
Logger.error(WebPagesListener.class, ex);
}
}
/**
* Fixne problem s JSON objektom vlozenym do HTML kodu, problem je hlavne so </script> tagom, ktory na urovni HTML parsera ukonci parsing javascript kodu a hodi chybu
* @param json
* @return
*/
private String fixJson(String json) {
String fixed = json;
fixed = Tools.replace(fixed, "</script>", "<\\/script>");
fixed = Tools.replace(fixed, "</SCRIPT>", "<\\/SCRIPT>");
return fixed;
}
/**
* Expandne priecinky podla zadaneho naposledy otvoreneho groupId
* @param rootGroups
* @param lastGroupId
* @return
*/
private List<JsTreeItem> expandGroupsLastFolder(List<JsTreeItem> rootGroups, int lastGroupId, Identity user, boolean showPages, String click, HttpServletRequest request) {
if (lastGroupId < 1) return rootGroups;
List<JsTreeItem> expanded = new ArrayList<>();
expanded.addAll(rootGroups);
//ziskaj zoznam parent priecinkov
List<GroupDetails> parentGroups = GroupsDB.getInstance().getParentGroups(lastGroupId);
Collections.reverse(parentGroups);
expandGroups(expanded, parentGroups, lastGroupId, 0, user, showPages, click, request);
//vyresetuj selected atribut
for (JsTreeItem item : expanded) {
if (item.getId().equals(String.valueOf(lastGroupId))) item.getState().setSelected(true);
else item.getState().setSelected(false);
}
return expanded;
}
private void expandGroups(List<JsTreeItem> groups, List<GroupDetails> parentGroups, int lastGroupId, int position, Identity user, boolean showPages, String click, HttpServletRequest request) {
if (position>=parentGroups.size()) return;
int addGroupId = parentGroups.get(position).getGroupId();
//prevencia ConcurrentModificationException
List<JsTreeItem> groupsOriginal = new ArrayList<>();
groupsOriginal.addAll(groups);
for (JsTreeItem item : groupsOriginal) {
if (item instanceof GroupsJsTreeItem) {
GroupsJsTreeItem gitem = (GroupsJsTreeItem)item;
if (position == 0 && Tools.isEmpty(gitem.getParent())) {
gitem.setParent("#");
}
if (gitem.getGroup().getGroupId()==addGroupId) {
//nastav stav na neselektnuty a otvoreny
gitem.getState().setSelected(false);
gitem.getState().setOpened(true);
gitem.getState().setLoaded(true);
//pridaj child elementy
List<JsTreeItem> childs = groupsTreeService.getItems(user, addGroupId, showPages, click, null, request);
for (JsTreeItem child : childs) {
child.setParent(String.valueOf(addGroupId));
//ak je to posledny nastav stav na selectnuty
if (child.getId().equals(String.valueOf(lastGroupId))) child.getState().setSelected(true);
}
groups.addAll(childs);
//vyvolaj rekurziu
expandGroups(groups, parentGroups, lastGroupId, position+1, user, showPages, click, request);
}
}
if (item instanceof DocumentsJsTreeItem) {
DocumentsJsTreeItem ditem = (DocumentsJsTreeItem)item;
if (position == 0 && Tools.isEmpty(ditem.getParent())) {
ditem.setParent("#");
}
}
}
}
/**
* Ziska naposledy zobrazene ID priecinka, alebo 0 ak nie je nastavene
* @param request
* @param groupId - groupId based on docId value or 0
* @return
*/
public static int getLastGroupId(HttpServletRequest request, int groupId) {
int lastGroupId = 0;
try {
int docId = Tools.getIntValue(request.getParameter("docid"), -1);
if (docId > 0) {
//ak je zadane docid nerobime ziaden preload
lastGroupId = groupId;
} else if (request.getParameter("groupid") != null) {
lastGroupId = Integer.parseInt(request.getParameter("groupid"));
} else {
// skus ziskat data zo session
if (request.getSession().getAttribute(Constants.SESSION_GROUP_ID) != null) {
lastGroupId = Integer
.parseInt((String) request.getSession().getAttribute(Constants.SESSION_GROUP_ID));
}
}
} catch (Exception ex) {
//
}
//ak je zadana hodnota 0 zmaz zo session zapamatanie
if (lastGroupId==0) request.getSession().removeAttribute(Constants.SESSION_GROUP_ID);
if (lastGroupId>0) {
GroupDetails group = GroupsDB.getInstance().getGroup(lastGroupId);
if (group != null && Tools.isNotEmpty(group.getDomainName())) {
String currentDomain = CloudToolsForCore.getDomainName();
if (Tools.isNotEmpty(currentDomain) && currentDomain.contains(".") && currentDomain.equals(group.getDomainName())==false) {
lastGroupId = 0;
request.getSession().removeAttribute(Constants.SESSION_GROUP_ID);
}
}
}
return lastGroupId;
}
}