| /******************************************************************************* |
| * Copyright (c) 2000, 2010 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.jdt.internal.core; |
| |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.jobs.ISchedulingRule; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.JavaModelException; |
| |
| /* |
| * Abstract class for operations that change the classpath |
| */ |
| public abstract class ChangeClasspathOperation extends JavaModelOperation { |
| |
| protected boolean canChangeResources; |
| |
| public ChangeClasspathOperation(IJavaElement[] elements, boolean canChangeResources) { |
| super(elements); |
| this.canChangeResources = canChangeResources; |
| } |
| |
| protected boolean canModifyRoots() { |
| // changing the classpath can modify roots |
| return true; |
| } |
| |
| /* |
| * The resolved classpath of the given project may have changed: |
| * - generate a delta |
| * - trigger indexing |
| * - update project references |
| * - create resolved classpath markers |
| */ |
| protected void classpathChanged(ClasspathChange change, boolean refreshExternalFolder) throws JavaModelException { |
| // reset the project's caches early since some clients rely on the project's caches being up-to-date when run inside an IWorkspaceRunnable |
| // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=212769#c5 ) |
| JavaProject project = change.project; |
| project.resetCaches(); |
| |
| if (this.canChangeResources) { |
| // workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=177922 |
| if (isTopLevelOperation() && !ResourcesPlugin.getWorkspace().isTreeLocked()) { |
| new ClasspathValidation(project).validate(); |
| } |
| |
| // delta, indexing and classpath markers are going to be created by the delta processor |
| // while handling the resource change (either .classpath change, or project touched) |
| |
| // however ensure project references are updated |
| // since some clients rely on the project references when run inside an IWorkspaceRunnable |
| new ProjectReferenceChange(project, change.oldResolvedClasspath).updateProjectReferencesIfNecessary(); |
| |
| // and ensure that external folders are updated as well |
| new ExternalFolderChange(project, change.oldResolvedClasspath).updateExternalFoldersIfNecessary(refreshExternalFolder, null); |
| |
| } else { |
| DeltaProcessingState state = JavaModelManager.getDeltaState(); |
| JavaElementDelta delta = new JavaElementDelta(getJavaModel()); |
| int result = change.generateDelta(delta, true/*add classpath change*/); |
| if ((result & ClasspathChange.HAS_DELTA) != 0) { |
| // create delta |
| addDelta(delta); |
| |
| // need to recompute root infos |
| state.rootsAreStale = true; |
| |
| // ensure indexes are updated |
| change.requestIndexing(); |
| |
| // ensure classpath is validated on next build |
| state.addClasspathValidation(project); |
| } |
| if ((result & ClasspathChange.HAS_PROJECT_CHANGE) != 0) { |
| // ensure project references are updated on next build |
| state.addProjectReferenceChange(project, change.oldResolvedClasspath); |
| } |
| if ((result & ClasspathChange.HAS_LIBRARY_CHANGE) != 0) { |
| // ensure external folders are updated on next build |
| state.addExternalFolderChange(project, change.oldResolvedClasspath); |
| } |
| } |
| } |
| |
| protected ISchedulingRule getSchedulingRule() { |
| return null; // no lock taken while changing classpath |
| } |
| |
| public boolean isReadOnly() { |
| return !this.canChangeResources; |
| } |
| |
| } |