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

org.jetbrains.jps.ProjectPaths Maven / Gradle / Ivy

Go to download

A packaging of the IntelliJ Community Edition jps-builders library. This is release number 1 of trunk branch 142.

The newest version!
/*
 * Copyright 2000-2012 JetBrains s.r.o.
 *
 * 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.jetbrains.jps;

import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.JpsDummyElement;
import org.jetbrains.jps.model.java.*;
import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile;
import org.jetbrains.jps.model.library.JpsOrderRootType;
import org.jetbrains.jps.model.library.sdk.JpsSdk;
import org.jetbrains.jps.model.module.JpsDependencyElement;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
import org.jetbrains.jps.model.module.JpsSdkDependency;
import org.jetbrains.jps.util.JpsPathUtil;

import java.io.File;
import java.util.*;

/**
 * @author Eugene Zhuravlev
 *         Date: 9/30/11
 */
public class ProjectPaths {
  private ProjectPaths() {
  }

  @NotNull
  public static Collection getCompilationClasspathFiles(ModuleChunk chunk,
                                                       boolean includeTests,
                                                       final boolean excludeMainModuleOutput,
                                                       final boolean exportedOnly) {
    return getClasspathFiles(chunk, JpsJavaClasspathKind.compile(includeTests), excludeMainModuleOutput, ClasspathPart.WHOLE, exportedOnly);
  }

  @NotNull
  public static Collection getPlatformCompilationClasspath(ModuleChunk chunk, boolean excludeMainModuleOutput) {
    return getClasspathFiles(chunk, JpsJavaClasspathKind.compile(chunk.containsTests()), excludeMainModuleOutput, ClasspathPart.BEFORE_JDK, true);
  }

  @NotNull
  public static Collection getCompilationClasspath(ModuleChunk chunk, boolean excludeMainModuleOutput) {
    return getClasspathFiles(chunk, JpsJavaClasspathKind.compile(chunk.containsTests()), excludeMainModuleOutput, ClasspathPart.AFTER_JDK, true);
  }

  @NotNull
  private static Collection getClasspathFiles(ModuleChunk chunk,
                                             JpsJavaClasspathKind kind,
                                             final boolean excludeMainModuleOutput,
                                             ClasspathPart classpathPart, final boolean exportedOnly) {
    final Set files = new LinkedHashSet();
    for (JpsModule module : chunk.getModules()) {
      JpsJavaDependenciesEnumerator enumerator = JpsJavaExtensionService.dependencies(module).includedIn(kind).recursively();
      if (exportedOnly) {
        enumerator = enumerator.exportedOnly();
      }
      if (classpathPart == ClasspathPart.BEFORE_JDK) {
        enumerator = enumerator.satisfying(new BeforeJavaSdkItemFilter(module));
      }
      else if (classpathPart == ClasspathPart.AFTER_JDK) {
        enumerator = enumerator.satisfying(new AfterJavaSdkItemFilter(module));
      }
      JpsJavaDependenciesRootsEnumerator rootsEnumerator = enumerator.classes();
      if (excludeMainModuleOutput) {
        rootsEnumerator = rootsEnumerator.withoutSelfModuleOutput();
      }
      files.addAll(rootsEnumerator.getRoots());
    }

    if (classpathPart == ClasspathPart.BEFORE_JDK) {
      for (JpsModule module : chunk.getModules()) {
        JpsSdk sdk = module.getSdk(JpsJavaSdkType.INSTANCE);
        if (sdk != null) {
          files.addAll(sdk.getParent().getFiles(JpsOrderRootType.COMPILED));
        }
      }
    }
    return files;
  }

  private static void addFile(Set classpath, @Nullable String url) {
    if (url != null) {
      classpath.add(JpsPathUtil.urlToFile(url));
    }
  }

  /**
   *
   * @param chunk
   * @return mapping "sourceRoot" -> "package prefix" Package prefix uses slashes instead of dots and ends with trailing slash
   */
  @NotNull
  public static Map getSourceRootsWithDependents(ModuleChunk chunk) {
    final boolean includeTests = chunk.containsTests();
    final Map result = new LinkedHashMap();
    processModulesRecursively(chunk, JpsJavaClasspathKind.compile(includeTests), new Consumer() {
      @Override
      public void consume(JpsModule module) {
        for (JpsModuleSourceRoot root : module.getSourceRoots()) {
          if (root.getRootType().equals(JavaSourceRootType.SOURCE) ||
              includeTests && root.getRootType().equals(JavaSourceRootType.TEST_SOURCE)) {
            String prefix = ((JavaSourceRootProperties)root.getProperties()).getPackagePrefix();
            if (!prefix.isEmpty()) {
              prefix = prefix.replace('.', '/');
              if (!prefix.endsWith("/")) {
                prefix += "/";
              }
            }
            else {
              prefix = null;
            }
            result.put(JpsPathUtil.urlToFile(root.getUrl()), prefix);
          }
        }
      }
    });
    return result;
  }

  public static Collection getOutputPathsWithDependents(final ModuleChunk chunk) {
    final boolean forTests = chunk.containsTests();
    final Set sourcePaths = new LinkedHashSet();
    processModulesRecursively(chunk, JpsJavaClasspathKind.compile(forTests), new Consumer() {
      @Override
      public void consume(JpsModule module) {
        addFile(sourcePaths, JpsJavaExtensionService.getInstance().getOutputUrl(module, forTests));
      }
    });
    return sourcePaths;
  }

  public static Set getModulesWithDependentsRecursively(final JpsModule module, final boolean includeTests) {
    return JpsJavaExtensionService.dependencies(module).includedIn(JpsJavaClasspathKind.compile(includeTests)).recursively().getModules();
  }

  private static void processModulesRecursively(ModuleChunk chunk, JpsJavaClasspathKind kind, Consumer processor) {
    JpsJavaExtensionService.getInstance().enumerateDependencies(chunk.getModules()).includedIn(kind).recursively().processModules(processor);
  }

  @Nullable
  public static File getModuleOutputDir(JpsModule module, boolean forTests) {
    return JpsJavaExtensionService.getInstance().getOutputDirectory(module, forTests);
  }

  @Nullable
  public static File getAnnotationProcessorGeneratedSourcesOutputDir(JpsModule module, final boolean forTests, ProcessorConfigProfile profile) {
    final String sourceDirName = profile.getGeneratedSourcesDirectoryName(forTests);
    if (profile.isOutputRelativeToContentRoot()) {
      List roots = module.getContentRootsList().getUrls();
      if (roots.isEmpty()) {
        return null;
      }
      if (roots.size() > 1) {
        roots = new ArrayList(roots); // sort roots to get deterministic result
        Collections.sort(roots, new Comparator() {
          @Override
          public int compare(String o1, String o2) {
            return o1.compareTo(o2);
          }
        });
      }
      final File parent = JpsPathUtil.urlToFile(roots.get(0));
      return StringUtil.isEmpty(sourceDirName)? parent : new File(parent, sourceDirName);
    }

    final File outputDir = getModuleOutputDir(module, forTests);
    if (outputDir == null) {
      return null;
    }
    return StringUtil.isEmpty(sourceDirName)? outputDir : new File(outputDir, sourceDirName);
  }

  private enum ClasspathPart {WHOLE, BEFORE_JDK, AFTER_JDK}

  private static class BeforeJavaSdkItemFilter implements Condition {
    private JpsModule myModule;
    private boolean mySdkFound;

    private BeforeJavaSdkItemFilter(JpsModule module) {
      myModule = module;
    }

    @Override
    public boolean value(JpsDependencyElement dependency) {
      boolean isJavaSdk = dependency instanceof JpsSdkDependency && ((JpsSdkDependency)dependency).getSdkType().equals(JpsJavaSdkType.INSTANCE);
      if (myModule.equals(dependency.getContainingModule()) && isJavaSdk) {
        mySdkFound = true;
      }
      return !mySdkFound && !isJavaSdk;
    }
  }

  private static class AfterJavaSdkItemFilter implements Condition {
    private JpsModule myModule;
    private boolean mySdkFound;

    private AfterJavaSdkItemFilter(JpsModule module) {
      myModule = module;
    }

    @Override
    public boolean value(JpsDependencyElement dependency) {
      if (myModule.equals(dependency.getContainingModule())) {
        if (dependency instanceof JpsSdkDependency && ((JpsSdkDependency)dependency).getSdkType().equals(JpsJavaSdkType.INSTANCE)) {
          mySdkFound = true;
          return false;
        }
      }
      return mySdkFound;
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy