MissingMetadataNotificationJob.java 12.8 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.granite.taskmanagement.Task
 *  com.adobe.granite.taskmanagement.TaskAction
 *  com.adobe.granite.taskmanagement.TaskManager
 *  com.adobe.granite.taskmanagement.TaskManagerException
 *  com.adobe.granite.taskmanagement.TaskManagerFactory
 *  com.day.cq.dam.api.ui.editor.metadata.MetadataEditorHelper
 *  com.day.cq.dam.commons.util.DamUtil
 *  com.day.cq.search.PredicateGroup
 *  com.day.cq.search.Query
 *  com.day.cq.search.QueryBuilder
 *  com.day.cq.search.result.Hit
 *  com.day.cq.search.result.SearchResult
 *  javax.jcr.Node
 *  javax.jcr.Property
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ResourceResolverFactory
 *  org.apache.sling.commons.scheduler.Job
 *  org.apache.sling.commons.scheduler.JobContext
 *  org.apache.sling.commons.scheduler.Scheduler
 *  org.osgi.service.component.ComponentContext
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.dam.core.impl;

import com.adobe.granite.taskmanagement.Task;
import com.adobe.granite.taskmanagement.TaskAction;
import com.adobe.granite.taskmanagement.TaskManager;
import com.adobe.granite.taskmanagement.TaskManagerException;
import com.adobe.granite.taskmanagement.TaskManagerFactory;
import com.day.cq.dam.api.ui.editor.metadata.MetadataEditorHelper;
import com.day.cq.dam.commons.util.DamUtil;
import com.day.cq.search.PredicateGroup;
import com.day.cq.search.Query;
import com.day.cq.search.QueryBuilder;
import com.day.cq.search.result.Hit;
import com.day.cq.search.result.SearchResult;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.commons.scheduler.Job;
import org.apache.sling.commons.scheduler.JobContext;
import org.apache.sling.commons.scheduler.Scheduler;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(metatype=1, label="Adobe CQ DAM Missing Metadata Notification", description="Adobe CQ DAM Missing Metadata Notification", enabled=0)
public class MissingMetadataNotificationJob
implements Job {
    private static final Logger log = LoggerFactory.getLogger(MissingMetadataNotificationJob.class);
    @Reference
    private Scheduler scheduler;
    @Reference
    private MetadataEditorHelper metadataEditorHelper;
    @Reference
    private ResourceResolverFactory resolverFactory;
    @Reference
    private QueryBuilder queryBuilder;
    @Property(boolValue={1}, label="Time based Scheduler", description="Whether to schedule a time based schedular")
    public static final String SCHEDULE_TIME_BASED = "cq.dam.missingmetadata.notification.scheduler.istimebased";
    @Property(value={"0 0 0 * * ?"}, label="Time Based Scheduler Rule", description="Regular expression for time based Scheduler. Eg: '0 0 0 * * ?'. The example expression triggers the Job @ 00 hrs. This expression get picked if Time Based Scheduler is true")
    public static final String SCHEDULER_TIMEBASED_RULE = "cq.dam.missingmetadata.notification.scheduler.timebased.rule";
    @Property(longValue={10}, label="Preiodic Scheduler", description="Time in seconds for periodic scheduler. This expression get picked if Time Based Scheduler is set false")
    public static final String SCHEDULER_PERIOD = "cq.dam.missingmetadata.notification.scheduler.period.rule";
    @Property(value={"admin"}, label="Notification Recipient ID", description="ID of the recipient of the notification for missing metadata")
    public static final String RECIPIENT_ID = "cq.dam.missingmetadata.notification.recipient";
    public static final String TASK_TYPE = "missingMetadataNotification";
    public static final String TASK_NAME = "REQUIRED METADATA MISSING";
    private static String RECIPIENT;
    private static Calendar LAST_RUN;
    private static Calendar THIS_RUN;
    private static final long QUERY_LIMIT = 1000;

    public void execute(JobContext context) {
        THIS_RUN = Calendar.getInstance();
        try {
            SearchResult result;
            List hits;
            ResourceResolver resolver = this.resolverFactory.getAdministrativeResourceResolver(null);
            long offset = 0;
            while (null != (hits = (result = this.getNewUploads(resolver, offset, 1000)).getHits()) && hits.size() > 0) {
                List<Resource> missingMtdtResources = this.getInvalidMetadataAssets(resolver, result);
                if (null != missingMtdtResources && missingMtdtResources.size() > 0) {
                    this.setMetadataPropertyValidity(resolver, missingMtdtResources, false);
                    this.sendNotification(resolver, missingMtdtResources);
                }
                if ((long)hits.size() < 1000) break;
                offset += 1000;
            }
            offset = 0;
            while (null != (hits = (result = this.getMarkedInvalidMetadataAssets(resolver, offset, 1000)).getHits()) && hits.size() > 0) {
                List<Resource> rectifiedMetadata = this.getValidMetadataAssets(resolver, result);
                if (null != rectifiedMetadata && rectifiedMetadata.size() > 0) {
                    this.setMetadataPropertyValidity(resolver, rectifiedMetadata, true);
                }
                if ((long)hits.size() >= 1000) {
                    offset += 1000;
                    continue;
                }
                break;
            }
        }
        catch (Exception e) {
            log.error("Error to execute missing metadata notification job.", (Throwable)e);
        }
        LAST_RUN = THIS_RUN;
    }

    protected void activate(ComponentContext componentContext) throws Exception {
        try {
            LAST_RUN = Calendar.getInstance();
            LAST_RUN.setTime(new Date(0));
            boolean isTimeBased = (Boolean)componentContext.getProperties().get("cq.dam.missingmetadata.notification.scheduler.istimebased");
            RECIPIENT = (String)componentContext.getProperties().get("cq.dam.missingmetadata.notification.recipient");
            if (isTimeBased) {
                String expression = (String)componentContext.getProperties().get("cq.dam.missingmetadata.notification.scheduler.timebased.rule");
                this.scheduler.addJob(MissingMetadataNotificationJob.class.getName(), (Object)this, null, expression, false);
            } else {
                long periodinsecs = (Long)componentContext.getProperties().get("cq.dam.missingmetadata.notification.scheduler.period.rule");
                this.scheduler.addPeriodicJob(MissingMetadataNotificationJob.class.getName(), (Object)this, null, periodinsecs, false);
            }
        }
        catch (Exception e) {
            log.error("Error in activate.", (Throwable)e);
            throw e;
        }
    }

    protected void deactivate(ComponentContext componentContext) {
        log.debug("Deactivating the expiry notification scheduler");
        this.scheduler.removeJob(MissingMetadataNotificationJob.class.getName());
    }

    private void sendNotification(ResourceResolver resolver, List<Resource> resources) throws TaskManagerException {
        TaskManager tm = (TaskManager)resolver.adaptTo(TaskManager.class);
        TaskManagerFactory tmf = tm.getTaskManagerFactory();
        Task newTask = tmf.newTask("missingMetadataNotification");
        newTask.setName("REQUIRED METADATA MISSING");
        TaskAction newTaskAction = tmf.newTaskAction("Remove");
        newTask.setActions(Collections.singletonList(newTaskAction));
        newTask.setContentPath("/content/dam");
        newTask.setCurrentAssignee(RECIPIENT);
        StringBuffer description = new StringBuffer("Following Assets are doesn't have valid metadata:\n");
        for (Resource each : resources) {
            description.append("\n" + each.getPath());
        }
        newTask.setDescription(description.toString());
        tm.createTask(newTask);
    }

    private List<Resource> getInvalidMetadataAssets(ResourceResolver resolver, SearchResult result) throws RepositoryException {
        return this.filterAssets(resolver, result, true);
    }

    private List<Resource> getValidMetadataAssets(ResourceResolver resolver, SearchResult result) throws RepositoryException {
        return this.filterAssets(resolver, result, false);
    }

    private List<Resource> filterAssets(ResourceResolver resolver, SearchResult result, boolean isFetchValid) throws RepositoryException {
        ArrayList<Resource> missingMetadataResList = new ArrayList<Resource>();
        if (null == result) {
            return null;
        }
        List hits = result.getHits();
        if (null == hits || hits.size() == 0) {
            return null;
        }
        for (Hit hit : hits) {
            Resource res = resolver.getResource(hit.getPath());
            List missingMetadataItems = this.metadataEditorHelper.getInvalidFormItems(res);
            if (null == res || !DamUtil.isAsset((Resource)res) || isFetchValid ^ (null != missingMetadataItems && missingMetadataItems.size() > 0)) continue;
            missingMetadataResList.add(res);
        }
        return missingMetadataResList;
    }

    private SearchResult getNewUploads(ResourceResolver resolver, long offset, long limit) {
        Long timeinsecs = (THIS_RUN.getTimeInMillis() - LAST_RUN.getTimeInMillis()) / 1000;
        HashMap<String, String> map = new HashMap<String, String>();
        map.put("path", "/content/dam");
        map.put("1_relativedaterange.property", "jcr:created");
        map.put("1_relativedaterange.lowerBound", "-" + timeinsecs + "s");
        map.put("1_relativedaterange.upperBound", "-0s");
        map.put("p.offset", "" + offset);
        map.put("p.limit", "" + limit);
        map.put("type", "dam:Asset");
        map.put("mainasset", "true");
        Query query = this.queryBuilder.createQuery(PredicateGroup.create(map), (Session)resolver.adaptTo(Session.class));
        return query.getResult();
    }

    private SearchResult getMarkedInvalidMetadataAssets(ResourceResolver resolver, long offset, long limit) {
        HashMap<String, String> map = new HashMap<String, String>();
        map.put("path", "/content/dam");
        map.put("type", "dam:Asset");
        map.put("1_property", "jcr:content/hasValidMetadata");
        map.put("1_property.value", "false");
        map.put("p.offset", "" + offset);
        map.put("p.limit", "" + limit);
        map.put("mainasset", "true");
        Query query = this.queryBuilder.createQuery(PredicateGroup.create(map), (Session)resolver.adaptTo(Session.class));
        return query.getResult();
    }

    private void setMetadataPropertyValidity(ResourceResolver resolver, List<Resource> resources, boolean set) throws RepositoryException {
        for (Resource each : resources) {
            ((Node)each.getChild("jcr:content").adaptTo(Node.class)).setProperty("hasValidMetadata", set);
        }
        ((Session)resolver.adaptTo(Session.class)).save();
    }

    protected void bindScheduler(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

    protected void unbindScheduler(Scheduler scheduler) {
        if (this.scheduler == scheduler) {
            this.scheduler = null;
        }
    }

    protected void bindMetadataEditorHelper(MetadataEditorHelper metadataEditorHelper) {
        this.metadataEditorHelper = metadataEditorHelper;
    }

    protected void unbindMetadataEditorHelper(MetadataEditorHelper metadataEditorHelper) {
        if (this.metadataEditorHelper == metadataEditorHelper) {
            this.metadataEditorHelper = null;
        }
    }

    protected void bindResolverFactory(ResourceResolverFactory resourceResolverFactory) {
        this.resolverFactory = resourceResolverFactory;
    }

    protected void unbindResolverFactory(ResourceResolverFactory resourceResolverFactory) {
        if (this.resolverFactory == resourceResolverFactory) {
            this.resolverFactory = null;
        }
    }

    protected void bindQueryBuilder(QueryBuilder queryBuilder) {
        this.queryBuilder = queryBuilder;
    }

    protected void unbindQueryBuilder(QueryBuilder queryBuilder) {
        if (this.queryBuilder == queryBuilder) {
            this.queryBuilder = null;
        }
    }
}