/*******************************************************************************
* Copyright (c) 2005, 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.erlide.project.buildpath;
import java.util.Collection;
import org.eclipse.core.runtime.IPath;
import com.google.common.collect.Lists;
public class BuildpathUtils {
/**
* Name of the User Library Container id.
*/
public static final String USER_LIBRARY_CONTAINER_ID = "org.erlide.USER_LIBRARY"; //$NON-NLS-1$
private static final Collection<IPath> INCLUDE_ALL = Lists.newArrayList();
private static final Collection<IPath> EXCLUDE_NONE = Lists.newArrayList();
private static final BuildpathAttributes NO_EXTRA_ATTRIBUTES = new BuildpathAttributes();
private static final BuildpathAttributes OPTIONAL_ATTRIBUTES = new BuildpathAttributes(
"optional", "true");
// /**
// * Creates and returns a new buildpath entry of kind
// <code>CPE_SOURCE</code>
// * for the project's source folder identified by the given absolute
// * workspace-relative path using the given inclusion and exclusion
// patterns
// * to determine which source files are included, and the given output path
// * to control the output location of generated files.
// * <p>
// * The source folder is referred to using an absolute path relative to the
// * workspace root, e.g. <code>/Project/src</code>. A project's source
// * folders are located with that project. That is, a source buildpath
// entry
// * specifying the path <code>/P1/src</code> is only usable for project
// * <code>P1</code>.
// * </p>
// * <p>
// * The inclusion patterns determines the initial set of source files that
// * are to be included; the exclusion patterns are then used to reduce this
// * set. When no inclusion patterns are specified, the initial file set
// * includes all relevent files in the resource tree rooted at the source
// * entry's path. On the other hand, specifying one or more inclusion
// * patterns means that all <b>and only</b> files matching at least one of
// * the specified patterns are to be included. If exclusion patterns are
// * specified, the initial set of files is then reduced by eliminating
// files
// * matched by at least one of the exclusion patterns. Inclusion and
// * exclusion patterns look like relative file paths with wildcards and are
// * interpreted relative to the source entry's path. File patterns are
// * case-sensitive can contain '**', '*' or '?' wildcards (see
// * {@link IBuildpathEntry#getExclusionPatterns()} for the full description
// * of their syntax and semantics). The resulting set of files are included
// * in the corresponding package fragment root; all package fragments
// within
// * the root will have children of type <code>ISourceModule</code>.
// * </p>
// * <p>
// * For example, if the source folder path is <code>/Project/src</code>,
// * there are no inclusion filters, and the exclusion pattern is
// * <code>com/xyz/tests/**</code>, then source files like
// * <code>/Project/src/com/xyz/Foo.java</code> and
// * <code>/Project/src/com/xyz/utils/Bar.java</code> would be included,
// * whereas <code>/Project/src/com/xyz/tests/T1.java</code> and
// * <code>/Project/src/com/xyz/tests/quick/T2.java</code> would be
// excluded.
// * </p>
// * <p>
// * Additionally, a source entry can be associated with a specific output
// * location. By doing so, the script builder will ensure that the
// generated
// * ".class" files will be issued inside this output location, as opposed
// to
// * be generated into the project default output location (when output
// * location is <code>null</code>). Note that multiple source entries may
// * target the same output location. The output location is referred to
// using
// * an absolute path relative to the workspace root, e.g.
// * <code>"/Project/bin"</code>, it must be located inside the same project
// * as the source folder.
// * </p>
// * <p>
// * Also note that all sources/binaries inside a project are contributed as
// a
// * whole through a project entry (see
// * <code>BuildpathUtils.newProjectEntry</code> ). Particular source
// entries
// * cannot be selectively exported.
// * </p>
// * <p>
// * The <code>extraAttributes</code> list contains name/value pairs that
// must
// * be persisted with this entry. If no extra attributes are provided, an
// * empty array must be passed in.<br>
// * Note that this list should not contain any duplicate name.
// * </p>
// *
// * @param path
// * the absolute workspace-relative path of a source folder
// * @param inclusionPatterns
// * the possibly empty list of inclusion patterns represented as
// * relative paths
// * @param exclusionPatterns
// * the possibly empty list of exclusion patterns represented as
// * relative paths
// * @param specificOutputLocation
// * the specific output location for this source entry (
// * <code>null</code> if using project default ouput location)
// * @param extraAttributes
// * the possibly empty list of extra attributes to persist with
// * this entry
// * @return a new source buildpath entry with the given exclusion patterns
// * @see IBuildpoathEntry#getInclusionPatterns()
// * @see IBuildpoathEntry#getExclusionPatterns()
// * @see IBuildpoathEntry#getOutputLocation()
// *
// */
// public static IBuildpathEntry newSourceEntry(final IPath path,
// final Collection<IPath> inclusionPatterns,
// final Collection<IPath> exclusionPatterns,
// final BuildpathAttributes extraAttributes) {
//
// Assert.isNotNull(path, "Source path cannot be null"); //$NON-NLS-1$
// if (!path.isAbsolute()) {
// Assert.isTrue(false, "Path for IBuildpathEntry must be absolute"); //$NON-NLS-1$
// }
// if (exclusionPatterns == null) {
// Assert.isTrue(false, "Exclusion pattern set cannot be null"); //$NON-NLS-1$
// }
// if (inclusionPatterns == null) {
// Assert.isTrue(false, "Inclusion pattern set cannot be null"); //$NON-NLS-1$
// }
//
// return new BuildpathFolder(IProjectFragment.K_SOURCE,
// IBuildpathEntry.BPE_SOURCE, path, false, inclusionPatterns,
// exclusionPatterns, null, false, extraAttributes, false);
// }
//
// /**
// * Creates and returns a new buildpath entry of kind
// * <code>CPE_PROJECT</code> for the project identified by the given
// absolute
// * path.
// * <p>
// * A project entry is used to denote a prerequisite project on a
// buildpath.
// * The referenced project will be contributed as a whole, either as
// sources
// * (in the script Model, it contributes all its package fragment roots) or
// * as binaries (when building, it contributes its whole output location).
// * </p>
// * <p>
// * A project reference allows to indirect through another project,
// * independently from its internal layout.
// * </p>
// * <p>
// * The prerequisite project is referred to using an absolute path relative
// * to the workspace root.
// * </p>
// * <p>
// * The access rules determine the set of accessible source files in the
// * project. If the list of access rules is empty then all files in this
// * project are accessible. See {@link IAccessRule} for a detailed
// * description of access rules.
// * </p>
// * <p>
// * The <code>combineAccessRules</code> flag indicates whether access rules
// * of one (or more) exported entry of the project should be combined with
// * the given access rules. If they should be combined, the given access
// * rules are considered first, then the entry's access rules are
// considered.
// * </p>
// * <p>
// * The <code>extraAttributes</code> list contains name/value pairs that
// must
// * be persisted with this entry. If no extra attributes are provided, an
// * empty array must be passed in.<br>
// * Note that this list should not contain any duplicate name.
// * </p>
// * <p>
// * The <code>isExported</code> flag indicates whether this entry is
// * contributed to dependent projects. If not exported, dependent projects
// * will not see any of the classes from this entry. If exported, dependent
// * projects will concatenate the accessible files patterns of this entry
// * with the accessible files patterns of the projects, and they will
// * concatenate the non accessible files patterns of this entry with the
// non
// * accessible files patterns of the project.
// * </p>
// *
// * @param path
// * the absolute path of the prerequisite project
// * @param accessRules
// * the possibly empty list of access rules for this entry
// * @param combineAccessRules
// * whether the access rules of the project's exported entries
// * should be combined with the given access rules
// * @param extraAttributes
// * the possibly empty list of extra attributes to persist with
// * this entry
// * @param isExported
// * indicates whether this entry is contributed to dependent
// * projects in addition to the output location
// * @return a new project buildpath entry
// *
// */
// public static IBuildpathEntry newProjectEntry(final IPath path,
// final BuildpathAttributes extraAttributes, final boolean isExported) {
//
// if (!path.isAbsolute()) {
// Assert.isTrue(false, "Path for IBuildpathEntry must be absolute"); //$NON-NLS-1$
// }
//
// return new BuildpathEntry(IProjectFragment.K_SOURCE,
// IBuildpathEntry.BPE_PROJECT, path, isExported, INCLUDE_ALL, // inclusion
// // patterns
// EXCLUDE_NONE, // exclusion patterns
// extraAttributes, false);
// }
//
// /**
// * Creates and returns a new buildpath entry of kind
// * <code>CPE_CONTAINER</code> for the given path. This method is fully
// * equivalent to calling {@link #newContainerEntry(IPath,
// * Collection<IBuildpathAttribute>, boolean)
// * newContainerEntry(containerPath, new IAccessRule[0], new
// * IBuildpathAttribute[0], isExported)}.
// *
// * @param containerPath
// * the path identifying the container, it must be formed of at
// * least one segment (ID+hints)
// * @param isExported
// * a boolean indicating whether this entry is contributed to
// * dependent projects in addition to the output location
// * @return a new container buildpath entry
// *
// * @see BuildpathUtils#getBuildpathContainer(IPath, IErlangProject)
// * @see BuildpathUtils#setBuildpathContainer(IPath, IErlangProject[],
// * IBuildpathContainer[], IProgressMonitor)
// *
// */
// public static IBuildpathEntry newContainerEntry(final IPath
// containerPath,
// final boolean isExported) {
// return newContainerEntry(containerPath, NO_EXTRA_ATTRIBUTES, isExported);
// }
//
// /**
// * Creates and returns a new buildpath entry of kind
// * <code>CPE_CONTAINER</code> for the given path. The path of the
// container
// * will be used during resolution so as to map this container entry to a
// set
// * of other buildpath entries the container is acting for.
// * <p>
// * A container entry allows to express indirect references to a set of
// * libraries, projects and variable entries, which can be interpreted
// * differently for each script project where it is used. A buildpath
// * container entry can be resolved using
// * <code>BuildpathUtils.getResolvedBuildpathContainer</code>, and updated
// * with <code>BuildpathUtils.buildpathContainerChanged</code>
// * <p>
// * A container is exclusively resolved by a
// * <code>BuildpathContainerInitializer</code> registered onto the
// extension
// * point "org.eclipse.dltk.core.buildpathContainerInitializer".
// * <p>
// * A container path must be formed of at least one segment, where:
// * <ul>
// * <li>the first segment is a unique ID identifying the target container,
// * there must be a container initializer registered onto this ID through
// the
// * extension point
// "org.eclipse.dltk.core.buildpathContainerInitializer".</li>
// * <li>the remaining segments will be passed onto the initializer, and can
// * be used as additional hints during the initialization phase.</li>
// * </ul>
// * The access rules determine the set of accessible source and source
// files
// * in the container. If the list of access rules is empty, then all files
// in
// * this container are accessible. See {@link IAccessRule} for a detailed
// * description of access rules. Note that if an entry defined by the
// * container defines access rules, then these access rules are combined
// with
// * the given access rules. The given access rules are considered first,
// then
// * the entry's access rules are considered.
// * </p>
// * <p>
// * The <code>extraAttributes</code> list contains name/value pairs that
// must
// * be persisted with this entry. If no extra attributes are provided, an
// * empty array must be passed in.<br>
// * Note that this list should not contain any duplicate name.
// * </p>
// * <p>
// * The <code>isExported</code> flag indicates whether this entry is
// * contributed to dependent projects. If not exported, dependent projects
// * will not see any of the classes from this entry. If exported, dependent
// * projects will concatenate the accessible files patterns of this entry
// * with the accessible files patterns of the projects, and they will
// * concatenate the non accessible files patterns of this entry with the
// non
// * accessible files patterns of the project.
// * </p>
// * <p>
// * Note that this operation does not attempt to validate buildpath
// * containers or access the resources at the given paths.
// * </p>
// *
// * @param containerPath
// * the path identifying the container, it must be formed of at
// * least one segment (ID+hints)
// * @param accessRules
// * the possibly empty list of access rules for this entry
// * @param extraAttributes
// * the possibly empty list of extra attributes to persist with
// * this entry
// * @param isExported
// * a boolean indicating whether this entry is contributed to
// * dependent projects in addition to the output location
// * @return a new container buildpath entry
// *
// * @see BuildpathUtils#getBuildpathContainer(IPath, IErlangProject)
// * @see BuildpathUtils#setBuildpathContainer(IPath, IErlangProject[],
// * IBuildpathContainer[], IProgressMonitor)
// * @see BuildpathUtils#newContainerEntry(IPath, boolean)
// * @see BuildpathUtils#newAccessRule(IPath, int)
// *
// */
// public static IBuildpathEntry newContainerEntry(final IPath
// containerPath,
// final BuildpathAttributes extraAttributes, final boolean isExported) {
//
// if (containerPath == null) {
// Assert.isTrue(false, "Container path cannot be null"); //$NON-NLS-1$
// } else if (containerPath.segmentCount() < 1) {
// Assert.isTrue(
// false,
// "Illegal buildpath container path: \'" + containerPath.makeRelative().toString() + "\', must have at least one segment (containerID+hints)"); //$NON-NLS-1$//$NON-NLS-2$
// }
// final BuildpathEntry entry = new BuildpathEntry(
// IProjectFragment.K_SOURCE, IBuildpathEntry.BPE_CONTAINER,
// containerPath, isExported, INCLUDE_ALL, EXCLUDE_NONE,
// extraAttributes, false);
//
// entry.setIsContainerEntry(true);
// return entry;
// }
//
// /**
// * Runs the given action as an atomic script model operation.
// * <p>
// * After running a method that modifies elements, registered listeners
// * receive after-the-fact notification of what just transpired, in the
// form
// * of a element changed event. This method allows clients to call a number
// * of methods that modify elements and only have element changed event
// * notifications reported at the end of the entire batch.
// * </p>
// * <p>
// * If this method is called outside the dynamic scope of another such
// call,
// * this method runs the action and then reports a single element changed
// * event describing the net effect of all changes done to elements by the
// * action.
// * </p>
// * <p>
// * If this method is called in the dynamic scope of another such call,
// this
// * method simply runs the action.
// * </p>
// *
// * @param action
// * the action to perform
// * @param monitor
// * a progress monitor, or <code>null</code> if progress reporting
// * and cancellation are not desired
// * @exception CoreException
// * if the operation failed.
// *
// */
// public static void run(final IWorkspaceRunnable action,
// final IProgressMonitor monitor) throws CoreException {
// run(action, ResourcesPlugin.getWorkspace().getRoot(), monitor);
// }
//
// /**
// * Runs the given action as an atomic script model operation.
// * <p>
// * After running a method that modifies elements, registered listeners
// * receive after-the-fact notification of what just transpired, in the
// form
// * of a element changed event. This method allows clients to call a number
// * of methods that modify elements and only have element changed event
// * notifications reported at the end of the entire batch.
// * </p>
// * <p>
// * If this method is called outside the dynamic scope of another such
// call,
// * this method runs the action and then reports a single element changed
// * event describing the net effect of all changes done to elements by the
// * action.
// * </p>
// * <p>
// * If this method is called in the dynamic scope of another such call,
// this
// * method simply runs the action.
// * </p>
// * <p>
// * The supplied scheduling rule is used to determine whether this
// operation
// * can be run simultaneously with workspace changes in other threads. See
// * <code>IWorkspace.run(...)</code> for more details.
// * </p>
// *
// * @param action
// * the action to perform
// * @param rule
// * the scheduling rule to use when running this operation, or
// * <code>null</code> if there are no scheduling restrictions for
// * this operation.
// * @param monitor
// * a progress monitor, or <code>null</code> if progress reporting
// * and cancellation are not desired
// * @exception CoreException
// * if the operation failed.
// *
// */
// public static void run(final IWorkspaceRunnable action,
// final ISchedulingRule rule, final IProgressMonitor monitor)
// throws CoreException {
// final IWorkspace workspace = ResourcesPlugin.getWorkspace();
// if (workspace.isTreeLocked()) {
// action.run(monitor);
// } else {
// // use IWorkspace.run(...) to ensure that a build will be done in
// // autobuild mode
// workspace.run(action, rule, IWorkspace.AVOID_UPDATE, monitor);
// }
// }
//
// /**
// * Resolve a variable path (helper method).
// *
// * @param variablePath
// * the given variable path
// * @return the resolved variable path or <code>null</code> if none
// */
// public static IPath getResolvedVariablePath(final IPath variablePath) {
//
// if (variablePath == null) {
// return null;
// }
// final int count = variablePath.segmentCount();
// if (count == 0) {
// return null;
// }
//
// // lookup variable
// final String variableName = variablePath.segment(0);
// IPath resolvedPath = BuildpathUtils.getBuildpathVariable(variableName);
// if (resolvedPath == null) {
// return null;
// }
//
// // append path suffix
// if (count > 1) {
// resolvedPath = resolvedPath.append(variablePath
// .removeFirstSegments(1));
// }
// return resolvedPath;
// }
//
// /**
// * Answers the project specific value for a given buildpath container. In
// * case this container path could not be resolved, then will answer
// * <code>null</code>. Both the container path and the project context are
// * supposed to be non-null.
// * <p>
// * The containerPath is a formed by a first ID segment followed with extra
// * segments, which can be used as additional hints for resolution. If no
// * container was ever recorded for this container path onto this project
// * (using <code>setBuildpathContainer</code>, then a
// * <code>buildpathContainerInitializer</code> will be activated if any was
// * registered for this container ID onto the extension point
// * "org.eclipse.dltk.core.buildpathContainerInitializer".
// * <p>
// * There is no assumption that the returned container must answer the
// exact
// * same containerPath when requested
// * <code>IBuildpathContainer#getPath</code>. Indeed, the containerPath is
// * just an indication for resolving it to an actual container object.
// * <p>
// * buildpath container values are persisted locally to the workspace, but
// * are not preserved from a session to another. It is thus highly
// * recommended to register a <code>buildpathContainerInitializer</code>
// for
// * each referenced container (through the extension point
// * "org.eclipse.dltk.core.buildpathContainerInitializer").
// * <p>
// *
// * @param containerPath
// * the name of the container, which needs to be resolved
// * @param project
// * a specific project in which the container is being resolved
// * @return the corresponding buildpath container or <code>null</code> if
// * unable to find one.
// *
// * @exception ModelException
// * if an exception occurred while resolving the container, or
// * if the resolved container contains illegal entries
// * (contains BPE_CONTAINER entries or null entries).
// *
// * @see buildpathContainerInitializer
// * @see IBuildpathContainer
// * @see #setbuildpathContainer(IPath, IErlangProject[],
// * IBuildpathContainer[], IProgressMonitor)
// *
// */
// public static IBuildpathContainer getBuildpathContainer(
// final IPath containerPath, final IErlangProject project)
// throws ModelException {
// final ModelManager manager = ModelManager.getModelManager();
// final IBuildpathContainer container = manager.getBuildpathContainer(
// containerPath, project);
// if (container == ModelManager.CONTAINER_INITIALIZATION_IN_PROGRESS) {
// return manager.getPreviousSessionContainer(containerPath, project);
// }
// return container;
// }
//
// public static IBuildpathEntry newExtLibraryEntry(final IPath path) {
//
// return newLibraryEntry(path, NO_EXTRA_ATTRIBUTES,
// false/* not exported */, true);
// }
//
// public static IBuildpathEntry newLibraryEntry(final IPath path,
// final BuildpathAttributes extraAttributes,
// final Collection<IPath> include, final Collection<IPath> exclude,
// final boolean isExported, final boolean externalLib) {
//
// if (path == null) {
// Assert.isTrue(false, "Library path cannot be null"); //$NON-NLS-1$
// }
// if (!path.isAbsolute()) {
// Assert.isTrue(false, "Path for IBuildpathEntry must be absolute"); //$NON-NLS-1$
// }
// return new BuildpathEntry(IProjectFragment.K_BINARY,
// IBuildpathEntry.BPE_LIBRARY,
// ScriptProject.canonicalizedPath(path), isExported, include, // inclusion
// // patterns
// exclude, // exclusion patterns
// extraAttributes, externalLib);
// }
//
// public static IBuildpathEntry newBuiltinEntry(final IPath path,
// final BuildpathAttributes extraAttributes,
// final Collection<IPath> include, final Collection<IPath> exclude,
// final boolean isExported, final boolean externalLib) {
//
// if (path == null) {
// Assert.isTrue(false, "Library path cannot be null"); //$NON-NLS-1$
// }
// return new BuildpathEntry(IProjectFragment.K_BINARY,
// IBuildpathEntry.BPE_LIBRARY, path, isExported, include, // inclusion
// // patterns
// exclude, // exclusion patterns
// extraAttributes, externalLib);
// }
//
}