blob: 4c7d9306b4f628f67e316acf1df1116759bcdd83 [file] [log] [blame]
/*=============================================================================#
# 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) );
}
}
});
}
}