Search in sources :

Example 1 with ISO8601DateFormatMethod

use of org.alfresco.repo.template.ISO8601DateFormatMethod in project alfresco-repository by Alfresco.

the class FeedTaskProcessor method process.

public void process(int jobTaskNode, long minSeq, long maxSeq, RepoCtx ctx) throws Exception {
    long startTime = System.currentTimeMillis();
    if (logger.isDebugEnabled()) {
        logger.debug("Process: jobTaskNode '" + jobTaskNode + "' from seq '" + minSeq + "' to seq '" + maxSeq + "' on this node from grid job.");
    }
    ActivityPostEntity selector = new ActivityPostEntity();
    selector.setJobTaskNode(jobTaskNode);
    selector.setMinId(minSeq);
    selector.setMaxId(maxSeq);
    selector.setStatus(ActivityPostEntity.STATUS.POSTED.toString());
    List<ActivityPostEntity> activityPosts = null;
    int totalGenerated = 0;
    try {
        activityPosts = selectPosts(selector);
        if (logger.isDebugEnabled()) {
            logger.debug("Process: " + activityPosts.size() + " activity posts");
        }
        // local caches for this run of activity posts
        // site -> site members
        Map<String, Set<String>> siteConnectedUsers = new HashMap<String, Set<String>>();
        // user -> followers
        Map<Pair<String, String>, Set<String>> followerConnectedUsers = new HashMap<Pair<String, String>, Set<String>>();
        // <user, site> -> true/false (note: used when following, implied as true for site members)
        Map<Pair<String, String>, Boolean> canUserReadSite = new HashMap<Pair<String, String>, Boolean>();
        Map<String, List<FeedControlEntity>> userFeedControls = new HashMap<String, List<FeedControlEntity>>();
        List<String> fmTemplates = Arrays.asList(new String[] { "activities/org/alfresco/generic.json.ftl" });
        // for each activity post ...
        for (ActivityPostEntity activityPost : activityPosts) {
            String postingUserId = activityPost.getUserId();
            String activityType = activityPost.getActivityType();
            if (fmTemplates.size() == 0) {
                logger.error("Skipping activity post " + activityPost.getId() + " since no specific/generic templates for activityType: " + activityType);
                updatePostStatus(activityPost.getId(), ActivityPostEntity.STATUS.ERROR);
                continue;
            }
            Map<String, Object> model = null;
            try {
                model = JSONtoFmModel.convertJSONObjectToMap(activityPost.getActivityData());
            } catch (JSONException je) {
                logger.error("Skipping activity post " + activityPost.getId() + " due to invalid activity data: ", je);
                updatePostStatus(activityPost.getId(), ActivityPostEntity.STATUS.ERROR);
                continue;
            }
            String nodeRefStr = (String) model.get(PostLookup.JSON_NODEREF);
            try {
                // If a nodeRef is present, then it must be valid.
                if (nodeRefStr != null) {
                    // Attempt to create a nodeRef, making use of the constructor's validation.
                    new NodeRef(nodeRefStr);
                }
            } catch (Exception e) {
                logger.error("Skipping activity post " + activityPost.getId() + " due to invalid nodeRef: " + nodeRefStr);
                updatePostStatus(activityPost.getId(), ActivityPostEntity.STATUS.ERROR);
                continue;
            }
            // note: for MT share, site id should already be mangled - in addition to extra tenant domain info
            String thisSite = activityPost.getSiteNetwork();
            String tenantDomain = (String) model.get(PostLookup.JSON_TENANT_DOMAIN);
            if (thisSite != null) {
                if (tenantDomain != null) {
                    thisSite = getTenantName(thisSite, tenantDomain);
                } else {
                    // for backwards compatibility
                    tenantDomain = getTenantDomain(thisSite);
                }
            }
            if (tenantDomain == null) {
                tenantDomain = TenantService.DEFAULT_DOMAIN;
            }
            model.put(ActivityFeedEntity.KEY_ACTIVITY_FEED_TYPE, activityPost.getActivityType());
            model.put(ActivityFeedEntity.KEY_ACTIVITY_FEED_SITE, thisSite);
            model.put("userId", activityPost.getUserId());
            model.put("id", activityPost.getId());
            // post date rather than time that feed is generated
            model.put("date", activityPost.getPostDate());
            model.put("xmldate", new ISO8601DateFormatMethod());
            model.put("repoEndPoint", ctx.getRepoEndPoint());
            // Get recipients of this post
            Set<String> recipients = null;
            try {
                recipients = getRecipients(ctx, thisSite, activityPost.getUserId(), tenantDomain, siteConnectedUsers, followerConnectedUsers, canUserReadSite);
            } catch (Exception e) {
                logger.error("Skipping activity post " + activityPost.getId() + " since failed to get recipients: ", e);
                updatePostStatus(activityPost.getId(), ActivityPostEntity.STATUS.ERROR);
                continue;
            }
            try {
                startTransaction();
                if (logger.isTraceEnabled()) {
                    logger.trace("Process: " + recipients.size() + " candidate connections for activity post " + activityPost.getId());
                }
                int excludedConnections = 0;
                for (String recipient : recipients) {
                    List<FeedControlEntity> feedControls = null;
                    if (!recipient.equals("")) {
                        // Get user's feed controls
                        feedControls = userFeedControls.get(recipient);
                        if (feedControls == null) {
                            feedControls = getFeedControls(recipient);
                            userFeedControls.put(recipient, feedControls);
                        }
                    }
                    // filter based on opt-out feed controls (if any)
                    if (!acceptActivity(activityPost, feedControls)) {
                        excludedConnections++;
                    } else {
                        // node read permission check (if nodeRef is present)
                        if (!canRead(ctx, recipient, model)) {
                            excludedConnections++;
                            continue;
                        }
                        for (String fmTemplate : fmTemplates) {
                            String formatFound = FeedTaskProcessor.FEED_FORMAT_JSON;
                            ActivityFeedEntity feed = new ActivityFeedEntity();
                            // MNT-9104 If username contains uppercase letters the action of joining a site will not be displayed in "My activities"
                            if (!userNamesAreCaseSensitive) {
                                recipient = recipient.toLowerCase();
                                postingUserId = postingUserId.toLowerCase();
                            }
                            feed.setFeedUserId(recipient);
                            feed.setPostUserId(postingUserId);
                            feed.setActivityType(activityType);
                            String activitySummary = null;
                            // allows JSON to simply pass straight through
                            activitySummary = activityPost.getActivityData();
                            if (!activitySummary.equals("")) {
                                if (activitySummary.length() > ActivityFeedDAO.MAX_LEN_ACTIVITY_SUMMARY) {
                                    logger.warn("Skip feed entry (activity post " + activityPost.getId() + ") since activity summary - exceeds " + ActivityFeedDAO.MAX_LEN_ACTIVITY_SUMMARY + " chars: " + activitySummary);
                                } else {
                                    feed.setActivitySummary(activitySummary);
                                    feed.setSiteNetwork(thisSite);
                                    feed.setAppTool(activityPost.getAppTool());
                                    feed.setPostDate(activityPost.getPostDate());
                                    feed.setPostId(activityPost.getId());
                                    feed.setFeedDate(new Date());
                                    // Insert activity feed
                                    // ignore returned feedId
                                    insertFeedEntry(feed);
                                    totalGenerated++;
                                }
                            } else {
                                if (logger.isDebugEnabled()) {
                                    logger.debug("Empty template result for activityType '" + activityType + "' using format '" + formatFound + "' hence skip feed entry (activity post " + activityPost.getId() + ")");
                                }
                            }
                        }
                    }
                }
                updatePostStatus(activityPost.getId(), ActivityPostEntity.STATUS.PROCESSED);
                commitTransaction();
                if (logger.isDebugEnabled()) {
                    logger.debug("Processed: " + (recipients.size() - excludedConnections) + " connections for activity post " + activityPost.getId() + " (excluded " + excludedConnections + ")");
                }
            } finally {
                endTransaction();
            }
        }
    } catch (SQLException se) {
        logger.error(se);
        throw se;
    } finally {
        int postCnt = activityPosts == null ? 0 : activityPosts.size();
        // TODO i18n info message
        StringBuilder sb = new StringBuilder();
        sb.append("Generated ").append(totalGenerated).append(" activity feed entr").append(totalGenerated == 1 ? "y" : "ies");
        sb.append(" for ").append(postCnt).append(" activity post").append(postCnt != 1 ? "s" : "").append(" (in ").append(System.currentTimeMillis() - startTime).append(" msecs)");
        logger.info(sb.toString());
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) SQLException(java.sql.SQLException) ActivityPostEntity(org.alfresco.repo.domain.activities.ActivityPostEntity) ActivityFeedEntity(org.alfresco.repo.domain.activities.ActivityFeedEntity) NodeRef(org.alfresco.service.cmr.repository.NodeRef) FeedControlEntity(org.alfresco.repo.domain.activities.FeedControlEntity) ArrayList(java.util.ArrayList) List(java.util.List) Pair(org.alfresco.util.Pair) JSONException(org.json.JSONException) ISO8601DateFormatMethod(org.alfresco.repo.template.ISO8601DateFormatMethod) URISyntaxException(java.net.URISyntaxException) TemplateException(freemarker.template.TemplateException) SQLException(java.sql.SQLException) JSONException(org.json.JSONException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) Date(java.util.Date) JSONObject(org.json.JSONObject)

Aggregations

TemplateException (freemarker.template.TemplateException)1 FileNotFoundException (java.io.FileNotFoundException)1 IOException (java.io.IOException)1 MalformedURLException (java.net.MalformedURLException)1 URISyntaxException (java.net.URISyntaxException)1 SQLException (java.sql.SQLException)1 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 List (java.util.List)1 Set (java.util.Set)1 ActivityFeedEntity (org.alfresco.repo.domain.activities.ActivityFeedEntity)1 ActivityPostEntity (org.alfresco.repo.domain.activities.ActivityPostEntity)1 FeedControlEntity (org.alfresco.repo.domain.activities.FeedControlEntity)1 ISO8601DateFormatMethod (org.alfresco.repo.template.ISO8601DateFormatMethod)1 NodeRef (org.alfresco.service.cmr.repository.NodeRef)1 Pair (org.alfresco.util.Pair)1 JSONException (org.json.JSONException)1 JSONObject (org.json.JSONObject)1