/******************************************************************************* * Copyright (c) 2012-2015 Codenvy, S.A. * 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: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.core.internal.resources; import org.eclipse.che.core.internal.utils.Policy; import org.eclipse.core.internal.resources.ICoreConstants; import org.eclipse.core.internal.resources.ResourceException; import org.eclipse.core.internal.utils.Messages; import org.eclipse.core.internal.utils.WrappedRuntimeException; import org.eclipse.core.internal.watson.IPathRequestor; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IPathVariableManager; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceProxy; import org.eclipse.core.resources.IResourceProxyVisitor; import org.eclipse.core.resources.IResourceStatus; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourceAttributes; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Assert; 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.OperationCanceledException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.MultiRule; import org.eclipse.osgi.util.NLS; import java.io.IOException; import java.net.URI; import java.nio.file.FileVisitOption; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.attribute.BasicFileAttributes; import java.util.Arrays; import java.util.Collections; import java.util.Map; import java.util.Optional; /** * @author Evgen Vidolob */ public abstract class Resource implements IResource, IPathRequestor, ICoreConstants { /* package */ IPath path; /* package */ Workspace workspace; protected Resource(IPath path, Workspace workspace) { this.path = path.removeTrailingSeparator(); this.workspace = workspace; } @Override public void accept(IResourceProxyVisitor visitor, int memberFlags) throws CoreException { accept(visitor, IResource.DEPTH_INFINITE, memberFlags); } @Override public void accept(final IResourceProxyVisitor visitor, final int depth, final int memberFlags) throws CoreException { java.io.File file = workspace.getFile(getFullPath()); int maxDepth = depth == IResource.DEPTH_INFINITE ? Integer.MAX_VALUE : depth; try { final ResourceProxy resourceProxy = new ResourceProxy(); final int workspacePath = workspace.getAbsoluteWorkspacePath().length(); Files.walkFileTree(file.toPath(), Collections.<FileVisitOption>emptySet(), maxDepth, new FileVisitor<java.nio.file.Path>() { @Override public FileVisitResult preVisitDirectory(java.nio.file.Path dir, BasicFileAttributes attrs) throws IOException { return FileVisitResult.CONTINUE; } @Override public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes attrs) throws IOException { FileVisitResult result = FileVisitResult.CONTINUE; try { String string = file.toString(); IPath path = new Path(string.substring(workspacePath)); resourceProxy.info = workspace.getResourceInfo(path); resourceProxy.fullPath = path; boolean shouldContinue = true; switch (depth) { case DEPTH_ZERO : shouldContinue = false; break; case DEPTH_ONE : shouldContinue = !Resource.this.path.equals(path.removeLastSegments(1)); break; case DEPTH_INFINITE : shouldContinue = true; break; } boolean visit = visitor.visit(resourceProxy) && shouldContinue; result = visit? FileVisitResult.CONTINUE : FileVisitResult.SKIP_SUBTREE; } catch (CoreException e) { throw new WrappedRuntimeException(e); } finally { resourceProxy.reset(); } return result; } @Override public FileVisitResult visitFileFailed(java.nio.file.Path file, IOException exc) throws IOException { return FileVisitResult.CONTINUE; } @Override public FileVisitResult postVisitDirectory(java.nio.file.Path dir, IOException exc) throws IOException { return FileVisitResult.CONTINUE; } }); } catch (IOException e) { throw new CoreException(new Status(IStatus.ERROR, ResourcesPlugin.getPluginId(), e.getMessage(), e)); } } @Override public void accept(IResourceVisitor visitor) throws CoreException { accept(visitor, IResource.DEPTH_INFINITE, 0); } @Override public void accept(IResourceVisitor visitor, int depth, boolean includePhantoms) throws CoreException { accept(visitor, depth, includePhantoms ? IContainer.INCLUDE_PHANTOMS : 0); } @Override public void accept(final IResourceVisitor visitor, int depth, int memberFlags) throws CoreException { //use the fast visitor if visiting to infinite depth if (depth == IResource.DEPTH_INFINITE) { accept(new IResourceProxyVisitor() { public boolean visit(IResourceProxy proxy) throws CoreException { return visitor.visit(proxy.requestResource()); } }, memberFlags); return; } // it is invalid to call accept on a phantom when INCLUDE_PHANTOMS is not specified final boolean includePhantoms = (memberFlags & IContainer.INCLUDE_PHANTOMS) != 0; ResourceInfo info = getResourceInfo(includePhantoms, false); int flags = getFlags(info); if ((memberFlags & IContainer.DO_NOT_CHECK_EXISTENCE) == 0) checkAccessible(flags); //check that this resource matches the member flags if (!isMember(flags, memberFlags)) return; // visit this resource if (!visitor.visit(this) || depth == DEPTH_ZERO) return; // get the info again because it might have been changed by the visitor info = getResourceInfo(includePhantoms, false); if (info == null) return; // thread safety: (cache the type to avoid changes -- we might not be inside an operation) int type = info.getType(); if (type == FILE) return; // if we had a gender change we need to fix up the resource before asking for its members IContainer resource = getType() != type ? (IContainer) workspace.newResource(getFullPath(), type) : (IContainer) this; IResource[] members = resource.members(memberFlags); for (int i = 0; i < members.length; i++) members[i].accept(visitor, DEPTH_ZERO, memberFlags | IContainer.DO_NOT_CHECK_EXISTENCE); } public int getFlags(ResourceInfo info) { // return (info == null) ? NULL_FLAG : info.getFlags(); return NULL_FLAG; } /** * Returns whether a resource should be included in a traversal * based on the provided member flags. * * @param flags The resource info flags * @param memberFlags The member flag mask * @return Whether the resource is included */ protected boolean isMember(int flags, int memberFlags) { int excludeMask = 0; if ((memberFlags & IContainer.INCLUDE_PHANTOMS) == 0) excludeMask |= M_PHANTOM; if ((memberFlags & IContainer.INCLUDE_HIDDEN) == 0) excludeMask |= M_HIDDEN; if ((memberFlags & IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS) == 0) excludeMask |= M_TEAM_PRIVATE_MEMBER; if ((memberFlags & IContainer.EXCLUDE_DERIVED) != 0) excludeMask |= M_DERIVED; //the resource is a matching member if it matches none of the exclude flags return flags != NULL_FLAG && (flags & excludeMask) == 0; } @Override public boolean contains(ISchedulingRule rule) { if (this == rule) return true; //must allow notifications to nest in all resource rules if (rule.getClass().equals(WorkManager.NotifyRule.class)) return true; if (rule instanceof MultiRule) { MultiRule multi = (MultiRule) rule; ISchedulingRule[] children = multi.getChildren(); for (int i = 0; i < children.length; i++) if (!contains(children[i])) return false; return true; } if (!(rule instanceof IResource)) return false; IResource resource = (IResource) rule; if (!workspace.equals(resource.getWorkspace())) return false; return path.isPrefixOf(resource.getFullPath()); } @Override public void clearHistory(IProgressMonitor monitor) throws CoreException { throw new UnsupportedOperationException(); } @Override public void copy(IPath destination, boolean force, IProgressMonitor monitor) throws CoreException { throw new UnsupportedOperationException(); } @Override public void copy(IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException { throw new UnsupportedOperationException(); } @Override public void copy(IProjectDescription destDesc, boolean force, IProgressMonitor monitor) throws CoreException { throw new UnsupportedOperationException(); } @Override public void copy(IProjectDescription destDesc, int updateFlags, IProgressMonitor monitor) throws CoreException { throw new UnsupportedOperationException(); } @Override public IResourceProxy createProxy() { throw new UnsupportedOperationException(); } @Override public IMarker createMarker(String type) throws CoreException { throw new UnsupportedOperationException(); } @Override public void delete(boolean force, IProgressMonitor monitor) throws CoreException { delete(force ? IResource.FORCE : IResource.NONE, monitor); } @Override public void delete(int updateFlags, IProgressMonitor monitor) throws CoreException { monitor = Policy.monitorFor(monitor); try { // String message = NLS.bind(Messages.resources_deleting, getFullPath()); // monitor.beginTask("", Policy.totalWork * 1000); //$NON-NLS-1$ // monitor.subTask(message); final ISchedulingRule rule = workspace.getRuleFactory().deleteRule(this); try { workspace.prepareOperation(rule, monitor); // if there is no resource then there is nothing to delete so just return if (!exists()) return; workspace.beginOperation(true); // broadcastPreDeleteEvent(); // when a project is being deleted, flush the build order in case there is a problem // if (this.getType() == IResource.PROJECT) // workspace.flushBuildOrder(); // final IFileStore originalStore = getStore(); // boolean wasLinked = isLinked(); // message = Messages.resources_deleteProblem; // MultiStatus status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IResourceStatus.FAILED_DELETE_LOCAL, message, null); WorkManager workManager = workspace.getWorkManager(); // ResourceTree tree = new ResourceTree(workspace.getFileSystemManager(), workManager.getLock(), status, updateFlags); int depth = 0; try { depth = workManager.beginUnprotected(); workspace.delete(this); // unprotectedDelete(tree, updateFlags, monitor); } finally { workManager.endUnprotected(depth); } if (getType() == ROOT) { // // need to clear out the root info // workspace.getMarkerManager().removeMarkers(this, IResource.DEPTH_ZERO); // getPropertyManager().deleteProperties(this, IResource.DEPTH_ZERO); // getResourceInfo(false, false).clearSessionProperties(); } // Invalidate the tree for further use by clients. // tree.makeInvalid(); // if (!tree.getStatus().isOK()) // throw new ResourceException(tree.getStatus()); //update any aliases of this resource //note that deletion of a linked resource cannot affect other resources // if (!wasLinked) // workspace.getAliasManager().updateAliases(this, originalStore, IResource.DEPTH_INFINITE, monitor); // if (getType() == PROJECT) { // make sure the rule factory is cleared on project deletion // ((Rules) workspace.getRuleFactory()).setRuleFactory((IProject) this, null); // make sure project deletion is remembered // workspace.getSaveManager().requestSnapshot(); // } } catch (OperationCanceledException e) { workspace.getWorkManager().operationCanceled(); throw e; } finally { workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork * 1000)); } } finally { monitor.done(); } } @Override public void deleteMarkers(String type, boolean includeSubtypes, int depth) throws CoreException { throw new UnsupportedOperationException(); } @Override public boolean exists() { return workspace.getFile(path).exists(); } @Override public IMarker findMarker(long id) throws CoreException { throw new UnsupportedOperationException(); } @Override public IMarker[] findMarkers(String type, boolean includeSubtypes, int depth) throws CoreException { // throw new UnsupportedOperationException(); //TODO return new IMarker[0]; } @Override public int findMaxProblemSeverity(String type, boolean includeSubtypes, int depth) throws CoreException { throw new UnsupportedOperationException(); } @Override public String getFileExtension() { String name = getName(); int index = name.lastIndexOf('.'); if (index == -1) return null; if (index == (name.length() - 1)) return ""; //$NON-NLS-1$ return name.substring(index + 1); } @Override public IPath getFullPath() { return path; } @Override public long getLocalTimeStamp() { throw new UnsupportedOperationException(); } @Override public IPath getLocation() { return new Path(workspace.getAbsoluteWorkspacePath() + path.toOSString()); } @Override public URI getLocationURI() { IProject project = getProject(); if (project != null && !project.exists()) return null; return workspace.getFile(getFullPath()).toURI(); } @Override public IMarker getMarker(long id) { throw new UnsupportedOperationException(); } @Override public long getModificationStamp() { return 0; } @Override public String getName() { return path.lastSegment(); } @Override public IContainer getParent() { int segments = path.segmentCount(); //zero and one segments handled by subclasses if (segments < 2) Assert.isLegal(false, path.toString()); if (segments == 2) return workspace.getRoot().getProject(path.segment(0)); IPath parentPath = this.path.removeLastSegments(1); ResourceInfo resourceInfo = workspace.getResourceInfo(parentPath); if (resourceInfo == null) { return null; } return (IContainer)workspace.newResource(parentPath, resourceInfo.getType()); } @Override public Map<QualifiedName, String> getPersistentProperties() throws CoreException { throw new UnsupportedOperationException(); } @Override public String getPersistentProperty(QualifiedName qualifiedName) throws CoreException { throw new UnsupportedOperationException(); } @Override public IProject getProject() { if (this instanceof IProject) { return (IProject)this; } final IProject[] projects = workspace.getRoot().getProjects(); //here we try to found project by path of resources. We will get all projects and select longest path of project that //start with path of resource. final Optional<IProject> max = Arrays.stream(projects) .filter(iProject -> path.toOSString().startsWith(iProject.getFullPath().toOSString())) .max((o1, o2) -> { if (o1.getFullPath().toOSString().length() > o2.getFullPath().toOSString().length()) { return 1; } if (o2.getFullPath().toOSString().length() > o1.getFullPath().toOSString().length()) { return -1; } return 0; }); if(max.isPresent()){ return max.get(); } else { return null; } } @Override public IPath getProjectRelativePath() { return getFullPath().removeFirstSegments(getProject().getFullPath().segmentCount()); } @Override public IPath getRawLocation() { // if (isLinked()) // return FileUtil.toPath(((Project) getProject()).internalGetDescription().getLinkLocationURI(getProjectRelativePath())); // return getLocation(); throw new UnsupportedOperationException(); } @Override public URI getRawLocationURI() { // if (isLinked()) // return ((Project) getProject()).internalGetDescription().getLinkLocationURI(getProjectRelativePath()); // return getLocationURI(); throw new UnsupportedOperationException(); } @Override public ResourceAttributes getResourceAttributes() { // throw new UnsupportedOperationException(); return new ResourceAttributes(); } @Override public Map<QualifiedName, Object> getSessionProperties() throws CoreException { throw new UnsupportedOperationException(); } @Override public Object getSessionProperty(QualifiedName qualifiedName) throws CoreException { throw new UnsupportedOperationException(); } public abstract int getType(); public IWorkspace getWorkspace() { return workspace; } @Override public int hashCode() { // the container may be null if the identified resource // does not exist so don't bother with it in the hash return getFullPath().hashCode(); } /* (non-Javadoc) * @see IResource#isAccessible() */ public boolean isAccessible() { return exists(); } @Override public boolean isDerived() { return isDerived(IResource.NONE); } @Override public boolean isDerived(int options) { // throw new UnsupportedOperationException(); return true; } @Override public boolean isHidden() { throw new UnsupportedOperationException(); } @Override public boolean isHidden(int options) { throw new UnsupportedOperationException(); } @Override public boolean isLinked() { return isLinked(NONE); } @Override public boolean isLocal(int depth) { throw new UnsupportedOperationException(); } @Override public boolean isVirtual() { throw new UnsupportedOperationException(); } @Override public boolean isLinked(int options) { // throw new UnsupportedOperationException(); return false; } @Override public boolean isPhantom() { // throw new UnsupportedOperationException(); return false; } @Override public boolean isReadOnly() { // throw new UnsupportedOperationException(); return false; } @Override public boolean isSynchronized(int depth) { // throw new UnsupportedOperationException(); return true; } @Override public boolean isTeamPrivateMember() { throw new UnsupportedOperationException(); } @Override public boolean isTeamPrivateMember(int options) { throw new UnsupportedOperationException(); } @Override public void move(IPath destination, boolean force, IProgressMonitor monitor) throws CoreException { move(destination, force ? IResource.FORCE : IResource.NONE, monitor); } @Override public void move(IPath destination, int updateFlags, IProgressMonitor monitor) throws CoreException { monitor = Policy.monitorFor(monitor); try{ String message = NLS.bind(Messages.resources_moving, getFullPath()); monitor.beginTask(message, Policy.totalWork); Policy.checkCanceled(monitor); destination = makePathAbsolute(destination); // checkValidPath(destination, getType(), false); Resource destResource = workspace.newResource(destination, getType()); final ISchedulingRule rule = workspace.getRuleFactory().moveRule(this, destResource); WorkManager workManager = workspace.getWorkManager(); try { workspace.prepareOperation(rule, monitor); workspace.beginOperation(true); int depth = 0; try { depth = workManager.beginUnprotected(); unprotectedMove(destResource, updateFlags, monitor); } finally { workManager.endUnprotected(depth); } } finally { workspace.endOperation(rule, true, Policy.subMonitorFor(monitor, Policy.endOpWork)); } } finally { monitor.done(); } } protected IPath makePathAbsolute(IPath target) { if (target.isAbsolute()) return target; return getParent().getFullPath().append(target); } /** * Calls the move/delete hook to perform the move. Since this method calls * client code, it is run "unprotected", so the workspace lock is not held. * Returns true if resources were actually moved, and false otherwise. */ private boolean unprotectedMove(final IResource destination, int updateFlags, IProgressMonitor monitor) throws CoreException, ResourceException { // IMoveDeleteHook hook = workspace.getMoveDeleteHook(); switch (getType()) { case IResource.FILE : // if (!hook.moveFile(tree, (IFile) this, (IFile) destination, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork / 2))) workspace.standardMoveFile((IFile) this, (IFile) destination, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork)); break; case IResource.FOLDER : // if (!hook.moveFolder(tree, (IFolder) this, (IFolder) destination, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork / 2))) workspace.standardMoveFolder((IFolder) this, (IFolder) destination, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork)); break; case IResource.PROJECT : IProject project = (IProject) this; // if there is no change in name, there is nothing to do so return. if (getName().equals(destination.getName())) return false; IProjectDescription description = project.getDescription(); description.setName(destination.getName()); // if (!hook.moveProject(tree, project, description, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork / 2))) workspace.standardMoveProject(project, description, updateFlags, Policy.subMonitorFor(monitor, Policy.opWork)); break; case IResource.ROOT : String msg = Messages.resources_moveRoot; throw new ResourceException(new ResourceStatus(IResourceStatus.INVALID_VALUE, getFullPath(), msg)); } return true; } @Override public void move(IProjectDescription description, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException { throw new UnsupportedOperationException(); } @Override public void move(IProjectDescription description, int updateFlags, IProgressMonitor monitor) throws CoreException { throw new UnsupportedOperationException(); } @Override public void refreshLocal(int depth, IProgressMonitor monitor) throws CoreException { // throw new UnsupportedOperationException(); } @Override public void revertModificationStamp(long value) throws CoreException { // throw new UnsupportedOperationException(); } @Override public IPath requestPath() { return getFullPath(); } @Override public String requestName() { return getName(); } @Override public void setDerived(boolean isDerived) throws CoreException { throw new UnsupportedOperationException(); } @Override public void setDerived(boolean isDerived, IProgressMonitor monitor) throws CoreException { throw new UnsupportedOperationException(); } @Override public void setHidden(boolean isHidden) throws CoreException { throw new UnsupportedOperationException(); } @Override public void setLocal(boolean flag, int depth, IProgressMonitor monitor) throws CoreException { throw new UnsupportedOperationException(); } @Override public long setLocalTimeStamp(long value) throws CoreException { // throw new UnsupportedOperationException(); return value; } @Override public void setPersistentProperty(QualifiedName key, String value) throws CoreException { throw new UnsupportedOperationException(); } @Override public void setReadOnly(boolean readonly) { throw new UnsupportedOperationException(); } @Override public void setResourceAttributes(ResourceAttributes attributes) throws CoreException { throw new UnsupportedOperationException(); } @Override public void setSessionProperty(QualifiedName key, Object value) throws CoreException { throw new UnsupportedOperationException(); } @Override public void setTeamPrivateMember(boolean isTeamPrivate) throws CoreException { throw new UnsupportedOperationException(); } public String getTypeString() { switch (getType()) { case FILE : return "L"; //$NON-NLS-1$ case FOLDER : return "F"; //$NON-NLS-1$ case PROJECT : return "P"; //$NON-NLS-1$ case ROOT : return "R"; //$NON-NLS-1$ } return ""; //$NON-NLS-1$ } @Override public Object getAdapter(Class aClass) { throw new UnsupportedOperationException(); } /* (non-Javadoc) * @see IProject#delete(boolean, boolean, IProgressMonitor) * @see IWorkspaceRoot#delete(boolean, boolean, IProgressMonitor) * N.B. This is not an IResource method! */ public void delete(boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException { int updateFlags = force ? IResource.FORCE : IResource.NONE; updateFlags |= keepHistory ? IResource.KEEP_HISTORY : IResource.NONE; delete(updateFlags, monitor); } @Override public boolean isConflicting(ISchedulingRule rule) { if (this == rule) return true; //must not schedule at same time as notification if (rule.getClass().equals(WorkManager.NotifyRule.class)) return true; if (rule instanceof MultiRule) { MultiRule multi = (MultiRule) rule; ISchedulingRule[] children = multi.getChildren(); for (int i = 0; i < children.length; i++) if (isConflicting(children[i])) return true; return false; } if (!(rule instanceof IResource)) return false; IResource resource = (IResource) rule; if (!workspace.equals(resource.getWorkspace())) return false; IPath otherPath = resource.getFullPath(); return path.isPrefixOf(otherPath) || otherPath.isPrefixOf(path); } @Override public void touch(IProgressMonitor iProgressMonitor) throws CoreException { // do nothing //todo } /* (non-Javadoc) * @see IResource#getPathVariableManager() */ public IPathVariableManager getPathVariableManager() { // if (getProject() == null) // return workspace.getPathVariableManager(); // return new ProjectPathVariableManager(this); throw new UnsupportedOperationException(); } /* (non-Javadoc) * @see Object#toString() */ @Override public String toString() { return getTypeString() + getFullPath().toString(); } /* (non-Javadoc) * @see IResource#equals(Object) */ @Override public boolean equals(Object target) { if (this == target) return true; if (!(target instanceof Resource)) return false; Resource resource = (Resource) target; return getType() == resource.getType() && path.equals(resource.path) && workspace.equals(resource.workspace); } /* (non-Javadoc) * @see IFile#move(IPath, boolean, boolean, IProgressMonitor) * @see IFolder#move(IPath, boolean, boolean, IProgressMonitor) */ public void move(IPath destination, boolean force, boolean keepHistory, IProgressMonitor monitor) throws CoreException { int updateFlags = force ? IResource.FORCE : IResource.NONE; updateFlags |= keepHistory ? IResource.KEEP_HISTORY : IResource.NONE; move(destination, updateFlags, monitor); } /* (non-Javadoc) * @see org.eclipse.core.resources.IFolder#createLink(IPath, int, IProgressMonitor) * @see org.eclipse.core.resources.IFile#createLink(IPath, int, IProgressMonitor) */ public void createLink(IPath localLocation, int updateFlags, IProgressMonitor monitor) throws CoreException { // Assert.isNotNull(localLocation); // createLink(URIUtil.toURI(localLocation), updateFlags, monitor); throw new UnsupportedOperationException(); } /* (non-Javadoc) * @see org.eclipse.core.resources.IFolder#createLink(URI, int, IProgressMonitor) * @see org.eclipse.core.resources.IFile#createLink(URI, int, IProgressMonitor) */ public void createLink(URI localLocation, int updateFlags, IProgressMonitor monitor) throws CoreException { throw new UnsupportedOperationException(); } /** * Returns the resource info. Returns null if the resource doesn't exist. * If the phantom flag is true, phantom resources are considered. * If the mutable flag is true, a mutable info is returned. */ public ResourceInfo getResourceInfo(boolean phantom, boolean mutable) { return workspace.getResourceInfo(getFullPath()); } public void checkAccessible(int flags) throws CoreException { checkExists(flags, true); } /** * Checks that this resource exists. * If checkType is true, the type of this resource and the one in the tree must match. * * @exception CoreException if this resource does not exist */ public void checkExists(int flags, boolean checkType) throws CoreException { if (!exists(flags, checkType)) { String message = NLS.bind(Messages.resources_mustExist, getFullPath()); throw new ResourceException(IResourceStatus.RESOURCE_NOT_FOUND, getFullPath(), message, null); } } public boolean exists(int flags, boolean checkType) { // return flags != NULL_FLAG && !(checkType && ResourceInfo.getType(flags) != getType()); return true; } }