@Override public void cleanup() { myOpenProjectSettingsAfter = false; myProjectRoot = null; myFoundOtpApps = Collections.emptyList(); mySelectedOtpApps = Collections.emptyList(); }
@NotNull public Collection<? extends PackagingSourceItem> getSourceItems( @NotNull ArtifactEditorContext editorContext, @NotNull Artifact artifact, PackagingSourceItem parent) { if (parent == null) { return createModuleItems(editorContext, artifact, ArrayUtil.EMPTY_STRING_ARRAY); } else if (parent instanceof ModuleGroupItem) { return createModuleItems(editorContext, artifact, ((ModuleGroupItem) parent).getPath()); } else if (parent instanceof ModuleSourceItemGroup) { return createClasspathItems( editorContext, artifact, ((ModuleSourceItemGroup) parent).getModule()); } return Collections.emptyList(); }
public static void addLibrary( Module module, ModifiableRootModel model, String libName, String libPath, String... jarArr) { List<VirtualFile> classesRoots = new ArrayList<>(); for (String jar : jarArr) { if (!libPath.endsWith("/") && !jar.startsWith("/")) { jar = "/" + jar; } String path = libPath + jar; VirtualFile root; if (path.endsWith(".jar")) { root = JarFileSystem.getInstance().refreshAndFindFileByPath(path + "!/"); } else { root = LocalFileSystem.getInstance().refreshAndFindFileByPath(path); } assert root != null : "Library root folder not found: " + path + "!/"; classesRoots.add(root); } addProjectLibrary(module, model, libName, classesRoots, Collections.emptyList()); }
@NotNull private List<Pair<PsiClass, VirtualFile>> doFindClasses( @NotNull String qName, @NotNull final GlobalSearchScope scope) { final Collection<PsiClass> classes = JavaFullClassNameIndex.getInstance().get(qName.hashCode(), myManager.getProject(), scope); if (classes.isEmpty()) return Collections.emptyList(); List<Pair<PsiClass, VirtualFile>> result = new ArrayList<>(classes.size()); for (PsiClass aClass : classes) { final String qualifiedName = aClass.getQualifiedName(); if (qualifiedName == null || !qualifiedName.equals(qName)) continue; PsiFile file = aClass.getContainingFile(); if (file == null) { throw new AssertionError("No file for class: " + aClass + " of " + aClass.getClass()); } final boolean valid = file.isValid(); VirtualFile vFile = file.getVirtualFile(); if (!valid) { LOG.error( "Invalid file " + file + "; virtualFile:" + vFile + (vFile != null && !vFile.isValid() ? " (invalid)" : "") + "; id=" + (vFile == null ? 0 : ((VirtualFileWithId) vFile).getId()), new PsiInvalidElementAccessException(aClass)); continue; } if (!hasAcceptablePackage(vFile)) continue; result.add(Pair.create(aClass, vFile)); } return result; }
public static void addProjectLibrary(Module module, String libName, VirtualFile... classesRoots) { addProjectLibrary(module, libName, Arrays.asList(classesRoots), Collections.emptyList()); }
public class RebarProjectImportBuilder extends ProjectImportBuilder<ImportedOtpApp> { private static final Logger LOG = Logger.getInstance(RebarProjectImportBuilder.class); private boolean myOpenProjectSettingsAfter = false; @Nullable private VirtualFile myProjectRoot = null; @NotNull private List<ImportedOtpApp> myFoundOtpApps = Collections.emptyList(); @NotNull private List<ImportedOtpApp> mySelectedOtpApps = Collections.emptyList(); private boolean myImportExamples; @NotNull private String myRebarPath = ""; private boolean myIsImportingProject; @NotNull @NonNls @Override public String getName() { return "Rebar"; } @Override public Icon getIcon() { return ErlangIcons.REBAR; } @Override public boolean isSuitableSdkType(@NotNull SdkTypeId sdkType) { return sdkType == ErlangSdkType.getInstance(); } @Override public List<ImportedOtpApp> getList() { return new ArrayList<ImportedOtpApp>(myFoundOtpApps); } @Override public void setList(@Nullable List<ImportedOtpApp> selectedOtpApps) throws ConfigurationException { if (selectedOtpApps != null) { mySelectedOtpApps = selectedOtpApps; } } @Override public boolean isMarked(@Nullable ImportedOtpApp importedOtpApp) { return importedOtpApp != null && mySelectedOtpApps.contains(importedOtpApp); } @Override public boolean isOpenProjectSettingsAfter() { return myOpenProjectSettingsAfter; } @Override public void setOpenProjectSettingsAfter(boolean openProjectSettingsAfter) { myOpenProjectSettingsAfter = openProjectSettingsAfter; } @Override public void cleanup() { myOpenProjectSettingsAfter = false; myProjectRoot = null; myFoundOtpApps = Collections.emptyList(); mySelectedOtpApps = Collections.emptyList(); } public boolean setProjectRoot(@NotNull final VirtualFile projectRoot) { if (projectRoot.equals(myProjectRoot)) { return true; } boolean unitTestMode = ApplicationManager.getApplication().isUnitTestMode(); myProjectRoot = projectRoot; if (!unitTestMode && projectRoot instanceof VirtualDirectoryImpl) { ((VirtualDirectoryImpl) projectRoot).refreshAndFindChild("deps"); } ProgressManager.getInstance() .run( new Task.Modal(getCurrentProject(), "Scanning Rebar projects", true) { public void run(@NotNull final ProgressIndicator indicator) { List<VirtualFile> rebarConfigFiles = findRebarConfigs(myProjectRoot, indicator); final LinkedHashSet<ImportedOtpApp> importedOtpApps = new LinkedHashSet<ImportedOtpApp>(rebarConfigFiles.size()); VfsUtilCore.visitChildrenRecursively( projectRoot, new VirtualFileVisitor() { @Override public boolean visitFile(@NotNull VirtualFile file) { indicator.checkCanceled(); if (file.isDirectory()) { indicator.setText2(file.getPath()); if (isExamplesDirectory(file) || isRelDirectory(projectRoot.getPath(), file.getPath())) return false; } ContainerUtil.addAllNotNull(importedOtpApps, createImportedOtpApp(file)); return true; } }); myFoundOtpApps = ContainerUtil.newArrayList(importedOtpApps); } }); Collections.sort( myFoundOtpApps, new Comparator<ImportedOtpApp>() { @Override public int compare(ImportedOtpApp o1, ImportedOtpApp o2) { int nameCompareResult = String.CASE_INSENSITIVE_ORDER.compare(o1.getName(), o2.getName()); if (nameCompareResult == 0) { return String.CASE_INSENSITIVE_ORDER.compare( o1.getRoot().getPath(), o2.getRoot().getPath()); } return nameCompareResult; } }); mySelectedOtpApps = myFoundOtpApps; return !myFoundOtpApps.isEmpty(); } private static boolean isRelDirectory(String projectRootPath, String path) { return (projectRootPath + "/rel").equals(path); } @SuppressWarnings("DialogTitleCapitalization") @Override public boolean validate(Project current, Project dest) { if (!findIdeaModuleFiles(mySelectedOtpApps)) { return true; } int resultCode = Messages.showYesNoCancelDialog( ApplicationInfoEx.getInstanceEx().getFullApplicationName() + " module files found:\n\n" + StringUtil.join( mySelectedOtpApps, new Function<ImportedOtpApp, String>() { public String fun(ImportedOtpApp importedOtpApp) { VirtualFile ideaModuleFile = importedOtpApp.getIdeaModuleFile(); return ideaModuleFile != null ? " " + ideaModuleFile.getPath() + "\n" : ""; } }, "") + "\nWould you like to reuse them?", "Module files found", Messages.getQuestionIcon()); if (resultCode == DialogWrapper.OK_EXIT_CODE) { return true; } else if (resultCode == DialogWrapper.CANCEL_EXIT_CODE) { try { deleteIdeaModuleFiles(mySelectedOtpApps); return true; } catch (IOException e) { LOG.error(e); return false; } } else { return false; } } @Override public List<Module> commit( @NotNull Project project, @Nullable ModifiableModuleModel moduleModel, @NotNull ModulesProvider modulesProvider, @Nullable ModifiableArtifactModel modifiableArtifactModel) { Set<String> selectedAppNames = ContainerUtil.newHashSet(); for (ImportedOtpApp importedOtpApp : mySelectedOtpApps) { selectedAppNames.add(importedOtpApp.getName()); } Sdk projectSdk = fixProjectSdk(project); List<Module> createdModules = new ArrayList<Module>(); final List<ModifiableRootModel> createdRootModels = new ArrayList<ModifiableRootModel>(); final ModifiableModuleModel obtainedModuleModel = moduleModel != null ? moduleModel : ModuleManager.getInstance(project).getModifiableModel(); for (ImportedOtpApp importedOtpApp : mySelectedOtpApps) { VirtualFile ideaModuleDir = importedOtpApp.getRoot(); String ideaModuleFile = ideaModuleDir.getCanonicalPath() + File.separator + importedOtpApp.getName() + ".iml"; Module module = obtainedModuleModel.newModule(ideaModuleFile, ErlangModuleType.getInstance().getId()); createdModules.add(module); importedOtpApp.setModule(module); if (importedOtpApp.getIdeaModuleFile() == null) { ModifiableRootModel rootModel = ModuleRootManager.getInstance(module).getModifiableModel(); // Make it inherit SDK from the project. rootModel.inheritSdk(); // Initialize source and test paths. ContentEntry content = rootModel.addContentEntry(importedOtpApp.getRoot()); addSourceDirToContent(content, ideaModuleDir, "src", false); addSourceDirToContent(content, ideaModuleDir, "test", true); addIncludeDirectories(content, importedOtpApp); // Exclude standard folders excludeDirFromContent(content, ideaModuleDir, "doc"); // Initialize output paths according to Rebar conventions. CompilerModuleExtension compilerModuleExt = rootModel.getModuleExtension(CompilerModuleExtension.class); compilerModuleExt.inheritCompilerOutputPath(false); compilerModuleExt.setCompilerOutputPath(ideaModuleDir + File.separator + "ebin"); compilerModuleExt.setCompilerOutputPathForTests(ideaModuleDir + File.separator + ".eunit"); createdRootModels.add(rootModel); // Set inter-module dependencies resolveModuleDeps(rootModel, importedOtpApp, projectSdk, selectedAppNames); } } // Commit project structure. LOG.info("Commit project structure"); ApplicationManager.getApplication() .runWriteAction( new Runnable() { public void run() { for (ModifiableRootModel rootModel : createdRootModels) { rootModel.commit(); } obtainedModuleModel.commit(); } }); addErlangFacets(mySelectedOtpApps); RebarSettings.getInstance(project).setRebarPath(myRebarPath); if (myIsImportingProject) { ErlangCompilerSettings.getInstance(project).setUseRebarCompilerEnabled(true); } CompilerWorkspaceConfiguration.getInstance(project).CLEAR_OUTPUT_DIRECTORY = false; return createdModules; } private static void addErlangFacets(final List<ImportedOtpApp> apps) { ApplicationManager.getApplication() .runWriteAction( new Runnable() { @Override public void run() { for (ImportedOtpApp app : apps) { Module module = app.getModule(); if (module == null) continue; ErlangFacet facet = ErlangFacet.getFacet(module); if (facet == null) { ErlangFacet.createFacet(module); facet = ErlangFacet.getFacet(module); } if (facet != null) { ErlangFacetConfiguration configuration = facet.getConfiguration(); configuration.addParseTransforms(app.getParseTransforms()); } } } }); } @Nullable private static Sdk fixProjectSdk(@NotNull Project project) { final ProjectRootManagerEx projectRootMgr = ProjectRootManagerEx.getInstanceEx(project); Sdk selectedSdk = projectRootMgr.getProjectSdk(); if (selectedSdk == null || selectedSdk.getSdkType() != ErlangSdkType.getInstance()) { final Sdk moreSuitableSdk = ProjectJdkTable.getInstance().findMostRecentSdkOfType(ErlangSdkType.getInstance()); ApplicationManager.getApplication() .runWriteAction( new Runnable() { @Override public void run() { projectRootMgr.setProjectSdk(moreSuitableSdk); } }); return moreSuitableSdk; } return selectedSdk; } private static void addSourceDirToContent( @NotNull ContentEntry content, @NotNull VirtualFile root, @NotNull String sourceDir, boolean test) { VirtualFile sourceDirFile = root.findChild(sourceDir); if (sourceDirFile != null) { content.addSourceFolder(sourceDirFile, test); } } private static void addIncludeDirectories(@NotNull ContentEntry content, ImportedOtpApp app) { for (VirtualFile includeDirectory : app.getIncludePaths()) { ErlangIncludeDirectoryUtil.markAsIncludeDirectory(content, includeDirectory); } } private static void excludeDirFromContent( ContentEntry content, VirtualFile root, String excludeDir) { VirtualFile excludeDirFile = root.findChild(excludeDir); if (excludeDirFile != null) { content.addExcludeFolder(excludeDirFile); } } @NotNull private List<VirtualFile> findRebarConfigs( @NotNull final VirtualFile root, @NotNull final ProgressIndicator indicator) { root.refresh(false, true); final List<VirtualFile> foundRebarConfigs = new ArrayList<VirtualFile>(); VfsUtilCore.visitChildrenRecursively( root, new VirtualFileVisitor() { @Override public boolean visitFile(@NotNull VirtualFile file) { indicator.checkCanceled(); if (file.isDirectory()) { if (isExamplesDirectory(file) || isRelDirectory(root.getPath(), file.getPath())) return false; indicator.setText2(file.getPath()); } else if (file.getName().equalsIgnoreCase("rebar.config")) { foundRebarConfigs.add(file); } return true; } }); return foundRebarConfigs; } private boolean isExamplesDirectory(VirtualFile virtualFile) { return "examples".equals(virtualFile.getName()) && !myImportExamples; } @Nullable private static ImportedOtpApp createImportedOtpApp(@NotNull VirtualFile appRoot) { VirtualFile appResourceFile = findAppResourceFile(appRoot); if (appResourceFile == null) { return null; } return new ImportedOtpApp(appRoot, appResourceFile); } @Nullable private static VirtualFile findAppResourceFile(@NotNull VirtualFile applicationRoot) { VirtualFile appResourceFile = null; VirtualFile sourceDir = applicationRoot.findChild("src"); if (sourceDir != null) { appResourceFile = findFileByExtension(sourceDir, "app.src"); } if (appResourceFile == null) { VirtualFile ebinDir = applicationRoot.findChild("ebin"); if (ebinDir != null) { appResourceFile = findFileByExtension(ebinDir, "app"); } } return appResourceFile; } @Nullable private static VirtualFile findFileByExtension( @NotNull VirtualFile dir, @NotNull String extension) { for (VirtualFile file : dir.getChildren()) { String fileName = file.getName(); if (!file.isDirectory() && fileName.endsWith(extension)) { return file; } } return null; // To change body of created methods use File | Settings | File Templates. } private static void deleteIdeaModuleFiles(@NotNull final List<ImportedOtpApp> importedOtpApps) throws IOException { final IOException[] ex = new IOException[1]; ApplicationManager.getApplication() .runWriteAction( new Runnable() { @Override public void run() { for (ImportedOtpApp importedOtpApp : importedOtpApps) { VirtualFile ideaModuleFile = importedOtpApp.getIdeaModuleFile(); if (ideaModuleFile != null) { try { ideaModuleFile.delete(this); importedOtpApp.setIdeaModuleFile(null); } catch (IOException e) { ex[0] = e; } } } } }); if (ex[0] != null) { throw ex[0]; } } private static boolean findIdeaModuleFiles(@NotNull List<ImportedOtpApp> importedOtpApps) { boolean ideaModuleFileExists = false; for (ImportedOtpApp importedOtpApp : importedOtpApps) { VirtualFile applicationRoot = importedOtpApp.getRoot(); String ideaModuleName = importedOtpApp.getName(); VirtualFile imlFile = applicationRoot.findChild(ideaModuleName + ".iml"); if (imlFile != null) { ideaModuleFileExists = true; importedOtpApp.setIdeaModuleFile(imlFile); } else { VirtualFile emlFile = applicationRoot.findChild(ideaModuleName + ".eml"); if (emlFile != null) { ideaModuleFileExists = true; importedOtpApp.setIdeaModuleFile(emlFile); } } } return ideaModuleFileExists; } @NotNull private static Set<String> resolveModuleDeps( @NotNull ModifiableRootModel rootModel, @NotNull ImportedOtpApp importedOtpApp, @Nullable Sdk projectSdk, @NotNull Set<String> allImportedAppNames) { HashSet<String> unresolvedAppNames = ContainerUtil.newHashSet(); for (String depAppName : importedOtpApp.getDeps()) { if (allImportedAppNames.contains(depAppName)) { rootModel.addInvalidModuleEntry(depAppName); } else if (projectSdk != null && isSdkOtpApp(depAppName, projectSdk)) { // SDK is already a dependency } else { rootModel.addInvalidModuleEntry(depAppName); unresolvedAppNames.add(depAppName); } } return unresolvedAppNames; } private static boolean isSdkOtpApp(@NotNull String otpAppName, @NotNull Sdk sdk) { Pattern appDirNamePattern = Pattern.compile(otpAppName + "-.*"); for (VirtualFile srcSdkDir : sdk.getRootProvider().getFiles(OrderRootType.SOURCES)) { for (VirtualFile child : srcSdkDir.getChildren()) { if (child.isDirectory() && appDirNamePattern.matcher(child.getName()).find()) { return true; } } } return false; } public void setImportExamples(boolean importExamples) { myImportExamples = importExamples; } public void setRebarPath(@NotNull String rebarPath) { myRebarPath = rebarPath; } public void setIsImportingProject(boolean isImportingProject) { myIsImportingProject = isImportingProject; } }