View Javadoc
1   /*
2    * Copyright (C) 2003-2010 eXo Platform SAS.
3    *
4    * This program is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Affero General Public License
6    * as published by the Free Software Foundation; either version 3
7    * of the License, or (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program; if not, see<http://www.gnu.org/licenses/>.
16   */
17  package org.exoplatform.social.core.application;
18  
19  import java.util.HashMap;
20  import java.util.Map;
21  
22  import org.exoplatform.container.PortalContainer;
23  import org.exoplatform.container.xml.InitParams;
24  import org.exoplatform.services.log.ExoLogger;
25  import org.exoplatform.services.log.Log;
26  import org.exoplatform.social.common.xmlprocessor.XMLProcessor;
27  import org.exoplatform.social.core.BaseActivityProcessorPlugin;
28  import org.exoplatform.social.core.activity.model.ExoSocialActivity;
29  import org.exoplatform.social.core.activity.model.ExoSocialActivityImpl;
30  import org.exoplatform.social.core.identity.model.Identity;
31  import org.exoplatform.social.core.identity.model.Profile;
32  import org.exoplatform.social.core.identity.provider.OrganizationIdentityProvider;
33  import org.exoplatform.social.core.manager.ActivityManager;
34  import org.exoplatform.social.core.manager.IdentityManager;
35  import org.exoplatform.social.core.manager.RelationshipManager;
36  import org.exoplatform.social.core.processor.I18NActivityUtils;
37  import org.exoplatform.social.core.relationship.RelationshipEvent;
38  import org.exoplatform.social.core.relationship.RelationshipListenerPlugin;
39  import org.exoplatform.social.core.relationship.model.Relationship;
40  import org.exoplatform.social.core.space.SpaceUtils;
41  import org.exoplatform.social.core.storage.api.IdentityStorage;
42  
43  /**
44   * Publish a status update in activity streams of 2 confirmed relations.
45   * @author <a href="mailto:patrice.lamarque@exoplatform.com">Patrice Lamarque</a>
46   * @version $Revision$
47   */
48  public class RelationshipPublisher extends RelationshipListenerPlugin {
49  
50    public static enum TitleId {
51      CONNECTION_REQUESTED,
52      CONNECTION_CONFIRMED
53    }
54  
55    public static final String USER_RELATION_CONFIRMED = "user_relation_confirmed";
56  
57    public static final String SENDER_PARAM = "SENDER";
58    public static final String RECEIVER_PARAM = "RECEIVER";
59    public static final String RELATIONSHIP_UUID_PARAM = "RELATIONSHIP_UUID";
60    public static final String RELATIONSHIP_ACTIVITY_TYPE = "exosocial:relationship";
61    public static final String NUMBER_OF_CONNECTIONS = "NUMBER_OF_CONNECTIONS";
62    public static final String USER_ACTIVITIES_FOR_RELATIONSHIP = "USER_ACTIVITIES_FOR_RELATIONSHIP";
63    public static final String USER_COMMENTS_ACTIVITY_FOR_RELATIONSHIP = "USER_COMMENTS_ACTIVITY_FOR_RELATIONSHIP";
64    public static final String USER_DISPLAY_NAME_PARAM = "USER_DISPLAY_NAME_PARAM";
65  
66    private static final Log LOG = ExoLogger.getLogger(RelationshipPublisher.class);
67    private ActivityManager  activityManager;
68  
69    private IdentityManager identityManager;
70  
71    public RelationshipPublisher(InitParams params, ActivityManager activityManager, IdentityManager identityManager) {
72      this.activityManager = activityManager;
73      this.identityManager = identityManager;
74    }
75  
76    private ExoSocialActivity createNewActivity(Identity identity, int nbOfConnections) {
77      ExoSocialActivity activity = new ExoSocialActivityImpl();
78      activity.setType(USER_ACTIVITIES_FOR_RELATIONSHIP);
79      updateActivity(activity, nbOfConnections);
80      return activity;
81    }
82    
83    private ExoSocialActivity createNewComment(Identity userIdenity, String fullName) {
84      ExoSocialActivityImpl comment = new ExoSocialActivityImpl();
85      comment.setType(USER_COMMENTS_ACTIVITY_FOR_RELATIONSHIP);
86      String message = String.format("I'm now connected with %s", fullName);
87      comment.setTitle(message);
88      comment.setUserId(userIdenity.getId());
89  
90      I18NActivityUtils.addResourceKeyToProcess(comment, USER_RELATION_CONFIRMED);
91      I18NActivityUtils.addResourceKey(comment, USER_RELATION_CONFIRMED, fullName);
92      return comment;
93    }
94    
95    private void updateActivity(ExoSocialActivity activity, int numberOfConnections) {
96      String title = String.format("I'm now connected with %s user(s)", numberOfConnections);
97      String titleId = "user_relations";
98      Map<String,String> params = new HashMap<String,String>();
99      activity.setTitle(title);
100     activity.setTitleId(null);
101     activity.setTemplateParams(params);
102     I18NActivityUtils.addResourceKey(activity, titleId, "" + numberOfConnections);
103   }
104 
105   /**
106    * Publish an activity on both user's stream to indicate their new connection
107    */
108   public void confirmed(RelationshipEvent event) {
109     Relationship relationship = event.getPayload();
110     try {
111       Identity sender = identityManager.getOrCreateIdentity(OrganizationIdentityProvider.NAME, relationship.getSender().getRemoteId(), true); 
112       Identity receiver = identityManager.getOrCreateIdentity(OrganizationIdentityProvider.NAME, relationship.getReceiver().getRemoteId(), true);
113       
114       String activityIdSender = getIdentityStorage().getProfileActivityId(sender.getProfile(), Profile.AttachedActivityType.RELATIONSHIP);
115       int nbOfSenderConnections = getRelationShipManager().getConnections(sender).getSize();
116       String activityIdReceiver = getIdentityStorage().getProfileActivityId(receiver.getProfile(), Profile.AttachedActivityType.RELATIONSHIP);
117       int nbOfReceiverConnections = getRelationShipManager().getConnections(receiver).getSize();
118       
119       String fullNameReceiver = receiver.getProfile().getFullName();
120       ExoSocialActivity senderComment = createNewComment(sender, fullNameReceiver);
121       String fullNameSender = sender.getProfile().getFullName();
122       ExoSocialActivity receiverComment = createNewComment(receiver, fullNameSender);
123       
124       if (activityIdSender != null) {
125         ExoSocialActivity activitySender = activityManager.getActivity(activityIdSender);
126         if (activitySender != null) {
127           updateActivity(activitySender, nbOfSenderConnections);
128           activityManager.updateActivity(activitySender);
129           activityManager.saveComment(activitySender, senderComment);
130         } else {
131           activityIdSender = null;
132         }
133       }
134       if (activityIdSender == null) {
135         ExoSocialActivity newActivitySender = createNewActivity(sender, nbOfSenderConnections);
136         activityManager.saveActivityNoReturn(sender, newActivitySender);
137         getIdentityStorage().updateProfileActivityId(sender, newActivitySender.getId(), Profile.AttachedActivityType.RELATIONSHIP);
138         SpaceUtils.endRequest();
139         activityManager.saveComment(newActivitySender, senderComment);
140       }
141       
142       if (activityIdReceiver != null) {
143         ExoSocialActivity activityReceiver = activityManager.getActivity(activityIdReceiver);
144         if (activityReceiver != null) {
145           updateActivity(activityReceiver, nbOfReceiverConnections);
146           activityManager.updateActivity(activityReceiver);
147           activityManager.saveComment(activityReceiver, receiverComment);
148         } else {
149           activityIdReceiver = null;
150         }
151       }
152       if (activityIdReceiver == null) {
153         ExoSocialActivity newActivityReceiver = createNewActivity(receiver, nbOfReceiverConnections);
154         activityManager.saveActivityNoReturn(receiver, newActivityReceiver);
155         getIdentityStorage().updateProfileActivityId(receiver, newActivityReceiver.getId(), Profile.AttachedActivityType.RELATIONSHIP);
156         SpaceUtils.endRequest();
157         activityManager.saveComment(newActivityReceiver, receiverComment);
158       }
159     } catch (Exception e) {
160       LOG.warn("Failed to publish event " + event + ": " + e.getMessage());
161     }
162   }
163 
164   private void reloadIfNeeded(Identity identity) throws Exception {
165     if (identity.getId() == null || identity.getProfile().getFullName().length() == 0) {
166       identity = identityManager.getIdentity(identity.getGlobalId().toString(), true);
167     }
168   }
169 
170   @Override
171   public void ignored(RelationshipEvent event) {
172     ;// void on purpose
173   }
174 
175   @Override
176   public void removed(RelationshipEvent event) {
177     Relationship relationship = event.getPayload();
178     try {
179       Identity sender = identityManager.getOrCreateIdentity(OrganizationIdentityProvider.NAME, relationship.getSender().getRemoteId(), true); 
180       Identity receiver = identityManager.getOrCreateIdentity(OrganizationIdentityProvider.NAME, relationship.getReceiver().getRemoteId(), true);
181       
182       String activityIdSender = getIdentityStorage().getProfileActivityId(sender.getProfile(), Profile.AttachedActivityType.RELATIONSHIP);
183       int nbOfSenderConnections = getRelationShipManager().getConnections(sender).getSize();
184       String activityIdReceiver = getIdentityStorage().getProfileActivityId(receiver.getProfile(), Profile.AttachedActivityType.RELATIONSHIP);
185       int nbOfReceiverConnections = getRelationShipManager().getConnections(receiver).getSize();
186       
187       if (activityIdSender != null) {
188         ExoSocialActivity activitySender = activityManager.getActivity(activityIdSender);
189         if (activitySender != null) {
190           updateActivity(activitySender, nbOfSenderConnections);
191           activityManager.updateActivity(activitySender);
192         }
193       }
194       
195       if (activityIdReceiver != null) {
196         ExoSocialActivity activityReceiver = activityManager.getActivity(activityIdReceiver);
197         if (activityReceiver != null) {
198           updateActivity(activityReceiver, nbOfReceiverConnections);
199           activityManager.updateActivity(activityReceiver);
200         }
201       }
202 
203     } catch (Exception e) {
204       LOG.debug("Failed to update relationship activity when remove connection : " + e.getMessage());
205     }
206   }
207 
208   public void denied(RelationshipEvent event) {
209     ;// void on purpose
210 
211   }
212 
213   /**
214    * Publish an activity on invited member to show the invitation to connect
215    */
216   public void requested(RelationshipEvent event) {
217 //    Relationship relationship = event.getPayload();
218 //    try {
219 //      Map<String,String> params = this.getParams(relationship);
220 //      ExoSocialActivity activity1 = new ExoSocialActivityImpl(relationship.getSender().getId(), 
221 //                                                              RELATIONSHIP_ACTIVITY_TYPE,
222 //                                                              relationship.getSender().getProfile().getFullName() + " has invited " 
223 //                                                              + relationship.getReceiver().getProfile().getFullName() + " to connect", null);
224 //      activity1.setTitleId(TitleId.CONNECTION_REQUESTED.toString());
225 //      activity1.setTemplateParams(params);
226 //      activityManager.saveActivityNoReturn(relationship.getSender(), activity1);
227 //
228 //      //TODO hoatle a quick fix for activities gadget to allow deleting this activity
229 //      ExoSocialActivity activity2 = new ExoSocialActivityImpl(relationship.getReceiver().getId(), 
230 //                                                              RELATIONSHIP_ACTIVITY_TYPE,
231 //                                                              relationship.getSender().getProfile().getFullName() + " has invited "
232 //                                                              + relationship.getReceiver().getProfile().getFullName() + " to connect", null);
233 //      activity2.setTitleId(TitleId.CONNECTION_REQUESTED.toString());
234 //      activity2.setTemplateParams(params);
235 //      activityManager.saveActivityNoReturn(relationship.getReceiver(), activity2);
236 //
237 //    } catch (Exception e) {
238 //      LOG.warn("Failed to publish event " + event + ": " + e.getMessage());
239 //    }
240   }
241 
242   /**
243    * Gets params (sender, receiver, relationship uuid) from a provided relationship.
244    * 
245    * @param relationship
246    * @return
247    * @since 1.2.0-GA
248    */
249   private Map<String,String> getParams(Relationship relationship) throws Exception {
250     Identity sender = relationship.getSender();
251     reloadIfNeeded(sender);
252     Identity receiver = relationship.getReceiver();
253     reloadIfNeeded(receiver);
254     String senderRemoteId = sender.getRemoteId();
255     String receiverRemoteId = receiver.getRemoteId();
256     Map<String,String> params = new HashMap<String,String>();
257     params.put(SENDER_PARAM, senderRemoteId);
258     params.put(RECEIVER_PARAM, receiverRemoteId);
259     params.put(RELATIONSHIP_UUID_PARAM, relationship.getId());
260     return params;
261   }
262   
263   private IdentityStorage getIdentityStorage() {
264     return (IdentityStorage) PortalContainer.getInstance().getComponentInstanceOfType(IdentityStorage.class);
265   }
266   
267   private RelationshipManager getRelationShipManager() {
268     return (RelationshipManager) PortalContainer.getInstance().getComponentInstanceOfType(RelationshipManager.class);
269   }
270 }