All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.intellij.plugins.xpathView.search.SearchScope Maven / Gradle / Ivy

/**
 * Copyright 2006 Sascha Weinreuter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.intellij.plugins.xpathView.search;

import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ContentIterator;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderEnumerator;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Conditions;
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 com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiSearchScopeUtil;
import com.intellij.util.Processor;
import com.intellij.util.xmlb.annotations.Attribute;
import com.intellij.util.xmlb.annotations.Tag;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Collections;

public final class SearchScope {
  public enum ScopeType {
    PROJECT, MODULE, DIRECTORY, CUSTOM
  }

  private ScopeType myScopeType;
  private String myModuleName;
  private String myPath;
  private boolean myRecursive;
  private String myScopeName;

  private com.intellij.psi.search.SearchScope myCustomScope;

  public SearchScope() {
    myScopeType = ScopeType.PROJECT;
    myRecursive = true;
  }

  public SearchScope(SearchScope scope) {
    myScopeType = scope.getScopeType();

    myModuleName = scope.getModuleName();
    myPath = scope.getPath();
    myRecursive = scope.isRecursive();
    myScopeName = scope.getScopeName();
  }

  public SearchScope(ScopeType scopeType, String directoryName, boolean recursive, String moduleName, String scopeName) {
    myScopeType = scopeType;
    myPath = directoryName;
    myRecursive = recursive;
    myModuleName = moduleName;
    myScopeName = scopeName;
  }

  public void setCustomScope(com.intellij.psi.search.SearchScope customScope) {
    myCustomScope = customScope;
  }

  @NotNull
  public String getName() {
    switch (getScopeType()) {
      case PROJECT:
        return "Project";
      case MODULE:
        return "Module '" + getModuleName() + "'";
      case DIRECTORY:
        return "Directory '" + getPath() + "'";
      case CUSTOM:
        return getScopeName();
    }
    assert false;
    return null;
  }

  @NotNull
  @Attribute("type")
  public ScopeType getScopeType() {
    return myScopeType;
  }

  @SuppressWarnings("UnusedDeclaration")
  public void setScopeType(ScopeType scopeType) {
    myScopeType = scopeType;
  }

  @Tag
  public String getModuleName() {
    return myModuleName;
  }

  @SuppressWarnings("UnusedDeclaration")
  public void setModuleName(String moduleName) {
    myModuleName = moduleName;
  }

  @Nullable
  @Attribute("scope-name")
  public String getScopeName() {
    return myScopeName;
  }

  @SuppressWarnings("UnusedDeclaration")
  public void setScopeName(String scopeName) {
    myScopeName = scopeName;
  }

  @Nullable
  @Tag
  public String getPath() {
    return myPath;
  }

  public void setPath(String path) {
    myPath = path;
  }

  @Attribute
  public boolean isRecursive() {
    return myRecursive;
  }

  @SuppressWarnings("UnusedDeclaration")
  public void setRecursive(boolean recursive) {
    myRecursive = recursive;
  }

  public boolean isValid() {
    final String dirName = getPath();
    final String moduleName = getModuleName();

    switch (getScopeType()) {
      case MODULE:
        return moduleName != null && moduleName.length() > 0;
      case DIRECTORY:
        return dirName != null && dirName.length() > 0 && findFile(dirName) != null;
      case CUSTOM:
        return myCustomScope != null;
      case PROJECT:
        return true;
    }
    return false;
  }

  public void iterateContent(@NotNull final Project project, final Processor processor) {
    switch (getScopeType()) {
      case PROJECT:
        //noinspection unchecked
        ProjectRootManager.getInstance(project).getFileIndex().iterateContent(new MyFileIterator(processor, Conditions.alwaysTrue()));
        break;
      case MODULE:
        final Module module = ModuleManager.getInstance(project).findModuleByName(getModuleName());
        assert module != null;
        ModuleRootManager.getInstance(module).getFileIndex().iterateContent(new MyFileIterator(processor, Conditions.alwaysTrue()));
        break;
      case DIRECTORY:
        final String dirName = getPath();
        assert dirName != null;

        final VirtualFile virtualFile = findFile(dirName);
        if (virtualFile != null) {
          iterateRecursively(virtualFile, processor, isRecursive());
        }
        break;
      case CUSTOM:
        assert myCustomScope != null;

        final ContentIterator iterator;
        if (myCustomScope instanceof GlobalSearchScope) {
          final GlobalSearchScope searchScope = (GlobalSearchScope)myCustomScope;
          iterator = new MyFileIterator(processor, new Condition() {
            @Override
            public boolean value(VirtualFile virtualFile) {
              return searchScope.contains(virtualFile);
            }
          });
          if (searchScope.isSearchInLibraries()) {
            final OrderEnumerator enumerator = OrderEnumerator.orderEntries(project).withoutModuleSourceEntries().withoutDepModules();
            final Collection libraryFiles = new THashSet();
            Collections.addAll(libraryFiles, enumerator.getClassesRoots());
            Collections.addAll(libraryFiles, enumerator.getSourceRoots());
            final Processor adapter = new Processor() {
              @Override
              public boolean process(VirtualFile virtualFile) {
                return iterator.processFile(virtualFile);
              }
            };
            for (final VirtualFile file : libraryFiles) {
              iterateRecursively(file, adapter, true);
            }
          }
        }
        else {
          final PsiManager manager = PsiManager.getInstance(project);
          iterator = new MyFileIterator(processor, new Condition() {
            @Override
            public boolean value(VirtualFile virtualFile) {
              final PsiFile element = manager.findFile(virtualFile);
              return element != null && PsiSearchScopeUtil.isInScope(myCustomScope, element);
            }
          });
        }

        ProjectRootManager.getInstance(project).getFileIndex().iterateContent(iterator);
    }
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }

    SearchScope scope = (SearchScope)o;
    return myRecursive == scope.myRecursive &&
           Comparing.equal(myCustomScope, scope.myCustomScope) &&
           Comparing.equal(myModuleName, scope.myModuleName) &&
           Comparing.equal(myPath, scope.myPath) &&
           Comparing.equal(myScopeName, scope.myScopeName) &&
           myScopeType == scope.myScopeType;
  }

  @Override
  public int hashCode() {
    int result = myScopeType != null ? myScopeType.hashCode() : 0;
    result = 31 * result + (myModuleName != null ? myModuleName.hashCode() : 0);
    result = 31 * result + (myPath != null ? myPath.hashCode() : 0);
    result = 31 * result + (myRecursive ? 1 : 0);
    result = 31 * result + (myScopeName != null ? myScopeName.hashCode() : 0);
    result = 31 * result + (myCustomScope != null ? myCustomScope.hashCode() : 0);
    return result;
  }

  @Nullable
  private static VirtualFile findFile(String dirName) {
    return LocalFileSystem.getInstance().findFileByPath(dirName.replace('\\', '/'));
  }

  private static void iterateRecursively(VirtualFile virtualFile, final Processor processor, boolean recursive) {
    VfsUtilCore.visitChildrenRecursively(virtualFile, new VirtualFileVisitor(recursive ? null : VirtualFileVisitor.ONE_LEVEL_DEEP) {
      @Override
      public boolean visitFile(@NotNull VirtualFile file) {
        if (!file.isDirectory()) {
          processor.process(file);
        }
        return true;
      }
    });
  }

  private static class MyFileIterator implements ContentIterator {
    private final Processor myProcessor;
    private final Condition myCondition;

    public MyFileIterator(Processor processor, Condition condition) {
      myCondition = condition;
      myProcessor = processor;
    }

    @Override
    public boolean processFile(VirtualFile fileOrDir) {
      if (!fileOrDir.isDirectory() && myCondition.value(fileOrDir)) {
        myProcessor.process(fileOrDir);
      }
      return true;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy