/*******************************************************************************
* Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
* 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
*******************************************************************************/
package org.ebayopensource.turmeric.eclipse.utils.plugin;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.ebayopensource.turmeric.eclipse.exception.core.SOANullParameterException;
import org.ebayopensource.turmeric.eclipse.exception.resources.SOAResourceNotAccessibleException;
import org.ebayopensource.turmeric.eclipse.utils.collections.CollectionUtil;
import org.ebayopensource.turmeric.eclipse.utils.collections.SetUtil;
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.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.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
/**
* The Class WorkspaceUtil.
*
* @author smathew This util class contains the util methods for workspace,
* workbench and resource related calls.
*/
public class WorkspaceUtil {
/** The Constant PATH_SEPERATOR. */
public static final String PATH_SEPERATOR = "/";
/**
* Gets the workspace.
*
* @return the workspace
*/
public static IWorkspace getWorkspace() {
return ResourcesPlugin.getWorkspace();
}
/**
* Gets the workspace root.
*
* @return the workspace root
*/
public static IWorkspaceRoot getWorkspaceRoot() {
return getWorkspace().getRoot();
}
/**
* Project exists in work space.
*
* @param projectName the project name
* @return true, if successful
*/
public static boolean projectExistsInWorkSpace(String projectName) {
IProject project = getWorkspaceRoot().getProject(projectName);
return project != null && project.exists();
}
/**
* Directory exists in file system.
*
* @param dir the dir
* @return True if the directory exists
*/
public static boolean directoryExistsInFileSystem(String dir) {
return new File(dir).exists();
}
/**
* Gets the project dir path.
*
* @param parentFolder the parent folder
* @param file the file
* @return Concatenates the folder and project name and return the complete
* path as a string
*/
public static String getProjectDirPath(String parentFolder, String file) {
return parentFolder + File.separator + file;
}
/**
* Gets the all projects in work space.
*
* @return the all projects in work space
*/
public static IProject[] getAllProjectsInWorkSpace() {
return getWorkspaceRoot().getProjects();
}
/**
* This function resolves the project location if the project location
* logically ie if the project location already has the project name as its
* last segment then it will remove it and will return the new location with
* project name only once at the end.
*
* @param projectName the project name
* @param projectLocation the project location
* @return the i path
*/
public static IPath resolveProjectPath(final String projectName,
final IPath projectLocation) {
if (projectLocation == null)
return null;
if (StringUtils.isBlank(projectName))
return projectLocation;
final IPath projectRoot = StringUtils.equals(projectLocation
.lastSegment(), projectName) ? projectLocation
.removeLastSegments(1) : projectLocation;
if (!projectRoot.toFile().exists())
return null;
return !StringUtils.equals(projectRoot.toString(), "/") ? new Path(
projectRoot + "/" + projectName) : new Path("/" + projectName);
}
/**
* Iterated wrapper to resolveProjectPath function.
*
* @param projectLocation the project location
* @param projectNames the project names
* @return the i path
*/
public static IPath resolveProjectRoot(final IPath projectLocation,
final String... projectNames) {
for (final String projectName : projectNames) {
final IPath location = resolveProjectPath(projectName,
projectLocation);
if (location == null)
return location;
if (StringUtils.equals(projectName, location.lastSegment()))
return location.removeLastSegments(1);
}
return projectLocation;
}
/**
* Creates the project.
*
* @param projectName the project name
* @param projectLocation the project location
* @param progressMonitor the progress monitor
* @return the i project
* @throws CoreException the core exception
*/
public static IProject createProject(final String projectName,
final IPath projectLocation, final IProgressMonitor progressMonitor)
throws CoreException {
final IProgressMonitor monitor = ProgressUtil
.getDefaultMonitor(progressMonitor);
final IProject project = getProject(projectName);
if (project.exists())
return openProject(project, monitor);
final IPath resolvedLocation = resolveProjectPath(projectName,
projectLocation);
final IProjectDescription description = getWorkspace()
.newProjectDescription(projectName);
if (resolvedLocation != null
&& projectLocation.equals(getWorkspace().getRoot()
.getLocation()) == false)
description.setLocation(resolvedLocation);
project.create(description, monitor);
return openProject(project, monitor);
}
/**
* Gets the project.
*
* @param projectName the project name
* @return the project
*/
public static IProject getProject(final String projectName) {
return getWorkspaceRoot().getProject(projectName);
}
/**
* Gets the project.
*
* @param path the path
* @return the project
*/
public static IProject getProject(final IPath path) {
final IProject project = getWorkspaceRoot().getProject(
path.lastSegment());
return project;
}
/**
* Open project.
*
* @param project the project
* @param progressMonitor the progress monitor
* @return the i project
* @throws CoreException the core exception
*/
public static IProject openProject(final IProject project,
final IProgressMonitor progressMonitor) throws CoreException {
final IProgressMonitor monitor = progressMonitor != null ? progressMonitor
: new NullProgressMonitor();
if (project == null || !project.exists())
return project;
if (!project.isOpen())
project.open(monitor);
return project;
}
/**
* Creates the folders.
*
* @param project the project
* @param folders the folders
* @param monitor the monitor
* @throws CoreException This method creates sub folder. Good thing is that it will
* check for existance of parent directories and eliminates the
* chance of folder creation failures to a certain level
* @WorkSpaceUtil.PATH_SEPERATOR
*/
public static void createFolders(IProject project,
final List<String> folders, final IProgressMonitor monitor)
throws CoreException {
if (project.isAccessible() && project.exists()) {
for (final String folder : folders) {
// Ignore . Dir. The project is created so Current dir
// already exists. Meaning . should be ignored
if (!isDotDirectory(folder)) {
StringBuilder path = new StringBuilder();
String subFolders[] = StringUtils.split(folder,
PATH_SEPERATOR);
for (String subFolder : subFolders) {
path.append(PATH_SEPERATOR);
path.append(subFolder);
// target folder shouldnt exist but the parent folder
// should. simple
String spath = path.toString();
if (!project.getFolder(spath).exists()
&& project.getFolder(subFolder).getParent() != null
&& project.getFolder(subFolder).getParent()
.exists()) {
project.getFolder(spath).create(true, true, monitor);
}
refresh(project.getFolder(spath));
}
}
}
}
}
/**
* Refresh.
*
* @param resources the resources
* @throws CoreException the core exception
*/
public static void refresh(final IResource... resources)
throws CoreException {
for (final IResource resource : resources)
refresh(resource, null);
}
/**
* Refresh.
*
* @param monitor the monitor
* @param resources the resources
* @throws CoreException the core exception
*/
public static void refresh(final IProgressMonitor monitor,
final IResource... resources) throws CoreException {
for (final IResource resource : resources)
refresh(resource, monitor);
}
/**
* Refresh.
*
* @param resource the resource
* @param progressMonitor the progress monitor
* @throws CoreException the core exception
*/
public static void refresh(final IResource resource,
final IProgressMonitor progressMonitor) throws CoreException {
if (resource == null)
return;
final IProgressMonitor monitor = ProgressUtil
.getDefaultMonitor(progressMonitor);
resource.refreshLocal(IResource.DEPTH_INFINITE, monitor);
}
/**
* This method assumes the path is relative to the workspace root or is
* indeed a true absolute location.
*
* @param path the path
* @return the location
*/
public static IPath getLocation(final IPath path) {
if (path == null)
return null;
final IResource resource = getWorkspaceRoot().findMember(
path.makeAbsolute());
if (resource == null)
return path.makeAbsolute();
return resource.getLocation();
}
/**
* Write to file.
*
* @param contents the contents
* @param file the file
* @param progressMonitor the progress monitor
* @throws CoreException This is a simple write method. If the file doesnt exist it
* will create one,Any issues will result in Core Exception
* being thrown, Clients should handle those
*/
public static void writeToFile(final String contents, final IFile file,
final IProgressMonitor progressMonitor) throws CoreException {
writeToFile(IOUtils.toInputStream(contents), file, ProgressUtil
.getDefaultMonitor(progressMonitor));
}
/**
* Write to file.
*
* @param input the input
* @param file the file
* @param progressMonitor the progress monitor
* @throws CoreException This is a simple write method. If the file doesnt exist it
* will create one,Any issues will result in Core Exception
* being thrown, Clients should handle those
*/
public static void writeToFile(final InputStream input, final IFile file,
final IProgressMonitor progressMonitor) throws CoreException {
try {
if (!file.exists()) {
file.create(input, true, ProgressUtil
.getDefaultMonitor(progressMonitor));
} else {
file.setContents(input, true, true, ProgressUtil
.getDefaultMonitor(progressMonitor));
}
} finally {
IOUtils.closeQuietly(input);
}
}
/**
* Load properties.
*
* @param file the file
* @return the properties
* @throws CoreException the core exception
* @throws IOException Signals that an I/O exception has occurred.
*/
public static Properties loadProperties(IFile file) throws CoreException,
IOException {
InputStream input = null;
try {
final Properties props = new Properties();
if (file.exists()) {
input = file.getContents(true);
props.load(input);
}
return props;
}
finally {
IOUtils.closeQuietly(input);
}
}
/**
* for a,b,c output will be a/b/c/.
*
* @param dirs the dirs
* @return the string
*/
public static String addPathSeperators(String... dirs) {
StringBuffer strBuffer = new StringBuffer("");
for (String str : dirs) {
strBuffer.append(str);
strBuffer.append(PATH_SEPERATOR);
}
return strBuffer.toString();
}
/**
* Delete.
*
* @param resource the resource
* @param monitor the monitor
* @throws CoreException the core exception
*/
public static void delete(IResource resource, IProgressMonitor monitor)
throws CoreException {
if (resource instanceof IFile)
((IFile) resource).delete(true, true, monitor);
else if (resource instanceof IFolder)
((IFolder) resource).delete(true, true, monitor);
else if (resource instanceof IProject)
((IProject) resource).delete(false, true, monitor);
else
resource.delete(true, monitor);
}
/**
* Right now used for testing purpose.
*
* @param bool the new builds the automatically
* @throws CoreException the core exception
*/
public static void setBuildAutomatically(boolean bool) throws CoreException {
IWorkspaceDescription description = getWorkspace().getDescription();
description.setAutoBuilding(bool);
getWorkspace().setDescription(description);
}
/**
* Right now used for testing purpose.
*
* @param projectName the project name
* @throws CoreException the core exception
*/
public static void deleteProject(String projectName) throws CoreException {
IProject project = getWorkspaceRoot().getProject(projectName);
project.delete(true, new NullProgressMonitor());
}
/**
* Checks if is resource writable.
*
* @param resource If the resource doesnt exist thats fin in this case.It will
* return true is the resource doesnt exist
* @return true, if is resource writable
*/
public static boolean isResourceWritable(IResource resource) {
if (resource.exists()) {// resource exists
if (resource.isAccessible() == false
|| (resource.getResourceAttributes() != null && resource
.getResourceAttributes().isReadOnly())) {
// If its not accessible or if its read only
return false;
}
} else {
if (resource.getParent() != null) {
final IResource parent = resource.getParent();
// Parent can decide on child's Writability
if (parent.exists()) {
// No Parent is fine
if (!parent.isAccessible()
|| (parent.getResourceAttributes() != null && parent
.getResourceAttributes().isReadOnly())) {
// If parent is not accessible or if the parent is just
// read only
return false;
}
}
}
}
return true;
}
/**
* Checks if is resource modifiable.
*
* @param resource In this case resource should exist
* @return true, if is resource modifiable
*/
public static boolean isResourceModifiable(IResource resource) {
if (resource.exists()) {// resource there
if (!resource.isAccessible()
|| resource.getResourceAttributes().isReadOnly()) {
// Not accessible or if just readable
return false;
}
} else {// Without resource how will we modify :)
return false;
}
return true;
}
/**
* Checks if is resource readable.
*
* @param resource In this case resource should exist and should be readable
* @return true, if is resource readable
*/
public static boolean isResourceReadable(IResource resource) {
if (resource.exists()) {// resource there
if (!resource.isAccessible()) {// Not accessible, No good to read
return false;
}
} else {// resource not there, Dont try to make us read a non existing
// file.
return false;
}
return true;
}
/**
* Gets the open projects in work space.
*
* @return Only open projects are returned
*/
public static IProject[] getOpenProjectsInWorkSpace() {
IProject projects[] = getWorkspaceRoot().getProjects();
ArrayList<IProject> openedProjects = new ArrayList<IProject>();
for (IProject project : projects) {
if (project.isOpen())
openedProjects.add(project);
}
return openedProjects.toArray(new IProject[0]);
}
/**
* Gets the projects by nature.
*
* @param natureIds the nature ids
* @return the projects by nature
* @throws CoreException the core exception
* Returns the projects with this nature Only open projects are returned
*/
public static ArrayList<IProject> getProjectsByNature(String... natureIds)
throws CoreException {
Set<String> searchNatureSet = SetUtil.hashSet(natureIds);
IProject projects[] = getWorkspaceRoot().getProjects();
ArrayList<IProject> resultProjects = new ArrayList<IProject>();
for (IProject project : projects) {
if (project.isOpen() && project.isAccessible()) {
String[] projectNatureIds = project.getDescription()
.getNatureIds();
Set<String> projectNatureSet = SetUtil
.hashSet(projectNatureIds);
if (!CollectionUtil.intersection(projectNatureSet,
searchNatureSet).isEmpty()) {
resultProjects.add(project);
}
}
}
return resultProjects;
}
/**
* Creates the empty file.
*
* @param project the project
* @param fileName the file name
* @param monitor the monitor
* @return the i file
* @throws CoreException the core exception
*/
public static IFile createEmptyFile(IProject project, String fileName,
IProgressMonitor monitor) throws CoreException {
IFile file = project.getFile(fileName);
StringBuilder folder = new StringBuilder();
for (int i = 0; i < file.getProjectRelativePath().segmentCount() - 1; i++) {
folder.append(file.getProjectRelativePath().segment(i));
folder.append(PATH_SEPERATOR);
String sfolder = folder.toString();
if (!project.getFolder(sfolder).exists()) {
project.getFolder(sfolder).create(true, true,
new NullProgressMonitor());
project.getFolder(sfolder).refreshLocal(
IResource.DEPTH_INFINITE, new NullProgressMonitor());
}
}
file.create(IOUtils.toInputStream(" "), true, monitor);
return file;
}
/**
* Gets the files with extensions.
*
* @param folder the folder
* @param checkExistence the check existence
* @param fileExt the file ext
* @return the files with extensions
* @throws CoreException the core exception
*/
public static List<IFile> getFilesWithExtensions(final IFolder folder,
final boolean checkExistence, final String fileExt)
throws CoreException {
final List<IFile> result = new ArrayList<IFile>();
if (folder == null || folder.isAccessible() == false
|| StringUtils.isBlank(fileExt))
return result;
for (final IResource resource : folder.members()) {
if (resource instanceof IFile
&& fileExt.equalsIgnoreCase(resource.getFileExtension())) {
if (checkExistence == false
|| (checkExistence && resource.isAccessible())) {
result.add((IFile) resource);
}
} else if (resource instanceof IFolder && resource.isAccessible()) {
result.addAll(getFilesWithExtensions((IFolder) resource,
checkExistence, fileExt));
}
}
return result;
}
/**
* Deletes the contents of the folder. Checks for existence. Does not
* perform a null check. Silently returning for null is not a good idea.
*
* @param folder the folder
* @param refresh the refresh
* @throws CoreException the core exception
* @throws SOANullParameterException the sOA null parameter exception
* @throws SOAResourceNotAccessibleException the sOA resource not accessible exception
*/
public static void deleteContents(IFolder folder, boolean refresh)
throws CoreException, SOANullParameterException,
SOAResourceNotAccessibleException {
if (folder == null)
throw new SOANullParameterException(0);
if (refresh)
WorkspaceUtil.refresh(folder);
if (!folder.exists())
throw new SOAResourceNotAccessibleException(folder.getName()
+ " does not exist", folder);
for (IResource resource : folder.members(IContainer.INCLUDE_PHANTOMS
| IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS)) {
WorkspaceUtil
.delete(resource, ProgressUtil.getDefaultMonitor(null));
}
if (refresh)
WorkspaceUtil.refresh(folder);
}
/**
* Checks if is dot directory.
*
* @param folder the folder
* @return true, if is dot directory
*/
public static boolean isDotDirectory(String folder) {
return StringUtils.equals(".", folder)
|| StringUtils.equals("." + PATH_SEPERATOR, folder);
}
/**
* Adds the extension if required.
*
* @param path the path
* @param extension the extension
* @return the i path
*/
public static IPath addExtensionIfRequired(IPath path, String extension) {
if (!StringUtils.equals(path.getFileExtension(), extension)) {
path.addFileExtension(extension);
}
return path;
}
}