1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.exoplatform.social.plugin.doc;
18
19 import java.io.InputStream;
20
21 import javax.jcr.Node;
22 import javax.jcr.PathNotFoundException;
23 import javax.jcr.RepositoryException;
24 import javax.jcr.ValueFormatException;
25 import javax.portlet.PortletRequest;
26
27 import org.apache.commons.io.FileUtils;
28 import org.apache.commons.lang.StringUtils;
29
30 import org.exoplatform.commons.utils.CommonsUtils;
31 import org.exoplatform.container.PortalContainer;
32 import org.exoplatform.ecm.jcr.model.VersionNode;
33 import org.exoplatform.ecm.webui.utils.Utils;
34 import org.exoplatform.services.cms.documents.DocumentService;
35 import org.exoplatform.services.log.ExoLogger;
36 import org.exoplatform.services.log.Log;
37 import org.exoplatform.services.security.ConversationState;
38 import org.exoplatform.services.wcm.core.NodeLocation;
39 import org.exoplatform.services.wcm.core.NodetypeConstant;
40 import org.exoplatform.services.wcm.core.WebSchemaConfigService;
41 import org.exoplatform.services.wcm.friendly.FriendlyService;
42 import org.exoplatform.services.wcm.utils.WCMCoreUtils;
43 import org.exoplatform.services.wcm.webcontent.WebContentSchemaHandler;
44 import org.exoplatform.social.webui.activity.BaseUIActivity;
45 import org.exoplatform.social.webui.activity.UIActivitiesContainer;
46 import org.exoplatform.social.webui.composer.PopupContainer;
47 import org.exoplatform.web.application.ApplicationMessage;
48 import org.exoplatform.webui.application.WebuiRequestContext;
49 import org.exoplatform.webui.application.portlet.PortletRequestContext;
50 import org.exoplatform.webui.config.annotation.ComponentConfig;
51 import org.exoplatform.webui.config.annotation.EventConfig;
52 import org.exoplatform.webui.core.UIApplication;
53 import org.exoplatform.webui.core.lifecycle.UIFormLifecycle;
54 import org.exoplatform.webui.cssfile.CssClassManager;
55 import org.exoplatform.webui.cssfile.CssClassUtils;
56 import org.exoplatform.webui.event.Event;
57 import org.exoplatform.webui.event.EventListener;
58
59
60
61
62
63
64
65
66 @ComponentConfig(
67 lifecycle = UIFormLifecycle.class,
68 template = "classpath:groovy/social/plugin/doc/UIDocActivity.gtmpl",
69 events = {
70 @EventConfig(listeners = UIDocActivity.DownloadDocumentActionListener.class),
71 @EventConfig(listeners = UIDocActivity.ViewDocumentActionListener.class),
72 @EventConfig(listeners = BaseUIActivity.LoadLikesActionListener.class),
73 @EventConfig(listeners = BaseUIActivity.ToggleDisplayCommentFormActionListener.class),
74 @EventConfig(listeners = BaseUIActivity.LikeActivityActionListener.class),
75 @EventConfig(listeners = BaseUIActivity.SetCommentListStatusActionListener.class),
76 @EventConfig(listeners = BaseUIActivity.PostCommentActionListener.class),
77 @EventConfig(listeners = BaseUIActivity.DeleteActivityActionListener.class),
78 @EventConfig(listeners = BaseUIActivity.DeleteCommentActionListener.class),
79 @EventConfig(listeners = BaseUIActivity.LikeCommentActionListener.class)
80 }
81 )
82 public class UIDocActivity extends BaseUIActivity {
83
84 private static final Log LOG = ExoLogger.getLogger(UIDocActivity.class);
85 private static final String IMAGE_PREFIX = "image/";
86 private static final String DOCUMENT_POSTFIX = "/pdf";
87
88 public static final String DOCLINK = "DOCLINK";
89 public static final String MESSAGE = "MESSAGE";
90 public static final String REPOSITORY = "REPOSITORY";
91 public static final String WORKSPACE = "WORKSPACE";
92 public static final String DOCNAME = "DOCNAME";
93 public static final String ID = "id";
94 public static final String DOCPATH = "DOCPATH";
95
96 public static final String CONTENT_NAME = "contentName";
97 public static final String CONTENT_LINK = "contenLink";
98 public static final String IMAGE_PATH = "imagePath";
99 public static final String MIME_TYPE = "mimeType";
100 public static final String STATE = "state";
101 public static final String AUTHOR = "author";
102 public static final String DATE_CREATED = "dateCreated";
103 public static final String LAST_MODIFIED = "lastModified";
104 public static final String DOCUMENT_TYPE_LABEL= "docTypeLabel";
105 public static final String DOCUMENT_TITLE = "docTitle";
106 public static final String DOCUMENT_VERSION = "docVersion";
107 public static final String DOCUMENT_SUMMARY = "docSummary";
108 public static final String IS_SYMLINK = "isSymlink";
109
110 public String docLink;
111 public String message;
112 public String docName;
113 public String docPath;
114 public String repository;
115 public String workspace;
116
117 private DocumentService documentService;
118
119 public UIDocActivity() {
120 documentService = CommonsUtils.getService(DocumentService.class);
121 }
122
123 protected boolean isPreviewable() {
124 return getMimeType().endsWith(DOCUMENT_POSTFIX);
125 }
126
127 protected boolean isImageFile() {
128 return getMimeType().startsWith(IMAGE_PREFIX);
129 }
130
131 protected String getDocThumbnail(){
132 String portalContainerName = PortalContainer.getCurrentPortalContainerName();
133 String restContextName = PortalContainer.getRestContextName(portalContainerName);
134 return new StringBuffer().append("/").append(portalContainerName).
135 append("/").append(restContextName).
136 append("/thumbnailImage/big").
137 append("/").append(UIDocActivityComposer.REPOSITORY).
138 append("/").append(UIDocActivityComposer.WORKSPACE).
139 append(docPath).toString();
140 }
141
142 protected String getSize() {
143 double size = 0;
144 Node docNode = getDocNode();
145 try {
146 if (docNode.hasNode(Utils.JCR_CONTENT)) {
147 Node contentNode = docNode.getNode(Utils.JCR_CONTENT);
148 if (contentNode.hasProperty(Utils.JCR_DATA)) {
149 size = contentNode.getProperty(Utils.JCR_DATA).getLength();
150 }
151
152 return FileUtils.byteCountToDisplaySize((long)size);
153 }
154 } catch (PathNotFoundException e) {
155 return StringUtils.EMPTY;
156 } catch (ValueFormatException e) {
157 return StringUtils.EMPTY;
158 } catch (RepositoryException e) {
159 return StringUtils.EMPTY;
160 }
161 return StringUtils.EMPTY;
162 }
163
164 protected int getVersion() {
165 try {
166 VersionNode rootVersion_ = new VersionNode(NodeLocation.getNodeByLocation(new NodeLocation(repository, workspace, docPath))
167 .getVersionHistory().getRootVersion(), getDocNode().getSession());
168 if (rootVersion_ != null) {
169 return rootVersion_.getChildren().size();
170 }
171 } catch (Exception e) {
172 if(LOG.isDebugEnabled()) {
173 LOG.debug("cannot version node", e);
174 }
175 }
176 return 0;
177 }
178
179 protected String getCssClassIconFile(String fileName, String fileType) {
180 String cssClass = CssClassUtils.getCSSClassByFileNameAndFileType(fileName, fileType, CssClassManager.ICON_SIZE.ICON_64).replace("uiIcon", "uiBgd");
181 return cssClass;
182 }
183
184 protected boolean isDisplayThumbnail(String mimeType) {
185 if( mimeType.startsWith("application/pdf") ||
186 mimeType.startsWith("application/msword") ||
187 mimeType.startsWith("application/vnd.oasis.opendocument.text") ||
188 mimeType.startsWith("application/vnd.openxmlformats-officedocument.wordprocessingml.document") ||
189 mimeType.startsWith("application/rtf") ){
190 return true;
191 }
192 return false;
193 }
194
195 public String getDocOpenUri() {
196 String uri = "";
197
198 if(docPath != null) {
199 try {
200 uri = documentService.getLinkInDocumentsApp(docPath);
201 } catch(Exception e) {
202 LOG.error("Cannot get document open URI of node " + docPath + " : " + e.getMessage(), e);
203 uri = "";
204 }
205 }
206
207 return uri;
208 }
209
210 private boolean hasPermissionViewFile() {
211 return (getDocNode() != null);
212 }
213
214 public static class ViewDocumentActionListener extends EventListener<UIDocActivity> {
215 @Override
216 public void execute(Event<UIDocActivity> event) throws Exception {
217 final UIDocActivity docActivity = event.getSource();
218 if (! docActivity.hasPermissionViewFile()) {
219 WebuiRequestContext ctx = event.getRequestContext();
220 UIApplication uiApplication = ctx.getUIApplication();
221 uiApplication.addMessage(new ApplicationMessage("UIDocActivity.msg.noPermission", null, ApplicationMessage.WARNING));
222 return;
223 }
224 final UIActivitiesContainer activitiesContainer = docActivity.getAncestorOfType(UIActivitiesContainer.class);
225 final PopupContainer popupContainer = activitiesContainer.getPopupContainer();
226
227 if (docActivity.getChild(UIDocViewer.class) != null) {
228 docActivity.removeChild(UIDocViewer.class);
229 }
230
231 UIDocViewer docViewer = popupContainer.createUIComponent(UIDocViewer.class, null, "DocViewer");
232 docViewer.docPath = docActivity.docPath;
233 docViewer.repository = docActivity.repository;
234 docViewer.workspace = docActivity.workspace;
235
236 popupContainer.activate(docViewer, 800, 600, true);
237 event.getRequestContext().addUIComponentToUpdateByAjax(popupContainer);
238 }
239 }
240
241 public static class DownloadDocumentActionListener extends EventListener<UIDocActivity> {
242 @Override
243 public void execute(Event<UIDocActivity> event) throws Exception {
244 UIDocActivity uiComp = event.getSource() ;
245 if (! uiComp.hasPermissionViewFile()) {
246 WebuiRequestContext ctx = event.getRequestContext();
247 UIApplication uiApplication = ctx.getUIApplication();
248 uiApplication.addMessage(new ApplicationMessage("UIDocActivity.msg.noPermission", null, ApplicationMessage.WARNING));
249 return;
250 }
251 String downloadLink = null;
252 if (getRealNode(uiComp.getDocNode()).getPrimaryNodeType().getName().equals(Utils.NT_FILE)) {
253 downloadLink = Utils.getDownloadRestServiceLink(uiComp.getDocNode());
254 }
255 event.getRequestContext().getJavascriptManager().addJavascript("ajaxRedirect('" + downloadLink + "');");
256 }
257
258 private Node getRealNode(Node node) throws Exception {
259
260 if (node.isNodeType("nt:frozenNode")) {
261 String uuid = node.getProperty("jcr:frozenUuid").getString();
262 return node.getSession().getNodeByUUID(uuid);
263 }
264 return node;
265 }
266 }
267
268 protected Node getDocNode() {
269 NodeLocation nodeLocation = new NodeLocation(repository, workspace, docPath);
270 return NodeLocation.getNodeByLocation(nodeLocation);
271 }
272
273
274
275
276
277
278
279 public String getWebdavURL() throws Exception {
280 Node contentNode = getDocNode();
281 NodeLocation nodeLocation = new NodeLocation(repository, workspace, docPath);
282 PortletRequestContext portletRequestContext = WebuiRequestContext.getCurrentInstance();
283 PortletRequest portletRequest = portletRequestContext.getRequest();
284 String repository = nodeLocation.getRepository();
285 String workspace = nodeLocation.getWorkspace();
286 String baseURI = portletRequest.getScheme() + "://" + portletRequest.getServerName() + ":"
287 + String.format("%s", portletRequest.getServerPort());
288
289 FriendlyService friendlyService = WCMCoreUtils.getService(FriendlyService.class);
290 String link = "#";
291
292 String portalName = PortalContainer.getCurrentPortalContainerName();
293 String restContextName = PortalContainer.getCurrentRestContextName();
294 if (contentNode.isNodeType("nt:frozenNode")) {
295 String uuid = contentNode.getProperty("jcr:frozenUuid").getString();
296 Node originalNode = contentNode.getSession().getNodeByUUID(uuid);
297 link = baseURI + "/" + portalName + "/" + restContextName + "/jcr/" + repository + "/"
298 + workspace + originalNode.getPath() + "?version=" + contentNode.getParent().getName();
299 } else {
300 link = baseURI + "/" + portalName + "/" + restContextName + "/jcr/" + repository + "/"
301 + workspace + contentNode.getPath();
302 }
303
304 return friendlyService.getFriendlyUri(link);
305 }
306
307
308
309
310
311
312 public String getSummary() {
313 String desc = "";
314 Node node = getDocNode();
315 try {
316 if (node != null) {
317 if (node.hasProperty("exo:summary")) {
318 desc = node.getProperty("exo:summary").getValue().getString();
319 } else if (node.hasNode("jcr:content")) {
320 Node content = node.getNode("jcr:content");
321 if (content.hasProperty("dc:description") && content.getProperty("dc:description").getValues().length > 0) {
322 desc = content.getProperty("dc:description").getValues()[0].getString();
323 }
324 }
325 }
326 } catch (RepositoryException re) {
327 if (LOG.isWarnEnabled())
328 LOG.warn("RepositoryException: ", re);
329 }
330
331 return desc;
332 }
333
334 public String getTitle() throws Exception {
335 return Utils.getTitle(getDocNode());
336 }
337
338
339
340
341
342
343 public static String getActivityOwnerId(Node node) {
344 String activityOwnerId = "";
345 ConversationState conversationState = ConversationState.getCurrent();
346 if (conversationState != null) {
347 activityOwnerId = conversationState.getIdentity().getUserId();
348 }else{
349 try {
350 activityOwnerId = node.getProperty("publication:lastUser").getString();
351 } catch (Exception e) {
352 LOG.info("No lastUser publication");
353 }
354 }
355 return activityOwnerId;
356 }
357
358
359
360
361
362
363
364 public static String getIllustrativeImage(Node node) {
365 WebSchemaConfigService schemaConfigService = WCMCoreUtils.getService(WebSchemaConfigService.class);
366 WebContentSchemaHandler contentSchemaHandler = schemaConfigService.getWebSchemaHandlerByType(WebContentSchemaHandler.class);
367 Node illustrativeImage = null;
368 String uri = "";
369 try {
370 illustrativeImage = contentSchemaHandler.getIllustrationImage(node);
371 uri = generateThumbnailImageURI(illustrativeImage);
372 } catch (PathNotFoundException ex) {
373 return uri;
374 } catch (Exception e) {
375 LOG.warn(e.getMessage(), e);
376 }
377 return uri;
378 }
379
380
381
382
383
384
385
386
387 public static String generateThumbnailImageURI(Node file) throws Exception {
388 StringBuilder builder = new StringBuilder();
389 NodeLocation fielLocation = NodeLocation.getNodeLocationByNode(file);
390 String repository = fielLocation.getRepository();
391 String workspaceName = fielLocation.getWorkspace();
392 String nodeIdentifiler = file.getPath().replaceFirst("/", "");
393 String portalName = PortalContainer.getCurrentPortalContainerName();
394 String restContextName = PortalContainer.getCurrentRestContextName();
395 InputStream stream = file.getNode(NodetypeConstant.JCR_CONTENT)
396 .getProperty(NodetypeConstant.JCR_DATA)
397 .getStream();
398 if (stream.available() == 0)
399 return null;
400 stream.close();
401 builder.append("/")
402 .append(portalName)
403 .append("/")
404 .append(restContextName)
405 .append("/")
406 .append("thumbnailImage/medium/")
407 .append(repository)
408 .append("/")
409 .append(workspaceName)
410 .append("/")
411 .append(nodeIdentifiler);
412 return builder.toString();
413 }
414
415
416
417
418
419
420
421
422 public static String getContentLink(Node node) throws Exception {
423 DocumentService documentService = CommonsUtils.getService(DocumentService.class);
424 return documentService.getLinkInDocumentsApp(node.getPath());
425 }
426
427
428
429
430
431
432
433 public static String getMimeType(Node node) {
434 try {
435 if (node.getPrimaryNodeType().getName().equals(NodetypeConstant.NT_FILE)) {
436 if (node.hasNode(NodetypeConstant.JCR_CONTENT))
437 return node.getNode(NodetypeConstant.JCR_CONTENT)
438 .getProperty(NodetypeConstant.JCR_MIME_TYPE)
439 .getString();
440 }
441 } catch (RepositoryException e) {
442 LOG.error(e.getMessage(), e);
443 }
444 return "";
445 }
446
447
448 private String getMimeType() {
449 String mimeType = "";
450 try {
451 mimeType = getDocNode().getNode("jcr:content").getProperty("jcr:mimeType").getString();
452 } catch (ValueFormatException e) {
453 if (LOG.isDebugEnabled())
454 LOG.debug(e);
455 return StringUtils.EMPTY;
456 } catch (PathNotFoundException e) {
457 if (LOG.isDebugEnabled())
458 LOG.debug(e);
459 return StringUtils.EMPTY;
460 } catch (RepositoryException e) {
461 if (LOG.isDebugEnabled())
462 LOG.debug(e);
463 return StringUtils.EMPTY;
464 }
465 return mimeType;
466 }
467 }