View Javadoc
1   package org.codehaus.mojo.clirr;
2   
3   /*
4    * Copyright 2006 The Codehaus
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * 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, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import net.sf.clirr.core.ApiDifference;
20  import net.sf.clirr.core.DiffListener;
21  import net.sf.clirr.core.Severity;
22  
23  import java.util.ArrayList;
24  import java.util.Collections;
25  import java.util.HashMap;
26  import java.util.List;
27  import java.util.Map;
28  
29  /**
30   * Delegates to a number of listeners, filtering by severity.
31   *
32   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
33   */
34  public class DelegatingListener
35      implements MojoDiffListener
36  {
37      private final List<DiffListener> listeners;
38  
39      private final Severity minSeverity;
40  
41      private final List<Difference> ignored;
42  
43      private Map<Difference, Map<Object, List<ApiDifference>>> deferredMatchesPerDifference = new HashMap<Difference, Map<Object, List<ApiDifference>>>();
44  
45      public DelegatingListener( List<DiffListener> listeners, Severity minSeverity, List<Difference> ignored )
46      {
47          this.listeners = listeners == null ? Collections.<DiffListener>emptyList() : listeners;
48  
49          this.minSeverity = minSeverity;
50  
51          this.ignored = ignored == null ? Collections.<Difference>emptyList() : ignored;
52      }
53  
54      public void start()
55      {
56          deferredMatchesPerDifference.clear();
57  
58          for ( DiffListener listener : listeners )
59          {
60              listener.start();
61          }
62      }
63  
64      public void reportDiff( ApiDifference apiDifference )
65      {
66          if ( ( minSeverity == null || minSeverity.compareTo( apiDifference.getMaximumSeverity() ) <= 0 ) )
67          {
68              Difference reasonToIgnoreDiff = getReasonToIgnoreDiff( apiDifference );
69              if ( reasonToIgnoreDiff == null )
70              {
71                  reportDiff_(apiDifference);
72              }
73              else
74              {
75                  reportIgnoredDiff(apiDifference, reasonToIgnoreDiff);
76              }
77          }
78      }
79  
80      private void reportDiff_(ApiDifference apiDifference)
81      {
82          for ( DiffListener listener : listeners )
83          {
84              listener.reportDiff( apiDifference );
85          }
86      }
87  
88      public void reportIgnoredDiff( ApiDifference ignoredDiff, Difference reason )
89      {
90          for ( DiffListener listener : listeners )
91          {
92              if ( listener instanceof MojoDiffListener )
93              {
94                  MojoDiffListener l = (MojoDiffListener) listener;
95                  l.reportIgnoredDiff( ignoredDiff, reason );
96              }
97          }
98      }
99  
100     public void stop()
101     {
102         //process the deferred matches now
103         for ( Map.Entry<Difference, Map<Object, List<ApiDifference>>> perDifferenceEntry : deferredMatchesPerDifference.entrySet() )
104         {
105             Difference diff = perDifferenceEntry.getKey();
106             Map<Object, List<ApiDifference>> diffsPerId = perDifferenceEntry.getValue();
107 
108             for ( List<ApiDifference> apiDiffs : diffsPerId.values() )
109             {
110                 if ( !diff.resolveDefferedMatches( apiDiffs ) )
111                 {
112                     for ( ApiDifference apiDiff : apiDiffs )
113                     {
114                         reportDiff_(apiDiff);
115                     }
116                 }
117                 else
118                 {
119                     for ( ApiDifference apiDiff : apiDiffs )
120                     {
121                         reportIgnoredDiff(apiDiff, diff);
122                     }
123                 }
124             }
125         }
126 
127         //and stop the underlying listeners
128         for ( DiffListener listener : listeners )
129         {
130             listener.stop();
131         }
132     }
133 
134     private Difference getReasonToIgnoreDiff( ApiDifference apiDiff )
135     {
136         if ( ignored == null )
137         {
138             return null;
139         }
140 
141         boolean someDeferred = false;
142         boolean matched = false;
143 
144         Difference reason = null;
145         for ( Difference difference : ignored )
146         {
147             if ( difference == null )
148             {
149                 continue;
150             }
151             Difference.Result res = difference.matches( apiDiff );
152 
153             switch ( res.getCode() )
154             {
155                 case Difference.Result.MATCHED:
156                     if ( reason == null )
157                     {
158                         reason = difference;
159                     }
160                     matched = true;
161                     break;
162                 case Difference.Result.NOT_MATCHED:
163                     break;
164                 case Difference.Result.DEFERRED_MATCH:
165                     Map<Object, List<ApiDifference>> diffsPerDifferentiator =
166                         deferredMatchesPerDifference.get( difference );
167                     if ( diffsPerDifferentiator == null )
168                     {
169                         diffsPerDifferentiator = new HashMap<Object, List<ApiDifference>>();
170                         deferredMatchesPerDifference.put( difference, diffsPerDifferentiator );
171                     }
172 
173                     List<ApiDifference> diffs = diffsPerDifferentiator.get( res.getDifferentiator() );
174                     if ( diffs == null )
175                     {
176                         diffs = new ArrayList<ApiDifference>();
177                         diffsPerDifferentiator.put( res.getDifferentiator(), diffs );
178                     }
179 
180                     diffs.add( apiDiff );
181                     if ( reason == null )
182                     {
183                         reason = difference;
184                     }
185                     someDeferred = true;
186                     break;
187             }
188         }
189 
190         if ( matched || someDeferred )
191         {
192           return reason;
193         }
194         return null;
195     }
196 }