blob: c28e15437e939455c8a511ba0e815de387b12834 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007 Borland Software Corporation
*
* 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:
* Borland Software Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.ui.wizards.project;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
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.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.m2m.internal.qvt.oml.common.MDAConstants;
import org.eclipse.m2m.internal.qvt.oml.ui.QVTUIPlugin;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.ide.undo.CreateFolderOperation;
import org.eclipse.ui.ide.undo.MoveResourcesOperation;
import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
class SourceContainerUpdater {
private IContainer fCurrentContainer;
public SourceContainerUpdater(IContainer existingContainer) {
if(existingContainer == null) {
throw new IllegalArgumentException();
}
this.fCurrentContainer = existingContainer;
}
/**
* Performs validation on the given source container path.
*
* @param srcContainerPath
* source container path relative to its project container.
* <p>
* Remark: <code>null</code> value is accepted and identifies
* the project container.
*
* @return status object representing the validation result
*/
public static IStatus validate(String srcContainerPath) {
IStatus result = Status.OK_STATUS;
if(srcContainerPath == null || srcContainerPath.length() == 0) {
// Remark:
// Allow this as we can avoid the problem with the source folder interference
// with namespaces when deployed
//return QVTUIPlugin.createStatus(IStatus.INFO, Messages.SourceContainerUpdater_ProjectAsSourceFolderNotRecommened);
} else if(srcContainerPath.trim().length() == 0) {
return QVTUIPlugin.createStatus(IStatus.ERROR, Messages.SourceContainerUpdater_NonBlankSourceFolderExpected);
} else {
IPath path = new Path(srcContainerPath);
if(!path.isValidPath(srcContainerPath)) {
return QVTUIPlugin.createStatus(IStatus.ERROR, Messages.SourceContainerUpdater_InvalidSourceFolder);
} else if(path.isAbsolute() || path.isUNC() || path.getDevice() != null ) {
return QVTUIPlugin.createStatus(IStatus.ERROR, Messages.SourceContainerUpdater_RelativeSourceFolderExpected);
} else {
result = ResourcesPlugin.getWorkspace().validatePath("/" + path.toString(), IResource.PROJECT | IResource.FOLDER | IResource.FILE); //$NON-NLS-1$
}
}
return result;
}
public IStatus setContainer(IContainer newContainer, boolean moveExistingSources, IProgressMonitor monitor, Shell shell) {
IStatus result = Status.OK_STATUS;
if(newContainer.getType() == IResource.FOLDER) {
result = ensureDestinationExists((IFolder)newContainer, monitor);
if(!result.isOK()) {
return result;
}
}
List<IResource> rootItems = collectRootMoveCandidates(fCurrentContainer);
IResource[] sources = rootItems.toArray(new IResource[rootItems.size()]);
IPath destPath = newContainer.getFullPath();
result = validateMoveSource(sources, destPath);
//MoveFilesAndFoldersOperation moveOperation = new MoveFilesAndFoldersOperation(fShell);
//moveOperation.validateDestination(newSourceContainer, sources);
//moveOperation.copyResources(sources, newSourceContainer);
if(result.isOK()) {
MoveResourcesOperation moveOperation = new MoveResourcesOperation(sources, destPath, "Moving"); //$NON-NLS-1$
try {
moveOperation.setQuietCompute(false);
result = moveOperation.execute(monitor, WorkspaceUndoUtil.getUIInfoAdapter(shell));
} catch (ExecutionException e) {
QVTUIPlugin.log(e);
try {
if(moveOperation.canUndo()) {
moveOperation.undo(monitor, null);
}
} catch (ExecutionException e1) {
QVTUIPlugin.log(e);
}
}
}
return result;
}
static IStatus ensureDestinationExists(IFolder container, IProgressMonitor monitor) {
IProgressMonitor safeMonitor = monitor != null ? monitor : new NullProgressMonitor();
try {
CreateFolderOperation operation = new CreateFolderOperation(container, null, "Creating source container"); //$NON-NLS-1$
return operation.execute(safeMonitor, null);
} catch (ExecutionException e) {
return QVTUIPlugin.createStatus(IStatus.ERROR, e.getLocalizedMessage(), e);
}
}
private IStatus validateMoveSource(IResource[] resourceToBeMoved, IPath destPath) {
for (int i = 0; i < resourceToBeMoved.length; i++) {
if(resourceToBeMoved[i].getFullPath().isPrefixOf(destPath)) {
// FIXME -
//return QVTUIPlugin.createStatus(IStatus.ERROR, "Invalid destination source container", null);
}
}
return Status.OK_STATUS;
}
private static List<IResource> collectRootMoveCandidates(IContainer rootContainer) {
final List<IResource> candidates = new ArrayList<IResource>();
final boolean isProjectContainer = rootContainer.getType() == IResource.PROJECT;
try {
rootContainer.accept(new IResourceProxyVisitor() {
int depth = 0;
public boolean visit(IResourceProxy proxy) throws CoreException {
if(depth > 0) {
if(proxy.getType() == IResource.FOLDER) {
if(!isProjectContainer || isQvtNamespaceFolder(((IFolder)proxy.requestResource()))) {
candidates.add(proxy.requestResource());
}
} else if(proxy.getType() == IResource.FILE) {
if(isQvtSourceFile(proxy)) {
candidates.add(proxy.requestResource());
}
}
}
return (depth == 0) ? (depth = 1) > 0 : false; // allow only for DEPTH_1
}
}, 0);
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return candidates;
}
static boolean isQvtNamespaceFolder(IFolder folder) {
final boolean[] foundQvtSource = new boolean[] { false };
final boolean[] foundOtherSource = new boolean[] { false };
try {
folder.accept(new IResourceProxyVisitor() {
public boolean visit(IResourceProxy proxy) throws CoreException {
if(isQvtSourceFile(proxy)) {
foundQvtSource[0] = true;
} else if(proxy.getType() == IResource.FILE) {
foundOtherSource[0] = true;
}
return !foundOtherSource[0];
}
}, 0);
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return foundQvtSource[0];
}
static boolean isQvtSourceFile(IResourceProxy proxy) {
return proxy.getType() == IResource.FILE && proxy.getName().endsWith(MDAConstants.QVTO_FILE_EXTENSION_WITH_DOT);
}
static class QvtSourceFinder implements IResourceProxyVisitor {
private int depth = IResource.DEPTH_ZERO;
private int nextDepth = IResource.DEPTH_ZERO;
private List<IResource> sources = new ArrayList<IResource>();
QvtSourceFinder() {
}
public void setDepth(int depth) {
this.depth = depth;
}
public boolean visit(IResourceProxy proxy) throws CoreException {
if(proxy.getType() == IResource.FILE &&
proxy.getName().endsWith(MDAConstants.QVTO_FILE_EXTENSION_WITH_DOT)) {
sources.add(proxy.requestResource());
}
if(nextDepth == IResource.DEPTH_ZERO) {
depth = IResource.DEPTH_ONE;
}
return depth != IResource.DEPTH_ZERO;
}
};
}