/**
*
* geo-platform
* Rich webgis framework
* http://geo-platform.org
* ====================================================================
*
* Copyright (C) 2008-2017 geoSDI Group (CNR IMAA - Potenza - ITALY).
*
* 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 3 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, see http://www.gnu.org/licenses/
*
* ====================================================================
*
* Linking this library statically or dynamically with other modules is
* making a combined work based on this library. Thus, the terms and
* conditions of the GNU General Public License cover the whole combination.
*
* As a special exception, the copyright holders of this library give you permission
* to link this library with independent modules to produce an executable, regardless
* of the license terms of these independent modules, and to copy and distribute
* the resulting executable under terms of your choice, provided that you also meet,
* for each linked independent module, the terms and conditions of the license of
* that module. An independent module is a module which is not derived from or
* based on this library. If you modify this library, you may extend this exception
* to your version of the library, but you are not obligated to do so. If you do not
* wish to do so, delete this exception statement from your version.
*/
package org.geosdi.geoplatform.gui.client.widget.components.filters.container;
import com.extjs.gxt.ui.client.Style;
import com.extjs.gxt.ui.client.data.*;
import com.extjs.gxt.ui.client.event.*;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.form.FieldSet;
import com.extjs.gxt.ui.client.widget.grid.*;
import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
import com.extjs.gxt.ui.client.widget.layout.FormLayout;
import com.extjs.gxt.ui.client.widget.tips.QuickTip;
import com.google.common.collect.Lists;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.HasRpcToken;
import com.google.gwt.user.client.rpc.RpcTokenException;
import com.google.gwt.user.client.rpc.XsrfToken;
import com.google.gwt.user.client.rpc.XsrfTokenServiceAsync;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.geosdi.geoplatform.gui.action.button.GPSecureButton;
import org.geosdi.geoplatform.gui.client.BasicWidgetResources;
import org.geosdi.geoplatform.gui.client.action.server.AddServerAction;
import org.geosdi.geoplatform.gui.client.action.server.DeleteServerAction;
import org.geosdi.geoplatform.gui.client.i18n.CatalogFinderConstants;
import org.geosdi.geoplatform.gui.client.puregwt.event.StatusWidgetEvent;
import org.geosdi.geoplatform.gui.client.puregwt.handler.LoadFirstServersHandler;
import org.geosdi.geoplatform.gui.client.service.GPCatalogFinderRemote;
import org.geosdi.geoplatform.gui.client.service.GPCatalogFinderRemoteAsync;
import org.geosdi.geoplatform.gui.client.widget.components.form.CSWServerFormWidget;
import org.geosdi.geoplatform.gui.client.widget.statusbar.GPCatalogStatusBar.GPCatalogStatusBarType;
import org.geosdi.geoplatform.gui.configuration.GPSecureStringTextField;
import org.geosdi.geoplatform.gui.configuration.action.event.ActionEnableEvent;
import org.geosdi.geoplatform.gui.configuration.message.GeoPlatformMessage;
import org.geosdi.geoplatform.gui.global.security.GPAccountLogged;
import org.geosdi.geoplatform.gui.impl.containers.pagination.grid.GridLayoutPaginationContainer;
import org.geosdi.geoplatform.gui.model.server.GPCSWServerBeanModel;
import org.geosdi.geoplatform.gui.model.server.GPCSWServerBeanModel.GPCSWServerKeyValue;
import org.geosdi.geoplatform.gui.puregwt.GPEventBus;
import org.geosdi.geoplatform.gui.responce.CatalogFinderBean;
import org.geosdi.geoplatform.gui.service.gwt.xsrf.GPXsrfTokenService;
import org.geosdi.geoplatform.gui.shared.GPTrustedLevel;
/**
*
* @author Giuseppe La Scaleia - CNR IMAA geoSDI Group
* @email giuseppe.lascaleia@geosdi.org
*/
@Singleton
public class CSWServerPaginationContainer
extends GridLayoutPaginationContainer<GPCSWServerBeanModel>
implements LoadFirstServersHandler {
private static final XsrfTokenServiceAsync xsrf = GPXsrfTokenService.Util.getInstance();
private static final GPCatalogFinderRemoteAsync catalogFinderRemote = GPCatalogFinderRemote.Util.getInstance();
//
private final CatalogFinderBean catalogFinder;
private final GPEventBus bus;
private final ActionEnableEvent enableEvent = new ActionEnableEvent(false);
//
private final CSWServerFormWidget serverForm;
private CheckBoxSelectionModel<GPCSWServerBeanModel> sm;
private GPSecureStringTextField searchField;
private GPSecureButton deleteServerButton;
@Inject
public CSWServerPaginationContainer(CatalogFinderBean theCatalogFinder,
GPEventBus theBus) {
super(true);
catalogFinder = theCatalogFinder;
bus = theBus;
serverForm = new CSWServerFormWidget(this, bus);
bus.addHandler(LoadFirstServersHandler.TYPE, this);
}
@Override
public void setGridProperties() {
super.widget.setSize(400, 350);
super.widget.setAutoExpandColumn(GPCSWServerKeyValue.ALIAS.toString());
super.panel.setLayout(new FlowLayout());
this.createSearchComponent();
this.createButtons();
super.widget.setSelectionModel(sm);
super.widget.addPlugin(sm);
// ADD URL tip
new QuickTip(super.widget);
}
private void createSearchComponent() {
searchField = new GPSecureStringTextField();
searchField.setFieldLabel(
CatalogFinderConstants.INSTANCE.CSWServerPaginationContainer_searchFieltLabelText());
searchField.addKeyListener(new KeyListener() {
@Override
public void componentKeyUp(ComponentEvent event) {
if (((event.getKeyCode() == KeyCodes.KEY_BACKSPACE)
|| (event.getKeyCode() == KeyCodes.KEY_DELETE))
&& (searchField.getValue() == null)) {
reset();
}
}
@Override
public void componentKeyPress(ComponentEvent event) {
if ((event.getKeyCode() == KeyCodes.KEY_ENTER)) {
loader.load(0, getPageSize());
}
}
});
FieldSet searchFieldSet = new FieldSet();
searchFieldSet.setBorders(false);
searchFieldSet.setSize(350, 40);
FormLayout layout = new FormLayout();
layout.setLabelWidth(80);
searchFieldSet.setLayout(layout);
searchFieldSet.add(searchField);
super.panel.add(searchFieldSet);
}
private void createButtons() {
super.panel.setButtonAlign(Style.HorizontalAlignment.CENTER);
GPSecureButton newServerButton = new GPSecureButton(CatalogFinderConstants.INSTANCE.
CSWServerPaginationContainer_newServerButtonText(),
new AddServerAction(GPTrustedLevel.NONE, this.serverForm));
newServerButton.setIcon(
AbstractImagePrototype.create(BasicWidgetResources.ICONS.done()));
newServerButton.setToolTip(CatalogFinderConstants.INSTANCE.
CSWServerPaginationContainer_newServerButtonTooltipText());
super.panel.addButton(newServerButton);
deleteServerButton = new GPSecureButton(CatalogFinderConstants.INSTANCE.
CSWServerPaginationContainer_deleteServerButtonText(),
new DeleteServerAction(GPTrustedLevel.HIGH, this));
deleteServerButton.setIcon(
AbstractImagePrototype.create(BasicWidgetResources.ICONS.delete()));
deleteServerButton.setToolTip(CatalogFinderConstants.INSTANCE.
CSWServerPaginationContainer_deleteServerButtonTooltipText());
super.panel.addButton(deleteServerButton);
deleteServerButton.disable();
}
@Override
public ColumnModel prepareColumnModel() {
List<ColumnConfig> configs = Lists.<ColumnConfig>newArrayList();
ColumnConfig aliasColumn = new ColumnConfig();
aliasColumn.setId(GPCSWServerKeyValue.ALIAS.toString());
aliasColumn.setHeaderHtml(CatalogFinderConstants.INSTANCE.
CSWServerPaginationContainer_aliasColumnHeaderText());
aliasColumn.setFixed(true);
aliasColumn.setResizable(false);
aliasColumn.setRenderer(new GridCellRenderer<GPCSWServerBeanModel>() {
@Override
public Object render(GPCSWServerBeanModel model, String property,
ColumnData config, int rowIndex, int colIndex,
ListStore<GPCSWServerBeanModel> store,
Grid<GPCSWServerBeanModel> grid) {
String url = model.getUrlServer();
return "<div qtitle='Server URL'"
+ " qtip='" + url + "'>" + model.getAlias() + "</div>";
}
});
configs.add(aliasColumn);
ColumnConfig titleColumn = new ColumnConfig();
titleColumn.setId(GPCSWServerKeyValue.TITLE.toString());
titleColumn.setHeaderHtml(CatalogFinderConstants.INSTANCE.
CSWServerPaginationContainer_titleColumnHeaderText());
titleColumn.setWidth(100);
titleColumn.setFixed(true);
titleColumn.setResizable(false);
configs.add(titleColumn);
sm = new CheckBoxSelectionModel<GPCSWServerBeanModel>();
sm.setSelectionMode(Style.SelectionMode.SINGLE);
sm.addSelectionChangedListener(
new SelectionChangedListener<GPCSWServerBeanModel>() {
@Override
public void selectionChanged(
SelectionChangedEvent<GPCSWServerBeanModel> se) {
GPCSWServerBeanModel selectedServer = se.getSelectedItem();
if (selectedServer == null) {
deleteServerButton.disable();
enableEvent.setEnabled(Boolean.FALSE);
} else {
deleteServerButton.enable();
catalogFinder.setServerID(
selectedServer.getId());
enableEvent.setEnabled(Boolean.TRUE);
}
bus.fireEvent(enableEvent);
}
});
ColumnConfig checkColumn = sm.getColumn();
checkColumn.setId("cheked");
checkColumn.setWidth(30);
checkColumn.setFixed(true);
checkColumn.setResizable(false);
configs.add(checkColumn);
return new ColumnModel(configs);
}
@Override
public void createStore() {
super.proxy = new RpcProxy<PagingLoadResult<GPCSWServerBeanModel>>() {
@Override
protected void load(final Object loadConfig,
final AsyncCallback<PagingLoadResult<GPCSWServerBeanModel>> callback) {
final String searchText = searchField.getValue() == null ? "" : searchField.getValue();
xsrf.getNewXsrfToken(new AsyncCallback<XsrfToken>() {
@Override
public void onFailure(Throwable caught) {
try {
throw caught;
} catch (RpcTokenException e) {
// Can be thrown for several reasons:
// - duplicate session cookie, which may be a sign of a cookie
// overwrite attack
// - XSRF token cannot be generated because session cookie isn't
// present
} catch (Throwable e) {
// unexpected
}
}
@Override
public void onSuccess(XsrfToken token) {
((HasRpcToken) catalogFinderRemote).setRpcToken(token);
catalogFinderRemote.searchCSWServers(
(PagingLoadConfig) loadConfig, searchText,
GPAccountLogged.getInstance().getOrganization(),
callback);
}
});
}
};
super.loader = new BasePagingLoader<PagingLoadResult<GPCSWServerBeanModel>>(
proxy);
super.loader.setRemoteSort(false);
super.store = new ListStore<GPCSWServerBeanModel>(loader);
}
@Override
protected void onLoaderBeforeLoad(LoadEvent le) {
widget.mask(
CatalogFinderConstants.INSTANCE.CSWServerPaginationContainer_gridLoadingMaskText());
}
@Override
protected void onLoaderLoad(LoadEvent le) {
BasePagingLoadResult result = (BasePagingLoadResult) le.getData();
if (result.getTotalLength() == 0) {
bus.fireEvent(new StatusWidgetEvent(CatalogFinderConstants.INSTANCE.
CSWServerPaginationContainer_eventNoCatalogsText(),
GPCatalogStatusBarType.STATUS_NOT_OK));
} else {
bus.fireEvent(new StatusWidgetEvent(CatalogFinderConstants.INSTANCE.
CSWServerPaginationContainer_eventLoadedCatalogsText(),
GPCatalogStatusBarType.STATUS_OK));
}
widget.unmask();
}
@Override
protected void onLoaderLoadException(LoadEvent le) {
System.out.println("\n*** " + le.exception.getMessage()); // TODO logger
GeoPlatformMessage.errorMessage(CatalogFinderConstants.INSTANCE.
CSWServerPaginationContainer_errorLoaderMessageTitleText(),
CatalogFinderConstants.INSTANCE.CSWServerPaginationContainer_errorLoaderMessageBodyText());
bus.fireEvent(new StatusWidgetEvent(CatalogFinderConstants.INSTANCE.
CSWServerPaginationContainer_errorLoaderMessageBodyText(),
GPCatalogStatusBarType.STATUS_ERROR));
super.reset();
widget.unmask();
}
public void executeDeleteServer() {
super.widget.mask(
CatalogFinderConstants.INSTANCE.CSWServerPaginationContainer_gridDeletingMaskText());
final GPCSWServerBeanModel selectedServer = sm.getSelectedItem();
xsrf.getNewXsrfToken(new AsyncCallback<XsrfToken>() {
@Override
public void onFailure(Throwable caught) {
try {
throw caught;
} catch (RpcTokenException e) {
// Can be thrown for several reasons:
// - duplicate session cookie, which may be a sign of a cookie
// overwrite attack
// - XSRF token cannot be generated because session cookie isn't
// present
} catch (Throwable e) {
// unexpected
}
}
@Override
public void onSuccess(XsrfToken token) {
((HasRpcToken) catalogFinderRemote).setRpcToken(token);
catalogFinderRemote.deleteServerCSW(selectedServer.getId(),
new AsyncCallback<Boolean>() {
@Override
public void onFailure(Throwable caught) {
System.out.println(
"\n*** Error on deleting server: " + caught.getMessage()); // TODO logger
bus.fireEvent(new StatusWidgetEvent(
CatalogFinderConstants.INSTANCE.CSWServerPaginationContainer_eventErrorDeletingServerText(),
GPCatalogStatusBarType.STATUS_ERROR));
widget.unmask();
}
@Override
public void onSuccess(Boolean result) {
store.remove(selectedServer);
bus.fireEvent(new StatusWidgetEvent(
CatalogFinderConstants.INSTANCE.CSWServerPaginationContainer_eventCorrectlyDeletedServerText(),
GPCatalogStatusBarType.STATUS_OK));
widget.unmask();
}
});
}
});
}
@Override
public void loadFirstServers() {
loader.load(0, super.getPageSize());
}
@Override
public void reset() {
super.reset();
this.searchField.reset();
}
/**
* TODO : MAKE IMPROVEMENT FOR PAGINATION HERE
*
* Add the server to store.
*
* @param server to add
*/
public void addNewServer(GPCSWServerBeanModel server) {
this.store.insert(server, 0);
}
/**
* Verify if the server URL is already exist into the store.
*
* @param url server URL to check
*
* @return server founded or null
*/
public GPCSWServerBeanModel containsServer(String url) {
for (GPCSWServerBeanModel server : store.getModels()) {
if (server.getUrlServer().equalsIgnoreCase(url)) {
return server;
}
}
return null;
}
}