'create library from files' action now automatically detects root types

This commit is contained in:
nik
2011-08-23 16:13:34 +04:00
parent cc7d6f8928
commit 05f0b88236
9 changed files with 102 additions and 62 deletions
@@ -23,6 +23,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.ui.OrderRoot;
import com.intellij.openapi.roots.ui.configuration.ModulesCombobox;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryNameAndLevelPanel;
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
@@ -50,13 +51,13 @@ public class CreateLibraryFromFilesDialog extends DialogWrapper {
private final LibraryNameAndLevelPanel myNameAndLevelPanel;
private final ModulesCombobox myModulesCombobox;
private final Project myProject;
private final List<VirtualFile> myRoots;
private final List<OrderRoot> myRoots;
private JPanel myPanel;
private final LibrariesContainer myLibrariesContainer;
private final String myDefaultName;
private final ModifiableRootModel myModifiableModel;
public CreateLibraryFromFilesDialog(@NotNull Project project, @NotNull List<VirtualFile> roots) {
public CreateLibraryFromFilesDialog(@NotNull Project project, @NotNull List<OrderRoot> roots) {
super(project, true);
setTitle("Create Library");
myProject = project;
@@ -114,15 +115,15 @@ public class CreateLibraryFromFilesDialog extends DialogWrapper {
}
@Nullable
private Module findModule(List<VirtualFile> files) {
for (VirtualFile file : files) {
private Module findModule(List<OrderRoot> roots) {
for (OrderRoot root : roots) {
Module module = null;
final VirtualFile local = JarFileSystem.getInstance().getVirtualFileForJar(file);
final VirtualFile local = JarFileSystem.getInstance().getVirtualFileForJar(root.getFile());
if (local != null) {
module = ModuleUtil.findModuleForFile(local, myProject);
}
if (module == null) {
module = ModuleUtil.findModuleForFile(file, myProject);
module = ModuleUtil.findModuleForFile(root.getFile(), myProject);
}
if (module != null) {
return module;
@@ -136,21 +137,20 @@ public class CreateLibraryFromFilesDialog extends DialogWrapper {
return myNameAndLevelPanel.getLibraryNameField();
}
private static String suggestLibraryName(List<VirtualFile> files) {
if (files.size() >= 1) {
return FileUtil.getNameWithoutExtension(PathUtil.getFileName(files.get(0).getPath()));
private static String suggestLibraryName(List<OrderRoot> roots) {
if (roots.size() >= 1) {
return FileUtil.getNameWithoutExtension(PathUtil.getFileName(roots.get(0).getFile().getPath()));
}
return "unnamed";
}
@Override
protected void doOKAction() {
final VirtualFile[] roots = myRoots.toArray(new VirtualFile[myRoots.size()]);
final LibrariesContainer.LibraryLevel level = myNameAndLevelPanel.getLibraryLevel();
AccessToken token = WriteAction.start();
try {
final Library library = myLibrariesContainer.createLibrary(myNameAndLevelPanel.getLibraryName(),
level, roots, VirtualFile.EMPTY_ARRAY);
level, myRoots);
if (level == LibrariesContainer.LibraryLevel.MODULE) {
myModifiableModel.commit();
}
@@ -21,6 +21,9 @@ import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.roots.libraries.ui.OrderRoot;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.DefaultLibraryRootsComponentDescriptor;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.RootDetectionUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
@@ -38,41 +41,57 @@ public class MarkLibraryRootAction extends AnAction {
final Project project = getEventProject(e);
if (project == null) return;
final List<VirtualFile> jars = getJarRoots(e);
final List<VirtualFile> jars = getRoots(e);
if (jars.isEmpty()) return;
new CreateLibraryFromFilesDialog(project, jars).show();
final List<OrderRoot> roots = RootDetectionUtil.detectRoots(jars, null, project, new DefaultLibraryRootsComponentDescriptor().getRootDetectors(), true);
new CreateLibraryFromFilesDialog(project, roots).show();
}
@NotNull
private static List<VirtualFile> getJarRoots(AnActionEvent e) {
private static List<VirtualFile> getRoots(AnActionEvent e) {
final Project project = getEventProject(e);
final VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
if (project == null || files == null || files.length == 0) return Collections.emptyList();
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
List<VirtualFile> archives = new ArrayList<VirtualFile>();
List<VirtualFile> roots = new ArrayList<VirtualFile>();
for (VirtualFile file : files) {
addJarRoot(archives, file, fileIndex);
if (file.isDirectory()) {
for (VirtualFile child : file.getChildren()) {
addJarRoot(archives, child, fileIndex);
roots.add(file);
}
else {
final VirtualFile root = JarFileSystem.getInstance().getJarRootForLocalFile(file);
if (root != null) {
roots.add(root);
}
}
}
return archives;
}
private static void addJarRoot(List<VirtualFile> archives, VirtualFile file, ProjectFileIndex index) {
final VirtualFile root = JarFileSystem.getInstance().getJarRootForLocalFile(file);
if (root != null && !index.isInLibraryClasses(root)) {
archives.add(root);
}
return roots;
}
@Override
public void update(AnActionEvent e) {
boolean visible = !getJarRoots(e).isEmpty();
final Project project = getEventProject(e);
boolean visible = false;
if (project != null) {
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
for (VirtualFile root : getRoots(e)) {
if (!root.isInLocalFileSystem() && !fileIndex.isInLibraryClasses(root)) {
visible = true;
break;
}
if (root.isInLocalFileSystem() && root.isDirectory()) {
for (VirtualFile child : root.getChildren()) {
final VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(child);
if (jarRoot != null && !fileIndex.isInLibraryClasses(child)) {
visible = true;
break;
}
}
}
}
}
e.getPresentation().setVisible(visible);
e.getPresentation().setEnabled(visible);
}
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.roots.ui.configuration.libraryEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.TitlePanel;
import com.intellij.openapi.vfs.VfsUtil;
@@ -28,8 +29,9 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* This dialog allows selecting source paths inside selected source archives or directories.
@@ -41,7 +43,7 @@ public class DetectedSourceRootsDialog extends DialogWrapper {
/**
* A tree with paths. The tree relies on the CheckboxTree for selection and unselection policy.
*/
private final CheckboxTree myTree;
private CheckboxTree myTree;
/**
* Root node for the tree. The tree is three-level:
* <ul>
@@ -50,37 +52,27 @@ public class DetectedSourceRootsDialog extends DialogWrapper {
* <li>The third level are paths with java sources inside pervious selection.</li>
* </ul>
*/
private final CheckedTreeNode myRootNode;
/**
* A scrollable pane that contains myTree
*/
private final JScrollPane myPane;
private CheckedTreeNode myRootNode;
private JScrollPane myPane;
public DetectedSourceRootsDialog(Component component, List<SuggestedChildRootInfo> suggestedRoots) {
this(component, createTree(suggestedRoots));
super(component, true);
init(suggestedRoots);
}
/**
* A constructor
*
* @param component a parent component
* @param tree a checkbox tree to use
*/
private DetectedSourceRootsDialog(Component component, CheckedTreeNode tree) {
super(component, true);
myRootNode = tree;
public DetectedSourceRootsDialog(Project project, List<SuggestedChildRootInfo> suggestedRoots) {
super(project, true);
init(suggestedRoots);
}
private void init(List<SuggestedChildRootInfo> suggestedRoots) {
myRootNode = createTree(suggestedRoots);
myTree = createCheckboxTree();
myPane = ScrollPaneFactory.createScrollPane(myTree);
setTitle("Detected Source Roots");
init();
}
/**
* Create a checkbox tree component for this dialog
*
* @return a created component
*/
private CheckboxTree createCheckboxTree() {
CheckboxTree tree = new CheckboxTree(new CheckboxTree.CheckboxTreeCellRenderer(true) {
public void customizeRenderer(JTree tree,
@@ -18,6 +18,7 @@ package com.intellij.openapi.roots.ui.configuration.libraryEditor;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.LibraryProperties;
import com.intellij.openapi.roots.libraries.LibraryType;
import com.intellij.openapi.roots.libraries.ui.OrderRoot;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -44,4 +45,16 @@ public abstract class LibraryEditorBase implements LibraryEditor {
public abstract void setProperties(LibraryProperties properties);
public abstract void setType(@NotNull LibraryType<?> type);
@Override
public void addRoots(Collection<? extends OrderRoot> roots) {
for (OrderRoot root : roots) {
if (root.isJarDirectory()) {
addJarDirectory(root.getFile(), false, root.getType());
}
else {
addRoot(root.getFile(), root.getType());
}
}
}
}
@@ -384,15 +384,7 @@ public class LibraryRootsComponent implements Disposable, LibraryEditorComponent
if (!rootsToAttach.isEmpty()) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
final LibraryEditor libraryEditor = getLibraryEditor();
for (OrderRoot root : rootsToAttach) {
if (root.isJarDirectory()) {
libraryEditor.addJarDirectory(root.getFile(), false, root.getType());
}
else {
libraryEditor.addRoot(root.getFile(), root.getType());
}
}
getLibraryEditor().addRoots(rootsToAttach);
}
});
updatePropertiesLabel();
@@ -41,7 +41,7 @@ public class RootDetectionUtil {
}
public static List<OrderRoot> detectRoots(@NotNull final Collection<VirtualFile> rootCandidates,
@NotNull Component parentComponent,
@Nullable Component parentComponent,
@Nullable Project project,
@NotNull final List<? extends RootDetector> detectors,
boolean allowUserToSelectRootTypeIfNothingIsDetected) {
@@ -68,7 +68,9 @@ public class RootDetectionUtil {
}.queue();
if (!suggestedRoots.isEmpty()) {
final DetectedSourceRootsDialog dialog = new DetectedSourceRootsDialog(parentComponent, suggestedRoots);
final DetectedSourceRootsDialog dialog = parentComponent != null
? new DetectedSourceRootsDialog(parentComponent, suggestedRoots)
: new DetectedSourceRootsDialog(project, suggestedRoots);
dialog.show();
if (!dialog.isOK()) {
return Collections.emptyList();
@@ -18,6 +18,7 @@ package com.intellij.openapi.roots.ui.configuration.projectRoot;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.ui.OrderRoot;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.ExistingLibraryEditor;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor;
import com.intellij.openapi.util.text.StringUtil;
@@ -26,6 +27,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
/**
@@ -59,6 +61,9 @@ public interface LibrariesContainer {
Library createLibrary(@NotNull @NonNls String name, @NotNull LibraryLevel level,
@NotNull VirtualFile[] classRoots, @NotNull VirtualFile[] sourceRoots);
Library createLibrary(@NotNull @NonNls String name, @NotNull LibraryLevel level,
@NotNull Collection<? extends OrderRoot> roots);
Library createLibrary(@NotNull NewLibraryEditor libraryEditor, @NotNull LibraryLevel level);
@NotNull
@@ -24,6 +24,7 @@ import com.intellij.openapi.roots.impl.libraries.LibraryTableBase;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
import com.intellij.openapi.roots.libraries.ui.OrderRoot;
import com.intellij.openapi.roots.ui.configuration.LibraryTableModifiableModelProvider;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.ExistingLibraryEditor;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor;
@@ -40,6 +41,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
@@ -123,6 +125,16 @@ public class LibrariesContainerFactory {
return createLibrary(editor, level);
}
@Override
public Library createLibrary(@NotNull @NonNls String name,
@NotNull LibraryLevel level,
@NotNull Collection<? extends OrderRoot> roots) {
final NewLibraryEditor editor = new NewLibraryEditor();
editor.setName(name);
editor.addRoots(roots);
return createLibrary(editor, level);
}
@NotNull
public Library[] getAllLibraries() {
Library[] libraries = getLibraries(LibraryLevel.GLOBAL);