1 package org.codehaus.mojo.clirr;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
31
32
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
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
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 }