blob: be49e39247ff494ee401eabb9ce1d5e5c05a9c0d [file] [log] [blame]
/**
* Copyright (c) 2009-2010 Thales Corporate Services S.A.S.
* 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:
* Thales Corporate Services S.A.S - initial API and implementation
*/
package org.eclipse.egf.common.helper;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
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.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.egf.common.EGFCommonPlugin;
import org.eclipse.egf.common.constant.EGFCommonConstants;
import org.eclipse.emf.common.util.URI;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.core.plugin.PluginRegistry;
/**
* @author brocard
*/
public class FileHelper {
private FileHelper() {
// Prevent Instantiation
}
/**
* Get file full url from relative one.
*
* @param fileRelativePath_p
* File path relative to workspace.<br>
* It <b>must</b> start with <i>pluginId</i>. It is also recommended
* that both plug-in id and plug-in project names are the same.<br>
* As a convenience, the full path will refer to the plug-in id.<br>
* <b>Example</b> :
* <i>com.thalesgroup.mde.mdsofa/model/example.ecore</i> is a path
* relative to the workspace that refers to the
* <i>com.thalesgroup.mde.mdsofa plug-in</i>, having a
* <i>model/example.ecore</i> file in its project.<br>
* In Eclipse resource system, such a path is considered as an
* absolute one against the workspace root.<br>
* It's still referred to as a relative path, since the returned URL
* is absolute in the file system.
* @return
*/
public static URL getFileFullUrl(String fileRelativePath_p) {
// Get the URI for given relative path.
return getFileFullUrl(getFileFullUri(fileRelativePath_p));
}
/**
* Get file full url from its full uri.<br>
* See {@link #getFileFullUri(String)} method.
*
* @param fileFullUri_p
* @return
*/
public static URL getFileFullUrl(URI fileFullUri_p) {
URL result = null;
// Resolve url from returned uri.
try {
result = FileLocator.resolve(new URL(fileFullUri_p.toString()));
} catch (Exception e) {
StringBuilder msg = new StringBuilder("FileHelper.getFileFullPath(..) _ "); //$NON-NLS-1$
msg.append("Unable to resolve the url for ").append(fileFullUri_p.toString()); //$NON-NLS-1$
EGFCommonPlugin.getDefault().logError(msg.toString(), e);
}
return result;
}
/**
* Get a file uri from relative one which is not resolved against the eclipse
* platform.<br>
* The returned uri starts with either 'platform:/plug-in/' or
* 'platform:/resource/'.
*
* @param fileRelativePath_p
* File path relative to workspace.<br>
* It <b>must</b> start with <i>pluginId</i>. It is also recommended
* that both plug-in id and plug-in project names are the same.<br>
* As a convenience, the full path will refer to the plug-in id.<br>
* <b>Example</b> :
* <i>com.thalesgroup.mde.mdsofa/model/example.ecore</i> is a path
* relative to the workspace that refers to the
* <i>com.thalesgroup.mde.mdsofa plug-in</i>, having a
* <i>model/example.ecore</i> file in its project.
* @return an {@link URI} not resolved against the eclipse platform.<br>
*/
public static URI getFileFullUri(String fileRelativePath_p) {
URI fileUri = null;
// Precondition.
if (fileRelativePath_p == null) {
return fileUri;
}
// Find plug-in model base from relative first segment.
IPath path = new Path(fileRelativePath_p);
IPluginModelBase modelBase = PluginRegistry.findModel(path.segment(0));
// Get underlying resource.
IResource resource = modelBase != null ? modelBase.getUnderlyingResource() : null;
if (resource != null) { // Resource found, the file is in the workspace.
fileUri = URI.createPlatformResourceURI(fileRelativePath_p, true);
} else { // Resource not found, the file is deployed elsewhere.
fileUri = URI.createPlatformPluginURI(fileRelativePath_p, true);
}
return fileUri;
}
/**
* Convert package name to a correct java folder path.
*
* @param packageName_p
* @return
*/
public static String convertPackageNameToFolderPath(String packageName_p) {
return packageName_p != null ? packageName_p.replace(EGFCommonConstants.DOT_CHARACTER, EGFCommonConstants.SLASH_CHARACTER) : null;
}
/**
* Read given input stream as an array of bytes.
*
* @param inputStream_p
* @return a not null array.
*/
public static byte[] readFile(InputStream inputStream_p) {
byte[] data = null;
try {
data = new byte[inputStream_p.available()];
inputStream_p.read(data);
} catch (Exception e) {
StringBuilder msg = new StringBuilder("FileHelper.readFile(..) _ "); //$NON-NLS-1$
msg.append("Failed to read the input stream ! "); //$NON-NLS-1$
EGFCommonPlugin.getDefault().logError(msg.toString(), e);
} finally {
if (inputStream_p != null) {
try {
inputStream_p.close();
} catch (IOException ioe) {
StringBuilder msg = new StringBuilder("FileHelper.readFile(..) _ "); //$NON-NLS-1$
msg.append("Failed to close input stream ! "); //$NON-NLS-1$
EGFCommonPlugin.getDefault().logError(msg.toString(), ioe);
}
}
}
// Ensure to return a not null array.
return (null == data) ? new byte[0] : data;
}
/**
* Read file as a string.
*
* @param filePath_p
* File path relative to the plug-in, plug-in id included.<br>
* See {@link #getFileFullUrl(String)} documentation.
* @return If an error occurred {@link EGFCommonConstants#EMPTY_STRING} is
* returned.
*/
public static String readFile(String filePath_p) {
byte[] rawContent = readRawFile(filePath_p);
return rawContent.length == 0 ? EGFCommonConstants.EMPTY_STRING : new String(rawContent);
}
/**
* Get file as a stream.
*
* @param filePath_p
* File path relative to the plug-in, plug-in id included.<br>
* See {@link #getFileFullUrl(String)} documentation.
* @return If an error occurred null is returned.
*/
public static InputStream readFileAsStream(String filePath_p) {
InputStream result = null;
// Get input stream and copy its content to resulting string.
URL fileURL = getFileFullUrl(filePath_p);
try {
result = fileURL.openStream();
} catch (Exception e) {
StringBuilder msg = new StringBuilder("FileHelper.readFileAsStream(..) _ "); //$NON-NLS-1$
msg.append("Failed to load ").append(filePath_p); //$NON-NLS-1$
EGFCommonPlugin.getDefault().logError(msg.toString(), e);
}
return result;
}
/**
* Read file as an array of bytes.
*
* @param filePath_p
* File path relative to the plug-in, plug-in id included.<br>
* See {@link #getFileFullUrl(String)} documentation.
* @return a not null array.
*/
public static byte[] readRawFile(String filePath_p) {
byte[] result = null;
// Get stream from file.
InputStream inputStream = readFileAsStream(filePath_p);
// Ensure the input stream got from the file path is not null.
if (inputStream != null) {
result = readFile(inputStream);
}
return (null == result) ? new byte[0] : result;
}
/**
* Copy given source file content in given target file.
*
* @param sourceFileRelativePath_p
* File path relative to the plug-in, plug-in id included.<br>
* See {@link #getFileFullUrl(String)} documentation.
* @param targetFileRelativePath_p
* File path relative to the plug-in, plug-in id included.<br>
* See {@link #getFileFullUrl(String)} documentation.
*/
public static void copyFile(String sourceFileRelativePath_p, String targetFileRelativePath_p) {
writeFile(targetFileRelativePath_p, true, readRawFile(sourceFileRelativePath_p));
}
/**
* Write given string contents at specified path.
*
* @param filePath_p
* File path relative to the plug-in, plug-in id included.<br>
* See {@link #getFileFullUrl(String)} documentation.
* @param ensureFolders_p
* Make sure all parent folders exist by creating all necessary ones.
* @param contents_p
* Contents that should be written to pointed file.
* @return
*/
public static boolean writeFile(String filePath_p, boolean ensureFolders_p, String contents_p) {
return writeFile(filePath_p, ensureFolders_p, contents_p.getBytes());
}
/**
* Write given contents of bytes at specified path.
*
* @param filePath_p
* File path relative to the plug-in, plug-in id included.<br>
* See {@link #getFileFullUrl(String)} documentation.
* @param ensureFolders_p
* Make sure all parent folders exist by creating all necessary ones.
* @param contents_p
* Contents that should be written to pointed file.
* @return
*/
public static boolean writeFile(String filePath_p, boolean ensureFolders_p, byte[] contents_p) {
FileChannel channel = null;
try {
// Get file full path from its relative one.
String fileFullPath = getFileFullUrl(filePath_p).getFile();
// Should path be enforced ?
if (ensureFolders_p) {
ensurePathAvailability(fileFullPath);
}
// Try and open the resulting file.
channel = new FileOutputStream(fileFullPath).getChannel();
// Write contents.
channel.write(ByteBuffer.wrap(contents_p));
} catch (Exception e) {
StringBuilder msg = new StringBuilder("FileHelper.writeFile(..) _ "); //$NON-NLS-1$
msg.append("Failed to open channel in write mode for "); //$NON-NLS-1$
msg.append(filePath_p).append(" !"); //$NON-NLS-1$
EGFCommonPlugin.getDefault().logError(msg.toString(), e);
return false;
} finally {
if (channel != null && channel.isOpen()) {
try {
// Close the channel.
channel.close();
} catch (IOException e) {
StringBuilder msg = new StringBuilder("FileHelper.writeFile(..) _ "); //$NON-NLS-1$
msg.append("Failed to close opened channel in write mode ! "); //$NON-NLS-1$
msg.append(filePath_p).append(" may no longer be usable."); //$NON-NLS-1$
EGFCommonPlugin.getDefault().logError(msg.toString(), e);
}
}
}
return true;
}
/**
* Rename file from source file relative path to destination relative path.
*
* @param sourceFileRelativePath_p
* File path relative to the plug-in, plug-in id included.<br>
* See {@link #getFileFullUrl(String)} documentation.
* @param destinationFileRelativePath_p
* File path relative to the plug-in, plug-in id included.<br>
* See {@link #getFileFullUrl(String)} documentation.
* @return
*/
public static boolean renameFile(String sourceFileRelativePath_p, String destinationFileRelativePath_p) {
// Preconditions.
if (sourceFileRelativePath_p == null || destinationFileRelativePath_p == null) {
return false;
}
IFile sourceFile = getPlatformFile(sourceFileRelativePath_p);
IPath destinationPath = getPlatformFile(destinationFileRelativePath_p).getFullPath();
return moveResource(sourceFile, destinationPath);
}
/**
* Rename folder from source folder relative path to destination relative
* path.
*
* @param sourceFolderRelativePath_p
* Folder path relative to the plug-in, plug-in id included.<br>
* See {@link #getFileFullUrl(String)} documentation.
* @param destinationFolderRelativePath_p
* Folder path relative to the plug-in, plug-in id included.<br>
* See {@link #getFileFullUrl(String)} documentation.
* @return
*/
public static boolean renameFolder(String sourceFolderRelativePath_p, String destinationFolderRelativePath_p) {
// Preconditions.
if (sourceFolderRelativePath_p == null || destinationFolderRelativePath_p == null) {
return false;
}
IFolder sourceFolder = getPlatformFolder(sourceFolderRelativePath_p);
IPath destinationPath = getPlatformFolder(destinationFolderRelativePath_p).getFullPath();
return moveResource(sourceFolder, destinationPath);
}
/**
* Move resource to given destination path.
*
* @param resource_p
* @param destinationPath_p
* @return true if move occurred with no exception, false otherwise.
*/
public static boolean moveResource(IResource resource_p, IPath destinationPath_p) {
boolean result = false;
try {
resource_p.move(destinationPath_p, true, new NullProgressMonitor());
result = true;
} catch (Exception e) {
StringBuilder msg = new StringBuilder("FileHelper.moveResource(..) _ "); //$NON-NLS-1$
msg.append("Could not move ").append(resource_p.getFullPath()); //$NON-NLS-1$
msg.append(" to ").append(destinationPath_p); //$NON-NLS-1$
EGFCommonPlugin.getDefault().logError(msg.toString(), e);
}
return result;
}
/**
* Is given file relative path pointing to an existing file ?
*
* @param fileRelativePath_p
* File path relative to the plug-in, plug-in id included.<br>
* See {@link #getFileFullUrl(String)} documentation.
* @return
*/
public static boolean exists(String fileRelativePath_p) {
IFile file = getPlatformFile(fileRelativePath_p);
return file != null ? file.exists() : false;
}
/**
* Make sure that given path is safe to use, ie ensure that all parent folders
* exist.
*
* @param fileFullPath_p
*/
public static void ensurePathAvailability(String fileFullPath_p) {
// Get rid of file extension and file name, for this has no meaning in the
// parent folders chain.
IPath parentFolderPath = new Path(fileFullPath_p).removeFileExtension().removeLastSegments(1);
// If it still makes sense to create a folder, go for it.
if (parentFolderPath.isEmpty() == false) {
File parentFolder = parentFolderPath.toFile();
// Create the chain of parent folders.
parentFolder.mkdirs();
}
}
/**
* Delete a workspace Resource. Optionally delete its parent folder if they
* are empty. Root folder is never deleted.
*
* @param javaProject_p
* @param resourcePath_p
*/
public static boolean deleteResource(IFolder root_p, IResource resource_p, boolean deleteParent_p) {
if (resource_p == null) {
return false;
}
// Delete found resource member
if (FileHelper.deleteResource(resource_p) == false) {
return false;
}
// Delete children container if they are empty
if (root_p != null && deleteParent_p) {
IContainer container = resource_p.getParent();
while (container.equals(root_p) == false) {
try {
IResource[] members = container.members();
if (members == null || members.length == 0) {
if (FileHelper.deleteResource(container)) {
container = container.getParent();
} else {
break;
}
} else {
break;
}
} catch (CoreException ce) {
break;
}
}
}
return true;
}
/**
* Delete given relative resource in the workspace.
*
* @param fileRelativePath_p
*/
public static boolean deleteFile(String fileRelativePath_p) {
if (fileRelativePath_p == null || fileRelativePath_p.trim().length() == 0) {
return false;
}
return deleteResource(getPlatformFile(fileRelativePath_p));
}
/**
* Delete given relative folder in the workspace.
*
* @param workspaceRelativePath_p
* @return true if successfully deleted, false otherwise.
*/
public static boolean deleteFolder(String folderRelativePath_p) {
if (folderRelativePath_p == null || folderRelativePath_p.trim().length() == 0) {
return false;
}
return deleteResource(getPlatformFolder(folderRelativePath_p));
}
/**
* Delete given relative resource in the workspace.
*
* @param resource_p
*/
public static boolean deleteResource(IResource resource_p) {
if (resource_p == null || resource_p.exists() == false) {
return false;
}
try {
resource_p.delete(true, new NullProgressMonitor());
return true;
} catch (CoreException ce) {
StringBuilder msg = new StringBuilder("FileHelper.deleteFile(..) _ "); //$NON-NLS-1$
msg.append("Unable to delete file:").append(resource_p.getFullPath()); //$NON-NLS-1$
EGFCommonPlugin.getDefault().logError(msg.toString(), ce);
}
return false;
}
/**
* Get platform IResource as an {@link IResource} from its relative IPath.
*
* @param path_p
* IPath relative to workspace.<br>
* @return
*/
public static IResource getPlatformResource(IPath path_p) {
// Precondition.
if (path_p == null) {
return null;
}
return ResourcesPlugin.getWorkspace().getRoot().findMember(path_p);
}
/**
* Get platform file as an {@link IResource} from its relative path.
*
* @param fileRelativePath
* File path relative to the plug-in, plug-in id included.<br>
* See {@link #getFileFullUrl(String)} documentation.
* @return
*/
public static IFile getPlatformFile(String fileRelativePath) {
// Precondition.
if (fileRelativePath == null) {
return null;
}
return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(fileRelativePath));
}
/**
* Get platform folder as an {@link IResource} from its relative path.
*
* @param folderRelativePath_p
* Folder path relative to the plug-in, plug-in id included.<br>
* See {@link #getFileFullUrl(String)} documentation.
* @return
*/
public static IFolder getPlatformFolder(String folderRelativePath_p) {
// Precondition.
if (folderRelativePath_p == null) {
return null;
}
return ResourcesPlugin.getWorkspace().getRoot().getFolder(new Path(folderRelativePath_p));
}
/**
* Returns the file extension portion for given file path, <br>
* or <code>null</code> if there is none.<br>
* <p>
* The file extension portion is defined as the string<br>
* following the last period (".") character in the last segment.<br>
* If there is no period in the last segment, the path has no<br>
* file extension portion. If the last segment ends in a period,<br>
* the file extension portion is the empty string.<br>
* </p>
*
* @param filePath_p
* @return the file extension or <code>null</code>
*/
public static String getFileExtension(String filePath_p) {
// Precondition.
if (filePath_p == null) {
return null;
}
return new Path(filePath_p).getFileExtension();
}
}