/* (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.data.store.geogig; import static org.locationtech.geogig.geotools.data.GeoGigDataStoreFactory.AUTO_INDEXING; import static org.locationtech.geogig.geotools.data.GeoGigDataStoreFactory.BRANCH; import static org.locationtech.geogig.geotools.data.GeoGigDataStoreFactory.REPOSITORY; import java.io.Serializable; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink; import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; import org.apache.wicket.markup.html.form.ChoiceRenderer; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.model.IModel; import org.apache.wicket.model.LoadableDetachableModel; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.model.ResourceModel; import org.geogig.geoserver.config.GeoServerGeoGigRepositoryResolver; import org.geogig.geoserver.config.RepositoryInfo; import org.geogig.geoserver.config.RepositoryManager; import org.geogig.geoserver.web.repository.RepositoryEditFormPanel; import org.geogig.geoserver.web.repository.RepositoryImportFormPanel; import org.geoserver.catalog.DataStoreInfo; import org.geoserver.web.data.store.DataAccessEditPage; import org.geoserver.web.data.store.DataAccessNewPage; import org.geoserver.web.data.store.StoreEditPanel; import org.geoserver.web.data.store.panel.CheckBoxParamPanel; import org.geoserver.web.data.store.panel.TextParamPanel; import org.geoserver.web.util.MapModel; import org.locationtech.geogig.repository.RepositoryResolver; import com.google.common.base.Objects; import com.google.common.base.Strings; import com.google.common.base.Throwables; public class GeoGigDataStoreEditPanel extends StoreEditPanel { private static final long serialVersionUID = 330172801498702374L; private final DropDownChoice<String> repository; private final BranchSelectionPanel branch; private final ModalWindow modalWindow; private final IModel<String> repositoryUriModel; private final IModel<String> branchNameModel; private final String originalRepo, originalBranch; private final IModel<Boolean> autoIndexingModel; /** * @param componentId the wicket component id * @param storeEditForm the data store edit form, as provided by {@link DataAccessEditPage} and * {@link DataAccessNewPage} */ @SuppressWarnings("unchecked") public GeoGigDataStoreEditPanel(final String componentId, final Form<DataStoreInfo> storeEditForm) { super(componentId, storeEditForm); final IModel<DataStoreInfo> model = storeEditForm.getModel(); setDefaultModel(model); final IModel<Map<String, Serializable>> paramsModel = new PropertyModel<>(model, "connectionParameters"); this.repositoryUriModel = new MapModel(paramsModel, REPOSITORY.key); this.branchNameModel = new MapModel(paramsModel, BRANCH.key); this.autoIndexingModel = new MapModel(paramsModel, AUTO_INDEXING.key); this.originalRepo = repositoryUriModel.getObject(); this.originalBranch = branchNameModel.getObject(); add(repository = createRepositoryPanel()); add(importExistingLink(storeEditForm)); add(addNewLink(storeEditForm)); add(branch = createBranchNameComponent(storeEditForm)); add(createAutoIndexingPanel()); add(modalWindow = new ModalWindow("modalWindow")); } private CheckBoxParamPanel createAutoIndexingPanel() { CheckBoxParamPanel checkBoxParamPanel = new CheckBoxParamPanel("autoIndexing", autoIndexingModel, new ResourceModel("autoIndexing", "Auto-Indexing")); checkBoxParamPanel.setOutputMarkupId(true); return checkBoxParamPanel; } private DropDownChoice<String> createRepositoryPanel() { IModel<List<String>> choices = new RepositoryListDettachableModel(); RepoInfoChoiceRenderer choiceRenderer = new RepoInfoChoiceRenderer(); DropDownChoice<String> choice = new DropDownChoice<>("geogig_repository", repositoryUriModel, choices, choiceRenderer); choice.setLabel(new ResourceModel("repository")); choice.setNullValid(true); choice.setRequired(true); choice.setOutputMarkupId(true); choice.add(new AjaxFormComponentUpdatingBehavior("change") { private static final long serialVersionUID = 6182000388125500580L; @Override protected void onUpdate(AjaxRequestTarget target) { String branchName = null; // do not lose the original branch if the user is moving around the repo choices if (Objects.equal(originalRepo, repositoryUriModel.getObject())) { branchName = originalBranch; } branchNameModel.setObject(branchName); branch.updateChoices(true, GeoGigDataStoreEditPanel.this.storeEditForm); target.add(branch); } }); return choice; } private BranchSelectionPanel createBranchNameComponent(Form<DataStoreInfo> form) { final String panelId = "branch"; BranchSelectionPanel selectionPanel; selectionPanel = new BranchSelectionPanel(panelId, repositoryUriModel, branchNameModel, form); selectionPanel.setOutputMarkupId(true); return selectionPanel; } private Component addNewLink(final Form<DataStoreInfo> storeEditForm) { AjaxSubmitLink link = new AjaxSubmitLink("addNew", storeEditForm) { private static final long serialVersionUID = 1242472443848716943L; @Override public boolean getDefaultFormProcessing() { return false; } @Override public void onSubmit(final AjaxRequestTarget target, final Form<?> form) { final RepositoryEditFormPanel panel; panel = new RepositoryEditFormPanel(modalWindow.getContentId()) { private static final long serialVersionUID = -2629733074852452891L; @SuppressWarnings("unchecked") @Override protected void saved(final RepositoryInfo info, final AjaxRequestTarget target) { modalWindow.close(target); updateRepository((Form<DataStoreInfo>) form, target, info); } @Override protected void cancelled(AjaxRequestTarget target) { modalWindow.close(target); } }; modalWindow.setContent(panel); modalWindow.setTitle( new ResourceModel("GeoGigDirectoryFormComponent.chooser.browseTitle")); modalWindow.show(target); } }; return link; } private Component importExistingLink(Form<DataStoreInfo> storeEditForm) { AjaxSubmitLink link = new AjaxSubmitLink("importExisting", storeEditForm) { private static final long serialVersionUID = 1242472443848716943L; @Override public boolean getDefaultFormProcessing() { return false; } @Override public void onSubmit(final AjaxRequestTarget target, final Form<?> form) { final RepositoryImportFormPanel panel; panel = new RepositoryImportFormPanel(modalWindow.getContentId()) { private static final long serialVersionUID = 1L; @SuppressWarnings("unchecked") @Override protected void saved(final RepositoryInfo info, final AjaxRequestTarget target) { modalWindow.close(target); updateRepository((Form<DataStoreInfo>) form, target, info); } @Override protected void cancelled(AjaxRequestTarget target) { modalWindow.close(target); } }; modalWindow.setContent(panel); modalWindow.setTitle( new ResourceModel("GeoGigDirectoryFormComponent.chooser.browseTitle")); modalWindow.show(target); } }; return link; } @SuppressWarnings("unchecked") private void updateRepository(final Form<DataStoreInfo> form, AjaxRequestTarget target, RepositoryInfo info) { repository.setModelObject(GeoServerGeoGigRepositoryResolver.getURI(info.getRepoName())); branchNameModel.setObject(null); branch.updateChoices(true, form); target.add(repository); target.add(branch); IModel<DataStoreInfo> storeModel = form.getModel(); String dataStoreName = storeModel.getObject().getName(); if (Strings.isNullOrEmpty(dataStoreName)) { Component namePanel = form.get("dataStoreNamePanel"); if (namePanel != null && namePanel instanceof TextParamPanel) { TextParamPanel paramPanel = (TextParamPanel) namePanel; paramPanel.getFormComponent().setModelObject(info.getRepoName()); target.add(form); } } } private static class RepositoryListDettachableModel extends LoadableDetachableModel<List<String>> { private static final long serialVersionUID = 6664339867388245896L; @Override protected List<String> load() { List<RepositoryInfo> all = RepositoryManager.get().getAll(); List<String> uris = new ArrayList<>(all.size()); for (RepositoryInfo info : all) { uris.add(GeoServerGeoGigRepositoryResolver.getURI(info.getRepoName())); } Collections.sort(uris); return uris; } } private static class RepoInfoChoiceRenderer extends ChoiceRenderer<String> { private static final long serialVersionUID = -7350304450283044479L; @Override public Object getDisplayValue(String repoUriStr) { try { URI repoUri = new URI(repoUriStr); RepositoryResolver resolver = RepositoryResolver.lookup(repoUri); RepositoryInfo info = RepositoryManager.get().getByRepoName(resolver.getName(repoUri)); return info.getRepoName() + " (" + info.getMaskedLocation()+ ")"; } catch (URISyntaxException e) { throw Throwables.propagate(e); } } @Override public String getIdValue(String id, int index) { return id; } } }