new framework detection: detection in wizard, initial

This commit is contained in:
nik
2011-08-08 13:18:52 +04:00
parent 92c3b773b6
commit 657424f3d4
16 changed files with 463 additions and 240 deletions
@@ -0,0 +1,54 @@
/*
* Copyright 2000-2011 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.ide.util.importProject;
import com.intellij.facet.Facet;
import com.intellij.facet.FacetConfiguration;
import com.intellij.facet.FacetType;
import com.intellij.framework.detection.DetectedFrameworkDescription;
import com.intellij.framework.detection.impl.FrameworkDetectionContextBase;
import com.intellij.ide.util.projectWizard.SourcePathsBuilder;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* @author nik
*/
public class FrameworkDetectionInWizardContext extends FrameworkDetectionContextBase {
private final SourcePathsBuilder myBuilder;
public FrameworkDetectionInWizardContext(SourcePathsBuilder builder) {
myBuilder = builder;
}
@NotNull
@Override
public <F extends Facet, C extends FacetConfiguration> List<? extends DetectedFrameworkDescription> createDetectedFacetDescriptions(@NotNull FacetType<F, C> facetType,
@NotNull Collection<VirtualFile> files,
@NotNull FacetConfigurationCreator<C> creator) {
return Collections.emptyList();
}
public VirtualFile getBaseDir() {
final String path = myBuilder.getContentEntryPath();
return path != null ? LocalFileSystem.getInstance().refreshAndFindFileByPath(path) : null;
}
}
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.ide.util.importProject.FacetDetectionStep">
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.ide.util.importProject.FrameworkDetectionStep">
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="5" left="5" bottom="5" right="5"/>
<constraints>
@@ -8,15 +8,15 @@
<properties/>
<border type="none"/>
<children>
<component id="586a7" class="javax.swing.JLabel" binding="myFacetsDetectedLabel">
<component id="586a7" class="javax.swing.JLabel" binding="myFrameworksDetectedLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/ProjectBundle" key="label.text.the.following.facets.are.detected"/>
<text resource-bundle="messages/ProjectBundle" key="label.text.the.following.frameworks.are.detected"/>
</properties>
</component>
<grid id="16a29" binding="myFacetsTreePanel" layout-manager="BorderLayout" hgap="0" vgap="0">
<grid id="16a29" binding="myFrameworksPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
@@ -23,21 +23,24 @@ import com.intellij.facet.autodetecting.UnderlyingFacetSelector;
import com.intellij.facet.impl.autodetecting.FacetDetectorForWizardRegistry;
import com.intellij.facet.impl.autodetecting.FacetDetectorRegistryEx;
import com.intellij.facet.impl.autodetecting.FileContentPattern;
import com.intellij.facet.impl.autodetecting.facetsTree.DetectedFacetsTreeComponent;
import com.intellij.facet.impl.ui.FacetDetectionProcessor;
import com.intellij.framework.detection.DetectedFrameworkDescription;
import com.intellij.framework.detection.DetectionExcludesConfiguration;
import com.intellij.framework.detection.FrameworkDetectionContext;
import com.intellij.framework.detection.impl.FrameworkDetectionProcessor;
import com.intellij.framework.detection.impl.ui.DetectedFrameworksComponent;
import com.intellij.ide.util.newProjectWizard.ProjectFromSourcesBuilder;
import com.intellij.ide.util.projectWizard.AbstractStepWithProgress;
import com.intellij.ide.util.projectWizard.SourcePathsBuilder;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.PlatformModifiableModelsProvider;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Ref;
import com.intellij.ui.ScrollPaneFactory;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -45,28 +48,26 @@ import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author nik
*/
public abstract class FacetDetectionStep extends AbstractStepWithProgress<Map<ModuleDescriptor, Map<File, List<FacetDetectionProcessor.DetectedInWizardFacetInfo>>>>
public abstract class FrameworkDetectionStep extends AbstractStepWithProgress<List<DetectedFrameworkDescription>>
implements ProjectFromSourcesBuilder.ProjectConfigurationUpdater {
private final Icon myIcon;
private final ModuleType myModuleType;
private List<File> myLastRoots = null;
private final DetectedFacetsTreeComponent myDetectedFacetsComponent;
private final DetectedFrameworksComponent myDetectedFrameworksComponent;
private JPanel myMainPanel;
private JPanel myFacetsTreePanel;
private JLabel myFacetsDetectedLabel;
private JPanel myFrameworksPanel;
private JLabel myFrameworksDetectedLabel;
private final FrameworkDetectionContext myContext;
public FacetDetectionStep(final Icon icon, ModuleType moduleType) {
super(ProjectBundle.message("message.text.stop.searching.for.facets", ApplicationNamesInfo.getInstance().getProductName()));
public FrameworkDetectionStep(final Icon icon, SourcePathsBuilder builder) {
super(ProjectBundle.message("message.text.stop.searching.for.frameworks", ApplicationNamesInfo.getInstance().getProductName()));
myIcon = icon;
myModuleType = moduleType;
myDetectedFacetsComponent = new DetectedFacetsTreeComponent();
myContext = new FrameworkDetectionInWizardContext(builder);
myDetectedFrameworksComponent = new DetectedFrameworksComponent(myContext);
}
public void updateDataModel() {
@@ -77,38 +78,28 @@ public abstract class FacetDetectionStep extends AbstractStepWithProgress<Map<Mo
}
protected String getProgressText() {
return ProjectBundle.message("progress.text.searching.facets");
return ProjectBundle.message("progress.text.searching.frameworks");
}
protected JComponent createResultsPanel() {
JPanel mainPanel = myDetectedFacetsComponent.getMainPanel();
myFacetsTreePanel.add(ScrollPaneFactory.createScrollPane(mainPanel), BorderLayout.CENTER);
JComponent mainPanel = myDetectedFrameworksComponent.getMainPanel();
myFrameworksPanel.add(mainPanel, BorderLayout.CENTER);
return myMainPanel;
}
protected Map<ModuleDescriptor, Map<File, List<FacetDetectionProcessor.DetectedInWizardFacetInfo>>> calculate() {
protected List<DetectedFrameworkDescription> calculate() {
myLastRoots = getRoots();
ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
Map<ModuleDescriptor, Map<File, List<FacetDetectionProcessor.DetectedInWizardFacetInfo>>> result = new HashMap<ModuleDescriptor, Map<File, List<FacetDetectionProcessor.DetectedInWizardFacetInfo>>>();
List<File> roots = new ArrayList<File>();
for (ModuleDescriptor moduleDescriptor : getModuleDescriptors()) {
Map<File, List<FacetDetectionProcessor.DetectedInWizardFacetInfo>> root2Facets = new HashMap<File, List<FacetDetectionProcessor.DetectedInWizardFacetInfo>>();
for (File root : moduleDescriptor.getContentRoots()) {
FacetDetectionProcessor processor = new FacetDetectionProcessor(progressIndicator, myModuleType);
processor.process(root);
List<FacetDetectionProcessor.DetectedInWizardFacetInfo> facets = processor.getDetectedFacetsInfos();
if (!facets.isEmpty()) {
root2Facets.put(root, facets);
}
}
if (!root2Facets.isEmpty()) {
result.put(moduleDescriptor, root2Facets);
}
roots.addAll(moduleDescriptor.getContentRoots());
}
List<DetectedFrameworkDescription> result = new ArrayList<DetectedFrameworkDescription>();
FrameworkDetectionProcessor processor = new FrameworkDetectionProcessor(progressIndicator, myContext);
processor.processRoots(roots);
return result;
}
@@ -122,17 +113,13 @@ public abstract class FacetDetectionStep extends AbstractStepWithProgress<Map<Mo
return roots;
}
protected void onFinished(final Map<ModuleDescriptor, Map<File, List<FacetDetectionProcessor.DetectedInWizardFacetInfo>>> result, final boolean canceled) {
myDetectedFacetsComponent.clear();
for (ModuleDescriptor moduleDescriptor : result.keySet()) {
myDetectedFacetsComponent.addFacets(moduleDescriptor, result.get(moduleDescriptor));
}
myDetectedFacetsComponent.createTree();
protected void onFinished(final List<DetectedFrameworkDescription> result, final boolean canceled) {
myDetectedFrameworksComponent.getTree().rebuildTree(result);
if (result.isEmpty()) {
myFacetsDetectedLabel.setText(ProjectBundle.message("label.text.no.facets.detected"));
myFrameworksDetectedLabel.setText(ProjectBundle.message("label.text.no.frameworks.detected"));
}
else {
myFacetsDetectedLabel.setText(ProjectBundle.message("label.text.the.following.facets.are.detected"));
myFrameworksDetectedLabel.setText(ProjectBundle.message("label.text.the.following.frameworks.are.detected"));
}
}
@@ -167,7 +154,11 @@ public abstract class FacetDetectionStep extends AbstractStepWithProgress<Map<Mo
return "reference.dialogs.new.project.fromCode.facets";
}
public void updateModule(final ModuleDescriptor descriptor, final Module module, final ModifiableRootModel rootModel) {
myDetectedFacetsComponent.createFacets(descriptor, module, rootModel);
public void updateProject(@NotNull Project project) {
final PlatformModifiableModelsProvider modelsProvider = new PlatformModifiableModelsProvider();
for (DetectedFrameworkDescription description : myDetectedFrameworksComponent.getSelectedFrameworks()) {
description.configureFramework(modelsProvider);
}
myDetectedFrameworksComponent.processUncheckedNodes(DetectionExcludesConfiguration.getInstance(project));
}
}
@@ -24,7 +24,8 @@ import com.intellij.ide.util.projectWizard.ExistingModuleLoader;
import com.intellij.ide.util.projectWizard.ModuleBuilder;
import com.intellij.ide.util.projectWizard.ProjectBuilder;
import com.intellij.ide.util.projectWizard.SourcePathsBuilder;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.module.*;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
@@ -36,7 +37,6 @@ import com.intellij.openapi.roots.libraries.LibraryTable;
import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.Pair;
@@ -96,101 +96,106 @@ public class ProjectFromSourcesBuilder extends ProjectBuilder implements SourceP
final LibraryTable projectLibraryTable = LibraryTablesRegistrar.getInstance().getLibraryTable(project);
final Map<LibraryDescriptor, Library> projectLibs = new HashMap<LibraryDescriptor, Library>();
final List<Module> result = new ArrayList<Module>();
// create project-level libraries
Exception e = ApplicationManager.getApplication().runWriteAction(new Computable<Exception>() {
public Exception compute() {
try {
for (LibraryDescriptor lib : myChosenLibraries) {
if (lib.getLevel() == LibraryDescriptor.Level.PROJECT) {
final Collection<File> files = lib.getJars();
final Library projectLib = projectLibraryTable.createLibrary(lib.getName());
final Library.ModifiableModel model = projectLib.getModifiableModel();
for (File file : files) {
model.addRoot(VfsUtil.getUrlForLibraryRoot(file), OrderRootType.CLASSES);
}
model.commit();
projectLibs.put(lib, projectLib);
try {
AccessToken token = WriteAction.start();
try {
// create project-level libraries
for (LibraryDescriptor lib : myChosenLibraries) {
if (lib.getLevel() == LibraryDescriptor.Level.PROJECT) {
final Collection<File> files = lib.getJars();
final Library projectLib = projectLibraryTable.createLibrary(lib.getName());
final Library.ModifiableModel libraryModel = projectLib.getModifiableModel();
for (File file : files) {
libraryModel.addRoot(VfsUtil.getUrlForLibraryRoot(file), OrderRootType.CLASSES);
}
libraryModel.commit();
projectLibs.put(lib, projectLib);
}
return null;
}
catch (Exception e) {
return e;
}
}
});
if (e != null) {
finally {
token.finish();
}
}
catch (Exception e) {
Messages.showErrorDialog(IdeBundle.message("error.adding.module.to.project", e.getMessage()), IdeBundle.message("title.add.module"));
}
// create modules and set up dependencies
final Map<String, String> sourceRootToPrefixMap = new HashMap<String, String>();
for (Pair<String, String> pair : getSourcePaths()) {
sourceRootToPrefixMap.put(FileUtil.toSystemIndependentName(pair.getFirst()), pair.getSecond());
}
final Map<ModuleDescriptor, Module> descriptorToModuleMap = new HashMap<ModuleDescriptor, Module>();
Exception ex = ApplicationManager.getApplication().runWriteAction(new Computable<Exception>() {
public Exception compute() {
try {
final ModifiableModuleModel moduleModel = model != null ? model : ModuleManager.getInstance(project).getModifiableModel();
for (final ModuleDescriptor moduleDescriptor : myChosenModules) {
final Module module;
if (moduleDescriptor.isReuseExistingElement()) {
final ExistingModuleLoader moduleLoader = ImportImlMode.setUpLoader(FileUtil.toSystemIndependentName(moduleDescriptor.computeModuleFilePath()));
module = moduleLoader.createModule(moduleModel);
}
else {
module = createModule(project, moduleDescriptor, sourceRootToPrefixMap, projectLibs, moduleModel);
}
result.add(module);
descriptorToModuleMap.put(moduleDescriptor, module);
try {
AccessToken token = WriteAction.start();
try {
final ModifiableModuleModel moduleModel = model != null ? model : ModuleManager.getInstance(project).getModifiableModel();
for (final ModuleDescriptor moduleDescriptor : myChosenModules) {
final Module module;
if (moduleDescriptor.isReuseExistingElement()) {
final ExistingModuleLoader moduleLoader =
ImportImlMode.setUpLoader(FileUtil.toSystemIndependentName(moduleDescriptor.computeModuleFilePath()));
module = moduleLoader.createModule(moduleModel);
}
moduleModel.commit();
else {
module = createModule(moduleDescriptor, sourceRootToPrefixMap, projectLibs, moduleModel);
}
result.add(module);
descriptorToModuleMap.put(moduleDescriptor, module);
}
catch (Exception e) {
return e;
}
return null;
moduleModel.commit();
}
finally {
token.finish();
}
});
if (ex != null) {
Messages.showErrorDialog(IdeBundle.message("error.adding.module.to.project", ex.getMessage()), IdeBundle.message("title.add.module"));
}
catch (Exception e) {
Messages.showErrorDialog(IdeBundle.message("error.adding.module.to.project", e.getMessage()), IdeBundle.message("title.add.module"));
}
// setup dependencies between modules
ex = ApplicationManager.getApplication().runWriteAction(new Computable<Exception>() {
public Exception compute() {
try {
for (final ModuleDescriptor descriptor : myChosenModules) {
final Module module = descriptorToModuleMap.get(descriptor);
if (module == null) {
continue;
}
final Set<ModuleDescriptor> deps = descriptor.getDependencies();
if (deps.size() == 0) {
continue;
}
final ModifiableRootModel rootModel = ModuleRootManager.getInstance(module).getModifiableModel();
for (ModuleDescriptor dependentDescriptor : deps) {
final Module dependentModule = descriptorToModuleMap.get(dependentDescriptor);
if (dependentModule != null) {
rootModel.addModuleOrderEntry(dependentModule);
}
}
rootModel.commit();
try {
AccessToken token = WriteAction.start();
try {
for (final ModuleDescriptor descriptor : myChosenModules) {
final Module module = descriptorToModuleMap.get(descriptor);
if (module == null) {
continue;
}
final Set<ModuleDescriptor> deps = descriptor.getDependencies();
if (deps.size() == 0) {
continue;
}
final ModifiableRootModel rootModel = ModuleRootManager.getInstance(module).getModifiableModel();
for (ModuleDescriptor dependentDescriptor : deps) {
final Module dependentModule = descriptorToModuleMap.get(dependentDescriptor);
if (dependentModule != null) {
rootModel.addModuleOrderEntry(dependentModule);
}
}
rootModel.commit();
}
catch (Exception e) {
return e;
}
return null;
}
});
if (ex != null) {
Messages.showErrorDialog(IdeBundle.message("error.adding.module.to.project", ex.getMessage()), IdeBundle.message("title.add.module"));
finally {
token.finish();
}
}
catch (Exception e) {
Messages.showErrorDialog(IdeBundle.message("error.adding.module.to.project", e.getMessage()), IdeBundle.message("title.add.module"));
}
AccessToken token = WriteAction.start();
try {
for (ProjectConfigurationUpdater updater : myUpdaters) {
updater.updateProject(project);
}
}
finally {
token.finish();
}
return result;
}
@@ -200,7 +205,7 @@ public class ProjectFromSourcesBuilder extends ProjectBuilder implements SourceP
}
@NotNull
public Module createModule(final Project project, final ModuleDescriptor descriptor, final Map<String, String> sourceRootToPrefixMap,
private Module createModule(final ModuleDescriptor descriptor, final Map<String, String> sourceRootToPrefixMap,
final Map<LibraryDescriptor, Library> projectLibs, final ModifiableModuleModel moduleModel)
throws InvalidDataException, IOException, ModuleWithNameAlreadyExists, JDOMException, ConfigurationException {
@@ -210,9 +215,6 @@ public class ProjectFromSourcesBuilder extends ProjectBuilder implements SourceP
final Module module = moduleModel.newModule(moduleFilePath, StdModuleTypes.JAVA);
final ModifiableRootModel modifiableModel = ModuleRootManager.getInstance(module).getModifiableModel();
setupRootModel(descriptor, modifiableModel, sourceRootToPrefixMap, projectLibs);
for (ProjectConfigurationUpdater updater : myUpdaters) {
updater.updateModule(descriptor, module, modifiableModel);
}
modifiableModel.commit();
return module;
}
@@ -310,10 +312,8 @@ public class ProjectFromSourcesBuilder extends ProjectBuilder implements SourceP
return available.contains(lib);
}
public static interface ProjectConfigurationUpdater {
void updateModule(final ModuleDescriptor descriptor, Module module, ModifiableRootModel rootModel);
public interface ProjectConfigurationUpdater {
void updateProject(@NotNull Project project);
}
@Override
@@ -70,14 +70,14 @@ public class CreateFromSourcesMode extends WizardMode {
sequence.addCommonStep(new ModulesDetectionStep(projectBuilder, moduleInsight, icon, "reference.dialogs.new.project.fromCode.page2"));
sequence.addCommonStep(factory.createProjectJdkStep(context));
if (FacetDetectionStep.isEnabled(StdModuleTypes.JAVA)) {
FacetDetectionStep facetDetectionStep = new FacetDetectionStep(icon, StdModuleTypes.JAVA) {
if (FrameworkDetectionStep.isEnabled(StdModuleTypes.JAVA)) {
FrameworkDetectionStep frameworkDetectionStep = new FrameworkDetectionStep(icon, projectBuilder) {
protected List<ModuleDescriptor> getModuleDescriptors() {
return projectBuilder.getModules();
}
};
projectBuilder.addConfigurationUpdater(facetDetectionStep);
sequence.addCommonStep(facetDetectionStep);
projectBuilder.addConfigurationUpdater(frameworkDetectionStep);
sequence.addCommonStep(frameworkDetectionStep);
}
return sequence;