/******************************************************************************* * Copyright (c) 2000, 2007 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.IResourceProxy; 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<IScriptProject, IProjectFragment[]>(); // 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 = new IResourceProxyVisitor() { public boolean visit(IResourceProxy proxy) throws CoreException { 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; } }