blob: 1b0996da59848873ae73cfbbb3df7ba2b8ad89df [file] [log] [blame]
/**
* Copyright 2020-present NAVER Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.navercorp.openwhisk.intellij.wskdeploy.toolwindow.ui;
import com.intellij.notification.NotificationType;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.ActionToolbar;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.navercorp.openwhisk.intellij.common.notification.SimpleNotifier;
import com.navercorp.openwhisk.intellij.common.service.WskDeployService;
import com.navercorp.openwhisk.intellij.common.utils.EventUtils;
import com.navercorp.openwhisk.intellij.common.utils.ValidationUtils;
import com.navercorp.openwhisk.intellij.common.whisk.model.wskdeploy.*;
import com.navercorp.openwhisk.intellij.wskdeploy.dialog.WskDeployCmdDialog;
import com.navercorp.openwhisk.intellij.wskdeploy.toolwindow.listener.ChooseWskDeployBinaryListener;
import com.navercorp.openwhisk.intellij.wskdeploy.toolwindow.listener.RefreshWskDeployManifestListener;
import com.navercorp.openwhisk.intellij.wskdeploy.toolwindow.tree.WskDeployTreeCellRenderer;
import com.navercorp.openwhisk.intellij.wskdeploy.toolwindow.tree.WskDeployTreeModel;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class WskDeployWindowForm {
private static final Logger LOG = Logger.getInstance(WskDeployWindowForm.class);
private static final SimpleNotifier NOTIFIER = SimpleNotifier.getInstance();
private static final String WSKDEPLOY_URL = "https://github.com/apache/openwhisk-wskdeploy/releases";
private JPanel mainJPanel;
private JPanel actionsJPanel;
private JScrollPane contentsJPanel;
private JTree wskdeployJTree;
private JPanel downloadGuideJPanel;
private JLabel urlJLabel;
private WskDeployService wskDeployService;
public WskDeployWindowForm(Project project, ToolWindow toolWindow) {
this.wskDeployService = ServiceManager.getService(project, WskDeployService.class);
// Toolbar
String actionGroupName = "WskDeployWindow.Actions.Controls";
ActionManager actionManager = ActionManager.getInstance();
ActionGroup actionGroup = (ActionGroup) actionManager.getAction(actionGroupName);
ActionToolbar actionToolbar = actionManager.createActionToolbar("", actionGroup, true);
actionToolbar.setTargetComponent(actionsJPanel);
actionsJPanel.add(actionToolbar.getComponent());
// Download url for wskdeploy
urlJLabel.setText("<html> WskDeploy download : <a href=\\\"\\\">" + WSKDEPLOY_URL + "</a></html>");
urlJLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
urlJLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
try {
Desktop.getDesktop().browse(new URI(WSKDEPLOY_URL));
} catch (IOException | URISyntaxException ex) {
String msg = "Cannot open " + WSKDEPLOY_URL;
LOG.error(msg, ex);
NOTIFIER.notify(project, msg, NotificationType.ERROR);
}
}
});
setWskDeployTree(project, loadWskDeployManifest(project));
}
private void setWskDeployTree(Project project, List<WskDeployManifest> manifests) {
boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows"); // TODO make a global value
WskDeployFile wskDeployFile = loadRegisteredWskDeploy() // 1. Registered wskdeploy
.orElse(loadWskDeployFileFromLocal(isWindows)); // 2. Local wskdeploy
wskdeployJTree.setModel(new WskDeployTreeModel(wskDeployFile, manifests));
wskdeployJTree.setCellRenderer(new WskDeployTreeCellRenderer());
expandAllNode(wskdeployJTree);
wskdeployJTree.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() > 1) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) wskdeployJTree.getLastSelectedPathComponent();
Object userObject = node.getUserObject();
if (userObject instanceof WskDeployCmdDeploy) {
WskDeployCmdDeploy cmd = (WskDeployCmdDeploy) userObject;
if (new WskDeployCmdDialog(project, cmd).showAndGet()) {
LOG.info("WskDeployCmdDialog(deploy) closed");
}
} else if (userObject instanceof WskDeployCmdUndeploy) {
WskDeployCmdUndeploy cmd = (WskDeployCmdUndeploy) userObject;
if (new WskDeployCmdDialog(project, cmd).showAndGet()) {
LOG.info("WskDeployCmdDialog(undeploy) closed");
}
}
}
}
});
EventUtils.subscribe(project, project, RefreshWskDeployManifestListener.TOPIC, () -> {
WskDeployFile reloadedWskDeployFile = loadRegisteredWskDeploy() // 1. Registered wskdeploy
.orElse(loadWskDeployFileFromLocal(isWindows)); // 2. Local wskdeploy
wskdeployJTree.setModel(new WskDeployTreeModel(reloadedWskDeployFile, loadWskDeployManifest(project)));
expandAllNode(wskdeployJTree);
});
EventUtils.subscribe(project, project, ChooseWskDeployBinaryListener.TOPIC, (chosenWskDeployFile) -> {
WskDeployBinary wskDeployBinary = new WskDeployBinary(chosenWskDeployFile.getPath(), chosenWskDeployFile.getName());
wskDeployService.setWskdeployName(wskDeployBinary.getName());
wskDeployService.setWskdeployPath(wskDeployBinary.getFullPath());
wskDeployService.loadState(wskDeployService);
wskdeployJTree.setModel(new WskDeployTreeModel(wskDeployBinary, loadWskDeployManifest(project)));
expandAllNode(wskdeployJTree);
});
}
private Optional<WskDeployFile> loadRegisteredWskDeploy() {
if (wskDeployService.getWskdeployPath() != null && wskDeployService.getWskdeployName() != null) {
VirtualFile file = LocalFileSystem.getInstance().findFileByPath(wskDeployService.getWskdeployPath());
return ValidationUtils.validateWskDeploy(Optional.ofNullable(file))
.map(validWskDeploy -> new WskDeployBinary(validWskDeploy.getPath(), validWskDeploy.getName()));
} else {
return Optional.empty();
}
}
private WskDeployFile loadWskDeployFileFromLocal(boolean isWindow) {
String[] dirs;
if (isWindow) {
dirs = new String[]{};
} else {
dirs = new String[]{"/usr/local/bin", "/usr/bin"};
}
for (String dir : dirs) {
File[] files = findFiles(dir, "wskdeploy");
if (files != null && files.length > 0) {
VirtualFile file = LocalFileSystem.getInstance().findFileByIoFile(files[0]);
Optional<WskDeployBinary> wskDeployBinary = ValidationUtils.validateWskDeploy(Optional.ofNullable(file))
.map(validWskDeploy -> new WskDeployBinary(validWskDeploy.getPath(), validWskDeploy.getName()));
if (wskDeployBinary.isPresent()) {
return wskDeployBinary.get();
}
}
}
return new NullWskDeployBinary();
}
private File[] findFiles(String parentDir, String fileName) {
File dir = new File(parentDir);
return dir.listFiles((dir1, name) -> name.startsWith(fileName));
}
private void expandAllNode(JTree tree) {
for (int i = 0; i < tree.getRowCount(); i++) {
tree.expandRow(i);
}
}
private List<WskDeployManifest> loadWskDeployManifest(Project project) {
List<WskDeployManifest> manifests = new ArrayList<>();
Collection<VirtualFile> yamlFiles = FilenameIndex.getAllFilesByExt(project, "yaml", GlobalSearchScope.projectScope(project));
Collection<VirtualFile> ymlFiles = FilenameIndex.getAllFilesByExt(project, "yml", GlobalSearchScope.projectScope(project));
List<VirtualFile> files = Stream.of(yamlFiles, ymlFiles).flatMap(Collection::stream).collect(Collectors.toList());
for (VirtualFile f : files) {
String fullPath = f.getPath();
String path = fullPath.replaceAll(project.getBasePath() + "/", "");
String name = f.getName();
manifests.add(new WskDeployManifest(path, fullPath, name));
}
return manifests;
}
public JPanel getContent() {
return mainJPanel;
}
}