@Override public void saveAllDocuments() { ApplicationManager.getApplication().assertIsDispatchThread(); myMultiCaster.beforeAllDocumentsSaving(); if (myUnsavedDocuments.isEmpty()) return; final Map<Document, IOException> failedToSave = new HashMap<Document, IOException>(); final Set<Document> vetoed = new HashSet<Document>(); while (true) { int count = 0; for (Document document : myUnsavedDocuments) { if (failedToSave.containsKey(document)) continue; if (vetoed.contains(document)) continue; try { doSaveDocument(document); } catch (IOException e) { //noinspection ThrowableResultOfMethodCallIgnored failedToSave.put(document, e); } catch (SaveVetoException e) { vetoed.add(document); } count++; } if (count == 0) break; } if (!failedToSave.isEmpty()) { handleErrorsOnSave(failedToSave); } }
@NotNull private static DartLibInfo collectPackagesLibraryRoots( @NotNull final Project project, @NotNull final DartSdk sdk) { final DartLibInfo libInfo = new DartLibInfo(false); final Collection<VirtualFile> pubspecYamlFiles = FilenameIndex.getVirtualFilesByName( project, PUBSPEC_YAML, GlobalSearchScope.projectScope(project)); final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); for (VirtualFile pubspecFile : pubspecYamlFiles) { final VirtualFile dotPackagesFile = pubspecFile.getParent().findChild(DotPackagesFileUtil.DOT_PACKAGES); final Module module = dotPackagesFile == null ? null : fileIndex.getModuleForFile(dotPackagesFile); if (dotPackagesFile != null && !dotPackagesFile.isDirectory() && module != null && DartSdkGlobalLibUtil.isDartSdkEnabled(module)) { final Map<String, String> packagesMap = DotPackagesFileUtil.getPackagesMap(dotPackagesFile); if (packagesMap != null) { for (Map.Entry<String, String> entry : packagesMap.entrySet()) { final String packageName = entry.getKey(); final String packagePath = entry.getValue(); if (isPathOutsideProjectContent(fileIndex, packagePath)) { libInfo.addPackage(packageName, packagePath); } } } } } return libInfo; }
@NotNull private static Map<Module, String> collectJpsPluginModules(@NotNull Module module) { XmlFile pluginXml = PluginModuleType.getPluginXml(module); if (pluginXml == null) return Collections.emptyMap(); DomFileElement<IdeaPlugin> fileElement = DomManager.getDomManager(module.getProject()).getFileElement(pluginXml, IdeaPlugin.class); if (fileElement == null) return Collections.emptyMap(); Map<Module, String> jpsPluginToOutputPath = new HashMap<Module, String>(); IdeaPlugin plugin = fileElement.getRootElement(); List<Extensions> extensions = plugin.getExtensions(); for (Extensions extensionGroup : extensions) { XmlTag extensionsTag = extensionGroup.getXmlTag(); String defaultExtensionNs = extensionsTag.getAttributeValue("defaultExtensionNs"); for (XmlTag tag : extensionsTag.getSubTags()) { String name = tag.getLocalName(); String qualifiedName = defaultExtensionNs != null ? defaultExtensionNs + "." + name : name; if (CompileServerPlugin.EP_NAME.getName().equals(qualifiedName)) { String classpath = tag.getAttributeValue("classpath"); if (classpath != null) { for (String path : StringUtil.split(classpath, ";")) { String moduleName = FileUtil.getNameWithoutExtension(PathUtil.getFileName(path)); Module jpsModule = ModuleManager.getInstance(module.getProject()).findModuleByName(moduleName); if (jpsModule != null) { jpsPluginToOutputPath.put(jpsModule, path); } } } } } } return jpsPluginToOutputPath; }
@NotNull private VirtualFilePointerImpl getOrCreate( @NotNull Disposable parentDisposable, @Nullable VirtualFilePointerListener listener, @NotNull String path, @NotNull Pair<VirtualFile, String> fileAndUrl) { FilePointerPartNode root = myPointers.get(listener); FilePointerPartNode node; if (root == null) { root = new FilePointerPartNode(path, null, fileAndUrl); myPointers.put(listener, root); node = root; } else { node = root.findPointerOrCreate(path, 0, fileAndUrl); } VirtualFilePointerImpl pointer; if (node.leaf == null) { pointer = new VirtualFilePointerImpl(listener, parentDisposable, fileAndUrl); node.associate(pointer, fileAndUrl); } else { pointer = node.leaf; } pointer.myNode.incrementUsageCount(1); root.checkConsistency(); return pointer; }
private void releaseAllEditors() { for (final Editor editor : myEditors.values()) { if (!editor.isDisposed()) { EditorFactory.getInstance().releaseEditor(editor); } } myEditors.clear(); }
void removeNode(@NotNull FilePointerPartNode node, VirtualFilePointerListener listener) { boolean rootNodeEmpty = node.remove(); if (rootNodeEmpty) { myPointers.remove(listener); } else { myPointers.get(listener).checkConsistency(); } }
private IdentityVirtualFilePointer getOrCreateIdentity(@NotNull String url, VirtualFile found) { IdentityVirtualFilePointer pointer = myUrlToIdentity.get(url); if (pointer == null) { pointer = new IdentityVirtualFilePointer(found, url); myUrlToIdentity.put(url, pointer); } return pointer; }
private synchronized int getNodeId(String fullTestName) { Integer nodeId = nodeIdsByFullTestName.get(fullTestName); if (nodeId == null) { nodeId = nextNodeId++; nodeIdsByFullTestName.put(fullTestName, nodeId); } return nodeId; }
static void registerDisposable(Disposable parentDisposable, VirtualFilePointerImpl pointer) { synchronized (ourInstances) { DelegatingDisposable result = ourInstances.get(parentDisposable); if (result == null) { ourInstances.put(parentDisposable, result = new DelegatingDisposable(parentDisposable)); Disposer.register(parentDisposable, result); } result.myCounts.put(pointer, result.myCounts.get(pointer) + 1); } }
@Override public final String getVersionString(String sdkHome) { String versionString = myCachedVersionStrings.get(sdkHome); if (versionString == null) { versionString = getJdkVersion(sdkHome); if (!StringUtil.isEmpty(versionString)) { myCachedVersionStrings.put(sdkHome, versionString); } } return versionString; }
@Override public void after(@NotNull final List<? extends VFileEvent> events) { incModificationCount(); for (FilePointerPartNode node : myPointersToUpdateUrl) { synchronized (this) { VirtualFilePointerImpl pointer = node.leaf; String urlBefore = pointer.getUrlNoUpdate(); Pair<VirtualFile, String> after = node.update(); String urlAfter = after.second; if (URL_COMPARATOR.compare(urlBefore, urlAfter) != 0) { // url has changed, reinsert FilePointerPartNode root = myPointers.get(pointer.getListener()); int useCount = node.useCount; node.remove(); FilePointerPartNode newNode = root.findPointerOrCreate(VfsUtilCore.urlToPath(urlAfter), 0, after); VirtualFilePointerImpl existingPointer = newNode.leaf; if (existingPointer != null) { // can happen when e.g. file renamed to the existing file // merge two pointers pointer.myNode = newNode; } else { newNode.associate(pointer, after); } newNode.incrementUsageCount(useCount); } } } VirtualFilePointer[] pointersToFireArray = toPointers(myPointersToFire); for (VirtualFilePointer pointer : pointersToFireArray) { ((VirtualFilePointerImpl) pointer).myNode.update(); } for (EventDescriptor event : myEvents) { event.fireAfter(); } if (pointersToFireArray.length != 0) { myBus.syncPublisher(VirtualFilePointerListener.TOPIC).validityChanged(pointersToFireArray); } myPointersToUpdateUrl = Collections.emptyList(); myEvents = Collections.emptyList(); myPointersToFire = Collections.emptyList(); for (FilePointerPartNode root : myPointers.values()) { root.checkConsistency(); } }
public static void addJavaHome(@NotNull JavaParameters params, @NotNull Module module) { final Sdk sdk = ModuleUtilCore.getSdk(module, JavaModuleExtensionImpl.class); if (sdk != null && sdk.getSdkType() instanceof JavaSdkType) { String path = StringUtil.trimEnd(sdk.getHomePath(), File.separator); if (StringUtil.isNotEmpty(path)) { Map<String, String> env = params.getEnv(); if (env == null) { env = new HashMap<String, String>(); params.setEnv(env); } env.put("JAVA_HOME", FileUtil.toSystemDependentName(path)); } } }
public void collectCommonPluginRoots( Map<String, VirtualFile> result, @NotNull Module module, boolean refresh) { if (isCommonPluginsModule(module)) { for (VirtualFile root : ModuleRootManager.getInstance(module).getContentRoots()) { String pluginName = getInstalledPluginNameByPath(module.getProject(), root); if (pluginName != null) { result.put(pluginName, root); } } } else { VirtualFile root = findAppRoot(module); if (root == null) return; extractPlugins( module.getProject(), root.findChild(MvcModuleStructureUtil.PLUGINS_DIRECTORY), result); extractPlugins( module.getProject(), MvcModuleStructureUtil.findFile(getCommonPluginsDir(module), refresh), result); extractPlugins( module.getProject(), MvcModuleStructureUtil.findFile(getGlobalPluginsDir(module), refresh), result); } }
private synchronized void assertAllPointersDisposed() { for (Map.Entry<VirtualFilePointerListener, FilePointerPartNode> entry : myPointers.entrySet()) { FilePointerPartNode root = entry.getValue(); ArrayList<FilePointerPartNode> left = new ArrayList<FilePointerPartNode>(); root.getPointersUnder(null, false, "", left); if (!left.isEmpty()) { VirtualFilePointerImpl p = left.get(0).leaf; try { p.throwDisposalError("Not disposed pointer: " + p); } finally { for (FilePointerPartNode pair : left) { VirtualFilePointerImpl pointer = pair.leaf; pointer.dispose(); } } } } synchronized (myContainers) { if (!myContainers.isEmpty()) { VirtualFilePointerContainerImpl container = myContainers.iterator().next(); container.throwDisposalError("Not disposed container"); } } }
private void executeDelete(@NotNull VirtualFile file) { if (!file.exists()) { LOG.error("Deleting a file, which does not exist: " + file.getPath()); return; } clearIdCache(); int id = getFileId(file); final VirtualFile parent = file.getParent(); final int parentId = parent == null ? 0 : getFileId(parent); if (parentId == 0) { String rootUrl = normalizeRootUrl(file.getPath(), (NewVirtualFileSystem) file.getFileSystem()); myRootsLock.writeLock().lock(); try { myRoots.remove(rootUrl); myRootsById.remove(id); FSRecords.deleteRootRecord(id); } finally { myRootsLock.writeLock().unlock(); } } else { removeIdFromParentList(parentId, id, parent, file); VirtualDirectoryImpl directory = (VirtualDirectoryImpl) file.getParent(); assert directory != null : file; directory.removeChild(file); } FSRecords.deleteRecordRecursively(id); invalidateSubtree(file); }
@TestOnly int numberOfPointers() { int number = 0; for (FilePointerPartNode root : myPointers.values()) { number = root.getPointersUnder(); } return number; }
@Override public void projectClosed(Project project) { myProjectDataMap.remove(getProjectPath(project)); final MessageBusConnection conn = myConnections.remove(project); if (conn != null) { conn.disconnect(); } }
private void runAutoMake() { if (ApplicationManager.getApplication().isUnitTestMode()) { return; } final Project[] openProjects = myProjectManager.getOpenProjects(); if (openProjects.length > 0) { final List<RequestFuture> futures = new ArrayList<RequestFuture>(); for (final Project project : openProjects) { if (project.isDefault() || project.isDisposed()) { continue; } final CompilerWorkspaceConfiguration config = CompilerWorkspaceConfiguration.getInstance(project); if (!config.useOutOfProcessBuild() || !config.MAKE_PROJECT_ON_SAVE) { continue; } final List<String> emptyList = Collections.emptyList(); final RequestFuture future = scheduleBuild( project, false, true, emptyList, emptyList, emptyList, Collections.<String, String>emptyMap(), new AutoMakeMessageHandler(project)); if (future != null) { futures.add(future); synchronized (myAutomakeFutures) { myAutomakeFutures.put(future, project); } } } try { for (RequestFuture future : futures) { future.waitFor(); } } finally { synchronized (myAutomakeFutures) { myAutomakeFutures.keySet().removeAll(futures); } } } }
@TestOnly public int countDupContainers() { Map<VirtualFilePointerContainer, Integer> c = new THashMap<VirtualFilePointerContainer, Integer>(); for (VirtualFilePointerContainerImpl container : myContainers) { Integer count = c.get(container); if (count == null) count = 0; count++; c.put(container, count); } int i = 0; for (Integer count : c.values()) { if (count > 1) { i++; } } return i; }
private void copyToTemp(VirtualFile file) { try { final byte[] bytes = file.contentsToByteArray(); mySavedCopies.put(file, bytes); mySavedTimestamps.put(file, file.getTimeStamp()); } catch (IOException e) { LOG.error(e); } }
private void addPointersUnder( VirtualFile parent, boolean separator, @NotNull CharSequence childName, @NotNull List<FilePointerPartNode> out) { for (FilePointerPartNode root : myPointers.values()) { root.getPointersUnder(parent, separator, childName, out); } }
private void addAllPointers(@NotNull Collection<VirtualFilePointerImpl> pointers) { List<FilePointerPartNode> out = new ArrayList<FilePointerPartNode>(); for (FilePointerPartNode root : myPointers.values()) { root.getPointersUnder(null, false, "", out); } for (FilePointerPartNode node : out) { pointers.add(node.leaf); } }
public void clearState(Project project) { myGlobals = null; final String projectPath = getProjectPath(project); synchronized (myProjectDataMap) { final ProjectData data = myProjectDataMap.get(projectPath); if (data != null) { data.dropChanges(); } } }
private void restoreCopy(VirtualFile file) { try { if (file == null) return; // Externally deleted actually. if (!file.isWritable()) return; // IDEA was unable to save it as well. So no need to restore. final byte[] bytes = mySavedCopies.get(file); if (bytes != null) { try { file.setBinaryContent(bytes, -1, mySavedTimestamps.get(file)); } catch (IOException e) { Messages.showWarningDialog( ProjectBundle.message("project.reload.write.failed", file.getPresentableUrl()), ProjectBundle.message("project.reload.write.failed.title")); } } } finally { mySavedCopies.remove(file); mySavedTimestamps.remove(file); } }
private static void processLibrariesAndJpsPlugins( final File jarFile, final File zipFile, final String pluginName, final Set<Library> libs, Map<Module, String> jpsModules, final ProgressIndicator progressIndicator) throws IOException { if (FileUtil.ensureCanCreateFile(zipFile)) { ZipOutputStream zos = null; try { zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile))); addStructure(pluginName, zos); addStructure(pluginName + "/" + MIDDLE_LIB_DIR, zos); final String entryName = pluginName + JAR_EXTENSION; ZipUtil.addFileToZip( zos, jarFile, getZipPath(pluginName, entryName), new HashSet<String>(), createFilter(progressIndicator, FileTypeManager.getInstance())); for (Map.Entry<Module, String> entry : jpsModules.entrySet()) { File jpsPluginJar = jarModulesOutput(Collections.singleton(entry.getKey()), null, null); ZipUtil.addFileToZip( zos, jpsPluginJar, getZipPath(pluginName, entry.getValue()), null, null); } Set<String> usedJarNames = new HashSet<String>(); usedJarNames.add(entryName); Set<VirtualFile> jarredVirtualFiles = new HashSet<VirtualFile>(); for (Library library : libs) { final VirtualFile[] files = library.getFiles(OrderRootType.CLASSES); for (VirtualFile virtualFile : files) { if (jarredVirtualFiles.add(virtualFile)) { if (virtualFile.getFileSystem() instanceof JarFileSystem) { addLibraryJar( virtualFile, zipFile, pluginName, zos, usedJarNames, progressIndicator); } else { makeAndAddLibraryJar( virtualFile, zipFile, pluginName, zos, usedJarNames, progressIndicator, library.getName()); } } } } } finally { if (zos != null) zos.close(); } } }
@Override @NotNull public VirtualFile[] getRoots() { myRootsLock.readLock().lock(); try { Collection<VirtualFileSystemEntry> roots = myRoots.values(); return VfsUtilCore.toVirtualFileArray(roots); } finally { myRootsLock.readLock().unlock(); } }
private PropertiesFile getSelectedPropertiesFile() { if (mySelectedEditor == null) return null; PropertiesFile selectedFile = null; for (Map.Entry<PropertiesFile, Editor> entry : myEditors.entrySet()) { Editor editor = entry.getValue(); if (editor == mySelectedEditor) { selectedFile = entry.getKey(); break; } } return selectedFile; }
@Override @Nullable public Project newProject( final String projectName, @NotNull String filePath, boolean useDefaultProjectSettings, boolean isDummy) { filePath = toCanonicalName(filePath); //noinspection ConstantConditions if (LOG_PROJECT_LEAKAGE_IN_TESTS && ApplicationManager.getApplication().isUnitTestMode()) { for (int i = 0; i < 42; i++) { if (myProjects.size() < MAX_LEAKY_PROJECTS) break; System.gc(); TimeoutUtil.sleep(100); System.gc(); } if (myProjects.size() >= MAX_LEAKY_PROJECTS) { List<Project> copy = new ArrayList<Project>(myProjects.keySet()); myProjects.clear(); throw new TooManyProjectLeakedException(copy); } } ProjectImpl project = createProject( projectName, filePath, false, ApplicationManager.getApplication().isUnitTestMode()); try { initProject(project, useDefaultProjectSettings ? (ProjectImpl) getDefaultProject() : null); if (LOG_PROJECT_LEAKAGE_IN_TESTS) { myProjects.put(project, null); } return project; } catch (final Exception e) { LOG.info(e); Messages.showErrorDialog(message(e), ProjectBundle.message("project.load.default.error")); } return null; }
public Collection<RequestFuture> cancelAutoMakeTasks(Project project) { final Collection<RequestFuture> futures = new ArrayList<RequestFuture>(); synchronized (myAutomakeFutures) { for (Map.Entry<RequestFuture, Project> entry : myAutomakeFutures.entrySet()) { if (entry.getValue().equals(project)) { final RequestFuture future = entry.getKey(); future.cancel(false); futures.add(future); } } } return futures; }
public void reloadProjectImpl(@NotNull final Project p, final boolean clearCopyToRestore) { if (clearCopyToRestore) { mySavedCopies.clear(); mySavedTimestamps.clear(); } final Project[] project = {p}; ProjectReloadState.getInstance(project[0]).onBeforeAutomaticProjectReload(); final Application application = ApplicationManager.getApplication(); application.invokeLater( new Runnable() { @Override public void run() { LOG.debug("Reloading project."); ProjectImpl projectImpl = (ProjectImpl) project[0]; if (projectImpl.isDisposed()) return; IProjectStore projectStore = projectImpl.getStateStore(); final String location = projectImpl.getPresentableUrl(); final List<IFile> original; try { final IComponentStore.SaveSession saveSession = projectStore.startSave(); original = saveSession.getAllStorageFiles(true); saveSession.finishSave(); } catch (IOException e) { LOG.error(e); return; } if (project[0].isDisposed() || ProjectUtil.closeAndDispose(project[0])) { application.runWriteAction( new Runnable() { @Override public void run() { for (final IFile originalFile : original) { restoreCopy( LocalFileSystem.getInstance().refreshAndFindFileByIoFile(originalFile)); } } }); project[0] = null; // Let it go. ProjectUtil.openProject(location, null, true); } } }, ModalityState.NON_MODAL); }