| /******************************************************************************* |
| * Copyright (c) 2005, 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 |
| * James Blackburn (Broadcom Corp.) - ongoing development |
| * Lars Vogel <Lars.Vogel@vogella.com> - Bug 473427 |
| *******************************************************************************/ |
| package org.eclipse.core.resources.mapping; |
| |
| import java.util.*; |
| import org.eclipse.core.internal.resources.mapping.ModelProviderManager; |
| import org.eclipse.core.resources.*; |
| import org.eclipse.core.runtime.*; |
| |
| /** |
| * Represents the provider of a logical model. The main purpose of this |
| * API is to support batch operations on sets of <code>ResourceMapping</code> |
| * objects that are part of the same model. |
| * |
| * <p> |
| * This class may be subclassed by clients. |
| * </p> |
| * @see org.eclipse.core.resources.mapping.ResourceMapping |
| * @since 3.2 |
| */ |
| public abstract class ModelProvider extends PlatformObject { |
| /** |
| * The model provider id of the Resources model. |
| */ |
| public static final String RESOURCE_MODEL_PROVIDER_ID = "org.eclipse.core.resources.modelProvider"; //$NON-NLS-1$ |
| |
| private IModelProviderDescriptor descriptor; |
| |
| /** |
| * Returns the descriptor for the model provider of the given id |
| * or <code>null</code> if the provider has not been registered. |
| * @param id a model provider id. |
| * @return the descriptor for the model provider of the given id |
| * or <code>null</code> if the provider has not been registered |
| */ |
| public static IModelProviderDescriptor getModelProviderDescriptor(String id) { |
| IModelProviderDescriptor[] descs = ModelProviderManager.getDefault().getDescriptors(); |
| for (IModelProviderDescriptor descriptor : descs) { |
| if (descriptor.getId().equals(id)) { |
| return descriptor; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Returns the descriptors for all model providers that are registered. |
| * |
| * @return the descriptors for all model providers that are registered. |
| */ |
| public static IModelProviderDescriptor[] getModelProviderDescriptors() { |
| return ModelProviderManager.getDefault().getDescriptors(); |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (obj instanceof ModelProvider) { |
| ModelProvider other = (ModelProvider) obj; |
| return other.getDescriptor().getId().equals(getDescriptor().getId()); |
| } |
| return super.equals(obj); |
| } |
| |
| /** |
| * Returns the descriptor of this model provider. The descriptor |
| * is set during initialization so implements cannot call this method |
| * until after the <code>initialize</code> method is invoked. |
| * @return the descriptor of this model provider |
| */ |
| public final IModelProviderDescriptor getDescriptor() { |
| return descriptor; |
| } |
| |
| /** |
| * Returns the unique identifier of this model provider. |
| * <p> |
| * The model provider identifier is composed of the model provider's |
| * plug-in id and the simple id of the provider extension. For example, if |
| * plug-in <code>"com.xyz"</code> defines a provider extension with id |
| * <code>"myModelProvider"</code>, the unique model provider identifier will be |
| * <code>"com.xyz.myModelProvider"</code>. |
| * </p> |
| * |
| * @return the unique model provider identifier |
| */ |
| public final String getId() { |
| return descriptor.getId(); |
| } |
| |
| /** |
| * Returns the resource mappings that cover the given resource. |
| * By default, an empty array is returned. Subclass may override |
| * this method but should consider overriding either |
| * {@link #getMappings(IResource[], ResourceMappingContext, IProgressMonitor)} |
| * or {@link #getMappings(ResourceTraversal[], ResourceMappingContext, IProgressMonitor)} |
| * if more context is needed to determine the proper mappings. |
| * |
| * @param resource the resource |
| * @param context a resource mapping context |
| * @param monitor a progress monitor, or <code>null</code> if progress |
| * reporting is not desired |
| * @return the resource mappings that cover the given resource. |
| * @exception CoreException |
| */ |
| public ResourceMapping[] getMappings(IResource resource, ResourceMappingContext context, IProgressMonitor monitor) throws CoreException { |
| return new ResourceMapping[0]; |
| } |
| |
| /** |
| * Returns the set of mappings that cover the given resources. |
| * This method is used to map operations on resources to |
| * operations on resource mappings. By default, this method |
| * calls <code>getMapping(IResource)</code> for each resource. |
| * <p> |
| * Subclasses may override this method. |
| * </p> |
| * |
| * @param resources the resources |
| * @param context a resource mapping context |
| * @param monitor a progress monitor, or <code>null</code> if progress |
| * reporting is not desired |
| * @return the set of mappings that cover the given resources |
| * @exception CoreException |
| */ |
| public ResourceMapping[] getMappings(IResource[] resources, ResourceMappingContext context, IProgressMonitor monitor) throws CoreException { |
| Set<ResourceMapping> mappings = new HashSet<>(); |
| for (IResource resource : resources) { |
| ResourceMapping[] resourceMappings = getMappings(resource, context, monitor); |
| if (resourceMappings.length > 0) |
| mappings.addAll(Arrays.asList(resourceMappings)); |
| } |
| return mappings.toArray(new ResourceMapping[mappings.size()]); |
| } |
| |
| /** |
| * Returns the set of mappings that overlap with the given resource traversals. |
| * This method is used to map operations on resources to |
| * operations on resource mappings. By default, this method |
| * calls {@link #getMappings(IResource[], ResourceMappingContext, IProgressMonitor)} |
| * with the resources extracted from each traversal. |
| * <p> |
| * Subclasses may override this method. |
| * </p> |
| * |
| * @param traversals the traversals |
| * @param context a resource mapping context |
| * @param monitor a progress monitor, or <code>null</code> if progress |
| * reporting is not desired |
| * @return the set of mappings that overlap with the given resource traversals |
| */ |
| public ResourceMapping[] getMappings(ResourceTraversal[] traversals, ResourceMappingContext context, IProgressMonitor monitor) throws CoreException { |
| Set<ResourceMapping> result = new HashSet<>(); |
| for (ResourceTraversal traversal : traversals) { |
| ResourceMapping[] mappings = getMappings(traversal.getResources(), context, monitor); |
| for (ResourceMapping mapping : mappings) |
| result.add(mapping); |
| } |
| return result.toArray(new ResourceMapping[result.size()]); |
| } |
| |
| /** |
| * Returns a set of traversals that cover the given resource mappings. The |
| * provided mappings must be from this provider or one of the providers this |
| * provider extends. |
| * <p> |
| * The default implementation accumulates the traversals from the given |
| * mappings. Subclasses can override to provide a more optimal |
| * transformation. |
| * </p> |
| * |
| * @param mappings the mappings being mapped to resources |
| * @param context the context used to determine the set of traversals that |
| * cover the mappings |
| * @param monitor a progress monitor, or <code>null</code> if progress |
| * reporting is not desired |
| * @return a set of traversals that cover the given mappings |
| * @exception CoreException |
| */ |
| public ResourceTraversal[] getTraversals(ResourceMapping[] mappings, ResourceMappingContext context, IProgressMonitor monitor) throws CoreException { |
| SubMonitor subMonitor = SubMonitor.convert(monitor, mappings.length); |
| List<ResourceTraversal> traversals = new ArrayList<>(); |
| for (ResourceMapping mapping : mappings) { |
| Collections.addAll(traversals, mapping.getTraversals(context, subMonitor.newChild(1))); |
| } |
| return traversals.toArray(new ResourceTraversal[traversals.size()]); |
| } |
| |
| @Override |
| public int hashCode() { |
| return getDescriptor().getId().hashCode(); |
| } |
| |
| /** |
| * This method is called by the model provider framework when the model |
| * provider is instantiated. This method should not be called by clients and |
| * cannot be overridden by subclasses. However, it invokes the |
| * <code>initialize</code> method once the descriptor is set so subclasses |
| * can override that method if they need to do additional initialization. |
| * |
| * @param desc the description of the provider as it appears in the plugin manifest |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public final void init(IModelProviderDescriptor desc) { |
| if (descriptor != null) { |
| // prevent subsequent calls from damaging this instance |
| return; |
| } |
| descriptor = desc; |
| initialize(); |
| } |
| |
| /** |
| * Initialization method that is called after the descriptor |
| * of this provider is set. Subclasses may override. |
| */ |
| protected void initialize() { |
| // Do nothing |
| } |
| |
| /** |
| * Validates the proposed changes contained in the given delta. |
| * <p> |
| * This method must return either a {@link ModelStatus}, or a {@link MultiStatus} |
| * whose children are {@link ModelStatus}. The severity of the returned status |
| * indicates the severity of the possible side-effects of the operation. Any |
| * severity other than <code>OK</code> will be shown to the user. The |
| * message should be a human readable message that will allow the user to |
| * make a decision on whether to continue with the operation. The model |
| * provider id should indicate which model is flagging the possible side effects. |
| * <p> |
| * This default implementation accepts all changes and returns a status with |
| * severity <code>OK</code>. Subclasses should override to perform |
| * validation specific to their model. |
| * </p> |
| * |
| * @param delta a delta tree containing the proposed changes |
| * @param monitor a progress monitor, or <code>null</code> if progress |
| * reporting is not desired |
| * @return a status indicating any potential side effects |
| * on the model that provided this validator. |
| */ |
| public IStatus validateChange(IResourceDelta delta, IProgressMonitor monitor) { |
| return new ModelStatus(IStatus.OK, ResourcesPlugin.PI_RESOURCES, descriptor.getId(), Status.OK_STATUS.getMessage()); |
| } |
| } |