| /******************************************************************************* |
| * 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.ArrayList; |
| |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.dltk.core.IModelElement; |
| import org.eclipse.dltk.core.IModelStatus; |
| import org.eclipse.dltk.core.IModelStatusConstants; |
| import org.eclipse.dltk.core.IProjectFragment; |
| import org.eclipse.dltk.core.IScriptFolder; |
| import org.eclipse.dltk.core.ModelException; |
| import org.eclipse.dltk.internal.core.util.Messages; |
| import org.eclipse.dltk.internal.core.util.Util; |
| |
| /** |
| * This operation creates a new script folder under a given project fragment. |
| * The following must be specified: |
| * <ul> |
| * <li>the project fragment |
| * <li>the folder name |
| * </ul> |
| * <p> |
| * Any needed folders are created. If the script folder already exists, this |
| * operation has no effect. The result elements include the |
| * <code>IScriptFolder</code> created and any side effect script folders that |
| * were created. |
| * |
| * <p> |
| * NOTE: A default script folder exists by default for a given project fragment. |
| * |
| * <p> |
| * Possible exception conditions: |
| * <ul> |
| * <li>project fragment is read-only |
| * <li>script folder's name is taken by a simple (non-folder) resource |
| * </ul> |
| */ |
| public class CreateScriptFolderOperation extends ModelOperation { |
| /** |
| * The fully qualified, folder name. |
| */ |
| protected IPath pkgName; |
| |
| /** |
| * When executed, this operation will create a script folder with the given |
| * name under the given project fragment. The slash-separated name is broken |
| * into segments. Intermediate folders are created as required for each |
| * segment. If the folders already exist, this operation has no effect. |
| */ |
| public CreateScriptFolderOperation(IProjectFragment parentElement, |
| String packageName, boolean force) { |
| super(null, new IModelElement[] { parentElement }, force); |
| this.pkgName = packageName == null ? null : new Path(packageName); |
| } |
| |
| /** |
| * Execute the operation - creates the new script folder and any side effect |
| * folders. |
| * |
| * @exception ModelException |
| * if the operation is unable to complete |
| */ |
| @Override |
| protected void executeOperation() throws ModelException { |
| ModelElementDelta delta = null; |
| IProjectFragment root = (IProjectFragment) getParentElement(); |
| beginTask(Messages.operation_createScriptFolderProgress, |
| this.pkgName.segmentCount()); |
| IContainer parentFolder = (IContainer) root.getResource(); |
| IPath sideEffectPackageName = Path.EMPTY; |
| ArrayList<IScriptFolder> results = new ArrayList<>( |
| this.pkgName.segmentCount()); |
| int i; |
| for (i = 0; i < this.pkgName.segmentCount(); i++) { |
| String subFolderName = this.pkgName.segment(i); |
| sideEffectPackageName = sideEffectPackageName.append(subFolderName); |
| IResource subFolder = parentFolder.findMember(subFolderName); |
| if (subFolder == null) { |
| createFolder(parentFolder, subFolderName, force); |
| parentFolder = parentFolder.getFolder(new Path(subFolderName)); |
| IScriptFolder addedFrag = root |
| .getScriptFolder(sideEffectPackageName); |
| if (!Util.isExcluded(parentFolder, root)) { |
| if (delta == null) { |
| delta = newModelElementDelta(); |
| } |
| delta.added(addedFrag); |
| } |
| results.add(addedFrag); |
| } else { |
| parentFolder = (IContainer) subFolder; |
| } |
| worked(1); |
| } |
| if (results.size() > 0) { |
| this.resultElements = new IModelElement[results.size()]; |
| results.toArray(this.resultElements); |
| if (delta != null) { |
| addDelta(delta); |
| } |
| } |
| done(); |
| } |
| |
| /** |
| * Possible failures: |
| * <ul> |
| * <li>NO_ELEMENTS_TO_PROCESS - the root supplied to the operation is |
| * <code>null</code>. |
| * <li>INVALID_NAME - the name provided to the operation is |
| * <code>null</code> or is not a valid script folder name. |
| * <li>READ_ONLY - the root provided to this operation is read only. |
| * <li>NAME_COLLISION - there is a pre-existing resource (file) with the |
| * same name as a folder in the script folder's hierarchy. |
| * <li>ELEMENT_NOT_PRESENT - the underlying resource for the root is missing |
| * </ul> |
| * |
| * @see IScriptModelStatus |
| * @see ScriptConventions |
| */ |
| @Override |
| public IModelStatus verify() { |
| if (getParentElement() == null) { |
| return new ModelStatus( |
| IModelStatusConstants.NO_ELEMENTS_TO_PROCESS); |
| } |
| IPath packageName = this.pkgName == null ? null |
| : this.pkgName.append("."); //$NON-NLS-1$ |
| String packageNameValue = null; |
| if (packageName != null) { |
| packageNameValue = packageName.toOSString(); |
| } |
| if (this.pkgName == null || (this.pkgName.segmentCount() > 0 |
| && !Util.isValidFolderNameForPackage( |
| (IContainer) getParentElement().getResource(), |
| packageName.toString()))) { |
| return new ModelStatus(IModelStatusConstants.INVALID_NAME, |
| packageNameValue); |
| } |
| IProjectFragment root = (IProjectFragment) getParentElement(); |
| if (root.isReadOnly()) { |
| return new ModelStatus(IModelStatusConstants.READ_ONLY, root); |
| } |
| IContainer parentFolder = (IContainer) root.getResource(); |
| int i; |
| for (i = 0; i < this.pkgName.segmentCount(); i++) { |
| IResource subFolder = parentFolder |
| .findMember(this.pkgName.segment(i)); |
| if (subFolder != null) { |
| if (subFolder.getType() != IResource.FOLDER) { |
| return new ModelStatus(IModelStatusConstants.NAME_COLLISION, |
| Messages.bind(Messages.status_nameCollision, |
| subFolder.getFullPath().toString())); |
| } |
| parentFolder = (IContainer) subFolder; |
| } |
| } |
| return ModelStatus.VERIFIED_OK; |
| } |
| } |