mirror of https://github.com/apache/maven.git
[MNG-4381] Allow extension plugins to contribute non-core components to be reused by other plugins
git-svn-id: https://svn.apache.org/repos/asf/maven/maven-3/trunk@819540 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
51b6120810
commit
5950571180
|
@ -43,6 +43,14 @@ public interface ClassRealmManager
|
||||||
*/
|
*/
|
||||||
ClassRealm createProjectRealm( Model model );
|
ClassRealm createProjectRealm( Model model );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new class realm for the specified build extension.
|
||||||
|
*
|
||||||
|
* @param plugin The extension plugin for which to create a realm, must not be {@code null}.
|
||||||
|
* @return The new extension realm, never {@code null}.
|
||||||
|
*/
|
||||||
|
ClassRealm createExtensionRealm( Plugin extension );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new class realm for the specified plugin.
|
* Creates a new class realm for the specified plugin.
|
||||||
*
|
*
|
||||||
|
|
|
@ -197,6 +197,16 @@ public class DefaultClassRealmManager
|
||||||
return "project>" + model.getGroupId() + ":" + model.getArtifactId() + ":" + model.getVersion();
|
return "project>" + model.getGroupId() + ":" + model.getArtifactId() + ":" + model.getVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ClassRealm createExtensionRealm( Plugin plugin )
|
||||||
|
{
|
||||||
|
if ( plugin == null )
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException( "extension plugin missing" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return createRealm( getKey( plugin, true ), null, null );
|
||||||
|
}
|
||||||
|
|
||||||
public ClassRealm createPluginRealm( Plugin plugin, ClassLoader parent, List<String> imports )
|
public ClassRealm createPluginRealm( Plugin plugin, ClassLoader parent, List<String> imports )
|
||||||
{
|
{
|
||||||
if ( plugin == null )
|
if ( plugin == null )
|
||||||
|
@ -204,13 +214,14 @@ public class DefaultClassRealmManager
|
||||||
throw new IllegalArgumentException( "plugin missing" );
|
throw new IllegalArgumentException( "plugin missing" );
|
||||||
}
|
}
|
||||||
|
|
||||||
return createRealm( getKey( plugin ), parent, imports );
|
return createRealm( getKey( plugin, false ), parent, imports );
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getKey( Plugin plugin )
|
private String getKey( Plugin plugin, boolean extension )
|
||||||
{
|
{
|
||||||
String version = ArtifactUtils.toSnapshotVersion( plugin.getVersion() );
|
String version = ArtifactUtils.toSnapshotVersion( plugin.getVersion() );
|
||||||
return "plugin>" + plugin.getGroupId() + ":" + plugin.getArtifactId() + ":" + version;
|
return ( extension ? "extension>" : "plugin>" ) + plugin.getGroupId() + ":" + plugin.getArtifactId() + ":"
|
||||||
|
+ version;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ClassRealmManagerDelegate> getDelegates()
|
private List<ClassRealmManagerDelegate> getDelegates()
|
||||||
|
|
|
@ -0,0 +1,231 @@
|
||||||
|
package org.apache.maven.plugin;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.maven.artifact.Artifact;
|
||||||
|
import org.apache.maven.artifact.repository.ArtifactRepository;
|
||||||
|
import org.apache.maven.artifact.repository.RepositoryRequest;
|
||||||
|
import org.apache.maven.model.Dependency;
|
||||||
|
import org.apache.maven.model.Exclusion;
|
||||||
|
import org.apache.maven.model.Plugin;
|
||||||
|
import org.apache.maven.project.ExtensionDescriptor;
|
||||||
|
import org.apache.maven.project.MavenProject;
|
||||||
|
import org.codehaus.plexus.classworlds.realm.ClassRealm;
|
||||||
|
import org.codehaus.plexus.component.annotations.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default extension realm cache implementation. Assumes cached data does not change.
|
||||||
|
*/
|
||||||
|
@Component( role = ExtensionRealmCache.class )
|
||||||
|
public class DefaultExtensionRealmCache
|
||||||
|
implements ExtensionRealmCache
|
||||||
|
{
|
||||||
|
|
||||||
|
private static class CacheKey
|
||||||
|
{
|
||||||
|
|
||||||
|
private final Plugin extension;
|
||||||
|
|
||||||
|
private final List<ArtifactRepository> repositories = new ArrayList<ArtifactRepository>();
|
||||||
|
|
||||||
|
private final int hashCode;
|
||||||
|
|
||||||
|
public CacheKey( Plugin extension, RepositoryRequest repositoryRequest )
|
||||||
|
{
|
||||||
|
this.extension = extension.clone();
|
||||||
|
this.repositories.add( repositoryRequest.getLocalRepository() );
|
||||||
|
this.repositories.addAll( repositoryRequest.getRemoteRepositories() );
|
||||||
|
|
||||||
|
int hash = 17;
|
||||||
|
hash = hash * 31 + extensionHashCode( extension );
|
||||||
|
hash = hash * 31 + repositories.hashCode();
|
||||||
|
this.hashCode = hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals( Object o )
|
||||||
|
{
|
||||||
|
if ( o == this )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !( o instanceof CacheKey ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CacheKey other = (CacheKey) o;
|
||||||
|
|
||||||
|
return extensionEquals( extension, other.extension ) && eq( repositories, other.repositories );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Map<CacheKey, CacheRecord> cache = new HashMap<CacheKey, CacheRecord>();
|
||||||
|
|
||||||
|
public CacheRecord get( Plugin extension, RepositoryRequest repositoryRequest )
|
||||||
|
{
|
||||||
|
return cache.get( new CacheKey( extension, repositoryRequest ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put( Plugin extension, RepositoryRequest repositoryRequest, ClassRealm extensionRealm,
|
||||||
|
List<Artifact> extensionArtifacts, ExtensionDescriptor extensionDescriptor )
|
||||||
|
{
|
||||||
|
if ( extensionRealm == null || extensionArtifacts == null )
|
||||||
|
{
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
|
||||||
|
CacheKey key = new CacheKey( extension, repositoryRequest );
|
||||||
|
|
||||||
|
if ( cache.containsKey( key ) )
|
||||||
|
{
|
||||||
|
throw new IllegalStateException( "Duplicate extension realm for extension " + extension.getId() );
|
||||||
|
}
|
||||||
|
|
||||||
|
CacheRecord record = new CacheRecord( extensionRealm, extensionArtifacts, extensionDescriptor );
|
||||||
|
cache.put( key, record );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush()
|
||||||
|
{
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static int extensionHashCode( Plugin extension )
|
||||||
|
{
|
||||||
|
int hash = 17;
|
||||||
|
|
||||||
|
hash = hash * 31 + extension.getGroupId().hashCode();
|
||||||
|
hash = hash * 31 + extension.getArtifactId().hashCode();
|
||||||
|
hash = hash * 31 + extension.getVersion().hashCode();
|
||||||
|
|
||||||
|
for ( Dependency dependency : extension.getDependencies() )
|
||||||
|
{
|
||||||
|
hash = hash * 31 + dependency.getGroupId().hashCode();
|
||||||
|
hash = hash * 31 + dependency.getArtifactId().hashCode();
|
||||||
|
hash = hash * 31 + dependency.getVersion().hashCode();
|
||||||
|
hash = hash * 31 + dependency.getType().hashCode();
|
||||||
|
hash = hash * 31 + ( dependency.getClassifier() != null ? dependency.getClassifier().hashCode() : 0 );
|
||||||
|
hash = hash * 31 + ( dependency.getScope() != null ? dependency.getScope().hashCode() : 0 );
|
||||||
|
|
||||||
|
for ( Exclusion exclusion : dependency.getExclusions() )
|
||||||
|
{
|
||||||
|
hash = hash * 31 + exclusion.getGroupId().hashCode();
|
||||||
|
hash = hash * 31 + exclusion.getArtifactId().hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean extensionEquals( Plugin a, Plugin b )
|
||||||
|
{
|
||||||
|
return eq( a.getGroupId(), b.getGroupId() ) //
|
||||||
|
&& eq( a.getArtifactId(), b.getArtifactId() ) //
|
||||||
|
&& eq( a.getVersion(), b.getVersion() ) //
|
||||||
|
&& a.isExtensions() == b.isExtensions() //
|
||||||
|
&& dependenciesEquals( a.getDependencies(), b.getDependencies() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean dependenciesEquals( List<Dependency> a, List<Dependency> b )
|
||||||
|
{
|
||||||
|
if ( a.size() != b.size() )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<Dependency> aI = a.iterator();
|
||||||
|
Iterator<Dependency> bI = b.iterator();
|
||||||
|
|
||||||
|
while ( aI.hasNext() )
|
||||||
|
{
|
||||||
|
Dependency aD = aI.next();
|
||||||
|
Dependency bD = bI.next();
|
||||||
|
|
||||||
|
boolean r = eq( aD.getGroupId(), bD.getGroupId() ) //
|
||||||
|
&& eq( aD.getArtifactId(), bD.getArtifactId() ) //
|
||||||
|
&& eq( aD.getVersion(), bD.getVersion() ) //
|
||||||
|
&& eq( aD.getType(), bD.getType() ) //
|
||||||
|
&& eq( aD.getClassifier(), bD.getClassifier() ) //
|
||||||
|
&& eq( aD.getScope(), bD.getScope() );
|
||||||
|
|
||||||
|
r &= exclusionsEquals( aD.getExclusions(), bD.getExclusions() );
|
||||||
|
|
||||||
|
if ( !r )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean exclusionsEquals( List<Exclusion> a, List<Exclusion> b )
|
||||||
|
{
|
||||||
|
if ( a.size() != b.size() )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<Exclusion> aI = a.iterator();
|
||||||
|
Iterator<Exclusion> bI = b.iterator();
|
||||||
|
|
||||||
|
while ( aI.hasNext() )
|
||||||
|
{
|
||||||
|
Exclusion aD = aI.next();
|
||||||
|
Exclusion bD = bI.next();
|
||||||
|
|
||||||
|
boolean r = eq( aD.getGroupId(), bD.getGroupId() ) //
|
||||||
|
&& eq( aD.getArtifactId(), bD.getArtifactId() );
|
||||||
|
|
||||||
|
if ( !r )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> boolean eq( T s1, T s2 )
|
||||||
|
{
|
||||||
|
return s1 != null ? s1.equals( s2 ) : s2 == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register( MavenProject project, ClassRealm extensionRealm )
|
||||||
|
{
|
||||||
|
// default cache does not track extension usage
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
package org.apache.maven.plugin;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.maven.artifact.Artifact;
|
||||||
|
import org.apache.maven.artifact.repository.RepositoryRequest;
|
||||||
|
import org.apache.maven.model.Plugin;
|
||||||
|
import org.apache.maven.project.ExtensionDescriptor;
|
||||||
|
import org.apache.maven.project.MavenProject;
|
||||||
|
import org.codehaus.plexus.classworlds.realm.ClassRealm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caches extension class realms. <strong>Warning:</strong> This is an internal utility interface that is only public
|
||||||
|
* for technical reasons, it is not part of the public API. In particular, this interface can be changed or deleted
|
||||||
|
* without prior notice.
|
||||||
|
*
|
||||||
|
* @author Igor Fedorenko
|
||||||
|
* @author Benjamin Bentmann
|
||||||
|
*/
|
||||||
|
public interface ExtensionRealmCache
|
||||||
|
{
|
||||||
|
|
||||||
|
public static class CacheRecord
|
||||||
|
{
|
||||||
|
|
||||||
|
public final ClassRealm realm;
|
||||||
|
|
||||||
|
public final List<Artifact> artifacts;
|
||||||
|
|
||||||
|
public final ExtensionDescriptor desciptor;
|
||||||
|
|
||||||
|
public CacheRecord( ClassRealm realm, List<Artifact> artifacts, ExtensionDescriptor descriptor )
|
||||||
|
{
|
||||||
|
this.realm = realm;
|
||||||
|
this.artifacts = artifacts;
|
||||||
|
this.desciptor = descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CacheRecord get( Plugin extension, RepositoryRequest repositoryRequest );
|
||||||
|
|
||||||
|
void put( Plugin extension, RepositoryRequest repositoryRequest, ClassRealm extensionRealm,
|
||||||
|
List<Artifact> extensionArtifacts, ExtensionDescriptor extensionDescriptor );
|
||||||
|
|
||||||
|
void flush();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the specified extension realm for usage with the given project. Integrators can use the information
|
||||||
|
* collected from this method in combination with a custom cache implementation to dispose unused extension realms
|
||||||
|
* from the cache.
|
||||||
|
*
|
||||||
|
* @param project The project that employs the extension realm, must not be {@code null}.
|
||||||
|
* @param extensionRealm The extension realm being used for the project, must not be {@code null}.
|
||||||
|
*/
|
||||||
|
void register( MavenProject project, ClassRealm extensionRealm );
|
||||||
|
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -42,6 +43,7 @@ import org.apache.maven.artifact.resolver.ArtifactResolutionException;
|
||||||
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
|
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
|
||||||
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
|
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
|
||||||
import org.apache.maven.artifact.resolver.ResolutionErrorHandler;
|
import org.apache.maven.artifact.resolver.ResolutionErrorHandler;
|
||||||
|
import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
|
||||||
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
|
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
|
||||||
import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
|
import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
|
||||||
import org.apache.maven.classrealm.ClassRealmManager;
|
import org.apache.maven.classrealm.ClassRealmManager;
|
||||||
|
@ -339,13 +341,16 @@ public class DefaultMavenPluginManager
|
||||||
throw new IllegalArgumentException( "incomplete plugin descriptor, plugin artifact missing" );
|
throw new IllegalArgumentException( "incomplete plugin descriptor, plugin artifact missing" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MavenProject project = session.getCurrentProject();
|
||||||
|
|
||||||
RepositoryRequest request = new DefaultRepositoryRequest();
|
RepositoryRequest request = new DefaultRepositoryRequest();
|
||||||
request.setLocalRepository( session.getLocalRepository() );
|
request.setLocalRepository( session.getLocalRepository() );
|
||||||
request.setRemoteRepositories( session.getCurrentProject().getPluginArtifactRepositories() );
|
request.setRemoteRepositories( project.getPluginArtifactRepositories() );
|
||||||
request.setCache( session.getRepositoryCache() );
|
request.setCache( session.getRepositoryCache() );
|
||||||
request.setOffline( session.isOffline() );
|
request.setOffline( session.isOffline() );
|
||||||
|
|
||||||
List<Artifact> pluginArtifacts = resolvePluginArtifacts( plugin, pluginArtifact, request );
|
List<Artifact> pluginArtifacts =
|
||||||
|
resolvePluginArtifacts( plugin, pluginArtifact, request, project.getExtensionArtifactFilter() );
|
||||||
|
|
||||||
ClassRealm pluginRealm = classRealmManager.createPluginRealm( plugin, parent, imports );
|
ClassRealm pluginRealm = classRealmManager.createPluginRealm( plugin, parent, imports );
|
||||||
|
|
||||||
|
@ -417,7 +422,8 @@ public class DefaultMavenPluginManager
|
||||||
*/
|
*/
|
||||||
// FIXME: only exposed to allow workaround for MNG-4194
|
// FIXME: only exposed to allow workaround for MNG-4194
|
||||||
protected List<Artifact> resolvePluginArtifacts( Plugin plugin, Artifact pluginArtifact,
|
protected List<Artifact> resolvePluginArtifacts( Plugin plugin, Artifact pluginArtifact,
|
||||||
RepositoryRequest repositoryRequest )
|
RepositoryRequest repositoryRequest,
|
||||||
|
ArtifactFilter extensionArtifactFilter )
|
||||||
throws PluginResolutionException
|
throws PluginResolutionException
|
||||||
{
|
{
|
||||||
Set<Artifact> overrideArtifacts = new LinkedHashSet<Artifact>();
|
Set<Artifact> overrideArtifacts = new LinkedHashSet<Artifact>();
|
||||||
|
@ -430,6 +436,11 @@ public class DefaultMavenPluginManager
|
||||||
|
|
||||||
ArtifactFilter resolutionFilter = artifactFilterManager.getCoreArtifactFilter();
|
ArtifactFilter resolutionFilter = artifactFilterManager.getCoreArtifactFilter();
|
||||||
|
|
||||||
|
if ( extensionArtifactFilter != null )
|
||||||
|
{
|
||||||
|
resolutionFilter = new AndArtifactFilter( Arrays.asList( resolutionFilter, extensionArtifactFilter ) );
|
||||||
|
}
|
||||||
|
|
||||||
ArtifactResolutionRequest request = new ArtifactResolutionRequest( repositoryRequest );
|
ArtifactResolutionRequest request = new ArtifactResolutionRequest( repositoryRequest );
|
||||||
request.setArtifact( pluginArtifact );
|
request.setArtifact( pluginArtifact );
|
||||||
request.setArtifactDependencies( overrideArtifacts );
|
request.setArtifactDependencies( overrideArtifacts );
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.apache.maven.artifact.repository.ArtifactRepository;
|
||||||
import org.apache.maven.artifact.repository.DefaultRepositoryRequest;
|
import org.apache.maven.artifact.repository.DefaultRepositoryRequest;
|
||||||
import org.apache.maven.artifact.repository.RepositoryRequest;
|
import org.apache.maven.artifact.repository.RepositoryRequest;
|
||||||
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
|
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
|
||||||
|
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
|
||||||
import org.apache.maven.model.Model;
|
import org.apache.maven.model.Model;
|
||||||
import org.apache.maven.model.building.AbstractModelBuildingListener;
|
import org.apache.maven.model.building.AbstractModelBuildingListener;
|
||||||
import org.apache.maven.model.building.ModelBuildingEvent;
|
import org.apache.maven.model.building.ModelBuildingEvent;
|
||||||
|
@ -46,6 +47,8 @@ class DefaultModelBuildingListener
|
||||||
|
|
||||||
private ClassRealm projectRealm;
|
private ClassRealm projectRealm;
|
||||||
|
|
||||||
|
private ArtifactFilter extensionArtifactFilter;
|
||||||
|
|
||||||
private List<ArtifactRepository> remoteRepositories;
|
private List<ArtifactRepository> remoteRepositories;
|
||||||
|
|
||||||
private List<ArtifactRepository> pluginRepositories;
|
private List<ArtifactRepository> pluginRepositories;
|
||||||
|
@ -78,6 +81,16 @@ class DefaultModelBuildingListener
|
||||||
return projectRealm;
|
return projectRealm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the artifact filter to exclude extension artifacts from plugin realms.
|
||||||
|
*
|
||||||
|
* @return The extension artifact filter or {@code null} if none.
|
||||||
|
*/
|
||||||
|
public ArtifactFilter getExtentionArtifactFilter()
|
||||||
|
{
|
||||||
|
return extensionArtifactFilter;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the effective remote artifact repositories for the project. The repository list is created from the
|
* Gets the effective remote artifact repositories for the project. The repository list is created from the
|
||||||
* repositories given by {@link ProjectBuildingRequest#getRemoteRepositories()} and the repositories given in the
|
* repositories given by {@link ProjectBuildingRequest#getRemoteRepositories()} and the repositories given in the
|
||||||
|
@ -111,17 +124,6 @@ class DefaultModelBuildingListener
|
||||||
{
|
{
|
||||||
Model model = event.getModel();
|
Model model = event.getModel();
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
remoteRepositories =
|
|
||||||
projectBuildingHelper.createArtifactRepositories( model.getRepositories(), remoteRepositories,
|
|
||||||
projectBuildingRequest );
|
|
||||||
}
|
|
||||||
catch ( Exception e )
|
|
||||||
{
|
|
||||||
event.getProblems().addError( "Invalid artifact repository: " + e.getMessage(), e );
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
pluginRepositories =
|
pluginRepositories =
|
||||||
|
@ -143,7 +145,11 @@ class DefaultModelBuildingListener
|
||||||
repositoryRequest.setRemoteRepositories( pluginRepositories );
|
repositoryRequest.setRemoteRepositories( pluginRepositories );
|
||||||
repositoryRequest.setOffline( projectBuildingRequest.isOffline() );
|
repositoryRequest.setOffline( projectBuildingRequest.isOffline() );
|
||||||
|
|
||||||
projectRealm = projectBuildingHelper.createProjectRealm( model, repositoryRequest );
|
ProjectRealmCache.CacheRecord record =
|
||||||
|
projectBuildingHelper.createProjectRealm( model, repositoryRequest );
|
||||||
|
|
||||||
|
projectRealm = record.realm;
|
||||||
|
extensionArtifactFilter = record.extensionArtifactFilter;
|
||||||
}
|
}
|
||||||
catch ( ArtifactResolutionException e )
|
catch ( ArtifactResolutionException e )
|
||||||
{
|
{
|
||||||
|
@ -164,6 +170,18 @@ class DefaultModelBuildingListener
|
||||||
Thread.currentThread().setContextClassLoader( projectRealm );
|
Thread.currentThread().setContextClassLoader( projectRealm );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// build the regular repos after extensions are loaded to allow for custom layouts
|
||||||
|
try
|
||||||
|
{
|
||||||
|
remoteRepositories =
|
||||||
|
projectBuildingHelper.createArtifactRepositories( model.getRepositories(), remoteRepositories,
|
||||||
|
projectBuildingRequest );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
event.getProblems().addError( "Invalid artifact repository: " + e.getMessage(), e );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -486,6 +486,7 @@ public class DefaultProjectBuilder
|
||||||
project.setPluginArtifactRepositories( listener.getPluginRepositories() );
|
project.setPluginArtifactRepositories( listener.getPluginRepositories() );
|
||||||
|
|
||||||
project.setClassRealm( listener.getProjectRealm() );
|
project.setClassRealm( listener.getProjectRealm() );
|
||||||
|
project.setExtensionArtifactFilter( listener.getExtentionArtifactFilter() );
|
||||||
|
|
||||||
Build build = project.getBuild();
|
Build build = project.getBuild();
|
||||||
project.addScriptSourceRoot( build.getScriptSourceDirectory() );
|
project.addScriptSourceRoot( build.getScriptSourceDirectory() );
|
||||||
|
|
|
@ -19,10 +19,14 @@ package org.apache.maven.project;
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.maven.ArtifactFilterManager;
|
import org.apache.maven.ArtifactFilterManager;
|
||||||
|
@ -35,6 +39,8 @@ import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
|
||||||
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
|
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
|
||||||
import org.apache.maven.artifact.resolver.ResolutionErrorHandler;
|
import org.apache.maven.artifact.resolver.ResolutionErrorHandler;
|
||||||
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
|
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
|
||||||
|
import org.apache.maven.artifact.resolver.filter.ExclusionSetFilter;
|
||||||
|
import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
|
||||||
import org.apache.maven.classrealm.ClassRealmManager;
|
import org.apache.maven.classrealm.ClassRealmManager;
|
||||||
import org.apache.maven.model.Build;
|
import org.apache.maven.model.Build;
|
||||||
import org.apache.maven.model.Dependency;
|
import org.apache.maven.model.Dependency;
|
||||||
|
@ -42,6 +48,7 @@ import org.apache.maven.model.Extension;
|
||||||
import org.apache.maven.model.Model;
|
import org.apache.maven.model.Model;
|
||||||
import org.apache.maven.model.Plugin;
|
import org.apache.maven.model.Plugin;
|
||||||
import org.apache.maven.model.Repository;
|
import org.apache.maven.model.Repository;
|
||||||
|
import org.apache.maven.plugin.ExtensionRealmCache;
|
||||||
import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
|
import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
|
||||||
import org.apache.maven.plugin.version.PluginVersionRequest;
|
import org.apache.maven.plugin.version.PluginVersionRequest;
|
||||||
import org.apache.maven.plugin.version.PluginVersionResolutionException;
|
import org.apache.maven.plugin.version.PluginVersionResolutionException;
|
||||||
|
@ -74,6 +81,12 @@ public class DefaultProjectBuildingHelper
|
||||||
@Requirement
|
@Requirement
|
||||||
private ClassRealmManager classRealmManager;
|
private ClassRealmManager classRealmManager;
|
||||||
|
|
||||||
|
@Requirement
|
||||||
|
private ExtensionRealmCache extensionRealmCache;
|
||||||
|
|
||||||
|
@Requirement
|
||||||
|
private ProjectRealmCache projectRealmCache;
|
||||||
|
|
||||||
@Requirement
|
@Requirement
|
||||||
private RepositorySystem repositorySystem;
|
private RepositorySystem repositorySystem;
|
||||||
|
|
||||||
|
@ -86,6 +99,8 @@ public class DefaultProjectBuildingHelper
|
||||||
@Requirement
|
@Requirement
|
||||||
private PluginVersionResolver pluginVersionResolver;
|
private PluginVersionResolver pluginVersionResolver;
|
||||||
|
|
||||||
|
private ExtensionDescriptorBuilder extensionDescriptorBuilder = new ExtensionDescriptorBuilder();
|
||||||
|
|
||||||
public List<ArtifactRepository> createArtifactRepositories( List<Repository> pomRepositories,
|
public List<ArtifactRepository> createArtifactRepositories( List<Repository> pomRepositories,
|
||||||
List<ArtifactRepository> externalRepositories,
|
List<ArtifactRepository> externalRepositories,
|
||||||
ProjectBuildingRequest request )
|
ProjectBuildingRequest request )
|
||||||
|
@ -114,20 +129,27 @@ public class DefaultProjectBuildingHelper
|
||||||
return artifactRepositories;
|
return artifactRepositories;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassRealm createProjectRealm( Model model, RepositoryRequest repositoryRequest )
|
public synchronized ProjectRealmCache.CacheRecord createProjectRealm( Model model,
|
||||||
|
RepositoryRequest repositoryRequest )
|
||||||
throws ArtifactResolutionException, PluginVersionResolutionException
|
throws ArtifactResolutionException, PluginVersionResolutionException
|
||||||
{
|
{
|
||||||
ClassRealm projectRealm = null;
|
ClassRealm projectRealm = null;
|
||||||
|
|
||||||
|
List<Plugin> extensionPlugins = new ArrayList<Plugin>();
|
||||||
|
|
||||||
Build build = model.getBuild();
|
Build build = model.getBuild();
|
||||||
|
|
||||||
if ( build == null )
|
if ( build != null )
|
||||||
{
|
{
|
||||||
return projectRealm;
|
for ( Extension extension : build.getExtensions() )
|
||||||
|
{
|
||||||
|
Plugin plugin = new Plugin();
|
||||||
|
plugin.setGroupId( extension.getGroupId() );
|
||||||
|
plugin.setArtifactId( extension.getArtifactId() );
|
||||||
|
plugin.setVersion( extension.getVersion() );
|
||||||
|
extensionPlugins.add( plugin );
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Plugin> extensionPlugins = new ArrayList<Plugin>();
|
|
||||||
|
|
||||||
for ( Plugin plugin : build.getPlugins() )
|
for ( Plugin plugin : build.getPlugins() )
|
||||||
{
|
{
|
||||||
if ( plugin.isExtensions() )
|
if ( plugin.isExtensions() )
|
||||||
|
@ -135,30 +157,20 @@ public class DefaultProjectBuildingHelper
|
||||||
extensionPlugins.add( plugin );
|
extensionPlugins.add( plugin );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( build.getExtensions().isEmpty() && extensionPlugins.isEmpty() )
|
|
||||||
{
|
|
||||||
return projectRealm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
projectRealm = classRealmManager.createProjectRealm( model );
|
if ( extensionPlugins.isEmpty() )
|
||||||
|
|
||||||
for ( Extension extension : build.getExtensions() )
|
|
||||||
{
|
{
|
||||||
if ( extension.getVersion() == null )
|
return new ProjectRealmCache.CacheRecord( null, null );
|
||||||
{
|
|
||||||
PluginVersionRequest versionRequest = new DefaultPluginVersionRequest( repositoryRequest );
|
|
||||||
versionRequest.setGroupId( extension.getGroupId() );
|
|
||||||
versionRequest.setArtifactId( extension.getArtifactId() );
|
|
||||||
extension.setVersion( pluginVersionResolver.resolve( versionRequest ).getVersion() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Artifact artifact =
|
List<ClassRealm> extensionRealms = new ArrayList<ClassRealm>();
|
||||||
repositorySystem.createArtifact( extension.getGroupId(), extension.getArtifactId(),
|
|
||||||
extension.getVersion(), "jar" );
|
|
||||||
|
|
||||||
populateRealm( projectRealm, artifact, null, repositoryRequest );
|
Map<ClassRealm, List<String>> exportedPackages = new HashMap<ClassRealm, List<String>>();
|
||||||
}
|
|
||||||
|
Map<ClassRealm, List<String>> exportedArtifacts = new HashMap<ClassRealm, List<String>>();
|
||||||
|
|
||||||
|
List<Artifact> publicArtifacts = new ArrayList<Artifact>();
|
||||||
|
|
||||||
for ( Plugin plugin : extensionPlugins )
|
for ( Plugin plugin : extensionPlugins )
|
||||||
{
|
{
|
||||||
|
@ -168,73 +180,206 @@ public class DefaultProjectBuildingHelper
|
||||||
plugin.setVersion( pluginVersionResolver.resolve( versionRequest ).getVersion() );
|
plugin.setVersion( pluginVersionResolver.resolve( versionRequest ).getVersion() );
|
||||||
}
|
}
|
||||||
|
|
||||||
Artifact artifact = repositorySystem.createPluginArtifact( plugin );
|
ClassRealm extensionRealm;
|
||||||
|
List<Artifact> artifacts;
|
||||||
|
ExtensionDescriptor extensionDescriptor = null;
|
||||||
|
|
||||||
Set<Artifact> dependencies = new LinkedHashSet<Artifact>();
|
ExtensionRealmCache.CacheRecord record = extensionRealmCache.get( plugin, repositoryRequest );
|
||||||
for ( Dependency dependency : plugin.getDependencies() )
|
|
||||||
|
if ( record != null )
|
||||||
{
|
{
|
||||||
dependencies.add( repositorySystem.createDependencyArtifact( dependency ) );
|
extensionRealm = record.realm;
|
||||||
|
artifacts = record.artifacts;
|
||||||
|
extensionDescriptor = record.desciptor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
artifacts = resolveExtensionArtifacts( plugin, repositoryRequest );
|
||||||
|
|
||||||
|
extensionRealm = classRealmManager.createExtensionRealm( plugin );
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled() )
|
||||||
|
{
|
||||||
|
logger.debug( "Populating extension realm for " + plugin.getId() );
|
||||||
}
|
}
|
||||||
|
|
||||||
populateRealm( projectRealm, artifact, dependencies, repositoryRequest );
|
for ( Artifact artifact : artifacts )
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
container.discoverComponents( projectRealm );
|
if ( artifact.getFile() != null )
|
||||||
}
|
|
||||||
catch ( Exception e )
|
|
||||||
{
|
|
||||||
throw new IllegalStateException( "Failed to discover components in project realm " + projectRealm.getId(),
|
|
||||||
e );
|
|
||||||
}
|
|
||||||
|
|
||||||
return projectRealm;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populateRealm( ClassRealm realm, Artifact artifact, Set<Artifact> dependencies,
|
|
||||||
RepositoryRequest repositoryRequest )
|
|
||||||
throws ArtifactResolutionException
|
|
||||||
{
|
|
||||||
ArtifactResolutionRequest request = new ArtifactResolutionRequest( repositoryRequest );
|
|
||||||
request.setArtifact( artifact );
|
|
||||||
request.setArtifactDependencies( dependencies );
|
|
||||||
request.setResolveTransitively( true );
|
|
||||||
// FIXME setTransferListener
|
|
||||||
|
|
||||||
ArtifactResolutionResult result = repositorySystem.resolve( request );
|
|
||||||
|
|
||||||
resolutionErrorHandler.throwErrors( request, result );
|
|
||||||
|
|
||||||
ArtifactFilter filter = artifactFilterManager.getCoreArtifactFilter();
|
|
||||||
|
|
||||||
for ( Artifact resultArtifact : result.getArtifacts() )
|
|
||||||
{
|
|
||||||
if ( filter.include( resultArtifact ) )
|
|
||||||
{
|
{
|
||||||
if ( logger.isDebugEnabled() )
|
if ( logger.isDebugEnabled() )
|
||||||
{
|
{
|
||||||
logger.debug( " Included: " + resultArtifact.getId() );
|
logger.debug( " Included: " + artifact.getId() );
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
realm.addURL( resultArtifact.getFile().toURI().toURL() );
|
extensionRealm.addURL( artifact.getFile().toURI().toURL() );
|
||||||
}
|
}
|
||||||
catch ( MalformedURLException e )
|
catch ( MalformedURLException e )
|
||||||
{
|
{
|
||||||
throw new IllegalStateException( "Failed to populate project realm " + realm.getId() + " with "
|
// Not going to happen
|
||||||
+ artifact.getFile(), e );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( logger.isDebugEnabled() )
|
if ( logger.isDebugEnabled() )
|
||||||
{
|
{
|
||||||
logger.debug( " Excluded: " + resultArtifact.getId() );
|
logger.debug( " Excluded: " + artifact.getId() );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
container.discoverComponents( extensionRealm );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
throw new IllegalStateException( "Failed to discover components in extension realm "
|
||||||
|
+ extensionRealm.getId(), e );
|
||||||
|
}
|
||||||
|
|
||||||
|
Artifact extensionArtifact = artifacts.get( 0 );
|
||||||
|
try
|
||||||
|
{
|
||||||
|
extensionDescriptor = extensionDescriptorBuilder.build( extensionArtifact.getFile() );
|
||||||
|
}
|
||||||
|
catch ( IOException e )
|
||||||
|
{
|
||||||
|
String message = "Invalid extension descriptor for " + plugin.getId() + ": " + e.getMessage();
|
||||||
|
if ( logger.isDebugEnabled() )
|
||||||
|
{
|
||||||
|
logger.error( message, e );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.error( message );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extensionRealmCache.put( plugin, repositoryRequest, extensionRealm, artifacts, extensionDescriptor );
|
||||||
|
}
|
||||||
|
|
||||||
|
extensionRealms.add( extensionRealm );
|
||||||
|
if ( extensionDescriptor != null )
|
||||||
|
{
|
||||||
|
exportedPackages.put( extensionRealm, extensionDescriptor.getExportedPackages() );
|
||||||
|
exportedArtifacts.put( extensionRealm, extensionDescriptor.getExportedArtifacts() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !plugin.isExtensions() && artifacts.size() == 1 && artifacts.get( 0 ).getFile() != null )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This is purely for backward-compat with 2.x where <extensions> consisting of a single artifact where
|
||||||
|
* loaded into the core and hence available to plugins, in contrast to bigger extensions that were
|
||||||
|
* loaded into a dedicated realm which is invisible to plugins.
|
||||||
|
*/
|
||||||
|
publicArtifacts.addAll( artifacts );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectRealmCache.CacheRecord record = projectRealmCache.get( extensionRealms );
|
||||||
|
|
||||||
|
if ( record == null )
|
||||||
|
{
|
||||||
|
projectRealm = classRealmManager.createProjectRealm( model );
|
||||||
|
|
||||||
|
if ( logger.isDebugEnabled() )
|
||||||
|
{
|
||||||
|
logger.debug( "Populating project realm for " + model.getId() );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( Artifact publicArtifact : publicArtifacts )
|
||||||
|
{
|
||||||
|
if ( logger.isDebugEnabled() )
|
||||||
|
{
|
||||||
|
logger.debug( " Included: " + publicArtifact.getId() );
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
projectRealm.addURL( publicArtifact.getFile().toURI().toURL() );
|
||||||
|
}
|
||||||
|
catch ( MalformedURLException e )
|
||||||
|
{
|
||||||
|
// can't happen
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> exclusions = new LinkedHashSet<String>();
|
||||||
|
|
||||||
|
for ( ClassRealm extensionRealm : extensionRealms )
|
||||||
|
{
|
||||||
|
List<String> excludes = exportedArtifacts.get( extensionRealm );
|
||||||
|
|
||||||
|
if ( excludes != null )
|
||||||
|
{
|
||||||
|
exclusions.addAll( excludes );
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> exports = exportedPackages.get( extensionRealm );
|
||||||
|
|
||||||
|
if ( exports == null || exports.isEmpty() )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Most existing extensions don't define exported packages, i.e. no classes are to be exposed to
|
||||||
|
* plugins, yet the components provided by the extension (e.g. artifact handlers) must be
|
||||||
|
* accessible, i.e. we still must import the extension realm into the project realm.
|
||||||
|
*/
|
||||||
|
exports = Arrays.asList( extensionRealm.getId() );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( String export : exports )
|
||||||
|
{
|
||||||
|
projectRealm.importFrom( extensionRealm, export );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ArtifactFilter extensionArtifactFilter = null;
|
||||||
|
if ( !exclusions.isEmpty() )
|
||||||
|
{
|
||||||
|
extensionArtifactFilter = new ExclusionSetFilter( exclusions );
|
||||||
|
}
|
||||||
|
|
||||||
|
projectRealmCache.put( extensionRealms, projectRealm, extensionArtifactFilter );
|
||||||
|
|
||||||
|
record = new ProjectRealmCache.CacheRecord( projectRealm, extensionArtifactFilter );
|
||||||
|
}
|
||||||
|
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Artifact> resolveExtensionArtifacts( Plugin extensionPlugin, RepositoryRequest repositoryRequest )
|
||||||
|
throws ArtifactResolutionException
|
||||||
|
{
|
||||||
|
Artifact extensionArtifact = repositorySystem.createPluginArtifact( extensionPlugin );
|
||||||
|
|
||||||
|
Set<Artifact> overrideArtifacts = new LinkedHashSet<Artifact>();
|
||||||
|
for ( Dependency dependency : extensionPlugin.getDependencies() )
|
||||||
|
{
|
||||||
|
overrideArtifacts.add( repositorySystem.createDependencyArtifact( dependency ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
ArtifactFilter collectionFilter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME_PLUS_SYSTEM );
|
||||||
|
|
||||||
|
ArtifactFilter resolutionFilter = artifactFilterManager.getCoreArtifactFilter();
|
||||||
|
|
||||||
|
ArtifactResolutionRequest request = new ArtifactResolutionRequest( repositoryRequest );
|
||||||
|
request.setArtifact( extensionArtifact );
|
||||||
|
request.setArtifactDependencies( overrideArtifacts );
|
||||||
|
request.setCollectionFilter( collectionFilter );
|
||||||
|
request.setResolutionFilter( resolutionFilter );
|
||||||
|
request.setResolveRoot( true );
|
||||||
|
request.setResolveTransitively( true );
|
||||||
|
|
||||||
|
ArtifactResolutionResult result = repositorySystem.resolve( request );
|
||||||
|
|
||||||
|
resolutionErrorHandler.throwErrors( request, result );
|
||||||
|
|
||||||
|
List<Artifact> extensionArtifacts = new ArrayList<Artifact>( result.getArtifacts() );
|
||||||
|
|
||||||
|
return extensionArtifacts;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
package org.apache.maven.project;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
|
||||||
|
import org.codehaus.plexus.classworlds.realm.ClassRealm;
|
||||||
|
import org.codehaus.plexus.component.annotations.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default project realm cache implementation. Assumes cached data does not change.
|
||||||
|
*/
|
||||||
|
@Component( role = ProjectRealmCache.class )
|
||||||
|
public class DefaultProjectRealmCache
|
||||||
|
implements ProjectRealmCache
|
||||||
|
{
|
||||||
|
|
||||||
|
private static class CacheKey
|
||||||
|
{
|
||||||
|
|
||||||
|
private final List<? extends ClassRealm> extensionRealms;
|
||||||
|
|
||||||
|
private final int hashCode;
|
||||||
|
|
||||||
|
public CacheKey( List<? extends ClassRealm> extensionRealms )
|
||||||
|
{
|
||||||
|
this.extensionRealms = ( extensionRealms != null ) ? extensionRealms : Collections.<ClassRealm> emptyList();
|
||||||
|
|
||||||
|
this.hashCode = this.extensionRealms.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals( Object o )
|
||||||
|
{
|
||||||
|
if ( o == this )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !( o instanceof CacheKey ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CacheKey other = (CacheKey) o;
|
||||||
|
|
||||||
|
return extensionRealms.equals( other.extensionRealms );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Map<CacheKey, CacheRecord> cache = new HashMap<CacheKey, CacheRecord>();
|
||||||
|
|
||||||
|
public CacheRecord get( List<? extends ClassRealm> extensionRealms )
|
||||||
|
{
|
||||||
|
return cache.get( new CacheKey( extensionRealms ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put( List<? extends ClassRealm> extensionRealms, ClassRealm projectRealm,
|
||||||
|
ArtifactFilter extensionArtifactFilter )
|
||||||
|
{
|
||||||
|
if ( projectRealm == null )
|
||||||
|
{
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
|
||||||
|
CacheKey key = new CacheKey( extensionRealms );
|
||||||
|
|
||||||
|
if ( cache.containsKey( key ) )
|
||||||
|
{
|
||||||
|
throw new IllegalStateException( "Duplicate project realm for extensions " + extensionRealms );
|
||||||
|
}
|
||||||
|
|
||||||
|
CacheRecord record = new CacheRecord( projectRealm, extensionArtifactFilter );
|
||||||
|
cache.put( key, record );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush()
|
||||||
|
{
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package org.apache.maven.project;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides metadata about a build extension. <strong>Warning:</strong> This is an internal utility class that is only
|
||||||
|
* public for technical reasons, it is not part of the public API. In particular, this class can be changed or deleted
|
||||||
|
* without prior notice.
|
||||||
|
*
|
||||||
|
* @author Benjamin Bentmann
|
||||||
|
*/
|
||||||
|
public class ExtensionDescriptor
|
||||||
|
{
|
||||||
|
|
||||||
|
private List<String> exportedPackages;
|
||||||
|
|
||||||
|
private List<String> exportedArtifacts;
|
||||||
|
|
||||||
|
ExtensionDescriptor()
|
||||||
|
{
|
||||||
|
// hide constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getExportedPackages()
|
||||||
|
{
|
||||||
|
if ( exportedPackages == null )
|
||||||
|
{
|
||||||
|
exportedPackages = new ArrayList<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return exportedPackages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExportedPackages( List<String> exportedPackages )
|
||||||
|
{
|
||||||
|
if ( exportedPackages == null )
|
||||||
|
{
|
||||||
|
this.exportedPackages = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.exportedPackages = new ArrayList<String>( exportedPackages );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getExportedArtifacts()
|
||||||
|
{
|
||||||
|
if ( exportedArtifacts == null )
|
||||||
|
{
|
||||||
|
exportedArtifacts = new ArrayList<String>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return exportedArtifacts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExportedArtifacts( List<String> exportedArtifacts )
|
||||||
|
{
|
||||||
|
if ( exportedArtifacts == null )
|
||||||
|
{
|
||||||
|
this.exportedArtifacts = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.exportedArtifacts = new ArrayList<String>( exportedArtifacts );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,159 @@
|
||||||
|
package org.apache.maven.project;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.jar.JarFile;
|
||||||
|
import java.util.zip.ZipEntry;
|
||||||
|
|
||||||
|
import org.codehaus.plexus.util.IOUtil;
|
||||||
|
import org.codehaus.plexus.util.ReaderFactory;
|
||||||
|
import org.codehaus.plexus.util.xml.Xpp3Dom;
|
||||||
|
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
|
||||||
|
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an extension descriptor from some XML stream.
|
||||||
|
*
|
||||||
|
* @author Benjamin Bentmann
|
||||||
|
*/
|
||||||
|
class ExtensionDescriptorBuilder
|
||||||
|
{
|
||||||
|
|
||||||
|
private String getExtensionDescriptorLocation()
|
||||||
|
{
|
||||||
|
return "META-INF/maven/extension.xml";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the extension descriptor (if any) from the specified JAR file.
|
||||||
|
*
|
||||||
|
* @param extensionJar The JAR file or directory to extract the descriptor from, must not be {@code null}.
|
||||||
|
* @return The extracted descriptor or {@code null} if no descriptor was found.
|
||||||
|
* @throws IOException If the descriptor is present but could not be parsed.
|
||||||
|
*/
|
||||||
|
public ExtensionDescriptor build( File extensionJar )
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
ExtensionDescriptor extensionDescriptor = null;
|
||||||
|
|
||||||
|
if ( extensionJar.isFile() )
|
||||||
|
{
|
||||||
|
JarFile pluginJar = new JarFile( extensionJar, false );
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ZipEntry pluginDescriptorEntry = pluginJar.getEntry( getExtensionDescriptorLocation() );
|
||||||
|
|
||||||
|
if ( pluginDescriptorEntry != null )
|
||||||
|
{
|
||||||
|
InputStream is = pluginJar.getInputStream( pluginDescriptorEntry );
|
||||||
|
|
||||||
|
extensionDescriptor = build( is );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
pluginJar.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
File pluginXml = new File( extensionJar, getExtensionDescriptorLocation() );
|
||||||
|
|
||||||
|
if ( pluginXml.canRead() )
|
||||||
|
{
|
||||||
|
InputStream is = new BufferedInputStream( new FileInputStream( pluginXml ) );
|
||||||
|
try
|
||||||
|
{
|
||||||
|
extensionDescriptor = build( is );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IOUtil.close( is );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return extensionDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtensionDescriptor build( InputStream is )
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
ExtensionDescriptor extensionDescriptor = new ExtensionDescriptor();
|
||||||
|
|
||||||
|
Xpp3Dom dom;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
dom = Xpp3DomBuilder.build( ReaderFactory.newXmlReader( is ) );
|
||||||
|
}
|
||||||
|
catch ( XmlPullParserException e )
|
||||||
|
{
|
||||||
|
throw (IOException) new IOException( e.getMessage() ).initCause( e );
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IOUtil.close( is );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !"extension".equals( dom.getName() ) )
|
||||||
|
{
|
||||||
|
throw new IOException( "Unexpected root element \"" + dom.getName() + "\", expected \"extension\"" );
|
||||||
|
}
|
||||||
|
|
||||||
|
extensionDescriptor.setExportedPackages( parseStrings( dom.getChild( "exportedPackages" ) ) );
|
||||||
|
|
||||||
|
extensionDescriptor.setExportedArtifacts( parseStrings( dom.getChild( "exportedArtifacts" ) ) );
|
||||||
|
|
||||||
|
return extensionDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> parseStrings( Xpp3Dom dom )
|
||||||
|
{
|
||||||
|
List<String> strings = null;
|
||||||
|
|
||||||
|
if ( dom != null )
|
||||||
|
{
|
||||||
|
strings = new ArrayList<String>();
|
||||||
|
|
||||||
|
for ( Xpp3Dom child : dom.getChildren() )
|
||||||
|
{
|
||||||
|
String string = child.getValue();
|
||||||
|
if ( string != null )
|
||||||
|
{
|
||||||
|
string = string.trim();
|
||||||
|
if ( string.length() > 0 )
|
||||||
|
{
|
||||||
|
strings.add( string );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -167,6 +167,8 @@ public class MavenProject
|
||||||
|
|
||||||
private ClassRealm classRealm;
|
private ClassRealm classRealm;
|
||||||
|
|
||||||
|
private ArtifactFilter extensionArtifactFilter;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
public MavenProject()
|
public MavenProject()
|
||||||
|
@ -1948,7 +1950,9 @@ public class MavenProject
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the project's class realm.
|
* Sets the project's class realm. <strong>Warning:</strong> This is an internal utility method that is only public
|
||||||
|
* for technical reasons, it is not part of the public API. In particular, this method can be changed or deleted
|
||||||
|
* without prior notice and must not be used by plugins.
|
||||||
*
|
*
|
||||||
* @param classRealm The class realm hosting the build extensions of this project, may be {@code null}.
|
* @param classRealm The class realm hosting the build extensions of this project, may be {@code null}.
|
||||||
*/
|
*/
|
||||||
|
@ -1959,6 +1963,9 @@ public class MavenProject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the project's class realm. This class realm hosts the build extensions of the project.
|
* Gets the project's class realm. This class realm hosts the build extensions of the project.
|
||||||
|
* <strong>Warning:</strong> This is an internal utility method that is only public for technical reasons, it is not
|
||||||
|
* part of the public API. In particular, this method can be changed or deleted without prior notice and must not be
|
||||||
|
* used by plugins.
|
||||||
*
|
*
|
||||||
* @return The project's class realm or {@code null}.
|
* @return The project's class realm or {@code null}.
|
||||||
*/
|
*/
|
||||||
|
@ -1967,4 +1974,28 @@ public class MavenProject
|
||||||
return classRealm;
|
return classRealm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the artifact filter used to exclude shared extension artifacts from plugin realms. <strong>Warning:</strong>
|
||||||
|
* This is an internal utility method that is only public for technical reasons, it is not part of the public API.
|
||||||
|
* In particular, this method can be changed or deleted without prior notice and must not be used by plugins.
|
||||||
|
*
|
||||||
|
* @param extensionArtifactFilter The artifact filter to apply to plugins, may be {@code null}.
|
||||||
|
*/
|
||||||
|
public void setExtensionArtifactFilter( ArtifactFilter extensionArtifactFilter )
|
||||||
|
{
|
||||||
|
this.extensionArtifactFilter = extensionArtifactFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the artifact filter used to exclude shared extension artifacts from plugin realms. <strong>Warning:</strong>
|
||||||
|
* This is an internal utility method that is only public for technical reasons, it is not part of the public API.
|
||||||
|
* In particular, this method can be changed or deleted without prior notice and must not be used by plugins.
|
||||||
|
*
|
||||||
|
* @return The artifact filter or {@code null}.
|
||||||
|
*/
|
||||||
|
public ArtifactFilter getExtensionArtifactFilter()
|
||||||
|
{
|
||||||
|
return extensionArtifactFilter;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ import org.apache.maven.artifact.resolver.ArtifactResolutionException;
|
||||||
import org.apache.maven.model.Model;
|
import org.apache.maven.model.Model;
|
||||||
import org.apache.maven.model.Repository;
|
import org.apache.maven.model.Repository;
|
||||||
import org.apache.maven.plugin.version.PluginVersionResolutionException;
|
import org.apache.maven.plugin.version.PluginVersionResolutionException;
|
||||||
import org.codehaus.plexus.classworlds.realm.ClassRealm;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assists the project builder. <strong>Warning:</strong> This is an internal utility interface that is only public for
|
* Assists the project builder. <strong>Warning:</strong> This is an internal utility interface that is only public for
|
||||||
|
@ -61,10 +60,10 @@ public interface ProjectBuildingHelper
|
||||||
*
|
*
|
||||||
* @param model The model to create the project realm for, must not be {@code null}
|
* @param model The model to create the project realm for, must not be {@code null}
|
||||||
* @param repositoryRequest The repository request to use for artifact resolution, must not be {@code null}.
|
* @param repositoryRequest The repository request to use for artifact resolution, must not be {@code null}.
|
||||||
* @return The project realm or {@code null} if the project uses no extensions.
|
* @return The record with the project realm and extension artifact filter, never {@code null}.
|
||||||
* @throws ArtifactResolutionException If any build extension could not be resolved.
|
* @throws ArtifactResolutionException If any build extension could not be resolved.
|
||||||
*/
|
*/
|
||||||
ClassRealm createProjectRealm( Model model, RepositoryRequest repositoryRequest )
|
ProjectRealmCache.CacheRecord createProjectRealm( Model model, RepositoryRequest repositoryRequest )
|
||||||
throws ArtifactResolutionException, PluginVersionResolutionException;
|
throws ArtifactResolutionException, PluginVersionResolutionException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
package org.apache.maven.project;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
|
||||||
|
import org.codehaus.plexus.classworlds.realm.ClassRealm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caches project class realms. <strong>Warning:</strong> This is an internal utility interface that is only public for
|
||||||
|
* technical reasons, it is not part of the public API. In particular, this interface can be changed or deleted without
|
||||||
|
* prior notice.
|
||||||
|
*
|
||||||
|
* @author Igor Fedorenko
|
||||||
|
* @author Benjamin Bentmann
|
||||||
|
*/
|
||||||
|
public interface ProjectRealmCache
|
||||||
|
{
|
||||||
|
|
||||||
|
public static class CacheRecord
|
||||||
|
{
|
||||||
|
|
||||||
|
public final ClassRealm realm;
|
||||||
|
|
||||||
|
public final ArtifactFilter extensionArtifactFilter;
|
||||||
|
|
||||||
|
public CacheRecord( ClassRealm realm, ArtifactFilter extensionArtifactFilter )
|
||||||
|
{
|
||||||
|
this.realm = realm;
|
||||||
|
this.extensionArtifactFilter = extensionArtifactFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CacheRecord get( List<? extends ClassRealm> extensionRealms );
|
||||||
|
|
||||||
|
void put( List<? extends ClassRealm> extensionRealms, ClassRealm projectRealm,
|
||||||
|
ArtifactFilter extensionArtifactFilter );
|
||||||
|
|
||||||
|
void flush();
|
||||||
|
|
||||||
|
}
|
|
@ -28,7 +28,6 @@ import org.apache.maven.artifact.repository.RepositoryRequest;
|
||||||
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
|
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
|
||||||
import org.apache.maven.model.Model;
|
import org.apache.maven.model.Model;
|
||||||
import org.apache.maven.model.Repository;
|
import org.apache.maven.model.Repository;
|
||||||
import org.codehaus.plexus.classworlds.realm.ClassRealm;
|
|
||||||
import org.codehaus.plexus.component.annotations.Component;
|
import org.codehaus.plexus.component.annotations.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,10 +55,10 @@ public class EmptyProjectBuildingHelper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassRealm createProjectRealm( Model model, RepositoryRequest repositoryRequest )
|
public ProjectRealmCache.CacheRecord createProjectRealm( Model model, RepositoryRequest repositoryRequest )
|
||||||
throws ArtifactResolutionException
|
throws ArtifactResolutionException
|
||||||
{
|
{
|
||||||
return null;
|
return new ProjectRealmCache.CacheRecord( null, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
package org.apache.maven.project;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests {@link ExtensionDescriptorBuilder}.
|
||||||
|
*
|
||||||
|
* @author Benjamin Bentmann
|
||||||
|
*/
|
||||||
|
public class ExtensionDescriptorBuilderTest
|
||||||
|
extends TestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
private ExtensionDescriptorBuilder builder;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
super.setUp();
|
||||||
|
|
||||||
|
builder = new ExtensionDescriptorBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void tearDown()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
builder = null;
|
||||||
|
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputStream toStream( String xml )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return new ByteArrayInputStream( xml.getBytes( "UTF-8" ) );
|
||||||
|
}
|
||||||
|
catch ( UnsupportedEncodingException e )
|
||||||
|
{
|
||||||
|
throw new IllegalStateException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testEmptyDescriptor()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
String xml = "<extension></extension>";
|
||||||
|
|
||||||
|
ExtensionDescriptor ed = builder.build( toStream( xml ) );
|
||||||
|
|
||||||
|
assertNotNull( ed );
|
||||||
|
assertNotNull( ed.getExportedPackages() );
|
||||||
|
assertTrue( ed.getExportedPackages().isEmpty() );
|
||||||
|
assertNotNull( ed.getExportedArtifacts() );
|
||||||
|
assertTrue( ed.getExportedArtifacts().isEmpty() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCompleteDescriptor()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
String xml =
|
||||||
|
"<?xml version='1.0' encoding='UTF-8'?>" + "<extension>" + "<exportedPackages>"
|
||||||
|
+ "<exportedPackage>a</exportedPackage>" + "<exportedPackage>b</exportedPackage>"
|
||||||
|
+ "<exportedPackage>c</exportedPackage>" + "</exportedPackages>" + "<exportedArtifacts>"
|
||||||
|
+ "<exportedArtifact>x</exportedArtifact>" + "<exportedArtifact>y</exportedArtifact>"
|
||||||
|
+ "<exportedArtifact> z </exportedArtifact>" + "</exportedArtifacts>" + "</extension>";
|
||||||
|
|
||||||
|
ExtensionDescriptor ed = builder.build( toStream( xml ) );
|
||||||
|
|
||||||
|
assertNotNull( ed );
|
||||||
|
assertEquals( Arrays.asList( "a", "b", "c" ), ed.getExportedPackages() );
|
||||||
|
assertEquals( Arrays.asList( "x", "y", "z" ), ed.getExportedArtifacts() );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
pom.xml
12
pom.xml
|
@ -38,11 +38,11 @@
|
||||||
<inceptionYear>2001</inceptionYear>
|
<inceptionYear>2001</inceptionYear>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<classWorldsVersion>2.1.0</classWorldsVersion>
|
<classWorldsVersion>2.2.0-SNAPSHOT</classWorldsVersion>
|
||||||
<commonsCliVersion>1.2</commonsCliVersion>
|
<commonsCliVersion>1.2</commonsCliVersion>
|
||||||
<easyMockVersion>1.2_Java1.3</easyMockVersion>
|
<easyMockVersion>1.2_Java1.3</easyMockVersion>
|
||||||
<junitVersion>3.8.2</junitVersion>
|
<junitVersion>3.8.2</junitVersion>
|
||||||
<plexusVersion>1.2.1</plexusVersion>
|
<plexusVersion>1.3.0-SNAPSHOT</plexusVersion>
|
||||||
<plexusInterpolationVersion>1.11</plexusInterpolationVersion>
|
<plexusInterpolationVersion>1.11</plexusInterpolationVersion>
|
||||||
<plexusPluginManagerVersion>1.0-alpha-1</plexusPluginManagerVersion>
|
<plexusPluginManagerVersion>1.0-alpha-1</plexusPluginManagerVersion>
|
||||||
<plexusUtilsVersion>2.0.0</plexusUtilsVersion>
|
<plexusUtilsVersion>2.0.0</plexusUtilsVersion>
|
||||||
|
@ -158,6 +158,14 @@
|
||||||
</site>
|
</site>
|
||||||
</distributionManagement>
|
</distributionManagement>
|
||||||
|
|
||||||
|
<!-- FIXME: Remove once snapshots have been released -->
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>sonatype.public</id>
|
||||||
|
<url>http://repository.sonatype.org/content/groups/public/</url>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
<!--bootstrap-start-comment-->
|
<!--bootstrap-start-comment-->
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<!--bootstrap-end-comment-->
|
<!--bootstrap-end-comment-->
|
||||||
|
|
Loading…
Reference in New Issue