/* (c) 2017 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geogig.geoserver.web.repository;
import static org.geoserver.catalog.CascadeRemovalReporter.ModificationType.DELETE;
import static org.geoserver.catalog.CascadeRemovalReporter.ModificationType.GROUP_CHANGED;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.request.resource.PackageResourceReference;
import org.geogig.geoserver.config.RepositoryInfo;
import org.geogig.geoserver.config.RepositoryManager;
import org.geogig.geoserver.web.RepositoryEditPage;
import org.geoserver.catalog.CascadeRemovalReporter;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CatalogInfo;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.web.GeoServerApplication;
import org.geoserver.web.GeoServerBasePage;
import org.geoserver.web.wicket.GeoServerDataProvider;
import org.geoserver.web.wicket.GeoServerDataProvider.Property;
import org.geoserver.web.wicket.GeoServerDialog;
import org.geoserver.web.wicket.GeoServerTablePanel;
import org.geoserver.web.wicket.ImageAjaxLink;
import org.geoserver.web.wicket.ParamResourceModel;
import org.geoserver.web.wicket.SimpleAjaxLink;
public class RepositoriesListPanel extends GeoServerTablePanel<RepositoryInfo> {
private static final long serialVersionUID = 5957961031378924960L;
private static final PackageResourceReference REMOVE_ICON = new PackageResourceReference(
GeoServerBasePage.class, "img/icons/silk/delete.png");
private final ModalWindow popupWindow;
private final GeoServerDialog dialog;
public RepositoriesListPanel(final String id) {
super(id, new RepositoryProvider(), false);
// the popup window for messages
popupWindow = new ModalWindow("popupWindow");
add(popupWindow);
add(dialog = new GeoServerDialog("dialog"));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
protected Component getComponentForProperty(String id, IModel<RepositoryInfo> itemModel,
Property<RepositoryInfo> property) {
if (property == RepositoryProvider.NAME) {
return nameLink(id, itemModel);
} else if (property == RepositoryProvider.LOCATION) {
String location = RepositoryProvider.LOCATION.getModel(itemModel).getObject().toString();
Label label = new Label(id, location);
// label.add(new SimpleAttributeModifier("style", "word-wrap:break-word;"));
return label;
} else if (property == RepositoryProvider.REMOVELINK) {
return removeLink(id, itemModel);
}
return null;
}
private Component nameLink(String id, IModel<RepositoryInfo> itemModel) {
@SuppressWarnings("unchecked")
IModel<?> nameModel = RepositoryProvider.NAME.getModel(itemModel);
SimpleAjaxLink<RepositoryInfo> link = new SimpleAjaxLink<RepositoryInfo>(id, itemModel,
nameModel) {
private static final long serialVersionUID = -18292070541084372L;
@Override
public void onClick(AjaxRequestTarget target) {
IModel<RepositoryInfo> model = getModel();
RepositoriesListPanel.this.setResponsePage(new RepositoryEditPage(model));
}
};
return link;
}
protected Component removeLink(final String id, final IModel<RepositoryInfo> itemModel) {
return new ImageAjaxLink(id, REMOVE_ICON) {
private static final long serialVersionUID = -3061812114487970427L;
private final IModel<RepositoryInfo> model = itemModel;
@Override
public void onClick(AjaxRequestTarget target) {
GeoServerDialog dialog = RepositoriesListPanel.this.dialog;
dialog.setTitle(
new ParamResourceModel("RepositoriesListPanel.confirmRemoval.title", this));
dialog.showOkCancel(target, new GeoServerDialog.DialogDelegate() {
private static final long serialVersionUID = -450822090965263894L;
@Override
protected Component getContents(String id) {
return new ConfirmRemovePanel(id, model);
}
@Override
protected boolean onSubmit(AjaxRequestTarget target, Component contents) {
boolean closeConfirmDialog = true;
final String repoId = model.getObject().getId();
RepositoryManager.get().delete(repoId);
return closeConfirmDialog;
}
@Override
public void onClose(AjaxRequestTarget target) {
target.add(RepositoriesListPanel.this);
}
});
}
};
}
static class ConfirmRemovePanel extends Panel {
private static final long serialVersionUID = 653769682579422516L;
public ConfirmRemovePanel(String id, IModel<RepositoryInfo> repo) {
super(id);
final String repoName = repo.getObject().getRepoName();
add(new Label("aboutRemoveMsg", new ParamResourceModel(
"RepositoriesListPanel$ConfirmRemovePanel.aboutRemove", this, repoName)));
final String repoId = repo.getObject().getId();
final List<? extends CatalogInfo> stores;
stores = RepositoryManager.get().findDataStores(repoId);
// collect the objects that will be removed (besides the roots)
Catalog catalog = GeoServerApplication.get().getCatalog();
CascadeRemovalReporter visitor = new CascadeRemovalReporter(catalog);
for (CatalogInfo info : stores) {
info.accept(visitor);
}
// visitor.removeAll(stores);
// removed objects root (we show it if any removed object is on the list)
WebMarkupContainer removed = new WebMarkupContainer("removedObjects");
List<CatalogInfo> cascaded = visitor.getObjects(CatalogInfo.class, DELETE);
// remove the resources, they are cascaded, but won't be show in the UI
for (Iterator<CatalogInfo> it = cascaded.iterator(); it.hasNext();) {
CatalogInfo catalogInfo = it.next();
if (catalogInfo instanceof ResourceInfo) {
it.remove();
}
}
removed.setVisible(!cascaded.isEmpty());
add(removed);
// removed stores
WebMarkupContainer str = new WebMarkupContainer("storesRemoved");
removed.add(str);
str.setVisible(!stores.isEmpty());
str.add(new Label("stores", names(stores)));
// removed layers
WebMarkupContainer lar = new WebMarkupContainer("layersRemoved");
removed.add(lar);
List<LayerInfo> layers = visitor.getObjects(LayerInfo.class, DELETE);
if (layers.isEmpty())
lar.setVisible(false);
lar.add(new Label("layers", names(layers)));
// modified objects root (we show it if any modified object is on the list)
WebMarkupContainer modified = new WebMarkupContainer("modifiedObjects");
modified.setVisible(visitor.getObjects(null, GROUP_CHANGED).size() > 0);
add(modified);
// groups modified
WebMarkupContainer grm = new WebMarkupContainer("groupsModified");
modified.add(grm);
List<LayerGroupInfo> groups = visitor.getObjects(LayerGroupInfo.class, GROUP_CHANGED);
grm.setVisible(!groups.isEmpty());
grm.add(new Label("groups", names(groups)));
}
String names(List<? extends CatalogInfo> objects) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < objects.size(); i++) {
sb.append(name(objects.get(i)));
if (i < (objects.size() - 1)) {
sb.append(", ");
}
}
return sb.toString();
}
String name(Object object) {
try {
return (String) BeanUtils.getProperty(object, "name");
} catch (Exception e) {
throw new RuntimeException("A catalog object that does not have "
+ "a 'name' property has been used, this is unexpected", e);
}
}
}
static class RepositoryProvider extends GeoServerDataProvider<RepositoryInfo> {
private static final long serialVersionUID = 4883560661021761394L;
static final Property<RepositoryInfo> NAME = new BeanProperty<>("name", "repoName");
static final Property<RepositoryInfo> LOCATION = new BeanProperty<>("location", "maskedLocation");
static final Property<RepositoryInfo> REMOVELINK = new AbstractProperty<RepositoryInfo>(
"remove") {
private static final long serialVersionUID = 1L;
@Override
public Boolean getPropertyValue(RepositoryInfo item) {
return Boolean.TRUE;
}
@Override
public boolean isSearchable() {
return false;
}
};
final List<Property<RepositoryInfo>> PROPERTIES = Arrays.asList(NAME, LOCATION, REMOVELINK);
public RepositoryProvider() {
}
@Override
protected List<RepositoryInfo> getItems() {
return RepositoryManager.get().getAll();
}
@Override
protected List<Property<RepositoryInfo>> getProperties() {
return PROPERTIES;
}
@Override
protected Comparator<RepositoryInfo> getComparator(SortParam sort) {
return super.getComparator(sort);
}
@Override
public IModel<RepositoryInfo> newModel(RepositoryInfo object) {
return new RepositoryInfoDetachableModel(object);
}
}
}