Commit 0a909e47 authored by Romain Bioteau's avatar Romain Bioteau Committed by GitHub
Browse files

feat(deploy) integrate engine statuses (#1840)

* Only display warnings and errors
* Fix issue with autocomplete

Closes BST-443
parent 23c49331
......@@ -84,4 +84,11 @@ DeployButtonLabel=Deploy
deployingApplicationArtifacts=Deploying application artifacts...
environment=Environment
processes=Processes
selectLatestVersion=Select latest
\ No newline at end of file
selectLatestVersion=Select latest
cannotResolveProcess=%s (%s) cannot be resolved: %s
cannotEnableProcess=%s (%s) has been deployed but cannot be enabled.
appDescriptorUnknownAppPage=Application descriptor '%s': Application page '%s' has not been found.
appDescriptorUnknownPageToken=Application descriptor '%s': Application page token '%s' doesn't exists.
appDescriptorUnknownLayoutPage=Application descriptor '%s': Application layout '%s' has not been found.
appDescriptorUnknownTheme=Application descriptor '%s': Application theme '%s' has not been found.
deploySuccessMsg=All artifacts has been deployed successfully.
\ No newline at end of file
......@@ -53,6 +53,7 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.ui.services.IServiceConstants;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.wizard.IWizardContainer;
import org.eclipse.swt.widgets.Shell;
......@@ -172,8 +173,14 @@ public class DeployArtifactsHandler {
private void openStatusDialog(Shell activeShell, IStatus status) {
if (status instanceof MultiStatus) {
new MultiStatusDialog(activeShell, Messages.deployStatus, Messages.deployStatusMessage,
new String[] { IDialogConstants.OK_LABEL }, (MultiStatus) status).open();
if(status.getSeverity() == IStatus.ERROR || status.getSeverity() == IStatus.WARNING) {
MultiStatusDialog multiStatusDialog = new MultiStatusDialog(activeShell, Messages.deployStatus, Messages.deployStatusMessage,
new String[] { IDialogConstants.OK_LABEL }, (MultiStatus) status);
multiStatusDialog.setLevel(IStatus.WARNING);
multiStatusDialog.open();
}else {
MessageDialog.openInformation(activeShell, Messages.deployStatus, Messages.deploySuccessMsg);
}
} else {
StatusManager.getManager().handle(status, StatusManager.SHOW);
}
......
......@@ -124,6 +124,16 @@ public class Messages extends NLS {
public static String processes;
public static String selectLatestVersion;
public static String cannotResolveProcess;
public static String cannotEnableProcess;
public static String appDescriptorUnknownAppPage;
public static String appDescriptorUnknownPageToken;
public static String appDescriptorUnknownLayoutPage;
public static String appDescriptorUnknownTheme;
public static String deploySuccessMsg;
static {
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
}
......
......@@ -17,9 +17,13 @@ package org.bonitasoft.studio.application.operation;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.util.HashSet;
import java.util.Set;
import org.bonitasoft.engine.api.ApplicationAPI;
import org.bonitasoft.engine.api.result.ExecutionResult;
import org.bonitasoft.engine.api.result.StatusCode;
import org.bonitasoft.engine.api.result.StatusContext;
import org.bonitasoft.engine.exception.ApplicationDeploymentException;
import org.bonitasoft.engine.exception.BonitaHomeNotSetException;
import org.bonitasoft.engine.exception.ServerAPIException;
......@@ -29,8 +33,6 @@ import org.bonitasoft.studio.application.ApplicationPlugin;
import org.bonitasoft.studio.application.i18n.Messages;
import org.bonitasoft.studio.common.core.IRunnableWithStatus;
import org.bonitasoft.studio.engine.BOSEngineManager;
import org.bonitasoft.studio.ui.dialog.EngineStatusMapper;
import org.eclipse.core.databinding.validation.ValidationStatus;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
......@@ -42,6 +44,10 @@ public class DeployProjectOperation implements IRunnableWithStatus {
private MultiStatus status = new MultiStatus(ApplicationPlugin.PLUGIN_ID, -1, null, null);
private IPath archivePath;
private APISession session;
private static final Set<StatusCode> FILTERED_STATUS_CODE = new HashSet<>();
static {
FILTERED_STATUS_CODE.add(StatusCode.LIVING_APP_DEPLOYMENT);
}
public DeployProjectOperation(APISession session, IPath archivePath) {
this.session = session;
......@@ -56,11 +62,10 @@ public class DeployProjectOperation implements IRunnableWithStatus {
ExecutionResult result = applicationAPI
.deployApplication(Files.readAllBytes(archivePath.toFile().toPath()));
result.getAllStatus().stream()
.map(new EngineStatusMapper())
.filter(status -> !FILTERED_STATUS_CODE.contains(status.getCode()))
.filter(status -> !(status.getCode() == StatusCode.PROCESS_DEPLOYMENT_IMPOSSIBLE_UNRESOLVED && status.getContext().get(StatusContext.PROCESS_RESOLUTION_PROBLEM_DESCRIPTION_KEY) == null))
.map(DeployStatusMapper.instance())
.forEach(status::add);
if (status.isOK() && status.getChildren().length == 0) {
status.add(ValidationStatus.info("Application artifacts deployed successfully."));
}
} catch (BonitaHomeNotSetException | ServerAPIException | UnknownAPITypeException | ApplicationDeploymentException
| IOException e) {
status.add(new Status(IStatus.ERROR, ApplicationPlugin.PLUGIN_ID, e.getMessage(), e));
......
/**
* Copyright (C) 2019 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.studio.application.operation;
import org.bonitasoft.engine.api.result.Status;
import org.bonitasoft.engine.api.result.StatusContext;
import org.bonitasoft.studio.application.i18n.Messages;
import org.bonitasoft.studio.ui.dialog.EngineStatusMapper;
public class DeployStatusMapper extends EngineStatusMapper {
private static DeployStatusMapper INSTANCE;
public static DeployStatusMapper instance() {
if (INSTANCE == null) {
INSTANCE = new DeployStatusMapper();
}
return INSTANCE;
}
@Override
public String localizedMessage(Status status) {
StatusContext context = status.getContext();
switch (status.getCode()) {
case PROCESS_DEPLOYMENT_IMPOSSIBLE_UNRESOLVED:
return String.format(Messages.cannotResolveProcess,
context.get(StatusContext.PROCESS_NAME_KEY),
context.get(StatusContext.PROCESS_VERSION_KEY),
context.get(StatusContext.PROCESS_RESOLUTION_PROBLEM_DESCRIPTION_KEY));
case PROCESS_DEPLOYMENT_ENABLEMENT_KO:
return String.format(Messages.cannotEnableProcess,
context.get(StatusContext.PROCESS_NAME_KEY),
context.get(StatusContext.PROCESS_VERSION_KEY));
case LIVING_APP_REFERENCES_UNKNOWN_APPLICATION_PAGE:
return String.format(Messages.appDescriptorUnknownPageToken,
context.get(StatusContext.LIVING_APPLICATION_TOKEN_KEY),
context.get(StatusContext.LIVING_APPLICATION_INVALID_ELEMENT_NAME));
case LIVING_APP_REFERENCES_UNKNOWN_PAGE:
return String.format(Messages.appDescriptorUnknownAppPage,
context.get(StatusContext.LIVING_APPLICATION_TOKEN_KEY),
context.get(StatusContext.LIVING_APPLICATION_INVALID_ELEMENT_NAME));
case LIVING_APP_REFERENCES_UNKNOWN_LAYOUT:
return String.format(Messages.appDescriptorUnknownLayoutPage,
context.get(StatusContext.LIVING_APPLICATION_TOKEN_KEY),
context.get(StatusContext.LIVING_APPLICATION_INVALID_ELEMENT_NAME));
case LIVING_APP_REFERENCES_UNKNOWN_THEME:
return String.format(Messages.appDescriptorUnknownTheme,
context.get(StatusContext.LIVING_APPLICATION_TOKEN_KEY),
context.get(StatusContext.LIVING_APPLICATION_INVALID_ELEMENT_NAME));
default:
return super.localizedMessage(status);
}
}
}
......@@ -16,7 +16,10 @@ package org.bonitasoft.studio.ui.dialog;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
......@@ -27,6 +30,7 @@ import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
......@@ -37,6 +41,16 @@ public class MultiStatusDialog extends ProblemsDialog<IStatus> {
private MultiStatus status;
private Predicate<IStatus> canFinish;
private int finishId;
private int level = IStatus.OK;
private static final Map<Integer,Integer> STATUS_LEVEL = new HashMap<>();
static {
STATUS_LEVEL.put(IStatus.CANCEL, 0);
STATUS_LEVEL.put(IStatus.ERROR, 1);
STATUS_LEVEL.put(IStatus.WARNING, 2);
STATUS_LEVEL.put(IStatus.INFO, 3);
STATUS_LEVEL.put(IStatus.OK, 4);
}
public MultiStatusDialog(Shell parentShell, String dialogTitle,
String dialogMessage,
......@@ -118,18 +132,20 @@ public class MultiStatusDialog extends ProblemsDialog<IStatus> {
}
};
}
@Override
protected ViewerComparator getComparator() {
return null;
}
/*
* (non-Javadoc)
* @see org.bonitasoft.studio.common.jface.dialog.ProblemsDialog#getInput()
*/
@Override
protected Collection<IStatus> getInput() {
return Stream
.of(status.getChildren())
.map(this::getChildren)
.flatMap(Collection::stream)
.sorted((s1, s2) -> -Integer.valueOf(s1.getSeverity()).compareTo(Integer.valueOf(s2.getSeverity())))
.filter(s -> STATUS_LEVEL.get(s.getSeverity()) <= level)
.sorted(new StatusSeverityComparator())
.collect(Collectors.toList());
}
......@@ -138,9 +154,24 @@ public class MultiStatusDialog extends ProblemsDialog<IStatus> {
return Arrays.asList(status.getChildren()).stream()
.map(this::getChildren)
.flatMap(Collection::stream)
.filter(s -> STATUS_LEVEL.get(s.getSeverity()) <= level)
.sorted(new StatusSeverityComparator())
.collect(Collectors.toList());
}
return Arrays.asList(status);
}
public void setLevel(int level) {
this.level = level;
}
static class StatusSeverityComparator implements Comparator<IStatus> {
@Override
public int compare(IStatus s1, IStatus s2) {
return STATUS_LEVEL.get(s1.getSeverity()).compareTo(STATUS_LEVEL.get(s2.getSeverity()));
}
}
}
/**
* Copyright (C) 2019 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.studio.ui.widget;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.eclipse.jface.fieldassist.IControlContentAdapter;
import org.eclipse.swt.widgets.Control;
public class CustomContentProposalAdapter extends ContentProposalAdapter {
public CustomContentProposalAdapter(Control control, IControlContentAdapter controlContentAdapter,
IContentProposalProvider proposalProvider, KeyStroke keyStroke, char[] autoActivationCharacters) {
super(control, controlContentAdapter, proposalProvider, keyStroke, autoActivationCharacters);
}
@Override
public void openProposalPopup() {
super.openProposalPopup();
}
}
......@@ -29,7 +29,6 @@ import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.value.ComputedValue;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
......@@ -39,10 +38,8 @@ import org.eclipse.jface.fieldassist.IContentProposalProvider;
import org.eclipse.jface.fieldassist.TextContentAdapter;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.layout.LayoutConstants;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
......@@ -52,7 +49,6 @@ import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
......@@ -316,21 +312,15 @@ public class TextWidget extends EditableControlWidget {
proposalProvider.ifPresent(provider -> {
final TextContentAdapter controlContentAdapter = new TextContentAdapter();
final KeyStroke keyStroke = KeyStroke.getInstance(SWT.MOD1, SWT.SPACE);
final ContentProposalAdapter proposalAdapter = new ContentProposalAdapter(text,
final CustomContentProposalAdapter proposalAdapter = new CustomContentProposalAdapter(text,
controlContentAdapter,
provider,
keyStroke,
null,
null);
proposalAdapter.setPropagateKeys(true);
proposalAdapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
proposalAdapter.setAutoActivationDelay(0);
text.addListener(SWT.FocusIn, e -> fireControlSpaceEvent(proposalAdapter,null));
text.addListener(SWT.KeyDown, e -> {
if (text.isFocusControl()) {
fireControlSpaceEvent(proposalAdapter, e);
}
});
text.addListener(SWT.FocusIn, e -> openProposalPopup(proposalAdapter));
});
text.addListener(SWT.FocusIn, event -> redraw(textContainer));
......@@ -384,14 +374,11 @@ public class TextWidget extends EditableControlWidget {
return textContainer;
}
private void fireControlSpaceEvent(ContentProposalAdapter proposalAdapter, Event e) {
private void openProposalPopup(CustomContentProposalAdapter proposalAdapter) {
text.getDisplay().asyncExec(() -> {
if (!text.isDisposed() && proposalAdapter != null && !proposalAdapter.isProposalPopupOpen()) {
if((e == null && text.getText() == null || text.getText().isEmpty()) ||( e != null && e.doit)) {
final Event ctrlSpaceEvent = new Event();
ctrlSpaceEvent.keyCode = SWT.SPACE;
ctrlSpaceEvent.stateMask = SWT.MOD1;
text.notifyListeners(SWT.KeyDown, ctrlSpaceEvent);
if(text.getText() == null || text.getText().isEmpty()) {
proposalAdapter.openProposalPopup();
}
}
});
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment