content: package com.lcw.util;
  
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.InputStreamReader;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.Map;
  import org.apache.commons.lang.StringUtils;
  import org.apache.maven.artifact.Artifact;
  import org.apache.maven.artifact.DefaultArtifact;
  import org.apache.maven.artifact.handler.DefaultArtifactHandler;
  import org.apache.maven.artifact.repository.ArtifactRepository;
  import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
  import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
  import org.apache.maven.repository.legacy.repository.ArtifactRepositoryFactory;
  import org.apache.maven.repository.legacy.repository.DefaultArtifactRepositoryFactory;
  import org.apache.maven.settings.building.DefaultSettingsBuilder;
  import org.apache.maven.settings.building.DefaultSettingsBuilderFactory;
  import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
  import org.apache.maven.settings.building.SettingsBuildingRequest;
  import org.apache.maven.settings.building.SettingsBuildingResult;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  /**
   *
   * @author lancw
   */
  public class MavenDependencyUtil {
  
      private static final Logger LOGGER = LoggerFactory.getLogger(MavenDependencyUtil.class.getName());
      private static final ArtifactRepositoryFactory FACTORY = new DefaultArtifactRepositoryFactory();
      private static final String MAVEN_HOME = "MAVEN_HOME";
      private static final String M2_HOME = "M2_HOME";
      private static final String MAVEN_HOME_END = "\\bin\\..";
      private static final String SUFFIX_JAR = ".jar";
      private static final String SUFFIX_WAR = ".war";
      private static final String INFO = "[INFO]";
      private static final String BF = "BUILD FAILURE";
      private static String mavenHome;
      private static final HashMap<String, ArrayList<URL>> CACHE = new HashMap<>();
  
      /**
       * 解析项目pom文件，返回依赖jar的URL数组
       *
       * @param pomPath
       * @return
       * @throws Exception
       */
      public static ArrayList<URL> analysisPOM(String pomPath) throws Exception {
          try {
              if (CACHE.isEmpty()) {
                  CACHE.putAll((Map<String, ArrayList<URL>>) SerializableUtil.readObject(SerializableUtil.FileNameEnum.DEPENDENCY_CACHE));
              }
          } catch (Exception e) {
              LOGGER.info("未找到依赖关系缓存,将从maven依赖中分析");
          }
          if (CACHE.get(pomPath) != null) {
              LOGGER.info("get URLs from cache");
              return CACHE.get(pomPath);
          }
          File pf = new File(pomPath);
          ArrayList<URL> urls = new ArrayList<>();
          if (pf.isDirectory()) {
              getSubFile(pf, urls, 1);
              if (!urls.isEmpty()) {
                  return urls;
              } else {
                  throw new Exception(pomPath + "文件夹中没有任何jar文件");
              }
          }
          ArtifactRepository localRepository = localRepository();
          File pomDir = new File(pomPath).getParentFile();
          String cmd = System.getProperties().getProperty("os.name").toUpperCase().contains("WINDOWS") ? "cmd /c " : "";
          Process p = Runtime.getRuntime().exec(cmd + "mvn dependency:list", null, pomDir);
          boolean error = false;
          try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
              String tmp = br.readLine();
              while (tmp != null) {
                  LOGGER.info(tmp);
                  if (tmp.startsWith(INFO) && tmp.contains(":jar:")) {//io.netty:netty:jar:3.7.0.Final:compile
                      tmp = tmp.replace(INFO, "").trim();
                      String[] args = tmp.split(":");
                      Artifact a = new DefaultArtifact(args[0], args[1], args[3], args[4], args[2], null, new DefaultArtifactHandler());
                      File file = new File(localRepository.getBasedir(), localRepository.pathOf(a) + SUFFIX_JAR);
                      if (!file.exists()) {
                          LOGGER.error("file not found:" + file.getAbsolutePath());
                      } else {
                          urls.add(file.toURI().toURL());
                      }
                  } else if (tmp.contains(BF)) {
                      error = true;
                  }
                  tmp = br.readLine();
              }
          }
          if (error) {
              throw new Exception("项目构建失败，请修复项目错误！");
          }
          p.destroy();
          File target = new File(pomDir.getAbsolutePath() + "/target");
          if (!target.exists()) {
              p = Runtime.getRuntime().exec(cmd + "mvn install -Dmaven.test.skip=true", null, pomDir);
              try (BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()))) {
                  String tmp = br.readLine();
                  while (tmp != null) {
                      LOGGER.info(tmp);
                      if (tmp.contains(BF)) {
                          error = true;
                      }
                      tmp = br.readLine();
                  }
              }
          }
          if (error) {
              throw new Exception("项目构建失败，请修复项目错误！");
          }
          File[] jar = target.listFiles((File dir, String name) -> name.endsWith(SUFFIX_JAR) || name.endsWith(SUFFIX_WAR));
          if (jar != null) {
              for (File file : jar) {
                  urls.add(file.toURI().toURL());
              }
          }
          if (urls.size() > 0) {
              CACHE.put(pomPath, urls);
              SerializableUtil.saveObject(CACHE, SerializableUtil.FileNameEnum.DEPENDENCY_CACHE);
          }
          return urls;
      }
  
      private static void getSubFile(File f, ArrayList<URL> urls, int deep) throws MalformedURLException {
          for (File file : f.listFiles()) {
              if (file.isDirectory() && deep < 30) {
                  getSubFile(file, urls, ++deep);
              } else if (file.getName().endsWith(".jar")) {
                  urls.add(file.toURI().toURL());
              }
          }
      }
  
      /**
       * 从系统环境变量中查找mavenHome
       *
       * @return
       */
      public static String getMavenHome() {
          if (mavenHome == null) {
              mavenHome = System.getenv(M2_HOME);
              if (StringUtils.isBlank(mavenHome)) {
                  LOGGER.error("查询" + M2_HOME + "失败,继续查询" + MAVEN_HOME);
                  mavenHome = System.getenv(MAVEN_HOME);
              }
              if (mavenHome == null || mavenHome.trim().isEmpty()) {
                  LOGGER.error("查询" + MAVEN_HOME + "失败");
              } else {
                  mavenHome = mavenHome.endsWith(MAVEN_HOME_END) ? mavenHome.replace(MAVEN_HOME_END, "") : mavenHome;
                  LOGGER.info(M2_HOME + ":" + mavenHome);
              }
          }
          mavenHome = mavenHome == null ? mavenHome : mavenHome.replace("\\", "/");
          return mavenHome;
      }
  
      /**
       * maven仓库处理
       *
       * @return
       * @throws Exception
       */
      private static ArtifactRepository localRepository() throws Exception {
          if (mavenHome == null) {
              getMavenHome();
          }
          SettingsBuildingRequest request = new DefaultSettingsBuildingRequest();
          request.setGlobalSettingsFile(new File(mavenHome, "/conf/settings.xml"));
  
          DefaultSettingsBuilder builder = new DefaultSettingsBuilderFactory().newInstance();
          SettingsBuildingResult ret = builder.build(request);
  
          String path = ret.getEffectiveSettings().getLocalRepository();
          path = path == null ? String.format("%s%s", System.getProperty("user.home"), "\\.m2\\repository") : path;
          return FACTORY.createArtifactRepository("local", "file://" + path, (ArtifactRepositoryLayout) new DefaultRepositoryLayout(), null, null);
      }
  
      public static void clearCache() {
          SerializableUtil.clearCache(SerializableUtil.FileNameEnum.DEPENDENCY_CACHE);
          CACHE.clear();
      }
  
  }
  