| /*=============================================================================# |
| # Copyright (c) 2012, 2019 Stephan Wahlbrink and others. |
| # |
| # This program and the accompanying materials are made available under the |
| # terms of the Eclipse Public License 2.0 which is available at |
| # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
| # which is available at https://www.apache.org/licenses/LICENSE-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
| # |
| # Contributors: |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.r.console.ui.tools; |
| |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.preferences.InstanceScope; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IWorkbenchPage; |
| |
| import org.eclipse.statet.jcommons.status.ProgressMonitor; |
| import org.eclipse.statet.jcommons.status.StatusException; |
| import org.eclipse.statet.jcommons.ts.core.SystemRunnable; |
| import org.eclipse.statet.jcommons.ts.core.Tool; |
| |
| import org.eclipse.statet.ecommons.preferences.core.Preference.NullableStringPref; |
| import org.eclipse.statet.ecommons.preferences.core.util.PreferenceUtils; |
| import org.eclipse.statet.ecommons.ui.util.UIAccess; |
| |
| import org.eclipse.statet.internal.r.console.ui.Messages; |
| import org.eclipse.statet.nico.ui.NicoUI; |
| import org.eclipse.statet.nico.ui.util.ToolMessageDialog; |
| import org.eclipse.statet.r.console.core.AbstractRController; |
| import org.eclipse.statet.r.console.core.AbstractRDataRunnable; |
| import org.eclipse.statet.r.console.core.IRDataAdapter; |
| import org.eclipse.statet.r.console.core.RProcess; |
| import org.eclipse.statet.r.core.pkgmanager.IRPkgInfoAndData; |
| import org.eclipse.statet.r.core.pkgmanager.IRPkgManager; |
| import org.eclipse.statet.r.core.pkgmanager.IRPkgSet; |
| import org.eclipse.statet.r.core.renv.IREnvManager; |
| import org.eclipse.statet.r.nico.impl.RjsController; |
| import org.eclipse.statet.r.ui.pkgmanager.RPkgManagerUI; |
| import org.eclipse.statet.r.ui.pkgmanager.StartAction; |
| import org.eclipse.statet.rj.renv.core.REnvConfiguration; |
| import org.eclipse.statet.rj.renv.core.RLibLocation; |
| import org.eclipse.statet.rj.renv.core.RPkgList; |
| import org.eclipse.statet.rj.renv.runtime.RPkgManager; |
| import org.eclipse.statet.rj.services.RVersion; |
| |
| |
| public class REnvAutoUpdater extends AbstractRDataRunnable implements SystemRunnable { |
| |
| |
| public static void connect(final RjsController controller, final IRPkgManager manager) { |
| if (controller == null || manager == null) { |
| return; |
| } |
| final REnvAutoUpdater checker= new REnvAutoUpdater(manager); |
| controller.getTool().getQueue().addOnIdle(checker, 1000); |
| } |
| |
| |
| private final IRPkgManager manager; |
| |
| private boolean initial= true; |
| |
| private boolean versionChecked; |
| |
| private int checkStamp; |
| |
| |
| private REnvAutoUpdater(final IRPkgManager manager) { |
| super("r/renv/check", Messages.REnvIndex_Check_task); //$NON-NLS-1$ |
| this.manager= manager; |
| } |
| |
| |
| @Override |
| public boolean changed(final int event, final Tool tool) { |
| if (event == MOVING_FROM) { |
| return false; |
| } |
| return true; |
| } |
| |
| @Override |
| protected void run(final IRDataAdapter r, final ProgressMonitor m) throws StatusException { |
| final AbstractRController rjs= (AbstractRController) r; |
| if (rjs.isBusy() || !r.isDefaultPrompt() || r.getChangeStamp() == this.checkStamp) { |
| return; |
| } |
| |
| int flags= 0; |
| if (this.initial) { |
| this.initial= false; |
| flags |= IRPkgManager.INITIAL; |
| } |
| this.manager.check(flags, r, m); |
| this.checkStamp= r.getChangeStamp(); |
| |
| if (!this.versionChecked) { |
| this.versionChecked= true; |
| |
| checkRVersion(r, m); |
| } |
| } |
| |
| private void checkRVersion(final IRDataAdapter r, final ProgressMonitor m) throws StatusException { |
| final RVersion rVersion= r.getPlatform().getRVersion(); |
| |
| final REnvConfiguration rEnvConfig= this.manager.getREnv().get(REnvConfiguration.class); |
| if (rEnvConfig == null) { |
| return; |
| } |
| final NullableStringPref pref= new NullableStringPref( |
| IREnvManager.PREF_QUALIFIER + '/' + rEnvConfig.getREnv().getId(), |
| "CheckedR.version" ); //$NON-NLS-1$ |
| final String s= PreferenceUtils.getInstancePrefs().getPreferenceValue(pref); |
| if (s != null) { |
| final RVersion checkedVersion= new RVersion(s); |
| if (!checkedVersion.equals(rVersion)) { |
| PreferenceUtils.setPrefValue(InstanceScope.INSTANCE, pref, rVersion.toString(), |
| PreferenceUtils.FLUSH_SYNC ); |
| if (checkedVersion.getMajor() != rVersion.getMajor() |
| || checkedVersion.getMinor() != rVersion.getMinor() ) { |
| final IRPkgSet.Ext rPkgDataset= (IRPkgSet.Ext) this.manager.getDataset( |
| RPkgManager.INSTALLED | RPkgManager.AVAILABLE, |
| r, m ); |
| if (hasNonBasePackages(rPkgDataset)) { |
| handleNewVersion(rEnvConfig, r.getTool(), (IRPkgManager.Ext) this.manager, |
| checkedVersion, rVersion ); |
| } |
| } |
| } |
| } |
| else { |
| PreferenceUtils.setPrefValue(InstanceScope.INSTANCE, pref, rVersion.toString(), |
| PreferenceUtils.FLUSH_SYNC ); |
| } |
| } |
| |
| private static String mainVersionString(final RVersion version) { |
| final StringBuilder sb= new StringBuilder(8); |
| sb.append(version.getMajor()); |
| sb.append('.'); |
| sb.append(version.getMinor()); |
| return sb.toString(); |
| } |
| |
| private boolean hasNonBasePackages(final IRPkgSet.Ext pkgSet) { |
| final List<? extends RPkgList<? extends IRPkgInfoAndData>> all= pkgSet.getInstalled().getAll(); |
| for (final RPkgList<? extends IRPkgInfoAndData> pkgList : all) { |
| for (final IRPkgInfoAndData pkg : pkgList) { |
| if ((pkg.getLibLocation() == null || pkg.getLibLocation().getSource() != RLibLocation.EPLUGIN) |
| && !"base".equals(pkg.getPriority())) { //$NON-NLS-1$ |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| private void handleNewVersion(final REnvConfiguration rEnvConfig, final RProcess tool, |
| final IRPkgManager.Ext rPkgManager, final RVersion oldVersion, final RVersion newVersion) { |
| final IWorkbenchPage page= NicoUI.getToolRegistry().findWorkbenchPage(tool); |
| final Shell shell= page.getWorkbenchWindow().getShell(); |
| final Display display= UIAccess.getDisplay(shell); |
| display.asyncExec(new Runnable() { |
| @Override |
| public void run() { |
| if (ToolMessageDialog.openQuestion(tool, shell, Messages.REnvIndex_NewVersion_title, |
| NLS.bind(Messages.REnvIndex_NewVersion_message, new Object[] { |
| rEnvConfig.getName(), mainVersionString(oldVersion), |
| mainVersionString(newVersion) }))) { |
| RPkgManagerUI.openDialog(rPkgManager, tool, shell, |
| new StartAction(StartAction.REINSTALL) ); |
| } |
| } |
| }); |
| } |
| |
| } |