mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
project structure dialog: 'Convert to Repository Library' action works for module-level libraries
(IDEA-176748)
This commit is contained in:
+2
@@ -40,6 +40,7 @@ import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable;
|
||||
import com.intellij.openapi.roots.ui.configuration.dependencyAnalysis.AnalyzeDependenciesDialog;
|
||||
import com.intellij.openapi.roots.ui.configuration.libraries.LibraryEditingUtil;
|
||||
import com.intellij.openapi.roots.ui.configuration.libraryEditor.EditExistingLibraryDialog;
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.ConvertModuleLibraryToRepositoryLibraryAction;
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.FindUsagesInProjectStructureActionBase;
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.ModuleStructureConfigurable;
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.StructureConfigurableContext;
|
||||
@@ -288,6 +289,7 @@ public class ClasspathPanelImpl extends JPanel implements ClasspathPanel {
|
||||
addChangeLibraryLevelAction(actionGroup, LibraryTablesRegistrar.PROJECT_LEVEL);
|
||||
addChangeLibraryLevelAction(actionGroup, LibraryTablesRegistrar.APPLICATION_LEVEL);
|
||||
addChangeLibraryLevelAction(actionGroup, LibraryTableImplUtil.MODULE_LEVEL);
|
||||
actionGroup.add(new ConvertModuleLibraryToRepositoryLibraryAction(this, getStructureConfigurableContext()));
|
||||
PopupHandler.installPopupHandler(myEntryTable, actionGroup, ActionPlaces.UNKNOWN, ActionManager.getInstance());
|
||||
}
|
||||
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.openapi.roots.ui.configuration.projectRoot
|
||||
|
||||
import com.intellij.jarRepository.RepositoryLibraryType
|
||||
import com.intellij.openapi.roots.LibraryOrderEntry
|
||||
import com.intellij.openapi.roots.impl.OrderEntryUtil
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryTableImplUtil
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.roots.ui.configuration.classpath.ClasspathPanel
|
||||
import com.intellij.openapi.roots.ui.configuration.libraryEditor.ExistingLibraryEditor
|
||||
import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditorBase
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
class ConvertModuleLibraryToRepositoryLibraryAction(private val classpathPanel: ClasspathPanel,
|
||||
context: StructureConfigurableContext)
|
||||
: ConvertToRepositoryLibraryActionBase(context) {
|
||||
|
||||
override fun getSelectedLibrary(): LibraryEx? {
|
||||
val entry = classpathPanel.selectedEntry as? LibraryOrderEntry
|
||||
if (entry == null || !entry.isModuleLevel) return null
|
||||
return entry.library as? LibraryEx
|
||||
}
|
||||
|
||||
override fun replaceLibrary(library: Library, configureNewLibrary: (LibraryEditorBase) -> Unit) {
|
||||
val name = library.name
|
||||
val modifiableModel = classpathPanel.getModifiableModelProvider(LibraryTableImplUtil.MODULE_LEVEL).modifiableModel
|
||||
val newLibrary = modifiableModel.createLibrary(name, RepositoryLibraryType.getInstance().kind, null)
|
||||
OrderEntryUtil.replaceLibraryEntryByAdded(classpathPanel.rootModel, classpathPanel.rootModel.findLibraryOrderEntry(library)!!)
|
||||
|
||||
val editor = ExistingLibraryEditor(newLibrary, null)
|
||||
configureNewLibrary(editor)
|
||||
editor.commit()
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.openapi.roots.ui.configuration.projectRoot
|
||||
|
||||
import com.intellij.jarRepository.RepositoryLibraryType
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable
|
||||
import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditorBase
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.LibraryProjectStructureElement
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
class ConvertProjectLibraryToRepositoryLibraryAction(private val librariesConfigurable: BaseLibrariesConfigurable,
|
||||
context: StructureConfigurableContext)
|
||||
: ConvertToRepositoryLibraryActionBase(context) {
|
||||
|
||||
override fun getSelectedLibrary() = (librariesConfigurable.selectedElement as? LibraryProjectStructureElement)?.library as? LibraryEx
|
||||
|
||||
override fun replaceLibrary(library: Library, configureNewLibrary: (LibraryEditorBase) -> Unit) {
|
||||
val name = library.name
|
||||
val modifiableModel = librariesConfigurable.modelProvider.modifiableModel
|
||||
|
||||
val usages = context.daemonAnalyzer.getUsages(LibraryProjectStructureElement(context, library))
|
||||
modifiableModel.removeLibrary(library)
|
||||
val newLibrary = modifiableModel.createLibrary(name, RepositoryLibraryType.getInstance().kind, null)
|
||||
usages.forEach { it.replaceElement(LibraryProjectStructureElement(context, newLibrary)) }
|
||||
|
||||
val editor = modifiableModel.getLibraryEditor(newLibrary)
|
||||
configureNewLibrary(editor)
|
||||
ProjectStructureConfigurable.getInstance(project).selectProjectOrGlobalLibrary(newLibrary, true)
|
||||
}
|
||||
}
|
||||
+20
-22
@@ -32,10 +32,12 @@ import com.intellij.openapi.roots.AnnotationOrderRootType
|
||||
import com.intellij.openapi.roots.OrderRootType
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.roots.libraries.LibraryUtil
|
||||
import com.intellij.openapi.roots.libraries.NewLibraryConfiguration
|
||||
import com.intellij.openapi.roots.libraries.ui.OrderRoot
|
||||
import com.intellij.openapi.roots.ui.configuration.ProjectStructureConfigurable
|
||||
import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor
|
||||
import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditorBase
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.LibraryProjectStructureElement
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
@@ -55,20 +57,23 @@ import java.util.*
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
private val LOG = logger<ConvertToRepositoryLibraryAction>()
|
||||
private val LOG = logger<ConvertToRepositoryLibraryActionBase>()
|
||||
|
||||
class ConvertToRepositoryLibraryAction(private val librariesConfigurable: BaseLibrariesConfigurable, private val project: Project) : DumbAwareAction(
|
||||
abstract class ConvertToRepositoryLibraryActionBase(protected val context: StructureConfigurableContext) : DumbAwareAction(
|
||||
"Convert to Repository Library...",
|
||||
"Convert a regular library to a repository library which additionally stores its Maven coordinates, so the IDE can automatically download the library JARs if they are missing",
|
||||
null) {
|
||||
protected val project = context.project
|
||||
|
||||
protected abstract fun getSelectedLibrary(): LibraryEx?
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
val library = (librariesConfigurable.selectedElement as? LibraryProjectStructureElement)?.library as? LibraryEx
|
||||
val library = getSelectedLibrary()
|
||||
e.presentation.isEnabledAndVisible = library != null && library.kind == null
|
||||
}
|
||||
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
val library = (librariesConfigurable.selectedElement as LibraryProjectStructureElement).library
|
||||
val library = getSelectedLibrary() ?: return
|
||||
val mavenCoordinates = detectOrSpecifyMavenCoordinates(library) ?: return
|
||||
|
||||
val libraryProperties = RepositoryLibraryProperties(mavenCoordinates.groupId, mavenCoordinates.artifactId, mavenCoordinates.version)
|
||||
@@ -85,14 +90,14 @@ class ConvertToRepositoryLibraryAction(private val librariesConfigurable: BaseLi
|
||||
if (task.cancelled) return
|
||||
|
||||
if (!task.filesAreTheSame) {
|
||||
val ok = LibraryJarsDiffDialog(task.libraryFileToCompare!!, task.downloadedFileToCompare!!, mavenCoordinates, library.name!!, project).showAndGet()
|
||||
val ok = LibraryJarsDiffDialog(task.libraryFileToCompare!!, task.downloadedFileToCompare!!, mavenCoordinates, LibraryUtil.getPresentableName(library), project).showAndGet()
|
||||
task.deleteTemporaryFiles()
|
||||
if (!ok) {
|
||||
return
|
||||
}
|
||||
}
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
replaceByLibrary(library, object : NewLibraryConfiguration(library.name!!, RepositoryLibraryType.getInstance(), libraryProperties) {
|
||||
replaceByLibrary(library, object : NewLibraryConfiguration(library.name ?: "", RepositoryLibraryType.getInstance(), libraryProperties) {
|
||||
override fun addRoots(editor: LibraryEditor) {
|
||||
editor.addRoots(roots)
|
||||
}
|
||||
@@ -102,7 +107,7 @@ class ConvertToRepositoryLibraryAction(private val librariesConfigurable: BaseLi
|
||||
|
||||
private fun detectOrSpecifyMavenCoordinates(library: Library): JpsMavenRepositoryLibraryDescriptor? {
|
||||
val detectedCoordinates = detectMavenCoordinates(library.getFiles(OrderRootType.CLASSES))
|
||||
LOG.debug("Maven coordinates for ${library.name} JARs: $detectedCoordinates")
|
||||
LOG.debug("Maven coordinates for ${LibraryUtil.getPresentableName(library)} JARs: $detectedCoordinates")
|
||||
if (detectedCoordinates.size == 1) {
|
||||
return detectedCoordinates[0]
|
||||
}
|
||||
@@ -120,23 +125,16 @@ class ConvertToRepositoryLibraryAction(private val librariesConfigurable: BaseLi
|
||||
|
||||
private fun replaceByLibrary(library: Library, configuration: NewLibraryConfiguration) {
|
||||
val annotationUrls = library.getUrls(AnnotationOrderRootType.getInstance())
|
||||
val name = library.name
|
||||
val modifiableModel = librariesConfigurable.modelProvider.modifiableModel
|
||||
val context = librariesConfigurable.myContext
|
||||
|
||||
val usages = context.daemonAnalyzer.getUsages(LibraryProjectStructureElement(context, library))
|
||||
modifiableModel.removeLibrary(library)
|
||||
val newLibrary = modifiableModel.createLibrary(name, RepositoryLibraryType.getInstance().kind, null)
|
||||
usages.forEach { it.replaceElement(LibraryProjectStructureElement(context, newLibrary)) }
|
||||
|
||||
val editor = modifiableModel.getLibraryEditor(newLibrary)
|
||||
editor.properties = configuration.properties
|
||||
editor.removeAllRoots()
|
||||
configuration.addRoots(editor)
|
||||
annotationUrls.forEach { editor.addRoot(it, AnnotationOrderRootType.getInstance()) }
|
||||
ProjectStructureConfigurable.getInstance(project).selectProjectOrGlobalLibrary(newLibrary, true)
|
||||
replaceLibrary(library) { editor ->
|
||||
editor.properties = configuration.properties
|
||||
editor.removeAllRoots()
|
||||
configuration.addRoots(editor)
|
||||
annotationUrls.forEach { editor.addRoot(it, AnnotationOrderRootType.getInstance()) }
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun replaceLibrary(library: Library, configureNewLibrary: (LibraryEditorBase) -> Unit)
|
||||
|
||||
companion object {
|
||||
fun detectMavenCoordinates(libraryRoots: Array<out VirtualFile>): List<JpsMavenRepositoryLibraryDescriptor> =
|
||||
libraryRoots.flatMap { root ->
|
||||
+1
-1
@@ -77,7 +77,7 @@ public class ProjectLibrariesConfigurable extends BaseLibrariesConfigurable {
|
||||
protected List<? extends AnAction> createCopyActions(boolean fromPopup) {
|
||||
List<? extends AnAction> actions = super.createCopyActions(fromPopup);
|
||||
if (fromPopup) {
|
||||
return ContainerUtil.concat(actions, Collections.singletonList(new ConvertToRepositoryLibraryAction(this, myProject)));
|
||||
return ContainerUtil.concat(actions, Collections.singletonList(new ConvertProjectLibraryToRepositoryLibraryAction(this, myContext)));
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
|
||||
+1
-5
@@ -16,13 +16,9 @@
|
||||
package com.intellij.openapi.roots.ui.configuration.projectRoot
|
||||
|
||||
import com.intellij.openapi.application.PathManager
|
||||
import com.intellij.openapi.projectRoots.ex.JavaSdkUtil
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.testFramework.LightPlatformTestCase
|
||||
import junit.framework.TestCase
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
@@ -32,7 +28,7 @@ class ConvertToRepositoryLibraryActionTest : LightPlatformTestCase() {
|
||||
val jarFile = PathManager.findFileInLibDirectory("commons-codec-1.9.jar")
|
||||
val file = VirtualFileManager.getInstance().refreshAndFindFileByUrl(VfsUtil.getUrlForLibraryRoot(jarFile))
|
||||
assertNotNull(jarFile.absolutePath, file)
|
||||
val coordinates = assertOneElement(ConvertToRepositoryLibraryAction.detectMavenCoordinates(arrayOf(file!!)))
|
||||
val coordinates = assertOneElement(ConvertToRepositoryLibraryActionBase.detectMavenCoordinates(arrayOf(file!!)))
|
||||
assertEquals("commons-codec", coordinates.groupId)
|
||||
assertEquals("commons-codec", coordinates.artifactId)
|
||||
assertEquals("1.9", coordinates.version)
|
||||
|
||||
Reference in New Issue
Block a user