@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);
      }
    }
예제 #10
0
 @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();
    }
  }
예제 #12
0
  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));
      }
    }
  }
예제 #13
0
  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");
      }
    }
  }
예제 #15
0
  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;
 }
예제 #17
0
 @Override
 public void projectClosed(Project project) {
   myProjectDataMap.remove(getProjectPath(project));
   final MessageBusConnection conn = myConnections.remove(project);
   if (conn != null) {
     conn.disconnect();
   }
 }
예제 #18
0
 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);
   }
 }
예제 #23
0
 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();
     }
   }
 }
예제 #26
0
 @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;
  }
예제 #29
0
 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);
  }