Skip to content
This repository was archived by the owner on Apr 23, 2025. It is now read-only.

Commit 6d7e8db

Browse files
committed
feat: validate new project name (#237)
Signed-off-by: Andre Dietisheim <[email protected]>
1 parent 3aaa623 commit 6d7e8db

File tree

6 files changed

+251
-68
lines changed

6 files changed

+251
-68
lines changed

src/main/java/org/jboss/tools/intellij/openshift/actions/project/ChangeActiveProjectAction.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ private void doActionPerformed(final ApplicationsRootNode rootNode, final Point
7676
throw new RuntimeException(e);
7777
}
7878
}, SwingUtils.EXECUTOR_BACKGROUND)
79-
.handleAsync((ClusterProjects, error) -> {
79+
.handleAsync((clusterProjects, error) -> {
8080
if (error != null) {
8181
return null;
8282
}
83-
ChangeActiveProjectDialog dialog = openActiveProjectDialog(ClusterProjects.isOpenShift, ClusterProjects.current, ClusterProjects.all, location, project);
83+
ChangeActiveProjectDialog dialog = openActiveProjectDialog(clusterProjects.isOpenShift, clusterProjects.current, clusterProjects.all, location, project);
8484
if (dialog.isOK()) {
8585
return new ChangeActiveProjectOperation(dialog.getActiveProject(), odo);
8686
} else if (dialog.isCreateNewProject()) {

src/main/java/org/jboss/tools/intellij/openshift/actions/project/CreateProjectAction.java

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,17 @@
1919
import org.jboss.tools.intellij.openshift.actions.ActionUtils;
2020
import org.jboss.tools.intellij.openshift.actions.NotificationUtils;
2121
import org.jboss.tools.intellij.openshift.actions.cluster.LoggedInClusterAction;
22+
import org.jboss.tools.intellij.openshift.telemetry.TelemetryService;
2223
import org.jboss.tools.intellij.openshift.tree.application.ApplicationsRootNode;
24+
import org.jboss.tools.intellij.openshift.ui.SwingUtils;
25+
import org.jboss.tools.intellij.openshift.ui.project.CreateNewProjectDialog;
2326
import org.jboss.tools.intellij.openshift.utils.odo.Odo;
2427
import org.jetbrains.annotations.NotNull;
2528

29+
import java.awt.Point;
2630
import java.io.IOException;
31+
import java.util.List;
32+
import java.util.concurrent.CompletableFuture;
2733
import java.util.concurrent.CompletionException;
2834

2935
import static org.jboss.tools.intellij.openshift.actions.ActionUtils.runWithProgress;
@@ -40,35 +46,69 @@ public static void execute(ApplicationsRootNode rootNode) {
4046
return;
4147
}
4248
CreateProjectAction action = ActionUtils.createAction(CreateProjectAction.class.getName());
43-
action.doActionPerformed(rootNode, odo, rootNode.getProject());
49+
action.doActionPerformed(null, odo, rootNode.getProject());
4450
}
4551

4652
@Override
4753
public void actionPerformedOnSelectedObject(AnActionEvent anActionEvent, Object selected, @NotNull Odo odo) {
48-
ApplicationsRootNode clusterNode = (ApplicationsRootNode) selected;
49-
doActionPerformed(clusterNode, odo, getEventProject(anActionEvent));
54+
Point location = ActionUtils.getLocation(anActionEvent);
55+
doActionPerformed(location, odo, getEventProject(anActionEvent));
5056
}
5157

52-
private void doActionPerformed(ApplicationsRootNode clusterNode, Odo odo, Project project) {
53-
String projectName = Messages.showInputDialog("Project name", "New Project", Messages.getQuestionIcon());
54-
if ((projectName == null) || projectName.trim().isEmpty()) {
55-
sendTelemetryResults(TelemetryResult.ABORTED);
56-
return;
57-
}
58-
runWithProgress((ProgressIndicator progress) -> {
59-
try {
60-
Notification notif = NotificationUtils.notifyInformation("Create Project", "Creating project " + projectName);
61-
odo.createProject(projectName);
62-
notif.expire();
63-
NotificationUtils.notifyInformation("Create Project", "Project " + projectName + " successfully created");
64-
clusterNode.getStructure().fireModified(clusterNode);
58+
private void doActionPerformed(final Point location, final Odo odo, Project project) {
59+
runWithProgress((ProgressIndicator progress) ->
60+
CompletableFuture
61+
.supplyAsync(() -> {
62+
try {
63+
return odo.getNamespaces();
64+
} catch (IOException e) {
65+
NotificationUtils.notifyError("Create New Project", "Could not get projects: " + e.getMessage());
66+
sendTelemetryError(e.getMessage());
67+
throw new CompletionException(e);
68+
}
69+
}, SwingUtils.EXECUTOR_BACKGROUND)
70+
.handleAsync((allProjects, error) -> {
71+
if (error != null) {
72+
return null;
73+
}
74+
CreateNewProjectDialog dialog = openCreateProjectDialog(allProjects, location, project);
75+
if (dialog.isOK()) {
76+
return dialog.getNewProject();
77+
} else {
78+
sendTelemetryResults(TelemetryService.TelemetryResult.ABORTED);
79+
return null;
80+
}
81+
}
82+
, SwingUtils.EXECUTOR_UI)
83+
.whenCompleteAsync((newProject, error) -> {
84+
if (error != null
85+
|| newProject == null) {
86+
return;
87+
}
88+
createProject(newProject, odo);
89+
}, SwingUtils.EXECUTOR_BACKGROUND),
90+
"Create Active Project...",
91+
project);
92+
}
93+
94+
private void createProject(String newProject, Odo odo) {
95+
Notification notification = NotificationUtils.notifyInformation("Create Project", "Creating project " + newProject);
96+
try {
97+
odo.createProject(newProject);
98+
notification.expire();
99+
NotificationUtils.notifyInformation("Create Project", "Project " + newProject + " successfully created");
65100
sendTelemetryResults(TelemetryResult.SUCCESS);
66101
} catch (IOException | CompletionException e) {
102+
notification.expire();
67103
sendTelemetryError(e);
68104
UIHelper.executeInUI(() -> Messages.showErrorDialog("Error: " + e.getLocalizedMessage(), "Create Project"));
69105
}
70-
},
71-
"Create Project...",
72-
project);
73106
}
107+
108+
private CreateNewProjectDialog openCreateProjectDialog(List<String> allProjects, Point location, Project project) {
109+
CreateNewProjectDialog dialog = new CreateNewProjectDialog(project, allProjects, location);
110+
dialog.show();
111+
return dialog;
112+
}
113+
74114
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 Red Hat, Inc.
3+
* Distributed under license by Red Hat, Inc. All rights reserved.
4+
* This program is made available under the terms of the
5+
* Eclipse Public License v2.0 which accompanies this distribution,
6+
* and is available at http://www.eclipse.org/legal/epl-v20.html
7+
*
8+
* Contributors:
9+
* Red Hat, Inc. - initial API and implementation
10+
******************************************************************************/
11+
package org.jboss.tools.intellij.openshift.ui;
12+
13+
import com.intellij.openapi.actionSystem.ActionManager;
14+
import com.intellij.openapi.actionSystem.AnAction;
15+
import com.intellij.openapi.actionSystem.CommonShortcuts;
16+
import com.intellij.openapi.actionSystem.IdeActions;
17+
import com.intellij.openapi.project.DumbAwareAction;
18+
import com.intellij.openapi.project.Project;
19+
import com.intellij.openapi.ui.DialogWrapper;
20+
import com.intellij.ui.PopupBorder;
21+
import org.jetbrains.annotations.Nullable;
22+
23+
import javax.swing.JRootPane;
24+
import javax.swing.RootPaneContainer;
25+
import java.awt.Point;
26+
import java.awt.Window;
27+
28+
import static org.jboss.tools.intellij.openshift.ui.SwingUtils.locationOrMouseLocation;
29+
30+
public abstract class BaseDialog extends DialogWrapper {
31+
32+
private final Point location;
33+
34+
protected BaseDialog(@Nullable Project project, Point location) {
35+
super(project, false);
36+
this.location = location;
37+
init();
38+
}
39+
40+
@Override
41+
protected void init() {
42+
super.init();
43+
Window dialogWindow = getPeer().getWindow();
44+
JRootPane rootPane = ((RootPaneContainer) dialogWindow).getRootPane();
45+
registerShortcuts(rootPane);
46+
setBorders(rootPane);
47+
setLocation(locationOrMouseLocation(location));
48+
}
49+
50+
private void registerShortcuts(JRootPane rootPane) {
51+
AnAction escape = ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_ESCAPE);
52+
DumbAwareAction.create(e -> closeImmediately())
53+
.registerCustomShortcutSet(
54+
escape == null ? CommonShortcuts.ESCAPE : escape.getShortcutSet(),
55+
rootPane,
56+
myDisposable);
57+
}
58+
59+
private void setBorders(JRootPane rootPane) {
60+
rootPane.setBorder(PopupBorder.Factory.create(true, true));
61+
rootPane.setWindowDecorationStyle(JRootPane.NONE);
62+
}
63+
64+
protected void closeImmediately() {
65+
if (isVisible()) {
66+
doCancelAction();
67+
}
68+
}
69+
}

src/main/java/org/jboss/tools/intellij/openshift/ui/SwingUtils.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
import java.awt.Component;
3939
import java.awt.Dimension;
4040
import java.awt.Font;
41+
import java.awt.MouseInfo;
42+
import java.awt.Point;
4143
import java.util.concurrent.Executor;
4244
import java.util.regex.Matcher;
4345
import java.util.regex.Pattern;
@@ -140,4 +142,11 @@ public static void setMovable(JRootPane rootPane, JComponent... movableComponent
140142
component -> component.addMouseListener(windowMoveListener));
141143
}
142144

145+
public static Point locationOrMouseLocation(Point location) {
146+
if (location == null) {
147+
location = MouseInfo.getPointerInfo().getLocation();
148+
}
149+
return location;
150+
}
151+
143152
}

src/main/java/org/jboss/tools/intellij/openshift/ui/project/ChangeActiveProjectDialog.java

Lines changed: 3 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -10,50 +10,39 @@
1010
******************************************************************************/
1111
package org.jboss.tools.intellij.openshift.ui.project;
1212

13-
import com.intellij.openapi.actionSystem.ActionManager;
14-
import com.intellij.openapi.actionSystem.AnAction;
15-
import com.intellij.openapi.actionSystem.CommonShortcuts;
16-
import com.intellij.openapi.actionSystem.IdeActions;
17-
import com.intellij.openapi.project.DumbAwareAction;
1813
import com.intellij.openapi.project.Project;
1914
import com.intellij.openapi.ui.ComponentValidator;
20-
import com.intellij.openapi.ui.DialogWrapper;
2115
import com.intellij.openapi.ui.ValidationInfo;
2216
import com.intellij.openapi.util.text.StringUtil;
23-
import com.intellij.ui.PopupBorder;
2417
import com.intellij.ui.TextFieldWithAutoCompletion;
2518
import com.intellij.ui.TextFieldWithAutoCompletionListProvider;
2619
import com.intellij.ui.components.JBLabel;
2720
import com.intellij.util.textCompletion.TextFieldWithCompletion;
2821
import com.intellij.util.ui.JBUI;
2922
import net.miginfocom.swing.MigLayout;
23+
import org.jboss.tools.intellij.openshift.ui.BaseDialog;
3024
import org.jboss.tools.intellij.openshift.ui.SwingUtils;
3125
import org.jetbrains.annotations.NotNull;
3226
import org.jetbrains.annotations.Nullable;
3327

3428
import javax.swing.JComponent;
3529
import javax.swing.JLabel;
3630
import javax.swing.JPanel;
37-
import javax.swing.JRootPane;
38-
import javax.swing.RootPaneContainer;
3931
import javax.swing.SwingConstants;
40-
import java.awt.MouseInfo;
4132
import java.awt.Point;
42-
import java.awt.Window;
4333
import java.awt.event.MouseAdapter;
4434
import java.awt.event.MouseEvent;
4535
import java.awt.event.MouseListener;
4636
import java.util.Collection;
4737
import java.util.function.Supplier;
4838

49-
public class ChangeActiveProjectDialog extends DialogWrapper {
39+
public class ChangeActiveProjectDialog extends BaseDialog {
5040

5141
private static final String WIDTH = "300";
5242
private final Project project;
5343
private final String kind;
5444
private final String currentProject;
5545
private final Collection<String> allProjects;
56-
private final Point location;
5746
private TextFieldWithCompletion activeProjectTextField;
5847

5948
private String activeProject;
@@ -66,48 +55,21 @@ public ChangeActiveProjectDialog(
6655
String currentProject,
6756
Collection<String> allProjects,
6857
Point location) {
69-
super(project, false);
58+
super(project, location);
7059
this.project = project;
7160
this.kind = kind;
7261
this.currentProject = currentProject;
7362
this.allProjects = allProjects;
74-
this.location = location;
7563
init();
7664
}
7765

7866
@Override
7967
protected void init() {
8068
super.init();
81-
Window dialogWindow = getPeer().getWindow();
82-
JRootPane rootPane = ((RootPaneContainer) dialogWindow).getRootPane();
83-
registerShortcuts(rootPane);
8469
setOKButtonText("Change");
85-
setBorders(rootPane);
86-
setLocation(location);
8770
setTitle("Change Active " + kind);
8871
}
8972

90-
@Override
91-
public void setLocation(Point location) {
92-
if (location == null) {
93-
location = MouseInfo.getPointerInfo().getLocation();
94-
}
95-
super.setLocation(location);
96-
}
97-
98-
private void registerShortcuts(JRootPane rootPane) {
99-
AnAction escape = ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_ESCAPE);
100-
DumbAwareAction.create(e -> closeImmediately())
101-
.registerCustomShortcutSet(escape == null ?
102-
CommonShortcuts.ESCAPE
103-
: escape.getShortcutSet(), rootPane, myDisposable);
104-
}
105-
106-
private void setBorders(JRootPane rootPane) {
107-
rootPane.setBorder(PopupBorder.Factory.create(true, true));
108-
rootPane.setWindowDecorationStyle(JRootPane.NONE);
109-
}
110-
11173
@Override
11274
protected @Nullable JComponent createCenterPanel() {
11375
JComponent panel = new JPanel(new MigLayout(
@@ -156,12 +118,6 @@ private TextFieldWithAutoCompletionListProvider<String> onLookup(Collection<Stri
156118
};
157119
}
158120

159-
private void closeImmediately() {
160-
if (isVisible()) {
161-
doCancelAction();
162-
}
163-
}
164-
165121
@Override
166122
protected void doOKAction() {
167123
super.doOKAction();

0 commit comments

Comments
 (0)