Package com.intellij.javascript.karma.server.watch

Source Code of com.intellij.javascript.karma.server.watch.KarmaWatchPattern

package com.intellij.javascript.karma.server.watch;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileVisitor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.util.regex.Pattern;

public class KarmaWatchPattern {

  private static final Logger LOG = Logger.getInstance(KarmaWatchPattern.class);
  private static final Pattern[] BASE_DIR_PATTERNS = new Pattern[] {
    // /path/to/{,model/}*.js',
    Pattern.compile("/[^/]*\\{.*\\}.*$"),

    // /path/to/*.js
    Pattern.compile("/[^/]*\\*.*$"),

    // /path/to/!(...)
    Pattern.compile("/[^/]*!\\(.*$"),

    // /path/to/+(...)
    Pattern.compile("/[^/]*\\+\\(.*$"),

    // /path/to/(...)?
    Pattern.compile("/[^/]*\\)\\?.*$"),
  };

  private final LocalFileSystem myFileSystem;
  private final KarmaChangedFilesManager myChangedFileManager;
  private final String myVfsPath;
  private final String myBasePathDir;
  private final boolean myCheckBasePathDir;
  private LocalFileSystem.WatchRequest myWatchRequest;
  private VirtualFile myRoot;
  private String myRootPath;

  KarmaWatchPattern(@NotNull LocalFileSystem fileSystem,
                    @NotNull KarmaChangedFilesManager changedFilesManager,
                    @NotNull final String pattern) {
    LOG.info("Start watching path pattern " + pattern);

    myFileSystem = fileSystem;
    myChangedFileManager = changedFilesManager;
    myVfsPath = pattern.replace(File.separatorChar, KarmaWatchSession.SEPARATOR_CHAR);
    String baseDirPath = extractBaseDir(myVfsPath);
    if (baseDirPath.isEmpty()) {
      baseDirPath = KarmaWatchSession.SEPARATOR;
    }
    myBasePathDir = baseDirPath;
    myCheckBasePathDir = !myVfsPath.equals(myBasePathDir);

    update(false);
  }

  @NotNull
  public static String extractBaseDir(@NotNull String filePattern) {
    for (Pattern pattern : BASE_DIR_PATTERNS) {
      filePattern = pattern.matcher(filePattern).replaceFirst("");
    }
    return filePattern;
  }

  public void update(boolean rescan) {
    boolean noRootBefore = false;
    boolean rootValid = myRoot != null && myRoot.isValid();
    if (rootValid) {
      String path = myRoot.getPath();
      if (!path.equals(myRootPath)) {
        rootValid = false;
        if (myRootPath != null) {
          VfsUtilCore.visitChildrenRecursively(myRoot, new VirtualFileVisitor() {
            @Override
            public boolean visitFile(@NotNull VirtualFile file) {
              if (!file.isDirectory()) {
                String subPath = VfsUtilCore.getRelativePath(file, myRoot, KarmaWatchSession.SEPARATOR_CHAR);
                if (subPath != null) {
                  myChangedFileManager.onFileRemoved(KarmaWatchSession.join(myRootPath, subPath));
                }
              }
              return true;
            }
          });
        }
      }
    }
    if (!rootValid) {
      noRootBefore = true;
      myRoot = null;
      myRootPath = null;
      stopWatching();
      final VirtualFile file = myFileSystem.findFileByPath(myVfsPath);
      if (file != null && file.isValid()) {
        myRoot = file;
      }
      else if (myCheckBasePathDir) {
        final VirtualFile baseDir = myFileSystem.findFileByPath(myBasePathDir);
        if (baseDir != null && baseDir.isValid()) {
          myRoot = baseDir;
        }
      }
      if (myRoot != null) {
        myRootPath = myRoot.getPath();
      }
    }
    if (myRoot == null) {
      LOG.warn("[Karma watch] Can not find vfs root for " + myBasePathDir);
      return;
    }
    if (myWatchRequest == null) {
      myWatchRequest = watchRoot(myRoot, rescan && noRootBefore);
      LOG.info("Watching " + myRoot.getPath());
    }
  }

  @Nullable
  private LocalFileSystem.WatchRequest watchRoot(@NotNull final VirtualFile dir, final boolean reportChildren) {
    VfsUtilCore.visitChildrenRecursively(dir, new VirtualFileVisitor() {
      @Override
      public boolean visitFile(@NotNull VirtualFile file) {
        if (reportChildren && !file.isDirectory()) {
          myChangedFileManager.onFileAdded(file.getPath());
        }
        file.getChildren();
        return true;
      }
    });
    LocalFileSystem.WatchRequest watchRequest = myFileSystem.addRootToWatch(dir.getPath(), true);
    if (watchRequest == null) {
      LOG.warn("Can not watch valid directory " + dir.getPath());
    }
    return watchRequest;
  }

  public void stopWatching() {
    LocalFileSystem.WatchRequest watchRequest = myWatchRequest;
    if (watchRequest != null) {
      myFileSystem.removeWatchedRoot(watchRequest);
    }
    myWatchRequest = null;
  }

  @Nullable
  public String findWatchedOriginalPath(@NotNull VirtualFile file) {
    VirtualFile root = myRoot;
    if (root != null && VfsUtilCore.isAncestor(root, file, false)) {
      String filePath = file.getPath();
      if (SystemInfo.isWindows) {
        String originalRoot = myCheckBasePathDir ? myBasePathDir : myVfsPath;
        if (StringUtil.startsWithIgnoreCase(filePath, originalRoot)) {
          return originalRoot + filePath.substring(originalRoot.length());
        }
      }
      return filePath;
    }
    return null;
  }
}
TOP

Related Classes of com.intellij.javascript.karma.server.watch.KarmaWatchPattern

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.