diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactBySourceFileFinder.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactBySourceFileFinder.java new file mode 100644 index 000000000000..5a2211bb0abd --- /dev/null +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactBySourceFileFinder.java @@ -0,0 +1,35 @@ +/* + * 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.components.ServiceManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.packaging.artifacts.Artifact; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +/** + * @author nik + */ +public abstract class ArtifactBySourceFileFinder { + public static ArtifactBySourceFileFinder getInstance(@NotNull Project project) { + return ServiceManager.getService(project, ArtifactBySourceFileFinder.class); + } + + public abstract Collection findArtifacts(@NotNull VirtualFile sourceFile); +} diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactBySourceFileFinderImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactBySourceFileFinderImpl.java new file mode 100644 index 000000000000..3c5876239ad6 --- /dev/null +++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactBySourceFileFinderImpl.java @@ -0,0 +1,104 @@ +/* + * 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.ModificationTracker; +import com.intellij.openapi.util.MultiValuesMap; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.packaging.artifacts.Artifact; +import com.intellij.packaging.artifacts.ArtifactManager; +import com.intellij.packaging.elements.ComplexPackagingElementType; +import com.intellij.packaging.elements.PackagingElementFactory; +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.SmartList; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * @author nik + */ +public class ArtifactBySourceFileFinderImpl extends ArtifactBySourceFileFinder { + private CachedValue> myFile2Artifacts; + private final Project myProject; + + public ArtifactBySourceFileFinderImpl(Project project) { + myProject = project; + } + + public CachedValue> getFileToArtifactsMap() { + if (myFile2Artifacts == null) { + myFile2Artifacts = + CachedValuesManager.getManager(myProject).createCachedValue(new CachedValueProvider>() { + public Result> compute() { + MultiValuesMap result = computeFileToArtifactsMap(); + List trackers = new ArrayList(); + trackers.add(ArtifactManager.getInstance(myProject).getModificationTracker()); + for (ComplexPackagingElementType type : PackagingElementFactory.getInstance().getComplexElementTypes()) { + ContainerUtil.addIfNotNull(type.getAllSubstitutionsModificationTracker(myProject), trackers); + } + return Result.create(result, trackers.toArray(new ModificationTracker[trackers.size()])); + } + }, false); + } + return myFile2Artifacts; + } + + private MultiValuesMap computeFileToArtifactsMap() { + final MultiValuesMap result = new MultiValuesMap(); + final ArtifactManager artifactManager = ArtifactManager.getInstance(myProject); + for (final Artifact artifact : artifactManager.getArtifacts()) { + ArtifactUtil.processFileOrDirectoryCopyElements(artifact, new PackagingElementProcessor>() { + @Override + public boolean process(@NotNull FileOrDirectoryCopyPackagingElement element, @NotNull PackagingElementPath path) { + final VirtualFile root = element.findFile(); + if (root != null) { + result.put(root, artifact); + } + return true; + } + }, artifactManager.getResolvingContext(), true); + } + return result; + } + + @Override + public Collection findArtifacts(@NotNull VirtualFile sourceFile) { + final MultiValuesMap map = getFileToArtifactsMap().getValue(); + if (map.isEmpty()) { + return Collections.emptyList(); + } + + List result = null; + VirtualFile file = sourceFile; + while (file != null) { + final Collection artifacts = map.get(file); + if (artifacts != null) { + if (result == null) { + result = new SmartList(); + } + result.addAll(artifacts); + } + file = file.getParent(); + } + return result != null ? result : Collections.emptyList(); + } +} 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 5908245ce3da..560d317b8fcb 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 @@ -294,15 +294,6 @@ public class ArtifactUtil { }); } - public static Collection findArtifactsByFile(@NotNull final VirtualFile file, @NotNull Project project) { - final Collection> items = findContainingArtifactsWithOutputPaths(file, project); - final List result = new ArrayList(); - for (Trinity item : items) { - result.add(item.getFirst()); - } - return result; - } - public static void processFileOrDirectoryCopyElements(Artifact artifact, PackagingElementProcessor> processor, PackagingElementResolvingContext context, diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileAction.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileAction.java index ba1312d806c7..4615cc1f191c 100644 --- a/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileAction.java +++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileAction.java @@ -15,11 +15,10 @@ import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.WindowManager; import com.intellij.packaging.artifacts.Artifact; -import com.intellij.packaging.impl.artifacts.ArtifactUtil; +import com.intellij.packaging.impl.artifacts.ArtifactBySourceFileFinder; import org.jetbrains.annotations.NotNull; import java.io.IOException; @@ -36,16 +35,17 @@ public class PackageFileAction extends AnAction { boolean visible = false; final Project project = e.getData(PlatformDataKeys.PROJECT); if (project != null) { - final VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); - if (files != null && files.length > 0) { + final List files = getFilesToPackage(e, project); + if (!files.isEmpty()) { visible = true; - e.getPresentation().setText(files.length == 1 ? CompilerBundle.message("action.name.package.file") : CompilerBundle.message("action.name.package.files")); + e.getPresentation().setText(files.size() == 1 ? CompilerBundle.message("action.name.package.file") : CompilerBundle.message("action.name.package.files")); } } e.getPresentation().setVisible(visible); } + @NotNull private static List getFilesToPackage(@NotNull AnActionEvent e, @NotNull Project project) { final VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY); if (files == null) return Collections.emptyList(); @@ -58,7 +58,7 @@ public class PackageFileAction extends AnAction { fileIndex.isInSourceContent(file) && compilerManager.isCompilableFileType(file.getFileType())) { return Collections.emptyList(); } - final Collection artifacts = ArtifactUtil.findArtifactsByFile(file, project); + final Collection artifacts = ArtifactBySourceFileFinder.getInstance(project).findArtifacts(file); for (Artifact artifact : artifacts) { if (!StringUtil.isEmpty(artifact.getOutputPath())) { result.add(file); @@ -80,22 +80,22 @@ public class PackageFileAction extends AnAction { for (VirtualFile file : files) { PackageFileWorker.packageFile(file, project); } - setStatusText(project, VfsUtil.toVirtualFileArray(files)); + setStatusText(project, files); } catch (IOException e) { Messages.showErrorDialog(CompilerBundle.message("message.tect.package.file.io.error", e), CommonBundle.getErrorTitle()); } } - public static void setStatusText(Project project, VirtualFile[] files) { - if (files.length != 0) { + private static void setStatusText(Project project, List files) { + if (!files.isEmpty()) { String fileNames = ""; for (VirtualFile file : files) { if (fileNames.length() != 0) fileNames += ", "; fileNames+="'"+file.getName()+"'"; } String time = DateFormat.getTimeInstance().format(new Date()); - final String statusText = CompilerBundle.message("status.text.file.has.been.packaged", files.length, fileNames, time); + final String statusText = CompilerBundle.message("status.text.file.has.been.packaged", files.size(), fileNames, time); WindowManager.getInstance().getStatusBar(project).setInfo(statusText); } } diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElementType.java b/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElementType.java index 890b165228fc..7fd3d995c60c 100644 --- a/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElementType.java +++ b/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElementType.java @@ -16,8 +16,11 @@ package com.intellij.packaging.elements; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.ModificationTracker; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author nik @@ -28,4 +31,9 @@ public abstract class ComplexPackagingElementType +