package com.iqmen.components.dashboard;
import java.util.*;
import org.hibernate.Session;
import org.hibernate.Query;
import org.w3c.dom.Element;
import com.iqmen.components.lock.LockManager;
import com.iqmen.components.security.ACL;
import com.iqmen.components.security.CheckInfo;
import com.iqmen.components.security.StandartSecurityPolicy;
import com.iqmen.components.security.User;
import com.iqmen.components.security.StandartSecurityPolicy.Filter;
import com.iqmen.server.QueryContext;
import com.iqmen.utils.StringUtils;
import com.iqmen.utils.Validation;
import com.iqmen.utils.ValidationException;
import com.iqmen.utils.XmlWrapper;
import static com.iqmen.queries.QueryTagConstants.*;
import static com.iqmen.components.dashboard.Actions.*;
import com.iqmen.components.export.Exporter;
import com.iqmen.components.export.importers.XmlImportListener;
/**
* менеджер сохраненных в системе представлений
*
*/
public class LayoutManager implements Exporter {
private Map<String, PortletImporter> importers = new HashMap<String, PortletImporter>();
private Map<String, PortletExporter> exporters = new HashMap<String, PortletExporter>();
private PortletImporter defaultImporter;
private PortletExporter defaultExporter;
private LockManager lockManager;
/**
* политика безопасности
*/
private StandartSecurityPolicy securityPolicy = null;
private List<XmlImportListener> layoutImportListeners;
public LayoutManager () {}
public void init () throws Exception {
Validation.checkPropertyNotNull(securityPolicy, "securityPolicy");
Validation.checkPropertyNotNull(defaultImporter, "defaultImporter");
Validation.checkPropertyNotNull(defaultExporter, "defaultExporter");
Validation.checkPropertyNotNull(layoutImportListeners, "layoutImportListeners");
Validation.checkPropertyNotNull(lockManager, "lockManager");
}
/**
* создает новое пустое представление
* @param equery
* @param eresponse
* @throws Exception
*/
public void createLayout (Element equery, Element eresponse) throws Exception {
Element elayout = XmlWrapper.getMandatoryElement(equery, TAG_LAYOUT);
Layout layout = createLayout(elayout, QueryContext.getQueryContext().user);
XmlWrapper.addTextElement(eresponse, TAG_LAYOUTID, layout.getId() + "");
}
public Layout createLayout(Element elayout, User user) throws Exception {
Session session = QueryContext.getQueryContext().session;
Layout layout = Layout.create(elayout, user, session);
checkAccess(layout, CREATE_LAYOUT, user);
ACL acl = securityPolicy.getACLFromXml(elayout);
if (acl == null){
acl = new ACL();
}
//для новых представлений будут добавлены обязательные ace (даже если пользователь ничего не задал)
securityPolicy.setACL(layout, user, acl, true);
LayoutVisit visit = getLayoutVisit(user, session);
if (visit != null){
visit.drop(session);
}
LayoutVisit.create(user, layout, session);
return layout;
}
/**
* редактирует основные свойства представления - название, описание, доступ
* @param equery
* @param eresponse
* @throws Exception
*/
public void editLayout (Element equery, Element eresponse) throws Exception {
Element elayout = XmlWrapper.getMandatoryElement(equery, TAG_LAYOUT);
Long id = XmlWrapper.getMandatoryLongElement(elayout, TAG_ID);
Layout layout = getLayout(id);
checkAccess(layout, EDIT_LAYOUT);
layout.fromXml(elayout);
ACL acl = securityPolicy.getACLFromXml(elayout);
if (acl != null){
//проверяем, что пользователь может поменять доступ
checkAccess(layout, EDIT_LAYOUT_ACCESS);
securityPolicy.setACL(layout, layout.getCreator(), acl, false);
}
}
/**
* удаление представления
* @param equery
* @throws Exception
*/
public void removeLayout (Element equery) throws Exception {
Long id = XmlWrapper.getMandatoryLongElement(equery, TAG_LAYOUTID);
Session session = QueryContext.getQueryContext().session;
Layout layout = getLayout(id);
checkAccess(layout, DELETE_LAYOUT);
securityPolicy.onObjectRemoval(layout);
session.delete(layout);
}
/**
* доступ к представлению по его идентификатору
* @param equery
* @param eresponse
* @throws Exception
*/
public void getLayout (Element equery, Element eresponse) throws Exception {
Layout layout = getLayout(equery);
User user = QueryContext.getQueryContext().user;
boolean printsections = XmlWrapper.getBooleanElementYN(equery, TAG_NEEDCONFIGS, false);
appendLayoutInformation(eresponse, layout, user, true, printsections);
}
/**
* доступ к последнему просмотренному пользователем представлению
* @param eresponse
* @throws Exception
*/
public void getLastLayout(Element eresponse) throws Exception {
User user = QueryContext.getQueryContext().user;
Session session = QueryContext.getQueryContext().session;
LayoutVisit visit = getLayoutVisit(user, session);
Collection<Long> unsortedids = getLayoutIdsUnsorted(user);
Long layoutid = null;
if (visit != null) {
if (unsortedids.contains(visit.getLayout().getId()) && hasRight(visit.getLayout(), VIEW_LAYOUT, user)) {
layoutid = visit.getLayout().getId();
}
}
if (layoutid == null){
/**
* visit отсутствует или больше нет прав на просмотр последнего представления.
* В таком случае вернем первое попавшееся представление
*/
for (Long id : unsortedids){
if (hasRight(getLayout(id), VIEW_LAYOUT, user)) {
layoutid = id;
break;
}
}
}
XmlWrapper.addTextElement(eresponse, TAG_LAYOUTID, layoutid != null ? layoutid + "" : "");
}
/**
* установка последнего просмотренного пользователем представления
* @param equery
* @throws Exception
*/
public void setLastLayout (Element equery) throws Exception {
User user = QueryContext.getQueryContext().user;
Session session = QueryContext.getQueryContext().session;
//захват блокировки
lockManager.acquireLock(user.getId(), true);
Layout layout = getLayout(equery);
LayoutVisit visit = getLayoutVisit(user, session);
boolean update = visit == null || !visit.getLayout().equals(layout);
if (update){
if (visit != null){
visit.drop(session);
}
LayoutVisit.create(user, layout, session);
}
}
/**
* добавить чужое представление в список импортированных
* @param equery
* @throws Exception
*/
public void importLayouts (Element equery) throws Exception {
User user = QueryContext.getQueryContext().user;
Session session = QueryContext.getQueryContext().session;
long[] layoutIds = XmlWrapper.getLongArray(equery, TAG_LAYOUTS);
List<Layout> layouts = new ArrayList<Layout> (layoutIds.length);
for (long layoutId : layoutIds){
Layout layout = getLayoutForRead(layoutId);
if (layout.getCreator().equals(user)){
//попытка импортировать свое же представление
throw ValidationException.format("LAYOUTS.IMPORTMYLAYOUT");
}
layouts.add(layout);
}
//старые привязки удаляем
Query query = session.createQuery("delete from LayoutImport link where link.user=:user").setEntity("user", user);
query.executeUpdate();
//новые - создаем
for (Layout layout : layouts){
LayoutImport.create(user, layout, session);
}
//если импортировали пачку представлений при загрузке попадем в первое из пачки
if (layouts.size() > 0) {
Layout firstImported = layouts.get(0);
LayoutVisit visit = getLayoutVisit(user, session);
boolean update = visit == null || !visit.getLayout().equals(firstImported);
if (update){
if (visit != null){
visit.drop(session);
}
LayoutVisit.create(user, firstImported, session);
}
}
}
/**
* удалить чужое представление из списка импортированных
* @param equery
* @throws Exception
*/
public void unImportLayout (Element equery) throws Exception {
Layout layout = getLayout(equery);
User user = QueryContext.getQueryContext().user;
Session session = QueryContext.getQueryContext().session;
LayoutImport layoutImport = getLayoutImport(user, layout, session);
if (layoutImport != null){
layoutImport.drop(session);
}
}
/**
* получить список представлений, доступных для чтения, - своих
* и импортированных
* @param user
* @param eresponse
* @throws Exception
*/
public void getLayoutList (User user, Element equery, Element eresponse) throws Exception {
Collection<Long> ids = getLayoutIdsUnsorted(user);
Element elayouts = XmlWrapper.addTextElement(eresponse, TAG_LAYOUTS, "");
Layout[] layouts = getSortedLayouts(ids);
for (Layout layout : layouts){
appendLayoutInformation(elayouts, layout, user, true, false);
}
}
public Collection<Long> getLayoutIdsUnsorted(User user) throws Exception {
Session session = QueryContext.getQueryContext().session;
Collection<Long> ids = securityPolicy.getObjectsWithReadPermission(user, new LayoutFilterImpl(session, user, true));
return ids;
}
/**
* получить список представлений, которые пользователь может импортировать
* (включая уже импортированные)
* @param user
* @param eresponse
* @throws Exception
*/
public void getLayoutListForImport (final User user, Element eresponse) throws Exception {
//возвращаем все чужие представления, которые пользователь еще не импортирова