All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.day.cq.mcm.core.NewsletterHelper Maven / Gradle / Ivy

/*
 * Copyright 1997-2010 Day Management AG
 * Barfuesserplatz 6, 4001 Basel, Switzerland
 * All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * Day Management AG, ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Day.
 */
package com.day.cq.mcm.core;

import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.DamConstants;
import com.day.cq.dam.commons.util.AssetReferenceSearch;
import com.day.cq.mcm.api.newsletter.NewsLetter;
import com.day.cq.mcm.api.newsletter.NewsletterEmailService;
import com.day.cq.replication.ReplicationStatus;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import org.apache.commons.lang.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.request.RequestParameterMap;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;


/**
 *Tool for UI to build, test and send Newsletters.
 *
 */
public class NewsletterHelper {

    /** Parameter Name for the Path to a newsletter*/
    public static final String PARAM_NEWSLETTER = "newsletter";

    /** Parameter Name for the MailingList the Newsletter should be sent to*/
    public static final String PARAM_RECIPIENTS = "letterRecipient";

    /** Parameter Name for the an User-ID used to send a Newsletter for testing*/
    public static final String PARAM_TEST_TO = "testRecipient";

    /** Parameter Name for the an User-ID used to personlize a Newsletter for testing*/
    public static final String PARAM_TEST_PROFILE = "testProfile";


    /**
     * Reads the request parameter and tries to build a Newsletter from.
     * A path and a Resource given by {@link #PARAM_NEWSLETTER}, falls back to
     * the {@link org.apache.sling.api.SlingHttpServletRequest#getResource() Request's Resource}
     * Helper tries to access a {@link com.day.cq.wcm.api.Page Page}
     * if the Resource found {@link PageManager#getContainingPage(Resource) is part of a Page}
     * Subject and from are set, if present in Request
     *
     * @param request to access parameter from
     * @param service to build Newsletter with
     * @return the letter or null if could not be build.
     * @throws RepositoryException in case of error accessing the Repository
     */
    public static NewsLetter fromRequest(SlingHttpServletRequest request,
                                         NewsletterEmailService service) throws RepositoryException {

        RequestParameterMap map = request.getRequestParameterMap();
        Resource resource;
        String path = getParameter(map, PARAM_NEWSLETTER);
        if (path != null) {
            resource = request.getResourceResolver().resolve(path);
        } else {
            resource = request.getResource();
        }
        NewsLetter news =  null;
        PageManager pmgr = request.getResourceResolver().adaptTo(PageManager.class);
        if (pmgr!=null) {
            Page page = pmgr.getContainingPage(resource);
            if (page!=null) {
                news = service.buildNewsletter(page);
                resource = page.adaptTo(Resource.class);
            }
        }
        // resource was not a page or host could not be found try request host
        if (news == null) {
            URI uri = null;
            try {
                uri = new URI(request.getScheme(),
                        null,
                        request.getServerName(),
                        request.getServerPort(),
                        request.getContextPath() + resource.getPath(),
                        null,
                        null);
            } catch (URISyntaxException ignore) {
            } //cant happen
            news = service.buildNewsletter(resource, uri);
        }
        return news;
    }

    /**
     * Collect the Resources referenced by the Newsletter and the Newsletters
     * Resource and check if they have been modified since last publish or if
     * they are not published at all
     *
     * @param letter to inspect
     * @param resolver to use for access to the Resources
     * @return all Resources that are outdated
     * @throws RepositoryException in case of error accessing the Repository
     */
    public static Collection getUnpublishedResources(NewsLetter letter,
                                                               ResourceResolver resolver) throws RepositoryException {

        HashSet set = new HashSet();
        Resource resource = resolver.getResource(letter.getPath());
        if (resource != null) {
            Calendar lastMod;
            Page page = resource.adaptTo(Page.class);
            if (page!=null) {
                lastMod = page.getLastModified();
            } else {
                ValueMap map = resource.adaptTo(ValueMap.class);
                lastMod = map.get(JcrConstants.JCR_LASTMODIFIED, Calendar.class);

            }
            if (lastMod!=null &&
                    needsReplication(resource,lastMod.getTimeInMillis())) {
                set.add(resource);
            }
            addPublishAssets(resource.adaptTo(Node.class), resolver, set);
        }
        return Collections.unmodifiableSet(set);
    }
	/**
	 * Checks that no outdated resources, see {@link #getUnpublishedResources(NewsLetter, ResourceResolver) getUnpublishedResources}, are referenced by the NewsLetter and
	 * that the Newsletter is 'delivered' (see {@link ReplicationStatus#isDelivered() ReplicationStatus}).
	 * 
	 * @param letter to inspect
	 * @param resolver to use for access to the Resources
	 * @return true if no resources are outdated and letter is 'delivered'. Otherwise and in case of exception false. 
	 * @throws RepositoryException in case of error accessing the Repository
	 */
    public static boolean isPublishUptodate(NewsLetter letter, ResourceResolver resolver) {
    	try{
	    	boolean unPublishedResources = getUnpublishedResources(letter, resolver).size()>0;
	        Resource resource = resolver.resolve(letter.getPath());
	        ReplicationStatus status = resource.adaptTo(ReplicationStatus.class);
	        boolean delivered = status != null && status.isDelivered();
	        return !unPublishedResources && delivered;
        }catch(RepositoryException e){
        	return false;
        }
    }
    /**
     * Utility to trim existing Parameter Values
     * @param map to access
     * @param key to return
     * @return the trimmed value or null
     */
    public static String getParameter(RequestParameterMap map, String key) {
        if (map.containsKey(key)) {
            String val = map.getValue(key).getString();
            if (!StringUtils.isBlank(val)) {
                return val.trim();
            }
        }
        return null;
    }

    //------------------------------------------------< helper >----------------
    private static HashSet addPublishAssets(Node node,
                                                      ResourceResolver resolver,
                                                      HashSet set) throws RepositoryException {

        AssetReferenceSearch search = new AssetReferenceSearch(node,
                DamConstants.MOUNTPOINT_ASSETS,
                resolver);
        Map refs = search.search();
        for (Asset asset : refs.values()) {
            final Resource resource = asset.adaptTo(Resource.class);
            if (resource != null
                    && needsReplication(resource, asset.getLastModified())) {
                set.add(resource);
            }
        }
        return set;
    }

    private static boolean needsReplication(Resource resource, long lastModTimestamp) {
        ReplicationStatus replStatus = resource.adaptTo(ReplicationStatus.class);
        if (replStatus != null) {
            boolean needsReplication = !(replStatus.isDelivered() && replStatus.isActivated());
            return needsReplication || replStatus.getLastPublished().getTimeInMillis() < lastModTimestamp;
        }
        return false;
    }


}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy