/* (c) 2016 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 java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; 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.basic.Label; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.markup.repeater.DefaultItemReuseStrategy; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.ResourceModel; import org.apache.wicket.request.resource.PackageResourceReference; import org.geogig.geoserver.config.RepositoryManager; 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; import org.locationtech.geogig.model.Ref; import org.locationtech.geogig.model.SymRef; public class RemotesListPanel extends GeoServerTablePanel<RemoteInfo> { 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; private final RemotesProvider provider; private final FeedbackPanel pingFeedbackPanel; public RemotesListPanel(final String id, final List<RemoteInfo> remotes) { super(id, new RemotesProvider(remotes), false); super.setFilterable(false); this.provider = (RemotesProvider) super.getDataProvider(); this.setOutputMarkupId(true); // set the reuse strategy, otherwise the list does not get updated when the popup window // closes this.setItemReuseStrategy(DefaultItemReuseStrategy.getInstance()); // the popup window for messages popupWindow = new ModalWindow("popupWindow"); add(popupWindow); add(dialog = new GeoServerDialog("dialog")); add(pingFeedbackPanel = new FeedbackPanel("feedback")); pingFeedbackPanel.setOutputMarkupId(true); } public void add(RemoteInfo remote) { this.provider.getItems().add(remote); } public Iterable<RemoteInfo> getRemotes() { return provider.getItems(); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override protected Component getComponentForProperty(String id, IModel<RemoteInfo> itemModel, Property<RemoteInfo> property) { IModel<RemoteInfo> model = itemModel; if (property == RemotesProvider.NAME) { return nameLink(id, itemModel); } else if (property == RemotesProvider.URL) { String location = (String) RemotesProvider.URL.getModel(itemModel).getObject(); Label label = new Label(id, location); // label.add(new SimpleAttributeModifier("style", "word-wrap:break-word;")); return label; } else if (property == RemotesProvider.PINGLINK) { return new RemotePingLink(id, model); } else if (property == RemotesProvider.REMOVELINK) { return removeLink(id, itemModel); } return null; } private Component nameLink(String id, IModel<RemoteInfo> itemModel) { @SuppressWarnings("unchecked") IModel<?> nameModel = RemotesProvider.NAME.getModel(itemModel); SimpleAjaxLink<RemoteInfo> link = new SimpleAjaxLink<RemoteInfo>(id, itemModel, nameModel) { private static final long serialVersionUID = -18292070541084372L; @Override public void onClick(AjaxRequestTarget target) { IModel<RemoteInfo> model = this.getModel(); RemotesListPanel table = RemotesListPanel.this; RemoteEditPanel editPanel = new RemoteEditPanel(popupWindow.getContentId(), model, popupWindow, table); popupWindow.setContent(editPanel); popupWindow.setTitle(new ResourceModel("RemoteEditPanel.title")); popupWindow.show(target); } }; return link; } protected Component removeLink(final String id, final IModel<RemoteInfo> itemModel) { return new ImageAjaxLink(id, REMOVE_ICON) { private static final long serialVersionUID = -3061812114487970427L; private final IModel<RemoteInfo> model = itemModel; @Override public void onClick(AjaxRequestTarget target) { GeoServerDialog dialog = RemotesListPanel.this.dialog; dialog.setTitle(new ParamResourceModel("RemotesListPanel.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 RemoteInfo remote = model.getObject(); List<RemoteInfo> items = RemotesListPanel.this.provider.getItems(); items.remove(remote); target.add(RemotesListPanel.this); return closeConfirmDialog; } @Override public void onClose(AjaxRequestTarget target) { target.add(RemotesListPanel.this); } }); } }; } static class ConfirmRemovePanel extends Panel { private static final long serialVersionUID = 653769682579422516L; public ConfirmRemovePanel(String id, IModel<RemoteInfo> remote) { super(id); add(new Label("aboutRemoveMsg", new ParamResourceModel( "RemotesListPanel$ConfirmRemovePanel.aboutRemove", this, remote.getObject() .getName()))); } } static class RemotesProvider extends GeoServerDataProvider<RemoteInfo> { private static final long serialVersionUID = 4883560661021761394L; static final Property<RemoteInfo> NAME = new BeanProperty<>("name", "name"); static final Property<RemoteInfo> URL = new BeanProperty<>("URL", "URL"); static final Property<RemoteInfo> PINGLINK = new AbstractProperty<RemoteInfo>("") { private static final long serialVersionUID = 1L; @Override public Boolean getPropertyValue(RemoteInfo item) { return Boolean.TRUE; } @Override public boolean isSearchable() { return false; } }; static final Property<RemoteInfo> REMOVELINK = new AbstractProperty<RemoteInfo>("remove") { private static final long serialVersionUID = 1L; @Override public Boolean getPropertyValue(RemoteInfo item) { return Boolean.TRUE; } @Override public boolean isSearchable() { return false; } }; final List<Property<RemoteInfo>> PROPERTIES = Arrays .asList(NAME, URL, PINGLINK, REMOVELINK); private final ArrayList<RemoteInfo> items; public RemotesProvider(final List<RemoteInfo> remotes) { this.items = new ArrayList<>(remotes); } @Override protected List<RemoteInfo> getItems() { return items; } @Override protected List<Property<RemoteInfo>> getProperties() { return PROPERTIES; } @Override protected Comparator<RemoteInfo> getComparator(SortParam sort) { return super.getComparator(sort); } @Override public IModel<RemoteInfo> newModel(RemoteInfo object) { return new Model<>(object); } } private final class RemotePingLink extends SimpleAjaxLink<RemoteInfo> { private static final long serialVersionUID = 1L; private RemotePingLink(String id, IModel<RemoteInfo> model) { super(id, model, new Model<>("ping")); } @Override protected void onClick(AjaxRequestTarget target) { RemoteInfo remoteInfo = getModelObject(); String location = remoteInfo.getURL(); String username = remoteInfo.getUserName(); String pwd = remoteInfo.getPassword(); try { Ref head = RepositoryManager.pingRemote(location, username, pwd); String headTarget; if (head instanceof SymRef) { headTarget = ((SymRef) head).getTarget(); } else { headTarget = head.getObjectId().toString(); } pingFeedbackPanel.info("Connection suceeded. HEAD is at " + headTarget); } catch (Exception e) { pingFeedbackPanel.error(e.getMessage()); } target.add(pingFeedbackPanel); } } }