/** * Copyright (C) 2014 BonitaSoft S.A. * BonitaSoft, 32 rue Gustave Eiffel - 38000 Grenoble * 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.0 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/>. */ package org.bonitasoft.console.client.admin.page.view; import static org.bonitasoft.web.toolkit.client.common.i18n.AbstractI18n._; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.bonitasoft.web.rest.model.application.ApplicationDefinition; import org.bonitasoft.web.rest.model.application.ApplicationItem; import org.bonitasoft.web.rest.model.applicationpage.ApplicationPageDefinition; import org.bonitasoft.web.rest.model.applicationpage.ApplicationPageItem; import org.bonitasoft.web.rest.model.portal.page.PageDefinition; import org.bonitasoft.web.rest.model.portal.page.PageItem; import org.bonitasoft.web.toolkit.client.RequestBuilder; import org.bonitasoft.web.toolkit.client.ViewController; import org.bonitasoft.web.toolkit.client.common.json.JSonItemReader; import org.bonitasoft.web.toolkit.client.data.api.APICaller; import org.bonitasoft.web.toolkit.client.data.api.callback.APICallback; import org.bonitasoft.web.toolkit.client.ui.JsId; import org.bonitasoft.web.toolkit.client.ui.Page; import org.bonitasoft.web.toolkit.client.ui.action.Action; import org.bonitasoft.web.toolkit.client.ui.component.Paragraph; import org.bonitasoft.web.toolkit.client.ui.component.Text; import org.bonitasoft.web.toolkit.client.ui.component.callout.CalloutWarning; import org.bonitasoft.web.toolkit.client.ui.component.form.Form; import org.bonitasoft.web.toolkit.client.ui.component.form.button.FormSubmitButton; import com.google.gwt.http.client.RequestException; import com.google.gwt.json.client.JSONArray; import com.google.gwt.json.client.JSONParser; import com.google.gwt.json.client.JSONValue; /** * @author Julien Mege */ public class DeleteCustomPage extends Page { public static final String TOKEN = "deletepageadmin"; public static final List<String> PRIVILEGES = new ArrayList<String>(); private FormSubmitButton deleteButton; private final ArrayList<String> idsAsString; private boolean firstPageLinkNotFound = true; private boolean firstFormNotFound = true; private int pagesLeft; static { PRIVILEGES.add(PageListingPage.TOKEN); } public DeleteCustomPage(final ArrayList<String> idsAsString) { this.idsAsString = idsAsString; } @Override public void defineTitle() { this.setTitle(_("Delete pages")); } @Override public String defineToken() { return TOKEN; } @Override public void buildView() { addBody(new Text(getParameter("message"))); buildform(); if (idsAsString.size() > 1) { // multiple selection addBody(new Text(_("If these pages are used in a profile, the pages and related profile entries will be permanently deleted."))); } else { addBody(new Text(_("If this page is used in a profile, the page and related profile entries will be permanently deleted."))); } searchApplicationDependencies(); searchFormMappingDependencies(); } private void buildform() { final Form form = new Form(); deleteButton = new FormSubmitButton(new JsId("delete"), _("Delete"), _("Delete the pages"), new Action() { @Override public void execute() { new APICaller<PageItem>(PageDefinition.get()).delete(idsAsString, new APICallback() { @Override public void onSuccess(final int httpStatusCode, final String response, final Map<String, String> headers) { ViewController.closePopup(); ViewController.refreshCurrentPage(); } }); } }); deleteButton.setVisible(true); form.addButton(deleteButton); form.addCancelButton(); setFooter(form); } private void searchApplicationDependencies() { for (final String pageId : idsAsString) { searchApplicationDependenciesForPage(pageId); searchApplicationLayoutDependanciesForPage(pageId); searchApplicationThemeDependanciesForPage(pageId); } } private void searchApplicationDependenciesForPage(final String pageId) { final Map<String, String> filter = new HashMap<String, String>(); filter.put(ApplicationPageItem.ATTRIBUTE_PAGE_ID, pageId); final List<String> deploys = Arrays.asList(ApplicationPageItem.ATTRIBUTE_PAGE_ID, ApplicationPageItem.ATTRIBUTE_APPLICATION_ID); new APICaller<ApplicationPageItem>(ApplicationPageDefinition.get()).search( 0, Integer.MAX_VALUE, null, null, filter, deploys, new DeletePageProblemCallback()); } private void searchApplicationLayoutDependanciesForPage(final String pageId) { final Map<String, String> filter = new HashMap<String, String>(); filter.put(ApplicationItem.ATTRIBUTE_LAYOUT_ID, pageId); final List<String> deploys = Arrays.asList(ApplicationItem.ATTRIBUTE_LAYOUT_ID); new APICaller<ApplicationItem>(ApplicationDefinition.get()).search( 0, Integer.MAX_VALUE, null, null, filter, deploys, new DeleteApplicationLayoutCallback()); } private void searchApplicationThemeDependanciesForPage(final String pageId) { final Map<String, String> filter = new HashMap<String, String>(); filter.put(ApplicationItem.ATTRIBUTE_THEME_ID, pageId); final List<String> deploys = Arrays.asList(ApplicationItem.ATTRIBUTE_THEME_ID); new APICaller<ApplicationItem>(ApplicationDefinition.get()).search( 0, Integer.MAX_VALUE, null, null, filter, deploys, new DeleteApplicationThemeCallback()); } private class DeletePageProblemCallback extends APICallback { @Override public void onSuccess(final int httpStatusCode, final String response, final Map<String, String> headers) { final List<ApplicationPageItem> applicationPages = JSonItemReader.parseItems(response, ApplicationPageDefinition.get()); if (applicationPages.size() > 0) { addInfoMessageOnApplicationPageLinkFound(); addBody(new DeletePageProblemsCallout(applicationPages)); } } } private void addInfoMessageOnApplicationPageLinkFound() { if (firstPageLinkNotFound) { setBody(new Text(_("These pages cannot be deleted because at least one is used in an application. You must remove a page from an application before you can delete it."))); activateDeleteButton(false); firstPageLinkNotFound = false; } } private class DeleteApplicationLayoutCallback extends APICallback { @Override public void onSuccess(final int httpStatusCode, final String response, final Map<String, String> headers) { final List<ApplicationItem> applications = JSonItemReader.parseItems(response, ApplicationDefinition.get()); if (applications.size() > 0) { addInfoMessageOnApplicationPageLinkFound(); addBody(new DeleteApplicationLayoutProblemsCallout(applications)); } } } private class DeleteApplicationThemeCallback extends APICallback { @Override public void onSuccess(final int httpStatusCode, final String response, final Map<String, String> headers) { final List<ApplicationItem> applications = JSonItemReader.parseItems(response, ApplicationDefinition.get()); if (applications.size() > 0) { addInfoMessageOnApplicationPageLinkFound(); addBody(new DeleteApplicationThemeProblemsCallout(applications)); } } } private void searchFormMappingDependencies() { //pagesLeft = 0; for (final String pageId : idsAsString) { searchFormMappingDependenciesForPage(pageId); } } private void searchFormMappingDependenciesForPage(final String pageId) { final Map<String, String> filter = new HashMap<String, String>(); filter.put(ApplicationPageItem.ATTRIBUTE_PAGE_ID, pageId); final RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.GET, "../API/form/mapping?c=10&p=0&f=pageId=" + pageId); requestBuilder.setCallback(new DeletePageProblemFormCallback(pageId)); try { requestBuilder.send(); } catch (final RequestException e) { e.printStackTrace(); } } private class DeletePageProblemFormCallback extends APICallback { private final String pageId; private final Boolean isLastPage = false; public DeletePageProblemFormCallback(final String pageId) { this.pageId = pageId; } @Override public void onSuccess(final int httpStatusCode, final String response, final Map<String, String> headers) { final JSONValue root= JSONParser.parseLenient(response); final JSONArray formMappings=root.isArray(); if (firstPageLinkNotFound) { if (formMappings.size()>0) { if (firstFormNotFound) { pagesLeft=1; setBody(new Paragraph(_("Some of the pages you selected for deletion are used by processes:"))); firstFormNotFound = false; setTitle(_("Confirm Delete?")); } else { pagesLeft++; } new APICaller<PageItem>(PageDefinition.get()).get(pageId, new GetPageNameCallback(formMappings)); } } } private class GetPageNameCallback extends APICallback { private final JSONArray formMappings; public GetPageNameCallback(final JSONArray formMappings) { this.formMappings = formMappings; } @Override public void onSuccess(final int httpStatusCode, final String response, final Map<String, String> headers) { final PageItem page = JSonItemReader.parseItem(response, PageDefinition.get()); addBody(new DeletePageFormProblemsCallout(formMappings, page.getDisplayName())); if (--pagesLeft==0) { addBody(new CalloutWarning(_("If you delete a page that is used by a process, the process becomes unresolved.\nBefore deleting a page, you should also check whether it is used in a custom profile navigation."))); addBody(new Paragraph(_("Do you still want to delete the selected pages?"))); } } } } private void activateDeleteButton(final boolean noApplicationLink) { deleteButton.setVisible(noApplicationLink); } }