MvnRepository.java
package org.docascode.api.core.mvn;
import org.apache.maven.model.building.DefaultModelBuilderFactory;
import org.apache.maven.model.building.ModelBuilder;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.apache.maven.settings.*;
import org.apache.maven.settings.io.DefaultSettingsReader;
import org.docascode.api.core.errors.DocAsCodeException;
import org.docascode.api.event.Event;
import org.docascode.api.listener.APIEventListener;
import org.docascode.api.listener.TransfertListener;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
import org.eclipse.aether.deployment.DeployRequest;
import org.eclipse.aether.deployment.DeploymentException;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.repository.Authentication;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.*;
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.transport.classpath.ClasspathTransporterFactory;
import org.eclipse.aether.transport.file.FileTransporterFactory;
import org.eclipse.aether.transport.http.HttpTransporterFactory;
import org.eclipse.aether.util.repository.AuthenticationBuilder;
import org.eclipse.aether.version.Version;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class MvnRepository extends APIEventListener {
private static final ModelBuilder MODEL_BUILDER = new DefaultModelBuilderFactory().newInstance();
private Settings settings;
private Settings localSettings;
private Settings projectSettings;
private File projectSettingsFile;
private List<RemoteRepository> remoteRepositories = new ArrayList<>();
private List<String> profilesId = new ArrayList<>();
private DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
private RepositorySystem repoSys;
private TransfertListener transfertListener = new TransfertListener();
private File baseDir;
public MvnRepository(File projectSettings, File baseDir){
this.baseDir = baseDir;
this.projectSettingsFile = projectSettings;
locator.setServices( ModelBuilder.class, MODEL_BUILDER );
locator.addService( RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class );
locator.addService( TransporterFactory.class, FileTransporterFactory.class );
locator.addService( TransporterFactory.class, HttpTransporterFactory.class );
locator.addService( TransporterFactory.class, ClasspathTransporterFactory.class );
}
private Settings getLocalSettings() throws DocAsCodeException {
if ( localSettings == null )
{
File userSettingsFile = new File( System.getProperty( "user.home" ),".m2/settings.xml" );
if ( userSettingsFile.exists() )
{
DefaultSettingsReader reader = new DefaultSettingsReader();
try {
localSettings = reader.read(userSettingsFile,null);
} catch (IOException e) {
throw new DocAsCodeException(
String.format("Unable to load user settings file '%s'.",userSettingsFile),
e);
}
} else {
localSettings = new Settings();
}
if ( localSettings.getLocalRepository()==null )
{
String location = new File( System.getProperty( "user.home" ), ".m2/repository" ).getAbsolutePath();
localSettings.setLocalRepository( location );
}
}
return localSettings;
}
private File getProjectSettingsFile() {
return projectSettingsFile;
}
private Settings getProjectSettings() throws DocAsCodeException {
if ( projectSettings == null )
{
if ( getProjectSettingsFile().exists() )
{
DefaultSettingsReader reader = new DefaultSettingsReader();
try {
projectSettings = reader.read(getProjectSettingsFile(),null);
} catch (IOException e) {
throw new DocAsCodeException(
String.format("Unable to load project settings file '%s'.",projectSettingsFile),
e);
}
} else {
projectSettings = new Settings();
}
}
return projectSettings;
}
private List<Profile> getProfiles(String id) throws DocAsCodeException {
List<String> activeProfiles = getSettings().getActiveProfiles();
List<Profile> profiles = new ArrayList<>();
if (id != null){
profiles.add(getSettings().getProfilesAsMap().get(id));
} else {
for (Profile profile : getSettings().getProfiles()) {
if ((profile.getActivation() != null && profile.getActivation().isActiveByDefault())
|| activeProfiles.contains(profile.getId())) {
profiles.add(profile);
}
}
}
return profiles;
}
public MvnRepository addRemoteRepositories(String id) throws DocAsCodeException {
if (!this.profilesId.contains(id)) {
this.profilesId.add(id);
List<Profile> profiles = getProfiles(id);
for (Profile profile : profiles) {
if (profile.getRepositories().isEmpty()) {
Repository r = new Repository();
r.setUrl(String.format(
"file://%s/releases",
this.baseDir.getAbsolutePath()));
r.setId("default");
r.setLayout("default");
profile.addRepository(r);
}
for (Repository r : profile.getRepositories()) {
RemoteRepository.Builder builder =
new RemoteRepository.Builder(
r.getId(),
r.getLayout(),
r.getUrl());
Server server = getSettings().getServer(r.getId());
AuthenticationBuilder authBuilder = new AuthenticationBuilder();
if (server != null) {
authBuilder
.addUsername(server.getUsername())
.addPassword(server.getPassword());
} else {
log(
String.format(
"No authentication parameters found for server '%s'.",
r.getId()), Event.Level.DEBUG);
}
Authentication a = authBuilder.build();
builder.setAuthentication(a);
remoteRepositories.add(builder.build());
}
}
}
return this;
}
private Settings getSettings() throws DocAsCodeException {
if ( settings == null )
{
SettingsUtils.merge( getProjectSettings(), getLocalSettings(), TrackableBase.GLOBAL_LEVEL );
this.settings = projectSettings;
}
return settings;
}
public synchronized RepositorySystem getSystem()
{
if ( repoSys == null )
{
repoSys = locator.getService( RepositorySystem.class );
}
return repoSys;
}
public List<Version> getVersionRange(Artifact artifact) throws DocAsCodeException {
List<Version> result = new ArrayList<>();
for (RemoteRepository r : this.remoteRepositories){
result.addAll(getVersionRange(artifact,r));
}
return result;
}
private List<Version> getVersionRange(Artifact artifact, RemoteRepository repo) throws DocAsCodeException {
VersionRangeRequest request = new VersionRangeRequest();
request.setRepositories(Arrays.asList(repo));
Artifact a =
new DefaultArtifact(artifact.getGroupId(),
artifact.getArtifactId(),
artifact.getClassifier(),
artifact.getExtension(),
"[0,)");
request.setArtifact(a);
try {
VersionRangeResult result = getSystem().resolveVersionRange(
getSession(),
request);
return result.getVersions();
} catch (DocAsCodeException e) {
throw new DocAsCodeException(
String.format("Unable to get versions list for artifact '%s'.",a),
e);
} catch (VersionRangeResolutionException e) {
log(String.format("Unable to get versions list for artifact '%s'.",a), Event.Level.WARN);
return new ArrayList<>();
}
}
private ArtifactResult resolve(Artifact artifact, RemoteRepository repo) throws DocAsCodeException {
RepositorySystemSession session = getSession( );
ArtifactRequest request = new ArtifactRequest();
request.setRepositories(Arrays.asList(repo));
request.setArtifact(artifact);
try {
fireEvent(new Event(this)
.setMessage(String.format(
"Resolving artifact '%s'",artifact)
));
return getSystem().resolveArtifacts(session, Arrays.asList(request)).get(0);
} catch (ArtifactResolutionException e) {
throw new DocAsCodeException(
String.format("Unable to resolve artifact '%s' : %s",
artifact,
e.getMessage()),e);
}
}
public ArtifactResult resolve(Artifact artifact) throws DocAsCodeException {
ArtifactResult result = null;
for (RemoteRepository r : this.remoteRepositories){
ArtifactResult ret = resolve(artifact,r);
if (ret.isResolved()){
result = ret;
}
}
return result;
}
public Void deploy(List<Artifacts> artifacts, RemoteRepository repo) throws DocAsCodeException {
RepositorySystemSession session = getSession( );
DeployRequest request = new DeployRequest();
request.setRepository( repo );
for (Artifacts a : artifacts){
List<Version> listVersion = getVersionRange(a.getMainArtifact(),repo);
List<String> listVersionString = new ArrayList<>();
for (Version v : listVersion){
listVersionString.add(v.toString());
}
if (!(listVersionString.contains(a.getMainArtifact().getVersion()))){
request.setArtifacts(a.getArtifacts());
log(String.format(
"Deploying artifact '%s'...",a.getMainArtifact()), Event.Level.INFO);
try {
getSystem().deploy(session, request);
} catch (DeploymentException ex) {
throw new DocAsCodeException(
String.format(
"Failed to deploy artifact '%s': %s",
a.getMainArtifact(),
ex.getMessage())
, ex);
}
} else {
log(String.format(
"Artifact '%s' is already deployed.",a.getMainArtifact()), Event.Level.INFO);
}
}
return null;
}
public Void deploy(List<Artifacts> artifacts) throws DocAsCodeException {
for (RemoteRepository r : this.remoteRepositories){
deploy(artifacts,r);
}
return null;
}
private RepositorySystemSession getSession() throws DocAsCodeException {
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
org.eclipse.aether.repository.LocalRepository localRepo =
new org.eclipse.aether.repository.LocalRepository(new File(
getSettings().getLocalRepository()
));
session.setLocalRepositoryManager(
getSystem().newLocalRepositoryManager( session, localRepo));
session.setTransferListener(transfertListener);
return session;
}
@Override
public MvnRepository addListener(org.docascode.api.listener.EventListener listener){
super.addListener(listener);
transfertListener.addListener(listener);
return this;
}
}