/******************************************************************************* * Copyright (c) 2000, 2015 IBM Corporation 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: * IBM Corporation - initial API and implementation * Anton Leherbauer (Wind River Systems) - Adapted for CDT *******************************************************************************/ package org.eclipse.cdt.ui.testplugin; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobManager; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IWidgetTokenKeeper; import org.eclipse.jface.text.IWidgetTokenOwner; import org.eclipse.jface.text.reconciler.AbstractReconciler; import org.eclipse.jface.text.reconciler.IReconcilingStrategy; import org.eclipse.jface.text.reconciler.MonoReconciler; import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IViewReference; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchPartSite; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.dialogs.IOverwriteQuery; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.texteditor.AbstractTextEditor; import org.eclipse.ui.texteditor.IDocumentProvider; import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider; import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider; import org.eclipse.ui.wizards.datatransfer.ImportOperation; import org.junit.Assert; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.ResourceHelper; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.PreferenceConstants; import org.eclipse.cdt.internal.ui.text.CReconcilingStrategy; import org.eclipse.cdt.internal.ui.text.CompositeReconcilingStrategy; /** * Copied from org.eclipse.jdt.text.tests.performance. * * @since 4.0 */ public class EditorTestHelper { private static class ImportOverwriteQuery implements IOverwriteQuery { @Override public String queryOverwrite(String file) { return ALL; } } public static final String TEXT_EDITOR_ID= "org.eclipse.ui.DefaultTextEditor"; public static final String C_EDITOR_ID= "org.eclipse.cdt.ui.editor.CEditor"; public static final String RESOURCE_PERSPECTIVE_ID= "org.eclipse.ui.resourcePerspective"; public static final String C_PERSPECTIVE_ID= "org.eclipse.cdt.ui.CPerspective"; public static final String OUTLINE_VIEW_ID= "org.eclipse.ui.views.ContentOutline"; public static final String C_VIEW_ID= "org.eclipse.cdt.ui.CView"; public static final String NAVIGATOR_VIEW_ID= "org.eclipse.ui.views.ResourceNavigator"; public static final String INTRO_VIEW_ID= "org.eclipse.ui.internal.introview"; private static final long MAX_WAIT_TIME = 60000; // don't wait longer than 60 seconds public static IEditorPart openInEditor(IFile file, boolean runEventLoop) throws PartInitException { IEditorPart part= IDE.openEditor(getActivePage(), file); if (runEventLoop) runEventQueue(part); return part; } public static IEditorPart openInEditor(IFile file, String editorId, boolean runEventLoop) throws PartInitException { IEditorPart part= IDE.openEditor(getActivePage(), file, editorId); if (runEventLoop) runEventQueue(part); return part; } public static AbstractTextEditor[] openInEditor(IFile[] files, String editorId) throws PartInitException { AbstractTextEditor editors[]= new AbstractTextEditor[files.length]; for (int i= 0; i < files.length; i++) { editors[i]= (AbstractTextEditor) openInEditor(files[i], editorId, true); joinReconciler(getSourceViewer(editors[i]), 100, 10000, 100); } return editors; } public static IDocument getDocument(ITextEditor editor) { IDocumentProvider provider= editor.getDocumentProvider(); IEditorInput input= editor.getEditorInput(); return provider.getDocument(input); } public static void revertEditor(ITextEditor editor, boolean runEventQueue) { editor.doRevertToSaved(); if (runEventQueue) runEventQueue(editor); } public static void closeEditor(IEditorPart editor) { IWorkbenchPartSite site; IWorkbenchPage page; if (editor != null && (site= editor.getSite()) != null && (page= site.getPage()) != null) page.closeEditor(editor, false); } public static void closeAllEditors() { IWorkbenchWindow[] windows= PlatformUI.getWorkbench().getWorkbenchWindows(); for (int i= 0; i < windows.length; i++) { IWorkbenchPage[] pages= windows[i].getPages(); for (int j= 0; j < pages.length; j++) { pages[j].closeAllEditors(false); } } } /** * Runs the event queue on the current display until it is empty. */ public static void runEventQueue() { IWorkbenchWindow window= getActiveWorkbenchWindow(); if (window != null) runEventQueue(window.getShell()); } public static void runEventQueue(IWorkbenchPart part) { runEventQueue(part.getSite().getShell()); } public static void runEventQueue(Shell shell) { runEventQueue(shell.getDisplay()); } public static void runEventQueue(Display display) { while (display.readAndDispatch()) { // do nothing } } /** * Runs the event queue on the current display and lets it sleep until the * timeout elapses. * * @param millis the timeout in milliseconds */ public static void runEventQueue(long millis) { runEventQueue(getActiveDisplay(), millis); } public static void runEventQueue(IWorkbenchPart part, long millis) { runEventQueue(part.getSite().getShell(), millis); } public static void runEventQueue(Shell shell, long millis) { runEventQueue(shell.getDisplay(), millis); } public static void runEventQueue(Display display, long minTime) { if (display != null) { DisplayHelper.sleep(display, minTime); } else { sleep((int) minTime); } } public static IWorkbenchWindow getActiveWorkbenchWindow() { return PlatformUI.getWorkbench().getActiveWorkbenchWindow(); } public static void forceFocus() { IWorkbenchWindow window= getActiveWorkbenchWindow(); if (window == null) { IWorkbenchWindow[] wbWindows= PlatformUI.getWorkbench().getWorkbenchWindows(); if (wbWindows.length == 0) return; window= wbWindows[0]; } Shell shell= window.getShell(); if (shell != null && !shell.isDisposed()) { shell.forceActive(); shell.forceFocus(); } } public static IWorkbenchPage getActivePage() { IWorkbenchWindow window= getActiveWorkbenchWindow(); return window != null ? window.getActivePage() : null; } public static Display getActiveDisplay() { IWorkbenchWindow window= getActiveWorkbenchWindow(); return window != null ? window.getShell().getDisplay() : null; } public static void joinBackgroundActivities(AbstractTextEditor editor) throws CoreException { joinBackgroundActivities(getSourceViewer(editor)); } public static void joinBackgroundActivities(SourceViewer sourceViewer) throws CoreException { joinBackgroundActivities(); joinReconciler(sourceViewer, 500, 0, 500); } public static void joinBackgroundActivities() throws CoreException { // Join Building boolean interrupted= true; while (interrupted) { try { Job.getJobManager().join(ResourcesPlugin.FAMILY_AUTO_BUILD, null); interrupted= false; } catch (InterruptedException e) { interrupted= true; } } // Join indexing IIndexManager indexManager= CCorePlugin.getIndexManager(); indexManager.joinIndexer(1000, new NullProgressMonitor()); // Join jobs joinJobs(0, 1000, 500); } public static boolean joinJobs(long minTime, long maxTime, long intervalTime) { runEventQueue(minTime); DisplayHelper helper= new DisplayHelper() { @Override public boolean condition() { return allJobsQuiet(); } }; return helper.waitForCondition(getActiveDisplay(), maxTime > 0 ? maxTime : MAX_WAIT_TIME, intervalTime); } public static void sleep(int intervalTime) { try { Thread.sleep(intervalTime); } catch (InterruptedException e) { e.printStackTrace(); } } public static boolean allJobsQuiet() { IJobManager jobManager= Job.getJobManager(); Job[] jobs= jobManager.find(null); for (int i= 0; i < jobs.length; i++) { Job job= jobs[i]; int state= job.getState(); if (state == Job.RUNNING || state == Job.WAITING) { return false; } } return true; } public static boolean isViewShown(String viewId) { return getActivePage().findViewReference(viewId) != null; } public static boolean showView(String viewId, boolean show) throws PartInitException { IWorkbenchPage activePage= getActivePage(); IViewReference view= activePage.findViewReference(viewId); boolean shown= view != null; if (shown != show) if (show) { activePage.showView(viewId); } else { activePage.hideView(view); } return shown; } public static void bringToTop() { getActiveWorkbenchWindow().getShell().forceActive(); } public static void forceReconcile(SourceViewer sourceViewer) { Accessor reconcilerAccessor= new Accessor(getReconciler(sourceViewer), AbstractReconciler.class); reconcilerAccessor.invoke("forceReconciling", new Object[0]); } public static boolean joinReconciler(SourceViewer sourceViewer, long minTime, long maxTime, long intervalTime) { runEventQueue(minTime); AbstractReconciler reconciler= getReconciler(sourceViewer); if (reconciler == null) return true; final Accessor backgroundThreadAccessor= getBackgroundThreadAccessor(reconciler); Accessor reconcilerAccessor= null; if (reconciler instanceof MonoReconciler) { IReconcilingStrategy strategy= reconciler.getReconcilingStrategy(IDocument.DEFAULT_CONTENT_TYPE); if (strategy instanceof CReconcilingStrategy) { reconcilerAccessor= new Accessor(strategy, CReconcilingStrategy.class); } else if (strategy instanceof CompositeReconcilingStrategy) { IReconcilingStrategy[] strategies= ((CompositeReconcilingStrategy)strategy).getReconcilingStrategies(); for (int i = 0; i < strategies.length; i++) { if (strategies[i] instanceof CReconcilingStrategy) { reconcilerAccessor= new Accessor(strategies[i], CReconcilingStrategy.class); break; } } } } final Accessor cReconcilerAccessor= reconcilerAccessor; DisplayHelper helper= new DisplayHelper() { @Override public boolean condition() { return !isRunning(cReconcilerAccessor, backgroundThreadAccessor); } }; return helper.waitForCondition(getActiveDisplay(), maxTime > 0 ? maxTime : MAX_WAIT_TIME, intervalTime); } public static AbstractReconciler getReconciler(SourceViewer sourceViewer) { return (AbstractReconciler) new Accessor(sourceViewer, SourceViewer.class).get("fReconciler"); } public static SourceViewer getSourceViewer(AbstractTextEditor editor) { SourceViewer sourceViewer= (SourceViewer) new Accessor(editor, AbstractTextEditor.class).invoke("getSourceViewer", new Object[0]); return sourceViewer; } private static Accessor getBackgroundThreadAccessor(AbstractReconciler reconciler) { Object backgroundThread= new Accessor(reconciler, AbstractReconciler.class).get("fThread"); return new Accessor(backgroundThread, backgroundThread.getClass()); } private static boolean isRunning(Accessor cReconcilerAccessor, Accessor backgroundThreadAccessor) { return (cReconcilerAccessor != null ? !isInitialProcessDone(cReconcilerAccessor) : false) || isDirty(backgroundThreadAccessor) || isActive(backgroundThreadAccessor); } private static boolean isInitialProcessDone(Accessor cReconcilerAccessor) { return ((Boolean) cReconcilerAccessor.get("fInitialProcessDone")).booleanValue(); } private static boolean isDirty(Accessor backgroundThreadAccessor) { return ((Boolean) backgroundThreadAccessor.invoke("isDirty", new Object[0])).booleanValue(); } private static boolean isActive(Accessor backgroundThreadAccessor) { return ((Boolean) backgroundThreadAccessor.invoke("isActive", new Object[0])).booleanValue(); } public static String showPerspective(String perspective) throws WorkbenchException { String shownPerspective= getActivePage().getPerspective().getId(); if (!perspective.equals(shownPerspective)) { IWorkbench workbench= PlatformUI.getWorkbench(); IWorkbenchWindow activeWindow= workbench.getActiveWorkbenchWindow(); workbench.showPerspective(perspective, activeWindow); } return shownPerspective; } public static void closeAllPopUps(SourceViewer sourceViewer) { IWidgetTokenKeeper tokenKeeper= new IWidgetTokenKeeper() { @Override public boolean requestWidgetToken(IWidgetTokenOwner owner) { return true; } }; sourceViewer.requestWidgetToken(tokenKeeper, Integer.MAX_VALUE); sourceViewer.releaseWidgetToken(tokenKeeper); } public static void resetFolding() { CUIPlugin.getDefault().getPreferenceStore().setToDefault(PreferenceConstants.EDITOR_FOLDING_ENABLED); } public static boolean enableFolding(boolean value) { IPreferenceStore preferenceStore= CUIPlugin.getDefault().getPreferenceStore(); boolean oldValue= preferenceStore.getBoolean(PreferenceConstants.EDITOR_FOLDING_ENABLED); if (value != oldValue) preferenceStore.setValue(PreferenceConstants.EDITOR_FOLDING_ENABLED, value); return oldValue; } public static ICProject createCProject(String project, String externalSourceFolder) throws CoreException { return createCProject(project, externalSourceFolder, false, false); } public static ICProject createCProject(String project, String externalSourceFolder, boolean linkSourceFolder) throws CoreException { return createCProject(project, externalSourceFolder, linkSourceFolder, false); } public static ICProject createCProject(String project, String externalSourceFolder, boolean linkSourceFolder, boolean useIndexer) throws CoreException { ICProject cProject= CProjectHelper.createCCProject(project, "bin", useIndexer ? IPDOMManager.ID_FAST_INDEXER : IPDOMManager.ID_NO_INDEXER); IFolder folder; if (linkSourceFolder) { File file= FileTool.getFileInPlugin(CTestPlugin.getDefault(), new Path(externalSourceFolder)); folder= ResourceHelper.createLinkedFolder((IProject) cProject.getUnderlyingResource(), "src", file.getAbsolutePath()); } else { folder= ((IProject) cProject.getUnderlyingResource()).getFolder("src"); importFilesFromDirectory(FileTool.getFileInPlugin(CTestPlugin.getDefault(), new Path(externalSourceFolder)), folder.getFullPath(), null); } Assert.assertNotNull(folder); Assert.assertTrue(folder.exists()); CProjectHelper.addCContainer(cProject, "src"); if (useIndexer) { IIndexManager indexManager= CCorePlugin.getIndexManager(); indexManager.joinIndexer(5000, new NullProgressMonitor()); } return cProject; } public static IProject createNonCProject(final String projectName, String externalSourceFolder, boolean linkSourceFolder) throws CoreException { final IWorkspace ws = ResourcesPlugin.getWorkspace(); final IProject newProject[] = new IProject[1]; ws.run(new IWorkspaceRunnable() { @Override public void run(IProgressMonitor monitor) throws CoreException { IWorkspaceRoot root = ws.getRoot(); IProject project = root.getProject(projectName); if (!project.exists()) { project.create(null); } else { project.refreshLocal(IResource.DEPTH_INFINITE, null); } if (!project.isOpen()) { project.open(null); } newProject[0] = project; } }, null); final IProject project= newProject[0]; Assert.assertNotNull(project); final IFolder folder; if (linkSourceFolder) { File file= FileTool.getFileInPlugin(CTestPlugin.getDefault(), new Path(externalSourceFolder)); folder= ResourceHelper.createLinkedFolder(project, "src", file.getAbsolutePath()); } else { folder= project.getFolder("src"); importFilesFromDirectory(FileTool.getFileInPlugin(CTestPlugin.getDefault(), new Path(externalSourceFolder)), folder.getFullPath(), null); } Assert.assertNotNull(folder); Assert.assertTrue(folder.exists()); return project; } public static IFile createFile(IContainer container, String fileName, String contents, IProgressMonitor monitor) throws CoreException { // Obtain file handle. IFile file = container.getFile(new Path(fileName)); InputStream stream = new ByteArrayInputStream(contents.getBytes()); // Create file input stream. if(file.exists()) file.setContents(stream, false, false, monitor); else file.create(stream, false, monitor); return file; } public static IFile[] findFiles(IResource resource) throws CoreException { List<IResource> files= new ArrayList<>(); findFiles(resource, files); return files.toArray(new IFile[files.size()]); } private static void findFiles(IResource resource, List<IResource> files) throws CoreException { if (resource instanceof IFile) { files.add(resource); return; } if (resource instanceof IContainer) { IResource[] resources= ((IContainer) resource).members(); for (int i= 0; i < resources.length; i++) findFiles(resources[i], files); } } public static boolean setDialogEnabled(String id, boolean enabled) { // boolean wasEnabled= OptionalMessageDialog.isDialogEnabled(id); // if (wasEnabled != enabled) // OptionalMessageDialog.setDialogEnabled(id, enabled); // return wasEnabled; return false; } public static void importFilesFromDirectory(File rootDir, IPath destPath, IProgressMonitor monitor) throws CoreException { try { IImportStructureProvider structureProvider= FileSystemStructureProvider.INSTANCE; List<File> files= new ArrayList<>(100); addFiles(rootDir, files); ImportOperation op= new ImportOperation(destPath, rootDir, structureProvider, new ImportOverwriteQuery(), files); op.setCreateContainerStructure(false); op.run(monitor); } catch (Exception x) { throw newCoreException(x); } } private static CoreException newCoreException(Throwable x) { return new CoreException(new Status(IStatus.ERROR, CTestPlugin.PLUGIN_ID, -1, "", x)); } private static void addFiles(File dir, List<File> collection) throws IOException { File[] files= dir.listFiles(); List<File> subDirs= new ArrayList<>(2); for (int i= 0; i < files.length; i++) { if (files[i].isFile()) { collection.add(files[i]); } else if (files[i].isDirectory()) { subDirs.add(files[i]); } } Iterator<File> iter= subDirs.iterator(); while (iter.hasNext()) { File subDir= iter.next(); addFiles(subDir, collection); } } }