/*==========================================================================*\ | $Id: StackTraceDependencyChecker.java,v 1.2 2009/09/13 12:59:28 aallowat Exp $ |*-------------------------------------------------------------------------*| | Copyright (C) 2006-2009 Virginia Tech | | This file is part of Web-CAT Eclipse Plugins. | | Web-CAT is free software; you can redistribute it and/or modify | it under the terms of the GNU General Public License as published by | the Free Software Foundation; either version 2 of the License, or | (at your option) any later version. | | Web-CAT is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | You should have received a copy of the GNU General Public License | along with Web-CAT; if not, see <http://www.gnu.org/licenses/>. \*==========================================================================*/ package net.sf.webcat.eclipse.cxxtest.internal; import java.lang.reflect.InvocationTargetException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import net.sf.webcat.eclipse.cxxtest.CxxTestPlugin; import net.sf.webcat.eclipse.cxxtest.IStackTraceDependencyCheck; import net.sf.webcat.eclipse.cxxtest.i18n.Messages; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; 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.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.progress.IProgressService; /** * * @author Tony Allevato (Virginia Tech Computer Science) * @author latest changes by: $Author: aallowat $ * @version $Revision: 1.2 $ $Date: 2009/09/13 12:59:28 $ */ public class StackTraceDependencyChecker { private StackTraceDependencyChecker() { // Prevent instantiation. } public static boolean checkForDependencies(final boolean forceModal) { final IPreferenceStore store = CxxTestPlugin.getDefault().getPreferenceStore(); final MutableBoolean result = new MutableBoolean(); final boolean alreadyFound = store.getBoolean( CxxTestPlugin.CXXTEST_PREF_HAS_REQUIRED_LIBRARIES); if (!forceModal && alreadyFound) { // Run the check in the background if we've already found the // dependencies once. That way if anything on the system changes // since the last run, we can still detect it and disable stack // tracing, but without forcing the user to wait for a modal // operation at every startup. Job job = new Job( Messages.StackTraceDependencyChecker_BackgroundJobName) { @Override protected IStatus run(IProgressMonitor monitor) { boolean success = runDependencyChecks( forceModal || !alreadyFound, store, monitor); result.setValue(success); return Status.OK_STATUS; } }; job.schedule(); return result.getValue(); } // If this is the first time we're checking, or if it's being forced // by the user (for example, by enable stack traces in the preferences // window), then display it has a modal dialog. Display.getDefault().syncExec(new Runnable() { public void run() { try { IProgressService service = PlatformUI.getWorkbench().getProgressService(); service.run(true, false, new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { boolean success = runDependencyChecks( forceModal || !alreadyFound, store, monitor); result.setValue(success); } }); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }); return result.getValue(); } private static boolean runDependencyChecks(boolean forceModal, IPreferenceStore store, IProgressMonitor monitor) { boolean anyDependenciesMissing = false; final ArrayList<String> missingDependencies = new ArrayList<String>(); IExtensionRegistry registry = Platform.getExtensionRegistry(); IExtensionPoint extensionPoint = registry.getExtensionPoint(CxxTestPlugin.PLUGIN_ID + ".stackTraceDependencyCheck"); //$NON-NLS-1$ IConfigurationElement[] elements = extensionPoint.getConfigurationElements(); monitor.beginTask( Messages.StackTraceDependencyChecker_BackgroundJobDescription, elements.length); for(IConfigurationElement element : elements) { SubProgressMonitor submon = new SubProgressMonitor(monitor, 1); if ("dependencyCheck".equals(element.getName())) //$NON-NLS-1$ { try { Object obj = element.createExecutableExtension("class"); //$NON-NLS-1$ if (obj instanceof IStackTraceDependencyCheck) { IStackTraceDependencyCheck checker = (IStackTraceDependencyCheck) obj; boolean success = checker.checkForDependencies(submon); if (!success) { anyDependenciesMissing = true; missingDependencies.add( checker.missingDependencies()); } } } catch (CoreException e) { // Do nothing. } } monitor.worked(1); } monitor.done(); if (anyDependenciesMissing) { boolean hadDependenciesBefore = store.getBoolean( CxxTestPlugin.CXXTEST_PREF_HAS_REQUIRED_LIBRARIES); if (hadDependenciesBefore || forceModal) { final IWorkbench workbench = PlatformUI.getWorkbench(); workbench.getDisplay().syncExec(new Runnable() { public void run() { Shell shell = workbench.getActiveWorkbenchWindow().getShell(); showMissingDependencyDialog(shell, missingDependencies); } }); } // Disable stack traces in preferences. store.setValue(CxxTestPlugin.CXXTEST_PREF_TRACE_STACK, false); store.setValue(CxxTestPlugin.CXXTEST_PREF_HAS_REQUIRED_LIBRARIES, false); return false; } else { // Don't enable PREF_TRACE_STACK here. The default value is // already true, and since this runs on every startup, store.setValue(CxxTestPlugin.CXXTEST_PREF_HAS_REQUIRED_LIBRARIES, true); return true; } } private static void showMissingDependencyDialog(Shell shell, List<String> missingDependencies) { StringBuffer buffer = new StringBuffer(); buffer.append( Messages.StackTraceDependencyChecker_MissingDependencyMsgStart); for (String missingDep : missingDependencies) { buffer.append(MessageFormat.format( Messages.StackTraceDependencyChecker_MissingDependencyPartDescription, missingDep)); } buffer.append(Messages.StackTraceDependencyChecker_MissingDependencyMsgEnd); MessageDialog.openInformation(shell, Messages.StackTraceDependencyChecker_ShellTitle, buffer.toString()); } }