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.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MvnRepository extends APIEventListener {
private static final ModelBuilder MODEL_BUILDER = new DefaultModelBuilderFactory().newInstance();
private Settings settings;
private Settings localSettings;
private Settings projectSettings;
private List<RemoteRepository> remoteRepositories;
private DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
private RepositorySystem repoSys;
private TransfertListener transfertListener = new TransfertListener();
private File projectSettingsFile;
public MvnRepository(File projectSettings){
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 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 File getProjectSettingsFile() {
return projectSettingsFile;
}
private Settings getLocalSettings() throws DocAsCodeException {
if ( localSettings == null )
{
File userSettingsFile = newFile( 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 = newFile( System.getProperty( "user.home" ), ".m2", "repository" ).getAbsolutePath();
localSettings.setLocalRepository( location );
}
}
return localSettings;
}
public List<RemoteRepository> getRemoteRepositories(String id) throws DocAsCodeException {
if (remoteRepositories == null){
remoteRepositories = new ArrayList<>();
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);
}
}
}
for (Profile profile : profiles){
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 authentification parameters found for server '%s'.",
r.getId()), Event.Level.WARN);
}
Authentication a = authBuilder.build();
builder.setAuthentication(a);
remoteRepositories.add(builder.build());
}
}
}
return remoteRepositories;
}
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;
}
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<>();
}
}
public List<Version> getVersionRange(Artifact artifact, List<RemoteRepository> repos) throws DocAsCodeException {
List<Version> result = new ArrayList<>();
for (RemoteRepository r : repos){
result.addAll(getVersionRange(artifact,r));
}
return result;
}
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, List<RemoteRepository> repos) throws DocAsCodeException {
ArtifactResult result = null;
for (RemoteRepository r : repos){
ArtifactResult ret = resolve(artifact,r);
if (ret.isResolved()){
result = ret;
}
}
return result;
}
public Void deploy(List<Artifact> artifacts, RemoteRepository repo) throws DocAsCodeException {
RepositorySystemSession session = getSession( );
DeployRequest request = new DeployRequest();
request.setRepository( repo );
for (Artifact a : artifacts){
List<Version> listVersion = getVersionRange(a,repo);
List<String> listVersionString = new ArrayList<>();
for (Version v : listVersion){
listVersionString.add(v.toString());
}
if (!(listVersionString.contains(a.getVersion()))){
request.setArtifacts(Arrays.asList(a));
log(String.format(
"Deploying artifact '%s'...",a), Event.Level.INFO);
try {
getSystem().deploy(session, request);
} catch (DeploymentException ex) {
throw new DocAsCodeException(
String.format(
"Failed to deploy artifact '%s': %s",
a,
ex.getMessage())
, ex);
}
} else {
log(String.format(
"Artifact '%s' is already deployed.",a), Event.Level.INFO);
}
}
return null;
}
public Void deploy(List<Artifact> artifacts, List<RemoteRepository> repos) throws DocAsCodeException {
for (RemoteRepository r : repos){
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;
}
private File newFile( String parent, String subdir, String filename )
{
return new File( new File( parent, subdir ), filename );
}
}