Copyright (c) 2006, 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 - Bug 473427
/******************************************************************************* * Copyright (c) 2006, 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.ArrayList; import java.util.List; import org.eclipse.core.internal.resources.mapping.ChangeDescription; import org.eclipse.core.internal.resources.mapping.ResourceChangeDescriptionFactory; 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.osgi.util.NLS;
The resource change validator is used to validate that changes made to resources will not adversely affect the models stored in those resources.

The validator is used by first creating a resource delta describing the proposed changes. A delta can be generated using a IResourceChangeDescriptionFactory. The change is then validated by calling the validateChange(IResourceDelta, IProgressMonitor) method. This example validates a change to a single file: IFile file = ..;//some file that is going to be changed ResourceChangeValidator validator = ResourceChangeValidator.getValidator(); IResourceChangeDescriptionFactory factory = validator.createDeltaFactory(); factory.change(file); IResourceDelta delta = factory.getDelta(); IStatus result = validator.validateChange(delta, null); If the result status does not have severity IStatus.OK, then the changes may cause problems for models that are built on those resources. In this case the user should be presented with the status message to determine if they want to proceed with the modification.

Since:3.2
/** * The resource change validator is used to validate that changes made to * resources will not adversely affect the models stored in those resources. * <p> * The validator is used by first creating a resource delta describing the * proposed changes. A delta can be generated using a {@link IResourceChangeDescriptionFactory}. * The change is then validated by calling the {@link #validateChange(IResourceDelta, IProgressMonitor)} * method. This example validates a change to a single file: * <code> * IFile file = ..;//some file that is going to be changed * ResourceChangeValidator validator = ResourceChangeValidator.getValidator(); * IResourceChangeDescriptionFactory factory = validator.createDeltaFactory(); * factory.change(file); * IResourceDelta delta = factory.getDelta(); * IStatus result = validator.validateChange(delta, null); * </code> * If the result status does not have severity {@link IStatus#OK}, then * the changes may cause problems for models that are built on those * resources. In this case the user should be presented with the status message * to determine if they want to proceed with the modification. * </p> * * @since 3.2 */
public final class ResourceChangeValidator { private static ResourceChangeValidator instance;
Return the singleton change validator.
Returns:the singleton change validator
/** * Return the singleton change validator. * @return the singleton change validator */
public static ResourceChangeValidator getValidator() { if (instance == null) instance = new ResourceChangeValidator(); return instance; }
Singleton accessor method should be used instead.
See Also:
  • getValidator()
/** * Singleton accessor method should be used instead. * @see #getValidator() */
private ResourceChangeValidator() { super(); } private IStatus combineResults(IStatus[] result) { List<IStatus> notOK = new ArrayList<>(); for (IStatus status : result) { if (!status.isOK()) { notOK.add(status); } } if (notOK.isEmpty()) { return Status.OK_STATUS; } if (notOK.size() == 1) { return notOK.get(0); } return new MultiStatus(ResourcesPlugin.PI_RESOURCES, 0, notOK.toArray(new IStatus[notOK.size()]), Messages.mapping_multiProblems, null); }
Return an empty change description factory that can be used to build a proposed resource delta.
Returns:an empty change description factory that can be used to build a proposed resource delta
/** * Return an empty change description factory that can be used to build a * proposed resource delta. * @return an empty change description factory that can be used to build a * proposed resource delta */
public IResourceChangeDescriptionFactory createDeltaFactory() { return new ResourceChangeDescriptionFactory(); } private ModelProvider[] getProviders(IResource[] resources) { IModelProviderDescriptor[] descriptors = ModelProvider.getModelProviderDescriptors(); List<ModelProvider> result = new ArrayList<>(); for (IModelProviderDescriptor descriptor : descriptors) { try { IResource[] matchingResources = descriptor.getMatchingResources(resources); if (matchingResources.length > 0) { result.add(descriptor.getModelProvider()); } } catch (CoreException e) { Policy.log(e.getStatus().getSeverity(), NLS.bind("Could not instantiate provider {0}", descriptor.getId()), e); //$NON-NLS-1$ } } return result.toArray(new ModelProvider[result.size()]); } /* * Get the roots of any changes. */ private IResource[] getRootResources(IResourceDelta root) { final ChangeDescription changeDescription = new ChangeDescription(); try { root.accept(delta -> changeDescription.recordChange(delta)); } catch (CoreException e) { // Shouldn't happen since the ProposedResourceDelta accept doesn't throw an // exception and our visitor doesn't either Policy.log(IStatus.ERROR, "Internal error", e); //$NON-NLS-1$ } return changeDescription.getRootResources(); }
Validate the proposed changes contained in the given delta by consulting all model providers to determine if the changes have any adverse side effects.

This method returns either a ModelStatus, or a MultiStatus whose children are ModelStatus. In either case, the severity of the status indicates the severity of the possible side-effects of the operation. Any severity other than OK should 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 the possible side effects.

Params:
  • delta – a delta tree containing the proposed changes
Returns:a status indicating any potential side effects on models stored in the affected resources.
/** * Validate the proposed changes contained in the given delta * by consulting all model providers to determine if the changes * have any adverse side effects. * <p> * This method returns either a {@link ModelStatus}, or a {@link MultiStatus} * whose children are {@link ModelStatus}. In either case, the severity * of the status indicates the severity of the possible side-effects of * the operation. Any severity other than <code>OK</code> should 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 * the possible side effects. * </p> * * @param delta a delta tree containing the proposed changes * @return a status indicating any potential side effects * on models stored in the affected resources. */
public IStatus validateChange(IResourceDelta delta, IProgressMonitor monitor) { monitor = Policy.monitorFor(monitor); try { IResource[] resources = getRootResources(delta); ModelProvider[] providers = getProviders(resources); if (providers.length == 0) return Status.OK_STATUS; monitor.beginTask(Messages.mapping_validate, providers.length); IStatus[] result = new IStatus[providers.length]; for (int i = 0; i < providers.length; i++) result[i] = providers[i].validateChange(delta, Policy.subMonitorFor(monitor, 1)); return combineResults(result); } finally { monitor.done(); } } }