1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.watchlist.internal

File DefaultUserAvatarAttachmentExtractor.java

 

Coverage histogram

../../../../img/srcFileCovDistChart9.png
38% of files have more coverage

Code metrics

12
48
4
1
197
115
12
0.25
12
4
3

Classes

Class Line # Actions
DefaultUserAvatarAttachmentExtractor 57 48 0% 12 12
0.812581.2%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.watchlist.internal;
21   
22    import java.awt.Image;
23    import java.awt.image.RenderedImage;
24    import java.io.IOException;
25    import java.io.InputStream;
26    import java.io.OutputStream;
27   
28    import javax.inject.Inject;
29    import javax.inject.Provider;
30    import javax.inject.Singleton;
31   
32    import org.apache.commons.io.IOUtils;
33    import org.slf4j.Logger;
34    import org.xwiki.component.annotation.Component;
35    import org.xwiki.environment.Environment;
36    import org.xwiki.model.reference.DocumentReference;
37    import org.xwiki.model.reference.EntityReferenceSerializer;
38   
39    import com.xpn.xwiki.XWiki;
40    import com.xpn.xwiki.XWikiContext;
41    import com.xpn.xwiki.api.Attachment;
42    import com.xpn.xwiki.api.Document;
43    import com.xpn.xwiki.doc.XWikiAttachment;
44    import com.xpn.xwiki.doc.XWikiAttachmentContent;
45    import com.xpn.xwiki.doc.XWikiDocument;
46    import com.xpn.xwiki.plugin.image.ImageProcessor;
47    import com.xpn.xwiki.user.api.XWikiRightService;
48   
49    /**
50    * Default implementation for {@link UserAvatarAttachmentExtractor}.
51    *
52    * @version $Id: c88093bd06d93d5e838c747d51777ef5a1225ca4 $
53    * @since 7.1RC1
54    */
55    @Component
56    @Singleton
 
57    public class DefaultUserAvatarAttachmentExtractor implements UserAvatarAttachmentExtractor
58    {
59    /**
60    * Logging framework.
61    */
62    @Inject
63    private Logger logger;
64   
65    /**
66    * Used to get file resources.
67    */
68    @Inject
69    private Environment environment;
70   
71    /**
72    * Used to resize user avatars.
73    */
74    @Inject
75    private ImageProcessor imageProcessor;
76   
77    @Inject
78    private Provider<XWikiContext> xwikiContextProvider;
79   
80    @Inject
81    private EntityReferenceSerializer<String> serializer;
82   
 
83  1 toggle @Override
84    public Attachment getUserAvatar(DocumentReference userReference)
85    {
86  1 String fileName = getFileName(userReference);
87  1 return getUserAvatar(userReference, 50, 50, fileName);
88    }
89   
 
90  1 toggle private String getFileName(DocumentReference userReference)
91    {
92  1 String fileName;
93  1 if (userReference == null) {
94  0 fileName = XWikiRightService.GUEST_USER_FULLNAME;
95    } else {
96  1 fileName = serializer.serialize(userReference);
97    }
98  1 fileName = String.format("%s.png", fileName);
99  1 return fileName;
100    }
101   
 
102  1 toggle @Override
103    public Attachment getUserAvatar(DocumentReference userReference, int width, int height, String fileName)
104    {
105    // FIXME: Unfortunately, the ImagePlugin is too much request-oriented and not generic enough to be reused
106    // without rewriting. In the end, that might be the right way to go and rewriting it might be inevitable.
107   
108  1 Attachment result = null;
109   
110  1 InputStream sourceImageInputStream = null;
111  1 try {
112  1 XWikiContext context = xwikiContextProvider.get();
113  1 XWiki wiki = context.getWiki();
114   
115  1 XWikiAttachment realAvatarAttachment;
116  1 XWikiAttachment fakeAvatarAttachment = null;
117   
118    // Use a second variable to be able to reassign it on the else branch below.
119  1 DocumentReference actualUserReference = userReference;
120  1 if (actualUserReference != null) {
121    // Registered user.
122   
123  1 XWikiDocument userProfileDocument = wiki.getDocument(userReference, context);
124   
125  1 DocumentReference usersClassReference = wiki.getUserClass(context).getDocumentReference();
126  1 String avatarFileName = userProfileDocument.getStringValue(usersClassReference, "avatar");
127   
128  1 realAvatarAttachment = userProfileDocument.getAttachment(avatarFileName);
129   
130  1 if (realAvatarAttachment != null && realAvatarAttachment.isImage(context)) {
131    // Valid avatar, use the real attachment (and image), but make sure to use a clone as to not impact
132    // the
133    // real document.
134  0 fakeAvatarAttachment = (XWikiAttachment) realAvatarAttachment.clone();
135  0 sourceImageInputStream = realAvatarAttachment.getContentInputStream(context);
136   
137  0 result = new Attachment(new Document(userProfileDocument, context), fakeAvatarAttachment, context);
138    } else {
139    // No or invalid avatar, treat the user reference as it did not exist (guest user) so it can be
140    // handled below for both cases.
141  1 actualUserReference = null;
142    }
143    }
144   
145  1 if (actualUserReference == null) {
146    // Guest user.
147   
148    // No avatar. Return a fake attachment with the "noavatar.png" standard image.
149  1 fakeAvatarAttachment = new XWikiAttachment();
150  1 sourceImageInputStream = environment.getResourceAsStream("/resources/icons/xwiki/noavatar.png");
151   
152  1 result = new Attachment(null, fakeAvatarAttachment, context);
153    }
154   
155    // In both cases, set an empty attachment content that will be filled with the resized image. This way we
156    // also avoid a request to the DB for the attachment content, since it will already be available.
157  1 fakeAvatarAttachment.setAttachment_content(new XWikiAttachmentContent(fakeAvatarAttachment));
158   
159    // Resize the image and write it to the fake attachment.
160  1 int resizedWidth = 50;
161  1 int resizedHeight = 50;
162  1 resizeImageToAttachment(sourceImageInputStream, resizedWidth, resizedHeight, fakeAvatarAttachment);
163   
164    // Set a fixed name for the user avatar file so that it is easy to work with in a template, for example.
165  1 fakeAvatarAttachment.setFilename(fileName);
166    } catch (Exception e) {
167  0 logger.error("Failed to retrieve the avatar for the user {}", userReference, e);
168  0 return null;
169    } finally {
170    // Close the source image input stream since we are done reading from it.
171  1 if (sourceImageInputStream != null) {
172  1 IOUtils.closeQuietly(sourceImageInputStream);
173    }
174    }
175   
176  1 return result;
177    }
178   
 
179  1 toggle private void resizeImageToAttachment(InputStream imageFileInputStream, int width, int height,
180    XWikiAttachment outputAttachment) throws IOException
181    {
182  1 OutputStream attachmentOutputStream = null;
183  1 try {
184  1 Image originalImage = imageProcessor.readImage(imageFileInputStream);
185   
186  1 RenderedImage resizedImage = imageProcessor.scaleImage(originalImage, width, height);
187   
188  1 attachmentOutputStream = outputAttachment.getAttachment_content().getContentOutputStream();
189  1 imageProcessor.writeImage(resizedImage, "image/png", 1.0f, attachmentOutputStream);
190    } finally {
191    // Close the attachment output stream since we are done writing to it.
192  1 if (attachmentOutputStream != null) {
193  1 IOUtils.closeQuietly(attachmentOutputStream);
194    }
195    }
196    }
197    }