NewsletterManagerImpl.java 14.3 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.wcm.api.Page
 *  javax.jcr.Node
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.Workspace
 *  javax.jcr.lock.Lock
 *  javax.jcr.lock.LockManager
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.resource.ModifiableValueMap
 *  org.apache.sling.api.resource.PersistenceException
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ResourceUtil
 *  org.apache.sling.api.resource.ValueMap
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.mcm.campaign.impl;

import com.adobe.cq.mcm.campaign.NewsletterException;
import com.adobe.cq.mcm.campaign.NewsletterManager;
import com.adobe.cq.mcm.campaign.Publisher;
import com.adobe.cq.mcm.campaign.impl.Util;
import com.day.cq.wcm.api.Page;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.UUID;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Workspace;
import javax.jcr.lock.Lock;
import javax.jcr.lock.LockManager;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.ModifiableValueMap;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(metatype=0)
@Service
public class NewsletterManagerImpl
implements NewsletterManager {
    private final Logger log;
    private final String[] EMPTY_STRING_ARRAY;
    @Reference
    protected Publisher publisher;

    public NewsletterManagerImpl() {
        this.log = LoggerFactory.getLogger(this.getClass());
        this.EMPTY_STRING_ARRAY = new String[0];
    }

    private void check(Page newsletter) throws NewsletterException {
        if (!this.isNewsletter(newsletter)) {
            throw new NewsletterException("Page " + newsletter.getPath() + " is not a newsletter");
        }
    }

    @Override
    public boolean isNewsletter(Page page) {
        Resource content;
        Resource resource = content = page != null ? page.getContentResource() : null;
        if (content == null) {
            return false;
        }
        return Util.isNewsletterType(content);
    }

    @Override
    public boolean isLinked(Page newsletter, String deliveryId) throws NewsletterException {
        this.check(newsletter);
        ValueMap properties = (ValueMap)newsletter.getContentResource().adaptTo(ValueMap.class);
        String[] deliveriesArray = (String[])properties.get("cq:acLinks", (Object)new String[0]);
        LinkedHashSet<String> deliveriesSet = new LinkedHashSet<String>(Arrays.asList(deliveriesArray));
        return deliveriesSet.contains(deliveryId);
    }

    @Override
    public String[] getLinkedDeliveries(Page newsletter) throws NewsletterException {
        this.check(newsletter);
        Resource resource = newsletter.getContentResource();
        ValueMap values = ResourceUtil.getValueMap((Resource)resource);
        String[] links = (String[])values.get("cq:acLinks", String[].class);
        if (links == null) {
            links = this.EMPTY_STRING_ARRAY;
        }
        return links;
    }

    @Override
    public String link(Page newsletter, String deliveryId) throws NewsletterException, PersistenceException {
        String uuid;
        this.check(newsletter);
        Resource content = newsletter.getContentResource();
        ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
        if (!this.isLinked(newsletter, deliveryId)) {
            String[] deliveriesArray = (String[])properties.get("cq:acLinks", (Object)new String[0]);
            LinkedHashSet<String> deliveriesSet = new LinkedHashSet<String>(Arrays.asList(deliveriesArray));
            deliveriesSet.add(deliveryId);
            deliveriesArray = deliveriesSet.toArray(new String[0]);
            properties.put((Object)"cq:acLinks", (Object)deliveriesArray);
        }
        if ((uuid = (String)properties.get("cq:acUUID", (Object)null)) == null) {
            uuid = UUID.randomUUID().toString();
            properties.put((Object)"cq:acUUID", (Object)uuid);
        }
        content.getResourceResolver().commit();
        return uuid;
    }

    @Override
    public void unlink(Page newsletter, String deliveryId) throws NewsletterException, PersistenceException {
        this.check(newsletter);
        Resource content = newsletter.getContentResource();
        if (!this.isLinked(newsletter, deliveryId)) {
            return;
        }
        ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
        if (deliveryId.equals(properties.get("cq:acLockedBy", (Object)null))) {
            throw new NewsletterException("Cannot unlink delivery that was used to lock the newsletter");
        }
        String[] deliveriesArray = (String[])properties.get("cq:acLinks", (Object)new String[0]);
        LinkedHashSet<String> deliveriesSet = new LinkedHashSet<String>(Arrays.asList(deliveriesArray));
        deliveriesSet.remove(deliveryId);
        deliveriesArray = deliveriesSet.toArray(new String[0]);
        if (deliveriesArray.length > 0) {
            properties.put((Object)"cq:acLinks", (Object)deliveriesArray);
        } else {
            properties.remove((Object)"cq:acLinks");
        }
        content.getResourceResolver().commit();
    }

    @Override
    public boolean isModifiedSince(Page newsletter, long timestamp) throws NewsletterException {
        this.check(newsletter);
        long lastModified = this.getLastModified(newsletter);
        return lastModified > timestamp;
    }

    @Override
    public long getLastModified(Page newsletter) throws NewsletterException {
        this.check(newsletter);
        Resource content = newsletter.getContentResource();
        ValueMap properties = (ValueMap)content.adaptTo(ValueMap.class);
        Date lastModified = (Date)properties.get("cq:lastModified", Date.class);
        return lastModified.getTime();
    }

    @Override
    public String getSubject(Page newsletter) throws NewsletterException {
        this.check(newsletter);
        Resource content = newsletter.getContentResource();
        ValueMap properties = (ValueMap)content.adaptTo(ValueMap.class);
        String subject = properties.containsKey((Object)"subject") ? (String)properties.get("subject", String.class) : newsletter.getTitle();
        if (subject == null) {
            throw new NewsletterException("No subject found (neither subject nor page title are available).");
        }
        return subject;
    }

    @Override
    public String getPlainText(Page newsletter) throws NewsletterException {
        this.check(newsletter);
        Resource content = newsletter.getContentResource();
        ValueMap properties = (ValueMap)content.adaptTo(ValueMap.class);
        String plainText = null;
        if (properties.containsKey((Object)"plaintext")) {
            plainText = (String)properties.get("plaintext", String.class);
        }
        return plainText;
    }

    @Override
    public boolean isApproved(Page newsletter) throws NewsletterException {
        this.check(newsletter);
        Resource content = newsletter.getContentResource();
        ValueMap properties = (ValueMap)content.adaptTo(ValueMap.class);
        return (Boolean)properties.get("cq:acApproved", (Object)false);
    }

    @Override
    public void approve(Page newsletter) throws NewsletterException, PersistenceException {
        this.check(newsletter);
        Resource content = newsletter.getContentResource();
        if (this.isApproved(newsletter)) {
            throw new NewsletterException("Newsletter " + newsletter.getPath() + " has already been approved");
        }
        ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
        properties.put((Object)"cq:acApproved", (Object)true);
        content.getResourceResolver().commit();
    }

    @Override
    public void disapprove(Page newsletter) throws NewsletterException, PersistenceException {
        this.check(newsletter);
        Resource content = newsletter.getContentResource();
        if (!this.isApproved(newsletter)) {
            throw new NewsletterException("Newsletter " + newsletter.getPath() + " is currently not approved");
        }
        ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
        properties.put((Object)"cq:acApproved", (Object)false);
        content.getResourceResolver().commit();
    }

    @Override
    public void markAsSent(Page newsletter, String deliveryId) throws NewsletterException, PersistenceException {
        this.check(newsletter);
        Resource content = newsletter.getContentResource();
        if (!this.isLinked(newsletter, deliveryId)) {
            throw new NewsletterException("Newsletter " + newsletter.getPath() + " is not linked to delivery " + deliveryId);
        }
        ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
        if (properties.containsKey((Object)"cq:acSentBy")) {
            throw new NewsletterException("Newsletter " + newsletter.getPath() + " has already been marked as sent");
        }
        properties.put((Object)"cq:acSentBy", (Object)deliveryId);
        content.getResourceResolver().commit();
    }

    private LockManager getLockManager(Page newsletter) throws NewsletterException {
        try {
            Session session = ((Node)newsletter.adaptTo(Node.class)).getSession();
            return session.getWorkspace().getLockManager();
        }
        catch (RepositoryException e) {
            throw new NewsletterException("Could not retrieve lock manager", (Throwable)e);
        }
    }

    private boolean isLocked(Page newsletter) throws NewsletterException {
        LockManager lockManager = this.getLockManager(newsletter);
        try {
            return lockManager.isLocked(newsletter.getContentResource().getPath());
        }
        catch (RepositoryException e) {
            throw new NewsletterException("Could not check lock", (Throwable)e);
        }
    }

    @Override
    public void lock(Page newsletter, String deliveryId) throws NewsletterException {
        this.check(newsletter);
        Resource content = newsletter.getContentResource();
        if (!this.isLinked(newsletter, deliveryId)) {
            throw new NewsletterException("Newsletter " + newsletter.getPath() + " is not linked to delivery " + deliveryId);
        }
        if (this.isLocked(newsletter)) {
            throw new NewsletterException("Newsletter " + newsletter.getPath() + " is already locked");
        }
        LockManager lockManager = this.getLockManager(newsletter);
        try {
            Node node = (Node)content.adaptTo(Node.class);
            node.addMixin("mix:lockable");
            node.getSession().save();
            lockManager.lock(content.getPath(), true, false, Long.MAX_VALUE, null);
            ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
            properties.put((Object)"cq:acLockedBy", (Object)deliveryId);
            content.getResourceResolver().commit();
        }
        catch (RepositoryException e) {
            String msg = "Could not lock newsletter " + newsletter.getPath();
            this.log.error(msg, (Throwable)e);
            throw new NewsletterException(msg, (Throwable)e);
        }
        catch (PersistenceException e) {
            String msg = "Could not write cq:acLockedBy";
            this.log.warn(msg);
            try {
                lockManager.unlock(content.getPath());
            }
            catch (RepositoryException re) {
                this.log.error("Could not undo locking of newsletter", (Throwable)re);
            }
            throw new NewsletterException(msg, (Throwable)e);
        }
    }

    @Override
    public void unlock(Page newsletter, String deliveryId) throws NewsletterException {
        this.check(newsletter);
        Resource content = newsletter.getContentResource();
        if (!this.isLinked(newsletter, deliveryId)) {
            throw new NewsletterException("Newsletter " + newsletter.getPath() + " is not linked to delivery " + deliveryId);
        }
        ModifiableValueMap properties = (ModifiableValueMap)content.adaptTo(ModifiableValueMap.class);
        String storedDeliveryId = (String)properties.get("cq:acLockedBy", String.class);
        if (storedDeliveryId == null || storedDeliveryId.isEmpty()) {
            throw new NewsletterException("No associated delivery stored");
        }
        if (!storedDeliveryId.equals(deliveryId)) {
            throw new NewsletterException("Newsletter " + newsletter.getPath() + " has been locked" + " using a different delivery, use the same delivery to unlock");
        }
        if (!this.isLocked(newsletter)) {
            throw new NewsletterException("Newsletter " + newsletter.getPath() + " is currently not locked");
        }
        LockManager lockManager = this.getLockManager(newsletter);
        try {
            lockManager.unlock(content.getPath());
            properties.remove((Object)"cq:acLockedBy");
            content.getResourceResolver().commit();
        }
        catch (RepositoryException e) {
            throw new NewsletterException("Could not unlock newsletter " + newsletter.getPath(), (Throwable)e);
        }
        catch (PersistenceException e) {
            this.log.warn("Could not remove delivery property");
        }
    }

    @Override
    public void publish(Page newsletter) throws NewsletterException {
        this.check(newsletter);
        this.publisher.publish((Resource)newsletter.adaptTo(Resource.class));
    }

    protected void bindPublisher(Publisher publisher) {
        this.publisher = publisher;
    }

    protected void unbindPublisher(Publisher publisher) {
        if (this.publisher == publisher) {
            this.publisher = null;
        }
    }
}