From 03a552c5f3a5e97391a063439218343c1abdcaea Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 5 Nov 2009 12:11:30 +0300 Subject: [PATCH] IDEADEV-40824: Artifact: project elements move/rename does not update artifact definition --- .../impl/artifacts/ArtifactManagerImpl.java | 5 +- .../impl/artifacts/ArtifactUtil.java | 2 +- .../ArtifactVirtualFileListener.java | 112 ++++++++++++++++++ 3 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactVirtualFileListener.java diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java index adfe8b9fb574..bb89c9db80db 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java @@ -23,7 +23,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.ModificationTracker; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.*; import com.intellij.packaging.artifacts.*; import com.intellij.packaging.elements.*; import com.intellij.util.containers.ContainerUtil; @@ -65,9 +65,10 @@ public class ArtifactManagerImpl extends ArtifactManager implements ProjectCompo }; private Map myWatchedOutputs = new HashMap(); - public ArtifactManagerImpl(Project project) { + public ArtifactManagerImpl(Project project, VirtualFileManager virtualFileManager) { myProject = project; myResolvingContext = new DefaultPackagingElementResolvingContext(myProject); + virtualFileManager.addVirtualFileListener(new ArtifactVirtualFileListener(myProject, this), myProject); } @NotNull diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactUtil.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactUtil.java index 019aa3e91ecf..cf2b82412988 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactUtil.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactUtil.java @@ -297,7 +297,7 @@ public class ArtifactUtil { return result; } - private static void processFileOrDirectoryCopyElements(Artifact artifact, + public static void processFileOrDirectoryCopyElements(Artifact artifact, PackagingElementProcessor> processor, PackagingElementResolvingContext context, boolean processSubstitutions) { diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactVirtualFileListener.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactVirtualFileListener.java new file mode 100644 index 000000000000..04828320c0ce --- /dev/null +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactVirtualFileListener.java @@ -0,0 +1,112 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.packaging.impl.artifacts; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.MultiValuesMap; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileAdapter; +import com.intellij.openapi.vfs.VirtualFileMoveEvent; +import com.intellij.openapi.vfs.VirtualFilePropertyEvent; +import com.intellij.packaging.artifacts.Artifact; +import com.intellij.packaging.artifacts.ModifiableArtifactModel; +import com.intellij.packaging.elements.CompositePackagingElement; +import com.intellij.packaging.impl.elements.FileOrDirectoryCopyPackagingElement; +import com.intellij.psi.util.CachedValue; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; +import com.intellij.util.PathUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; +import java.util.List; + +/** + * @author nik + */ +public class ArtifactVirtualFileListener extends VirtualFileAdapter { + private CachedValue> myParentPathsToArtifacts; + private final ArtifactManagerImpl myArtifactManager; + + public ArtifactVirtualFileListener(Project project, final ArtifactManagerImpl artifactManager) { + myArtifactManager = artifactManager; + myParentPathsToArtifacts = + CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider>() { + public Result> compute() { + MultiValuesMap result = computeParentPathToArtifactMap(); + return Result.createSingleDependency(result, artifactManager.getModificationTracker()); + } + }, false); + } + + private MultiValuesMap computeParentPathToArtifactMap() { + final MultiValuesMap result = new MultiValuesMap(); + for (final Artifact artifact : myArtifactManager.getArtifacts()) { + ArtifactUtil.processFileOrDirectoryCopyElements(artifact, new PackagingElementProcessor>() { + @Override + public boolean process(@NotNull List> parents, @NotNull FileOrDirectoryCopyPackagingElement element) { + String path = element.getFilePath(); + while (path.length() > 0) { + result.put(path, artifact); + path = PathUtil.getParentPath(path); + } + return true; + } + }, myArtifactManager.getResolvingContext(), false); + } + return result; + } + + + @Override + public void fileMoved(VirtualFileMoveEvent event) { + final String oldPath = event.getOldParent().getPath() + "/" + event.getFileName(); + filePathChanged(oldPath, event.getNewParent().getPath() + "/" + event.getFileName()); + } + + private void filePathChanged(@NotNull final String oldPath, @NotNull final String newPath) { + final Collection artifacts = myParentPathsToArtifacts.getValue().get(oldPath); + if (artifacts != null) { + final ModifiableArtifactModel model = myArtifactManager.createModifiableModel(); + for (Artifact artifact : artifacts) { + final Artifact copy = model.getOrCreateModifiableArtifact(artifact); + ArtifactUtil.processFileOrDirectoryCopyElements(copy, new PackagingElementProcessor>() { + @Override + public boolean process(@NotNull List> parents, + @NotNull FileOrDirectoryCopyPackagingElement element) { + final String path = element.getFilePath(); + if (FileUtil.startsWith(path, oldPath)) { + element.setFilePath(newPath + path.substring(oldPath.length())); + } + return true; + } + }, myArtifactManager.getResolvingContext(), false); + } + model.commit(); + } + } + + @Override + public void propertyChanged(VirtualFilePropertyEvent event) { + if (VirtualFile.PROP_NAME.equals(event.getPropertyName())) { + final VirtualFile parent = event.getParent(); + if (parent != null) { + filePathChanged(parent.getPath() + "/" + event.getOldValue(), parent.getPath() + "/" + event.getNewValue()); + } + } + } +}