20
20
21
21
import javax .inject .Inject ;
22
22
23
- import java .security . MessageDigest ;
24
- import java .security . NoSuchAlgorithmException ;
23
+ import java .io . IOException ;
24
+ import java .io . UncheckedIOException ;
25
25
import java .util .ArrayList ;
26
26
import java .util .HashMap ;
27
27
import java .util .List ;
36
36
import org .apache .maven .plugins .annotations .Mojo ;
37
37
import org .apache .maven .plugins .annotations .Parameter ;
38
38
import org .apache .maven .project .ProjectBuilder ;
39
+ import org .apache .maven .report .projectinfo .avatars .AvatarsProvider ;
39
40
import org .apache .maven .reporting .MavenReportException ;
40
41
import org .apache .maven .repository .RepositorySystem ;
41
42
import org .codehaus .plexus .i18n .I18N ;
@@ -52,19 +53,51 @@ public class TeamReport extends AbstractProjectInfoReport {
52
53
/**
53
54
* Shows avatar images for team members that have a) properties/picUrl set b) An avatar at gravatar.com for their
54
55
* email address
55
- * <p/>
56
- * Future versions of this plugin may implement different strategies for resolving avatar images, possibly
57
- * using different providers.
58
- *<p>
59
- *<strong>Note</strong>: This property will be renamed to {@code tteam.showAvatarImages} in 3.0.
56
+ *
60
57
* @since 2.6
61
58
*/
62
59
@ Parameter (property = "teamlist.showAvatarImages" , defaultValue = "true" )
63
60
private boolean showAvatarImages ;
64
61
62
+ /**
63
+ * Indicate if URL should be used for avatar images.
64
+ * <p>
65
+ * If set to <code>false</code> images will be downloaded and attached to report during build.
66
+ * Local path will be used for images.
67
+ *
68
+ * @since 3.9.0
69
+ */
70
+ @ Parameter (property = "teamlist.externalAvatarImages" , defaultValue = "true" )
71
+ private boolean externalAvatarImages ;
72
+
73
+ /**
74
+ * Base URL for avatar provider.
75
+ *
76
+ * @since 3.9.0
77
+ */
78
+ @ Parameter (property = "teamlist.avatarBaseUrl" , defaultValue = "https://www.gravatar.com/avatar/" )
79
+ private String avatarBaseUrl ;
80
+
81
+ /**
82
+ * Provider name for avatar images.
83
+ * <p>
84
+ * Report has one implementation for gravatar.com. Users can provide other by implementing {@link AvatarsProvider}.
85
+ *
86
+ * @since 3.9.0
87
+ */
88
+ @ Parameter (property = "teamlist.avatarProviderName" , defaultValue = "gravatar" )
89
+ private String avatarProviderName ;
90
+
91
+ private final Map <String , AvatarsProvider > avatarsProviders ;
92
+
65
93
@ Inject
66
- public TeamReport (RepositorySystem repositorySystem , I18N i18n , ProjectBuilder projectBuilder ) {
94
+ public TeamReport (
95
+ RepositorySystem repositorySystem ,
96
+ I18N i18n ,
97
+ ProjectBuilder projectBuilder ,
98
+ Map <String , AvatarsProvider > avatarsProviders ) {
67
99
super (repositorySystem , i18n , projectBuilder );
100
+ this .avatarsProviders = avatarsProviders ;
68
101
}
69
102
70
103
// ----------------------------------------------------------------------
@@ -83,9 +116,22 @@ public boolean canGenerateReport() throws MavenReportException {
83
116
}
84
117
85
118
@ Override
86
- public void executeReport (Locale locale ) {
87
- ProjectTeamRenderer r =
88
- new ProjectTeamRenderer (getSink (), project .getModel (), getI18N (locale ), locale , showAvatarImages );
119
+ public void executeReport (Locale locale ) throws MavenReportException {
120
+ AvatarsProvider avatarsProvider = avatarsProviders .get (avatarProviderName );
121
+ if (avatarsProvider == null ) {
122
+ throw new MavenReportException ("No AvatarsProvider found for name " + avatarProviderName );
123
+ }
124
+ avatarsProvider .setBaseUrl (avatarBaseUrl );
125
+ avatarsProvider .setOutputDirectory (getReportOutputDirectory ());
126
+
127
+ ProjectTeamRenderer r = new ProjectTeamRenderer (
128
+ getSink (),
129
+ project .getModel (),
130
+ getI18N (locale ),
131
+ locale ,
132
+ showAvatarImages ,
133
+ externalAvatarImages ,
134
+ avatarsProvider );
89
135
r .render ();
90
136
}
91
137
@@ -134,20 +180,24 @@ private static class ProjectTeamRenderer extends AbstractProjectInfoRenderer {
134
180
135
181
private final boolean showAvatarImages ;
136
182
137
- private final String protocol ;
183
+ private final boolean externalAvatarImages ;
138
184
139
- ProjectTeamRenderer (Sink sink , Model model , I18N i18n , Locale locale , boolean showAvatarImages ) {
185
+ private final AvatarsProvider avatarsProvider ;
186
+
187
+ ProjectTeamRenderer (
188
+ Sink sink ,
189
+ Model model ,
190
+ I18N i18n ,
191
+ Locale locale ,
192
+ boolean showAvatarImages ,
193
+ boolean externalAvatarImages ,
194
+ AvatarsProvider avatarsProvider ) {
140
195
super (sink , i18n , locale );
141
196
142
197
this .model = model ;
143
198
this .showAvatarImages = showAvatarImages ;
144
-
145
- // prepare protocol for gravatar
146
- if (model .getUrl () != null && model .getUrl ().startsWith ("https://" )) {
147
- this .protocol = "https" ;
148
- } else {
149
- this .protocol = "http" ;
150
- }
199
+ this .externalAvatarImages = externalAvatarImages ;
200
+ this .avatarsProvider = avatarsProvider ;
151
201
}
152
202
153
203
@ Override
@@ -226,10 +276,7 @@ private void renderTeamMember(Contributor member, Map<String, Boolean> headersMa
226
276
Properties properties = member .getProperties ();
227
277
String picUrl = properties .getProperty ("picUrl" );
228
278
if (picUrl == null || picUrl .isEmpty ()) {
229
- picUrl = getGravatarUrl (member .getEmail ());
230
- }
231
- if (picUrl == null || picUrl .isEmpty ()) {
232
- picUrl = getSpacerGravatarUrl ();
279
+ picUrl = getExternalAvatarUrl (member .getEmail ());
233
280
}
234
281
sink .tableCell ();
235
282
sink .figure ();
@@ -288,32 +335,13 @@ private void renderTeamMember(Contributor member, Map<String, Boolean> headersMa
288
335
sink .tableRow_ ();
289
336
}
290
337
291
- private static final String AVATAR_SIZE = "s=60" ;
292
-
293
- private String getSpacerGravatarUrl () {
294
- return protocol + "://www.gravatar.com/avatar/00000000000000000000000000000000?d=blank&f=y&" + AVATAR_SIZE ;
295
- }
296
-
297
- private String getGravatarUrl (String email ) {
298
- if (email == null ) {
299
- return null ;
300
- }
301
- email = StringUtils .trim (email );
302
- email = email .toLowerCase ();
303
- MessageDigest md ;
338
+ private String getExternalAvatarUrl (String email ) {
304
339
try {
305
- md = MessageDigest .getInstance ("MD5" );
306
- md .update (email .getBytes ());
307
- byte [] byteData = md .digest ();
308
- StringBuilder sb = new StringBuilder ();
309
- final int lowerEightBitsOnly = 0xff ;
310
- for (byte aByteData : byteData ) {
311
- sb .append (Integer .toString ((aByteData & lowerEightBitsOnly ) + 0x100 , 16 )
312
- .substring (1 ));
313
- }
314
- return protocol + "://www.gravatar.com/avatar/" + sb .toString () + "?d=mm&" + AVATAR_SIZE ;
315
- } catch (NoSuchAlgorithmException e ) {
316
- return null ;
340
+ return externalAvatarImages
341
+ ? avatarsProvider .getExternalAvatarUrl (email )
342
+ : avatarsProvider .getLocalAvatarPath (email );
343
+ } catch (IOException e ) {
344
+ throw new UncheckedIOException (e );
317
345
}
318
346
}
319
347
0 commit comments