Skip to content

Commit f19caf1

Browse files
committed
Patch for user input validation when using commands 'Java: New Project...' and 'Java: New File from Template...'.
1 parent e2b966b commit f19caf1

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed

build.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
patches/8260.diff
5757
patches/8280.diff
5858
patches/8289.diff
59+
patches/7893-draft.diff
5960
patches/disable-error-notification.diff
6061
patches/mvn-sh.diff
6162
patches/project-marker-jdk.diff

patches/7893-draft.diff

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/LspTemplateUI.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/LspTemplateUI.java
2+
index 891bfa328d..ed80b903a5 100644
3+
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/LspTemplateUI.java
4+
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/LspTemplateUI.java
5+
@@ -27,6 +27,7 @@ import java.net.MalformedURLException;
6+
import java.net.URI;
7+
import java.net.URISyntaxException;
8+
import java.net.URL;
9+
+import java.nio.file.Paths;
10+
import java.util.ArrayList;
11+
import java.util.Arrays;
12+
import java.util.Collections;
13+
@@ -39,6 +40,7 @@ import java.util.function.Function;
14+
import java.util.logging.Level;
15+
import java.util.logging.Logger;
16+
import java.util.stream.Collectors;
17+
+import javax.lang.model.SourceVersion;
18+
import org.eclipse.lsp4j.ExecuteCommandParams;
19+
import org.eclipse.lsp4j.MessageParams;
20+
import org.eclipse.lsp4j.MessageType;
21+
@@ -73,14 +75,21 @@ import org.openide.util.Utilities;
22+
"CTL_TemplateUI_SelectGroup=Select Template Type",
23+
"CTL_TemplateUI_SelectTemplate=Select Template",
24+
"CTL_TemplateUI_SelectTarget=Where to put the object?",
25+
- "CTL_TemplateUI_SelectProjectTarget=Specify the project directory",
26+
+ "CTL_TemplateUI_SelectProjectTarget=Specify the new project directory",
27+
"CTL_TemplateUI_SelectPackageName=Package name of your project?",
28+
"CTL_TemplateUI_SelectPackageNameSuggestion=org.yourcompany.yourproject",
29+
"CTL_TemplateUI_SelectName=Name of the object?",
30+
"# {0} - path",
31+
- "ERR_InvalidPath={0} isn't valid folder",
32+
+ "ERR_InvalidPath={0} isn't a valid folder or is read-only",
33+
"# {0} - path",
34+
"ERR_ExistingPath={0} already exists",
35+
+ "# {0} - packageName",
36+
+ "ERR_InvalidPackageName={0} isn't valid package name",
37+
+ "# {0} - path",
38+
+ "ERR_InvalidNewPath={0} isn't a valid path or is read-only",
39+
+ "# {0} - ObjectName",
40+
+ "ERR_InvalidObjectName={0} isn't valid object name"
41+
+
42+
})
43+
final class LspTemplateUI {
44+
/**
45+
@@ -165,8 +174,20 @@ final class LspTemplateUI {
46+
}
47+
48+
private static CompletionStage<String> findPackage(CompletionStage<?> uiBefore, NbCodeLanguageClient client) {
49+
- return uiBefore.thenCompose((__) ->
50+
- client.showInputBox(new ShowInputBoxParams(Bundle.CTL_TemplateUI_SelectPackageName(), Bundle.CTL_TemplateUI_SelectPackageNameSuggestion()))
51+
+ return uiBefore.thenCompose((__) -> {
52+
+ class ValidatePackageName implements Function<String, CompletionStage<String>> {
53+
+
54+
+ @Override
55+
+ public CompletionStage<String> apply(String packageName) {
56+
+ if (!SourceVersion.isName(packageName)) {
57+
+ client.showMessage(new MessageParams(MessageType.Error, Bundle.ERR_InvalidPackageName(packageName)));
58+
+ return client.showInputBox(new ShowInputBoxParams(Bundle.CTL_TemplateUI_SelectPackageName(), Bundle.CTL_TemplateUI_SelectPackageNameSuggestion())).thenCompose(this);
59+
+ }
60+
+ return CompletableFuture.completedFuture(packageName);
61+
+ }
62+
+ }
63+
+ return client.showInputBox(new ShowInputBoxParams(Bundle.CTL_TemplateUI_SelectPackageName(), Bundle.CTL_TemplateUI_SelectPackageNameSuggestion())).thenCompose(new ValidatePackageName());
64+
+ }
65+
);
66+
}
67+
68+
@@ -188,8 +209,9 @@ final class LspTemplateUI {
69+
if (path == null) {
70+
throw raise(RuntimeException.class, new UserCancelException(path));
71+
}
72+
- FileObject fo = FileUtil.toFileObject(new File(path));
73+
- if (fo == null || !fo.isFolder()) {
74+
+ File target = new File(path);
75+
+ FileObject fo = FileUtil.toFileObject(target);
76+
+ if (!target.canWrite() || fo == null || !fo.isFolder()) {
77+
client.showMessage(new MessageParams(MessageType.Error, Bundle.ERR_InvalidPath(path)));
78+
return client.showInputBox(new ShowInputBoxParams(Bundle.CTL_TemplateUI_SelectTarget(), suggestion.getPrimaryFile().getPath())).thenCompose(this);
79+
}
80+
@@ -202,7 +224,7 @@ final class LspTemplateUI {
81+
82+
private static CompletionStage<Pair<DataFolder, String>> findTargetAndNameForProject(CompletionStage<DataObject> findTemplate, NbCodeLanguageClient client) {
83+
return findTemplate.thenCompose(__ -> client.workspaceFolders()).thenCompose(folders -> {
84+
- class VerifyNonExistingFolder implements Function<String, CompletionStage<Pair<DataFolder,String>>> {
85+
+ class VerifyNewFolderCreation implements Function<String, CompletionStage<Pair<DataFolder,String>>> {
86+
@Override
87+
public CompletionStage<Pair<DataFolder,String>> apply(String path) {
88+
if (path == null) {
89+
@@ -215,12 +237,14 @@ final class LspTemplateUI {
90+
}
91+
targetPath.getParentFile().mkdirs();
92+
FileObject fo = FileUtil.toFileObject(targetPath.getParentFile());
93+
- if (fo == null || !fo.isFolder()) {
94+
+ if (fo == null || !fo.isFolder() || !targetPath.getParentFile().canWrite() || !SourceVersion.isName(targetPath.getName())) {
95+
+ client.showMessage(new MessageParams(MessageType.Error, Bundle.ERR_InvalidNewPath(path)));
96+
+ return client.showInputBox(new ShowInputBoxParams(Bundle.CTL_TemplateUI_SelectProjectTarget(), suggestWorkspaceRoot(folders))).thenCompose(this);
97+
}
98+
return CompletableFuture.completedFuture(Pair.of(DataFolder.findFolder(fo), targetPath.getName()));
99+
}
100+
}
101+
- return client.showInputBox(new ShowInputBoxParams(Bundle.CTL_TemplateUI_SelectProjectTarget(), suggestWorkspaceRoot(folders))).thenCompose(new VerifyNonExistingFolder());
102+
+ return client.showInputBox(new ShowInputBoxParams(Bundle.CTL_TemplateUI_SelectProjectTarget(), suggestWorkspaceRoot(folders))).thenCompose(new VerifyNewFolderCreation());
103+
});
104+
}
105+
106+
@@ -229,9 +253,21 @@ final class LspTemplateUI {
107+
FileObject template = desc.getTemplate();
108+
Object handler = template.getAttribute(FileBuilder.ATTR_TEMPLATE_HANDLER);
109+
if (handler == null) {
110+
- return client.showInputBox(new ShowInputBoxParams(Bundle.CTL_TemplateUI_SelectName(), desc.getProposedName())).thenApply(name -> {
111+
- return name != null ? builder.name(name) : null;
112+
- });
113+
+ class ValidateJavaObjectName implements Function<String, CompletionStage<String>> {
114+
+
115+
+ @Override
116+
+ public CompletionStage<String> apply(String name) {
117+
+ if (!SourceVersion.isName(name)) {
118+
+ client.showMessage(new MessageParams(MessageType.Error, Bundle.ERR_InvalidObjectName(name)));
119+
+ return client.showInputBox(new ShowInputBoxParams(Bundle.CTL_TemplateUI_SelectName(), desc.getProposedName())).thenCompose(this);
120+
+ }
121+
+ return CompletableFuture.completedFuture(name);
122+
+ }
123+
+ }
124+
+ boolean isJavaTemplate = "text/x-java".equals(FileUtil.getMIMEType(template));
125+
+ CompletionStage<String> userInput = client.showInputBox(new ShowInputBoxParams(Bundle.CTL_TemplateUI_SelectName(), desc.getProposedName()));
126+
+ if(isJavaTemplate) userInput = userInput.thenCompose(new ValidateJavaObjectName());
127+
+ return userInput.thenApply(name -> {return name != null ? builder.name(name) : null;});
128+
}
129+
return CompletableFuture.completedFuture(builder);
130+
}
131+
@@ -242,7 +278,7 @@ final class LspTemplateUI {
132+
suggestion = Utilities.toFile(new URI(folders.get(0).getUri())).getParent();
133+
} catch (URISyntaxException ex) {
134+
}
135+
- return suggestion;
136+
+ return Paths.get(suggestion,"ProjectName").toString();
137+
}
138+
139+
private static CompletionStage<DataObject> findTemplate(DataFolder templates, NbCodeLanguageClient client, ExecuteCommandParams params) {

0 commit comments

Comments
 (0)