UIDocActivity.java
/*
* Copyright (C) 2003-2010 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see<http://www.gnu.org/licenses/>.
*/
package org.exoplatform.social.plugin.doc;
import java.io.InputStream;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.ValueFormatException;
import javax.portlet.PortletRequest;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.exoplatform.commons.utils.CommonsUtils;
import org.exoplatform.container.PortalContainer;
import org.exoplatform.ecm.jcr.model.VersionNode;
import org.exoplatform.ecm.webui.utils.Utils;
import org.exoplatform.services.cms.documents.DocumentService;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.security.ConversationState;
import org.exoplatform.services.wcm.core.NodeLocation;
import org.exoplatform.services.wcm.core.NodetypeConstant;
import org.exoplatform.services.wcm.core.WebSchemaConfigService;
import org.exoplatform.services.wcm.friendly.FriendlyService;
import org.exoplatform.services.wcm.utils.WCMCoreUtils;
import org.exoplatform.services.wcm.webcontent.WebContentSchemaHandler;
import org.exoplatform.social.webui.activity.BaseUIActivity;
import org.exoplatform.social.webui.activity.UIActivitiesContainer;
import org.exoplatform.social.webui.composer.PopupContainer;
import org.exoplatform.web.application.ApplicationMessage;
import org.exoplatform.webui.application.WebuiRequestContext;
import org.exoplatform.webui.application.portlet.PortletRequestContext;
import org.exoplatform.webui.config.annotation.ComponentConfig;
import org.exoplatform.webui.config.annotation.EventConfig;
import org.exoplatform.webui.core.UIApplication;
import org.exoplatform.webui.core.lifecycle.UIFormLifecycle;
import org.exoplatform.webui.cssfile.CssClassManager;
import org.exoplatform.webui.cssfile.CssClassUtils;
import org.exoplatform.webui.event.Event;
import org.exoplatform.webui.event.EventListener;
/**
* Created by The eXo Platform SAS
* Author : Zun
* exo@exoplatform.com
* Jul 23, 2010
*/
@ComponentConfig(
lifecycle = UIFormLifecycle.class,
template = "classpath:groovy/social/plugin/doc/UIDocActivity.gtmpl",
events = {
@EventConfig(listeners = UIDocActivity.DownloadDocumentActionListener.class),
@EventConfig(listeners = UIDocActivity.ViewDocumentActionListener.class),
@EventConfig(listeners = BaseUIActivity.LoadLikesActionListener.class),
@EventConfig(listeners = BaseUIActivity.ToggleDisplayCommentFormActionListener.class),
@EventConfig(listeners = BaseUIActivity.LikeActivityActionListener.class),
@EventConfig(listeners = BaseUIActivity.SetCommentListStatusActionListener.class),
@EventConfig(listeners = BaseUIActivity.PostCommentActionListener.class),
@EventConfig(listeners = BaseUIActivity.DeleteActivityActionListener.class),
@EventConfig(listeners = BaseUIActivity.DeleteCommentActionListener.class),
@EventConfig(listeners = BaseUIActivity.LikeCommentActionListener.class)
}
)
public class UIDocActivity extends BaseUIActivity {
private static final Log LOG = ExoLogger.getLogger(UIDocActivity.class);
private static final String IMAGE_PREFIX = "image/";
private static final String DOCUMENT_POSTFIX = "/pdf";
public static final String DOCLINK = "DOCLINK";
public static final String MESSAGE = "MESSAGE";
public static final String REPOSITORY = "REPOSITORY";
public static final String WORKSPACE = "WORKSPACE";
public static final String DOCNAME = "DOCNAME";
public static final String ID = "id";
public static final String DOCPATH = "DOCPATH";
public static final String CONTENT_NAME = "contentName";
public static final String CONTENT_LINK = "contenLink";
public static final String IMAGE_PATH = "imagePath";
public static final String MIME_TYPE = "mimeType";
public static final String STATE = "state";
public static final String AUTHOR = "author";
public static final String DATE_CREATED = "dateCreated";
public static final String LAST_MODIFIED = "lastModified";
public static final String DOCUMENT_TYPE_LABEL= "docTypeLabel";
public static final String DOCUMENT_TITLE = "docTitle";
public static final String DOCUMENT_VERSION = "docVersion";
public static final String DOCUMENT_SUMMARY = "docSummary";
public static final String IS_SYMLINK = "isSymlink";
public String docLink;
public String message;
public String docName;
public String docPath;
public String repository;
public String workspace;
private DocumentService documentService;
public UIDocActivity() {
documentService = CommonsUtils.getService(DocumentService.class);
}
protected boolean isPreviewable() {
return getMimeType().endsWith(DOCUMENT_POSTFIX);
}
protected boolean isImageFile() {
return getMimeType().startsWith(IMAGE_PREFIX);
}
protected String getDocThumbnail(){
String portalContainerName = PortalContainer.getCurrentPortalContainerName();
String restContextName = PortalContainer.getRestContextName(portalContainerName);
return new StringBuffer().append("/").append(portalContainerName).
append("/").append(restContextName).
append("/thumbnailImage/big").
append("/").append(UIDocActivityComposer.REPOSITORY).
append("/").append(UIDocActivityComposer.WORKSPACE).
append(docPath).toString();
}
protected String getSize() {
double size = 0;
Node docNode = getDocNode();
try {
if (docNode.hasNode(Utils.JCR_CONTENT)) {
Node contentNode = docNode.getNode(Utils.JCR_CONTENT);
if (contentNode.hasProperty(Utils.JCR_DATA)) {
size = contentNode.getProperty(Utils.JCR_DATA).getLength();
}
return FileUtils.byteCountToDisplaySize((long)size);
}
} catch (PathNotFoundException e) {
return StringUtils.EMPTY;
} catch (ValueFormatException e) {
return StringUtils.EMPTY;
} catch (RepositoryException e) {
return StringUtils.EMPTY;
}
return StringUtils.EMPTY;
}
protected int getVersion() {
try {
VersionNode rootVersion_ = new VersionNode(NodeLocation.getNodeByLocation(new NodeLocation(repository, workspace, docPath))
.getVersionHistory().getRootVersion(), getDocNode().getSession());
if (rootVersion_ != null) {
return rootVersion_.getChildren().size();
}
} catch (Exception e) {
if(LOG.isDebugEnabled()) {
LOG.debug("cannot version node", e);
}
}
return 0;
}
protected String getCssClassIconFile(String fileName, String fileType) {
String cssClass = CssClassUtils.getCSSClassByFileNameAndFileType(fileName, fileType, CssClassManager.ICON_SIZE.ICON_64).replace("uiIcon", "uiBgd");
return cssClass;
}
protected boolean isDisplayThumbnail(String mimeType) {
if( mimeType.startsWith("application/pdf") ||
mimeType.startsWith("application/msword") ||
mimeType.startsWith("application/vnd.oasis.opendocument.text") ||
mimeType.startsWith("application/vnd.openxmlformats-officedocument.wordprocessingml.document") ||
mimeType.startsWith("application/rtf") ){
return true;
}
return false;
}
public String getDocOpenUri() {
String uri = "";
if(docPath != null) {
try {
uri = documentService.getLinkInDocumentsApp(docPath);
} catch(Exception e) {
LOG.error("Cannot get document open URI of node " + docPath + " : " + e.getMessage(), e);
uri = "";
}
}
return uri;
}
private boolean hasPermissionViewFile() {
return (getDocNode() != null);
}
public static class ViewDocumentActionListener extends EventListener<UIDocActivity> {
@Override
public void execute(Event<UIDocActivity> event) throws Exception {
final UIDocActivity docActivity = event.getSource();
if (! docActivity.hasPermissionViewFile()) {
WebuiRequestContext ctx = event.getRequestContext();
UIApplication uiApplication = ctx.getUIApplication();
uiApplication.addMessage(new ApplicationMessage("UIDocActivity.msg.noPermission", null, ApplicationMessage.WARNING));
return;
}
final UIActivitiesContainer activitiesContainer = docActivity.getAncestorOfType(UIActivitiesContainer.class);
final PopupContainer popupContainer = activitiesContainer.getPopupContainer();
if (docActivity.getChild(UIDocViewer.class) != null) {
docActivity.removeChild(UIDocViewer.class);
}
UIDocViewer docViewer = popupContainer.createUIComponent(UIDocViewer.class, null, "DocViewer");
docViewer.docPath = docActivity.docPath;
docViewer.repository = docActivity.repository;
docViewer.workspace = docActivity.workspace;
popupContainer.activate(docViewer, 800, 600, true);
event.getRequestContext().addUIComponentToUpdateByAjax(popupContainer);
}
}
public static class DownloadDocumentActionListener extends EventListener<UIDocActivity> {
@Override
public void execute(Event<UIDocActivity> event) throws Exception {
UIDocActivity uiComp = event.getSource() ;
if (! uiComp.hasPermissionViewFile()) {
WebuiRequestContext ctx = event.getRequestContext();
UIApplication uiApplication = ctx.getUIApplication();
uiApplication.addMessage(new ApplicationMessage("UIDocActivity.msg.noPermission", null, ApplicationMessage.WARNING));
return;
}
String downloadLink = null;
if (getRealNode(uiComp.getDocNode()).getPrimaryNodeType().getName().equals(Utils.NT_FILE)) {
downloadLink = Utils.getDownloadRestServiceLink(uiComp.getDocNode());
}
event.getRequestContext().getJavascriptManager().addJavascript("ajaxRedirect('" + downloadLink + "');");
}
private Node getRealNode(Node node) throws Exception {
// TODO: Need to add to check symlink node
if (node.isNodeType("nt:frozenNode")) {
String uuid = node.getProperty("jcr:frozenUuid").getString();
return node.getSession().getNodeByUUID(uuid);
}
return node;
}
}
protected Node getDocNode() {
NodeLocation nodeLocation = new NodeLocation(repository, workspace, docPath);
return NodeLocation.getNodeByLocation(nodeLocation);
}
/**
* Gets the webdav url.
*
* @return the webdav url
* @throws Exception the exception
*/
public String getWebdavURL() throws Exception {
Node contentNode = getDocNode();
NodeLocation nodeLocation = new NodeLocation(repository, workspace, docPath);
PortletRequestContext portletRequestContext = WebuiRequestContext.getCurrentInstance();
PortletRequest portletRequest = portletRequestContext.getRequest();
String repository = nodeLocation.getRepository();
String workspace = nodeLocation.getWorkspace();
String baseURI = portletRequest.getScheme() + "://" + portletRequest.getServerName() + ":"
+ String.format("%s", portletRequest.getServerPort());
FriendlyService friendlyService = WCMCoreUtils.getService(FriendlyService.class);
String link = "#";
String portalName = PortalContainer.getCurrentPortalContainerName();
String restContextName = PortalContainer.getCurrentRestContextName();
if (contentNode.isNodeType("nt:frozenNode")) {
String uuid = contentNode.getProperty("jcr:frozenUuid").getString();
Node originalNode = contentNode.getSession().getNodeByUUID(uuid);
link = baseURI + "/" + portalName + "/" + restContextName + "/jcr/" + repository + "/"
+ workspace + originalNode.getPath() + "?version=" + contentNode.getParent().getName();
} else {
link = baseURI + "/" + portalName + "/" + restContextName + "/jcr/" + repository + "/"
+ workspace + contentNode.getPath();
}
return friendlyService.getFriendlyUri(link);
}
/**
* Gets the summary.
*
* @return the summary of Node. Return empty string if catch an exception.
*/
public String getSummary() {
String desc = "";
Node node = getDocNode();
try {
if (node != null) {
if (node.hasProperty("exo:summary")) {
desc = node.getProperty("exo:summary").getValue().getString();
} else if (node.hasNode("jcr:content")) {
Node content = node.getNode("jcr:content");
if (content.hasProperty("dc:description") && content.getProperty("dc:description").getValues().length > 0) {
desc = content.getProperty("dc:description").getValues()[0].getString();
}
}
}
} catch (RepositoryException re) {
if (LOG.isWarnEnabled())
LOG.warn("RepositoryException: ", re);
}
return desc;
}
public String getTitle() throws Exception {
return Utils.getTitle(getDocNode());
}
/**
* get activity owner
*
* @return activity owner
*/
public static String getActivityOwnerId(Node node) {
String activityOwnerId = "";
ConversationState conversationState = ConversationState.getCurrent();
if (conversationState != null) {
activityOwnerId = conversationState.getIdentity().getUserId();
}else{
try {
activityOwnerId = node.getProperty("publication:lastUser").getString();
} catch (Exception e) {
LOG.info("No lastUser publication");
}
}
return activityOwnerId;
}
/**
* Gets the illustrative image.
*
* @param node the node
* @return the illustrative image
*/
public static String getIllustrativeImage(Node node) {
WebSchemaConfigService schemaConfigService = WCMCoreUtils.getService(WebSchemaConfigService.class);
WebContentSchemaHandler contentSchemaHandler = schemaConfigService.getWebSchemaHandlerByType(WebContentSchemaHandler.class);
Node illustrativeImage = null;
String uri = "";
try {
illustrativeImage = contentSchemaHandler.getIllustrationImage(node);
uri = generateThumbnailImageURI(illustrativeImage);
} catch (PathNotFoundException ex) {
return uri;
} catch (Exception e) { // WebContentSchemaHandler
LOG.warn(e.getMessage(), e);
}
return uri;
}
/**
* Generate the Thumbnail Image URI.
*
* @param file the node
* @return the Thumbnail uri with medium size
* @throws Exception the exception
*/
public static String generateThumbnailImageURI(Node file) throws Exception {
StringBuilder builder = new StringBuilder();
NodeLocation fielLocation = NodeLocation.getNodeLocationByNode(file);
String repository = fielLocation.getRepository();
String workspaceName = fielLocation.getWorkspace();
String nodeIdentifiler = file.getPath().replaceFirst("/", "");
String portalName = PortalContainer.getCurrentPortalContainerName();
String restContextName = PortalContainer.getCurrentRestContextName();
InputStream stream = file.getNode(NodetypeConstant.JCR_CONTENT)
.getProperty(NodetypeConstant.JCR_DATA)
.getStream();
if (stream.available() == 0)
return null;
stream.close();
builder.append("/")
.append(portalName)
.append("/")
.append(restContextName)
.append("/")
.append("thumbnailImage/medium/")
.append(repository)
.append("/")
.append(workspaceName)
.append("/")
.append(nodeIdentifiler);
return builder.toString();
}
/**
* Generate the viewer link to site explorer by node
*
* @param node the node
* @return String the viewer link
* @throws RepositoryException
*/
public static String getContentLink(Node node) throws Exception {
DocumentService documentService = CommonsUtils.getService(DocumentService.class);
return documentService.getLinkInDocumentsApp(node.getPath());
}
/**
* Get the MimeType
*
* @param node the node
* @return the MimeType
*/
public static String getMimeType(Node node) {
try {
if (node.getPrimaryNodeType().getName().equals(NodetypeConstant.NT_FILE)) {
if (node.hasNode(NodetypeConstant.JCR_CONTENT))
return node.getNode(NodetypeConstant.JCR_CONTENT)
.getProperty(NodetypeConstant.JCR_MIME_TYPE)
.getString();
}
} catch (RepositoryException e) {
LOG.error(e.getMessage(), e);
}
return "";
}
private String getMimeType() {
String mimeType = "";
try {
mimeType = getDocNode().getNode("jcr:content").getProperty("jcr:mimeType").getString();
} catch (ValueFormatException e) {
if (LOG.isDebugEnabled())
LOG.debug(e);
return StringUtils.EMPTY;
} catch (PathNotFoundException e) {
if (LOG.isDebugEnabled())
LOG.debug(e);
return StringUtils.EMPTY;
} catch (RepositoryException e) {
if (LOG.isDebugEnabled())
LOG.debug(e);
return StringUtils.EMPTY;
}
return mimeType;
}
}