2 * Copyright (C) 2009-2011 BonitaSoft S.A.
3 * BonitaSoft, 31 rue Gustave Eiffel - 38000 Grenoble
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2.0 of the License, or
7 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 package org.bonitasoft.studio.application;
18 import java.io.IOException;
19 import java.lang.reflect.InvocationTargetException;
22 import java.util.Objects;
23 import java.util.stream.Stream;
25 import org.apache.maven.cli.configuration.SettingsXmlConfigurationProcessor;
26 import org.bonitasoft.studio.application.contribution.IPreShutdownContribution;
27 import org.bonitasoft.studio.application.handler.OpenReleaseNoteHandler;
28 import org.bonitasoft.studio.application.i18n.Messages;
29 import org.bonitasoft.studio.common.DateUtil;
30 import org.bonitasoft.studio.common.FileUtil;
31 import org.bonitasoft.studio.common.ProjectUtil;
32 import org.bonitasoft.studio.common.RedirectURLBuilder;
33 import org.bonitasoft.studio.common.extension.BonitaStudioExtensionRegistryManager;
34 import org.bonitasoft.studio.common.extension.IPostStartupContribution;
35 import org.bonitasoft.studio.common.jface.MessageDialogWithLink;
36 import org.bonitasoft.studio.common.log.BonitaStudioLog;
37 import org.bonitasoft.studio.common.platform.tools.PlatformUtil;
38 import org.bonitasoft.studio.common.repository.AbstractRepository;
39 import org.bonitasoft.studio.common.repository.RepositoryManager;
40 import org.bonitasoft.studio.common.repository.core.ActiveOrganizationProvider;
41 import org.bonitasoft.studio.common.repository.core.maven.DependencyGetOperation;
42 import org.bonitasoft.studio.common.repository.core.maven.contribution.InstallBonitaMavenArtifactsOperation;
43 import org.bonitasoft.studio.common.repository.core.maven.migration.model.GAV;
44 import org.bonitasoft.studio.common.repository.core.maven.repository.MavenRepositories;
45 import org.bonitasoft.studio.designer.core.UIDesignerServerManager;
46 import org.bonitasoft.studio.engine.BOSEngineManager;
47 import org.bonitasoft.studio.engine.BOSWebServerManager;
48 import org.bonitasoft.studio.engine.server.StartEngineJob;
49 import org.bonitasoft.studio.model.process.diagram.part.ProcessDiagramEditorPlugin;
50 import org.bonitasoft.studio.model.process.impl.ContractInputImpl;
51 import org.bonitasoft.studio.preferences.BonitaStudioPreferencesPlugin;
52 import org.bonitasoft.studio.preferences.BonitaThemeConstants;
53 import org.bonitasoft.studio.preferences.dialog.BonitaPreferenceDialog;
54 import org.eclipse.core.internal.databinding.beans.BeanPropertyHelper;
55 import org.eclipse.core.internal.resources.Workspace;
56 import org.eclipse.core.resources.ResourcesPlugin;
57 import org.eclipse.core.runtime.CoreException;
58 import org.eclipse.core.runtime.FileLocator;
59 import org.eclipse.core.runtime.IConfigurationElement;
60 import org.eclipse.core.runtime.IProgressMonitor;
61 import org.eclipse.core.runtime.IStatus;
62 import org.eclipse.core.runtime.InvalidRegistryObjectException;
63 import org.eclipse.core.runtime.MultiStatus;
64 import org.eclipse.core.runtime.Path;
65 import org.eclipse.core.runtime.Platform;
66 import org.eclipse.core.runtime.Status;
67 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
68 import org.eclipse.core.runtime.jobs.Job;
69 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
70 import org.eclipse.e4.core.contexts.ContextInjectionFactory;
71 import org.eclipse.e4.core.di.InjectionException;
72 import org.eclipse.e4.ui.css.swt.theme.IThemeEngine;
73 import org.eclipse.gmf.runtime.lite.svg.SVGFigure;
74 import org.eclipse.jface.dialogs.ErrorDialog;
75 import org.eclipse.jface.dialogs.IDialogConstants;
76 import org.eclipse.jface.dialogs.MessageDialog;
77 import org.eclipse.jface.operation.IRunnableWithProgress;
78 import org.eclipse.jface.resource.ImageDescriptor;
79 import org.eclipse.m2e.core.MavenPlugin;
80 import org.eclipse.m2e.core.embedder.IMavenConfiguration;
81 import org.eclipse.m2e.core.repository.IRepository;
82 import org.eclipse.m2e.core.repository.IRepositoryRegistry;
83 import org.eclipse.swt.widgets.Display;
84 import org.eclipse.swt.widgets.Shell;
85 import org.eclipse.ui.IStartup;
86 import org.eclipse.ui.IWorkbenchPage;
87 import org.eclipse.ui.PlatformUI;
88 import org.eclipse.ui.application.IWorkbenchConfigurer;
89 import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
90 import org.eclipse.ui.application.WorkbenchAdvisor;
91 import org.eclipse.ui.application.WorkbenchWindowAdvisor;
92 import org.eclipse.ui.contexts.IContextService;
93 import org.eclipse.ui.ide.IDE;
94 import org.eclipse.ui.internal.Workbench;
95 import org.eclipse.ui.internal.browser.WebBrowserUtil;
96 import org.eclipse.ui.internal.ide.IDEInternalWorkbenchImages;
97 import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
98 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
99 import org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog;
100 import org.osgi.framework.Bundle;
102 import com.google.common.base.Joiner;
104 public class BonitaStudioWorkbenchAdvisor extends WorkbenchAdvisor implements IStartup {
106 private static final String AWT_DRAW_STRING_AS_IMAGE = "drawStringAsImage";
108 private final class PreShutdownStudio implements IRunnableWithProgress {
111 public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
112 monitor.beginTask(Messages.shuttingDown, IProgressMonitor.UNKNOWN);
113 UIDesignerServerManager.getInstance().stop();
114 Job.getJobManager().cancel(StartEngineJob.FAMILY);
115 executePreShutdownContribution();
116 new ActiveOrganizationProvider().flush();
117 if (BOSWebServerManager.getInstance().serverIsStarted() && BOSEngineManager.getInstance().isRunning()) {
118 BOSEngineManager.getInstance().stop();
120 FileUtil.deleteDir(ProjectUtil.getBonitaStudioWorkFolder());
121 deleteTomcatTempDir();
125 private void deleteTomcatTempDir() {
126 File tempDir = new File(ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString() + File.separator
127 + "tomcat" + File.separator + "server" + File.separator + "temp");
128 if (tempDir.exists()) {
129 FileUtil.deleteDir(tempDir);
133 private void executePreShutdownContribution() {
134 final IConfigurationElement[] elements = BonitaStudioExtensionRegistryManager.getInstance()
135 .getConfigurationElements(
136 "org.bonitasoft.studio.application.preshutdown"); //$NON-NLS-1$
137 IPreShutdownContribution contrib = null;
138 for (final IConfigurationElement elem : elements) {
140 contrib = (IPreShutdownContribution) elem.createExecutableExtension("class"); //$NON-NLS-1$
142 } catch (final CoreException e) {
143 BonitaStudioLog.error(e);
149 private static final String FIRST_STARTUP = "firstStartup";
152 public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(final IWorkbenchWindowConfigurer configurer) {
153 return new BonitaStudioWorkbenchWindowAdvisor(configurer);
157 public void initialize(final IWorkbenchConfigurer configurer) {
158 super.initialize(configurer);
159 configurer.setSaveAndRestore(true);
160 final IContextService contextService = PlatformUI.getWorkbench().getService(IContextService.class);
161 contextService.activateContext("org.bonitasoft.studio.context.id");
162 initializeIDEImages(configurer);
166 * Workaround to load icons for Common Navigator component in a RCP
168 private void initializeIDEImages(final IWorkbenchConfigurer configurer) {
169 IDE.registerAdapters();
170 declareWorkbenchImages();
173 /********************************************************************
174 * /!\ Copy-pasted from IDEWorkbenchAvisor.declareWorkbenchImages() *
175 * ******************************************************************
176 * Declares all IDE-specific workbench images. This includes both "shared"
177 * images (named in {@link org.eclipse.ui.ide.IDE.SharedImages}) and internal images (named in
178 * {@link org.eclipse.ui.internal.ide.IDEInternalWorkbenchImages}).
180 * @see IWorkbenchConfigurer#declareImage
182 private void declareWorkbenchImages() {
184 final String ICONS_PATH = "$nl$/icons/full/";//$NON-NLS-1$
185 final String PATH_ELOCALTOOL = ICONS_PATH + "elcl16/"; // Enabled //$NON-NLS-1$
189 final String PATH_DLOCALTOOL = ICONS_PATH + "dlcl16/"; // Disabled //$NON-NLS-1$
193 final String PATH_ETOOL = ICONS_PATH + "etool16/"; // Enabled toolbar //$NON-NLS-1$
196 final String PATH_DTOOL = ICONS_PATH + "dtool16/"; // Disabled toolbar //$NON-NLS-1$
199 final String PATH_OBJECT = ICONS_PATH + "obj16/"; // Model object //$NON-NLS-1$
202 final String PATH_WIZBAN = ICONS_PATH + "wizban/"; // Wizard //$NON-NLS-1$
207 final String PATH_EVIEW = ICONS_PATH + "eview16/"; //$NON-NLS-1$
209 final Bundle ideBundle = Platform.getBundle(IDEWorkbenchPlugin.IDE_WORKBENCH);
211 declareWorkbenchImage(ideBundle,
212 IDEInternalWorkbenchImages.IMG_ETOOL_BUILD_EXEC, PATH_ETOOL
213 + "build_exec.png", //$NON-NLS-1$
215 declareWorkbenchImage(ideBundle,
216 IDEInternalWorkbenchImages.IMG_ETOOL_BUILD_EXEC_HOVER,
217 PATH_ETOOL + "build_exec.png", false); //$NON-NLS-1$
218 declareWorkbenchImage(ideBundle,
219 IDEInternalWorkbenchImages.IMG_ETOOL_BUILD_EXEC_DISABLED,
220 PATH_DTOOL + "build_exec.png", false); //$NON-NLS-1$
222 declareWorkbenchImage(ideBundle,
223 IDEInternalWorkbenchImages.IMG_ETOOL_SEARCH_SRC, PATH_ETOOL
224 + "search_src.png", //$NON-NLS-1$
226 declareWorkbenchImage(ideBundle,
227 IDEInternalWorkbenchImages.IMG_ETOOL_SEARCH_SRC_HOVER,
228 PATH_ETOOL + "search_src.png", false); //$NON-NLS-1$
229 declareWorkbenchImage(ideBundle,
230 IDEInternalWorkbenchImages.IMG_ETOOL_SEARCH_SRC_DISABLED,
231 PATH_DTOOL + "search_src.png", false); //$NON-NLS-1$
233 declareWorkbenchImage(ideBundle,
234 IDEInternalWorkbenchImages.IMG_ETOOL_NEXT_NAV, PATH_ETOOL
235 + "next_nav.png", //$NON-NLS-1$
238 declareWorkbenchImage(ideBundle,
239 IDEInternalWorkbenchImages.IMG_ETOOL_PREVIOUS_NAV, PATH_ETOOL
240 + "prev_nav.png", //$NON-NLS-1$
243 declareWorkbenchImage(ideBundle,
244 IDEInternalWorkbenchImages.IMG_WIZBAN_NEWPRJ_WIZ, PATH_WIZBAN
245 + "newprj_wiz.png", //$NON-NLS-1$
247 declareWorkbenchImage(ideBundle,
248 IDEInternalWorkbenchImages.IMG_WIZBAN_NEWFOLDER_WIZ,
249 PATH_WIZBAN + "newfolder_wiz.png", false); //$NON-NLS-1$
250 declareWorkbenchImage(ideBundle,
251 IDEInternalWorkbenchImages.IMG_WIZBAN_NEWFILE_WIZ, PATH_WIZBAN
252 + "newfile_wiz.png", //$NON-NLS-1$
255 declareWorkbenchImage(ideBundle,
256 IDEInternalWorkbenchImages.IMG_WIZBAN_IMPORTDIR_WIZ,
257 PATH_WIZBAN + "importdir_wiz.png", false); //$NON-NLS-1$
258 declareWorkbenchImage(ideBundle,
259 IDEInternalWorkbenchImages.IMG_WIZBAN_IMPORTZIP_WIZ,
260 PATH_WIZBAN + "importzip_wiz.png", false); //$NON-NLS-1$
262 declareWorkbenchImage(ideBundle,
263 IDEInternalWorkbenchImages.IMG_WIZBAN_EXPORTDIR_WIZ,
264 PATH_WIZBAN + "exportdir_wiz.png", false); //$NON-NLS-1$
265 declareWorkbenchImage(ideBundle,
266 IDEInternalWorkbenchImages.IMG_WIZBAN_EXPORTZIP_WIZ,
267 PATH_WIZBAN + "exportzip_wiz.png", false); //$NON-NLS-1$
269 declareWorkbenchImage(ideBundle,
270 IDEInternalWorkbenchImages.IMG_WIZBAN_RESOURCEWORKINGSET_WIZ,
271 PATH_WIZBAN + "workset_wiz.png", false); //$NON-NLS-1$
273 declareWorkbenchImage(ideBundle,
274 IDEInternalWorkbenchImages.IMG_DLGBAN_SAVEAS_DLG, PATH_WIZBAN
275 + "saveas_wiz.png", //$NON-NLS-1$
278 declareWorkbenchImage(ideBundle,
279 IDEInternalWorkbenchImages.IMG_DLGBAN_QUICKFIX_DLG, PATH_WIZBAN
280 + "quick_fix.png", //$NON-NLS-1$
283 declareWorkbenchImage(ideBundle, IDE.SharedImages.IMG_OBJ_PROJECT,
284 PATH_OBJECT + "prj_obj.png", true); //$NON-NLS-1$
285 declareWorkbenchImage(ideBundle,
286 IDE.SharedImages.IMG_OBJ_PROJECT_CLOSED, PATH_OBJECT
287 + "cprj_obj.png", //$NON-NLS-1$
289 declareWorkbenchImage(ideBundle, IDE.SharedImages.IMG_OPEN_MARKER,
290 PATH_ELOCALTOOL + "gotoobj_tsk.png", true); //$NON-NLS-1$
293 declareWorkbenchImage(ideBundle,
294 IDEInternalWorkbenchImages.IMG_ELCL_QUICK_FIX_ENABLED,
295 PATH_ELOCALTOOL + "smartmode_co.png", true); //$NON-NLS-1$
297 declareWorkbenchImage(ideBundle,
298 IDEInternalWorkbenchImages.IMG_DLCL_QUICK_FIX_DISABLED,
299 PATH_DLOCALTOOL + "smartmode_co.png", true); //$NON-NLS-1$
301 declareWorkbenchImage(ideBundle,
302 IDEInternalWorkbenchImages.IMG_OBJS_FIXABLE_WARNING,
303 PATH_OBJECT + "quickfix_warning_obj.png", true); //$NON-NLS-1$
304 declareWorkbenchImage(ideBundle,
305 IDEInternalWorkbenchImages.IMG_OBJS_FIXABLE_ERROR,
306 PATH_OBJECT + "quickfix_error_obj.png", true); //$NON-NLS-1$
309 // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_HPRIO_TSK,
310 // PATH_OBJECT+"hprio_tsk.png");
311 // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_MPRIO_TSK,
312 // PATH_OBJECT+"mprio_tsk.png");
313 // declareRegistryImage(IDEInternalWorkbenchImages.IMG_OBJS_LPRIO_TSK,
314 // PATH_OBJECT+"lprio_tsk.png");
316 declareWorkbenchImage(ideBundle, IDE.SharedImages.IMG_OBJS_TASK_TSK,
317 PATH_OBJECT + "taskmrk_tsk.png", true); //$NON-NLS-1$
318 declareWorkbenchImage(ideBundle, IDE.SharedImages.IMG_OBJS_BKMRK_TSK,
319 PATH_OBJECT + "bkmrk_tsk.png", true); //$NON-NLS-1$
321 declareWorkbenchImage(ideBundle,
322 IDEInternalWorkbenchImages.IMG_OBJS_COMPLETE_TSK, PATH_OBJECT
323 + "complete_tsk.png", //$NON-NLS-1$
325 declareWorkbenchImage(ideBundle,
326 IDEInternalWorkbenchImages.IMG_OBJS_INCOMPLETE_TSK, PATH_OBJECT
327 + "incomplete_tsk.png", //$NON-NLS-1$
329 declareWorkbenchImage(ideBundle,
330 IDEInternalWorkbenchImages.IMG_OBJS_WELCOME_ITEM, PATH_OBJECT
331 + "welcome_item.png", //$NON-NLS-1$
333 declareWorkbenchImage(ideBundle,
334 IDEInternalWorkbenchImages.IMG_OBJS_WELCOME_BANNER, PATH_OBJECT
335 + "welcome_banner.png", //$NON-NLS-1$
337 declareWorkbenchImage(ideBundle,
338 IDEInternalWorkbenchImages.IMG_OBJS_ERROR_PATH, PATH_OBJECT
339 + "error_tsk.png", //$NON-NLS-1$
341 declareWorkbenchImage(ideBundle,
342 IDEInternalWorkbenchImages.IMG_OBJS_WARNING_PATH, PATH_OBJECT
343 + "warn_tsk.png", //$NON-NLS-1$
345 declareWorkbenchImage(ideBundle,
346 IDEInternalWorkbenchImages.IMG_OBJS_INFO_PATH, PATH_OBJECT
347 + "info_tsk.png", //$NON-NLS-1$
350 declareWorkbenchImage(ideBundle,
351 IDEInternalWorkbenchImages.IMG_LCL_FLAT_LAYOUT, PATH_ELOCALTOOL
352 + "flatLayout.png", //$NON-NLS-1$
354 declareWorkbenchImage(ideBundle,
355 IDEInternalWorkbenchImages.IMG_LCL_HIERARCHICAL_LAYOUT,
356 PATH_ELOCALTOOL + "hierarchicalLayout.png", true); //$NON-NLS-1$
357 declareWorkbenchImage(ideBundle,
358 IDEInternalWorkbenchImages.IMG_ETOOL_PROBLEM_CATEGORY,
359 PATH_ETOOL + "problem_category.png", true); //$NON-NLS-1$
361 declareWorkbenchImage(ideBundle,
362 IDEInternalWorkbenchImages.IMG_ETOOL_PROBLEMS_VIEW,
363 PATH_EVIEW + "problems_view.png", true); //$NON-NLS-1$
364 declareWorkbenchImage(ideBundle,
365 IDEInternalWorkbenchImages.IMG_ETOOL_PROBLEMS_VIEW_ERROR,
366 PATH_EVIEW + "problems_view_error.png", true); //$NON-NLS-1$
367 declareWorkbenchImage(ideBundle,
368 IDEInternalWorkbenchImages.IMG_ETOOL_PROBLEMS_VIEW_WARNING,
369 PATH_EVIEW + "problems_view_warning.png", true); //$NON-NLS-1$
373 * Declares an IDE-specific workbench image.
375 * @param symbolicName
376 * the symbolic name of the image
378 * the path of the image file; this path is relative to the base
381 * <code>true</code> if this is a shared image, and
382 * <code>false</code> if this is not a shared image
383 * @see IWorkbenchConfigurer#declareImage
385 private void declareWorkbenchImage(final Bundle ideBundle, final String symbolicName,
386 final String path, final boolean shared) {
387 final URL url = FileLocator.find(ideBundle, new Path(path), null);
388 final ImageDescriptor desc = ImageDescriptor.createFromURL(url);
389 getWorkbenchConfigurer().declareImage(symbolicName, desc, shared);
393 public String getInitialWindowPerspectiveId() {
398 public String getMainPreferencePageId() {
399 return "org.bonitasoft.studio.preferences.preferences.UIPreferencePage";
403 public void preStartup() {
404 // Initialize adapter factories and avoid deadlock at startup
405 ProcessDiagramEditorPlugin.getInstance().getItemProvidersAdapterFactory();
407 new InstallBonitaMavenArtifactsOperation(MavenPlugin.getMaven().getLocalRepository()).execute();
408 } catch (CoreException e) {
409 BonitaStudioLog.error(e);
411 disableInternalWebBrowser();
412 setSystemProperties();
415 protected void setSystemProperties() {
416 var instanceLocation = Platform.getInstanceLocation();
417 if (instanceLocation != null) {
418 String workspaceLocation = new File(instanceLocation.getURL().getFile()).getPath();
419 System.setProperty("bonita.tomcat.lib.dir", String.format("%s%stomcat%sserver%slib", workspaceLocation,
420 File.separator, File.separator, File.separator));
421 BonitaStudioLog.info("bonita.tomcat.lib.dir=" + System.getProperty("bonita.tomcat.lib.dir"),
422 ApplicationPlugin.PLUGIN_ID);
424 BonitaStudioLog.warning("Property 'bonita.tomcat.lib.dir' has not been set.", ApplicationPlugin.PLUGIN_ID);
426 // Workaround for STUDIO-3651
427 System.setProperty(AWT_DRAW_STRING_AS_IMAGE, System.getProperty(AWT_DRAW_STRING_AS_IMAGE, "true"));
431 public void postStartup() {
432 var initializeProjectJob = new Job("Initialize project") {
435 protected IStatus run(IProgressMonitor monitor) {
436 RepositoryManager.getInstance().getAccessor().start(monitor);
437 return Status.OK_STATUS;
440 initializeProjectJob.addJobChangeListener(new JobChangeAdapter() {
443 public void done(IJobChangeEvent event) {
444 if (initializeProjectJob.equals(event.getJob())) {
445 executePostStartupContributions();
450 initializeProjectJob.setPriority(Job.INTERACTIVE);
451 initializeProjectJob.schedule();
454 IThemeEngine engine = PlatformUI.getWorkbench().getService(IThemeEngine.class);
455 synchroniseTheme(engine);
460 * Synchronise active eclipse theme with the Bonita preference,
461 * to ensure that specifics adjustments for Dark theme are applied.
462 * The preference value can be outdated if the user update the theme from the eclipse preference panel.
464 private void synchroniseTheme(IThemeEngine engine) {
465 String currentValue = BonitaStudioPreferencesPlugin.getDefault().getPreferenceStore()
466 .getString(BonitaThemeConstants.STUDIO_THEME_PREFERENCE);
467 String activeTheme = engine.getActiveTheme() == null
469 : engine.getActiveTheme().getId();
470 if (!themeIsValid(activeTheme)) {
471 BonitaStudioPreferencesPlugin.getDefault().getPreferenceStore()
472 .setValue(BonitaThemeConstants.STUDIO_THEME_PREFERENCE, BonitaThemeConstants.LIGHT_THEME);
473 } else if (!Objects.equals(currentValue, engine.getActiveTheme().getId())) {
474 BonitaStudioPreferencesPlugin.getDefault().getPreferenceStore()
475 .setValue(BonitaThemeConstants.STUDIO_THEME_PREFERENCE, engine.getActiveTheme().getId());
479 private boolean themeIsValid(String themeId) {
480 if (themeId != null && !themeId.isBlank()) {
481 return Objects.equals(themeId, BonitaThemeConstants.LIGHT_THEME)
482 || Objects.equals(themeId, BonitaThemeConstants.DARK_THEME);
488 * Apply the theme if required (usually on first start).
490 private void applyTheme(IThemeEngine engine) {
491 String expectedTheme = BonitaStudioPreferencesPlugin.getDefault().getPreferenceStore()
492 .getString(BonitaThemeConstants.STUDIO_THEME_PREFERENCE);
493 if (engine.getActiveTheme() == null
494 || !Objects.equals(expectedTheme, engine.getActiveTheme().getId())) {
495 BonitaStudioLog.info(String.format("Applying theme %s", expectedTheme), ApplicationPlugin.PLUGIN_ID);
496 engine.setTheme(expectedTheme, true);
501 * Disconnect from the core workspace.
503 private void disconnectFromWorkspace(final IProgressMonitor monitor) {
504 // save the workspace
505 final MultiStatus status = new MultiStatus(
506 IDEWorkbenchPlugin.IDE_WORKBENCH, 1,
507 IDEWorkbenchMessages.ProblemSavingWorkbench, null);
509 final ProgressMonitorJobsDialog p = new ProgressMonitorJobsDialog(
512 final boolean applyPolicy = ResourcesPlugin.getWorkspace()
513 .getDescription().isApplyFileStatePolicy();
515 final IRunnableWithProgress runnable = new IRunnableWithProgress() {
518 public void run(final IProgressMonitor monitor) {
521 status.merge(((Workspace) ResourcesPlugin
522 .getWorkspace()).save(true, true, monitor));
524 } catch (final CoreException e) {
525 status.merge(e.getStatus());
529 p.run(true, false, runnable);
530 } catch (final InvocationTargetException e) {
532 .merge(new Status(IStatus.ERROR,
533 IDEWorkbenchPlugin.IDE_WORKBENCH, 1,
534 IDEWorkbenchMessages.InternalError, e
535 .getTargetException()));
536 } catch (final InterruptedException e) {
537 status.merge(new Status(IStatus.ERROR,
538 IDEWorkbenchPlugin.IDE_WORKBENCH, 1,
539 IDEWorkbenchMessages.InternalError, e));
541 ErrorDialog.openError(null,
542 IDEWorkbenchMessages.ProblemsSavingWorkspace, null, status,
543 IStatus.ERROR | IStatus.WARNING);
544 if (!status.isOK()) {
545 IDEWorkbenchPlugin.log(
546 IDEWorkbenchMessages.ProblemsSavingWorkspace, status);
550 protected void disableInternalWebBrowser() {
551 final String noRegister = System.getProperty("bonita.noregister"); //$NON-NLS-1$
552 if (noRegister == null || !noRegister.equals("1")) {
553 WebBrowserUtil.isInternalBrowserOperational = false;
558 public void postShutdown() {
559 super.postShutdown();
560 disconnectFromWorkspace(AbstractRepository.NULL_PROGRESS_MONITOR);
564 public boolean preShutdown() {
565 IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
567 Stream.of(activePage.getViewReferences())
568 .filter(vr -> Objects.equals("org.eclipse.ui.browser.view", vr.getId()))
569 .forEach(activePage::hideView);
570 Job.getJobManager().cancel(StartEngineJob.FAMILY);
571 final boolean returnValue = super.preShutdown();
574 if (PlatformUI.isWorkbenchRunning() && PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null
575 && PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() != null) {
576 PlatformUI.getWorkbench().getProgressService().run(true, false, new PreShutdownStudio());
579 } catch (final Exception e) {
580 BonitaStudioLog.error(e);
587 public void earlyStartup() {
588 if (PlatformUtil.isHeadless()) {
589 return;//Do not execute earlyStartup in headless mode
592 new Job("Setup internal maven repository") {
595 protected IStatus run(IProgressMonitor monitor) {
596 new InstallBonitaMavenArtifactsOperation(MavenRepositories.internalRepository()).execute();
598 testMavenCentralAccess(monitor);
599 } catch (InvocationTargetException | InterruptedException e) {
600 return new Status(IStatus.ERROR, getClass(), e.getMessage());
602 return Status.OK_STATUS;
605 private void testMavenCentralAccess(IProgressMonitor monitor)
606 throws InvocationTargetException, InterruptedException {
607 // Use an arbitrary artifact (small) to test maven central access
608 var operation = new DependencyGetOperation(
609 new GAV("org.bonitasoft.engine", "bonita-engine", "7.13.0", null, "pom", null));
610 MavenPlugin.getRepositoryRegistry().getRepositories(IRepositoryRegistry.SCOPE_SETTINGS).stream()
611 .map(IRepository::getUrl)
612 .forEach(operation::addRemoteRespository);
613 operation.run(monitor);
614 var result = operation.getResult();
615 if (result == null) {
616 IMavenConfiguration mavenConfiguration = MavenPlugin.getMavenConfiguration();
617 var userSettingsFile = mavenConfiguration.getUserSettingsFile() != null
618 ? new File(mavenConfiguration.getUserSettingsFile())
619 : SettingsXmlConfigurationProcessor.DEFAULT_USER_SETTINGS_FILE;
620 Display.getDefault().syncExec(() -> {
621 var message = Messages.cannotReachMavenCentralRepositoryMessage;
622 if (userSettingsFile.exists()) {
623 message = message + System.lineSeparator()
624 + String.format(Messages.validateExistingMavenConfigurationMessage,
625 userSettingsFile.getAbsolutePath());
627 int buttonId = new MessageDialogWithLink(Display.getDefault().getActiveShell(),
628 Messages.cannotReachMavenCentralRepositoryTitle,
631 MessageDialog.WARNING,
632 new String[] { IDialogConstants.IGNORE_LABEL,
634 Messages.configure },
636 URI.create(RedirectURLBuilder.create("728"))).open();
638 BonitaPreferenceDialog dialog = new BonitaPreferenceDialog(
639 new Shell(Display.getDefault()));
641 dialog.setSelectedPreferencePage(BonitaPreferenceDialog.MAVEN_PAGE_ID);
644 testMavenCentralAccess(monitor);
645 } catch (InvocationTargetException | InterruptedException e) {
646 BonitaStudioLog.error(e);
648 } else if (buttonId == 1) {
650 testMavenCentralAccess(monitor);
651 } catch (InvocationTargetException | InterruptedException e) {
652 BonitaStudioLog.error(e);
662 final long startupDuration = System.currentTimeMillis() - BonitaStudioApplication.START_TIME;
663 BonitaStudioLog.info("Startup duration : " + DateUtil.getDisplayDuration(startupDuration),
664 ApplicationPlugin.PLUGIN_ID);
665 ApplicationPlugin.getDefault().getPreferenceStore().setDefault(FIRST_STARTUP, true);
666 if (isFirstStartup()) {
667 // new OpenReleaseNoteHandler().openBrowser();
668 // PlatformUtil.openIntroIfNoOtherEditorOpen();
670 PlatformUtil.openDashboardIfNoOtherEditorOpen();
672 ApplicationPlugin.getDefault().getPreferenceStore().setValue(FIRST_STARTUP, false);
675 private void executePostStartupContributions() {
676 final IConfigurationElement[] elements = BonitaStudioExtensionRegistryManager.getInstance()
677 .getConfigurationElements(
678 "org.bonitasoft.studio.common.poststartup"); //$NON-NLS-1$
679 for (final IConfigurationElement elem : elements) {
680 final Workbench workbench = (Workbench) PlatformUI.getWorkbench();
682 IPostStartupContribution contrib = (IPostStartupContribution) ContextInjectionFactory
683 .make(Platform.getBundle(elem.getDeclaringExtension().getNamespaceIdentifier())
684 .loadClass(elem.getAttribute("class")), workbench.getContext());
685 Display.getDefault().asyncExec(contrib::execute);
686 } catch (InjectionException | ClassNotFoundException | InvalidRegistryObjectException e) {
687 BonitaStudioLog.error(e);
692 private boolean isFirstStartup() {
693 return ApplicationPlugin.getDefault().getPreferenceStore().getBoolean(FIRST_STARTUP);
696 private void preLoad() {
697 //Fix performance issue
698 BeanPropertyHelper.getPropertyDescriptor(ContractInputImpl.class, "name");
702 private void preLoadSVG() {
703 final SVGFigure svgFigure = new SVGFigure();
705 final File iconsFolder = new File(
706 FileLocator.toFileURL(Platform.getBundle("org.bonitasoft.studio.pics").getResource("icons"))
708 initSVGFigure(svgFigure, iconsFolder, "figures");
709 initSVGFigure(svgFigure, iconsFolder, "decoration", "svg");
710 } catch (final IOException e) {
711 BonitaStudioLog.error(e);
715 private void initSVGFigure(final SVGFigure svgFigure, final File iconsFolder, final String... pathToFolder) {
716 for (final String filename : new File(iconsFolder, Joiner.on(File.separatorChar).join(pathToFolder)).list()) {
717 if (filename.endsWith(".svgz")) {
719 .setURI("platform:/plugin/org.bonitasoft.studio.pics/icons/" + Joiner.on("/").join(pathToFolder)