/******************************************************************************* * Copyright (c) 2005 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 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.buckminster.pde.internal.dialogs; import org.eclipse.buckminster.pde.PDEPlugin; import org.eclipse.buckminster.runtime.MonitorUtils; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; 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.Status; import org.eclipse.osgi.util.NLS; /** * For creating folder resources that currently do not exist, along a given * workspace path. * <p> * This class may be instantiated; it is not intended to be subclassed. * </p> * <p> * Example usage: * * <pre> * ContainerGenerator gen = new ContainerGenerator(new Path("/A/B")); * IContainer res = null; * try { * res = gen.getContainer(monitor); // creates project A and folder B if * // required * } catch (CoreException e) { * // handle failure * } catch (OperationCanceledException e) { * // handle cancelation * } * </pre> * * </p> */ public class ContainerGenerator { private IPath containerFullPath; private IContainer container; /** * Creates a generator for the container resource (folder or project) at the * given workspace path. Assumes the path has already been validated. * <p> * Call <code>getContainer</code> to create any missing resources along the * path. * </p> * * @param containerPath * the workspace path of the container */ public ContainerGenerator(IPath containerPath) { super(); this.containerFullPath = containerPath; } /** * Ensures that this generator's container resource exists. Creates any * missing resource containers along the path; does nothing if the container * resource already exists. * <p> * Note: This method should be called within a workspace modify operation * since it may create resources. * </p> * * @param monitor * a progress monitor * @return the container resource * @exception CoreException * if the operation fails * @exception OperationCanceledException * if the operation is canceled */ public IContainer generateContainer(IProgressMonitor topMonitor) throws CoreException { ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { @Override public void run(IProgressMonitor monitor) throws CoreException { monitor.beginTask("IDEWorkbenchMessages.ContainerGenerator_progressMessage", 1000 * containerFullPath //$NON-NLS-1$ .segmentCount()); if (container != null) return; // Does the container exist already? IWorkspaceRoot root = getWorkspaceRoot(); container = (IContainer) root.findMember(containerFullPath); if (container != null) return; // Create the container for the given path container = root; for (int i = 0; i < containerFullPath.segmentCount(); i++) { String currentSegment = containerFullPath.segment(i); IResource resource = container.findMember(currentSegment); if (resource != null) { if (resource.getType() == IResource.FILE) { String msg = NLS.bind("IDEWorkbenchMessages.ContainerGenerator_pathOccupied", resource //$NON-NLS-1$ .getFullPath().makeRelative()); throw new CoreException(new Status(IStatus.ERROR, PDEPlugin.getPluginId(), 1, msg, null)); } container = (IContainer) resource; MonitorUtils.worked(monitor, 1000); } else { if (i == 0) { IProject projectHandle = createProjectHandle(root, currentSegment); container = createProject(projectHandle, MonitorUtils.subMonitor(monitor, 1000)); } else { IFolder folderHandle = createFolderHandle(container, currentSegment); container = createFolder(folderHandle, MonitorUtils.subMonitor(monitor, 1000)); } } } } }, null, IResource.NONE, topMonitor); return container; } /** * Creates a folder resource for the given folder handle. * * @param folderHandle * the handle to create a folder resource * @param monitor * the progress monitor to show visual progress * @return the folder handle (<code>folderHandle</code>) * @throws CoreException * if the operation fails */ private IFolder createFolder(IFolder folderHandle, IProgressMonitor monitor) throws CoreException { folderHandle.create(false, true, monitor); MonitorUtils.testCancelStatus(monitor); return folderHandle; } /** * Creates a folder resource handle for the folder with the given name. This * method does not create the folder resource; this is the responsibility of * <code>createFolder</code>. * * @param container * the resource container * @param folderName * the name of the folder * @return the new folder resource handle */ private IFolder createFolderHandle(IContainer resourceContainer, String folderName) { return resourceContainer.getFolder(new Path(folderName)); } /** * Creates a project resource for the given project handle. * * @param projectHandle * the handle to create a project resource * @param monitor * the progress monitor to show visual progress * @return the project handle (<code>projectHandle</code>) * @exception CoreException * if the operation fails * @exception OperationCanceledException * if the operation is canceled */ private IProject createProject(IProject projectHandle, IProgressMonitor monitor) throws CoreException { try { monitor.beginTask("", 2000);//$NON-NLS-1$ projectHandle.create(MonitorUtils.subMonitor(monitor, 1000)); projectHandle.open(MonitorUtils.subMonitor(monitor, 1000)); } finally { monitor.done(); } return projectHandle; } /** * Creates a project resource handle for the project with the given name. * This method does not create the project resource; this is the * responsibility of <code>createProject</code>. * * @param root * the workspace root resource * @param projectName * the name of the project * @return the new project resource handle */ private IProject createProjectHandle(IWorkspaceRoot root, String projectName) { return root.getProject(projectName); } /** * Returns the workspace root resource handle. * * @return the workspace root resource handle */ private IWorkspaceRoot getWorkspaceRoot() { return ResourcesPlugin.getWorkspace().getRoot(); } }