Java tutorial
/*=============================================================================# # Copyright (c) 2008-2015 Stephan Wahlbrink (WalWare.de) and others. # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 # which accompanies this distribution, and is available at # http://www.eclipse.org/legal/epl-v10.html # # Contributors: # Stephan Wahlbrink - initial API and implementation #=============================================================================*/ package de.walware.statet.r.internal.console.ui.launching; import java.lang.reflect.InvocationTargetException; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.jdt.debug.ui.launchConfigurations.JavaJRETab; import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; import org.eclipse.jdt.launching.IVMInstall; import org.eclipse.jdt.launching.IVMInstall3; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jdt.launching.VMStandin; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import de.walware.ecommons.debug.ui.InputArgumentsComposite; import de.walware.ecommons.preferences.PreferencesUtil; import de.walware.ecommons.preferences.SettingsChangeNotifier.ChangeListener; import de.walware.ecommons.ui.util.LayoutUtil; import de.walware.ecommons.ui.util.UIAccess; import de.walware.statet.r.core.renv.IREnv; import de.walware.statet.r.core.renv.IREnvConfiguration; import de.walware.statet.r.core.renv.IREnvManager; import de.walware.statet.r.internal.console.ui.RConsoleMessages; import de.walware.statet.r.internal.console.ui.RConsoleUIPlugin; import de.walware.statet.r.launching.ui.REnvTab; /** * Adds: * <li>Optional requirement/validation of JRE</li> * <li>VM Arguments</li> */ class ExtJavaJRETab extends JavaJRETab implements ChangeListener { private boolean is32(final String arch) { return (arch.equals(Platform.ARCH_X86) || arch.equals("i386") || arch.equals("i586") //$NON-NLS-1$//$NON-NLS-2$ || arch.equals("i686")); //$NON-NLS-1$ } private boolean is64(final String arch) { return (arch.equals(Platform.ARCH_X86_64) || arch.equals("amd64")); //$NON-NLS-1$ } private final RConsoleMainTab fMainTab; private final REnvTab fREnvTab; private InputArgumentsComposite fVmArgsControl; private boolean fEnableVMArchCheck; private IVMInstall fLastCheckedVM; private int fLastCheckedVMBits; private int fLastCheckedRBits; private boolean fValidInBackground; public ExtJavaJRETab(final RConsoleMainTab mainTab, final REnvTab renvTab) { fMainTab = mainTab; fREnvTab = renvTab; PreferencesUtil.getSettingsChangeNotifier().addChangeListener(this); fEnableVMArchCheck = ((Platform.getOS().startsWith("win") || Platform.getOS().equals(Platform.OS_LINUX)) //$NON-NLS-1$ && (Platform.getOSArch().startsWith("x86") || Platform.getOSArch().startsWith("amd64"))); //$NON-NLS-1$ //$NON-NLS-2$ } @Override public void createControl(final Composite parent) { super.createControl(parent); final Composite tabHolder = getDynamicTabHolder(); final Composite composite = tabHolder.getParent(); final GridLayout layout = (GridLayout) composite.getLayout(); tabHolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, layout.numColumns, 1)); final Composite extComposite = new Composite(composite, SWT.NONE); final GridLayout extLayout = new GridLayout(); extLayout.marginHeight = 0; extComposite.setLayout(extLayout); extComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, layout.numColumns, 1)); final Group group = new Group(extComposite, SWT.NONE); group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); group.setLayout(LayoutUtil.applyGroupDefaults(new GridLayout(), 1)); group.setText(RConsoleMessages.JavaJRE_Tab_VMConfig_group); fVmArgsControl = new InputArgumentsComposite(group, RConsoleMessages.JavaJRE_Tab_VMArguments_label); fVmArgsControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); fVmArgsControl.getTextControl().addModifyListener(new ModifyListener() { @Override public void modifyText(final ModifyEvent e) { updateLaunchConfigurationDialog(); } }); final Label note = new Label(group, SWT.WRAP); note.setText(fVmArgsControl.getNoteText()); note.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); Dialog.applyDialogFont(extComposite); } @Override protected void loadDynamicJREArea() { super.loadDynamicJREArea(); final Composite tabHolder = getDynamicTabHolder(); tabHolder.getParent().layout(new Control[] { tabHolder }); } @Override public void settingsChanged(final Set<String> groupIds) { if (groupIds.contains(IREnvManager.SETTINGS_GROUP_ID)) { UIAccess.getDisplay().syncExec(new Runnable() { @Override public void run() { final int previous = fLastCheckedRBits; updateRBits(); if (previous != fLastCheckedRBits) { getLaunchConfigurationDialog().updateMessage(); getLaunchConfigurationDialog().updateButtons(); } } }); } } @Override public void dispose() { PreferencesUtil.getSettingsChangeNotifier().removeChangeListener(this); super.dispose(); } @Override public boolean isValid(final ILaunchConfiguration config) { if (fEnableVMArchCheck) { if (fValidInBackground) { scheduleUpdateJob(); return false; } final RConsoleType type = fMainTab.getSelectedType(); if (type == null || !type.requireJRE()) { setErrorMessage(null); setMessage(null); return true; } if (!super.isValid(config)) { return false; } // try to check compatibility updateRBits(); if (fLastCheckedRBits == -1) { // check not necessary return true; } IVMInstall jre = null; try { jre = JavaRuntime.computeVMInstall(config); } catch (final CoreException e) { } if (jre instanceof VMStandin) { jre = ((VMStandin) jre).convertToRealVM(); } if (jre != null && fLastCheckedVM != jre) { fLastCheckedVM = jre; updateVMBits(); } if (jre == null || fLastCheckedVMBits == -1) { // check failed technically return true; } if (fLastCheckedVMBits == fLastCheckedRBits) { return true; } else { setErrorMessage(NLS.bind(RConsoleMessages.JavaJRE_RCompatibility_error_DifferentBits_message, fLastCheckedRBits, fLastCheckedVMBits)); return false; } } return true; } private void updateRBits() { fLastCheckedRBits = -1; final IREnv rEnv = fREnvTab.getSelectedEnv(); if (rEnv == null) { return; } final IREnvConfiguration config = rEnv.getConfig(); if (config == null) { return; } final String arch = config.getSubArch(); if (arch != null && arch.length() > 0) { if (is32(arch)) { fLastCheckedRBits = 32; } else if (is64(arch)) { fLastCheckedRBits = 64; } } } private void updateVMBits() { fLastCheckedVMBits = -1; if (fLastCheckedVM instanceof IVMInstall3) { fValidInBackground = true; try { getLaunchConfigurationDialog().run(true, true, new IRunnableWithProgress() { @Override public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { final String[] propertyNames = new String[] { "os.arch", "java.vm.name", //$NON-NLS-1$//$NON-NLS-2$ "sun.arch.data.model", "com.ibm.vm.bitmode" }; //$NON-NLS-1$ //$NON-NLS-2$ try { final Map<String, String> properties = ((IVMInstall3) fLastCheckedVM) .evaluateSystemProperties(propertyNames, monitor); { // try known os.arch final String p = properties.get("os.arch"); //$NON-NLS-1$ if (p != null && p.length() > 0) { if (is32(p)) { fLastCheckedVMBits = 32; return; } else if (is64(p)) { fLastCheckedVMBits = 64; return; } } } } catch (final CoreException e) { throw new InvocationTargetException(e); } } }); } catch (final InvocationTargetException e) { RConsoleUIPlugin.log(new Status(IStatus.ERROR, RConsoleUIPlugin.PLUGIN_ID, -1, "An error when trying to fetch VM properties for JRE validation.", e.getTargetException())); //$NON-NLS-1$ } catch (final InterruptedException e) { } finally { fValidInBackground = false; } } } @Override public void initializeFrom(final ILaunchConfiguration configuration) { super.initializeFrom(configuration); String vmArgs = null; try { vmArgs = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, (String) null); } catch (final CoreException e) { } fVmArgsControl.getTextControl().setText(vmArgs != null ? vmArgs : ""); //$NON-NLS-1$ } @Override public void performApply(final ILaunchConfigurationWorkingCopy configuration) { super.performApply(configuration); final String vmArgs = fVmArgsControl.getTextControl().getText(); configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_VM_ARGUMENTS, (vmArgs.length() > 0) ? vmArgs : (String) null); } @Override protected long getUpdateJobDelay() { return 400; } }