/* * Copyright 2009-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.groovy.eclipse.test; import static org.codehaus.groovy.eclipse.core.model.GroovyRuntime.ensureGroovyClasspathContainer; import static org.junit.Assert.assertEquals; import java.io.ByteArrayInputStream; import java.io.InputStream; import org.codehaus.groovy.eclipse.core.builder.GroovyClasspathContainer; import org.codehaus.groovy.eclipse.core.model.GroovyProjectFacade; import org.codehaus.groovy.eclipse.core.util.ArrayUtils; import org.codehaus.groovy.runtime.DefaultGroovyMethods; import org.codehaus.jdt.groovy.model.GroovyNature; import org.eclipse.core.internal.events.BuildCommand; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IMarker; 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.IWorkspaceDescription; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaModelMarker; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.groovy.tests.SimpleProgressMonitor; import org.eclipse.jdt.core.tests.util.Util; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner; import org.eclipse.jdt.internal.core.JavaModelManager; import org.eclipse.jdt.launching.JavaRuntime; public class TestProject { public static final String TEST_PROJECT_NAME = "TestProject"; private final IProject project; private final IJavaProject javaProject; private IPackageFragmentRoot sourceFolder; public TestProject() throws Exception { this(TEST_PROJECT_NAME); } public TestProject(String name) throws Exception { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); project = root.getProject(name); if (!project.exists()) { project.create(null); } project.open(null); javaProject = JavaCore.create(project); prepareForJava(); prepareForGroovy(); createOutputFolder(createBinFolder()); sourceFolder = createSourceFolder(); javaProject.setOption(CompilerOptions.OPTION_Source, "1.5"); javaProject.setOption(CompilerOptions.OPTION_Compliance, "1.5"); javaProject.setOption(CompilerOptions.OPTION_TargetPlatform, "1.5"); } public IProject getProject() { return project; } public IJavaProject getJavaProject() { return javaProject; } public IPackageFragmentRoot getSourceFolder() { return sourceFolder; } public GroovyProjectFacade getGroovyProjectFacade() { return new GroovyProjectFacade(javaProject); } public boolean hasGroovyContainer() throws Exception { for (IClasspathEntry entry : javaProject.getRawClasspath()) { if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER && entry.getPath().equals(GroovyClasspathContainer.CONTAINER_ID)) { return true; } } return false; } /** Adds base Java nature and classpath entries to project. */ private void prepareForJava() throws Exception { addNature(JavaCore.NATURE_ID); javaProject.setRawClasspath(new IClasspathEntry[] {JavaRuntime.getDefaultJREContainerEntry()}, null); } /** Adds base Groovy nature and classpath entries to project. */ private void prepareForGroovy() throws Exception { addNature(GroovyNature.GROOVY_NATURE); if (!hasGroovyContainer()) { ensureGroovyClasspathContainer(getJavaProject(), true); } } public void addBuilder(String newBuilder) throws Exception { ICommand buildCommand = new BuildCommand(); buildCommand.setBuilderName(newBuilder); final IProjectDescription description = project.getDescription(); description.setBuildSpec((ICommand[]) ArrayUtils.add(description.getBuildSpec(), 0, buildCommand)); project.setDescription(description, null); } public void addNature(String natureId) throws Exception { final IProjectDescription description = project.getDescription(); description.setNatureIds((String[]) ArrayUtils.add(description.getNatureIds(), 0, natureId)); project.setDescription(description, null); } public void removeNature(String natureId) throws Exception { final IProjectDescription description = project.getDescription(); final String[] ids = description.getNatureIds(); for (int i = 0, n = ids.length; i < n; i += 1) { if (ids[i].equals(natureId)) { description.setNatureIds((String[]) ArrayUtils.remove(ids, i)); project.setDescription(description, null); return; } } } public void addClasspathEntry(IClasspathEntry classpathEntry) throws Exception { IClasspathEntry[] entries = (IClasspathEntry[]) ArrayUtils.add(javaProject.getRawClasspath(), classpathEntry); SimpleProgressMonitor monitor = new SimpleProgressMonitor("Add " + classpathEntry); javaProject.setRawClasspath(entries, monitor); monitor.waitForCompletion(); } public void addExternalLibrary(IPath libraryPath) throws Exception { addClasspathEntry(JavaCore.newLibraryEntry(libraryPath, null, null)); } public void addProjectReference(IJavaProject referent) throws Exception { addClasspathEntry(JavaCore.newProjectEntry(referent.getPath())); } public IPackageFragment createPackage(String name) throws Exception { return sourceFolder.createPackageFragment(name, true, null); } public void deletePackage(String name) throws CoreException { sourceFolder.getPackageFragment(name).delete(true, null); } private void appendPackage(StringBuilder b, IPackageFragment p, CharSequence source) { if (!p.isDefaultPackage() && (source.length() < 8 || !source.subSequence(0, 7).toString().equals("package"))) { b.append("package "); b.append(p.getElementName()); b.append(";"); b.append(System.getProperty("line.separator")); b.append(System.getProperty("line.separator")); } } public ICompilationUnit createJavaType(IPackageFragment packageFrag, String fileName, CharSequence source) throws Exception { StringBuilder buf = new StringBuilder(); appendPackage(buf, packageFrag, source); buf.append(source); ICompilationUnit unit = packageFrag.createCompilationUnit(fileName, buf.toString(), false, null); unit.becomeWorkingCopy(null); return unit; } public ICompilationUnit createJavaTypeAndPackage(String packageName, String fileName, CharSequence source) throws Exception { return createJavaType(createPackage(packageName), fileName, source); } @SuppressWarnings("deprecation") public ICompilationUnit createGroovyTypeAndPackage(String packageName, String fileName, InputStream source) throws Exception { return createGroovyType(createPackage(packageName), fileName, DefaultGroovyMethods.getText(source)); } public ICompilationUnit createGroovyTypeAndPackage(String packageName, String fileName, CharSequence source) throws Exception { return createGroovyType(createPackage(packageName), fileName, source); } public ICompilationUnit createGroovyType(IPackageFragment packageFrag, String fileName, CharSequence source) throws Exception { StringBuilder buf = new StringBuilder(); appendPackage(buf, packageFrag, source); buf.append(source); ICompilationUnit unit = packageFrag.createCompilationUnit(fileName, buf.toString(), false, null); unit.becomeWorkingCopy(null); return unit; } public void dispose() throws Exception { deleteWorkingCopies(); Util.delete(project); } public void deleteContents() throws Exception { deleteWorkingCopies(); for (IPackageFragment frag : javaProject.getPackageFragments()) { if (!frag.isReadOnly()) { frag.delete(true, null); } } } private void deleteWorkingCopies() throws Exception { SynchronizationUtils.joinBackgroudActivities(); ICompilationUnit[] workingCopies = JavaModelManager.getJavaModelManager().getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, true); if (workingCopies != null && workingCopies.length > 0) { for (ICompilationUnit workingCopy : workingCopies) { if (workingCopy.isWorkingCopy()) { workingCopy.discardWorkingCopy(); } } } System.gc(); } private IFolder createBinFolder() throws Exception { final IFolder binFolder = project.getFolder("bin"); if (!binFolder.exists()) { ensureExists(binFolder); } return binFolder; } private void createOutputFolder(IFolder binFolder) throws Exception { IPath outputLocation = binFolder.getFullPath(); javaProject.setOutputLocation(outputLocation, null); } private IPackageFragmentRoot createSourceFolder() throws Exception { return createSourceFolder("src", null, (IPath[]) null); } public IPackageFragmentRoot createSourceFolder(String path, String outPath, IPath... exclusionPatterns) throws Exception { IFolder folder = project.getFolder(path); if (!folder.exists()) { ensureExists(folder); } final IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(folder); for (IClasspathEntry entry : javaProject.getRawClasspath()) { if (entry.getPath().equals(folder.getFullPath())) { return root; } } IPath outPathPath = outPath == null ? null : getProject().getFullPath().append(outPath).makeAbsolute(); addClasspathEntry(JavaCore.newSourceEntry(root.getPath(), exclusionPatterns, outPathPath)); return root; } private void ensureExists(IFolder folder) throws Exception { if (folder.getParent().getType() == IResource.FOLDER && !folder.getParent().exists()) { ensureExists((IFolder) folder.getParent()); } folder.create(false, true, null); } public void waitForIndexer() { SynchronizationUtils.waitForIndexingToComplete(getJavaProject()); } public void fullBuild() throws Exception { SimpleProgressMonitor spm = new SimpleProgressMonitor("full build of " + getProject().getName()); getProject().build(org.eclipse.core.resources.IncrementalProjectBuilder.FULL_BUILD, spm); spm.waitForCompletion(); } public String getProblems() throws Exception { IMarker[] markers = getProject().findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); if (markers == null || markers.length == 0) { return null; } boolean errorFound = false; StringBuilder sb = new StringBuilder("Problems:\n"); for (IMarker marker : markers) { if (((Number) marker.getAttribute(IMarker.SEVERITY)).intValue() == IMarker.SEVERITY_ERROR) { errorFound = true; sb.append(" "); sb.append(marker.getResource().getName()); sb.append(" : "); sb.append(marker.getAttribute(IMarker.LOCATION)); sb.append(" : "); sb.append(marker.getAttribute(IMarker.MESSAGE)); sb.append("\n"); } } return errorFound ? sb.toString() : null; } public IFile createFile(String name, String contents) throws Exception { String encoding = null; try { encoding = project.getDefaultCharset(); // get project encoding as file is not accessible } catch (CoreException ce) { // use no encoding } InputStream stream = new ByteArrayInputStream(encoding == null ? contents.getBytes() : contents.getBytes(encoding)); IFile file = project.getFolder("src").getFile(new Path(name)); if (!file.getParent().exists()) { createFolder(file.getParent()); } file.create(stream, true, null); return file; } private void createFolder(IContainer parent) throws Exception { if (!parent.getParent().exists()) { assertEquals("Project doesn't exist " + parent.getParent(), parent.getParent().getType(), IResource.FOLDER); createFolder(parent.getParent()); } ((IFolder) parent).create(true, true, null); } public ICompilationUnit[] createUnits(String[] packages, String[] cuNames, String[] cuContents) throws Exception { ICompilationUnit[] units = new ICompilationUnit[packages.length]; for (int i = 0, n = cuContents.length; i < n; i += 1) { units[i] = createPackage(packages[i]).createCompilationUnit(cuNames[i], cuContents[i], false, null); } return units; } public static void setAutoBuilding(boolean value) { try { IWorkspace w = ResourcesPlugin.getWorkspace(); IWorkspaceDescription d = w.getDescription(); d.setAutoBuilding(value); w.setDescription(d); } catch (CoreException e) { e.printStackTrace(); throw new RuntimeException(e); } } public static boolean isAutoBuilding() { IWorkspace w = ResourcesPlugin.getWorkspace(); IWorkspaceDescription d = w.getDescription(); return d.isAutoBuilding(); } }