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

File DefaultMessageStream.java

 

Coverage histogram

../../../../img/srcFileCovDistChart6.png
69% of files have more coverage

Code metrics

20
71
14
1
253
188
29
0.41
5.07
14
2.07

Classes

Class Line # Actions
DefaultMessageStream 54 71 0% 29 46
0.561904856.2%
 

Contributing tests

This file is covered by 28 tests. .

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.messagestream.internal;
21   
22    import java.util.ArrayList;
23    import java.util.List;
24   
25    import javax.inject.Inject;
26    import javax.inject.Singleton;
27   
28    import org.apache.commons.lang3.StringUtils;
29    import org.slf4j.Logger;
30    import org.slf4j.LoggerFactory;
31    import org.xwiki.bridge.DocumentAccessBridge;
32    import org.xwiki.component.annotation.Component;
33    import org.xwiki.eventstream.Event;
34    import org.xwiki.eventstream.Event.Importance;
35    import org.xwiki.eventstream.EventFactory;
36    import org.xwiki.eventstream.EventStream;
37    import org.xwiki.messagestream.MessageStream;
38    import org.xwiki.model.ModelContext;
39    import org.xwiki.model.reference.DocumentReference;
40    import org.xwiki.model.reference.EntityReferenceSerializer;
41    import org.xwiki.model.reference.ObjectReference;
42    import org.xwiki.query.Query;
43    import org.xwiki.query.QueryException;
44    import org.xwiki.query.QueryManager;
45   
46    /**
47    * Implementation of the {@link MessageStream} that stores messages as {@link Event events} in the {@link EventStream}.
48    *
49    * @version $Id: 823ac02b88e1a0440fa2d43e5e22f862cd9d50f5 $
50    * @since 3.0M3
51    */
52    @Component
53    @Singleton
 
54    public class DefaultMessageStream implements MessageStream
55    {
56    /** Logging helper object. */
57    private static final Logger LOG = LoggerFactory.getLogger(DefaultMessageStream.class);
58   
59    /** Needed for altering queries. */
60    @Inject
61    private QueryManager qm;
62   
63    /** Needed for obtaining the current wiki name. */
64    @Inject
65    private ModelContext context;
66   
67    /** Entity serializer, used for converting references to strings suitable for storing in the "stream" field. */
68    @Inject
69    private EntityReferenceSerializer<String> serializer;
70   
71    /** The event stream used for storing the messages. */
72    @Inject
73    private EventStream stream;
74   
75    /** The default factory for creating event objects. */
76    @Inject
77    private EventFactory factory;
78   
79    /** Needed for retrieving the current user. */
80    @Inject
81    private DocumentAccessBridge bridge;
82   
 
83  4 toggle @Override
84    public void postPublicMessage(String message)
85    {
86  4 Event e = createMessageEvent(message, "publicMessage");
87  4 DocumentReference userDoc = this.bridge.getCurrentUserReference();
88  4 e.setRelatedEntity(userDoc);
89  4 e.setImportance(Importance.MINOR);
90  4 e.setStream(this.serializer.serialize(userDoc));
91  4 this.stream.addEvent(e);
92    }
93   
 
94  4 toggle @Override
95    public void postPersonalMessage(String message)
96    {
97  4 Event e = createMessageEvent(message, "personalMessage");
98  4 DocumentReference userDoc = this.bridge.getCurrentUserReference();
99  4 e.setRelatedEntity(userDoc);
100  4 e.setStream(this.serializer.serialize(userDoc));
101  4 this.stream.addEvent(e);
102    }
103   
 
104  5 toggle @Override
105    public void postDirectMessageToUser(String message, DocumentReference user)
106    {
107  5 if (!this.bridge.exists(user)) {
108  1 throw new IllegalArgumentException("Target user does not exist");
109    }
110  4 Event e = createMessageEvent(message, "directMessage");
111  4 e.setRelatedEntity(new ObjectReference("XWiki.XWikiUsers", user));
112  4 e.setStream(this.serializer.serialize(user));
113  4 e.setImportance(Importance.CRITICAL);
114  4 this.stream.addEvent(e);
115    }
116   
 
117  2 toggle @Override
118    public void postMessageToGroup(String message, DocumentReference group) throws IllegalAccessError
119    {
120  2 if (!this.bridge.exists(group)) {
121  1 throw new IllegalArgumentException("Target group does not exist");
122    }
123  1 Event e = createMessageEvent(message, "groupMessage");
124  1 e.setRelatedEntity(new ObjectReference("XWiki.XWikiGroups", group));
125  1 e.setStream(this.serializer.serialize(group));
126  1 e.setImportance(Importance.MAJOR);
127  1 this.stream.addEvent(e);
128    }
129   
 
130  2 toggle @Override
131    public List<Event> getRecentPersonalMessages()
132    {
133  2 return getRecentPersonalMessages(this.bridge.getCurrentUserReference(), 30, 0);
134    }
135   
 
136  10 toggle @Override
137    public List<Event> getRecentPersonalMessages(int limit, int offset)
138    {
139  10 return getRecentPersonalMessages(this.bridge.getCurrentUserReference(), limit, offset);
140    }
141   
 
142  1 toggle @Override
143    public List<Event> getRecentPersonalMessages(DocumentReference author)
144    {
145  1 return getRecentPersonalMessages(author, 30, 0);
146    }
147   
 
148  13 toggle @Override
149    public List<Event> getRecentPersonalMessages(DocumentReference author, int limit, int offset)
150    {
151  13 List<Event> result = new ArrayList<Event>();
152  13 try {
153  13 Query q = this.qm.createQuery(
154    "where event.application = 'MessageStream' and event.type = 'personalMessage'"
155    + " and event.user = :user order by event.date desc",
156    Query.XWQL);
157  13 q.bindValue("user", this.serializer.serialize(author));
158  13 q.setLimit(limit > 0 ? limit : 30).setOffset(offset >= 0 ? offset : 0);
159  13 result = this.stream.searchEvents(q);
160    } catch (QueryException ex) {
161  1 LOG.warn("Failed to search personal messages: {}", ex.getMessage());
162    }
163  13 return result;
164    }
165   
 
166  0 toggle @Override
167    public List<Event> getRecentDirectMessages()
168    {
169  0 return getRecentDirectMessages(30, 0);
170    }
171   
 
172  0 toggle @Override
173    public List<Event> getRecentDirectMessages(int limit, int offset)
174    {
175  0 List<Event> result = new ArrayList<Event>();
176  0 try {
177  0 Query q = this.qm.createQuery(
178    "where event.application = 'MessageStream' and event.type = 'directMessage'"
179    + " and event.stream = :targetUser order by event.date desc",
180    Query.XWQL);
181  0 q.bindValue("targetUser", this.serializer.serialize(this.bridge.getCurrentUserReference()));
182  0 q.setLimit(limit > 0 ? limit : 30).setOffset(offset >= 0 ? offset : 0);
183  0 result = this.stream.searchEvents(q);
184    } catch (QueryException ex) {
185  0 LOG.warn("Failed to search direct messages: {}", ex.getMessage());
186    }
187  0 return result;
188    }
189   
 
190  0 toggle @Override
191    public List<Event> getRecentMessagesForGroup(DocumentReference group)
192    {
193  0 return getRecentMessagesForGroup(group, 30, 0);
194    }
195   
 
196  0 toggle @Override
197    public List<Event> getRecentMessagesForGroup(DocumentReference group, int limit, int offset)
198    {
199  0 List<Event> result = new ArrayList<Event>();
200  0 try {
201  0 Query q = this.qm.createQuery(
202    "where event.application = 'MessageStream' and event.type = 'groupMessage'"
203    + " and event.stream = :group order by event.date desc",
204    Query.XWQL);
205  0 q.bindValue("group", this.serializer.serialize(group));
206  0 q.setLimit(limit > 0 ? limit : 30).setOffset(offset >= 0 ? offset : 0);
207  0 result = this.stream.searchEvents(q);
208    } catch (QueryException ex) {
209  0 LOG.warn("Failed to search group messages: {}", ex.getMessage());
210    }
211  0 return result;
212    }
213   
 
214  0 toggle @Override
215    public void deleteMessage(String id)
216    {
217  0 Query q;
218  0 try {
219  0 q = this.qm.createQuery("where event.id = :id", Query.XWQL);
220  0 q.bindValue("id", id);
221  0 List<Event> events = this.stream.searchEvents(q);
222  0 if (events == null || events.isEmpty()) {
223  0 throw new IllegalArgumentException("This message does not exist");
224  0 } else if (events.get(0).getUser().equals(this.bridge.getCurrentUserReference())) {
225  0 this.stream.deleteEvent(events.get(0));
226    } else {
227  0 throw new IllegalArgumentException("You are not authorized to delete this message");
228    }
229    } catch (QueryException ex) {
230  0 LOG.warn("Failed to delete message: {}", ex.getMessage());
231    }
232    }
233   
234    /**
235    * Creates an {@link Event} object with the common fields filled in: event ID, target document, application, user...
236    * It also fills in the provided message body and type.
237    *
238    * @param message the message to store in the event; at most 2000 characters are stored, longer messages are
239    * automatically trimmed
240    * @param messageType the type of message
241    * @return the initialized event object
242    */
 
243  13 toggle protected Event createMessageEvent(String message, String messageType)
244    {
245  13 Event e = this.factory.createEvent();
246  13 e.setApplication("MessageStream");
247  13 e.setDocument(new DocumentReference(this.context.getCurrentEntityReference().getRoot().getName(), "XWiki",
248    e.getId()));
249  13 e.setBody(StringUtils.left(message, 2000));
250  13 e.setType(messageType);
251  13 return e;
252    }
253    }