blob: be223e61fd756d714c3553335ab2a9184ec48773 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2006 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.ltk.core.refactoring.participants;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.resources.IFile;
import org.eclipse.ltk.core.refactoring.IRefactoringCoreStatusCodes;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.internal.core.refactoring.Messages;
import org.eclipse.ltk.internal.core.refactoring.RefactoringCoreMessages;
import org.eclipse.ltk.internal.core.refactoring.RefactoringCorePlugin;
/**
* A context that is shared between the refactoring processor and all its
* associated participants during condition checking.
* <p>
* The context manages a set of {@link IConditionChecker}objects to collect
* condition checks that should be perform across all participants and the
* processor. For example validating if a file can be changed (see
* {@link org.eclipse.core.resources.IWorkspace#validateEdit(org.eclipse.core.resources.IFile[], java.lang.Object)}
* should only be called once for all files modified by the processor and all
* participants.
* </p>
* <p>
* Note: this class is not intended to be extended by clients.
* </p>
*
* @since 3.0
*/
public class CheckConditionsContext {
private Map fCheckers= new HashMap();
/**
* Returns the condition checker of the given type.
*
* @param clazz the type of the condition checker
*
* @return the condition checker or <code>null</code> if
* no checker is registered for the given type
*/
public IConditionChecker getChecker(Class clazz) {
return (IConditionChecker)fCheckers.get(clazz);
}
/**
* Adds the given condition checker. An exception will be
* thrown if a checker of the same type already exists in
* this context.
*
* @param checker the checker to add
* @throws CoreException if a checker of the same type already
* exists
*/
public void add(IConditionChecker checker) throws CoreException {
Object old= fCheckers.put(checker.getClass(), checker);
if (old != null) {
fCheckers.put(checker.getClass(), old);
throw new CoreException(new Status(IStatus.ERROR, RefactoringCorePlugin.getPluginId(),
IRefactoringCoreStatusCodes.CHECKER_ALREADY_EXISTS_IN_CONTEXT,
Messages.format(RefactoringCoreMessages.CheckConditionContext_error_checker_exists, checker.getClass().toString()),
null));
}
}
/**
* Checks the condition of all registered condition checkers and returns a
* merge status result.
*
* @param pm a progress monitor or <code>null</code> if no progress
* reporting is desired
*
* @return the combined status result
*
* @throws CoreException if an error occurs during condition checking
*/
public RefactoringStatus check(IProgressMonitor pm) throws CoreException {
if (pm == null)
pm= new NullProgressMonitor();
RefactoringStatus result= new RefactoringStatus();
mergeResourceOperationAndValidateEdit();
List values= new ArrayList(fCheckers.values());
Collections.sort(values, new Comparator() {
public int compare(Object o1, Object o2) {
// Note there can only be one ResourceOperationChecker. So it
// is save to not test the case that both objects are
// ResourceOperationChecker
if (o1 instanceof ResourceChangeChecker)
return -1;
if (o2 instanceof ResourceChangeChecker)
return 1;
return 0;
}
});
pm.beginTask("", values.size()); //$NON-NLS-1$
for (Iterator iter= values.iterator(); iter.hasNext();) {
IConditionChecker checker= (IConditionChecker)iter.next();
result.merge(checker.check(new SubProgressMonitor(pm, 1)));
if (pm.isCanceled())
throw new OperationCanceledException();
}
return result;
}
private void mergeResourceOperationAndValidateEdit() throws CoreException {
ValidateEditChecker validateEditChecker= (ValidateEditChecker) getChecker(ValidateEditChecker.class);
if (validateEditChecker == null)
return;
ResourceChangeChecker resourceChangeChecker= (ResourceChangeChecker) getChecker(ResourceChangeChecker.class);
if (resourceChangeChecker == null)
return;
IFile[] changedFiles= resourceChangeChecker.getChangedFiles();
validateEditChecker.addFiles(changedFiles);
}
}