Skip to content

Commit c85b895

Browse files
committed
Validate runtime + node.js wizard page.. See
angelozerr#147
1 parent e5d8da0 commit c85b895

File tree

7 files changed

+157
-35
lines changed

7 files changed

+157
-35
lines changed

eclipse/ts.eclipse.ide.ui/src/ts/eclipse/ide/internal/ui/TypeScriptUIMessages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ public class TypeScriptUIMessages extends NLS {
206206
public static String NPMModuleVersionsSelectionDialog_searchJob_taskName;
207207

208208
// NPM Install Widgets
209+
public static String NPMInstallWidget_versionText_message;
209210
public static String NPMInstallWidget_ValidateVersionJob_name;
210211
public static String NPMInstallWidget_SearchingVersions_status;
211212
public static String NPMInstallWidget_InvalidVersion_status;

eclipse/ts.eclipse.ide.ui/src/ts/eclipse/ide/internal/ui/TypeScriptUIMessages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ NPMModuleVersionsSelectionDialog_message=&Enter NPM module version or pattern (?
181181
NPMModuleVersionsSelectionDialog_searchJob_taskName=Searching
182182

183183
# NPN Install Widgets
184+
NPMInstallWidget_versionText_message=Fill version or use Ctrl+Space to open content assist.
184185
NPMInstallWidget_ValidateVersionJob_name=Validate NPM module version job.
185186
NPMInstallWidget_SearchingVersions_status=Searching available versions for ''{0}'' module with 'npm show'...
186187
NPMInstallWidget_InvalidVersion_status=Invalid version ''{0}'' for ''{1}'' module.

eclipse/ts.eclipse.ide.ui/src/ts/eclipse/ide/internal/ui/dialogs/StatusUtil.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
package ts.eclipse.ide.internal.ui.dialogs;
1313

1414
import org.eclipse.core.runtime.IStatus;
15+
import org.eclipse.core.runtime.Status;
1516
import org.eclipse.jface.dialogs.DialogPage;
1617
import org.eclipse.jface.dialogs.IMessageProvider;
1718

@@ -56,7 +57,7 @@ public static IStatus getMostSevere(IStatus[] status) {
5657
* Applies the status to the status line of a dialog page.
5758
*/
5859
public static void applyToStatusLine(DialogPage page, IStatus status) {
59-
String message= status.getMessage();
60+
String message= Status.OK_STATUS.equals(status) ? null : status.getMessage();
6061
switch (status.getSeverity()) {
6162
case IStatus.OK:
6263
page.setMessage(message, IMessageProvider.NONE);

eclipse/ts.eclipse.ide.ui/src/ts/eclipse/ide/internal/ui/wizards/TSConfigWizardPage.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
package ts.eclipse.ide.internal.ui.wizards;
1414

1515
import org.eclipse.core.runtime.IPath;
16+
import org.eclipse.core.runtime.IStatus;
1617
import org.eclipse.core.runtime.Path;
1718
import org.eclipse.swt.SWT;
1819
import org.eclipse.swt.graphics.Font;
@@ -95,11 +96,11 @@ protected void createBody(Composite parent) {
9596
cbTarget.addListener(SWT.Modify, this);
9697
GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
9798
cbTarget.setLayoutData(data);
98-
99+
99100
// Data for Combobox target
100101
cbTarget.setItems(TsconfigJson.getAvailableTargets());
101102
// cbTarget.select(0); // select "es3"
102-
103+
103104
// Module
104105
label = new Label(subGroup, SWT.NONE);
105106
label.setText(TypeScriptUIMessages.TSConfigWizardPage_module);
@@ -124,11 +125,11 @@ protected void createBody(Composite parent) {
124125
cbModuleResolution.addListener(SWT.Modify, this);
125126
data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
126127
cbModuleResolution.setLayoutData(data);
127-
128+
128129
// Data for Combobox moduele resolution
129130
cbModuleResolution.setItems(TsconfigJson.getAvailableModuleResolutions());
130131
// cbModuleResolution.select(1); // select "classic"
131-
132+
132133
// outDir
133134
label = new Label(subGroup, SWT.NONE);
134135
label.setText(TypeScriptUIMessages.TSConfigWizardPage_outDir);
@@ -258,10 +259,8 @@ protected void initializeDefaultValues() {
258259
}
259260

260261
@Override
261-
protected boolean validatePage() {
262-
boolean valid = true;
263-
264-
return valid;
262+
protected IStatus[] validatePage() {
263+
return null;
265264
}
266265

267266
public IPath getPath() {

eclipse/ts.eclipse.ide.ui/src/ts/eclipse/ide/internal/ui/wizards/TypeScriptRuntimeAndNodejsWizardPage.java

Lines changed: 122 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,16 @@
1111
*/
1212
package ts.eclipse.ide.internal.ui.wizards;
1313

14+
import java.io.File;
15+
1416
import org.eclipse.core.resources.IResource;
17+
import org.eclipse.core.runtime.IStatus;
18+
import org.eclipse.core.runtime.Status;
1519
import org.eclipse.jface.resource.JFaceResources;
1620
import org.eclipse.jface.viewers.ArrayContentProvider;
1721
import org.eclipse.jface.viewers.ComboViewer;
1822
import org.eclipse.jface.window.Window;
23+
import org.eclipse.osgi.util.NLS;
1924
import org.eclipse.swt.SWT;
2025
import org.eclipse.swt.events.SelectionAdapter;
2126
import org.eclipse.swt.events.SelectionEvent;
@@ -32,12 +37,16 @@
3237
import ts.eclipse.ide.core.TypeScriptCorePlugin;
3338
import ts.eclipse.ide.core.nodejs.IDENodejsProcessHelper;
3439
import ts.eclipse.ide.core.nodejs.IEmbeddedNodejs;
40+
import ts.eclipse.ide.core.utils.WorkbenchResourceUtil;
3541
import ts.eclipse.ide.internal.ui.TypeScriptUIMessages;
3642
import ts.eclipse.ide.internal.ui.dialogs.WorkspaceResourceSelectionDialog;
3743
import ts.eclipse.ide.internal.ui.dialogs.WorkspaceResourceSelectionDialog.Mode;
44+
import ts.eclipse.ide.ui.preferences.StatusInfo;
3845
import ts.eclipse.ide.ui.widgets.NPMInstallWidget;
3946
import ts.eclipse.ide.ui.wizards.AbstractWizardPage;
47+
import ts.nodejs.NodejsProcessHelper;
4048
import ts.repository.ITypeScriptRepository;
49+
import ts.utils.FileUtils;
4150
import ts.utils.StringUtils;
4251

4352
public class TypeScriptRuntimeAndNodejsWizardPage extends AbstractWizardPage {
@@ -112,6 +121,7 @@ private void createEmbeddedTypeScriptField(Composite parent) {
112121
useEmbeddedTsRuntimeButton = new Button(parent, SWT.RADIO);
113122
useEmbeddedTsRuntimeButton
114123
.setText(TypeScriptUIMessages.TypeScriptRuntimeAndNodejsWizardPage_useEmbeddedTsRuntime_label);
124+
useEmbeddedTsRuntimeButton.addListener(SWT.Selection, this);
115125
useEmbeddedTsRuntimeButton.addSelectionListener(new SelectionAdapter() {
116126
@Override
117127
public void widgetSelected(SelectionEvent e) {
@@ -133,13 +143,15 @@ private void createInstallScriptField(Composite parent) {
133143
Button useInstallTsRuntime = new Button(parent, SWT.RADIO);
134144
useInstallTsRuntime
135145
.setText(TypeScriptUIMessages.TypeScriptRuntimeAndNodejsWizardPage_useInstallTsRuntime_label);
146+
useInstallTsRuntime.addListener(SWT.Selection, this);
136147
useInstallTsRuntime.addSelectionListener(new SelectionAdapter() {
137148
@Override
138149
public void widgetSelected(SelectionEvent e) {
139150
updateTsRuntimeMode();
140151
}
141152
});
142153
installTsRuntime = new NPMInstallWidget("typescript", this, parent, SWT.NONE);
154+
installTsRuntime.getVersionText().addListener(SWT.Modify, this);
143155
}
144156

145157
private void updateTsRuntimeMode() {
@@ -148,6 +160,13 @@ private void updateTsRuntimeMode() {
148160
installTsRuntime.setEnabled(!useEmbeddedTsRuntime);
149161
}
150162

163+
private IStatus validateTypeScriptRuntime() {
164+
if (useEmbeddedTsRuntimeButton.getSelection()) {
165+
return Status.OK_STATUS;
166+
}
167+
return installTsRuntime.getStatus();
168+
}
169+
151170
// ------------------- Node.js content
152171

153172
private void createNodejsBody(Composite parent) {
@@ -173,6 +192,7 @@ private void createEmbeddedNodejsField(Composite parent) {
173192
useEmbeddedNodeJsButton = new Button(parent, SWT.RADIO);
174193
useEmbeddedNodeJsButton
175194
.setText(TypeScriptUIMessages.TypeScriptRuntimeAndNodejsWizardPage_useEmbeddedNodeJs_label);
195+
useEmbeddedNodeJsButton.addListener(SWT.Selection, this);
176196
useEmbeddedNodeJsButton.addSelectionListener(new SelectionAdapter() {
177197
@Override
178198
public void widgetSelected(SelectionEvent e) {
@@ -195,27 +215,22 @@ public void widgetSelected(SelectionEvent e) {
195215
}
196216
embeddedNodeJs.setItems(valueLabels);
197217
embeddedNodeJs.setFont(JFaceResources.getDialogFont());
198-
218+
embeddedNodeJs.addListener(SWT.Modify, this);
199219
}
200220

201221
private void createInstalledNodejsField(Composite parent) {
202222
Button useInstalledNodejs = new Button(parent, SWT.RADIO);
203223
useInstalledNodejs.setText(TypeScriptUIMessages.TypeScriptRuntimeAndNodejsWizardPage_useInstalledNodeJs_label);
204-
useInstalledNodejs.addSelectionListener(new SelectionAdapter() {
205-
@Override
206-
public void widgetSelected(SelectionEvent e) {
207-
updateNodeJsMode();
208-
}
209-
});
224+
useInstalledNodejs.addListener(SWT.Selection, this);
210225

211226
String[] defaultPaths = IDENodejsProcessHelper.getAvailableNodejsPaths();
212227
installedNodeJs = new Combo(parent, SWT.NONE);
213228
installedNodeJs.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
214229
installedNodeJs.setItems(defaultPaths);
230+
installedNodeJs.addListener(SWT.Modify, this);
215231

216232
// Create Browse buttons.
217233
createBrowseButtons(parent, installedNodeJs);
218-
219234
}
220235

221236
protected void createBrowseButtons(final Composite parent, final Combo filePathCombo) {
@@ -250,8 +265,8 @@ public void widgetSelected(SelectionEvent e) {
250265
Mode.FILE);
251266
if (dialog.open() == Window.OK) {
252267
IResource resource = (IResource) dialog.getFirstResult();
253-
filePathCombo.setText(TypeScriptCorePlugin.getTypeScriptRepositoryManager()
254-
.generateFileName(resource, null));
268+
filePathCombo.setText(
269+
TypeScriptCorePlugin.getTypeScriptRepositoryManager().generateFileName(resource, null));
255270
}
256271

257272
}
@@ -289,7 +304,6 @@ private void createNodePathInfo(Composite parent) {
289304
gridData.horizontalSpan = 2;
290305
gridData.widthHint = 200;
291306
nodePath.setLayoutData(gridData);
292-
293307
}
294308

295309
@Override
@@ -303,7 +317,6 @@ protected void initializeDefaultValues() {
303317
embeddedNodeJs.select(0);
304318
useEmbeddedNodeJsButton.setSelection(true);
305319
updateNodeJsMode();
306-
307320
}
308321

309322
private void updateNodeJsMode() {
@@ -312,13 +325,107 @@ private void updateNodeJsMode() {
312325
installedNodeJs.setEnabled(!useEmbeddedNodeJs);
313326
browseFileSystemButton.setEnabled(!useEmbeddedNodeJs);
314327
browseWorkspaceButton.setEnabled(!useEmbeddedNodeJs);
328+
}
329+
330+
private class NodeJsStatus extends StatusInfo {
331+
332+
private final File nodeFile;
333+
private final String version;
315334

335+
public NodeJsStatus(File nodeFile, String version, String errorMessage) {
336+
if (errorMessage != null) {
337+
setError(errorMessage);
338+
}
339+
this.nodeFile = nodeFile;
340+
this.version = version;
341+
}
342+
343+
public File getNodeFile() {
344+
return nodeFile;
345+
}
346+
347+
public String getNodeVersion() {
348+
return version;
349+
}
350+
}
351+
352+
/**
353+
* Update the node version, path labels and returns the validation status of
354+
* the nodejs path.
355+
*
356+
* @return the validation status of the nodejs path.
357+
*/
358+
private IStatus validateAndUpdateNodejsPath() {
359+
// Compute node.j status
360+
NodeJsStatus status = validateNodejsPath();
361+
// Update node version & path
362+
if (status.isOK()) {
363+
nodeVersion.setText(status.getNodeVersion());
364+
nodePath.setText(FileUtils.getPath(status.getNodeFile()));
365+
} else {
366+
nodeVersion.setText("");
367+
nodePath.setText("");
368+
}
369+
return status;
370+
}
371+
372+
/**
373+
* Returns the status of the node.js path.
374+
*
375+
* @return the status of the node.js path.
376+
*/
377+
private NodeJsStatus validateNodejsPath() {
378+
File nodeFile = null;
379+
String version = null;
380+
boolean embedded = useEmbeddedNodeJsButton.getSelection();
381+
if (embedded) {
382+
int selectedIndex = embeddedNodeJs.getSelectionIndex();
383+
/*
384+
* if (selectedIndex == 0) { // ERROR: the embedded node.js combo is
385+
* not selected. return new NodeJsStatus(null, null,
386+
* TypeScriptUIMessages.
387+
* NodejsConfigurationBlock_embeddedNode_required_error); } else {
388+
*/
389+
IEmbeddedNodejs[] installs = TypeScriptCorePlugin.getNodejsInstallManager().getNodejsInstalls();
390+
IEmbeddedNodejs install = installs[selectedIndex];
391+
nodeFile = install.getPath();
392+
// }
393+
} else {
394+
String nodeJsPath = installedNodeJs.getText();
395+
if (StringUtils.isEmpty(nodeJsPath)) {
396+
// ERROR: the installed path is empty
397+
return new NodeJsStatus(null, null,
398+
TypeScriptUIMessages.NodejsConfigurationBlock_installedNode_required_error);
399+
} else {
400+
nodeFile = WorkbenchResourceUtil.resolvePath(nodeJsPath, null);
401+
}
402+
}
403+
404+
if (!nodeFile.exists()) {
405+
// ERROR: node.js file doesn't exists
406+
return new NodeJsStatus(null, null, NLS.bind(
407+
TypeScriptUIMessages.NodejsConfigurationBlock_nodeFile_exists_error, FileUtils.getPath(nodeFile)));
408+
} else {
409+
version = NodejsProcessHelper.getNodeVersion(nodeFile);
410+
if (StringUtils.isEmpty(version)) {
411+
// ERROR: the file path is not a node.exe
412+
return new NodeJsStatus(null, null,
413+
NLS.bind(TypeScriptUIMessages.NodejsConfigurationBlock_nodeFile_invalid_error,
414+
FileUtils.getPath(nodeFile)));
415+
}
416+
}
417+
// Node.js path is valid
418+
return new NodeJsStatus(nodeFile, version, null);
316419
}
317420

318421
@Override
319-
protected boolean validatePage() {
320-
// TODO Auto-generated method stub
321-
return false;
422+
protected IStatus[] validatePage() {
423+
IStatus[] status = new IStatus[2];
424+
// Validate TypeScript Runtime
425+
status[0] = validateTypeScriptRuntime();
426+
// Validate Node
427+
status[1] = validateAndUpdateNodejsPath();
428+
return status;
322429
}
323430

324431
public String getNpmInstallCommand() {

eclipse/ts.eclipse.ide.ui/src/ts/eclipse/ide/ui/widgets/NPMInstallWidget.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ public class NPMInstallWidget extends Composite {
6565

6666
private final IStatusChangeListener handler;
6767
private ValidateVersionJob validateVersionJob;
68+
private IStatus status;
6869

6970
/**
7071
* Job which loads the available version of the given npm module and
@@ -126,6 +127,7 @@ public NPMInstallWidget(String moduleName, IStatusChangeListener handler, Compos
126127
super(parent, style);
127128
this.moduleName = moduleName;
128129
this.handler = handler;
130+
this.status = Status.OK_STATUS;
129131
createUI(this);
130132
}
131133

@@ -157,6 +159,7 @@ public void modifyText(ModifyEvent event) {
157159
validateVersion(version);
158160
}
159161
});
162+
versionText.setMessage(TypeScriptUIMessages.NPMInstallWidget_versionText_message);
160163
addContentProposal(versionText);
161164

162165
// Search button
@@ -240,6 +243,7 @@ private void validateVersionASynch(NPMModule module) {
240243
}
241244

242245
private void statusChanged(IStatus status) {
246+
this.status = status;
243247
handler.statusChanged(status);
244248
}
245249

@@ -271,4 +275,12 @@ public void setEnabled(boolean enabled) {
271275
public String getNpmInstallCommand() {
272276
return NPMHelper.getNpmInstallCommand(moduleName, version);
273277
}
278+
279+
public IStatus getStatus() {
280+
return status;
281+
}
282+
283+
public Text getVersionText() {
284+
return versionText;
285+
}
274286
}

0 commit comments

Comments
 (0)