1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.exoplatform.wcm.ext.component.activity.listener;
18
19 import org.apache.commons.lang.StringUtils;
20 import org.exoplatform.commons.utils.ActivityTypeUtils;
21 import org.exoplatform.commons.utils.CommonsUtils;
22 import org.exoplatform.commons.utils.ISO8601;
23 import org.exoplatform.container.ExoContainer;
24 import org.exoplatform.container.ExoContainerContext;
25 import org.exoplatform.container.PortalContainer;
26 import org.exoplatform.container.xml.PortalContainerInfo;
27 import org.exoplatform.services.cms.BasePath;
28 import org.exoplatform.services.cms.documents.DocumentService;
29 import org.exoplatform.services.cms.jcrext.activity.ActivityCommonService;
30 import org.exoplatform.services.cms.link.LinkManager;
31 import org.exoplatform.services.cms.templates.TemplateService;
32 import org.exoplatform.services.context.DocumentContext;
33 import org.exoplatform.services.jcr.core.ExtendedNode;
34 import org.exoplatform.services.jcr.core.ManageableRepository;
35 import org.exoplatform.services.jcr.ext.common.SessionProvider;
36 import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator;
37 import org.exoplatform.services.jcr.impl.core.NodeImpl;
38 import org.exoplatform.services.log.ExoLogger;
39 import org.exoplatform.services.log.Log;
40 import org.exoplatform.services.resources.ResourceBundleService;
41 import org.exoplatform.services.security.ConversationState;
42 import org.exoplatform.services.wcm.core.NodeLocation;
43 import org.exoplatform.services.wcm.core.NodetypeConstant;
44 import org.exoplatform.services.wcm.core.WebSchemaConfigService;
45 import org.exoplatform.services.wcm.friendly.FriendlyService;
46 import org.exoplatform.services.wcm.utils.WCMCoreUtils;
47 import org.exoplatform.services.wcm.webcontent.WebContentSchemaHandler;
48 import org.exoplatform.social.core.activity.model.ExoSocialActivity;
49 import org.exoplatform.social.core.activity.model.ExoSocialActivityImpl;
50 import org.exoplatform.social.core.identity.model.Identity;
51 import org.exoplatform.social.core.identity.model.Profile;
52 import org.exoplatform.social.core.identity.provider.OrganizationIdentityProvider;
53 import org.exoplatform.social.core.identity.provider.SpaceIdentityProvider;
54 import org.exoplatform.social.core.manager.ActivityManager;
55 import org.exoplatform.social.core.manager.IdentityManager;
56 import org.exoplatform.social.core.service.LinkProvider;
57 import org.exoplatform.social.core.space.spi.SpaceService;
58 import org.exoplatform.social.core.space.model.Space;
59 import org.exoplatform.social.core.space.SpaceUtils;
60 import org.exoplatform.wcm.ext.component.activity.ContentUIActivity;
61 import org.exoplatform.wcm.ext.component.activity.FileUIActivity;
62 import org.exoplatform.webui.application.WebuiRequestContext;
63 import org.exoplatform.webui.cssfile.CssClassIconFile;
64 import org.exoplatform.webui.cssfile.CssClassManager;
65 import org.exoplatform.webui.cssfile.CssClassUtils;
66
67 import javax.jcr.Node;
68 import javax.jcr.PathNotFoundException;
69 import javax.jcr.RepositoryException;
70 import java.io.InputStream;
71 import java.net.URLEncoder;
72 import java.text.DateFormat;
73 import java.text.SimpleDateFormat;
74 import java.util.Calendar;
75 import java.util.HashMap;
76 import java.util.List;
77 import java.util.Locale;
78 import java.util.Map;
79 import java.util.MissingResourceException;
80 import java.util.ResourceBundle;
81
82
83
84
85
86
87
88 public class Utils {
89
90 private static final Log LOG = ExoLogger.getLogger(Utils.class);
91
92
93 public static final String CONTENT_SPACES = "contents:spaces";
94 public static final String FILE_SPACES = "files:spaces";
95 public static final String SHARE_FILE = "sharefiles:spaces";
96 public static final String SHARE_CONTENT = "sharecontents:spaces";
97
98
99 private static final String CURRENT_STATE_PROP = "publication:currentState";
100
101 public static final String EXO_RESOURCES_URI = "/eXoSkin/skin/images/themes/default/Icons/TypeIcons/EmailNotificationIcons/";
102 public static final String ICON_FILE_EXTENSION = ".png";
103 public static final String DEFAULT_AVATAR = "/eXoSkin/skin/images/themes/default/social/skin/ShareImages/UserAvtDefault.png";
104
105 private static String MIX_COMMENT = "exo:activityComment";
106 private static String MIX_COMMENT_ID = "exo:activityCommentID";
107 private static int MAX_SUMMARY_LINES_COUNT = 4;
108 private static int MAX_SUMMARY_CHAR_COUNT = 430;
109 private static String activityType;
110
111
112 public static String getActivityType() {
113 return activityType;
114 }
115
116 public static void setActivityType(String activityType) {
117 Utils.activityType = activityType;
118 }
119
120
121
122
123
124
125
126
127
128 public static Map<String, String> populateActivityData(Node node,
129 String activityOwnerId,
130 String activityMsgBundleKey) throws Exception {
131 return populateActivityData(node, activityOwnerId, activityMsgBundleKey, false, null, null);
132 }
133 public static Map<String, String> populateActivityData(Node node,
134 String activityOwnerId, String activityMsgBundleKey,
135 boolean isSystemComment, String systemComment, String perm) throws Exception {
136
137 DateFormat dateFormatter = null;
138 dateFormatter = new SimpleDateFormat(ISO8601.SIMPLE_DATETIME_FORMAT);
139 LinkManager linkManager = WCMCoreUtils.getService(LinkManager.class);
140
141 if(node.canAddMixin(NodetypeConstant.MIX_REFERENCEABLE)){
142 node.addMixin(NodetypeConstant.MIX_REFERENCEABLE);
143 node.save();
144 }
145
146 String repository = ((ManageableRepository) node.getSession().getRepository()).getConfiguration()
147 .getName();
148 String workspace = node.getSession().getWorkspace().getName();
149
150 String illustrationImg;
151 try{
152 illustrationImg = Utils.getIllustrativeImage(node);
153 }catch(Exception ex){
154 illustrationImg="";
155 }
156 String strDateCreated = "";
157 if (node.hasProperty(NodetypeConstant.EXO_DATE_CREATED)) {
158 Calendar dateCreated = node.getProperty(NodetypeConstant.EXO_DATE_CREATED).getDate();
159 strDateCreated = dateFormatter.format(dateCreated.getTime());
160 }
161 String strLastModified = "";
162 if (node.hasNode(NodetypeConstant.JCR_CONTENT)) {
163 Node contentNode = node.getNode(NodetypeConstant.JCR_CONTENT);
164 if (contentNode.hasProperty(NodetypeConstant.JCR_LAST_MODIFIED)) {
165 Calendar lastModified = contentNode.getProperty(NodetypeConstant.JCR_LAST_MODIFIED)
166 .getDate();
167 strLastModified = dateFormatter.format(lastModified.getTime());
168 }
169 }
170
171 activityOwnerId = activityOwnerId != null ? activityOwnerId : "";
172
173
174 Map<String, String> activityParams = new HashMap<String, String>();
175 activityParams.put(ContentUIActivity.NODE_UUID, node.getUUID());
176 activityParams.put(ContentUIActivity.CONTENT_NAME, node.getName());
177 activityParams.put(ContentUIActivity.AUTHOR, activityOwnerId);
178 activityParams.put(ContentUIActivity.DATE_CREATED, strDateCreated);
179 activityParams.put(ContentUIActivity.LAST_MODIFIED, strLastModified);
180 activityParams.put(ContentUIActivity.CONTENT_LINK, getContentLink(node));
181 activityParams.put(ContentUIActivity.ID,
182 node.isNodeType(NodetypeConstant.MIX_REFERENCEABLE) ? node.getUUID() : "");
183 activityParams.put(ContentUIActivity.REPOSITORY, repository);
184 activityParams.put(ContentUIActivity.WORKSPACE, workspace);
185 activityParams.put(ContentUIActivity.MESSAGE, activityMsgBundleKey);
186 activityParams.put(ContentUIActivity.MIME_TYPE, getMimeType(linkManager.isLink(node)?linkManager.getTarget(node, true):node));
187 activityParams.put(ContentUIActivity.IMAGE_PATH, illustrationImg);
188 activityParams.put(ContentUIActivity.IMAGE_PATH, illustrationImg);
189 if (isSystemComment) {
190 activityParams.put(ContentUIActivity.IS_SYSTEM_COMMENT, String.valueOf(isSystemComment));
191 activityParams.put(ContentUIActivity.SYSTEM_COMMENT, systemComment);
192 }else{
193 activityParams.put(ContentUIActivity.IS_SYSTEM_COMMENT, String.valueOf(false));
194 activityParams.put(ContentUIActivity.SYSTEM_COMMENT, "");
195 }
196 activityParams.put(ContentUIActivity.PERMISSION, perm);
197 activityParams.put(ContentUIActivity.COMMENT, systemComment);
198 activityParams.put(ContentUIActivity.THUMBNAIL, getThumbnailUrl(node, repository, workspace) != null ? getThumbnailUrl(node, repository, workspace) : getDefaultThumbnailUrl(node));
199 activityParams.put(ContentUIActivity.NODE_PATH, node.getPath());
200 return activityParams;
201 }
202
203 private static String getDefaultThumbnailUrl(Node node) throws RepositoryException {
204 LinkManager linkManager = WCMCoreUtils.getService(LinkManager.class);
205 String cssClass = CssClassUtils.getCSSClassByFileNameAndFileType(
206 node.getName(), getMimeType(linkManager.isLink(node)?linkManager.getTarget(node, true):node), CssClassManager.ICON_SIZE.ICON_64);
207
208 if (cssClass.indexOf(CssClassIconFile.DEFAULT_CSS) > 0) {
209 return CommonsUtils.getCurrentDomain() + EXO_RESOURCES_URI + "uiIcon64x64Templatent_file.png";
210 }
211 return CommonsUtils.getCurrentDomain() + EXO_RESOURCES_URI + cssClass.split(" ")[0] + ICON_FILE_EXTENSION;
212 }
213
214 private static String getThumbnailUrl(Node node, String repository, String workspace) {
215 try {
216 LinkManager linkManager = WCMCoreUtils.getService(LinkManager.class);
217 String mimeType = getMimeType(linkManager.isLink(node)?linkManager.getTarget(node, true):node);
218 ExoContainer container = ExoContainerContext.getCurrentContainer();
219 PortalContainerInfo containerInfo = (PortalContainerInfo) container.getComponentInstanceOfType(PortalContainerInfo.class);
220 String portalName = containerInfo.getContainerName();
221
222 String restContextName = org.exoplatform.ecm.webui.utils.Utils.getRestContextName(portalName);
223 String preferenceWS = node.getSession().getWorkspace().getName();
224 String encodedPath = URLEncoder.encode(node.getPath(), "utf-8");
225 encodedPath = encodedPath.replaceAll ("%2F", "/");
226
227 if (mimeType.startsWith("image")) {
228
229 return CommonsUtils.getCurrentDomain() + "/" + portalName + "/" + restContextName + "/thumbnailImage/custom/300x300/" +
230 repository + "/" + preferenceWS + encodedPath;
231 }
232 else if (mimeType.indexOf("icon") >=0) {
233 return getWebdavURL(node, repository, workspace);
234 }
235 else if (org.exoplatform.services.cms.impl.Utils.isSupportThumbnailView(mimeType)) {
236 return CommonsUtils.getCurrentDomain() + "/" + portalName + "/" + restContextName + "/thumbnailImage/big/" + repository + "/" + preferenceWS + encodedPath;
237 } else {
238 return null;
239 }
240
241 }
242 catch (Exception e) {
243 LOG.debug("Cannot get thumbnail url");
244 }
245 return StringUtils.EMPTY;
246 }
247
248 private static String getWebdavURL(Node contentNode, String repository, String workspace) throws Exception {
249 FriendlyService friendlyService = WCMCoreUtils.getService(FriendlyService.class);
250 String link = "#";
251
252 String portalName = PortalContainer.getCurrentPortalContainerName();
253 String restContextName = PortalContainer.getCurrentRestContextName();
254 if (contentNode.isNodeType("nt:frozenNode")) {
255 String uuid = contentNode.getProperty("jcr:frozenUuid").getString();
256 Node originalNode = contentNode.getSession().getNodeByUUID(uuid);
257 link = CommonsUtils.getCurrentDomain() + "/" + portalName + "/" + restContextName + "/jcr/" + repository + "/"
258 + workspace + originalNode.getPath() + "?version=" + contentNode.getParent().getName();
259 } else {
260 link = CommonsUtils.getCurrentDomain() + "/" + portalName + "/" + restContextName + "/jcr/" + repository + "/"
261 + workspace + contentNode.getPath();
262 }
263
264 return friendlyService.getFriendlyUri(link);
265 }
266
267
268
269
270 public static void postActivity(Node node, String activityMsgBundleKey) throws Exception {
271 postActivity(node, activityMsgBundleKey, false, false, null, null);
272 }
273
274 public static ExoSocialActivity createShareActivity(Node node, String activityMsgBundleKey, String activityType, String comments, String perm) throws Exception{
275 setActivityType(activityType);
276 if(SHARE_FILE.equals(activityType)){
277 return postFileActivity(node,activityMsgBundleKey,false,false,comments, perm);
278 }else if(SHARE_CONTENT.equals(activityType)){
279 return postActivity(node,activityMsgBundleKey,false,false,comments, perm);
280 }else{
281 setActivityType(null);
282 return postFileActivity(node,activityMsgBundleKey,false,false,comments, perm);
283 }
284 }
285
286
287
288 public static void postFileActivity(Node node, String activityMsgBundleKey) throws Exception {
289 postFileActivity(node, activityMsgBundleKey, false, false, null, null);
290 }
291
292
293
294
295
296
297
298
299
300
301
302
303 public static ExoSocialActivity postActivity(Node node, String activityMsgBundleKey, boolean needUpdate,
304 boolean isSystemComment, String systemComment, String perm) throws Exception {
305 Object isSkipRaiseAct = DocumentContext.getCurrent()
306 .getAttributes()
307 .get(DocumentContext.IS_SKIP_RAISE_ACT);
308 if (isSkipRaiseAct != null && Boolean.valueOf(isSkipRaiseAct.toString())) {
309 return null;
310 }
311
312
313
314
315
316 ExoContainer container = ExoContainerContext.getCurrentContainer();
317 ActivityManager activityManager = (ActivityManager) container.getComponentInstanceOfType(ActivityManager.class);
318 IdentityManager identityManager = (IdentityManager) container.getComponentInstanceOfType(IdentityManager.class);
319 ActivityCommonService activityCommonService =
320 (ActivityCommonService)container.getComponentInstanceOfType(ActivityCommonService.class);
321
322 SpaceService spaceService = WCMCoreUtils.getService(SpaceService.class);
323
324
325 refineNode(node);
326
327
328 String activityOwnerId = getActivityOwnerId(node);
329 String nodeActivityID = StringUtils.EMPTY;
330 ExoSocialActivity exa =null;
331 if (node.isNodeType(ActivityTypeUtils.EXO_ACTIVITY_INFO)) {
332 try {
333 nodeActivityID = node.getProperty(ActivityTypeUtils.EXO_ACTIVITY_ID).getString();
334 exa = activityManager.getActivity(nodeActivityID);
335 }catch (Exception e){
336 LOG.info("No activity is deleted, return no related activity");
337 }
338 }
339 ExoSocialActivity activity = null ;
340 String commentID;
341 boolean commentFlag = false;
342 if (node.isNodeType(MIX_COMMENT) && node.hasProperty(MIX_COMMENT_ID) && activityCommonService.isEditing(node))
343 {
344 commentID = node.getProperty(MIX_COMMENT_ID).getString();
345 if (StringUtils.isNotBlank(commentID)) activity = activityManager.getActivity(commentID);
346 commentFlag = (activity != null);
347 }
348 if (activity==null) {
349 String _activityType = StringUtils.isNotEmpty(activityType)?activityType:CONTENT_SPACES;
350 activity = createActivity(identityManager, activityOwnerId,
351 node, activityMsgBundleKey, _activityType, isSystemComment, systemComment, perm);
352 setActivityType(null);
353 }
354
355 if (exa!=null) {
356 if (commentFlag) {
357 Map<String, String> paramsMap = activity.getTemplateParams();
358 String paramMessage = paramsMap.get(ContentUIActivity.MESSAGE);
359 String paramContent = paramsMap.get(ContentUIActivity.SYSTEM_COMMENT);
360 if (!StringUtils.isEmpty(paramMessage)) {
361 paramMessage += ActivityCommonService.VALUE_SEPERATOR + activityMsgBundleKey;
362 if (StringUtils.isEmpty(systemComment)) {
363 paramContent += ActivityCommonService.VALUE_SEPERATOR + " ";
364 }else {
365 paramContent += ActivityCommonService.VALUE_SEPERATOR + systemComment;
366 }
367 } else {
368 paramMessage = activityMsgBundleKey;
369 paramContent = systemComment;
370 }
371 paramsMap.put(ContentUIActivity.MESSAGE, paramMessage);
372 paramsMap.put(ContentUIActivity.SYSTEM_COMMENT, paramContent);
373 activity.setTemplateParams(paramsMap);
374 updateNotifyMessages(activity, activityMsgBundleKey, systemComment);
375 activityManager.updateActivity(activity);
376 } else {
377 updateNotifyMessages(activity, activity.getTemplateParams().get(ContentUIActivity.MESSAGE), activity.getTemplateParams().get(ContentUIActivity.SYSTEM_COMMENT));
378 activityManager.saveComment(exa, activity);
379 if (activityCommonService.isEditing(node)) {
380 commentID = activity.getId();
381 if (node.canAddMixin(MIX_COMMENT)) node.addMixin(MIX_COMMENT);
382 if (node.isNodeType(MIX_COMMENT)) node.setProperty(MIX_COMMENT_ID, commentID);
383 }
384 }
385 if (needUpdate) {
386 updateMainActivity(activityManager, node, exa);
387 }
388 return activity;
389 }else {
390 String spaceGroupName = getSpaceName(node);
391 Space space = spaceService.getSpaceByGroupId(SpaceUtils.SPACE_GROUP + "/" + spaceGroupName);
392 if (spaceGroupName != null && spaceGroupName.length() > 0
393 && space != null) {
394
395 Identity spaceIdentity = identityManager.getOrCreateIdentity(SpaceIdentityProvider.NAME,
396 space.getPrettyName(),
397 true);
398 activityManager.saveActivityNoReturn(spaceIdentity, activity);
399 } else if (activityOwnerId != null && activityOwnerId.length() > 0) {
400
401 Identity ownerIdentity = identityManager.getOrCreateIdentity(OrganizationIdentityProvider.NAME,
402 activityOwnerId,
403 true);
404 activityManager.saveActivityNoReturn(ownerIdentity, activity);
405 } else {
406 return null;
407 }
408 String activityId = activity.getId();
409 if (!StringUtils.isEmpty(activityId)) {
410 ActivityTypeUtils.attachActivityId(node, activityId);
411 }
412 updateMainActivity(activityManager, node, activity);
413
414 if (node.isNodeType(ActivityTypeUtils.EXO_ACTIVITY_INFO)) {
415 try {
416 nodeActivityID = node.getProperty(ActivityTypeUtils.EXO_ACTIVITY_ID).getString();
417 exa = activityManager.getActivity(nodeActivityID);
418 } catch (Exception e) {
419 LOG.info("No activity is deleted, return no related activity");
420 }
421 if (exa != null && !commentFlag && isSystemComment) {
422 activityManager.saveComment(exa, activity);
423 if (activityCommonService.isEditing(node)) {
424 commentID = activity.getId();
425 if (node.canAddMixin(MIX_COMMENT)) node.addMixin(MIX_COMMENT);
426 if (node.isNodeType(MIX_COMMENT)) node.setProperty(MIX_COMMENT_ID, commentID);
427 }
428 }
429 }
430
431 return activity;
432 }
433 }
434
435
436
437
438
439
440
441
442
443
444 public static ExoSocialActivity postFileActivity(Node node, String activityMsgBundleKey, boolean needUpdate,
445 boolean isSystemComment, String systemComment, String perm) throws Exception {
446 Object isSkipRaiseAct = DocumentContext.getCurrent()
447 .getAttributes()
448 .get(DocumentContext.IS_SKIP_RAISE_ACT);
449 if (isSkipRaiseAct != null && Boolean.valueOf(isSkipRaiseAct.toString())) {
450 return null;
451 }
452
453
454
455
456
457 ExoContainer container = ExoContainerContext.getCurrentContainer();
458 ActivityManager activityManager = (ActivityManager) container.getComponentInstanceOfType(ActivityManager.class);
459 IdentityManager identityManager = (IdentityManager) container.getComponentInstanceOfType(IdentityManager.class);
460 ActivityCommonService activityCommonService =
461 (ActivityCommonService)container.getComponentInstanceOfType(ActivityCommonService.class);
462
463 SpaceService spaceService = WCMCoreUtils.getService(SpaceService.class);
464
465
466 refineNode(node);
467
468
469 String activityOwnerId = getActivityOwnerId(node);
470 String nodeActivityID = StringUtils.EMPTY;
471 ExoSocialActivity exa =null;
472 if (node.isNodeType(ActivityTypeUtils.EXO_ACTIVITY_INFO)) {
473 try {
474 nodeActivityID = node.getProperty(ActivityTypeUtils.EXO_ACTIVITY_ID).getString();
475 exa = activityManager.getActivity(nodeActivityID);
476 }catch (Exception e){
477 LOG.info("No activity is deleted, return no related activity");
478 }
479 }
480 ExoSocialActivity activity = null ;
481 String commentID;
482 boolean commentFlag = false;
483 if (node.isNodeType(MIX_COMMENT) && activityCommonService.isEditing(node)) {
484 if (node.hasProperty(MIX_COMMENT_ID)) {
485 commentID = node.getProperty(MIX_COMMENT_ID).getString();
486 if (StringUtils.isNotBlank(commentID)) activity = activityManager.getActivity(commentID);
487 commentFlag = (activity != null);
488 }
489 }
490 if (activity==null) {
491 String _activityType = StringUtils.isNotEmpty(activityType)?activityType:FILE_SPACES;
492 activity = createActivity(identityManager, activityOwnerId,
493 node, activityMsgBundleKey, _activityType, isSystemComment, systemComment, perm);
494 setActivityType(null);
495 }
496
497 if (exa!=null) {
498 if (commentFlag) {
499 Map<String, String> paramsMap = activity.getTemplateParams();
500 String paramMessage = paramsMap.get(ContentUIActivity.MESSAGE);
501 String paramContent = paramsMap.get(ContentUIActivity.SYSTEM_COMMENT);
502 if (!StringUtils.isEmpty(paramMessage)) {
503 paramMessage += ActivityCommonService.VALUE_SEPERATOR + activityMsgBundleKey;
504 if (StringUtils.isEmpty(systemComment)) {
505 paramContent += ActivityCommonService.VALUE_SEPERATOR + " ";
506 }else {
507 paramContent += ActivityCommonService.VALUE_SEPERATOR + systemComment;
508 }
509 } else {
510 paramMessage = activityMsgBundleKey;
511 paramContent = systemComment;
512 }
513 paramsMap.put(ContentUIActivity.MESSAGE, paramMessage);
514 paramsMap.put(ContentUIActivity.SYSTEM_COMMENT, paramContent);
515 activity.setTemplateParams(paramsMap);
516 updateNotifyMessages(activity, activityMsgBundleKey, systemComment);
517 activityManager.updateActivity(activity);
518 } else {
519 updateNotifyMessages(activity, activity.getTemplateParams().get(ContentUIActivity.MESSAGE), activity.getTemplateParams().get(ContentUIActivity.SYSTEM_COMMENT));
520 activityManager.saveComment(exa, activity);
521 if (activityCommonService.isEditing(node)) {
522 commentID = activity.getId();
523 if (node.canAddMixin(MIX_COMMENT)) node.addMixin(MIX_COMMENT);
524 if (node.isNodeType(MIX_COMMENT)) node.setProperty(MIX_COMMENT_ID, commentID);
525 }
526 }
527 return activity;
528 }else {
529 String spaceGroupName = getSpaceName(node);
530 Space space = spaceService.getSpaceByGroupId(SpaceUtils.SPACE_GROUP + "/" + spaceGroupName);
531 if (spaceGroupName != null && spaceGroupName.length() > 0
532 && space != null) {
533
534 Identity spaceIdentity = identityManager.getOrCreateIdentity(SpaceIdentityProvider.NAME,
535 space.getPrettyName(),
536 true);
537 activityManager.saveActivityNoReturn(spaceIdentity, activity);
538 } else if (activityOwnerId != null && activityOwnerId.length() > 0) {
539 if (!isPublic(node)) {
540
541 return null;
542 }
543
544 Identity ownerIdentity = identityManager.getOrCreateIdentity(OrganizationIdentityProvider.NAME,
545 activityOwnerId,
546 true);
547 activityManager.saveActivityNoReturn(ownerIdentity, activity);
548 } else {
549 return null;
550 }
551 String activityId = activity != null ? activity.getId() : null;
552 if (!StringUtils.isEmpty(activityId)) {
553 ActivityTypeUtils.attachActivityId(node, activityId);
554 }
555
556 if (node.isNodeType(ActivityTypeUtils.EXO_ACTIVITY_INFO)) {
557 try {
558 nodeActivityID = node.getProperty(ActivityTypeUtils.EXO_ACTIVITY_ID).getString();
559 exa = activityManager.getActivity(nodeActivityID);
560 } catch (Exception e) {
561 LOG.info("No activity is deleted, return no related activity");
562 }
563 if (exa != null && !commentFlag && isSystemComment) {
564 activity.setId(null);
565 activityManager.saveComment(exa, activity);
566 if (activityCommonService.isEditing(node)) {
567 commentID = activity.getId();
568 if (node.canAddMixin(MIX_COMMENT)) node.addMixin(MIX_COMMENT);
569 if (node.isNodeType(MIX_COMMENT)) node.setProperty(MIX_COMMENT_ID, commentID);
570 }
571 }
572 }
573
574 return activity;
575 }
576 }
577
578 public static void updateNotifyMessages(ExoSocialActivity activity, String activityMsgBundleKey, String systemComment)
579 throws Exception {
580 Locale locale = new Locale("en");
581 ResourceBundleService resourceBundleService = WCMCoreUtils.getService(ResourceBundleService.class);
582 ResourceBundle res = resourceBundleService.getResourceBundle("locale.extension.SocialIntegration", locale);
583 StringBuffer sb = new StringBuffer();
584 String[] keys = activityMsgBundleKey.split(ActivityCommonService.VALUE_SEPERATOR);
585 String[] values = systemComment.split(ActivityCommonService.VALUE_SEPERATOR);
586 String message;
587 for (String key : keys) {
588 try {
589 message = res.getString(key);
590 } catch(MissingResourceException mre) {
591 message = key;
592 }
593 if(values.length > 0) {
594 for(int i = 0; i < values.length; i++) {
595 message = message.replace("{"+i+"}", values[i]);
596 }
597 }
598 sb.append(message).append("\n");
599 }
600 activity.setTitle(sb.toString());
601 }
602
603
604 private static void updateMainActivity(ActivityManager activityManager, Node contentNode, ExoSocialActivity activity) {
605 Map<String, String> activityParams = activity.getTemplateParams();
606 String state;
607 String nodeTitle;
608 String nodeType = null;
609 String documentTypeLabel;
610 String currentVersion = null;
611 TemplateService templateService = WCMCoreUtils.getService(TemplateService.class);
612 try {
613 nodeType = contentNode.getPrimaryNodeType().getName();
614 documentTypeLabel = templateService.getTemplateLabel(nodeType);
615 }catch (Exception e) {
616 documentTypeLabel = "";
617 }
618 try {
619 nodeTitle = org.exoplatform.ecm.webui.utils.Utils.getTitle(contentNode);
620 } catch (Exception e1) {
621 nodeTitle ="";
622 }
623 try {
624 state = contentNode.hasProperty(CURRENT_STATE_PROP) ? contentNode.getProperty(CURRENT_STATE_PROP)
625 .getValue()
626 .getString() : "";
627 } catch (Exception e) {
628 state="";
629 }
630 try {
631 currentVersion = contentNode.getBaseVersion().getName();
632
633
634 if (currentVersion.contains("jcr:rootVersion")) currentVersion = "0";
635 }catch (Exception e) {
636 currentVersion ="";
637 }
638 activityParams.put(ContentUIActivity.STATE, state);
639 activityParams.put(ContentUIActivity.DOCUMENT_TYPE_LABEL, documentTypeLabel);
640 activityParams.put(ContentUIActivity.DOCUMENT_TITLE, nodeTitle);
641 activityParams.put(ContentUIActivity.DOCUMENT_VERSION, currentVersion);
642 String summary = getSummary(contentNode);
643 summary =getFirstSummaryLines(summary, MAX_SUMMARY_LINES_COUNT);
644 activityParams.put(ContentUIActivity.DOCUMENT_SUMMARY, summary);
645 activity.setTemplateParams(activityParams);
646 activityManager.updateActivity(activity);
647 }
648
649
650
651
652
653
654
655 private static boolean isSupportedContent(Node node) throws Exception {
656 if (getActivityOwnerId(node) != null && getActivityOwnerId(node).length() > 0) {
657 NodeHierarchyCreator nodeHierarchyCreator = (NodeHierarchyCreator) ExoContainerContext.getCurrentContainer()
658 .getComponentInstanceOfType(NodeHierarchyCreator.class);
659 SessionProvider sessionProvider = WCMCoreUtils.getUserSessionProvider();
660 if(sessionProvider == null){
661 sessionProvider = WCMCoreUtils.getSystemSessionProvider();
662 }
663 Node userNode = nodeHierarchyCreator.getUserNode(sessionProvider, getActivityOwnerId(node));
664 if (userNode != null && node.getPath().startsWith(userNode.getPath() + "/Private/")) {
665 return false;
666 }
667 }
668
669 return true;
670 }
671
672
673
674
675
676
677
678 private static void refineNode(Node currentNode) throws Exception {
679 if (currentNode instanceof NodeImpl && !((NodeImpl) currentNode).isValid()) {
680 ExoContainer container = ExoContainerContext.getCurrentContainer();
681 LinkManager linkManager = (LinkManager) container.getComponentInstanceOfType(LinkManager.class);
682 if (linkManager.isLink(currentNode)) {
683 try {
684 currentNode = linkManager.getTarget(currentNode, false);
685 } catch (RepositoryException ex) {
686 currentNode = linkManager.getTarget(currentNode, true);
687 }
688 }
689 }
690 }
691
692
693
694
695
696
697 private static String getActivityOwnerId(Node node) {
698 String activityOwnerId = "";
699 ConversationState conversationState = ConversationState.getCurrent();
700 if (conversationState != null) {
701 activityOwnerId = conversationState.getIdentity().getUserId();
702 }else{
703 try {
704 activityOwnerId = node.getProperty("publication:lastUser").getString();
705 } catch (Exception e) {
706 LOG.info("No lastUser publication");
707 }
708 }
709 return activityOwnerId;
710 }
711
712
713
714
715
716
717
718
719 private static String getSpaceName(Node node) throws Exception {
720 NodeHierarchyCreator nodeHierarchyCreator = (NodeHierarchyCreator) ExoContainerContext.getCurrentContainer()
721 .getComponentInstanceOfType(NodeHierarchyCreator.class);
722 String groupPath = nodeHierarchyCreator.getJcrPath(BasePath.CMS_GROUPS_PATH);
723 String spacesFolder = groupPath + "/spaces/";
724 String spaceName = "";
725 String nodePath = node.getPath();
726 if (nodePath.startsWith(spacesFolder)) {
727 spaceName = nodePath.substring(spacesFolder.length());
728 spaceName = spaceName.substring(0, spaceName.indexOf("/"));
729 }
730
731 return spaceName;
732 }
733
734 private static boolean isPublic(Node node) {
735 if (node instanceof ExtendedNode) {
736 ExtendedNode n = (ExtendedNode)node;
737 try {
738 List<String> permissions =n.getACL().getPermissions("any");
739 if(permissions != null && permissions.size() > 0) {
740 for (String p : permissions) {
741 if ("read".equalsIgnoreCase(p)) {
742 return true;
743 }
744 }
745 }
746 } catch (RepositoryException ex) {
747 return false;
748 }
749 }
750 return false;
751 }
752
753
754
755
756
757
758
759
760 public static String getContentLink(Node node) throws Exception {
761 DocumentService documentService = CommonsUtils.getService(DocumentService.class);
762 return documentService.getShortLinkInDocumentsApp(node.getSession().getWorkspace().getName(), ((NodeImpl)node).getInternalIdentifier());
763 }
764
765
766
767
768
769
770
771
772
773
774
775
776 public static ExoSocialActivity createActivity(IdentityManager identityManager,
777 String activityOwnerId, Node node,
778 String activityMsgBundleKey, String activityType) throws Exception {
779 return createActivity(identityManager, activityOwnerId, node, activityMsgBundleKey, activityType, false, null, null);
780 }
781 public static ExoSocialActivity createActivity(IdentityManager identityManager,
782 String activityOwnerId,
783 Node node, String activityMsgBundleKey, String activityType,
784 boolean isSystemComment, String systemComment, String perm) throws Exception {
785
786 Map<String, String> activityParams = populateActivityData(node, activityOwnerId, activityMsgBundleKey, isSystemComment, systemComment, perm);
787
788 String title = node.hasProperty(NodetypeConstant.EXO_TITLE) ? node.getProperty(NodetypeConstant.EXO_TITLE)
789 .getString()
790 : org.exoplatform.ecm.webui.utils.Utils.getTitle(node);
791 ExoSocialActivity activity = new ExoSocialActivityImpl();
792 String userId = "";
793 if(ConversationState.getCurrent() != null)
794 {
795 userId = ConversationState.getCurrent().getIdentity().getUserId();
796 }else{
797 userId = activityOwnerId;
798 }
799 Identity identity = identityManager.getOrCreateIdentity(OrganizationIdentityProvider.NAME,
800 userId, false);
801 activity.setUserId(identity.getId());
802 activity.setType(activityType);
803 activity.setUrl(node.getPath());
804 if(StringUtils.isNotEmpty(activityMsgBundleKey) && StringUtils.isNotEmpty(systemComment)) {
805 updateNotifyMessages(activity, activityMsgBundleKey, systemComment);
806 } else if(StringUtils.isNotEmpty(systemComment)){
807 activity.setTitle(systemComment);
808 } else {
809 activity.setTitle(title);
810 }
811 activity.setTemplateParams(activityParams);
812 return activity;
813 }
814
815 public static void deleteFileActivity(Node node) throws RepositoryException {
816
817 ExoContainer container = ExoContainerContext.getCurrentContainer();
818 ActivityManager activityManager = (ActivityManager) container.getComponentInstanceOfType(ActivityManager.class);
819
820
821 String nodeActivityID = StringUtils.EMPTY;
822 if (node.isNodeType(ActivityTypeUtils.EXO_ACTIVITY_INFO)) {
823 try {
824 nodeActivityID = node.getProperty(ActivityTypeUtils.EXO_ACTIVITY_ID).getString();
825 if(activityManager.getActivity(nodeActivityID) != null) {
826 activityManager.deleteActivity(nodeActivityID);
827 }
828 } catch (Exception e) {
829 LOG.info("No activity is deleted, return no related activity");
830 }
831 }
832 }
833
834
835
836
837
838
839
840 public static String getIllustrativeImage(Node node) {
841 WebSchemaConfigService schemaConfigService = WCMCoreUtils.getService(WebSchemaConfigService.class);
842 WebContentSchemaHandler contentSchemaHandler = schemaConfigService.getWebSchemaHandlerByType(WebContentSchemaHandler.class);
843 Node illustrativeImage = null;
844 String uri = "";
845 try {
846 illustrativeImage = contentSchemaHandler.getIllustrationImage(node);
847 uri = generateThumbnailImageURI(illustrativeImage);
848 } catch (PathNotFoundException ex) {
849 return uri;
850 } catch (Exception e) {
851 LOG.warn(e.getMessage(), e);
852 }
853 return uri;
854 }
855
856
857
858
859
860
861
862
863 public static String generateThumbnailImageURI(Node file) throws Exception {
864 StringBuilder builder = new StringBuilder();
865 NodeLocation fielLocation = NodeLocation.getNodeLocationByNode(file);
866 String repository = fielLocation.getRepository();
867 String workspaceName = fielLocation.getWorkspace();
868 String nodeIdentifiler = file.getPath().replaceFirst("/", "");
869 String portalName = PortalContainer.getCurrentPortalContainerName();
870 String restContextName = PortalContainer.getCurrentRestContextName();
871 InputStream stream = file.getNode(NodetypeConstant.JCR_CONTENT)
872 .getProperty(NodetypeConstant.JCR_DATA)
873 .getStream();
874 if (stream.available() == 0)
875 return null;
876 stream.close();
877 builder.append("/")
878 .append(portalName)
879 .append("/")
880 .append(restContextName)
881 .append("/")
882 .append("thumbnailImage/medium/")
883 .append(repository)
884 .append("/")
885 .append(workspaceName)
886 .append("/")
887 .append(nodeIdentifiler);
888 return builder.toString();
889 }
890
891
892
893
894
895
896
897 public static String getMimeType(Node node) {
898 try {
899 if (node.getPrimaryNodeType().getName().equals(NodetypeConstant.NT_FILE)) {
900 if (node.hasNode(NodetypeConstant.JCR_CONTENT))
901 return node.getNode(NodetypeConstant.JCR_CONTENT)
902 .getProperty(NodetypeConstant.JCR_MIME_TYPE)
903 .getString();
904 }
905 } catch (RepositoryException e) {
906 LOG.error(e.getMessage(), e);
907 }
908 return "";
909 }
910
911 public static String getSummary(Node node) {
912 String desc = "";
913 try {
914 if (node != null) {
915 if (node.hasProperty("exo:summary")) {
916 desc = node.getProperty("exo:summary").getValue().getString();
917 } else if (node.hasNode("jcr:content")) {
918 Node content = node.getNode("jcr:content");
919 if (content.hasProperty("dc:description") && content.getProperty("dc:description").getValues().length > 0) {
920 desc = content.getProperty("dc:description").getValues()[0].getString();
921 }
922 }
923 }
924 } catch (RepositoryException re) {
925 if (LOG.isWarnEnabled())
926 LOG.warn("RepositoryException: ", re);
927 }
928 return desc;
929 }
930 public static String getFirstSummaryLines(String source) {
931 return getFirstSummaryLines(source, MAX_SUMMARY_LINES_COUNT);
932 }
933
934
935 private static String convertActivityContent(String source){
936 String result = source;
937 result = result.replaceAll("(?i)<head>.*</head>", "");
938 result = result.replaceAll("(?i)<script.*>.*</script>", "");
939 result = result.replaceAll("(?i)<style.*>.*</style>", "");
940 result = result.replaceAll("<([a-zA-Z\"]+) *[^/]*?>", "");
941 result = result.replaceAll("</p>", "<br>");
942 result = result.replaceAll("</([a-zA-Z]+) *[^/]*?>", "");
943 result = result.replaceAll("([\r\n\t])+", "");
944 result = result.replaceAll("^(<br>)", "");
945 result = result.replaceAll("(<br>[ \r\t\n]+<br>)", "\n");
946 result = result.replaceAll("(<br>)+", "\n");
947 return result;
948 }
949
950
951
952
953
954
955
956 public static String getFirstSummaryLines(String source, int linesCount) {
957 String result = convertActivityContent(source);
958 int i = 0;
959 int index = -1;
960 while (true) {
961 index = result.indexOf("\n", index+1);
962 if (index<0) break;
963 i++;
964 if (i>=linesCount) break;
965 }
966 if (index <0) {
967 if (result.length()>MAX_SUMMARY_CHAR_COUNT)
968 return result.substring(0, MAX_SUMMARY_CHAR_COUNT-1) + "...";
969 return result;
970 }
971 if (index>MAX_SUMMARY_CHAR_COUNT) index = MAX_SUMMARY_CHAR_COUNT-1;
972 result = result.substring(0, index) + "\n...";
973 return result;
974 }
975
976 public static String[] getSystemCommentTitle(Map<String, String> activityParams) {
977 String[] result;
978 if (activityParams == null) return null;
979 String commentValue = activityParams.get(FileUIActivity.SYSTEM_COMMENT);
980 if (!StringUtils.isEmpty(commentValue)) {
981 if (commentValue.indexOf(ActivityCommonService.VALUE_SEPERATOR) >= 0) {
982 result = commentValue.split(ActivityCommonService.VALUE_SEPERATOR);
983 return result;
984 } else {
985 return new String[]{commentValue};
986 }
987 }
988 return null;
989 }
990
991 public static String[] getSystemCommentBundle(Map<String, String> activityParams) {
992 String[] result;
993 if (activityParams == null) return null;
994 String tmp = activityParams.get(FileUIActivity.IS_SYSTEM_COMMENT);
995 String commentMessage;
996 if (tmp == null) return null;
997 try {
998 if (Boolean.parseBoolean(tmp)) {
999 commentMessage = activityParams.get(FileUIActivity.MESSAGE);
1000 if (!StringUtils.isEmpty(commentMessage)) {
1001 if (commentMessage.indexOf(ActivityCommonService.VALUE_SEPERATOR) >= 0) {
1002 result = commentMessage.split(ActivityCommonService.VALUE_SEPERATOR);
1003 return result;
1004 } else {
1005 return new String[]{commentMessage};
1006 }
1007 }
1008 }
1009 } catch (Exception e) {
1010 return null;
1011 }
1012 return null;
1013 }
1014
1015 public static String getBundleValue(String key) {
1016 try {
1017 WebuiRequestContext context = WebuiRequestContext.getCurrentInstance();
1018 ResourceBundle res = context.getApplicationResourceBundle();
1019 String value = res.getString(key);
1020 return value;
1021 } catch (MissingResourceException e) {
1022 return key;
1023 }
1024 }
1025
1026 public static String processMentions(String comment) {
1027 String excerpts[] = comment.split("@");
1028 comment = excerpts[0];
1029 String mentioned = "";
1030 for (int i=1; i<excerpts.length; i++) {
1031 String name = excerpts[i].split(" ")[0];
1032 Identity identity = org.exoplatform.social.notification.Utils.getIdentityManager().getOrCreateIdentity(OrganizationIdentityProvider.NAME, name, true);
1033 if (identity != null) {
1034 mentioned = addMentioned(name, identity.getProfile().getFullName());
1035 }
1036 if (mentioned.isEmpty()) {
1037 if (excerpts[i].isEmpty()) comment = comment + " ";
1038 else comment = comment + excerpts[i] + " ";
1039 } else {
1040 comment = comment + mentioned + excerpts[i].substring(name.length(),excerpts[i].length());
1041 mentioned = "";
1042 }
1043 }
1044 return comment;
1045 }
1046
1047 private static String addMentioned(String mention, String fullname) {
1048 String profileURL = CommonsUtils.getCurrentDomain() + LinkProvider.getProfileUri(mention);
1049 return "<a href=" + profileURL + " type=\"mentionedUser\" rel=\"nofollow\">" + fullname + "</a>";
1050 }
1051
1052 public static void setAvatarUrl(Node commentNode) throws RepositoryException {
1053 String name = commentNode.getProperty("exo:commentor").getString();;
1054 Identity identity = org.exoplatform.social.notification.Utils.getIdentityManager().getOrCreateIdentity(OrganizationIdentityProvider.NAME, name, true);
1055 Profile profile = identity.getProfile();
1056 if (profile.getAvatarUrl() != null ) {
1057 commentNode.setProperty("exo:commentorAvatar", profile.getAvatarUrl());
1058 } else {
1059 commentNode.setProperty("exo:commentorAvatar", DEFAULT_AVATAR);
1060 } ;
1061 }
1062 }