/******************************************************************************* * Copyright (c) 2009 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 * Zend Technologies *******************************************************************************/ package org.eclipse.php.core.tests; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; 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.FileLocator; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.dltk.core.DLTKCore; import org.eclipse.dltk.core.IBuildpathAttribute; import org.eclipse.dltk.core.IBuildpathEntry; import org.eclipse.dltk.core.IProjectFragment; import org.eclipse.dltk.core.IScriptFolder; import org.eclipse.dltk.core.IScriptProject; import org.eclipse.dltk.core.ISourceModule; import org.eclipse.dltk.core.ModelException; import org.eclipse.dltk.internal.core.BuildpathEntry; import org.eclipse.dltk.internal.core.ModelManager; import org.eclipse.wst.validation.ValidationFramework; import org.osgi.framework.Bundle; import junit.framework.TestSuite; public abstract class AbstractProjectSuite extends TestSuite { public static final String WORKSPACE_BASE = "workspace"; private Bundle bundle; public AbstractProjectSuite(String name, Bundle bundle) { super(name); this.bundle = bundle; } public AbstractProjectSuite(String name) { this(name, PHPCoreTests.getDefault().getBundle()); } protected IProject setUpProject(final String projectName) throws CoreException, IOException { // copy files in project from source workspace to target workspace final File sourceWorkspacePath = getSourceWorkspacePath(); final File targetWorkspacePath = getWorkspaceRoot().getLocation().toFile(); copyDirectory(new File(sourceWorkspacePath, projectName), new File(targetWorkspacePath, projectName)); return createProject(projectName); } protected IScriptProject setUpScriptProjectTo(final String projectName, final String fromName) throws CoreException, IOException { final IProject project = setUpProjectTo(projectName, fromName); return DLTKCore.create(project); } protected IProject setUpProjectTo(final String projectName, final String fromName) throws CoreException, IOException { // copy files in project from source workspace to target workspace final File sourceWorkspacePath = getSourceWorkspacePath(); final File targetWorkspacePath = getWorkspaceRoot().getLocation().toFile(); copyDirectory(new File(sourceWorkspacePath, fromName), new File(targetWorkspacePath, projectName)); return createProject(projectName); } protected IScriptProject setUpScriptProject(final String projectName) throws CoreException, IOException { final IProject project = setUpProject(projectName); return DLTKCore.create(project); } /** * Returns the specified source module in the given project, root, and * folder or <code>null</code> if it does not exist. */ public ISourceModule getSourceModule(String projectName, String rootPath, IPath path) throws ModelException { IScriptFolder folder = getScriptFolder(projectName, rootPath, path.removeLastSegments(1)); if (folder == null) { return null; } return folder.getSourceModule(path.lastSegment()); } public ISourceModule getSourceModule(String projectName, String rootPath, String path) throws ModelException { IScriptFolder folder = getScriptFolder(projectName, rootPath, new Path(path).removeLastSegments(1)); if (folder == null) { return null; } return folder.getSourceModule(new Path(path).lastSegment().toString()); } /** * Returns the specified script folder in the given project and fragment, or * <code>null</code> if it does not exist. The rootPath must be specified as * a project relative path. The empty path refers to the default package * fragment. */ public IScriptFolder getScriptFolder(String projectName, String fragmentPath, IPath path) throws ModelException { IProjectFragment root = getProjectFragment(projectName, fragmentPath); if (root == null) { return null; } return root.getScriptFolder(path); } /** * Returns the specified package fragment root in the given project, or * <code>null</code> if it does not exist. If relative, the rootPath must be * specified as a project relative path. The empty path refers to the * package fragment root that is the project folder iteslf. If absolute, the * rootPath refers to either an external zip, or a resource internal to the * workspace */ public IProjectFragment getProjectFragment(String projectName, String fragmentPath) throws ModelException { IScriptProject project = getScriptProject(projectName); if (project == null) { return null; } IPath path = new Path(fragmentPath); if (path.isAbsolute()) { IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); IResource resource = workspaceRoot.findMember(path); IProjectFragment root; // resource in the workspace root = project.getProjectFragment(resource); return root; } else { IProjectFragment[] roots = project.getProjectFragments(); if (roots == null || roots.length == 0) { return null; } for (int i = 0; i < roots.length; i++) { IProjectFragment root = roots[i]; if (root.getUnderlyingResource().getProjectRelativePath().equals(path)) { return root; } } } return null; } /** * Returns the script Project with the given name in this test suite's * model. This is a convenience method. */ public IScriptProject getScriptProject(String name) { IProject project = getProject(name); return DLTKCore.create(project); } public IWorkspace getWorkspace() { return ResourcesPlugin.getWorkspace(); } public IWorkspaceRoot getWorkspaceRoot() { return getWorkspace().getRoot(); } protected IProject getProject(String project) { return getWorkspaceRoot().getProject(project); } public File getSourceWorkspacePath() { return new File(getPluginDirectoryPath(), WORKSPACE_BASE); } /** * Returns the OS path to the directory that contains this plugin. */ protected File getPluginDirectoryPath() { try { URL platformURL = bundle.getEntry("/"); return new File(FileLocator.toFileURL(platformURL).getFile()); } catch (IOException e) { e.printStackTrace(); } return null; } /** * Copy the given source directory (and all its contents) to the given * target directory. */ protected void copyDirectory(File source, File target) throws IOException { if (!target.exists()) { target.mkdirs(); } File[] files = source.listFiles(); if (files == null) return; for (int i = 0; i < files.length; i++) { File sourceChild = files[i]; String name = sourceChild.getName(); if (name.equals("CVS") || name.equals(".svn")) continue; File targetChild = new File(target, name); if (sourceChild.isDirectory()) { copyDirectory(sourceChild, targetChild); } else { copy(sourceChild, targetChild); } } } /** * Copy file from src (path to the original file) to dest (path to the * destination file). */ public static void copy(File src, File dest) throws IOException { InputStream in = null; OutputStream out = null; byte[] buffer = new byte[12 * 1024]; int read; try { in = new FileInputStream(src); try { out = new FileOutputStream(dest); while ((read = in.read(buffer)) != -1) { out.write(buffer, 0, read); } } finally { if (out != null) { out.close(); } } } finally { if (in != null) { in.close(); } } } /* * Create simple project. */ protected IProject createProject(final String projectName) throws CoreException { final IProject project = getProject(projectName); IWorkspaceRunnable create = new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { project.create(null); project.open(null); } }; getWorkspace().run(create, null); // Disable WTP validation to skip unnecessary clashes ValidationFramework.getDefault().suspendValidation(project, true); return project; } /* * Creates a script project with the given source folders an output * location. Add those on the project's buildpath. */ protected IScriptProject createScriptProject(String projectName, String[] natures, String[] sourceFolders) throws CoreException { return createScriptProject(projectName, natures, sourceFolders, null); } /* * Creates a script project with the given source folders an output * location. Add those on the project's buildpath. */ protected IScriptProject createScriptProject(final String projectName, final String[] natures, final String[] sourceFolders, final String[] projects) throws CoreException { final IScriptProject[] result = new IScriptProject[1]; IWorkspaceRunnable create = new IWorkspaceRunnable() { public void run(IProgressMonitor monitor) throws CoreException { // create project createProject(projectName); IProject project = getWorkspaceRoot().getProject(projectName); // add natures IProjectDescription description = project.getDescription(); description.setNatureIds(natures); project.setDescription(description, null); // create buildpath entries IPath projectPath = project.getFullPath(); int sourceLength = sourceFolders == null ? 0 : sourceFolders.length; int projectLength = projects == null ? 0 : projects.length; IBuildpathEntry[] entries = new IBuildpathEntry[sourceLength + projectLength]; for (int i = 0; i < sourceLength; i++) { IPath sourcePath = new Path(sourceFolders[i]); int segmentCount = sourcePath.segmentCount(); if (segmentCount > 0) { // create folder and its parents IContainer container = project; for (int j = 0; j < segmentCount; j++) { IFolder folder = container.getFolder(new Path(sourcePath.segment(j))); if (!folder.exists()) { folder.create(true, true, null); } container = folder; } } // create source entry entries[i] = DLTKCore.newSourceEntry(projectPath.append(sourcePath)); } for (int i = 0; i < projectLength; i++) { // accessible files IPath[] accessibleFiles; accessibleFiles = new IPath[0]; // non accessible files IPath[] nonAccessibleFiles; nonAccessibleFiles = new IPath[0]; entries[sourceLength + i] = DLTKCore.newProjectEntry(new Path(projects[i]), BuildpathEntry.getAccessRules(accessibleFiles, nonAccessibleFiles), true, new IBuildpathAttribute[0], false); } // set buildpath and output location IScriptProject scriptProject = DLTKCore.create(project); scriptProject.setRawBuildpath(entries, null); result[0] = scriptProject; } }; getWorkspace().run(create, null); return result[0]; } public static void waitUntilIndexesReady() { ModelManager.getModelManager().getIndexManager().waitUntilReady(); } protected void deleteProject(String projectName) throws CoreException { IProject project = this.getProject(projectName); if (project.exists() && !project.isOpen()) { // force opening so that // project can be // deleted without // logging (see bug // 23629) project.open(null); } deleteResource(project); } /** * Delete this resource. */ public void deleteResource(IResource resource) throws CoreException { CoreException lastException = null; try { resource.delete(true, null); } catch (CoreException e) { lastException = e; // just print for info System.out.println(e.getMessage()); } catch (IllegalArgumentException iae) { // just print for info System.out.println(iae.getMessage()); } int retryCount = 60; // wait 1 minute at most while (resource.isAccessible() && --retryCount >= 0) { try { Thread.sleep(1000); } catch (InterruptedException e) { } try { resource.delete(true, null); } catch (CoreException e) { lastException = e; // just print for info System.out.println("Retry " + retryCount + ": " + e.getMessage()); } catch (IllegalArgumentException iae) { // just print for info System.out.println("Retry " + retryCount + ": " + iae.getMessage()); } } if (!resource.isAccessible()) return; System.err.println("Failed to delete " + resource.getFullPath()); if (lastException != null) { throw lastException; } } }