package org.erlide.engine.util;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IncrementalProjectBuilder;
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.erlide.engine.ErlangEngine;
import org.erlide.engine.model.IErlElement;
import org.erlide.engine.model.builder.BuilderTool;
import org.erlide.engine.model.root.ErlangProjectProperties;
import org.erlide.engine.model.root.IErlModel;
import org.erlide.engine.model.root.IErlModule;
import org.erlide.engine.model.root.IErlProject;
import org.erlide.util.SystemConfiguration;
import com.google.common.collect.Lists;
public class ErlideTestUtils {
// TODO replace ResourceDeltaStub with a mock object
public static class ResourceDeltaStub implements IResourceDelta {
@Override
public Object getAdapter(@SuppressWarnings("rawtypes") final Class adapter) {
return null;
}
@Override
public void accept(final IResourceDeltaVisitor visitor) throws CoreException {
}
@Override
public void accept(final IResourceDeltaVisitor visitor,
final boolean includePhantoms) throws CoreException {
}
@Override
public void accept(final IResourceDeltaVisitor visitor, final int memberFlags)
throws CoreException {
}
@Override
public IResourceDelta findMember(final IPath path) {
return null;
}
@Override
public IResourceDelta[] getAffectedChildren() {
return null;
}
@Override
public IResourceDelta[] getAffectedChildren(final int kindMask) {
return null;
}
@Override
public IResourceDelta[] getAffectedChildren(final int kindMask,
final int memberFlags) {
return null;
}
@Override
public int getFlags() {
return CONTENT;
}
@Override
public IPath getFullPath() {
return null;
}
@Override
public int getKind() {
return 0;
}
@Override
public IMarkerDelta[] getMarkerDeltas() {
return null;
}
@Override
public IPath getMovedFromPath() {
return null;
}
@Override
public IPath getMovedToPath() {
return null;
}
@Override
public IPath getProjectRelativePath() {
return null;
}
@Override
public IResource getResource() {
return null;
}
}
private static List<IErlModule> modulesAndIncludes;
private static List<IErlProject> projects;
private static void buildPaths(final IWorkspaceRoot root, final IProject project,
final Collection<IPath> list) throws CoreException {
final IPath projectPath = project.getFullPath();
for (final IPath pp : list) {
// only create in-project paths
if (!pp.isAbsolute() && !pp.toString().equals(".") && !pp.isEmpty()) {
final IPath path = projectPath.append(pp);
final IFolder folder = root.getFolder(path);
createFolderHelper(folder);
}
}
}
public static void initModulesAndIncludes() {
modulesAndIncludes = Lists.newArrayList();
}
public static IErlModule createModule(final IErlProject project,
final String moduleName, final String moduleContents) throws CoreException {
final IFolder folder = project.getWorkspaceProject().getFolder("src");
final IErlModule module = createModule(moduleName, moduleContents, folder);
modulesAndIncludes.add(module);
return module;
}
public static IErlModule createInclude(final IErlProject project,
final String moduleName, final String moduleContents) throws CoreException {
final IFolder folder = project.getWorkspaceProject().getFolder("include");
final IErlModule module = createModule(moduleName, moduleContents, folder);
modulesAndIncludes.add(module);
return module;
}
public static IErlModule createModule(final String moduleName,
final String moduleContents, final IFolder folder) throws CoreException {
final IFile file = createFile(moduleName, moduleContents, folder);
final IErlModel model = ErlangEngine.getInstance().getModel();
IErlModule module = model.findModule(file);
if (module == null) {
final String path = file.getLocation().toPortableString();
module = model.getModuleFromFile(model, file.getName(), path,
Charset.defaultCharset().name(), path);
}
return module;
}
public static IFile createFile(final String name, final String contents,
final IFolder folder) throws CoreException {
final IFile file = folder.getFile(name);
final File f = new File(file.getLocation().toOSString());
f.delete();
file.create(new ByteArrayInputStream(contents.getBytes(Charset.defaultCharset())),
true, null);
return file;
}
public static void deleteModule(final IErlModule module) throws CoreException {
if (SystemConfiguration.getInstance().isOnWindows()) {
// FIXME seems needed on windows to release the file handle -- find out who is
// holding it
System.gc();
}
final String scannerName = module.getScannerName();
final IFile file = (IFile) module.getResource();
if (file != null) {
file.delete(true, null);
}
final IPath stateDir = new Path(ErlangEngine.getInstance().getStateDir());
// FIXME this code should not know about caches!
final String cacheExts[] = { ".noparse", ".refs", ".scan" };
for (final String ext : cacheExts) {
final IPath p = stateDir.append(scannerName + ext);
final File f = new File(p.toOSString());
f.delete();
}
module.dispose();
modulesAndIncludes.remove(module);
}
public static IErlProject createProject(final IPath path, final String name)
throws CoreException {
final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
final IProject project2 = root.getProject(name);
try {
project2.delete(true, null);
} catch (final CoreException x) {
// ignore
}
final IErlProject erlProject = ErlangEngine.getInstance().getModel()
.newProject(name, path.toPortableString());
erlProject.getBuilderProperties().setBuilderTool(BuilderTool.INTERNAL);
final IProject project = erlProject.getWorkspaceProject();
final ErlangProjectProperties prefs = erlProject.getProperties();
final List<IPath> srcDirs = new ArrayList<>();
srcDirs.add(new Path("src"));
prefs.setSourceDirs(srcDirs);
buildPaths(root, project, srcDirs);
final List<IPath> includeDirs = new ArrayList<>();
includeDirs.add(new Path("include"));
buildPaths(root, project, includeDirs);
prefs.setIncludeDirs(includeDirs);
final IPath ebinDir = new Path("ebin");
buildPaths(root, project, Lists.newArrayList(ebinDir));
prefs.setOutputDir(ebinDir);
projects.add(erlProject);
return erlProject;
}
public static IErlProject createExistingProject(final IPath path) {
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
try {
final IProjectDescription description = workspace
.loadProjectDescription(path.append(".project"));
final IWorkspaceRoot root = workspace.getRoot();
final IProject project = root.getProject(description.getName());
project.create(description, 0, null);
for (final String nature : description.getNatureIds()) {
project.getNature(nature).configure();
}
project.refreshLocal(IResource.DEPTH_INFINITE, null);
return ErlangEngine.getInstance().getModel().getErlangProject(project);
} catch (final CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
public static IErlProject getExistingProject(final String name) {
final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
final IProject project = root.getProject(name);
try {
project.open(null);
} catch (final CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return ErlangEngine.getInstance().getModel().getErlangProject(project);
}
public static void createFolderHelper(final IFolder folder) throws CoreException {
if (!folder.exists()) {
final IContainer parent = folder.getParent();
if (parent instanceof IFolder) {
createFolderHelper((IFolder) parent);
}
folder.create(false, true, null);
}
}
public static IPath getTmpPath(final String fileName) {
final String tmpdir = System.getProperty("java.io.tmpdir");
return new Path(tmpdir).append(fileName);
}
public static URI getTmpURIPath(final String fileName) {
return URIUtil.toURI(getTmpPath(fileName).toPortableString());
}
public static File createTmpFile(final String fileName, final String contentString)
throws IOException, FileNotFoundException {
final String pathString = getTmpPath(fileName).toOSString();
final File f = new File(pathString);
if (f.exists()) {
f.delete();
}
f.createNewFile();
try (final FileOutputStream fileOutputStream = new FileOutputStream(pathString)) {
fileOutputStream.write(contentString.getBytes());
}
return f;
}
public static void deleteProject(final IErlProject erlProject) throws CoreException {
final IProject project = erlProject.getWorkspaceProject();
final IPath location = project.getLocation();
project.delete(true, null);
if (location != null) {
new File(location.toPortableString()).delete();
}
if (modulesAndIncludes != null) {
final List<IErlModule> list = Lists.newArrayList(modulesAndIncludes);
for (final IErlModule module : list) {
if (ErlangEngine.getInstance().getModelUtilService()
.getProject(module) == erlProject) {
deleteModule(module);
}
}
}
erlProject.dispose();
if (projects != null) {
projects.remove(ErlangEngine.getInstance().getModel().findProject(project));
}
final IErlModel model = ErlangEngine.getInstance().getModel();
model.resourceChanged(null);
model.open(null);
}
public static void invokeBuilderOn(final IErlProject erlProject)
throws CoreException {
final IProject project = erlProject.getWorkspaceProject();
project.build(IncrementalProjectBuilder.FULL_BUILD, null);
}
public static void deleteModules() throws CoreException {
final List<IErlModule> list = Lists.newArrayList(modulesAndIncludes);
for (final IErlModule module : list) {
deleteModule(module);
}
}
public static void deleteProjects() throws CoreException {
final List<IErlProject> list = Lists.newArrayList(projects);
for (final IErlProject project : list) {
deleteProject(project);
}
}
public static void initProjects() throws CoreException {
projects = Lists.newArrayList();
final IErlModel model = ErlangEngine.getInstance().getModel();
model.open(null);
final List<IErlElement> children = model.getChildren();
for (final IErlElement child : children) {
if (child instanceof IErlProject) {
final IErlProject project = (IErlProject) child;
if (project.getName().startsWith("testproject")) {
deleteProject(project);
}
}
}
}
public static IErlModule createModuleFromText(final String initialText) {
final IErlModel model = ErlangEngine.getInstance().getModel();
final IErlModule module = model.getModuleFromText(model, "test1", initialText,
"test1");
modulesAndIncludes.add(module);
return module;
}
public static IErlProject createTmpErlProject(final String projectName)
throws CoreException {
return createProject(getTmpPath(projectName), projectName);
}
public static IPath[] splitPathAfter(final int i, final IPath p) {
final IPath last = p.removeFirstSegments(i);
final IPath first = p.removeLastSegments(p.segmentCount() - i);
return new IPath[] { first, last };
}
public static void refreshProjects() {
for (final IErlProject project : projects) {
project.resourceChanged(new ResourceDeltaStub());
}
}
}