Package org.jboss.forge.maven.dependencies

Source Code of org.jboss.forge.maven.dependencies.ClasspathWorkspaceReader

/*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Eclipse Public License version 1.0, available at
* http://www.eclipse.org/legal/epl-v10.html
*/

package org.jboss.forge.maven.dependencies;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jboss.forge.parser.xml.Node;
import org.jboss.forge.parser.xml.XMLParser;
import org.sonatype.aether.artifact.Artifact;
import org.sonatype.aether.repository.WorkspaceReader;
import org.sonatype.aether.repository.WorkspaceRepository;
import org.sonatype.aether.util.artifact.DefaultArtifact;

/**
* {@link WorkspaceReader} implementation capable of reading from the ClassPath
*
* Based on the ClasspathWorkspaceReader provided by ShrinkWrap Resolver
*
* @author <a href="mailto:ggastakd@redhat.com">George Gastaldi</a>
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
*/
public class ClasspathWorkspaceReader implements WorkspaceReader
{

   private static final Logger log = Logger.getLogger(ClasspathWorkspaceReader.class.getName());

   /**
    * class path entry
    */
   private static final String CLASS_PATH_KEY = "java.class.path";

   /**
    * surefire cannot modify class path for test execution, so it have to store it in a different variable
    */
   private static final String SUREFIRE_CLASS_PATH_KEY = "surefire.test.class.path";

   private final Set<String> classPathEntries = new LinkedHashSet<String>();

   /**
    * Cache classpath File objects and retrieved isFile isDirectory values. Key is a classpath entry
    *
    * @see #getClasspathFile(String)
    */
   private final Map<String, File> classpathFileInfoCache = new HashMap<String, File>();

   /**
    * Cache pom File objects and retrieved isFile isDirectory values. Key - child File
    *
    * @see #getPomFile(java.io.File)
    */
   private final Map<File, File> pomFileInfoCache = new HashMap<File, File>();

   /**
    * Cache Found in classpath artifacts. Key is a pom file.
    *
    * @see #getFoundArtifact(java.io.File)
    */
   private final Map<File, Artifact> foundArtifactCache = new HashMap<File, Artifact>();

   /**
    * Repository unique in this instance
    *
    * @see #getRepository()
    */
   private WorkspaceRepository repository = new WorkspaceRepository("classpath");

   public ClasspathWorkspaceReader()
   {
      final String classPath = System.getProperty(CLASS_PATH_KEY);
      final String surefireClassPath = System.getProperty(SUREFIRE_CLASS_PATH_KEY);
      this.classPathEntries.addAll(getClassPathEntries(surefireClassPath));
      this.classPathEntries.addAll(getClassPathEntries(classPath));
   }

   @Override
   public WorkspaceRepository getRepository()
   {
      return repository;
   }

   @Override
   public File findArtifact(final Artifact artifact)
   {
      for (String classpathEntry : classPathEntries)
      {
         final File file = getClasspathFile(classpathEntry);

         if (file.isDirectory())
         {
            // TODO: This is not reliable, file might have different name
            // FIXME: Surefire might user jar in the classpath instead of the target/classes
            final File pomFile = getPomFile(file);
            if (pomFile.isFile())
            {
               final Artifact foundArtifact = getFoundArtifact(pomFile);

               if (foundArtifact.getGroupId().equals(artifact.getGroupId())
                        && foundArtifact.getArtifactId().equals(artifact.getArtifactId())
                        && foundArtifact.getVersion().equals(artifact.getVersion()))
               {
                  if ("pom".equals(artifact.getExtension()))
                  {
                     return pomFile;
                  }
                  else
                  {
                     return new File(file.getParentFile(), "classes");
                  }
               }
            }
         }
         // this is needed for Surefire when run as 'mvn package'
         else if (file.isFile())
         {
            final StringBuilder name = new StringBuilder(artifact.getArtifactId()).append("-").append(
                     artifact.getVersion());

            // TODO: This is nasty
            // we need to get a a pom.xml file to be sure we fetch transitive deps as well
            if (file.getName().contains(name.toString()))
            {
               if ("pom".equals(artifact.getExtension()))
               {
                  // try to get pom file for the project
                  final File pomFile = new File(file.getParentFile().getParentFile(), "pom.xml");
                  if (pomFile.isFile())
                  {
                     Artifact foundArtifact = getFoundArtifact(pomFile);
                     if (foundArtifact.getGroupId().equals(artifact.getGroupId())
                              && foundArtifact.getArtifactId().equals(artifact.getArtifactId())
                              && foundArtifact.getVersion().equals(artifact.getVersion()))
                     {

                        // System.out
                        // .println("BUILD: ################################# Artifact: " + artifact + " POM: "
                        // + pomFile);
                        return pomFile;
                     }
                  }
               }
               // SHRINKRES-102, consider classifier as well
               String classifier = artifact.getClassifier();
               if (classifier != null && !classifier.isEmpty())
               {
                  name.append("-").append(classifier);
               }

               // we are looking for a non pom artifact, let's get it
               name.append(".").append(artifact.getExtension());
               if (file.getName().equals(name.toString()))
               {
                  // return raw file
                  return file;
               }
            }
         }
      }

      return null;
   }

   @Override
   public List<String> findVersions(final Artifact artifact)
   {
      Set<String> versions = new TreeSet<String>();
      for (String classpathEntry : classPathEntries)
      {
         final File file = getClasspathFile(classpathEntry);

         if (file.isDirectory())
         {
            // TODO: This is not reliable, file might have different name
            // FIXME: Surefire might use jar in the classpath instead of the target/classes
            final File pomFile = getPomFile(file);
            if (pomFile.isFile())
            {
               final Artifact foundArtifact = getFoundArtifact(pomFile);

               if (foundArtifact.getGroupId().equals(artifact.getGroupId())
                        && foundArtifact.getArtifactId().equals(artifact.getArtifactId()))
               {
                  versions.add(foundArtifact.getVersion());
               }
            }
         }
         // this is needed for Surefire when run as 'mvn package'
         else if (file.isFile())
         {
            final StringBuilder name = new StringBuilder(artifact.getArtifactId()).append("-").append(
                     artifact.getVersion());

            // TODO: This is nasty
            // we need to get a a pom.xml file to be sure we fetch transitive deps as well
            if (file.getName().contains(name.toString()))
            {
               if ("pom".equals(artifact.getExtension()))
               {
                  // try to get pom file for the project
                  final File pomFile = new File(file.getParentFile().getParentFile(), "pom.xml");
                  if (pomFile.isFile())
                  {
                     final Artifact foundArtifact = getFoundArtifact(pomFile);

                     if (foundArtifact.getGroupId().equals(artifact.getGroupId())
                              && foundArtifact.getArtifactId().equals(artifact.getArtifactId()))
                     {
                        versions.add(foundArtifact.getVersion());
                     }
                  }
               }
            }
         }
      }
      return new ArrayList<String>(versions);
   }

   private Set<String> getClassPathEntries(final String classPath)
   {
      if (classPath == null || classPath.isEmpty())
      {
         return Collections.emptySet();
      }
      return new LinkedHashSet<String>(Arrays.asList(classPath.split(File.pathSeparator)));
   }

   private File getClasspathFile(final String classpathEntry)
   {
      File classpathFileInfo = classpathFileInfoCache.get(classpathEntry);
      if (classpathFileInfo == null)
      {
         classpathFileInfo = new File(classpathEntry);
         classpathFileInfoCache.put(classpathEntry, classpathFileInfo);
      }
      return classpathFileInfo;
   }

   private File getPomFile(final File childFile)
   {
      File pomFileInfo = pomFileInfoCache.get(childFile);
      if (pomFileInfo == null)
      {
         pomFileInfo = new File(childFile.getParentFile().getParentFile(), "pom.xml");
         pomFileInfoCache.put(childFile, pomFileInfo);
      }
      return pomFileInfo;
   }

   private Artifact getFoundArtifact(final File pomFile)
   {
      Artifact foundArtifact = foundArtifactCache.get(pomFile);
      if (foundArtifact == null)
      {
         foundArtifact = createFoundArtifact(pomFile);
         foundArtifactCache.put(pomFile, foundArtifact);
      }
      return foundArtifact;
   }

   private Artifact createFoundArtifact(final File pomFile)
   {
      try
      {
         if (log.isLoggable(Level.FINE))
         {
            log.fine("Processing " + pomFile.getAbsolutePath() + " for classpath artifact resolution");
         }

         final Node pom = XMLParser.parse(pomFile);

         String groupId = pom.getTextValueForPatternName("groupId");
         String artifactId = pom.getTextValueForPatternName("artifactId");
         String type = pom.getTextValueForPatternName("packaging");
         String version = pom.getTextValueForPatternName("version");

         if (groupId == null || groupId.isEmpty())
         {
            groupId = pom.getTextValueForPatternName("parent/groupId");
         }
         if (type == null || type.isEmpty())
         {
            type = "jar";
         }
         if (version == null || version.isEmpty())
         {
            version = pom.getTextValueForPatternName("parent/version");
         }

         final Artifact foundArtifact = new DefaultArtifact(groupId, artifactId, type, version);
         foundArtifact.setFile(pomFile);
         return foundArtifact;
      }
      catch (final Exception e)
      {
         throw new RuntimeException("Could not parse pom.xml: " + pomFile, e);
      }
   }
}
TOP

Related Classes of org.jboss.forge.maven.dependencies.ClasspathWorkspaceReader

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.