package fr.itldev.koya.alfservice;
import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.activities.ActivityType;
import org.alfresco.repo.model.filefolder.HiddenAspect;
import org.alfresco.repo.webdav.WebDAVServerException;
import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.service.cmr.invitation.Invitation;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileFolderServiceType;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.model.FileNotFoundException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.PropertyCheck;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.InitializingBean;
import fr.itldev.koya.alfservice.security.CompanyAclService;
import fr.itldev.koya.exception.KoyaServiceException;
import fr.itldev.koya.model.KoyaActivityType;
import fr.itldev.koya.model.impl.Company;
import fr.itldev.koya.model.impl.Document;
import fr.itldev.koya.model.impl.Dossier;
import fr.itldev.koya.model.impl.Space;
import fr.itldev.koya.model.impl.User;
public class KoyaActivityPoster implements InitializingBean {
public static final char PathSeperatorChar = '/';
private static Log logger = LogFactory.getLog(KoyaActivityPoster.class);
private ActivityService activityService;
private SiteService siteService;
private NodeService nodeService;
private FileFolderService fileFolderService;
private HiddenAspect hiddenAspect;
private KoyaNodeService koyaNodeService;
private UserService userService;
private CompanyAclService companyAclService;
public KoyaActivityPoster() {
}
public void setHiddenAspect(HiddenAspect hiddenAspect) {
this.hiddenAspect = hiddenAspect;
}
public void setFileFolderService(FileFolderService fileFolderService) {
this.fileFolderService = fileFolderService;
}
public void setSiteService(SiteService siteService) {
this.siteService = siteService;
}
public void setNodeService(NodeService nodeService) {
this.nodeService = nodeService;
}
public void setActivityService(ActivityService activityService) {
this.activityService = activityService;
}
public void setKoyaNodeService(KoyaNodeService koyaNodeService) {
this.koyaNodeService = koyaNodeService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public void setCompanyAclService(CompanyAclService companyAclService) {
this.companyAclService = companyAclService;
}
public void afterPropertiesSet() throws Exception {
PropertyCheck.mandatory(this, "activityService", activityService);
PropertyCheck.mandatory(this, "siteService", siteService);
PropertyCheck.mandatory(this, "nodeService", nodeService);
PropertyCheck.mandatory(this, "fileFolderService", fileFolderService);
PropertyCheck.mandatory(this, "koyaNodeService", koyaNodeService);
PropertyCheck.mandatory(this, "userService", userService);
PropertyCheck.mandatory(this, "companyAclService", companyAclService);
}
public void postSpaceShared(User invitee, String inviterUserName, Space sharedSpace) {
try {
if (invitee != null && invitee.isEnabled() != null && invitee.isEnabled()) {
// TODO test if user still exists : treat invitation deletion
// case
String siteShortName = siteService.getSiteShortName(sharedSpace.getNodeRef());
List<Invitation> invitations = companyAclService.getPendingInvite(siteShortName,
null, invitee.getUserName());
if (invitations.isEmpty()) {
activityService.postActivity(KoyaActivityType.KOYA_SPACESHARED, siteShortName,
KoyaActivityType.KOYA_APPTOOL,
getShareActivityData(invitee, inviterUserName, sharedSpace),
invitee.getUserName());
}
}
} catch (KoyaServiceException ex) {
logger.error(ex.getMessage(), ex);
}
}
public void postSpaceUnshared(String revokedinviteeEmail, String revokerUserName,
Space unsharedSpace) {
try {
User user = userService.getUserByEmail(revokedinviteeEmail);
if (user.isEnabled() != null && user.isEnabled()) {
// TODO test if user still exists : treat invitation deletion
// case
String siteShortName = siteService.getSiteShortName(unsharedSpace.getNodeRef());
List<Invitation> invitations = companyAclService.getPendingInvite(siteShortName,
null, user.getUserName());
if (invitations.isEmpty()) {
// TODO call action
// Posting the according activity
activityService.postActivity(KoyaActivityType.KOYA_SPACEUNUNSHARED,
siteShortName, KoyaActivityType.KOYA_APPTOOL,
getShareActivityData(user, revokerUserName, unsharedSpace),
user.getUserName());
}
}
} catch (KoyaServiceException ex) {
logger.error(ex.getMessage(), ex);
}
}
public void postFileFolderAdded(NodeRef nodeRef) {
if (!hiddenAspect.hasHiddenAspect(nodeRef)) {
SiteInfo siteInfo = siteService.getSite(nodeRef);
String siteId = (siteInfo != null ? siteInfo.getShortName() : null);
if (siteId != null && !siteId.equals("")) {
// post only for nodes within sites
NodeRef parentNodeRef = nodeService.getPrimaryParent(nodeRef).getParentRef();
String path = null;
boolean isFolder = isFolder(nodeRef);
String name = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
if (isFolder) {
NodeRef documentLibrary = siteService.getContainer(siteId,
SiteService.DOCUMENT_LIBRARY);
path = "/";
try {
path = getPathFromNode(documentLibrary, nodeRef);
} catch (FileNotFoundException error) {
if (logger.isDebugEnabled()) {
logger.debug(
"No " + SiteService.DOCUMENT_LIBRARY + " container found.");
}
}
}
Company c = null;
Dossier d = null;
try {
c = koyaNodeService.getFirstParentOfType(nodeRef, Company.class);
} catch (KoyaServiceException kse) {
}
try {
d = koyaNodeService.getFirstParentOfType(nodeRef, Dossier.class);
} catch (KoyaServiceException kse) {
}
postFileFolderActivity(
(isFolder ? ActivityType.FOLDER_ADDED : ActivityType.FILE_ADDED), path,
parentNodeRef, nodeRef, siteId, name, c, d);
}
}
}
public void postFileFolderUpdated(boolean isFolder, NodeRef nodeRef) {
if (!hiddenAspect.hasHiddenAspect(nodeRef)) {
SiteInfo siteInfo = siteService.getSite(nodeRef);
String siteId = (siteInfo != null ? siteInfo.getShortName() : null);
if (siteId != null && !siteId.equals("")) {
// post only for nodes within sites
String fileName = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
Company c = null;
Dossier d = null;
try {
c = koyaNodeService.getFirstParentOfType(nodeRef, Company.class);
} catch (KoyaServiceException kse) {
}
try {
d = koyaNodeService.getFirstParentOfType(nodeRef, Dossier.class);
} catch (KoyaServiceException kse) {
}
// add new event folder-updated
postFileFolderActivity(
isFolder ? "org.alfresco.documentlibrary.folder-updated"
: ActivityType.FILE_UPDATED,
null, null, nodeRef, siteId, fileName, c, d);
}
}
}
public void postFileFolderDeleted(KoyaActivityInfo activityInfo) {
if (activityInfo.getSiteId() != null) {
// post only for nodes within sites
postFileFolderActivity(
(activityInfo.isFolder() ? ActivityType.FOLDER_DELETED
: ActivityType.FILE_DELETED),
activityInfo.getParentPath(), activityInfo.getParentNodeRef(),
activityInfo.getNodeRef(), activityInfo.getSiteId(), activityInfo.getFileName(),
activityInfo.getParentCompany(), activityInfo.getParentDossier());
}
}
public void postDlFileAvailable(KoyaActivityInfo activityInfo,String fileName) {
activityService.postActivity(KoyaActivityType.KOYA_DLFILEAVAILABLE,
activityInfo.getSiteId(), KoyaActivityType.KOYA_APPTOOL,
"{'fileName':'" + fileName + "', 'nodeRef' : '"
+ activityInfo.getNodeRef() + "'}");
}
public void postConsumerUpload(Document document,Dossier dossier, User uploader) {
KoyaActivityInfo activityInfo = getActivityInfo(document.getNodeRef());
activityService.postActivity(KoyaActivityType.KOYA_CONSUMERUPLOAD, activityInfo.getSiteId(),
KoyaActivityType.KOYA_APPTOOL,
"{'fileName':'" + document.getName() + "', 'nodeRef' : '" + document.getNodeRef() +
"', 'spaceNodeRef' : '" + dossier.getNodeRef() +"'}");
}
public KoyaActivityInfo getActivityInfo(NodeRef nodeRef) {
SiteInfo siteInfo = siteService.getSite(nodeRef);
String siteId = (siteInfo != null ? siteInfo.getShortName() : null);
if (siteId != null && !siteId.equals("")) {
NodeRef parentNodeRef = nodeService.getPrimaryParent(nodeRef).getParentRef();
FileInfo fileInfo = fileFolderService.getFileInfo(nodeRef);
String name = fileInfo.getName();
boolean isFolder = fileInfo.isFolder();
NodeRef documentLibrary = siteService.getContainer(siteId,
SiteService.DOCUMENT_LIBRARY);
String parentPath = "/";
try {
parentPath = getPathFromNode(documentLibrary, parentNodeRef);
} catch (FileNotFoundException error) {
if (logger.isDebugEnabled()) {
logger.debug("No " + SiteService.DOCUMENT_LIBRARY + " container found.");
}
}
Company c = null;
try {
c = koyaNodeService.getFirstParentOfType(nodeRef, Company.class);
} catch (KoyaServiceException kse) {
}
Dossier d = null;
try {
d = koyaNodeService.getFirstParentOfType(nodeRef, Dossier.class);
} catch (KoyaServiceException kse) {
}
return new KoyaActivityInfo(nodeRef, parentPath, parentNodeRef, siteId, name, isFolder,
c, d);
} else {
return null;
}
}
/*
* ===== Private Utils ======
*/
private void postFileFolderActivity(String activityType, String path, NodeRef parentNodeRef,
NodeRef nodeRef, String siteId, String name, Company parentCompany,
Dossier parentDossier) {
JSONObject json = createActivityJSON(path, parentNodeRef, nodeRef, name, parentCompany,
parentDossier);
activityService.postActivity(activityType, siteId, KoyaActivityType.KOYA_APPTOOL,
json.toString());
}
/**
* Create JSON suitable for create, modify or delete activity posts. Returns
* a new JSONObject containing appropriate key/value pairs.
*
* @param tenantDomain
* @param nodeRef
* @param fileName
* @throws WebDAVServerException
* @return JSONObject
*/
private JSONObject createActivityJSON(String path, NodeRef parentNodeRef, NodeRef nodeRef,
String fileName, Company parentCompany, Dossier parentDossier) {
JSONObject json = new JSONObject();
try {
json.put("nodeRef", nodeRef);
if (parentNodeRef != null) {
// Used for deleted files.
json.put("parentNodeRef", parentNodeRef);
}
if (path != null) {
// Used for deleted files and folders (added or deleted)
json.put("page", "documentlibrary?path=" + path);
} else {
// Used for added or modified files.
json.put("page", "document-details?nodeRef=" + nodeRef);
}
json.put("title", fileName);
if (parentCompany != null) {
json.put("koyaParentCompanyNodeRef", parentCompany.getNodeRef().toString());
json.put("koyaParentCompanyTitle", parentCompany.getTitle());
}
if (parentDossier != null) {
json.put("koyaParentDossierNodeRef", parentDossier.getNodeRef().toString());
json.put("koyaParentDossierTitle", parentDossier.getTitle());
}
} catch (JSONException error) {
throw new AlfrescoRuntimeException("", error);
}
return json;
}
protected String getShareActivityData(User invitee, String inviter, Space space)
throws KoyaServiceException {
try {
JSONObject activityData = new JSONObject();
activityData.put("email", invitee.getEmail());
activityData.put("spaceTitle", space.getTitle());
activityData.put("spaceNodeRef", space.getNodeRef());
activityData.put("inviter", inviter);
return activityData.toString();
} catch (JSONException jsonEx) {
throw new KoyaServiceException(0);// TODO define error code
}
}
private boolean isFolder(NodeRef nodeRef) {
QName typeQName = nodeService.getType(nodeRef);
FileFolderServiceType type = fileFolderService.getType(typeQName);
boolean isFolder = type.equals(FileFolderServiceType.FOLDER);
return isFolder;
}
private final String getPathFromNode(NodeRef rootNodeRef, NodeRef nodeRef)
throws FileNotFoundException {
// Check if the nodes are valid, or equal
if (rootNodeRef == null || nodeRef == null)
throw new IllegalArgumentException("Invalid node(s) in getPathFromNode call");
// short cut if the path node is the root node
if (rootNodeRef.equals(nodeRef))
return "";
// get the path elements
List<FileInfo> pathInfos = fileFolderService.getNamePath(rootNodeRef, nodeRef);
// build the path string
StringBuilder sb = new StringBuilder(pathInfos.size() * 20);
for (FileInfo fileInfo : pathInfos) {
sb.append(PathSeperatorChar);
sb.append(fileInfo.getName());
}
// done
if (logger.isDebugEnabled()) {
logger.debug("Build name path for node: \n" + " root: " + rootNodeRef + "\n"
+ " target: " + nodeRef + "\n" + " path: " + sb);
}
return sb.toString();
}
public static class KoyaActivityInfo {
private NodeRef nodeRef;
private String parentPath;
private NodeRef parentNodeRef;
private String siteId;
private String fileName;
private boolean isFolder;
private Company parentCompany;
private Dossier parentDossier;
public KoyaActivityInfo(NodeRef nodeRef, String parentPath, NodeRef parentNodeRef,
String siteId, String fileName, boolean isFolder, Company parentCompany,
Dossier parentDossier) {
super();
this.nodeRef = nodeRef;
this.parentPath = parentPath;
this.parentNodeRef = parentNodeRef;
this.siteId = siteId;
this.fileName = fileName;
this.isFolder = isFolder;
this.parentCompany = parentCompany;
this.parentDossier = parentDossier;
}
public NodeRef getNodeRef() {
return nodeRef;
}
public String getParentPath() {
return parentPath;
}
public NodeRef getParentNodeRef() {
return parentNodeRef;
}
public String getSiteId() {
return siteId;
}
public String getFileName() {
return fileName;
}
public boolean isFolder() {
return isFolder;
}
public Company getParentCompany() {
return parentCompany;
}
public Dossier getParentDossier() {
return parentDossier;
}
}
}