AbstractDependencyFilter xref

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
    10   *   http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing,
    13   * software distributed under the License is distributed on an
    14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   * KIND, either express or implied.  See the License for the
    16   * specific language governing permissions and limitations
    17   * under the License.
    18   */
    19  package org.apache.felix.bundleplugin;
    20
    21
    22  import java.util.Collection;
    23  import java.util.HashSet;
    24  import java.util.Iterator;
    25  import java.util.Map;
    26
    27  import org.apache.maven.artifact.Artifact;
    28  import org.apache.maven.plugin.MojoExecutionException;
    29
    30  import aQute.lib.osgi.Instruction;
    31
    32
    33  /**
    34   * Apply clause-based filter over given dependencies
    35   *
    36   * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
    37   */
    38  public abstract class AbstractDependencyFilter
    39  {
    40      /**
    41       * Dependency artifacts.
    42       */
    43      private final Collection m_dependencyArtifacts;
    44
    45
    46      public AbstractDependencyFilter( Collection dependencyArtifacts )
    47      {
    48          m_dependencyArtifacts = dependencyArtifacts;
    49      }
    50
    51      private static abstract class DependencyFilter
    52      {
    53          private final Instruction m_instruction;
    54          private final String m_defaultValue;
    55
    56
    57          public DependencyFilter( String expression )
    58          {
    59              this( expression, "" );
    60          }
    61
    62
    63          public DependencyFilter( String expression, String defaultValue )
    64          {
    65              m_instruction = Instruction.getPattern( expression );
    66              m_defaultValue = defaultValue;
    67          }
    68
    69
    70          public void filter( Collection dependencies )
    71          {
    72              for ( Iterator i = dependencies.iterator(); i.hasNext(); )
    73              {
    74                  if ( false == matches( ( Artifact ) i.next() ) )
    75                  {
    76                      i.remove();
    77                  }
    78              }
    79          }
    80
    81
    82          abstract boolean matches( Artifact dependency );
    83
    84
    85          boolean matches( String text )
    86          {
    87              boolean result;
    88
    89              if ( null == text )
    90              {
    91                  result = m_instruction.matches( m_defaultValue );
    92              }
    93              else
    94              {
    95                  result = m_instruction.matches( text );
    96              }
    97
    98              return m_instruction.isNegated() ? !result : result;
    99          }
    100     }
    101
    102
    103     protected final void processInstructions( Map instructions ) throws MojoExecutionException
    104     {
    105         DependencyFilter filter;
    106         for ( Iterator clauseIterator = instructions.entrySet().iterator(); clauseIterator.hasNext(); )
    107         {
    108             String inline = "false";
    109
    110             // must use a fresh *modifiable* collection for each unique clause
    111             Collection filteredDependencies = new HashSet( m_dependencyArtifacts );
    112
    113             // CLAUSE: REGEXP --> { ATTRIBUTE MAP }
    114             Map.Entry clause = ( Map.Entry ) clauseIterator.next();
    115             StringBuilder tag = new StringBuilder();
    116             tag.append( clause.getKey() );
    117
    118             if ( !( ( String ) clause.getKey() ).matches( "\\*~*" ) )
    119             {
    120                 filter = new DependencyFilter( ( String ) clause.getKey() )
    121                 {
    122                     boolean matches( Artifact dependency )
    123                     {
    124                         return super.matches( dependency.getArtifactId() );
    125                     }
    126                 };
    127                 // FILTER ON MAIN CLAUSE
    128                 filter.filter( filteredDependencies );
    129             }
    130
    131             for ( Iterator attrIterator = ( ( Map ) clause.getValue() ).entrySet().iterator(); attrIterator.hasNext(); )
    132             {
    133                 // ATTRIBUTE: KEY --> REGEXP
    134                 Map.Entry attr = ( Map.Entry ) attrIterator.next();
    135                 tag.append( ';' ).append( attr );
    136
    137                 if ( "groupId".equals( attr.getKey() ) )
    138                 {
    139                     filter = new DependencyFilter( ( String ) attr.getValue() )
    140                     {
    141                         boolean matches( Artifact dependency )
    142                         {
    143                             return super.matches( dependency.getGroupId() );
    144                         }
    145                     };
    146                 }
    147                 else if ( "artifactId".equals( attr.getKey() ) )
    148                 {
    149                     filter = new DependencyFilter( ( String ) attr.getValue() )
    150                     {
    151                         boolean matches( Artifact dependency )
    152                         {
    153                             return super.matches( dependency.getArtifactId() );
    154                         }
    155                     };
    156                 }
    157                 else if ( "version".equals( attr.getKey() ) )
    158                 {
    159                     filter = new DependencyFilter( ( String ) attr.getValue() )
    160                     {
    161                         boolean matches( Artifact dependency )
    162                         {
    163                             try
    164                             {
    165                                 // use the symbolic version if available (ie. 1.0.0-SNAPSHOT)
    166                                 return super.matches( dependency.getSelectedVersion().toString() );
    167                             }
    168                             catch ( Exception e )
    169                             {
    170                                 return super.matches( dependency.getVersion() );
    171                             }
    172                         }
    173                     };
    174                 }
    175                 else if ( "scope".equals( attr.getKey() ) )
    176                 {
    177                     filter = new DependencyFilter( ( String ) attr.getValue(), "compile" )
    178                     {
    179                         boolean matches( Artifact dependency )
    180                         {
    181                             return super.matches( dependency.getScope() );
    182                         }
    183                     };
    184                 }
    185                 else if ( "type".equals( attr.getKey() ) )
    186                 {
    187                     filter = new DependencyFilter( ( String ) attr.getValue(), "jar" )
    188                     {
    189                         boolean matches( Artifact dependency )
    190                         {
    191                             return super.matches( dependency.getType() );
    192                         }
    193                     };
    194                 }
    195                 else if ( "classifier".equals( attr.getKey() ) )
    196                 {
    197                     filter = new DependencyFilter( ( String ) attr.getValue() )
    198                     {
    199                         boolean matches( Artifact dependency )
    200                         {
    201                             return super.matches( dependency.getClassifier() );
    202                         }
    203                     };
    204                 }
    205                 else if ( "optional".equals( attr.getKey() ) )
    206                 {
    207                     filter = new DependencyFilter( ( String ) attr.getValue(), "false" )
    208                     {
    209                         boolean matches( Artifact dependency )
    210                         {
    211                             return super.matches( "" + dependency.isOptional() );
    212                         }
    213                     };
    214                 }
    215                 else if ( "inline".equals( attr.getKey() ) )
    216                 {
    217                     inline = ( String ) attr.getValue();
    218                     continue;
    219                 }
    220                 else
    221                 {
    222                     throw new MojoExecutionException( "Unexpected attribute " + attr.getKey() );
    223                 }
    224
    225                 // FILTER ON EACH ATTRIBUTE
    226                 filter.filter( filteredDependencies );
    227             }
    228
    229             processDependencies( tag.toString(), inline, filteredDependencies );
    230         }
    231     }
    232
    233
    234     protected abstract void processDependencies( String clause, String inline, Collection dependencies );
    235 }