package com.constellio.app.ui.pages.management.updates;
import static com.constellio.app.ui.i18n.i18n.$;
import java.awt.*;
import java.io.OutputStream;
import java.util.List;
import com.constellio.app.ui.framework.buttons.ConfirmDialogButton;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import com.constellio.app.api.extensions.UpdateModeExtension.UpdateModeHandler;
import com.constellio.app.entities.modules.ProgressInfo;
import com.constellio.app.services.appManagement.AppManagementService.LicenseInfo;
import com.constellio.app.services.recovery.UpdateRecoveryImpossibleCause;
import com.constellio.app.ui.framework.buttons.LinkButton;
import com.constellio.app.ui.framework.buttons.WindowButton;
import com.constellio.app.ui.framework.buttons.WindowButton.WindowConfiguration;
import com.constellio.app.ui.framework.components.LocalDateLabel;
import com.constellio.app.ui.pages.base.BaseViewImpl;
import com.constellio.app.ui.util.ComponentTreeUtils;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptAll;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.server.ExternalResource;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Link;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.UI;
import com.vaadin.ui.Upload;
import com.vaadin.ui.Upload.Receiver;
import com.vaadin.ui.Upload.SucceededEvent;
import com.vaadin.ui.Upload.SucceededListener;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.themes.ValoTheme;
import org.vaadin.dialogs.ConfirmDialog;
public class UpdateManagerViewImpl extends BaseViewImpl implements UpdateManagerView, DropHandler {
private final UpdateManagerPresenter presenter;
private UploadWaitWindow uploadWaitWindow;
private VerticalLayout layout;
private Component panel;
private Button license;
private Button standardUpdate;
private Button alternateUpdate;
private ConfirmDialogButton reindex;
public UpdateManagerViewImpl() {
presenter = new UpdateManagerPresenter(this);
}
@Override
protected String getTitle() {
return $("UpdateManagerViewImpl.viewTitle");
}
@Override
protected List<Button> buildActionMenuButtons(ViewChangeEvent event) {
List<Button> buttons = super.buildActionMenuButtons(event);
ConfirmDialogButton restart = new ConfirmDialogButton($("UpdateManagerViewImpl.restartButton")) {
@Override
protected String getConfirmDialogMessage() {
return $("UpdateManagerViewImpl.restartwarning");
}
@Override
protected void confirmButtonClick(ConfirmDialog dialog) {
presenter.restart();
}
};
restart.setDialogMode(ConfirmDialogButton.DialogMode.WARNING);
buttons.add(restart);
reindex = new ConfirmDialogButton($("UpdateManagerViewImpl.restartAndReindexButton")) {
@Override
protected String getConfirmDialogMessage() {
return $("UpdateManagerViewImpl.reindexwarning");
}
@Override
protected void confirmButtonClick(ConfirmDialog dialog) {
presenter.restartAndReindex();
}
};
reindex.setDialogMode(ConfirmDialogButton.DialogMode.WARNING);
reindex.setEnabled(presenter.isRestartWithReindexButtonEnabled());
buttons.add(reindex);
standardUpdate = new Button($("UpdateManagerViewImpl.automatic"));
standardUpdate.addClickListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
presenter.standardUpdateRequested();
}
});
buttons.add(standardUpdate);
alternateUpdate = new Button($("UpdateManagerViewImpl." + presenter.getAlternateUpdateName()));
alternateUpdate.addClickListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
presenter.alternateUpdateRequested();
}
});
alternateUpdate.setVisible(presenter.isAlternateUpdateAvailable());
buttons.add(alternateUpdate);
license = new Button($("UpdateManagerViewImpl.licenseButton"));
license.addClickListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
presenter.licenseUpdateRequested();
}
});
buttons.add(license);
return buttons;
}
@Override
protected Component buildMainComponent(ViewChangeEvent event) {
layout = new VerticalLayout(buildInfoItem($("UpdateManagerViewImpl.version"), presenter.getCurrentVersion()));
layout.setSpacing(true);
layout.setWidth("100%");
LicenseInfo info = presenter.getLicenseInfo();
if (info != null) {
layout.addComponents(
buildInfoItem($("UpdateManagerViewImpl.clientName"), info.getClientName()),
buildInfoItem($("UpdateManagerViewImpl.expirationDate"), info.getExpirationDate()));
}
Component messagePanel = buildMessagePanel();
layout.addComponent(messagePanel);
panel = new VerticalLayout();
layout.addComponent(panel);
layout.setSpacing(true);
showStandardUpdatePanel();
return layout;
}
private Component buildMessagePanel() {
VerticalLayout verticalLayout = new VerticalLayout();
UpdateRecoveryImpossibleCause cause = presenter.isUpdateWithRecoveryPossible();
if (cause != null) {
verticalLayout.addComponent(
new Label("<p style=\"color:red\">" + $("UpdateManagerViewImpl." + cause) + "</p>", ContentMode.HTML));
} else {
UpdateNotRecommendedReason updateNotRecommendedReason = presenter.getUpdateNotRecommendedReason();
if (updateNotRecommendedReason != null) {
verticalLayout.addComponent(
new Label("<p style=\"color:red\">" + $("UpdateManagerViewImpl." + updateNotRecommendedReason) + "</p>",
ContentMode.HTML));
}
}
final String exceptionDuringLastUpdate = presenter.getExceptionDuringLastUpdate();
if (StringUtils.isNotBlank(exceptionDuringLastUpdate)) {
verticalLayout.addComponent(new Label(
"<p style=\"color:red\">" + $("UpdateManagerViewImpl.exceptionCausedByLastVersion")+ "</p>", ContentMode.HTML));
WindowButton windowButton = new WindowButton($("details"), $("details"), WindowConfiguration.modalDialog("90%", "90%")) {
@Override
protected Component buildWindowContent() {
TextArea textArea = new TextArea();
textArea.setSizeFull();
textArea.setValue(exceptionDuringLastUpdate);
return textArea;
}
};
windowButton.addStyleName(ValoTheme.BUTTON_LINK);
verticalLayout.addComponent(windowButton);
verticalLayout.addComponent(new Label(
"<p style=\"color:red\">" + "" + "</p>", ContentMode.HTML));
}
return verticalLayout;
}
@Override
public void showStandardUpdatePanel() {
Component updatePanel = presenter.isLicensedForAutomaticUpdate() ? buildAutomaticUpdateLayout() : buildUnlicensedLayout();
layout.replaceComponent(panel, updatePanel);
license.setEnabled(true);
standardUpdate.setEnabled(false);
alternateUpdate.setEnabled(presenter.isUpdateEnabled());
panel = updatePanel;
}
@Override
public void showAlternateUpdatePanel(UpdateModeHandler handler) {
Component updatePanel = handler.buildUpdatePanel();
layout.replaceComponent(panel, updatePanel);
license.setEnabled(true);
reindex.setEnabled(presenter.isRestartWithReindexButtonEnabled());
standardUpdate.setEnabled(presenter.isUpdateEnabled());
alternateUpdate.setEnabled(false);
panel = updatePanel;
}
@Override
public void showLicenseUploadPanel() {
Component licensePanel = buildLicenseUploadPanel();
layout.replaceComponent(panel, licensePanel);
license.setEnabled(false);
reindex.setEnabled(presenter.isRestartWithReindexButtonEnabled());
boolean uploadPossible = presenter.isUpdateEnabled();
standardUpdate.setEnabled(uploadPossible);
alternateUpdate.setEnabled(uploadPossible);
panel = licensePanel;
}
@Override
public void showRestartRequiredPanel() {
Component restartPanel = buildRestartRequiredPanel();
layout.replaceComponent(panel, restartPanel);
license.setEnabled(false);
reindex.setEnabled(presenter.isRestartWithReindexButtonEnabled());
standardUpdate.setEnabled(false);
alternateUpdate.setEnabled(false);
panel = restartPanel;
}
private Component buildInfoItem(String caption, Object value) {
Label captionLabel = new Label(caption);
captionLabel.addStyleName(ValoTheme.LABEL_BOLD);
Label valueLabel = value instanceof LocalDate ? new LocalDateLabel((LocalDate) value) : new Label(value.toString());
HorizontalLayout layout = new HorizontalLayout(captionLabel, valueLabel);
layout.setSpacing(true);
return layout;
}
private Component buildAutomaticUpdateLayout() {
return presenter.isAutomaticUpdateAvailable() ? buildAvailableUpdateLayout() : buildUpToDateUpdateLayout();
}
private Component buildAvailableUpdateLayout() {
Label message = new Label($("UpdateManagerViewImpl.updateAvailable", presenter.getUpdateVersion()));
message.addStyleName(ValoTheme.LABEL_BOLD);
Button update = new LinkButton($("UpdateManagerViewImpl.updateButton")) {
@Override
protected void buttonClick(ClickEvent event) {
UI.getCurrent().access(new Thread(UpdateManagerViewImpl.class.getName() + "-updateFromServer") {
@Override
public void run() {
presenter.updateFromServer();
}
});
}
};
update.setVisible(presenter.isUpdateEnabled());
HorizontalLayout updater = new HorizontalLayout(message, update);
updater.setComponentAlignment(message, Alignment.MIDDLE_LEFT);
updater.setComponentAlignment(update, Alignment.MIDDLE_LEFT);
updater.setSpacing(true);
Label changelog = new Label(presenter.getChangelog(), ContentMode.HTML);
VerticalLayout layout = new VerticalLayout(updater, changelog);
layout.setSpacing(true);
layout.setWidth("100%");
return layout;
}
@Override
public ProgressInfo openProgressPopup() {
uploadWaitWindow = new UploadWaitWindow();
final ProgressInfo progressInfo = new ProgressInfo() {
@Override
public void setTask(String task) {
uploadWaitWindow.setTask(task);
}
@Override
public void setProgressMessage(String progressMessage) {
uploadWaitWindow.setProgressMessage(progressMessage);
}
};
UI.getCurrent().addWindow(uploadWaitWindow);
return progressInfo;
}
@Override
public void closeProgressPopup() {
uploadWaitWindow.close();
}
private Component buildUpToDateUpdateLayout() {
Label message = new Label($("UpdateManagerViewImpl.upToDate"));
message.addStyleName(ValoTheme.LABEL_BOLD);
return message;
}
private Component buildUnlicensedLayout() {
Label message = new Label($("UpdateManagerViewImpl.unlicensed"));
message.addStyleName(ValoTheme.LABEL_BOLD);
Link request = new Link($("UpdateManagerViewImpl.requestLicense"),
new ExternalResource("mailto:sales@constellio.com?Subject=Demande de license Constellio"));
VerticalLayout layout = new VerticalLayout(message, request);
layout.setSpacing(true);
return layout;
}
private Component buildLicenseUploadPanel() {
Upload upload = new Upload($("UpdateManagerViewImpl.uploadLicenseCaption"), new Receiver() {
@Override
public OutputStream receiveUpload(String filename, String mimeType) {
return presenter.getLicenseOutputStream();
}
});
upload.addSucceededListener(new SucceededListener() {
@Override
public void uploadSucceeded(SucceededEvent event) {
presenter.licenseUploadSucceeded();
}
});
upload.setButtonCaption($("UpdateManagerViewImpl.uploadLicense"));
Button cancel = new LinkButton($("cancel")) {
@Override
protected void buttonClick(ClickEvent event) {
presenter.licenseUploadCancelled();
}
};
VerticalLayout layout = new VerticalLayout(upload, cancel);
layout.setWidth("100%");
layout.setSpacing(true);
return layout;
}
private Component buildRestartRequiredPanel() {
return new Label("<p style=\"color:red\">" + $("UpdateManagerViewImpl.restart") + "</p>", ContentMode.HTML);
}
@Override
public void drop(DragAndDropEvent event) {
DropHandler childDropHandler = ComponentTreeUtils.getFirstChild((Component) panel, DropHandler.class);
if (panel instanceof DropHandler) {
((DropHandler) panel).drop(event);
} else if (childDropHandler != null) {
childDropHandler.drop(event);
}
}
@Override
public AcceptCriterion getAcceptCriterion() {
return AcceptAll.get();
}
}