Package net.sourceforge.javautil.classloader.resolver.impl.maven

Source Code of net.sourceforge.javautil.classloader.resolver.impl.maven.MavenRepositoryLocalPackage

package net.sourceforge.javautil.classloader.resolver.impl.maven;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;

import javax.xml.bind.JAXBException;

import net.sourceforge.javautil.classloader.resolver.IClassArtifactReference;
import net.sourceforge.javautil.classloader.resolver.IClassPackageDescriptor;
import net.sourceforge.javautil.classloader.resolver.ClassPackageException;
import net.sourceforge.javautil.classloader.resolver.IClassPackageReference;
import net.sourceforge.javautil.classloader.resolver.IClassPackageRepositoryLocalImportable;
import net.sourceforge.javautil.classloader.resolver.IClassPackageRepositoryRemote;
import net.sourceforge.javautil.classloader.resolver.IClassPackageRepositoryRemoteAttempt;
import net.sourceforge.javautil.classloader.resolver.IClassPackage.IVersion;
import net.sourceforge.javautil.classloader.resolver.IClassPackageRepositoryLocal.RepositoryType;
import net.sourceforge.javautil.classloader.resolver.IClassPackageResolver;
import net.sourceforge.javautil.classloader.resolver.impl.ClassPackageImpl;
import net.sourceforge.javautil.classloader.resolver.impl.ClassPackageRepositoryLocalAbstract;
import net.sourceforge.javautil.classloader.resolver.impl.ClassPackageRepositoryRemoteAttemptImpl;
import net.sourceforge.javautil.classloader.source.ClassSource;
import net.sourceforge.javautil.classloader.source.VirtualDirectoryClassSource;
import net.sourceforge.javautil.common.ChecksumUtil;
import net.sourceforge.javautil.common.CollectionUtil;
import net.sourceforge.javautil.common.FileUtil;
import net.sourceforge.javautil.common.IOUtil;
import net.sourceforge.javautil.common.exception.ThrowableManagerRegistry;
import net.sourceforge.javautil.common.io.IVirtualArtifact;
import net.sourceforge.javautil.common.io.VirtualArtifactNotFoundException;
import net.sourceforge.javautil.common.io.IVirtualDirectory;
import net.sourceforge.javautil.common.io.IVirtualFile;
import net.sourceforge.javautil.common.io.IVirtualPath;
import net.sourceforge.javautil.common.io.impl.SimplePath;
import net.sourceforge.javautil.common.io.impl.SystemDirectory;
import net.sourceforge.javautil.common.xml.XMLDocument;

/**
* This represents a standard maven repository with the standard Maven2 layout.
*
* @author elponderador
* @author $Author$
* @version $Id$
*/
public class MavenRepositoryLocalPackage extends ClassPackageRepositoryLocalAbstract implements IClassPackageRepositoryLocalImportable {
 
  public static final String LOCAL_DEFAULT_OVERRIDE = "net.sf.javautil.maven.repository.default";
 
  /**
   * This will return the default local maven repository. It will check the
   * {@value #LOCAL_DEFAULT_OVERRIDE} system property, and if set use it, otherwise
   * it will use the 'user.home' system property and append .m2/repository
   * to point to the local repository.
   *
   * @return A directory pointing to the local maven repository default
   */
  public static IVirtualDirectory getDefaultLocalPackageRepository () {
    String location = System.getProperty(LOCAL_DEFAULT_OVERRIDE);
    if (location == null) {
      location = MavenLocalSettings.getDefaultInstance().getLocalRepository();
      if (location == null) location = System.getProperty("user.home") + File.separator + ".m2/repository";
    }
    return new SystemDirectory(location);
  }

  protected Logger log = Logger.getLogger(MavenRepositoryLocalPackage.class.getName());
 
  protected final IVirtualDirectory directory;
  protected long lastModified;
 
  public MavenRepositoryLocalPackage() { this(getDefaultLocalPackageRepository()); }
  public MavenRepositoryLocalPackage(IVirtualDirectory directory) {
    this.directory = directory;
    this.lastModified = directory.getLastModified();
  }

  public RepositoryType getRepositoryType() {
    return RepositoryType.Packaged;
  }
 
  @Override protected boolean refreshRoot() {
    if (this.directory.getLastModified() > this.lastModified) {
      this.lastModified = this.directory.getLastModified();
      return true;
    }
    return false;
  }
 
  @Override public void cacheRemoteDescriptor(IClassPackageRepositoryRemote remote, IClassPackageDescriptor descriptor) {
    try {
      IVirtualDirectory packageDir = directory.getDirectory(this.createPackagePath(descriptor), true);

      String prefix = this.createFilenamePrefix(descriptor);
     
      IVirtualFile imported = packageDir.getFile(remote.getName().replaceAll("[:/]+", "-") + "remote-" + prefix + ".pom", true);
      ((ProjectObjectModel) descriptor).write(imported.getOutputStream());
    } catch (VirtualArtifactNotFoundException e) {
      throw new ClassPackageException(descriptor, "Could not import remote descriptor", e);
    } catch (IOException e) {
      throw new ClassPackageException(descriptor, "Could not import remote descriptor", e);
    } catch (JAXBException e) {
      throw new ClassPackageException(descriptor, "Could not import remote descriptor", e);
    }
  }
 
  @Override public IClassPackageDescriptor getCachedRemotedDescriptor(IClassPackageResolver resolver, IClassPackageRepositoryRemote remote, IClassPackageReference reference) {
    IVirtualDirectory packageDir = directory.getDirectory(this.createPackagePath(reference), true);

    String prefix = this.createFilenamePrefix(reference);
   
    IVirtualFile cache = packageDir.getFile( remote.getName().replaceAll("[:/ ]+", "-") + "remote-" + prefix + ".pom" );
   
    ProjectObjectModel pom = cache == null ? null : ProjectObjectModel.parse(resolver, cache);
   
    return pom;
  }
 
  public void cacheRemoteAttempt(List<IClassPackageRepositoryRemote> remote, IClassPackageReference reference) {
    IVirtualDirectory packageDir = directory.getDirectory(this.createPackagePath(reference), true);

    String filename = this.createFilenamePrefix(reference) + ".pom.lastUpdated";
    Properties properties = new Properties();
   
    if (packageDir.getFile(filename) != null) {
      try {
        properties.load(packageDir.getFile(filename).getInputStream());
      } catch (IOException e) {
        log.warning("Could not load previous remote attempt cache for: " + reference + ": " + e.getMessage());
        ThrowableManagerRegistry.caught(e);
      }
    }
   
    IVirtualFile cache = packageDir.getFile(filename, true);
    for (IClassPackageRepositoryRemote rr : remote) {
      properties.setProperty(rr.getRepositoryURL().toExternalForm(), String.valueOf(System.currentTimeMillis()));
    }
   
    OutputStream out = null;
    try {
      out = cache.getOutputStream();
      properties.store(out, "#Last modified on: " + new Date());
    } catch (IOException e) {
      throw ThrowableManagerRegistry.caught(e);
    } finally {
      if (out != null) try { out.close(); } catch (IOException e) { ThrowableManagerRegistry.caught(e); }
    }
  }
 
  public List<IClassPackageRepositoryRemoteAttempt> getLastRemoteAttempts(IClassPackageReference reference) {
    List<IClassPackageRepositoryRemoteAttempt> attempts = new ArrayList<IClassPackageRepositoryRemoteAttempt>();
   
    IVirtualDirectory packageDir = this.getDirectory(reference);
    if (packageDir != null) {
      IVirtualFile cache = packageDir.getFile(this.createFilenamePrefix(reference) + ".pom.lastUpdated");
      if (cache != null) {
        try {
          Properties properties = new Properties();
          properties.load( cache.getInputStream() );
          Enumeration names = properties.propertyNames();
          while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
            attempts.add(new ClassPackageRepositoryRemoteAttemptImpl(Long.parseLong(properties.getProperty(name)), name));
          }
        } catch (NumberFormatException e) {
          throw ThrowableManagerRegistry.caught(e);
        } catch (IOException e) {
          throw ThrowableManagerRegistry.caught(e);
        }
      }
    }
   
    return attempts;
  }
 
  public void importPackage(IVirtualFile file, String packaging, IClassPackageReference reference) {
    IVirtualDirectory packageDir = directory.getDirectory(this.createPackagePath(reference), true);
   
    String jarPrefix = this.createJarPrefix(reference);
    String prefix = this.createFilenamePrefix(reference);
   
    IVirtualFile target = packageDir.getFile(jarPrefix + "." + packaging);
    if (target == null) {
      ProjectObjectModel pom = new ProjectObjectModel();
      pom.setModelVersion("4.0");
      pom.setGroupId(reference.getGroupId());
      pom.setArtifactId(reference.getArtifactId());
      pom.setVersionString(reference.getVersion().toVersionString());
      pom.setPackaging(packaging);
     
      try {
        pom.write(packageDir.createFile(prefix + ".pom").getOutputStream());
        file.copy( packageDir.createFile(jarPrefix + "." + packaging) );
       
        this.clearCachedInformation(reference);
      } catch (JAXBException e) {
        throw ThrowableManagerRegistry.caught(e);
      } catch (IOException e) {
        throw ThrowableManagerRegistry.caught(e);
      }
    } else {
      throw new IllegalArgumentException("This package already exists");
    }
  }
 
  public void importPackage(IClassPackageRepositoryRemote remote, IClassPackageResolver resolver, IClassPackageReference reference) {
    IVirtualDirectory packageDir = directory.getDirectory(this.createPackagePath(reference), true);

    String jarPrefix = this.createJarPrefix(reference);
    String prefix = this.createFilenamePrefix(reference);
   
    URL source = null;
   
    URL pom = remote.getResource(reference, prefix + ".pom");
    if (pom != null) {
      boolean validated = this.download(pom, packageDir.getFile(prefix + ".pom", true));
     
      if (!validated) this.handleInvalidChecksum(packageDir, reference, pom);
     
      ProjectObjectModel pomXml = this.resolveDescriptor(resolver, reference);
      if ("pom".equals( pomXml.getPackaging() )) return;
     
      source = remote.getResource(reference, jarPrefix + ".jar");
      if (source == null) return;
     
    } else {
      return;
    }
   
    boolean validated = this.download(source, packageDir.getFile(jarPrefix + ".jar", true));
    if (!validated) this.handleInvalidChecksum(packageDir, reference, pom);
  }

  @Override protected ClassSource resolve(String type, IClassPackageResolver resolver, IClassPackageReference reference) {
    IClassPackageDescriptor descriptor = this.getDescriptor(resolver, reference);
    if (descriptor != null) {
      if (!"main".equalsIgnoreCase(type)) return null;
     
      try {
        IVirtualFile jar = this.getDirectory(reference).getFile(this.createJarPrefix(reference) + ".jar");
        return jar == null ? null : this.getClassSource(reference, jar);
      } catch (VirtualArtifactNotFoundException e) {
        throw ThrowableManagerRegistry.caught(e);
      }
    }
    return null;
  }

  @Override public ProjectObjectModel resolveDescriptor(IClassPackageResolver resolver, IClassPackageReference reference) {
    IVirtualDirectory directory = this.getDirectory(reference);
    if (directory != null) {
      IVirtualFile pd = directory.getFile( this.createFilenamePrefix(reference) + ".pom" );
      try {
        ProjectObjectModel model = pd != null ? ProjectObjectModel.parse(resolver, pd) : null;
//        if (model != null && model.getVersion() == null)
//          model.setVersionString( reference.getVersion().toVersionString() );
//       
//        if (model != null && model.getParent() != null) {
//          model.setParentPom( (ProjectObjectModel) resolver.getDescriptor(model.getParent()) );
//        }
       
        return model;
      } catch (Exception e) {
        e.printStackTrace();
        log.warning("Could not get descriptor: (" + reference + "): " + e.getMessage());
        throw ThrowableManagerRegistry.caught(e);
      }
    }
    return null;
  }
 
  public List<IVersion> getVersionsAvailable(IClassArtifactReference reference) {
    try {
      IVirtualDirectory artifactDir = this.directory.getDirectory( this.createArtifactPath(reference) );
     
      List<IVersion> version = new ArrayList<IVersion>();
     
      for (IVirtualDirectory versionDir : artifactDir.getDirectories()) {
        version.add( ClassPackageImpl.decode(versionDir.getName()) );
      }
     
      return version;
    } catch (VirtualArtifactNotFoundException e) {
      return Collections.EMPTY_LIST;
    }
  }

  public boolean contains(IClassPackageResolver resolver, IClassArtifactReference reference) { return this.getDirectory(reference) != null; }

  public boolean contains(IClassPackageResolver resolver, IClassPackageReference reference) { return this.getDirectory(reference) != null; }
 
  public IVirtualDirectory getDirectory (IClassPackageReference reference) {
    try {
      return this.directory.getDirectory( this.createPackagePath(reference) );
    } catch (VirtualArtifactNotFoundException e) {
      return null;
    }
  }

  public IVirtualDirectory getDirectory (IClassArtifactReference reference) {
    try {
      return this.directory.getDirectory( this.createArtifactPath(reference) );
    } catch (VirtualArtifactNotFoundException e) {
      return null;
    }
  }
 
  public String createJarPrefix(IClassPackageReference reference) {
    StringBuffer sb = new StringBuffer()
      .append( reference.getArtifactId() )
      .append( "-" )
      .append( reference.getVersion().toVersionString() );

    if (reference.getClassifier() != null) {
      sb.append("-").append(reference.getClassifier());
    }
   
    return sb.toString();
  }
 
  public String createFilenamePrefix(IClassPackageReference reference) {
    return new StringBuffer()
      .append( reference.getArtifactId() )
      .append( "-" )
      .append( reference.getVersion().toVersionString() )
      .toString();
  }

  public IVirtualPath createPackagePath(IClassPackageReference reference) {
    return new SimplePath( CollectionUtil.push(reference.getGroupId().split("\\."),
      reference.getArtifactId(), reference.getVersion().toVersionString()) );
  }

  public IVirtualPath createArtifactPath(IClassArtifactReference reference) {
    return new SimplePath( CollectionUtil.push(reference.getGroupId().split("\\."), reference.getArtifactId() ));
  }

  /**
   * @param versionDirectory The version directory related to the checksum failure
   * @param project The project related to the failure
   * @param url The URL that failed checksum validation
   */
  protected void handleInvalidChecksum (IVirtualDirectory versionDirectory, IClassPackageReference reference, URL url) {
    log.warning(reference + " download did not pass checksum validation: " + url);
   
    versionDirectory.remove();
    throw new ClassPackageException(reference, "Checksum invalid");
  }
 
  /**
   * Download and possibly validate (check sum) a package from one repository to this local repository.
   *
   * @param resolver The resolver to use in the download.
   */
  protected boolean download (URL source, IVirtualFile targetFile) {
    try {
      log.warning("Downloading to maven repository (" + directory + "): " + source);
     
      ByteArrayOutputStream checksumOut = new ByteArrayOutputStream();
      String type = ChecksumUtil.downloadWithChecksum(source, checksumOut, targetFile.getOutputStream(), false);

      if (type != null) {
        IVirtualFile checksumFile = targetFile.getOwner().getFile(targetFile.getName() + ("md5".equals(type) ? ".md5" : ".sha1"), true);
        IOUtil.transfer(new ByteArrayInputStream(checksumOut.toByteArray()), checksumFile.getOutputStream());
      }
     
      return true;
    } catch (NoSuchAlgorithmException e) {
      ThrowableManagerRegistry.caught(e);
      return false;
    } catch (IOException e) {
      ThrowableManagerRegistry.caught(e);
      return false;
    } catch (RuntimeException e) {
      ThrowableManagerRegistry.caught(e);
      return false;
    }
  }

}
TOP

Related Classes of net.sourceforge.javautil.classloader.resolver.impl.maven.MavenRepositoryLocalPackage

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.