Java tutorial
/* * Copyright (c) 2013 Haulmont Technology Ltd. All Rights Reserved. * Haulmont Technology proprietary and confidential. * Use is subject to license terms. */ package com.haulmont.ext.web.ui.Call; import com.haulmont.chile.core.model.MetaPropertyPath; import com.haulmont.cuba.core.entity.Entity; import com.haulmont.cuba.core.global.*; import com.haulmont.cuba.gui.AppConfig; import com.haulmont.cuba.gui.ServiceLocator; import com.haulmont.cuba.gui.UserSessionClient; import com.haulmont.cuba.gui.WindowManager; import com.haulmont.cuba.gui.components.*; import com.haulmont.cuba.gui.components.actions.CreateAction; import com.haulmont.cuba.gui.components.actions.EditAction; import com.haulmont.cuba.gui.components.actions.RefreshAction; import com.haulmont.cuba.gui.data.*; import com.haulmont.cuba.gui.data.impl.CollectionDsListenerAdapter; import com.haulmont.cuba.gui.data.impl.DsListenerAdapter; import com.haulmont.cuba.gui.settings.Settings; import com.haulmont.cuba.security.app.UserSettingService; import com.haulmont.cuba.security.entity.EntityOp; import com.haulmont.cuba.security.entity.User; import com.haulmont.cuba.web.App; import com.haulmont.cuba.web.filestorage.WebExportDisplay; import com.haulmont.cuba.web.gui.components.WebComponentsHelper; import com.haulmont.cuba.web.gui.components.WebFilter; import com.haulmont.cuba.web.gui.components.WebPopupButton; import com.haulmont.docflow.core.app.CardService; import com.haulmont.docflow.core.app.NumerationService; import com.haulmont.docflow.core.entity.Doc; import com.haulmont.docflow.core.entity.NumeratorType; import com.haulmont.docflow.web.DocflowAppWindow; import com.haulmont.docflow.web.actions.ThesisExcelAction; import com.haulmont.docflow.web.ui.common.DocCreator; import com.haulmont.docflow.web.ui.common.DocflowHelper; import com.haulmont.ext.core.entity.Call; import com.haulmont.taskman.core.app.TaskmanService; import com.haulmont.taskman.web.ui.common.CardTreeFrame; import com.haulmont.taskman.web.ui.common.RemoveCardNullChildAction; import com.haulmont.taskman.web.ui.task.ProcessMenuBuilderAction; import com.haulmont.workflow.core.app.WfService; import com.haulmont.workflow.core.app.WfUtils; import com.haulmont.workflow.core.entity.Card; import com.haulmont.workflow.core.entity.CardInfo; import com.haulmont.workflow.web.ui.base.ResolutionsFrame; import com.vaadin.terminal.ThemeResource; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.StringUtils; import javax.inject.Inject; import javax.inject.Named; import java.util.*; /** * Created by mahdi on 12/11/13. */ public class CallBrowser extends AbstractLookup { @Named("callTable.edit") protected Action editAction; @Inject protected GroupTable callTable; @Inject protected GroupDatasource<Call, UUID> callDs; @Inject protected WebFilter genericFilter; @Inject private java.util.List<CardInfo> infoList; @Inject protected ResolutionsFrame callFrame; @Inject protected ResolutionsFrame resolutionsFrame; @Inject protected CheckBox hideResolutions; @Inject protected PopupButton createButton; @Inject protected TaskmanService taskman_TaskmanService; @Inject protected CardService docflow_CardService; protected List<Card> cards; protected CardTreeFrame cardTreeFrame; private boolean isTemplate; protected String entityName; protected CheckBox showResolutions; protected Tabsheet tabsheet; protected CreateAction createAction; private static final String HIDE_RESOLUTIONS = "hideResolutions"; public CallBrowser(IFrame frame) { super(frame); entityName = MetadataProvider.getSession().getClass(MetadataProvider.getReplacedClass(Call.class)) .getName(); } @Override public void init(Map<String, Object> params) { super.init(params); //? ? ? : callTable.setMultiSelect(true); isTemplate = false; TableActionsHelper helper = new TableActionsHelper(this, callTable); helper.createRefreshAction(); final Action removeAction = callTable.getAction("remove"); final TaskmanService taskmanService = ServiceLocator.lookup(TaskmanService.NAME); callDs.addListener(new CollectionDsListenerAdapter() { @Override public void itemChanged(Datasource ds, Entity prevItem, Entity item) { super.itemChanged(ds, prevItem, item); if (editAction != null && editAction.getOwner() != null) ((Button) editAction.getOwner()).setEnabled(item != null); if (item == null) return; // ADMINISTRATOR_ROLE can remove any task, the CREATOR, // NOT INITIATOR only not sent on process Card card = (Card) ds.getItem(); User subCreator = card.getSubstitutedCreator(); User currentUser = UserSessionClient.getUserSession().getCurrentOrSubstitutedUser(); Set<Card> selected = callTable.getSelected(); boolean allowRemove = true; if (selected.size() > 1) { for (Card c : selected) { if (taskmanService.isCurrentUserAdministrator()) { break; } else if (!(currentUser.equals(c.getSubstitutedCreator()) && (StringUtils.isBlank(c.getState()) || WfUtils.isCardInState(c, "New")))) { allowRemove = false; break; } } removeAction.setEnabled(allowRemove); if (removeAction.getOwner() != null) ((Button) removeAction.getOwner()).setEnabled(allowRemove); } else { allowRemove = taskmanService.isCurrentUserAdministrator() || (currentUser.equals(subCreator) && (StringUtils.isBlank(((Card) ds.getItem()).getState()) || WfUtils.isCardInState((Card) ds.getItem(), "New"))); removeAction.setEnabled(allowRemove); if (removeAction.getOwner() != null) ((Button) removeAction.getOwner()).setEnabled(allowRemove); } if ((showResolutions != null) && BooleanUtils.isTrue((Boolean) showResolutions.getValue()) && (item == null || callTable.getSelected().size() < 2)) { String currentTab = tabsheet.getTab().getName(); if (currentTab.equals("resolutionsTab") && resolutionsFrame != null) resolutionsFrame.setCard((Card) item); if (currentTab.equals("hierarchyTab") && cardTreeFrame != null) cardTreeFrame.setCard((Card) item); } } @Override public void stateChanged(Datasource ds, Datasource.State prevState, Datasource.State state) { if (removeAction != null && removeAction.getOwner() != null) ((Button) removeAction.getOwner()) .setEnabled(Datasource.State.VALID.equals(state) && ds.getItem() != null); if (editAction != null && editAction.getOwner() != null) ((Button) editAction.getOwner()) .setEnabled(Datasource.State.VALID.equals(state) && ds.getItem() != null); } @Override public void collectionChanged(CollectionDatasource ds, Operation operation) { refresh(); } }); callTable.getDatasource().addListener(new CollectionDsListenerAdapter() { public void collectionChanged(CollectionDatasource ds, CollectionDatasourceListener.Operation operation) { loadCardInfoList(); } }); callTable.addAction(new AbstractAction("createDoc") { public void actionPerform(Component component) { Doc docPattern = (Doc) getDsContext().get("docsDs").getItem(); if (docPattern != null) { LoadContext loadContext = new LoadContext(docPattern.getClass()); loadContext.setId(docPattern.getId()); loadContext.setView("copy"); docPattern = ServiceLocator.getDataService().load(loadContext); Doc doc; try { doc = docPattern.getClass().newInstance(); } catch (Exception e) { throw new RuntimeException(e); } doc.copyFrom(docPattern); NumerationService ns = ServiceLocator.lookup(NumerationService.NAME); if (StringUtils.isBlank(docPattern.getNumber()) && doc.getDocKind() != null && NumeratorType.ON_CREATE.equals(doc.getDocKind().getNumeratorType())) { String num = ns.getNextNumber(doc); if (num != null) doc.setNumber(num); } doc.setCreateDate(TimeProvider.currentTimestamp()); doc.setTemplate(false); doc.setCreator(UserSessionClient.getUserSession().getUser()); doc.setSubstitutedCreator(UserSessionClient.getUserSession().getCurrentOrSubstitutedUser()); Map<String, Object> params = new HashMap<String, Object>(); params.put("justCreated", true); params.put("initialTemplate", docPattern); Window editor = openEditor(entityName + ".edit", doc, WindowManager.OpenType.THIS_TAB, params); editor.addListener(new CloseListener() { public void windowClosed(String actionId) { // refresh browser regardless of actionId as the new document // could be saved by DocCreator refresh(); } }); } else { showNotification(getMessage("selectDocPattern.msg"), IFrame.NotificationType.HUMANIZED); } } @Override public String getCaption() { return getMessage("actions.createDoc"); } @Override public boolean isVisible() { return super.isVisible() && isTemplate; } }); if (createButton != null) { // ? ? // . ?? ? ? //? ? createButton.setEnabled(UserSessionProvider.getUserSession().isEntityOpPermitted(callDs.getMetaClass(), EntityOp.CREATE)); // ?? " " createButton.addAction(new CreateAction(callTable) { // ? ? @Override public String getCaption() { final String messagesPackage = getMessagesPack(); return MessageProvider.getMessage(messagesPackage, "actions.CreateNew"); } }); // ?? " ?? " createButton.addAction(new CopyAction()); } // ?, ? ?? ? ? ?? ? // ? , ?? ??. callTable.addAction(new RemoveCardNullChildAction("remove", this, callTable)); callTable.addAction(new EditAction()); callTable.addAction(new RefreshAction(callTable)); callTable.addAction(new ThesisExcelAction(callTable, new WebExportDisplay(), genericFilter)); // ? ? callTable.addAction(new DeleteNotification()); cards = docflow_CardService.getCardsForCurrentUserActor(); // ? ? ?? ? //? ? initTableColoring(); callDs.addListener(new DsListenerAdapter() { @Override public void stateChanged(Datasource ds, Datasource.State prevState, Datasource.State state) { super.stateChanged(ds, prevState, state); if (Datasource.State.VALID.equals(state)) { loadCardInfoList(); } refresh(); } }); final Card exclItem = (Card) params.get("exclItem"); if (exclItem != null) { this.setLookupValidator(new Window.Lookup.Validator() { public boolean validate() { Card selectedCard = callTable.getSingleSelected(); CardService cardService = ServiceLocator.lookup(CardService.NAME); if (selectedCard != null && cardService.isDescendant(exclItem, selectedCard, MetadataProvider.getViewRepository().getView(Card.class, "_minimal"), "parentCard")) { showNotification(MessageProvider.getMessage(CallBrowser.class, "cardIsChild"), IFrame.NotificationType.WARNING); return false; } return true; } }); } addCommentColumn(); addHasAttachmentColumn(); refresh(); } protected void addHasAttachmentColumn() { MetaPropertyPath pp = callDs.getMetaClass().getPropertyPath("hasAttachments"); com.vaadin.ui.Table vTable = (com.vaadin.ui.Table) WebComponentsHelper.unwrap(callTable); vTable.removeGeneratedColumn(pp); vTable.addGeneratedColumn(pp, new com.vaadin.ui.Table.ColumnGenerator() { public com.vaadin.ui.Component generateCell(com.vaadin.ui.Table source, Object itemId, Object columnId) { Doc doc = callDs.getItem((UUID) itemId); if (doc.getHasAttachments() != null && doc.getHasAttachments()) { return new com.vaadin.ui.Embedded("", new ThemeResource("icons/attachment-small.png")); } return null; } }); } protected void refresh() { // ? callDs.refresh(); //callDs.getDsContext().refresh(); /* callTable.getDatasource().getDsContext().refresh(); callTable.getDatasource().refresh(); callTable.refresh(); */ callTable.getDatasource().refresh(); loadCardInfoList(); } // protected void loadCardInfoList() { LoadContext lc = new LoadContext(CardInfo.class); LoadContext.Query q = lc.setQueryString("select ci from wf$CardInfo ci where ci.user.id" + " = :userId"); q.addParameter("userId", UserSessionProvider.getUserSession().getCurrentOrSubstitutedUser()); lc.setView("card-browse"); infoList = ServiceLocator.getDataService().loadList(lc); } // ?, ? //? ?? protected void initTableColoring() { com.vaadin.ui.Table vTable = (com.vaadin.ui.Table) WebComponentsHelper.unwrap(callTable); vTable.setCellStyleGenerator(new com.vaadin.ui.Table.CellStyleGenerator() { public String getStyle(Object itemId, Object propertyId) { if (propertyId == null) { if (!(itemId instanceof UUID)) return ""; Call call = callDs.getItem((UUID) itemId); return getTableCellStyle(call); } return ""; } }); } protected String getTableCellStyle(Card card) { if (infoList != null) { if (WfUtils.isCardInState(card, "Obrabotan")) { return "taskfinished"; } for (CardInfo cardInfo : infoList) { if (cardInfo.getCard().getId().equals(card.getId()) && cardInfo.getDeleteTs() == null) { return "taskremind"; } } } return ""; } protected class EditAction extends AbstractAction { protected EditAction() { super("edit"); } @Override public String getCaption() { final String messagesPackage = AppConfig.getMessagesPack(); //? ? ?? , // ?? if (UserSessionProvider.getUserSession().isEntityOpPermitted(callDs.getMetaClass(), EntityOp.UPDATE)) return MessageProvider.getMessage(messagesPackage, "actions.Edit"); // ?? "?" else return MessageProvider.getMessage(messagesPackage, "actions.View"); } @Override public void actionPerform(Component component) { final Set selected = callTable.getSelected(); if (selected.size() == 1) { Call resolution = callDs.getItem(); CloseListener listener = new CloseListener() { public void windowClosed(String actionId) { // ? // ?? ? refresh(); } }; UserSettingService uss = ServiceLocator.lookup(UserSettingService.NAME); WindowManager.OpenType openType = "newTab".equals(uss.loadSetting("openEditorMode")) ? WindowManager.OpenType.NEW_TAB : WindowManager.OpenType.THIS_TAB; String type = ""; if (!isTemplate) type = ".edit"; else type = ".templateEdit"; Window window = frame.openEditor(entityName + type, resolution, openType, Collections.<String, Object>singletonMap("closeListener", listener)); window.addListener(listener); } } } /** Apply user settings to all components of this window */ @Override public void applySettings(Settings settings) { boolean isLookup = (getFrame() instanceof Window.Lookup); if (!isLookup) { super.applySettings(settings); } initAfterSetLookup(isLookup); callTable.removeAction(callTable.getAction("refresh")); callTable.removeAction(callTable.getAction("excel")); } private void initAfterSetLookup(boolean isLookup) { final User user = UserSessionClient.getUserSession().getCurrentOrSubstitutedUser(); SplitPanel splitPanel = getComponent("split"); splitPanel.setSplitPosition(100); splitPanel.setLocked(true); if (isLookup) { callTable.setMultiSelect(false); } else if (!isTemplate) { // final HashMap<UUID, com.vaadin.ui.Component> statesMap = new HashMap<UUID, com.vaadin.ui.Component>(); final CardService cardService = ServiceLocator.lookup(CardService.NAME); addLocStateColumn(); resolutionsFrame = getComponent("resolutionsFrame"); resolutionsFrame.init(); cardTreeFrame = getComponent("cardTreeFrame"); Map<String, Object> params = new HashMap<String, Object>(); params.put("card", null); cardTreeFrame.init(params); showResolutions = getComponent(HIDE_RESOLUTIONS); final SplitPanel split = getComponent("split"); showResolutions.addListener(new ValueListener() { public void valueChanged(Object source, String property, Object prevValue, Object value) { boolean showResolutionsValue = BooleanUtils.isTrue((Boolean) value); int pos = (!showResolutionsValue ? 100 : 60); split.setSplitPosition(pos); split.setLocked(!showResolutionsValue); Card card = (Card) callTable.getSingleSelected(); if (showResolutionsValue && card != null) { String currentTab = tabsheet.getTab().getName(); if (currentTab.equals("resolutionsTab")) resolutionsFrame.setCard(card); if (currentTab.equals("hierarchyTab")) cardTreeFrame.setCard(card); } } }); String value = getSettings().get(HIDE_RESOLUTIONS).attributeValue("value"); showResolutions.setValue(value == null ? false : BooleanUtils.toBoolean(value)); } else { SplitPanel split = getComponent("split"); split.setSplitPosition(100); split.setLocked(true); } } protected void addLocStateColumn() { MetaPropertyPath pp = callDs.getMetaClass().getPropertyEx("locState"); com.vaadin.ui.Table vTable = (com.vaadin.ui.Table) WebComponentsHelper.unwrap(callTable); vTable.removeGeneratedColumn(pp); vTable.addGeneratedColumn(pp, new com.vaadin.ui.Table.ColumnGenerator() { public com.vaadin.ui.Component generateCell(com.vaadin.ui.Table source, Object itemId, Object columnId) { UUID uuid = (UUID) itemId; com.vaadin.ui.Component component; Doc doc = callDs.getItem(uuid); boolean containsCard = cards != null ? cards.contains(doc) : false; if (doc != null && !WfUtils.isCardInStateList(doc, "Finished", "Canceled", "Obrabotan") && (containsCard || (!containsCard && WfUtils.isCardInState(doc, "New")))) { final PopupButton popupButton = new WebPopupButton(); popupButton.setCaption(callDs.getItem((UUID) itemId).getLocState()); int a = callTable.getSelected().size(); popupButton.addAction(new AbstractAction("onChange") { public void actionPerform(Component component) { if (callTable.getSelected().size() >= 1) { popupButton.setEnabled(false); } else popupButton.setEnabled(true); } }); component = WebComponentsHelper.unwrap(popupButton); ((org.vaadin.hene.popupbutton.PopupButton) component) .addListener(createProcessMenuBuilder(doc, callTable, popupButton)); component.addStyleName("link"); component.addStyleName("dashed"); } else { component = new com.vaadin.ui.Label(doc == null ? "" : doc.getLocState(), com.vaadin.ui.Label.CONTENT_XHTML); } component.setWidth("-1px"); return component; } }); } /* private void initAfterSetLookup(boolean isLookup) { //? ? ? ? ? ?? ?? // ? (SplitPanel) ???? 100% //??? ? ? if (isLookup) { SplitPanel split = getComponent("split"); split.setSplitPosition(100); split.setLocked(true); callTable.setMultiSelect(false); } // ??? ? else { ((com.vaadin.ui.Table) WebComponentsHelper.unwrap(callTable)).addGeneratedColumn(callDs.getMetaClass().getPropertyPath("locState"), new com.vaadin.ui.Table.ColumnGenerator() { public com.vaadin.ui.Component generateCell(com.vaadin.ui.Table source, Object itemId, Object columnId) { UUID uuid = (UUID) itemId; com.vaadin.ui.Component component; Doc doc = callDs.getItem(uuid); boolean containsCard = cards != null ? cards.contains(doc) : false; if (doc != null && !WfUtils.isCardInStateList(doc, "Finished", "Canceled") && (containsCard || (!containsCard && WfUtils.isCardInState(doc, "New")))) { //?? , ???? ?? ? ? //? ?? final PopupButton popupButton = new WebPopupButton(); // ?? ??? popupButton.setCaption(callDs.getItem((UUID) itemId).getLocState()); component = WebComponentsHelper.unwrap(popupButton); ((org.vaadin.hene.popupbutton.PopupButton) component).addListener(new ProcessMenuBuilderAction(doc, callTable, popupButton)); component.addStyleName("link"); component.addStyleName("dashed"); } else { component = new com.vaadin.ui.Label(doc == null ? "" : doc.getLocState(), com.vaadin.ui.Label.CONTENT_XHTML); } component.setWidth("-1px"); return component; } }); //? ? final SplitPanel split = getComponent("split"); // ??, ? ? ?? ? " ?" /*hideResolutions.addListener(new ValueListener() { public void valueChanged(Object source, String property, Object prevValue, Object value) { boolean hideResolutionsValue = BooleanUtils.isTrue((Boolean) value); int pos = (hideResolutionsValue ? 100 : 60); split.setSplitPosition(pos); split.setLocked(hideResolutionsValue); Card card = (Card) callTable.getSingleSelected(); } }); String value = getSettings().get("hideResolutions").attributeValue("value"); hideResolutions.setValue(value == null ? true : BooleanUtils.toBoolean(value)); } } */ protected void addCommentColumn() { MetaPropertyPath pp = callDs.getMetaClass().getPropertyPath("comment"); com.vaadin.ui.Table vTable = (com.vaadin.ui.Table) WebComponentsHelper.unwrap(callTable); vTable.removeGeneratedColumn(pp); vTable.addGeneratedColumn(pp, new com.vaadin.ui.Table.ColumnGenerator() { public com.vaadin.ui.Component generateCell(com.vaadin.ui.Table source, Object itemId, Object columnId) { UUID uuid = (UUID) itemId; com.vaadin.ui.Component component; Doc doc = callDs.getItem(uuid); String descr = doc.getComment(); int enterIdx = descr != null ? (descr.length() > 40 ? 40 : descr.indexOf('\n')) : -1; //? ?? if (enterIdx != -1) { com.vaadin.ui.TextField content = new com.vaadin.ui.TextField(null, descr); content.setReadOnly(true); content.setWidth("300px"); content.setHeight("300px"); component = new com.vaadin.ui.PopupView("<span>" + descr.substring(0, enterIdx) + "...</span>", content); component.addStyleName("longtext"); } else { component = new com.vaadin.ui.Label(descr == null ? "" : descr); } component.setWidth("-1px"); return component; } }); } protected class DeleteNotification extends AbstractAction { private static final long serialVersionUID = -4530817747247184231L; protected DeleteNotification() { super("deleteNotification"); } public void actionPerform(Component component) { Set selected = callTable.getSelected(); if (selected.size() != 1) return; WfService wfService = ServiceLocator.lookup(WfService.NAME); User user = UserSessionProvider.getUserSession().getCurrentOrSubstitutedUser(); wfService.deleteNotifications(callDs.getItem(), user); refresh(); // ((DocflowAppWindow) App.getInstance().getAppWindow()).reloadAppFolders(new ArrayList(selected)); } } protected class CopyAction extends AbstractAction { protected CopyAction() { super("copy"); } @Override public String getCaption() { return MessageProvider.getMessage(getClass(), "actions.Copy"); } // ?, ? ? ? // ? @Override public boolean isEnabled() { return super.isEnabled() && UserSessionProvider.getUserSession() .isEntityOpPermitted(callDs.getMetaClass(), EntityOp.CREATE); } public void actionPerform(Component component) { // ? , // ? "" Call call = callDs.getItem(); if (call != null) { LoadContext loadContext = new LoadContext(call.getClass()); loadContext.setId(call.getId()); loadContext.setView("edit"); loadContext.setUseSecurityConstraints(false); call = ServiceLocator.getDataService().load(loadContext); Call doc; try { //? doc = call.getClass().newInstance(); doc.setTemplate(true); } catch (Exception e) { throw new RuntimeException(e); } // doc.copyFrom(call); doc.setName(call.getName()); doc.setPriority(call.getPriority()); doc.setExtClient(call.getExtClient()); doc.setCallDescription(call.getCallDescription()); doc.setNumber(call.getNumber()); doc.setFinishDatePlan(call.getFinishDatePlan()); doc.setConfirmRequired(call.getConfirmRequired()); doc.setReassignEnabled(call.getReassignEnabled()); doc.setRefuseEnabled(call.getRefuseEnabled()); doc.setCreator(UserSessionProvider.getUserSession().getUser()); doc.setSubstitutedCreator(UserSessionProvider.getUserSession().getCurrentOrSubstitutedUser()); Map<String, Object> params = new java.util.HashMap<String, Object>(); params.put("justCreated", true); Window window = openEditor(entityName + ".edit", doc, WindowManager.OpenType.THIS_TAB, params); window.addListener(new Window.CloseListener() { public void windowClosed(String actionId) { if (Window.COMMIT_ACTION_ID.equals(actionId)) { callDs.refresh(); } } }); } } } protected ProcessMenuBuilderAction createProcessMenuBuilder(Doc doc, GroupTable docsTable, PopupButton popupButton) { return new ProcessMenuBuilderAction(doc, docsTable, popupButton); } }