blob: f8d48af11b98244485684df58875e5e71778dbfe [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.persistence;
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import org.eclipse.core.internal.resources.ResourceException;
import org.eclipse.core.internal.resources.ResourceStatus;
import org.eclipse.core.internal.utils.Messages;
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.IResourceStatus;
import org.eclipse.core.resources.IWorkspace;
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.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.epf.persistence.util.PersistenceResources;
import com.ibm.uma.util.IFileManager;
/**
* @author Phong Nguyen Le
* @since 1.0
*/
public class FileManager implements IFileManager {
private static final String PLUGIN_ID = FileManager.class.getPackage().getName();
private static FileManager instance = null;
private boolean validateEditInitialized = false;
public static final FileManager getInstance() {
if (instance == null) {
synchronized (FileManager.class) {
if (instance == null) {
instance = new FileManager();
}
}
}
return instance;
}
private FileManager() {
}
public static IResource getResourceForLocation(String location) {
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
IPath path = new Path(location);
IResource resource;
if (new File(location).isFile()) {
resource = workspaceRoot.getFileForLocation(path);
} else {
resource = workspaceRoot.getContainerForLocation(path);
}
return resource;
}
public static boolean refresh(IResource resource) throws CoreException {
if (!resource.exists()) {
ArrayList foldersToRefresh = new ArrayList();
IContainer container;
for (container = resource.getParent(); !container.exists(); container = container
.getParent()) {
foldersToRefresh.add(0, container);
}
if (container.exists()) {
container.refreshLocal(IResource.DEPTH_ONE, null);
}
if (!foldersToRefresh.isEmpty()) {
for (Iterator iter = foldersToRefresh.iterator(); iter
.hasNext();) {
IFolder folder = (IFolder) iter.next();
if (folder.exists()) {
folder.refreshLocal(IResource.DEPTH_ONE, null);
} else {
return false;
}
}
}
}
resource.refreshLocal(IResource.DEPTH_ONE, null);
return true;
}
private static boolean refresh(String oldPath) throws CoreException {
IResource resource = getResourceForLocation(oldPath);
if(resource != null) {
return refresh(resource);
}
return false;
}
public boolean move(String oldPath, String newPath) {
return move(oldPath, newPath, false);
}
public boolean move(String oldPath, String newPath,
boolean forceRemoveSource) {
try {
refresh(oldPath);
IResource resource = null;
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace()
.getRoot();
// create the folders of the destination if they did not exist
IPath destPath = new Path(newPath);
if (new File(oldPath).isFile()) {
resource = workspaceRoot.getFileForLocation(destPath);
} else {
resource = workspaceRoot.getContainerForLocation(destPath);
}
if (resource.exists()) {
throw new MultiFileIOException(PersistenceResources
.formatString(
"Persistence.moveError.msg", oldPath, newPath)); //$NON-NLS-1$
}
ArrayList foldersToCreate = new ArrayList();
IContainer container;
for (container = resource.getParent(); !container.exists(); container = container
.getParent()) {
foldersToCreate.add(0, container);
}
if (!foldersToCreate.isEmpty()) {
container.refreshLocal(IResource.DEPTH_ONE, null);
for (Iterator iter = foldersToCreate.iterator(); iter.hasNext();) {
IFolder folder = (IFolder) iter.next();
if (!folder.exists()) {
folder.create(true, false, null);
} else {
folder.refreshLocal(IResource.DEPTH_ONE, null);
}
}
}
destPath = resource.getFullPath();
IPath path = new Path(oldPath);
IFile file = workspaceRoot.getFileForLocation(path);
if (file != null && file.exists()) {
resource = file;
} else {
resource = workspaceRoot.getContainerForLocation(path);
}
if (resource != null) {
try {
resource.move(destPath, true, null);
} catch (ResourceException e) {
if (forceRemoveSource) {
throw e;
}
boolean failed = false;
// handle situation when Eclipse moves file/directory by
// copying it to destination then deleting the source
// but deletion failed
IStatus[] statuses = e.getStatus().getChildren();
for (int i = 0; i < statuses.length; i++) {
IStatus status = statuses[i];
if (status.getCode() == IResourceStatus.FAILED_DELETE_LOCAL
&& status.getMessage() == Messages.localstore_deleteProblemDuringMove) {
String msg = MessageFormat
.format(
"Warning while moving ''{0}'' to ''{1}'': {2}", new Object[] { oldPath, newPath, status.getMessage() }); //$NON-NLS-1$
CommonPlugin.INSTANCE.log(msg);
} else {
failed = true;
}
}
if (failed || !new File(newPath).exists()) {
return false;
}
}
return true;
}
} catch (CoreException e) {
CommonPlugin.INSTANCE.log(e);
if (MultiFileSaveUtil.DEBUG) {
e.printStackTrace();
}
}
return false;
}
public boolean rename(File oldFile, File newFile) {
return move(oldFile.getAbsolutePath(), newFile.getAbsolutePath());
}
public boolean delete(String path) {
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
try {
workspaceRoot.refreshLocal(IResource.DEPTH_INFINITE, null);
} catch (CoreException e1) {
e1.printStackTrace();
}
IPath loc = new Path(path);
IResource resource = null;
IFile file = workspaceRoot.getFileForLocation(loc);
if (file.exists()) {
resource = file;
} else {
resource = file.getProject().getFolder(
file.getProjectRelativePath());
}
if (resource != null) {
try {
resource.delete(true, null);
return true;
} catch (CoreException e) {
e.printStackTrace();
}
}
return false;
}
private static boolean fromCC(IStatus status) {
String pluginId = status.getPlugin();
return pluginId != null
&& pluginId.toLowerCase().indexOf("clearcase") != -1; //$NON-NLS-1$
}
public IStatus checkModify(String[] paths, Object context) {
IStatus status = null;
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IFile[] files = new IFile[paths.length];
ArrayList notFoundFiles = new ArrayList();
for (int i = 0; i < paths.length; i++) {
String path = paths[i];
try {
refresh(path);
} catch (CoreException e) {
CommonPlugin.INSTANCE.log(e);
}
IFile file = workspace.getRoot().getFileForLocation(new Path(path));
if (file == null) {
notFoundFiles.add(path);
} else {
files[i] = file;
}
}
if (!notFoundFiles.isEmpty()) {
return new Status(
IStatus.WARNING,
PLUGIN_ID,
IStatus.WARNING,
PersistenceResources.formatString(
"Persistence.fileNotFoundError.msg", notFoundFiles), null); //$NON-NLS-1$
}
if (!validateEditInitialized) {
status = workspace.validateEdit(files, context);
validateEditInitialized = true;
if(status.isOK()) {
// double-check after initialization
//
status = workspace.validateEdit(files, context);
}
}
else {
status = workspace.validateEdit(files, context);
}
if(status.isOK()) {
// some version control provider still returns OK status even though user cancelled the check out
// double-check here again to make sure the file is not read-only
//
ArrayList readOnlyFiles = new ArrayList();
for(int i = 0; i < files.length; i++) {
IFile file = files[i];
try {
file.refreshLocal(IResource.DEPTH_ZERO, null);
} catch (CoreException e) {
CommonPlugin.INSTANCE.log(e);
}
if(file.isReadOnly()) {
readOnlyFiles.add(file);
}
}
if(!readOnlyFiles.isEmpty()) {
MultiStatus multiStatus = new MultiStatus(PLUGIN_ID, IStatus.OK, PersistenceResources
.getString("Persistence.modifyFilesError.msg"), null); //$NON-NLS-1$
for (Iterator iter = readOnlyFiles.iterator(); iter.hasNext();) {
IFile file = (IFile) iter.next();
String localPath = file.getLocation().toOSString();
String msg = MessageFormat
.format(
PersistenceResources
.getString("Persistence.FileManager.fileReadOnly"), new Object[] { localPath }); //$NON-NLS-1$
multiStatus.add(new ResourceStatus(IStatus.ERROR, 0,
file.getFullPath(), msg, null));
}
status = multiStatus;
return status;
}
}
else {
// hack for clearcase
if (fromCC(status)) {
String msg = PersistenceResources
.getString("Persistence.modifyFilesError.msg"); //$NON-NLS-1$
MultiStatus multiStatus = new MultiStatus(PLUGIN_ID, status
.getCode(), msg, null);
multiStatus.add(status);
return multiStatus;
}
}
// convert workspace path to local file system path
if (status instanceof MultiStatus) {
MultiStatus ms = (MultiStatus) status;
for (int i = 0; i < ms.getChildren().length; i++) {
IStatus childStatus = ms.getChildren()[i];
if (childStatus instanceof IResourceStatus
&& childStatus.getCode() == IResourceStatus.READ_ONLY_LOCAL) {
IResourceStatus resourceStatus = ((IResourceStatus) childStatus);
IPath path = resourceStatus.getPath();
IFile file = ResourcesPlugin.getWorkspace().getRoot()
.getFile(path);
String localPath = file.getLocation().toOSString();
String msg = MessageFormat
.format(
PersistenceResources
.getString("Persistence.FileManager.fileReadOnly"), new Object[] { localPath }); //$NON-NLS-1$
ms.getChildren()[i] = new ResourceStatus(childStatus
.getSeverity(), childStatus.getCode(),
resourceStatus.getPath(), msg, childStatus
.getException());
}
}
}
return status;
}
/**
* @see com.ibm.uma.util.IFileManager#checkModify(java.lang.String,
* java.lang.Object)
*/
public IStatus checkModify(String path, Object context) {
return checkModify(new String[] { path }, context);
}
}