FELIX-3185: negative Embed-Dependency clauses (such as !*;groupId=example) should restrict available dependencies
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1189530 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/AbstractDependencyFilter.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/AbstractDependencyFilter.java
index 2974ffa..9b5d0cf 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/AbstractDependencyFilter.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/AbstractDependencyFilter.java
@@ -20,8 +20,8 @@
import java.util.Collection;
-import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.Map;
import java.util.regex.Pattern;
@@ -39,7 +39,7 @@
*/
public abstract class AbstractDependencyFilter
{
- private static final Pattern MISSING_KEY_PATTERN = Pattern.compile( "^(!)?([a-zA-Z]+=)" );
+ private static final Pattern MISSING_KEY_PATTERN = Pattern.compile( "(^|,)\\p{Blank}*(!)?\\p{Blank}*([a-zA-Z]+=)" );
/**
* Dependency artifacts.
@@ -106,20 +106,27 @@
protected final void processInstructions( String header ) throws MojoExecutionException
{
- Map instructions = OSGiHeader.parseHeader( MISSING_KEY_PATTERN.matcher( header ).replaceFirst( "$1*;$2" ) );
+ Map instructions = OSGiHeader.parseHeader( MISSING_KEY_PATTERN.matcher( header ).replaceAll( "$1$2*;$3" ) );
+
+ Collection availableDependencies = new LinkedHashSet( m_dependencyArtifacts );
DependencyFilter filter;
for ( Iterator clauseIterator = instructions.entrySet().iterator(); clauseIterator.hasNext(); )
{
String inline = "false";
- // must use a fresh *modifiable* collection for each unique clause
- Collection filteredDependencies = new HashSet( m_dependencyArtifacts );
+ // always start with a fresh *modifiable* collection for each unique clause
+ Collection filteredDependencies = new LinkedHashSet( availableDependencies );
// CLAUSE: REGEXP --> { ATTRIBUTE MAP }
Map.Entry clause = ( Map.Entry ) clauseIterator.next();
-
String primaryKey = ( ( String ) clause.getKey() ).replaceFirst( "~+$", "" );
+ boolean isNegative = primaryKey.startsWith( "!" );
+ if ( isNegative )
+ {
+ primaryKey = primaryKey.substring( 1 );
+ }
+
if ( !"*".equals( primaryKey ) )
{
filter = new DependencyFilter( primaryKey )
@@ -229,7 +236,21 @@
filter.filter( filteredDependencies );
}
- processDependencies( filteredDependencies, inline );
+ if ( isNegative )
+ {
+ // negative clauses reduce the set of available artifacts
+ availableDependencies.removeAll( filteredDependencies );
+ if ( !clauseIterator.hasNext() )
+ {
+ // assume there's an implicit * missing at the end
+ processDependencies( availableDependencies, inline );
+ }
+ }
+ else
+ {
+ // positive clause; doesn't alter the available artifacts
+ processDependencies( filteredDependencies, inline );
+ }
}
}
diff --git a/bundleplugin/src/test/java/org/apache/felix/bundleplugin/BundlePluginTest.java b/bundleplugin/src/test/java/org/apache/felix/bundleplugin/BundlePluginTest.java
index 9ecf37c..e224c96 100644
--- a/bundleplugin/src/test/java/org/apache/felix/bundleplugin/BundlePluginTest.java
+++ b/bundleplugin/src/test/java/org/apache/felix/bundleplugin/BundlePluginTest.java
@@ -245,6 +245,35 @@
}
+ public void testEmbedDependencyNegativeClauses() throws Exception
+ {
+ ArtifactStubFactory artifactFactory = new ArtifactStubFactory( plugin.getOutputDirectory(), true );
+
+ Set artifacts = new LinkedHashSet();
+
+ artifacts.addAll( artifactFactory.getClassifiedArtifacts() );
+ artifacts.addAll( artifactFactory.getScopedArtifacts() );
+ artifacts.addAll( artifactFactory.getTypedArtifacts() );
+
+ MavenProject project = getMavenProjectStub();
+ project.setDependencyArtifacts( artifacts );
+
+ Map instructions = new HashMap();
+ instructions.put( DependencyEmbedder.EMBED_DEPENDENCY, "!type=jar, !artifactId=c" );
+ Properties props = new Properties();
+
+ Builder builder = plugin.buildOSGiBundle( project, instructions, props, plugin.getClasspath( project ) );
+ Manifest manifest = builder.getJar().getManifest();
+
+ String bcp = manifest.getMainAttributes().getValue( Constants.BUNDLE_CLASSPATH );
+ assertEquals( ".," + "e-1.0.rar," + "a-1.0.war," + "d-1.0.zip", bcp );
+
+ String eas = manifest.getMainAttributes().getValue( "Embedded-Artifacts" );
+ assertEquals( "e-1.0.rar;g=\"g\";a=\"e\";v=\"1.0\"," + "a-1.0.war;g=\"g\";a=\"a\";v=\"1.0\","
+ + "d-1.0.zip;g=\"g\";a=\"d\";v=\"1.0\"", eas );
+ }
+
+
public void testEmbedDependencyDuplicateKeys() throws Exception
{
ArtifactStubFactory artifactFactory = new ArtifactStubFactory( plugin.getOutputDirectory(), true );
@@ -274,11 +303,6 @@
}
- public void testEmbedDependencyNegativeClauses() throws Exception
- {
- }
-
-
public void testEmbedDependencyMissingPositiveKey() throws Exception
{
ArtifactStubFactory artifactFactory = new ArtifactStubFactory( plugin.getOutputDirectory(), true );
@@ -300,15 +324,51 @@
Manifest manifest = builder.getJar().getManifest();
String bcp = manifest.getMainAttributes().getValue( Constants.BUNDLE_CLASSPATH );
- assertEquals( ".," + "a-1.0.war," + "a-1.0-one.jar," + "b-1.0.jar," + "b-1.0-two.jar", bcp );
+ assertEquals( ".," + "a-1.0-one.jar," + "b-1.0-two.jar," + "a-1.0.war," + "b-1.0.jar", bcp );
String eas = manifest.getMainAttributes().getValue( "Embedded-Artifacts" );
- assertEquals( "a-1.0.war;g=\"g\";a=\"a\";v=\"1.0\"," + "a-1.0-one.jar;g=\"g\";a=\"a\";v=\"1.0\";c=\"one\","
- + "b-1.0.jar;g=\"g\";a=\"b\";v=\"1.0\"," + "b-1.0-two.jar;g=\"g\";a=\"b\";v=\"1.0\";c=\"two\"", eas );
+ assertEquals( "a-1.0-one.jar;g=\"g\";a=\"a\";v=\"1.0\";c=\"one\","
+ + "b-1.0-two.jar;g=\"g\";a=\"b\";v=\"1.0\";c=\"two\"," + "a-1.0.war;g=\"g\";a=\"a\";v=\"1.0\","
+ + "b-1.0.jar;g=\"g\";a=\"b\";v=\"1.0\"", eas );
}
public void testEmbedDependencyMissingNegativeKey() throws Exception
{
+ ArtifactStubFactory artifactFactory = new ArtifactStubFactory( plugin.getOutputDirectory(), true );
+
+ Set artifacts = new LinkedHashSet();
+
+ artifacts.addAll( artifactFactory.getClassifiedArtifacts() );
+ artifacts.addAll( artifactFactory.getScopedArtifacts() );
+ artifacts.addAll( artifactFactory.getTypedArtifacts() );
+
+ MavenProject project = getMavenProjectStub();
+ project.setDependencyArtifacts( artifacts );
+ Properties props = new Properties();
+
+ Map instructions1 = new HashMap();
+ instructions1.put( DependencyEmbedder.EMBED_DEPENDENCY, "!scope=compile" );
+ Builder builder1 = plugin.buildOSGiBundle( project, instructions1, props, plugin.getClasspath( project ) );
+ Manifest manifest1 = builder1.getJar().getManifest();
+
+ Map instructions2 = new HashMap();
+ instructions2.put( DependencyEmbedder.EMBED_DEPENDENCY, "scope=!compile" );
+ Builder builder2 = plugin.buildOSGiBundle( project, instructions2, props, plugin.getClasspath( project ) );
+ Manifest manifest2 = builder2.getJar().getManifest();
+
+ String bcp1 = manifest1.getMainAttributes().getValue( Constants.BUNDLE_CLASSPATH );
+ assertEquals( ".," + "test-1.0.jar," + "provided-1.0.jar," + "runtime-1.0.jar," + "system-1.0.jar", bcp1 );
+
+ String eas1 = manifest1.getMainAttributes().getValue( "Embedded-Artifacts" );
+ assertEquals( "test-1.0.jar;g=\"g\";a=\"test\";v=\"1.0\","
+ + "provided-1.0.jar;g=\"g\";a=\"provided\";v=\"1.0\"," + "runtime-1.0.jar;g=\"g\";a=\"runtime\";v=\"1.0\","
+ + "system-1.0.jar;g=\"g\";a=\"system\";v=\"1.0\"", eas1 );
+
+ String bcp2 = manifest2.getMainAttributes().getValue( Constants.BUNDLE_CLASSPATH );
+ assertEquals( bcp1, bcp2 );
+
+ String eas2 = manifest2.getMainAttributes().getValue( "Embedded-Artifacts" );
+ assertEquals( eas1, eas2 );
}
}