| /******************************************************************************* |
| * Copyright (c) 2000, 2015 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Serge Beauchamp (Freescale Semiconductor) - [229633] Group and Project Path Variable Support |
| *******************************************************************************/ |
| package org.eclipse.core.internal.resources; |
| |
| import java.net.URI; |
| import org.eclipse.core.filesystem.IFileInfo; |
| import org.eclipse.core.filesystem.IFileStore; |
| import org.eclipse.core.internal.utils.Messages; |
| import org.eclipse.core.internal.utils.Policy; |
| import org.eclipse.core.resources.*; |
| import org.eclipse.core.runtime.*; |
| import org.eclipse.core.runtime.jobs.ISchedulingRule; |
| import org.eclipse.osgi.util.NLS; |
| |
| public class Folder extends Container implements IFolder { |
| protected Folder(IPath path, Workspace container) { |
| super(path, container); |
| } |
| |
| protected void assertCreateRequirements(IFileStore store, IFileInfo localInfo, int updateFlags) throws CoreException { |
| checkDoesNotExist(); |
| Container parent = (Container) getParent(); |
| ResourceInfo info = parent.getResourceInfo(false, false); |
| parent.checkAccessible(getFlags(info)); |
| checkValidGroupContainer(parent, false, false); |
| |
| final boolean force = (updateFlags & IResource.FORCE) != 0; |
| if (!force && localInfo.exists()) { |
| //return an appropriate error message for case variant collisions |
| if (!Workspace.caseSensitive) { |
| String name = getLocalManager().getLocalName(store); |
| if (name != null && !store.getName().equals(name)) { |
| String msg = NLS.bind(Messages.resources_existsLocalDifferentCase, new Path(store.toString()).removeLastSegments(1).append(name).toOSString()); |
| throw new ResourceException(IResourceStatus.CASE_VARIANT_EXISTS, getFullPath(), msg, null); |
| } |
| } |
| String msg = NLS.bind(Messages.resources_fileExists, store.toString()); |
| throw new ResourceException(IResourceStatus.FAILED_WRITE_LOCAL, getFullPath(), msg, null); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * Changes this folder to be a file in the resource tree and returns the newly |
| * created file. All related properties are deleted. It is assumed that on |
| * disk the resource is already a file so no action is taken to delete the disk |
| * contents. |
| * <p> |
| * <b>This method is for the exclusive use of the local refresh mechanism</b> |
| * |
| * @see org.eclipse.core.internal.localstore.RefreshLocalVisitor#folderToFile(UnifiedTreeNode, Resource) |
| */ |
| public IFile changeToFile() throws CoreException { |
| getPropertyManager().deleteProperties(this, IResource.DEPTH_INFINITE); |
| IFile result = workspace.getRoot().getFile(path); |
| if (isLinked()) { |
| URI location = getRawLocationURI(); |
| delete(IResource.NONE, null); |
| result.createLink(location, IResource.ALLOW_MISSING_LOCAL, null); |
| } else { |
| workspace.deleteResource(this); |
| workspace.createResource(result, false); |
| } |
| return result; |
| } |
| |
| @Override |
| public void create(int updateFlags, boolean local, IProgressMonitor monitor) throws CoreException { |
| if ((updateFlags & IResource.VIRTUAL) == IResource.VIRTUAL) { |
| createLink(LinkDescription.VIRTUAL_LOCATION, updateFlags, monitor); |
| return; |
| } |
| final boolean force = (updateFlags & IResource.FORCE) != 0; |
| String message = NLS.bind(Messages.resources_creating, getFullPath()); |
| SubMonitor subMonitor = SubMonitor.convert(monitor, message, 100); |
| checkValidPath(path, FOLDER, true); |
| final ISchedulingRule rule = workspace.getRuleFactory().createRule(this); |
| try { |
| workspace.prepareOperation(rule, subMonitor.newChild(1)); |
| IFileStore store = getStore(); |
| IFileInfo localInfo = store.fetchInfo(); |
| assertCreateRequirements(store, localInfo, updateFlags); |
| workspace.beginOperation(true); |
| if (force && !Workspace.caseSensitive && localInfo.exists()) { |
| String name = getLocalManager().getLocalName(store); |
| if (name == null || localInfo.getName().equals(name)) { |
| delete(true, null); |
| } else { |
| // The file system is not case sensitive and a case variant exists at this |
| // location |
| String msg = NLS.bind(Messages.resources_existsLocalDifferentCase, |
| new Path(store.toString()).removeLastSegments(1).append(name).toOSString()); |
| throw new ResourceException(IResourceStatus.CASE_VARIANT_EXISTS, getFullPath(), msg, null); |
| } |
| } |
| internalCreate(updateFlags, local, subMonitor.newChild(98)); |
| workspace.getAliasManager().updateAliases(this, getStore(), IResource.DEPTH_ZERO, subMonitor.newChild(1)); |
| } catch (OperationCanceledException e) { |
| workspace.getWorkManager().operationCanceled(); |
| throw e; |
| } finally { |
| subMonitor.done(); |
| workspace.endOperation(rule, true); |
| } |
| } |
| |
| @Override |
| public void create(boolean force, boolean local, IProgressMonitor monitor) throws CoreException { |
| // funnel all operations to central method |
| create((force ? IResource.FORCE : IResource.NONE), local, monitor); |
| } |
| |
| /** |
| * Ensures that this folder exists in the workspace. This is similar in |
| * concept to mkdirs but it does not work on projects. |
| * If this folder is created, it will be marked as being local. |
| */ |
| public void ensureExists(IProgressMonitor monitor) throws CoreException { |
| ResourceInfo info = getResourceInfo(false, false); |
| int flags = getFlags(info); |
| if (exists(flags, true)) |
| return; |
| if (exists(flags, false)) { |
| String message = NLS.bind(Messages.resources_folderOverFile, getFullPath()); |
| throw new ResourceException(IResourceStatus.RESOURCE_WRONG_TYPE, getFullPath(), message, null); |
| } |
| Container parent = (Container) getParent(); |
| if (parent.getType() == PROJECT) { |
| info = parent.getResourceInfo(false, false); |
| parent.checkExists(getFlags(info), true); |
| } else |
| ((Folder) parent).ensureExists(monitor); |
| if (getType() == FOLDER && isUnderVirtual()) |
| create(IResource.VIRTUAL | IResource.FORCE, true, monitor); |
| else |
| internalCreate(IResource.FORCE, true, monitor); |
| } |
| |
| @Override |
| public String getDefaultCharset(boolean checkImplicit) { |
| // non-existing resources default to parent's charset |
| if (!exists()) |
| return checkImplicit ? workspace.getCharsetManager().getCharsetFor(getFullPath().removeLastSegments(1), true) : null; |
| return workspace.getCharsetManager().getCharsetFor(getFullPath(), checkImplicit); |
| } |
| |
| @Override |
| public int getType() { |
| return FOLDER; |
| } |
| |
| public void internalCreate(int updateFlags, boolean local, IProgressMonitor monitor) throws CoreException { |
| monitor = Policy.monitorFor(monitor); |
| try { |
| String message = NLS.bind(Messages.resources_creating, getFullPath()); |
| monitor.beginTask(message, Policy.totalWork); |
| workspace.createResource(this, updateFlags); |
| if (local) { |
| try { |
| final boolean force = (updateFlags & IResource.FORCE) != 0; |
| getLocalManager().write(this, force, Policy.subMonitorFor(monitor, Policy.totalWork)); |
| } catch (CoreException e) { |
| // a problem happened creating the folder on disk, so delete from the workspace |
| workspace.deleteResource(this); |
| throw e; // rethrow |
| } |
| } |
| internalSetLocal(local, DEPTH_ZERO); |
| if (!local) |
| getResourceInfo(true, true).clearModificationStamp(); |
| } finally { |
| monitor.done(); |
| } |
| } |
| } |