/******************************************************************************* * Copyright (c) 2011, 2016 Eurotech and/or its affiliates * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Eurotech *******************************************************************************/ package org.eclipse.kura.web.client.ui.Packages; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.eclipse.kura.web.client.messages.Messages; import org.eclipse.kura.web.client.ui.EntryClassUi; import org.eclipse.kura.web.client.util.FailureHandler; import org.eclipse.kura.web.shared.model.GwtDeploymentPackage; import org.eclipse.kura.web.shared.model.GwtSession; import org.eclipse.kura.web.shared.model.GwtXSRFToken; import org.eclipse.kura.web.shared.service.GwtPackageService; import org.eclipse.kura.web.shared.service.GwtPackageServiceAsync; import org.eclipse.kura.web.shared.service.GwtSecurityTokenService; import org.eclipse.kura.web.shared.service.GwtSecurityTokenServiceAsync; import org.gwtbootstrap3.client.ui.Alert; import org.gwtbootstrap3.client.ui.Button; import org.gwtbootstrap3.client.ui.Modal; import org.gwtbootstrap3.client.ui.ModalBody; import org.gwtbootstrap3.client.ui.ModalFooter; import org.gwtbootstrap3.client.ui.TabListItem; import org.gwtbootstrap3.client.ui.TextBox; import org.gwtbootstrap3.client.ui.gwt.CellTable; import org.gwtbootstrap3.client.ui.html.Span; import org.gwtbootstrap3.client.ui.html.Text; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.cellview.client.TextColumn; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FileUpload; import com.google.gwt.user.client.ui.FormPanel; import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent; import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteHandler; import com.google.gwt.user.client.ui.Hidden; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.view.client.ListDataProvider; import com.google.gwt.view.client.SingleSelectionModel; public class PackagesPanelUi extends Composite { private static PackagesPanelUiUiBinder uiBinder = GWT.create(PackagesPanelUiUiBinder.class); private static final Logger logger = Logger.getLogger(PackagesPanelUi.class.getSimpleName()); private final GwtSecurityTokenServiceAsync gwtXSRFService = GWT.create(GwtSecurityTokenService.class); private final GwtPackageServiceAsync gwtPackageService = GWT.create(GwtPackageService.class); private static final String SERVLET_URL = "/" + GWT.getModuleName() + "/file/deploy"; private static final Messages MSGS = GWT.create(Messages.class); private int refreshRequests; private EntryClassUi entryClassUi; private final ListDataProvider<GwtDeploymentPackage> packagesDataProvider = new ListDataProvider<GwtDeploymentPackage>(); private final SingleSelectionModel<GwtDeploymentPackage> selectionModel = new SingleSelectionModel<GwtDeploymentPackage>(); private GwtSession gwtSession; private GwtDeploymentPackage selected; interface PackagesPanelUiUiBinder extends UiBinder<Widget, PackagesPanelUi> { } @UiField Modal uploadModal; @UiField FormPanel packagesFormFile, packagesFormUrl; @UiField Button fileCancel, fileSubmit, urlCancel, urlSubmit; @UiField TabListItem fileLabel; @UiField Alert notification; @UiField Modal uploadErrorModal; @UiField Text uploadErrorText; @UiField Button packagesRefresh, packagesInstall, packagesUninstall; @UiField CellTable<GwtDeploymentPackage> packagesGrid = new CellTable<GwtDeploymentPackage>(10); @UiField FileUpload filePath; @UiField TextBox formUrl; @UiField Hidden xsrfTokenFieldFile, xsrfTokenFieldUrl; public PackagesPanelUi() { // TODO - ServiceTree initWidget(uiBinder.createAndBindUi(this)); this.packagesGrid.setSelectionModel(this.selectionModel); initTable(); initTabButtons(); initModalHandlers(); initModal(); } public void setSession(GwtSession currentSession) { this.gwtSession = currentSession; } public void setMainUi(EntryClassUi entryClassUi) { this.entryClassUi = entryClassUi; } public void refresh() { refresh(100); } private void initTabButtons() { // Refresh Button this.packagesRefresh.setText(MSGS.refreshButton()); this.packagesRefresh.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { refresh(); } }); // Install Button this.packagesInstall.setText(MSGS.packageAddButton()); this.packagesInstall.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { upload(); } }); // Uninstall Button this.packagesUninstall.setText(MSGS.packageDeleteButton()); this.packagesUninstall.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { PackagesPanelUi.this.selected = PackagesPanelUi.this.selectionModel.getSelectedObject(); if (PackagesPanelUi.this.selected != null && PackagesPanelUi.this.selected.getVersion() != null) { final Modal modal = new Modal(); ModalBody modalBody = new ModalBody(); ModalFooter modalFooter = new ModalFooter(); modal.setClosable(true); modal.setTitle(MSGS.confirm()); modalBody.add(new Span(MSGS.deviceUninstallPackage(PackagesPanelUi.this.selected.getName()))); modalFooter.add(new Button("Yes", new ClickHandler() { @Override public void onClick(ClickEvent event) { modal.hide(); uninstall(PackagesPanelUi.this.selected); } })); modalFooter.add(new Button("No", new ClickHandler() { @Override public void onClick(ClickEvent event) { modal.hide(); } })); modal.add(modalBody); modal.add(modalFooter); modal.show(); } // end if null }// end on click }); } private void initModalHandlers() { this.fileSubmit.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { PackagesPanelUi.this.gwtXSRFService.generateSecurityToken(new AsyncCallback<GwtXSRFToken>() { @Override public void onFailure(Throwable ex) { FailureHandler.handle(ex); } @Override public void onSuccess(GwtXSRFToken token) { PackagesPanelUi.this.xsrfTokenFieldFile.setValue(token.getToken()); if (!"".equals(PackagesPanelUi.this.filePath.getFilename())) { PackagesPanelUi.this.packagesFormFile.submit(); } else { PackagesPanelUi.this.uploadModal.hide(); PackagesPanelUi.this.uploadErrorModal.show(); } } }); } }); this.fileCancel.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { PackagesPanelUi.this.uploadModal.hide(); } }); this.urlSubmit.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { PackagesPanelUi.this.gwtXSRFService.generateSecurityToken(new AsyncCallback<GwtXSRFToken>() { @Override public void onFailure(Throwable ex) { FailureHandler.handle(ex); } @Override public void onSuccess(GwtXSRFToken token) { if (!"".equals(PackagesPanelUi.this.formUrl.getValue())) { PackagesPanelUi.this.xsrfTokenFieldUrl.setValue(token.getToken()); PackagesPanelUi.this.packagesFormUrl.submit(); } else { PackagesPanelUi.this.uploadModal.hide(); PackagesPanelUi.this.uploadErrorModal.show(); } } }); } }); this.urlCancel.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { PackagesPanelUi.this.uploadModal.hide(); } }); } private void refresh(int delay) { Timer timer = new Timer() { @Override public void run() { if (PackagesPanelUi.this.refreshRequests == 0) { loadPackagesData(); PackagesPanelUi.this.refreshRequests++; } } }; timer.schedule(delay); } private void upload() { this.uploadModal.show(); // ******FILE TAB ****// this.fileLabel.setText(MSGS.fileLabel()); this.filePath.setName("uploadedFile"); this.xsrfTokenFieldFile.setID("xsrfToken"); this.xsrfTokenFieldFile.setName("xsrfToken"); this.xsrfTokenFieldFile.setValue(""); this.packagesFormFile.setAction(SERVLET_URL + "/upload"); this.packagesFormFile.setEncoding(FormPanel.ENCODING_MULTIPART); this.packagesFormFile.setMethod(FormPanel.METHOD_POST); this.packagesFormFile.addSubmitCompleteHandler(new SubmitCompleteHandler() { @Override public void onSubmitComplete(SubmitCompleteEvent event) { String result = event.getResults(); if (result == null || result.isEmpty()) { PackagesPanelUi.this.uploadModal.hide(); refresh(2500); } else { logger.log(Level.SEVERE, "Error uploading package!"); } } }); // ******URL TAB ****// this.formUrl.setName("packageUrl"); this.xsrfTokenFieldUrl.setID("xsrfToken"); this.xsrfTokenFieldUrl.setName("xsrfToken"); this.xsrfTokenFieldUrl.setValue(""); this.packagesFormUrl.setAction(SERVLET_URL + "/url"); this.packagesFormUrl.setMethod(FormPanel.METHOD_POST); this.packagesFormUrl.addSubmitCompleteHandler(new SubmitCompleteHandler() { @Override public void onSubmitComplete(SubmitCompleteEvent event) { String result = event.getResults(); if (result == null || result.isEmpty()) { PackagesPanelUi.this.uploadModal.hide(); refresh(2500); } else { String errMsg = result; int startIdx = result.indexOf("<pre>"); int endIndex = result.indexOf("</pre>"); if (startIdx != -1 && endIndex != -1) { errMsg = result.substring(startIdx + 5, endIndex); } logger.log(Level.SEVERE, MSGS.error() + ": " + MSGS.fileDownloadFailure() + ": " + errMsg); } } }); } private void uninstall(final GwtDeploymentPackage selected) { EntryClassUi.showWaitModal(); this.gwtXSRFService.generateSecurityToken(new AsyncCallback<GwtXSRFToken>() { @Override public void onFailure(Throwable ex) { EntryClassUi.hideWaitModal(); FailureHandler.handle(ex); } @Override public void onSuccess(GwtXSRFToken token) { PackagesPanelUi.this.gwtPackageService.uninstallDeploymentPackage(token, selected.getName(), new AsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { EntryClassUi.hideWaitModal(); FailureHandler.handle(caught); } @Override public void onSuccess(Void result) { refresh(1000); EntryClassUi.hideWaitModal(); } }); } }); } private void initTable() { TextColumn<GwtDeploymentPackage> col1 = new TextColumn<GwtDeploymentPackage>() { @Override public String getValue(GwtDeploymentPackage object) { return object.getName(); } }; col1.setCellStyleNames("status-table-row"); this.packagesGrid.addColumn(col1, "Name"); TextColumn<GwtDeploymentPackage> col2 = new TextColumn<GwtDeploymentPackage>() { @Override public String getValue(GwtDeploymentPackage object) { return object.getVersion(); } }; col2.setCellStyleNames("status-table-row"); this.packagesGrid.addColumn(col2, "Version"); this.packagesDataProvider.addDataDisplay(this.packagesGrid); } private void loadPackagesData() { this.packagesDataProvider.getList().clear(); EntryClassUi.showWaitModal(); this.gwtXSRFService.generateSecurityToken(new AsyncCallback<GwtXSRFToken>() { @Override public void onFailure(Throwable ex) { EntryClassUi.hideWaitModal(); FailureHandler.handle(ex); } @Override public void onSuccess(GwtXSRFToken token) { PackagesPanelUi.this.gwtPackageService.findDeviceDeploymentPackages(token, new AsyncCallback<List<GwtDeploymentPackage>>() { @Override public void onFailure(Throwable caught) { EntryClassUi.hideWaitModal(); GwtDeploymentPackage pkg = new GwtDeploymentPackage(); pkg.setName("Unavailable! Please click refresh"); pkg.setVersion(caught.getLocalizedMessage()); PackagesPanelUi.this.packagesDataProvider.getList().add(pkg); } @Override public void onSuccess(List<GwtDeploymentPackage> result) { for (GwtDeploymentPackage pair : result) { PackagesPanelUi.this.packagesDataProvider.getList().add(pair); } int size = PackagesPanelUi.this.packagesDataProvider.getList().size(); PackagesPanelUi.this.packagesGrid.setVisibleRange(0, size); PackagesPanelUi.this.packagesDataProvider.flush(); if (PackagesPanelUi.this.packagesDataProvider.getList().isEmpty()) { PackagesPanelUi.this.packagesGrid.setVisible(false); PackagesPanelUi.this.notification.setVisible(true); PackagesPanelUi.this.notification.setText(MSGS.devicePackagesNone()); } else { PackagesPanelUi.this.packagesGrid.setVisible(true); PackagesPanelUi.this.notification.setVisible(false); } if (PackagesPanelUi.this.entryClassUi != null) { PackagesPanelUi.this.entryClassUi.initServicesTree(); } PackagesPanelUi.this.refreshRequests--; EntryClassUi.hideWaitModal(); } }); } }); } private void initModal() { this.uploadErrorModal.setTitle(MSGS.warning()); this.uploadErrorText.setText(MSGS.missingFileUpload()); } }