package com.github.masahirosuzuka.PhoneGapIntelliJPlugin; import com.github.masahirosuzuka.PhoneGapIntelliJPlugin.commandLine.PhoneGapCommandLine; import com.github.masahirosuzuka.PhoneGapIntelliJPlugin.settings.PhoneGapSettings; import com.intellij.execution.configurations.PathEnvironmentVariableUtil; import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootModificationTracker; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.psi.PsiFile; import com.intellij.psi.search.FilenameIndex; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.CachedValueProvider; import com.intellij.psi.util.CachedValuesManager; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.ui.TextFieldWithHistory; import com.intellij.ui.TextFieldWithHistoryWithBrowseButton; import com.intellij.util.ArrayUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.SwingHelper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.Collection; import java.util.List; public class PhoneGapUtil { public static final String IONIC_CONFIG = "ionic.config.json"; public static final String FOLDER_PLATFORMS = "platforms"; public static final String FOLDER_WWW = "www"; public static final String FOLDER_CORDOVA = ".cordova"; public static final String FOLDER_PLUGINS = "plugins"; public static final String[] POSSIBLE_FOLDERS_IN_PHONEGAP_ROOT = {FOLDER_PLATFORMS, FOLDER_PLUGINS, FOLDER_WWW}; @NotNull public static TextFieldWithHistoryWithBrowseButton createPhoneGapExecutableTextField(@Nullable Project project) { TextFieldWithHistoryWithBrowseButton field = SwingHelper.createTextFieldWithHistoryWithBrowseButton( project, PhoneGapBundle.message("phonegap.conf.executable.name"), FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor(), () -> getDefaultExecutablePaths()); String executablePath = PhoneGapSettings.getInstance().getExecutablePath(); setDefaultValue(field, executablePath); return field; } @NotNull public static TextFieldWithHistoryWithBrowseButton createPhoneGapWorkingDirectoryField(@Nullable final Project project) { TextFieldWithHistoryWithBrowseButton field = SwingHelper.createTextFieldWithHistoryWithBrowseButton( project, PhoneGapBundle.message("phonegap.conf.work.dir.name"), FileChooserDescriptorFactory.createSingleFolderDescriptor(), () -> getDefaultWorkingDirectory(project)); setDefaultValue(field, PhoneGapSettings.getInstance().getWorkingDirectory(project)); return field; } public static void setFieldWithHistoryWithBrowseButtonPath(@NotNull TextFieldWithHistoryWithBrowseButton field, @Nullable String executablePath) { setDefaultValue(field, executablePath); } @NotNull public static List<String> getDefaultExecutablePaths() { List<String> paths = ContainerUtil.newArrayList(); ContainerUtil.addIfNotNull(paths, getPath(PhoneGapCommandLine.PLATFORM_PHONEGAP)); ContainerUtil.addIfNotNull(paths, getPath(PhoneGapCommandLine.PLATFORM_IONIC)); ContainerUtil.addIfNotNull(paths, getPath(PhoneGapCommandLine.PLATFORM_CORDOVA)); return paths; } @NotNull public static List<String> getDefaultWorkingDirectory(@Nullable Project project) { List<String> paths = ContainerUtil.newArrayList(); if (project == null) return paths; VirtualFile baseDir = project.getBaseDir(); if (baseDir == null) return paths; if (folderExist(baseDir, FOLDER_PLATFORMS) || folderExist(baseDir, FOLDER_WWW) || folderExist(baseDir, FOLDER_CORDOVA)) { ContainerUtil.addIfNotNull(paths, project.getBasePath()); } else { addPaths(paths, getFolders(project)); } return paths; } private static boolean folderExist(VirtualFile baseDir, String name) { VirtualFile child = baseDir.findChild(name); return child != null && child.isDirectory(); } private static void setDefaultValue(@NotNull TextFieldWithHistoryWithBrowseButton field, @Nullable String defaultValue) { final TextFieldWithHistory textFieldWithHistory = field.getChildComponent(); if (StringUtil.isNotEmpty(defaultValue)) { setTextFieldWithHistory(textFieldWithHistory, defaultValue); } } public static void setTextFieldWithHistory(TextFieldWithHistory textFieldWithHistory, String value) { if (null != value) { textFieldWithHistory.setText(value); textFieldWithHistory.addCurrentTextToHistory(); } } private static Collection<VirtualFile> getFolders(@NotNull Project project) { for (String folder : POSSIBLE_FOLDERS_IN_PHONEGAP_ROOT) { Collection<VirtualFile> files = ContainerUtil.filter(FilenameIndex.getVirtualFilesByName(project, folder, GlobalSearchScope.projectScope(project)), file -> file.isDirectory()); if (!files.isEmpty()) { return files; } } return ContainerUtil.emptyList(); } private static void addPaths(@NotNull List<String> paths, @NotNull Collection<VirtualFile> platforms) { for (VirtualFile platform : platforms) { ContainerUtil.addIfNotNull(paths, platform.getParent().getPath()); } } @Nullable private static String getPath(@NotNull String name) { File path = PathEnvironmentVariableUtil.findInPath(SystemInfo.isWindows ? name + ".cmd" : name); return (path != null && path.exists()) ? path.getAbsolutePath() : null; } public static boolean isPhoneGapProject(@NotNull final Project project) { if (DumbService.isDumb(project)) return false; return CachedValuesManager.getManager(project).getCachedValue(project, () -> { PsiFile[] files = FilenameIndex.getFilesByName(project, "config.xml", GlobalSearchScope.projectScope(project)); PsiFile matchedFile = ContainerUtil.find(files, psiFile -> { if (!(psiFile instanceof XmlFile)) return false; XmlTag root = ((XmlFile)psiFile).getRootTag(); if (root == null) return false; return root.getName().equals("widget"); }); if (matchedFile != null) { return CachedValueProvider.Result.create(true, matchedFile); } if (files.length > 0) { Object[] append = ArrayUtil.append(files, VirtualFileManager.VFS_STRUCTURE_MODIFICATIONS, Object.class); return CachedValueProvider.Result.create(false, append); } return CachedValueProvider.Result.create(false, VirtualFileManager.VFS_STRUCTURE_MODIFICATIONS, ProjectRootModificationTracker.getInstance(project)); }); } }