From 64dd67f94336cf6c02b2b4961270a2a8b6d95867 Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 5 Feb 2014 12:14:37 +0400 Subject: [PATCH] create project from existing sources: refactored and tests added --- .../util/importProject/DetectedRootData.java | 2 +- .../importProject/RootDetectionProcessor.java | 82 ++++++++++++++++++- .../importProject/RootsDetectionStep.java | 82 +------------------ .../JavaSourceRootDetectionUtil.java | 2 +- .../impl/ProjectFromSourcesBuilderImpl.java | 5 +- .../ImportFromSourcesTestCase.java | 76 +++++++++++++++++ 6 files changed, 166 insertions(+), 83 deletions(-) create mode 100644 java/testFramework/src/com/intellij/ide/projectWizard/ImportFromSourcesTestCase.java diff --git a/java/idea-ui/src/com/intellij/ide/util/importProject/DetectedRootData.java b/java/idea-ui/src/com/intellij/ide/util/importProject/DetectedRootData.java index ec047b7edda8..b4bf4b17395e 100644 --- a/java/idea-ui/src/com/intellij/ide/util/importProject/DetectedRootData.java +++ b/java/idea-ui/src/com/intellij/ide/util/importProject/DetectedRootData.java @@ -26,7 +26,7 @@ import java.util.*; /** * @author nik */ -class DetectedRootData { +public class DetectedRootData { private final File myDirectory; private MultiMap myRoots = MultiMap.createLinked(); diff --git a/java/idea-ui/src/com/intellij/ide/util/importProject/RootDetectionProcessor.java b/java/idea-ui/src/com/intellij/ide/util/importProject/RootDetectionProcessor.java index 62f0f4a04aab..f7e2b88bd585 100644 --- a/java/idea-ui/src/com/intellij/ide/util/importProject/RootDetectionProcessor.java +++ b/java/idea-ui/src/com/intellij/ide/util/importProject/RootDetectionProcessor.java @@ -25,6 +25,8 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.SmartList; +import com.intellij.util.containers.MultiMap; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; @@ -41,6 +43,11 @@ public class RootDetectionProcessor { private final FileTypeManager myTypeManager; private final ProgressIndicator myProgressIndicator; + @NotNull + public static List detectRoots(@NotNull File baseProjectFile) { + return new RootDetectionProcessor(baseProjectFile, ProjectStructureDetector.EP_NAME.getExtensions()).detectRoots(); + } + public RootDetectionProcessor(File baseDir, final ProjectStructureDetector[] detectors) { myBaseDir = getCanonicalDir(baseDir); myDetectors = detectors; @@ -60,8 +67,18 @@ public class RootDetectionProcessor { } } + public static MultiMap createRootsMap(List list) { + MultiMap roots = new MultiMap(); + for (final DetectedRootData rootData : list) { + for (ProjectStructureDetector detector : rootData.getSelectedDetectors()) { + roots.putValue(detector, rootData.getSelectedRoot()); + } + } + return roots; + } - public Map> findRoots() { + + public Map> runDetectors() { if (!myBaseDir.isDirectory()) { return Collections.emptyMap(); } @@ -145,4 +162,67 @@ public class RootDetectionProcessor { } return parentsToSkip; } + + private static void removeIncompatibleRoots(DetectedProjectRoot root, Map rootData) { + DetectedRootData[] allRoots = rootData.values().toArray(new DetectedRootData[rootData.values().size()]); + for (DetectedRootData child : allRoots) { + final File childDirectory = child.getDirectory(); + if (FileUtil.isAncestor(root.getDirectory(), childDirectory, true)) { + for (DetectedProjectRoot projectRoot : child.getAllRoots()) { + if (!root.canContainRoot(projectRoot)) { + child.removeRoot(projectRoot); + } + } + if (child.getAllRoots().length == 0) { + rootData.remove(childDirectory); + } + } + } + } + + private static boolean isUnderIncompatibleRoot(DetectedProjectRoot root, Map rootData) { + File directory = root.getDirectory().getParentFile(); + while (directory != null) { + final DetectedRootData data = rootData.get(directory); + if (data != null) { + for (DetectedProjectRoot parentRoot : data.getAllRoots()) { + if (!parentRoot.canContainRoot(root)) { + return true; + } + } + } + directory = directory.getParentFile(); + } + return false; + } + + private List detectRoots() { + Map> roots = runDetectors(); + if (myProgressIndicator != null) { + myProgressIndicator.setText2("Processing " + roots.values().size() + " project roots..."); + } + + Map rootData = new LinkedHashMap(); + for (ProjectStructureDetector detector : roots.keySet()) { + for (DetectedProjectRoot detectedRoot : roots.get(detector)) { + if (isUnderIncompatibleRoot(detectedRoot, rootData)) { + continue; + } + + final DetectedRootData data = rootData.get(detectedRoot.getDirectory()); + if (data == null) { + rootData.put(detectedRoot.getDirectory(), new DetectedRootData(detector, detectedRoot)); + } + else { + detectedRoot = data.addRoot(detector, detectedRoot); + } + removeIncompatibleRoots(detectedRoot, rootData); + } + } + + if (myProgressIndicator != null) { + myProgressIndicator.setText2(""); + } + return new ArrayList(rootData.values()); + } } diff --git a/java/idea-ui/src/com/intellij/ide/util/importProject/RootsDetectionStep.java b/java/idea-ui/src/com/intellij/ide/util/importProject/RootsDetectionStep.java index 93d7c09ebb67..0717d0ca6c04 100644 --- a/java/idea-ui/src/com/intellij/ide/util/importProject/RootsDetectionStep.java +++ b/java/idea-ui/src/com/intellij/ide/util/importProject/RootsDetectionStep.java @@ -16,20 +16,15 @@ package com.intellij.ide.util.importProject; import com.intellij.ide.IdeBundle; -import com.intellij.ide.util.newProjectWizard.*; +import com.intellij.ide.util.newProjectWizard.StepSequence; import com.intellij.ide.util.projectWizard.AbstractStepWithProgress; import com.intellij.ide.util.projectWizard.WizardContext; -import com.intellij.ide.util.projectWizard.importSources.DetectedProjectRoot; import com.intellij.ide.util.projectWizard.importSources.ProjectStructureDetector; import com.intellij.ide.util.projectWizard.importSources.impl.ProjectFromSourcesBuilderImpl; import com.intellij.openapi.application.ApplicationNamesInfo; -import com.intellij.openapi.progress.ProgressIndicator; -import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.ui.MultiLineLabelUI; import com.intellij.openapi.ui.ex.MultiLineLabel; -import com.intellij.openapi.util.io.FileUtil; import com.intellij.ui.IdeBorderFactory; -import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -122,17 +117,8 @@ public class RootsDetectionStep extends AbstractStepWithProgress roots = new MultiMap(); final List selectedElements = myDetectedRootsChooser.getMarkedElements(); - for (final DetectedRootData rootData : selectedElements) { - for (ProjectStructureDetector detector : rootData.getSelectedDetectors()) { - roots.putValue(detector, rootData.getSelectedRoot()); - } - } - myBuilder.setProjectRoots(roots); - for (ProjectStructureDetector detector : roots.keySet()) { - detector.setupProjectStructure(roots.get(detector), myBuilder.getProjectDescriptor(detector), myBuilder); - } + myBuilder.setupProjectStructure(RootDetectionProcessor.createRootsMap(selectedElements)); updateSelectedTypes(); } @@ -177,71 +163,9 @@ public class RootsDetectionStep extends AbstractStepWithProgress> roots = new RootDetectionProcessor(baseProjectFile, - ProjectStructureDetector.EP_NAME.getExtensions()).findRoots(); - final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); - if (progressIndicator != null) { - progressIndicator.setText2("Processing " + roots.values().size() + " project roots..."); - } - - Map rootData = new LinkedHashMap(); - for (ProjectStructureDetector detector : roots.keySet()) { - for (DetectedProjectRoot detectedRoot : roots.get(detector)) { - if (isUnderIncompatibleRoot(detectedRoot, rootData)) { - continue; - } - - final DetectedRootData data = rootData.get(detectedRoot.getDirectory()); - if (data == null) { - rootData.put(detectedRoot.getDirectory(), new DetectedRootData(detector, detectedRoot)); - } - else { - detectedRoot = data.addRoot(detector, detectedRoot); - } - removeIncompatibleRoots(detectedRoot, rootData); - } - } - - if (progressIndicator != null) { - progressIndicator.setText2(""); - } - return new ArrayList(rootData.values()); + return RootDetectionProcessor.detectRoots(new File(baseProjectPath)); } - private static void removeIncompatibleRoots(DetectedProjectRoot root, Map rootData) { - DetectedRootData[] allRoots = rootData.values().toArray(new DetectedRootData[rootData.values().size()]); - for (DetectedRootData child : allRoots) { - final File childDirectory = child.getDirectory(); - if (FileUtil.isAncestor(root.getDirectory(), childDirectory, true)) { - for (DetectedProjectRoot projectRoot : child.getAllRoots()) { - if (!root.canContainRoot(projectRoot)) { - child.removeRoot(projectRoot); - } - } - if (child.getAllRoots().length == 0) { - rootData.remove(childDirectory); - } - } - } - } - - - private static boolean isUnderIncompatibleRoot(DetectedProjectRoot root, Map rootData) { - File directory = root.getDirectory().getParentFile(); - while (directory != null) { - final DetectedRootData data = rootData.get(directory); - if (data != null) { - for (DetectedProjectRoot parentRoot : data.getAllRoots()) { - if (!parentRoot.canContainRoot(root)) { - return true; - } - } - } - directory = directory.getParentFile(); - } - return false; - } @Nullable private String getBaseProjectPath() { diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/JavaSourceRootDetectionUtil.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/JavaSourceRootDetectionUtil.java index f83a8abb1619..47665a6befe7 100644 --- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/JavaSourceRootDetectionUtil.java +++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/JavaSourceRootDetectionUtil.java @@ -48,7 +48,7 @@ public class JavaSourceRootDetectionUtil { public static Collection suggestRoots(@NotNull File dir) { final List detectors = ContainerUtil.findAll(ProjectStructureDetector.EP_NAME.getExtensions(), JavaSourceRootDetector.class); final RootDetectionProcessor processor = new RootDetectionProcessor(dir, detectors.toArray(new JavaSourceRootDetector[detectors.size()])); - final Map> rootsMap = processor.findRoots(); + final Map> rootsMap = processor.runDetectors(); Map result = new HashMap(); for (List roots : rootsMap.values()) { diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java index 1c33c8efdfe4..6b4fe75e7fa6 100644 --- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java +++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/importSources/impl/ProjectFromSourcesBuilderImpl.java @@ -128,8 +128,11 @@ public class ProjectFromSourcesBuilderImpl extends ProjectImportBuilder implemen return myBaseProjectPath; } - public void setProjectRoots(MultiMap roots) { + public void setupProjectStructure(MultiMap roots) { myRoots = roots; + for (ProjectStructureDetector detector : roots.keySet()) { + detector.setupProjectStructure(roots.get(detector), getProjectDescriptor(detector), this); + } } @NotNull diff --git a/java/testFramework/src/com/intellij/ide/projectWizard/ImportFromSourcesTestCase.java b/java/testFramework/src/com/intellij/ide/projectWizard/ImportFromSourcesTestCase.java new file mode 100644 index 000000000000..f52a623514f4 --- /dev/null +++ b/java/testFramework/src/com/intellij/ide/projectWizard/ImportFromSourcesTestCase.java @@ -0,0 +1,76 @@ +/* + * Copyright 2000-2014 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.projectWizard; + +import com.intellij.ide.util.importProject.DetectedRootData; +import com.intellij.ide.util.importProject.RootDetectionProcessor; +import com.intellij.ide.util.projectWizard.WizardContext; +import com.intellij.ide.util.projectWizard.importSources.impl.ProjectFromSourcesBuilderImpl; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ui.configuration.ModulesProvider; +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.testFramework.PlatformTestCase; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.List; + +/** + * @author nik + */ +public abstract class ImportFromSourcesTestCase extends PlatformTestCase { + private ProjectFromSourcesBuilderImpl myBuilder; + private File myRootDir; + + @Override + public void setUp() throws Exception { + super.setUp(); + myBuilder = new ProjectFromSourcesBuilderImpl(new WizardContext(null), ModulesProvider.EMPTY_MODULES_PROVIDER); + } + + @Override + protected void setUpProject() throws Exception { + } + + protected Module assertOneModule(@NotNull ModuleType moduleType) { + Module module = assertOneElement(ModuleManager.getInstance(myProject).getModules()); + assertEquals(moduleType, ModuleType.get(module)); + return module; + } + + protected void assertOneContentRoot(@NotNull Module module, String relativePath) { + File expected = new File(myRootDir, relativePath); + String url = assertOneElement(ModuleRootManager.getInstance(module).getContentRootUrls()); + File actual = new File(VfsUtilCore.urlToPath(url)); + assertEquals(expected.getAbsolutePath(), actual.getAbsolutePath()); + } + + protected void importFromSources(File dir) { + myRootDir = dir; + try { + myProject = doCreateProject(getIprFile()); + List list = RootDetectionProcessor.detectRoots(dir); + myBuilder.setupProjectStructure(RootDetectionProcessor.createRootsMap(list)); + myBuilder.commit(myProject, null, ModulesProvider.EMPTY_MODULES_PROVIDER); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } +}