Skip to content

Commit cd13212

Browse files
ruspl-afedlaeubi
authored andcommitted
Continue #2027: throw CoreException instead of returning null
* see #2027 (comment) * see #2027 (comment)
1 parent 1acb067 commit cd13212

File tree

6 files changed

+130
-118
lines changed

6 files changed

+130
-118
lines changed

terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/ConsoleManager.java

Lines changed: 86 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import java.util.Optional;
2222

2323
import org.eclipse.core.runtime.Assert;
24-
import org.eclipse.core.runtime.IStatus;
24+
import org.eclipse.core.runtime.CoreException;
2525
import org.eclipse.core.runtime.Status;
2626
import org.eclipse.swt.custom.CTabFolder;
2727
import org.eclipse.swt.custom.CTabItem;
@@ -183,21 +183,7 @@ private final IWorkbenchPage getActiveWorkbenchPage() {
183183
@Override
184184
public Optional<ITerminalsView> findConsoleView(TerminalViewId tvid) {
185185
Assert.isNotNull(Display.findDisplay(Thread.currentThread()));
186-
187-
ITerminalsView view = null;
188-
189-
// Get the active workbench page
190-
IWorkbenchPage page = getActiveWorkbenchPage();
191-
if (page != null) {
192-
// Look for the view
193-
IViewPart part = getTerminalsViewWithSecondaryId(tvid, true);
194-
// Check the interface
195-
if (part instanceof ITerminalsView) {
196-
view = (ITerminalsView) part;
197-
}
198-
}
199-
200-
return Optional.ofNullable(view);
186+
return findTerminalsViewWithSecondaryId(tvid, true);
201187
}
202188

203189
/**
@@ -209,18 +195,23 @@ public Optional<ITerminalsView> findConsoleView(TerminalViewId tvid) {
209195
*
210196
* @return The terminals console view instance or <code>null</code> if not found.
211197
*/
212-
private IViewPart getTerminalsViewWithSecondaryId(TerminalViewId tvid, boolean restore) {
213-
for (IViewReference ref : getActiveWorkbenchPage().getViewReferences()) {
198+
private Optional<ITerminalsView> findTerminalsViewWithSecondaryId(TerminalViewId tvid, boolean restore) {
199+
IWorkbenchPage page = getActiveWorkbenchPage();
200+
if (page == null) {
201+
return Optional.empty();
202+
}
203+
for (IViewReference ref : page.getViewReferences()) {
214204
if (ref.getId().equals(tvid.primary())) {
215205
String refSecondaryId = ref.getSecondaryId();
216206
String secondaryId = tvid.secondary().orElse(null);
217207
if (ITerminalsConnectorConstants.ANY_ACTIVE_SECONDARY_ID.equals(secondaryId)
218208
|| Objects.equals(secondaryId, refSecondaryId)) {
219-
return ref.getView(restore);
209+
return Optional.ofNullable(ref.getView(restore)).filter(ITerminalsView.class::isInstance)
210+
.map(ITerminalsView.class::cast);
220211
}
221212
}
222213
}
223-
return null;
214+
return Optional.empty();
224215
}
225216

226217
/**
@@ -230,34 +221,33 @@ private IViewPart getTerminalsViewWithSecondaryId(TerminalViewId tvid, boolean r
230221
* {@link ITerminalsConnectorConstants#LAST_ACTIVE_SECONDARY_ID} for its secondary part.
231222
* @return The terminals console view instance or <code>null</code> if not found.
232223
*/
233-
private IViewPart getActiveTerminalsView(TerminalViewId tvid) {
234-
IViewPart part = null;
224+
private Optional<ITerminalsView> findActiveTerminalsView(TerminalViewId tvid) {
225+
Optional<ITerminalsView> part = Optional.empty();
235226
String id = tvid.primary();
236-
237227
String secondaryId = tvid.secondary().orElse(null);
238228
if (id.equals(lastActiveViewId)) {
239229
if (ITerminalsConnectorConstants.LAST_ACTIVE_SECONDARY_ID.equals(secondaryId)
240230
|| Objects.equals(secondaryId, lastActiveSecondaryViewId)) {
241-
part = getTerminalsViewWithSecondaryId(new TerminalViewId(lastActiveViewId, lastActiveSecondaryViewId),
231+
part = findTerminalsViewWithSecondaryId(new TerminalViewId(lastActiveViewId, lastActiveSecondaryViewId),
242232
false);
243233
}
244234
}
245235

246-
if (part == null) {
236+
if (part.isEmpty()) {
247237
String finalSecondaryId;
248238
if (ITerminalsConnectorConstants.LAST_ACTIVE_SECONDARY_ID.equals(secondaryId)) {
249239
// There is no last available, so get any available instead
250240
finalSecondaryId = ITerminalsConnectorConstants.ANY_ACTIVE_SECONDARY_ID;
251241
} else {
252242
finalSecondaryId = secondaryId;
253243
}
254-
part = getTerminalsViewWithSecondaryId(new TerminalViewId(id, finalSecondaryId), true);
255-
if (part != null) {
256-
lastActiveViewId = part.getViewSite().getId();
257-
lastActiveSecondaryViewId = part.getViewSite().getSecondaryId();
244+
part = findTerminalsViewWithSecondaryId(new TerminalViewId(id, finalSecondaryId), true);
245+
if (part.isPresent()) {
246+
IViewSite site = part.get().getViewSite();
247+
lastActiveViewId = site.getId();
248+
lastActiveSecondaryViewId = site.getSecondaryId();
258249
}
259250
}
260-
261251
return part;
262252
}
263253

@@ -267,69 +257,72 @@ private IViewPart getActiveTerminalsView(TerminalViewId tvid) {
267257
* <b>Note:</b> The method must be called within the UI thread.
268258
*
269259
* @param tvid The terminals console view id.
260+
* @throws CoreException if the requested console cannot be opened
261+
* @return opened terminal console view part
270262
*/
271263
@Override
272-
public IViewPart showConsoleView(TerminalViewId tvid) {
264+
public ITerminalsView showConsoleView(TerminalViewId tvid) throws CoreException {
273265
Assert.isNotNull(Display.findDisplay(Thread.currentThread()));
274-
275-
// Get the active workbench page
276266
IWorkbenchPage page = getActiveWorkbenchPage();
277-
if (page != null) {
278-
try {
279-
// show the view
280-
IViewPart part = getActiveTerminalsView(tvid);
281-
if (part == null) {
282-
String secondaryId = tvid.secondary().orElse(null);
283-
String finalSecondaryId;
284-
if (ITerminalsConnectorConstants.LAST_ACTIVE_SECONDARY_ID.equals(secondaryId)
285-
|| ITerminalsConnectorConstants.ANY_ACTIVE_SECONDARY_ID.equals(secondaryId)) {
286-
// We have already checked all open views, so since none of the special flags work
287-
// we are opening the first view, which means no secondary id.
288-
finalSecondaryId = null;
289-
} else {
290-
finalSecondaryId = secondaryId;
291-
}
292-
part = page.showView(tvid.primary(), finalSecondaryId, IWorkbenchPage.VIEW_ACTIVATE);
293-
}
294-
// and force the view to the foreground
295-
page.bringToTop(part);
296-
return part;
297-
} catch (PartInitException e) {
298-
IStatus status = new Status(IStatus.ERROR, UIPlugin.getUniqueIdentifier(), e.getLocalizedMessage(), e);
299-
UIPlugin.getDefault().getLog().log(status);
267+
if (page == null) {
268+
throw noActivePage();
269+
}
270+
// show the view
271+
Optional<ITerminalsView> found = findActiveTerminalsView(tvid);
272+
if (found.isEmpty()) {
273+
String secondaryId = tvid.secondary().orElse(null);
274+
String finalSecondaryId;
275+
if (ITerminalsConnectorConstants.LAST_ACTIVE_SECONDARY_ID.equals(secondaryId)
276+
|| ITerminalsConnectorConstants.ANY_ACTIVE_SECONDARY_ID.equals(secondaryId)) {
277+
// We have already checked all open views, so since none of the special flags work
278+
// we are opening the first view, which means no secondary id.
279+
finalSecondaryId = null;
280+
} else {
281+
finalSecondaryId = secondaryId;
300282
}
283+
found = Optional.of(page.showView(tvid.primary(), finalSecondaryId, IWorkbenchPage.VIEW_ACTIVATE))
284+
.filter(ITerminalsView.class::isInstance).map(ITerminalsView.class::cast);
301285
}
302-
return null;
286+
// and force the view to the foreground
287+
found.ifPresent(page::bringToTop);
288+
return found.orElseThrow(this::cannotCreateConsole);
289+
}
290+
291+
private CoreException noActivePage() {
292+
return new CoreException(Status.error(Messages.ConsoleManager_e_no_active_page));
293+
}
294+
295+
private CoreException cannotCreateConsole() {
296+
return new CoreException(Status.error(Messages.ConsoleManager_e_cannot_create_console));
303297
}
304298

305299
/**
306300
* Bring the terminals console view, specified by the given id, to the top of the view stack.
307301
*
308302
* @param tvid The terminals console view id.
309303
* @param activate If <code>true</code> activate the console view.
304+
* @throws CoreException if the requested console cannot be opened
305+
* @return opened terminal console view part
310306
*/
311-
private IViewPart bringToTop(TerminalViewId tvid, boolean activate) {
307+
private ITerminalsView bringToTop(TerminalViewId tvid, boolean activate) throws CoreException {
312308
// Get the active workbench page
313309
IWorkbenchPage page = getActiveWorkbenchPage();
314-
if (page != null) {
315-
// get (last) active terminal view
316-
IViewPart activePart = getActiveTerminalsView(tvid);
317-
if (activePart == null) {
318-
// Create a new one
319-
IViewPart newPart = showConsoleView(
320-
new TerminalViewId(tvid.primary(), new TerminalViewId().next().secondary()));
321-
return newPart;
322-
}
323-
324-
if (activate) {
325-
page.activate(activePart);
326-
} else {
327-
page.bringToTop(activePart);
328-
}
329-
330-
return activePart;
310+
if (page == null) {
311+
throw noActivePage();
331312
}
332-
return null;
313+
// get (last) active terminal view
314+
Optional<ITerminalsView> found = findActiveTerminalsView(tvid);
315+
if (found.isEmpty()) {
316+
// Create a new one
317+
return showConsoleView(new TerminalViewId(tvid.primary(), new TerminalViewId().next().secondary()));
318+
}
319+
ITerminalsView tv = found.get();
320+
if (activate) {
321+
page.activate(tv);
322+
} else {
323+
page.bringToTop(tv);
324+
}
325+
return tv;
333326
}
334327

335328
/**
@@ -344,10 +337,12 @@ private IViewPart bringToTop(TerminalViewId tvid, boolean activate) {
344337
* @param connector The terminal connector. Must not be <code>null</code>.
345338
* @param data The custom terminal data node or <code>null</code>.
346339
* @param flags The flags controlling how the console is opened or <code>null</code> to use defaults.
340+
* @throws CoreException if the requested console cannot be opened
341+
* @return opened terminal console widget
347342
*/
348343
@Override
349-
public CTabItem openConsole(TerminalViewId tvid, String title, String encoding, ITerminalConnector connector,
350-
Object data, Map<String, Boolean> flags) {
344+
public Widget openConsole(TerminalViewId tvid, String title, String encoding, ITerminalConnector connector,
345+
Object data, Map<String, Boolean> flags) throws CoreException {
351346
Assert.isNotNull(title);
352347
Assert.isNotNull(connector);
353348
Assert.isNotNull(Display.findDisplay(Thread.currentThread()));
@@ -358,23 +353,18 @@ public CTabItem openConsole(TerminalViewId tvid, String title, String encoding,
358353
boolean forceNew = flags != null && flags.containsKey(ITerminalsConnectorConstants.PROP_FORCE_NEW)
359354
? flags.get(ITerminalsConnectorConstants.PROP_FORCE_NEW).booleanValue()
360355
: false;
361-
362356
// Make the consoles view visible
363-
IViewPart part = bringToTop(tvid, activate);
364-
if (!(part instanceof ITerminalsView view)) {
365-
return null;
366-
}
357+
ITerminalsView view = bringToTop(tvid, activate);
367358
// Cast to the correct type
368359
// Get the tab folder manager associated with the view
369360
TabFolderManager manager = view.getAdapter(TabFolderManager.class);
370361
if (manager == null) {
371-
return null;
362+
throw cannotCreateConsole();
372363
}
373364

374365
// Lookup an existing console first
375-
String secId = ((IViewSite) part.getSite()).getSecondaryId();
376-
CTabItem item = (CTabItem) findConsole(new TerminalViewId(tvid.primary(), secId), title, connector, data)
377-
.orElse(null);
366+
String secId = ((IViewSite) view.getSite()).getSecondaryId();
367+
Optional<Widget> item = findConsole(new TerminalViewId(tvid.primary(), secId), title, connector, data);
378368

379369
// Switch to the tab folder page _before_ calling TabFolderManager#createItem(...).
380370
// The createItem(...) method invokes the corresponding connect and this may take
@@ -383,7 +373,7 @@ public CTabItem openConsole(TerminalViewId tvid, String title, String encoding,
383373
view.switchToTabFolderControl();
384374

385375
// If no existing console exist or forced -> Create the tab item
386-
if (item == null || forceNew) {
376+
if (item.isEmpty() || forceNew) {
387377
// If configured, check all existing tab items if they are associated
388378
// with terminated consoles
389379
if (UIPlugin.getScopedPreferences().getBoolean(IPreferenceKeys.PREF_REMOVE_TERMINATED_TERMINALS)) {
@@ -396,21 +386,19 @@ public CTabItem openConsole(TerminalViewId tvid, String title, String encoding,
396386
}
397387

398388
// Create a new tab item
399-
item = manager.createTabItem(title, encoding, connector, data, flags);
400-
}
401-
// If still null, something went wrong
402-
if (item == null) {
403-
return null;
389+
item = Optional.ofNullable(manager.createTabItem(title, encoding, connector, data, flags));
404390
}
405-
391+
CTabItem tab = toTabItem(item);
406392
// Make the item the active console
407-
manager.bringToTop(item);
408-
393+
manager.bringToTop(tab);
409394
// Make sure the terminals view has the focus after opening a new terminal
410395
view.setFocus();
411-
412396
// Return the tab item of the opened console
413-
return item;
397+
return tab;
398+
}
399+
400+
private CTabItem toTabItem(Optional<Widget> item) throws CoreException {
401+
return item.filter(CTabItem.class::isInstance).map(CTabItem.class::cast).orElseThrow(this::cannotCreateConsole);
414402
}
415403

416404
/**

terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/Messages.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2011, 2021 Wind River Systems, Inc. and others. All rights reserved.
2+
* Copyright (c) 2011, 2025 Wind River Systems, Inc. and others. All rights reserved.
33
* This program and the accompanying materials are made available under the terms
44
* of the Eclipse Public License 2.0 which accompanies this distribution, and is
55
* available at https://www.eclipse.org/legal/epl-2.0/
@@ -10,6 +10,7 @@
1010
* Wind River Systems - initial API and implementation
1111
* Max Weninger (Wind River) - [361363] [TERMINALS] Implement "Pin&Clone" for the "Terminals" view
1212
* Dirk Fauth <[email protected]> - Bug 460496
13+
* Alexander Fedorov (ArSysOp) - further evolution
1314
*******************************************************************************/
1415
package org.eclipse.terminal.view.ui.internal;
1516

@@ -65,6 +66,8 @@ public static String getString(String key) {
6566
public static String AbstractConfigurationPanel_encoding_custom_message;
6667
public static String AbstractConfigurationPanel_encoding_custom_error;
6768

69+
public static String ConsoleManager_e_cannot_create_console;
70+
public static String ConsoleManager_e_no_active_page;
6871
public static String TabTerminalListener_consoleClosed;
6972
public static String TabTerminalListener_consoleConnecting;
7073

terminal/bundles/org.eclipse.terminal.view.ui/src/org/eclipse/terminal/view/ui/internal/Messages.properties

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
###############################################################################
2-
# Copyright (c) 2012, 2021 Wind River Systems, Inc. and others. All rights reserved.
2+
# Copyright (c) 2012, 2025 Wind River Systems, Inc. and others. All rights reserved.
33
# This program and the accompanying materials are made available under the terms
44
# of the Eclipse Public License 2.0 which accompanies this distribution, and is
55
# available at https://www.eclipse.org/legal/epl-2.0/
@@ -8,6 +8,7 @@
88
#
99
# Contributors:
1010
# Wind River Systems - initial API and implementation
11+
# Alexander Fedorov (ArSysOp) - further evolution
1112
###############################################################################
1213

1314
Extension_error_missingRequiredAttribute=Required attribute "{0}" missing for extension "{1}"!
@@ -26,6 +27,8 @@ AbstractConfigurationPanel_encoding_custom=Other...
2627
AbstractConfigurationPanel_encoding_custom_title=Other...
2728
AbstractConfigurationPanel_encoding_custom_message=Please enter the name of the encoding to use for the terminal.
2829
AbstractConfigurationPanel_encoding_custom_error=Unsupported encoding. Please enter the name of a supported encoding.
30+
ConsoleManager_e_cannot_create_console=Cannot create console
31+
ConsoleManager_e_no_active_page=No active workbench page
2932

3033
TabTerminalListener_consoleClosed=<{1}> {0}
3134
TabTerminalListener_consoleConnecting={0} : {1}...

0 commit comments

Comments
 (0)