blob: e449e5dab41588f6e0c5c5c86b6f3ac9a5fa71b5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2017 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
*
*******************************************************************************/
package org.eclipse.dltk.internal.core;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.dltk.core.IBuildpathEntry;
import org.eclipse.dltk.core.IModelStatus;
import org.eclipse.dltk.core.IModelStatusConstants;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptModel;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ModelException;
public class DeleteProjectFragmentOperation extends ModelOperation {
int updateResourceFlags;
int updateModelFlags;
public DeleteProjectFragmentOperation(IProjectFragment root,
int updateResourceFlags, int updateModelFlags) {
super(root);
this.updateResourceFlags = updateResourceFlags;
this.updateModelFlags = updateModelFlags;
}
@Override
protected void executeOperation() throws ModelException {
IProjectFragment root = (IProjectFragment) this.getElementToProcess();
IBuildpathEntry rootEntry = root.getRawBuildpathEntry();
// remember olds roots
DeltaProcessor deltaProcessor = ModelManager.getModelManager()
.getDeltaProcessor();
if (deltaProcessor.oldRoots == null)
deltaProcessor.oldRoots = new HashMap<>();
// update buildpath if needed
if ((updateModelFlags
& IProjectFragment.ORIGINATING_PROJECT_BUILDPATH) != 0) {
updateProjectBuildpath(rootEntry.getPath(), root.getScriptProject(),
deltaProcessor.oldRoots);
}
if ((updateModelFlags
& IProjectFragment.OTHER_REFERRING_PROJECTS_BUILDPATH) != 0) {
updateReferringProjectBuildpaths(rootEntry.getPath(),
root.getScriptProject(), deltaProcessor.oldRoots);
}
// delete resource
if (!root.isExternal() && (this.updateModelFlags
& IProjectFragment.NO_RESOURCE_MODIFICATION) == 0) {
deleteResource(root, rootEntry);
}
}
protected void deleteResource(IProjectFragment root,
IBuildpathEntry rootEntry) throws ModelException {
final char[][] exclusionPatterns = ((BuildpathEntry) rootEntry)
.fullExclusionPatternChars();
IResource rootResource = root.getResource();
if (rootEntry.getEntryKind() != IBuildpathEntry.BPE_SOURCE
|| exclusionPatterns == null) {
try {
rootResource.delete(this.updateResourceFlags, progressMonitor);
} catch (CoreException e) {
throw new ModelException(e);
}
} else {
final IPath[] nestedFolders = getNestedFolders(root);
IResourceProxyVisitor visitor = proxy -> {
if (proxy.getType() == IResource.FOLDER) {
IPath path = proxy.requestFullPath();
if (prefixesOneOf(path, nestedFolders)) {
// equals if nested source folder
return !equalsOneOf(path, nestedFolders);
} else {
// subtree doesn't contain any nested source folders
proxy.requestResource().delete(updateResourceFlags,
progressMonitor);
return false;
}
} else {
proxy.requestResource().delete(updateResourceFlags,
progressMonitor);
return false;
}
};
try {
rootResource.accept(visitor, IResource.NONE);
} catch (CoreException e) {
throw new ModelException(e);
}
}
this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
}
/*
* Deletes the buildpath entries equals to the given rootPath from all
* Script projects.
*/
protected void updateReferringProjectBuildpaths(IPath rootPath,
IScriptProject projectOfRoot,
Map<IScriptProject, IProjectFragment[]> oldRoots)
throws ModelException {
IScriptModel model = this.getModel();
IScriptProject[] projects = model.getScriptProjects();
for (int i = 0, length = projects.length; i < length; i++) {
IScriptProject project = projects[i];
if (project.equals(projectOfRoot))
continue;
updateProjectBuildpath(rootPath, project, oldRoots);
}
}
/*
* Deletes the buildpath entries equals to the given rootPath from the given
* project.
*/
protected void updateProjectBuildpath(IPath rootPath,
IScriptProject project,
Map<IScriptProject, IProjectFragment[]> oldRoots)
throws ModelException {
// remember old roots
oldRoots.put(project, project.getProjectFragments());
IBuildpathEntry[] buildpath = project.getRawBuildpath();
IBuildpathEntry[] newBuildpath = null;
int cpLength = buildpath.length;
int newCPIndex = -1;
for (int j = 0; j < cpLength; j++) {
IBuildpathEntry entry = buildpath[j];
if (rootPath.equals(entry.getPath())) {
if (newBuildpath == null) {
newBuildpath = new IBuildpathEntry[cpLength - 1];
System.arraycopy(buildpath, 0, newBuildpath, 0, j);
newCPIndex = j;
}
} else if (newBuildpath != null) {
newBuildpath[newCPIndex++] = entry;
}
}
if (newBuildpath != null) {
if (newCPIndex < newBuildpath.length) {
System.arraycopy(newBuildpath, 0,
newBuildpath = new IBuildpathEntry[newCPIndex], 0,
newCPIndex);
}
project.setRawBuildpath(newBuildpath, progressMonitor);
}
}
@Override
protected IModelStatus verify() {
IModelStatus status = super.verify();
if (!status.isOK()) {
return status;
}
IProjectFragment root = (IProjectFragment) this.getElementToProcess();
if (root == null || !root.exists()) {
return new ModelStatus(IModelStatusConstants.ELEMENT_DOES_NOT_EXIST,
root);
}
IResource resource = root.getResource();
if (resource instanceof IFolder) {
if (resource.isLinked()) {
return new ModelStatus(IModelStatusConstants.INVALID_RESOURCE,
root);
}
}
return ModelStatus.VERIFIED_OK;
}
}