Java tutorial
/** * This file is part of Jahia, next-generation open source CMS: * Jahia's next-generation, open source CMS stems from a widely acknowledged vision * of enterprise application convergence - web, search, document, social and portal - * unified by the simplicity of web content management. * * For more information, please visit http://www.jahia.com. * * Copyright (C) 2002-2012 Jahia Solutions Group SA. All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * As a special exception to the terms and conditions of version 2.0 of * the GPL (or any later version), you may redistribute this Program in connection * with Free/Libre and Open Source Software ("FLOSS") applications as described * in Jahia's FLOSS exception. You should have received a copy of the text * describing the FLOSS exception, and it is also available here: * http://www.jahia.com/license * * Commercial and Supported Versions of the program (dual licensing): * alternatively, commercial and supported versions of the program may be used * in accordance with the terms and conditions contained in a separate * written agreement between you and Jahia Solutions Group SA. * * If you are unsure which license is appropriate for your use, * please contact the sales department at sales@jahia.com. */ package org.jahia.ajax.gwt.client.widget.subscription; import com.extjs.gxt.ui.client.Style; import com.extjs.gxt.ui.client.Style.HorizontalAlignment; import com.extjs.gxt.ui.client.Style.SortDir; import com.extjs.gxt.ui.client.data.BasePagingLoader; import com.extjs.gxt.ui.client.data.PagingLoadConfig; import com.extjs.gxt.ui.client.data.PagingLoadResult; import com.extjs.gxt.ui.client.data.RpcProxy; import com.extjs.gxt.ui.client.event.*; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.widget.*; import com.extjs.gxt.ui.client.widget.button.Button; import com.extjs.gxt.ui.client.widget.form.AdapterField; import com.extjs.gxt.ui.client.widget.form.FormPanel; import com.extjs.gxt.ui.client.widget.form.FormPanel.Encoding; import com.extjs.gxt.ui.client.widget.form.FormPanel.Method; import com.extjs.gxt.ui.client.widget.grid.*; import com.extjs.gxt.ui.client.widget.layout.FitData; import com.extjs.gxt.ui.client.widget.layout.FitLayout; import com.extjs.gxt.ui.client.widget.toolbar.PagingToolBar; import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem; import com.extjs.gxt.ui.client.widget.toolbar.ToolBar; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.FileUpload; import org.jahia.ajax.gwt.client.core.JahiaGWTParameters; import org.jahia.ajax.gwt.client.data.GWTJahiaGroup; import org.jahia.ajax.gwt.client.data.GWTJahiaUser; import org.jahia.ajax.gwt.client.messages.Messages; import org.jahia.ajax.gwt.client.service.subscription.SubscriptionService; import org.jahia.ajax.gwt.client.service.subscription.SubscriptionServiceAsync; import org.jahia.ajax.gwt.client.util.icons.ToolbarIconProvider; import org.jahia.ajax.gwt.client.widget.Linker; import org.jahia.ajax.gwt.client.widget.contentengine.EngineContainer; import org.jahia.ajax.gwt.client.widget.usergroup.UserGroupAdder; import org.jahia.ajax.gwt.client.widget.usergroup.UserGroupSelect; import java.util.ArrayList; import java.util.List; /** * Represents a widget for managing e.g. newsletter subscriptions. * * @author Sergiy Shyrkov */ public class SubscriptionManager extends LayoutContainer { private class ImportWindow extends Window { public ImportWindow() { super(); setHeading(Messages.get("label.import", "Import")); setSize(400, 150); setResizable(true); setModal(true); } @Override protected void onRender(Element parent, int pos) { super.onRender(parent, pos); setStyleAttribute("margin", "10px"); final FormPanel panel = new FormPanel(); panel.setHeaderVisible(false); panel.setFrame(false); panel.setBorders(false); panel.setAction( (JahiaGWTParameters.getServiceEntryPoint() != null ? JahiaGWTParameters.getServiceEntryPoint() : "/gwt/") + "fileupload"); panel.setEncoding(Encoding.MULTIPART); panel.setMethod(Method.POST); panel.setButtonAlign(HorizontalAlignment.CENTER); panel.setLabelWidth(75); panel.setWidth(390); panel.setHeight(80); final FileUpload file = new FileUpload(); file.setName("asyncupload"); file.setWidth("300px"); AdapterField adapter = new AdapterField(file); adapter.setFieldLabel(Messages.get("fileMenu.label", "File")); panel.add(adapter); final Window theWindor = this; Button btn = new Button(Messages.get("label.cancel", "Cancel")); btn.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { theWindor.hide(); } }); panel.addButton(btn); btn = new Button(Messages.get("label.doImport", "Import")); btn.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { if (file.getFilename() == null || file.getFilename().trim().length() == 0) { return; } try { panel.submit(); } catch (Exception e) { panel.unmask(); MessageBox.alert(Messages.get("label.error", "Error"), e.getMessage(), null); } } }); panel.addButton(btn); panel.addListener(Events.BeforeSubmit, new Listener<FormEvent>() { public void handleEvent(FormEvent formEvent) { panel.mask(Messages.get("label.loading", "Loading...")); } }); panel.addListener(Events.Submit, new Listener<FormEvent>() { public void handleEvent(FormEvent formEvent) { String result = formEvent.getResultHtml(); String fileKey = null; if (result != null && result.contains(" key=\"")) { result = result.substring(result.indexOf(" key=\"") + " key=\"".length()); fileKey = result.indexOf("\"") != -1 ? result.substring(0, result.indexOf("\"")) : null; } if (fileKey != null) { doImport(theWindor, fileKey); } else { MessageBox.alert(Messages.get("label.error", "Error"), Messages.get("failure.upload", "Upload of the file failed"), null); } } }); add(panel); } } private abstract class SubscriptionAsyncCallback<T> implements AsyncCallback<T> { public void onFailure(Throwable caught) { MessageBox.alert(Messages.get("label.error", "Error"), caught.getMessage(), null); loader.load(); } } private static final int ITEMS_PER_PAGE = 20; private Button btnRemove; private Button btnResume; private Button btnSuspend; private Grid<GWTSubscription> grid; private BasePagingLoader<PagingLoadResult<GWTSubscription>> loader; private SubscriptionServiceAsync service; private String source; private Linker linker; private EngineContainer container; /** * Initializes an instance of this class. * */ public SubscriptionManager(String nodeIdentifier, Linker linker, EngineContainer engineContainer) { super(); this.source = nodeIdentifier; this.linker = linker; setLayout(new FitLayout()); this.container = engineContainer; container.setEngine(this, Messages.get("label.subscriptionManager", "Subscription Manager"), null, linker); } private BasePagingLoader<PagingLoadResult<GWTSubscription>> createDataLoader() { // data proxy RpcProxy<PagingLoadResult<GWTSubscription>> proxy = new RpcProxy<PagingLoadResult<GWTSubscription>>() { @Override protected void load(Object loadConfig, AsyncCallback<PagingLoadResult<GWTSubscription>> callback) { service.getSubscriptions(source, (PagingLoadConfig) loadConfig, callback); } }; final BasePagingLoader<PagingLoadResult<GWTSubscription>> loader = new BasePagingLoader<PagingLoadResult<GWTSubscription>>( proxy); loader.setRemoteSort(true); loader.setSortField("subscriber"); loader.setSortDir(SortDir.ASC); loader.setLimit(ITEMS_PER_PAGE); return loader; } private Grid<GWTSubscription> createGrid(BasePagingLoader<PagingLoadResult<GWTSubscription>> loader) { ListStore<GWTSubscription> store = new ListStore<GWTSubscription>(loader); final CheckBoxSelectionModel<GWTSubscription> sm = new CheckBoxSelectionModel<GWTSubscription>(); sm.addSelectionChangedListener(new SelectionChangedListener<GWTSubscription>() { @Override public void selectionChanged(SelectionChangedEvent<GWTSubscription> se) { updateToolbar(se.getSelection()); } }); final String msgYes = Messages.get("label.yes", "yes").toLowerCase(); final String msgNo = Messages.get("label.no", "no").toLowerCase(); List<ColumnConfig> columns = new ArrayList<ColumnConfig>(); columns.add(sm.getColumn()); ColumnConfig column = new ColumnConfig(); column.setId("id"); column.setHidden(true); columns.add(column); columns.add(new ColumnConfig("subscriber", Messages.get("label.subscriber", "Subscriber"), 140)); column = new ColumnConfig("lastName", Messages.get("org.jahia.admin.lastName.label", "Last name"), 140); column.setSortable(false); columns.add(column); column = new ColumnConfig("firstName", Messages.get("org.jahia.admin.firstName.label", "First name"), 140); column.setSortable(false); columns.add(column); column = new ColumnConfig("email", Messages.get("label.email", "Email"), 200); column.setSortable(false); columns.add(column); column = new ColumnConfig("provider", Messages.get("column.provider.label", "Provider"), 70); column.setAlignment(HorizontalAlignment.CENTER); columns.add(column); column = new ColumnConfig("confirmed", Messages.get("label.confirmed", "Confirmed"), 60); column.setRenderer(new GridCellRenderer<GWTSubscription>() { public Object render(GWTSubscription model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<GWTSubscription> store, Grid<GWTSubscription> grid) { return (Boolean) model.get(property) ? msgYes : "<span style='color:red'>" + msgNo + "</span>"; } }); column.setAlignment(HorizontalAlignment.CENTER); columns.add(column); column = new ColumnConfig("suspended", Messages.get("label.suspended", "Suspended"), 80); column.setRenderer(new GridCellRenderer<GWTSubscription>() { public Object render(GWTSubscription model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<GWTSubscription> store, Grid<GWTSubscription> grid) { return (Boolean) model.get(property) ? "<span style='color:red'>" + msgYes + "</span>" : msgNo; } }); column.setAlignment(HorizontalAlignment.CENTER); columns.add(column); Grid<GWTSubscription> grid = new Grid<GWTSubscription>(store, new ColumnModel(columns)); grid.setLoadMask(true); grid.setBorders(true); grid.setSelectionModel(sm); grid.addPlugin(sm); return grid; } private ToolBar createTopToolBar(final BasePagingLoader<PagingLoadResult<GWTSubscription>> loader) { final ToolBar toolBar = new ToolBar(); Button btn = new Button(Messages.get("label.add", "Add"), new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { doAdd(); } }); btn.setIcon(ToolbarIconProvider.getInstance().getIcon("newAction")); toolBar.add(btn); btnRemove = new Button(Messages.get("label.remove", "Remove"), new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { MessageBox.confirm(Messages.get("label.remove", "Remove"), Messages.getWithArgs("message.subscriptions.removeConfirm", "Do you really want to permanemtly remove {0} subscriptions?", new Object[] { String.valueOf(grid.getSelectionModel().getSelectedItems().size()) }), new Listener<MessageBoxEvent>() { public void handleEvent(MessageBoxEvent be) { if (Dialog.YES.equalsIgnoreCase(be.getButtonClicked().getText())) { doRemove(); } } }); } }); btnRemove.setIcon(ToolbarIconProvider.getInstance().getIcon("delete")); btnRemove.setEnabled(false); toolBar.add(btnRemove); toolBar.add(new SeparatorToolItem()); btnSuspend = new Button(Messages.get("label.suspend", "Suspend"), new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { MessageBox.confirm(Messages.get("label.suspend", "Suspend"), Messages.getWithArgs("message.subscriptions.suspendConfirm", "Do you really want to suspend {0} subscription(s)?", new Object[] { String.valueOf(grid.getSelectionModel().getSelectedItems().size()) }), new Listener<MessageBoxEvent>() { public void handleEvent(MessageBoxEvent be) { if (Dialog.YES.equalsIgnoreCase(be.getButtonClicked().getText())) { doSuspend(); } } }); } }); btnSuspend.setIcon(ToolbarIconProvider.getInstance().getIcon("suspend")); btnSuspend.setEnabled(false); toolBar.add(btnSuspend); btnResume = new Button(Messages.get("label.resume", "Resume"), new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { MessageBox.confirm(Messages.get("label.resume", "Resume"), Messages.getWithArgs( "message.subscriptions.resumeConfirm", "Do you really want to resume {0} subscription(s)?", new Object[] { String.valueOf(grid.getSelectionModel().getSelectedItems().size()) }), new Listener<MessageBoxEvent>() { public void handleEvent(MessageBoxEvent be) { if (Dialog.YES.equalsIgnoreCase(be.getButtonClicked().getText())) { doResume(); } } }); } }); btnResume.setIcon(ToolbarIconProvider.getInstance().getIcon("resume")); btnResume.setEnabled(false); toolBar.add(btnResume); toolBar.add(new SeparatorToolItem()); btn = new Button(Messages.get("label.import", "Import"), new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { new ImportWindow().show(); } }); btn.setIcon(ToolbarIconProvider.getInstance().getIcon("import")); toolBar.add(btn); toolBar.add(new SeparatorToolItem()); return toolBar; } private void doAdd() { new UserGroupSelect(new UserGroupAdder() { public void addGroups(List<GWTJahiaGroup> groups) { // do nothing } public void addUsers(List<GWTJahiaUser> users) { service.subscribe(source, users, new SubscriptionAsyncCallback<Void>() { public void onSuccess(Void result) { loader.load(); } }); } }, UserGroupSelect.VIEW_USERS, "currentSite"); } private void doImport(final Window window, String fileKey) { service.subscribe(source, fileKey, new SubscriptionAsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { window.hide(); super.onFailure(caught); } public void onSuccess(Void result) { window.hide(); MessageBox.info(Messages.get("label.import", "Import"), Messages.get("message.success", "Operation successfully completed"), null); loader.load(); } }); } private void doRemove() { final List<GWTSubscription> toRemove = grid.getSelectionModel().getSelectedItems(); service.cancel(toRemove, new SubscriptionAsyncCallback<Void>() { public void onSuccess(Void result) { for (GWTSubscription subscriber : toRemove) { grid.getStore().remove(subscriber); } loader.load(); } }); } private void doResume() { final List<GWTSubscription> toResume = grid.getSelectionModel().getSelectedItems(); service.resume(toResume, new SubscriptionAsyncCallback<Void>() { public void onSuccess(Void result) { for (GWTSubscription subscriber : toResume) { if (subscriber.isSuspended()) { subscriber.setSuspended(false); grid.getStore().update(subscriber); } } updateToolbar(grid.getSelectionModel().getSelectedItems()); } }); } private void doSuspend() { final List<GWTSubscription> toSuspend = grid.getSelectionModel().getSelectedItems(); service.suspend(toSuspend, new SubscriptionAsyncCallback<Void>() { public void onSuccess(Void result) { for (GWTSubscription subscriber : toSuspend) { if (!subscriber.isSuspended()) { subscriber.setSuspended(true); grid.getStore().update(subscriber); } } updateToolbar(grid.getSelectionModel().getSelectedItems()); } }); } @Override protected void onRender(Element parent, int pos) { super.onRender(parent, pos); service = SubscriptionService.App.getInstance(); loader = createDataLoader(); loader.load(); // main component grid = createGrid(loader); ContentPanel panel = new ContentPanel(new FitLayout()); panel.setFrame(true); panel.setHeaderVisible(false); panel.setCollapsible(false); panel.add(grid, new FitData()); // top toolbar panel.setTopComponent(createTopToolBar(loader)); // bottom toolbar final PagingToolBar bottomToolBar = new PagingToolBar(ITEMS_PER_PAGE); bottomToolBar.bind(loader); panel.setBottomComponent(bottomToolBar); Button cancel = new Button(Messages.get("label.close", "Close"), new SelectionListener<ButtonEvent>() { public void componentSelected(ButtonEvent event) { container.closeEngine(); } }); panel.addButton(cancel); panel.setButtonAlign(Style.HorizontalAlignment.CENTER); add(panel); } private void updateToolbar(List<GWTSubscription> currentSelection) { if (currentSelection.isEmpty()) { btnRemove.setEnabled(false); btnResume.setEnabled(false); btnSuspend.setEnabled(false); } else { btnRemove.setEnabled(true); btnResume.setEnabled(false); btnSuspend.setEnabled(false); for (GWTSubscription subscr : currentSelection) { if (subscr.isSuspended()) { btnResume.setEnabled(true); break; } } for (GWTSubscription subscr : currentSelection) { if (!subscr.isSuspended()) { btnSuspend.setEnabled(true); break; } } } } }