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

com.simiacryptus.util.lang.CodeUtil Maven / Gradle / Ivy

There is a newer version: 2.1.0
Show newest version
/*
 * Copyright (c) 2018 by Andrew Charneski.
 *
 * The author licenses this file to you 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 com.simiacryptus.util.lang;

import org.apache.commons.io.IOUtils;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryBuilder;
import org.eclipse.jgit.lib.StoredConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * The type Code util.
 */
public class CodeUtil {
  
  private static final Logger logger = LoggerFactory.getLogger(CodeUtil.class);

  private static final List sourceFolders = Arrays.asList("src/main/java", "src/test/java", "src/main/scala", "src/test/scala");
  /**
   * The constant projectRoot.
   */
  @javax.annotation.Nonnull
  public static File projectRoot = new File(System.getProperty("codeRoot", ".."));
  private static final List codeRoots = com.simiacryptus.util.lang.CodeUtil.loadCodeRoots();
  
  /**
   * Find file file.
   *
   * @param clazz the clazz
   * @return the file
   */
  @Nullable
  public static File findFile(@Nullable final Class clazz) {
    if (null == clazz) return null;
    String name = clazz.getName();
    if (null == name) return null;
    final CharSequence path = name.replaceAll("\\.", "/").replaceAll("\\$.*", "");
    return com.simiacryptus.util.lang.CodeUtil.findFile(path + ".java");
  }
  
  
  /**
   * Find file file.
   *
   * @param callingFrame the calling frame
   * @return the file
   */
  @javax.annotation.Nonnull
  public static File findFile(@javax.annotation.Nonnull final StackTraceElement callingFrame) {
    @javax.annotation.Nonnull final CharSequence[] packagePath = callingFrame.getClassName().split("\\.");
    @javax.annotation.Nonnull final String path = Arrays.stream(packagePath).limit(packagePath.length - 1).collect(Collectors.joining(File.separator)) + File.separator + callingFrame.getFileName();
    return com.simiacryptus.util.lang.CodeUtil.findFile(path);
  }
  
  /**
   * Find file file.
   *
   * @param path the path
   * @return the file
   */
  @javax.annotation.Nonnull
  public static File findFile(@javax.annotation.Nonnull final String path) {
    for (final File root : com.simiacryptus.util.lang.CodeUtil.codeRoots) {
      @javax.annotation.Nonnull final File file = new File(root, path);
      if (file.exists()) return file;
    }
    throw new RuntimeException(String.format("Not Found: %s; Project Roots = %s", path, com.simiacryptus.util.lang.CodeUtil.codeRoots));
  }
  
  /**
   * Gets indent.
   *
   * @param txt the txt
   * @return the indent
   */
  @javax.annotation.Nonnull
  public static CharSequence getIndent(@javax.annotation.Nonnull final CharSequence txt) {
    @javax.annotation.Nonnull final Matcher matcher = Pattern.compile("^\\s+").matcher(txt);
    return matcher.find() ? matcher.group(0) : "";
  }
  
  /**
   * Gets heapCopy text.
   *
   * @param callingFrame the calling frame
   * @return the heapCopy text
   */
  public static String getInnerText(@javax.annotation.Nonnull final StackTraceElement callingFrame) {
  
    String[] split = callingFrame.getClassName().split("\\.");
    String fileResource = Arrays.stream(split).limit(split.length - 1).reduce((a, b) -> a + "/" + b).get() + "/" + callingFrame.getFileName();
    InputStream resourceAsStream = CodeUtil.class.getClassLoader().getResourceAsStream(fileResource);
  
    try {
      List allLines = null;
      if (null != resourceAsStream) {
        try {
          allLines = IOUtils.readLines(resourceAsStream, "UTF-8");
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
      }
      if (null == allLines) {
        @javax.annotation.Nonnull final File file = com.simiacryptus.util.lang.CodeUtil.findFile(callingFrame);
        assert null != file;
        allLines = Files.readAllLines(file.toPath());
      }

      final int start = callingFrame.getLineNumber() - 1;
      final CharSequence txt = allLines.get(start);
      @javax.annotation.Nonnull final CharSequence indent = com.simiacryptus.util.lang.CodeUtil.getIndent(txt);
      @javax.annotation.Nonnull final ArrayList lines = new ArrayList<>();
      for (int i = start + 1; i < allLines.size() && (com.simiacryptus.util.lang.CodeUtil.getIndent(allLines.get(i)).length() > indent.length() || String.valueOf(allLines.get(i)).trim().isEmpty()); i++) {
        final String line = allLines.get(i);
        lines.add(line.substring(Math.min(indent.length(), line.length())));
      }
      return lines.stream().collect(Collectors.joining("\n"));
    
    } catch (@javax.annotation.Nonnull final Throwable e) {
      return "";
    }
  }
  
  /**
   * Gets javadoc.
   *
   * @param clazz the clazz
   * @return the javadoc
   */
  public static String getJavadoc(@Nullable final Class clazz) {
    try {
      if (null == clazz) return null;
      @Nullable final File source = com.simiacryptus.util.lang.CodeUtil.findFile(clazz);
      if (null == source) return clazz.getName() + " not found";
      final List lines = IOUtils.readLines(new FileInputStream(source), Charset.forName("UTF-8"));
      final int classDeclarationLine = IntStream.range(0, lines.size())
        .filter(i -> lines.get(i).contains("class " + clazz.getSimpleName())).findFirst().getAsInt();
      final int firstLine = IntStream.rangeClosed(1, classDeclarationLine).map(i -> classDeclarationLine - i)
        .filter(i -> !lines.get(i).matches("\\s*[/\\*@].*")).findFirst().orElse(-1) + 1;
      final String javadoc = lines.subList(firstLine, classDeclarationLine).stream()
        .filter(s -> s.matches("\\s*[/\\*].*"))
        .map(s -> s.replaceFirst("^[ \t]*[/\\*]+", "").trim())
        .filter(x -> !x.isEmpty()).reduce((a, b) -> a + "\n" + b).orElse("");
      return javadoc.replaceAll("

", "\n"); } catch (@javax.annotation.Nonnull final Throwable e) { e.printStackTrace(); return ""; } } private static List loadCodeRoots() { return Stream.concat( Stream.of(com.simiacryptus.util.lang.CodeUtil.projectRoot), Arrays.stream(com.simiacryptus.util.lang.CodeUtil.projectRoot.listFiles()) .filter(file -> file.exists() && file.isDirectory()) .collect(Collectors.toList()).stream()).flatMap(x -> scanProject(x).stream()) .distinct().collect(Collectors.toList()); } private static List scanProject(File file) { return sourceFolders.stream().map(name -> new File(file, name.toString())) .filter(f -> f.exists() && f.isDirectory()) .collect(Collectors.toList()); } @Nonnull public static String getGitBase() { File absoluteFile = new File(".").getAbsoluteFile(); try { Repository repository = new RepositoryBuilder().setWorkTree(absoluteFile).build(); StoredConfig config = repository.getConfig(); String head = repository.resolve("HEAD").toObjectId().getName(); String remoteUrl = config.getString("remote", "origin", "url"); Pattern githubPattern = Pattern.compile("[email protected]:([^/]+)/([^/]+).git"); Matcher matcher = githubPattern.matcher(remoteUrl); if (matcher.matches()) { return "https://github.com/" + matcher.group(1) + "/" + matcher.group(2) + "/tree/" + head + "/"; } } catch (Throwable e) { logger.debug("Error querying local git config for " + absoluteFile, e); } return System.getProperty("GITBASE", "https://github.com/SimiaCryptus/mindseye-art/tree/master/"); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy