AssetManagerImpl.java 15.7 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.granite.asset.api.Asset
 *  com.adobe.granite.asset.api.AssetException
 *  com.adobe.granite.asset.api.AssetManager
 *  com.adobe.granite.asset.api.AssetVersion
 *  com.adobe.granite.asset.api.AssetVersionManager
 *  com.adobe.granite.asset.api.Rendition
 *  com.day.cq.dam.api.Asset
 *  com.day.cq.dam.api.AssetManager
 *  com.day.cq.dam.api.DamEvent
 *  com.day.cq.dam.api.Rendition
 *  com.day.cq.dam.api.Revision
 *  com.day.cq.dam.commons.util.DamUtil
 *  javax.jcr.Node
 *  javax.jcr.PathNotFoundException
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.version.Version
 *  org.apache.commons.lang.StringUtils
 *  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.osgi.service.event.Event
 *  org.osgi.service.event.EventAdmin
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.dam.core.impl;

import com.adobe.granite.asset.api.AssetException;
import com.adobe.granite.asset.api.AssetVersion;
import com.adobe.granite.asset.api.AssetVersionManager;
import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.AssetManager;
import com.day.cq.dam.api.DamEvent;
import com.day.cq.dam.api.Rendition;
import com.day.cq.dam.api.Revision;
import com.day.cq.dam.commons.util.DamUtil;
import com.day.cq.dam.core.impl.AssetIDProvider;
import com.day.cq.dam.core.impl.RevisionImpl;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.version.Version;
import org.apache.commons.lang.StringUtils;
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.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AssetManagerImpl
implements AssetManager {
    private static final Logger log = LoggerFactory.getLogger(AssetManager.class);
    private static final char WHITESPACE_REPLACEMENT_IN_LABEL = ' ';
    private static final String[] PRESERVED_PROPERTIES = new String[]{"cq:lastReplicated", "cq:lastReplicatedBy", "cq:lastReplicationAction", "jcr:created", "jcr:createdBy"};
    private final ResourceResolver resolver;
    private final EventAdmin eventAdmin;
    private final Session session;
    private final AssetIDProvider idProvider;
    private final com.adobe.granite.asset.api.AssetManager graniteAssetMgr;
    private final AssetVersionManager graniteAssetVersionMgr;

    public AssetManagerImpl(ResourceResolver resolver, EventAdmin eventAdmin, AssetIDProvider idProvider) {
        this.resolver = resolver;
        this.eventAdmin = eventAdmin;
        this.idProvider = idProvider;
        this.session = (Session)resolver.adaptTo(Session.class);
        this.graniteAssetMgr = (com.adobe.granite.asset.api.AssetManager)resolver.adaptTo(com.adobe.granite.asset.api.AssetManager.class);
        this.graniteAssetVersionMgr = (AssetVersionManager)resolver.adaptTo(AssetVersionManager.class);
    }

    public Asset restore(String revisionId) throws Exception {
        try {
            com.adobe.granite.asset.api.Asset graniteAsset = this.graniteAssetMgr.getAsset(this.graniteAssetVersionMgr.getVersion(revisionId).getAssetPath());
            ValueMap graniteAssetProperties = (ValueMap)graniteAsset.adaptTo(ValueMap.class);
            HashMap<String, Object> preserved = new HashMap<String, Object>();
            for (String name : PRESERVED_PROPERTIES) {
                if (!graniteAssetProperties.containsKey((Object)name)) continue;
                preserved.put(name, graniteAssetProperties.get((Object)name));
            }
            if (this.session.hasPendingChanges()) {
                this.session.save();
            }
            com.adobe.granite.asset.api.Asset restoredAsset = this.graniteAssetVersionMgr.restore(revisionId);
            ValueMap restoredAssetProperties = (ValueMap)restoredAsset.adaptTo(ValueMap.class);
            for (Map.Entry e : preserved.entrySet()) {
                restoredAssetProperties.put(e.getKey(), e.getValue());
            }
            restoredAssetProperties.put((Object)"restored", (Object)Calendar.getInstance());
            restoredAssetProperties.put((Object)"newRendition", (Object)true);
            this.session.save();
            DamEvent evt = DamEvent.versioned((String)restoredAsset.getPath(), (String)((Session)this.resolver.adaptTo(Session.class)).getUserID(), (String)revisionId);
            this.eventAdmin.sendEvent(evt.toNonDistributableEvent());
            return (Asset)restoredAsset.adaptTo(Asset.class);
        }
        catch (RepositoryException e) {
            throw new Exception("Unable to restore version.", (Throwable)e);
        }
    }

    public Collection<Revision> getRevisions(String path, Calendar cal) throws Exception {
        ArrayList revisions = new ArrayList<Revision>();
        try {
            Iterator versions = this.graniteAssetVersionMgr.listVersions(path);
            while (versions.hasNext()) {
                AssetVersion assetVersion = (AssetVersion)versions.next();
                RevisionImpl r = new RevisionImpl(assetVersion, this.convertToVersion(assetVersion), this.resolver);
                revisions.add(r);
            }
        }
        catch (AssetException e) {
            throw new Exception("Unable to get versions", (Throwable)e);
        }
        Collections.sort(revisions, new Comparator<Revision>(){

            @Override
            public int compare(Revision r1, Revision r2) {
                return r2.getCreated().compareTo(r1.getCreated());
            }
        });
        if (null != cal) {
            ArrayList<Revision> filtered = new ArrayList<Revision>();
            String lastName = null;
            for (Revision r : revisions) {
                String name = r.getName();
                if (name.equals(lastName) || r.getCreated().compareTo(cal) > 0) continue;
                filtered.add(r);
                lastName = name;
            }
            revisions = filtered;
        }
        return revisions;
    }

    public Asset createAssetForBinary(String binaryPath, boolean doSave) {
        log.debug("createAssetForBinary: attempting to create asset for [{}] with save flag [{}]...", (Object)binaryPath, (Object)doSave);
        String assetPath = DamUtil.binaryToAssetPath((String)binaryPath);
        Asset asset = this.getAssetForBinary(binaryPath);
        if (null == asset && assetPath != null) {
            log.debug("createAssetForBinary: asset [{}] doesn't exist yet, creating...", (Object)assetPath);
            try {
                com.adobe.granite.asset.api.Asset graniteAsset = this.graniteAssetMgr.createAsset(assetPath);
                try {
                    ((Node)graniteAsset.adaptTo(Node.class)).addMixin("mix:referenceable");
                    ((Node)graniteAsset.adaptTo(Node.class)).getNode("jcr:content/metadata").addMixin("cq:Taggable");
                    if (doSave) {
                        this.session.save();
                    }
                }
                catch (RepositoryException e) {
                    log.error("createAssetContent: repository error while creating content for asset [{}]: ", (Object)assetPath, (Object)e);
                }
                asset = (Asset)graniteAsset.adaptTo(Asset.class);
            }
            catch (AssetException e) {
                e.printStackTrace();
                log.error("createAssetForBinary: repository error while creating asset [{}]: ", (Object)assetPath, (Object)e);
            }
        }
        return asset;
    }

    public Asset createAsset(String path, InputStream is, String mimeType, boolean doSave) {
        log.debug("createAsset: attempting to create asset at [{}]...", (Object)path);
        if (path == null) {
            log.debug("createAsset: path is null hence returning null");
            return null;
        }
        Resource resource = this.resolver.getResource(path);
        Asset asset = null;
        if (null != resource) {
            asset = (Asset)resource.adaptTo(Asset.class);
            if (is != null) {
                boolean oldBatchMode = asset.isBatchMode();
                asset.setBatchMode(true);
                asset.addRendition("original", is, mimeType);
                asset.setBatchMode(oldBatchMode);
            }
        } else {
            log.debug("createAsset: asset [{}] doesn't exist yet, creating...", (Object)path);
            try {
                com.adobe.granite.asset.api.Asset graniteAsset = this.graniteAssetMgr.createAsset(path);
                ((Node)graniteAsset.adaptTo(Node.class)).addMixin("mix:referenceable");
                HashMap<String, String> rhMap = new HashMap<String, String>();
                if (is != null) {
                    rhMap.put("rendition.mime", mimeType);
                    graniteAsset.setRendition("original", is, rhMap);
                }
                ((Node)graniteAsset.adaptTo(Node.class)).getNode("jcr:content/metadata").addMixin("cq:Taggable");
                asset = (Asset)graniteAsset.adaptTo(Asset.class);
            }
            catch (RepositoryException e) {
                log.error("createAsset: repository exception while createing asset [{}]: ", (Object)path, (Object)e);
                return null;
            }
            catch (AssetException e) {
                log.error("createAsset: asset error while creating asset [{}]: ", (Object)path, (Object)e);
                return null;
            }
        }
        if (doSave) {
            try {
                this.session.save();
            }
            catch (RepositoryException e) {
                log.error("Failed to save asset {}", (Object)asset.getPath());
                log.error("Stack Trace:", (Throwable)e);
                try {
                    this.session.refresh(false);
                }
                catch (RepositoryException re) {
                    log.error("Stack Trace:", (Throwable)re);
                }
            }
        }
        return asset;
    }

    public Revision createRevision(Asset asset, String label, String comment) throws Exception {
        String assetPath = asset.getPath();
        label = AssetManagerImpl.getValidLabel(label);
        com.adobe.granite.asset.api.Asset graniteAsset = (com.adobe.granite.asset.api.Asset)asset.adaptTo(com.adobe.granite.asset.api.Asset.class);
        if (graniteAsset == null) {
            log.warn("createRevision: unable to create revision for asset [{}], resource is not node-based.");
            return null;
        }
        ValueMap graniteAssetProperties = (ValueMap)graniteAsset.adaptTo(ValueMap.class);
        try {
            graniteAssetProperties.put((Object)"cq:parentPath", (Object)ResourceUtil.getParent((String)assetPath));
        }
        catch (AssetException e) {
            log.warn("createRevision: unable to set parent path for asset [{}]: ", (Object)assetPath, (Object)e);
        }
        try {
            graniteAssetProperties.put((Object)"cq:name", (Object)graniteAsset.getName());
        }
        catch (AssetException e) {
            log.warn("createRevision: unable to set name for asset [{}]: ", (Object)assetPath, (Object)e);
        }
        try {
            if (!graniteAssetProperties.containsKey((Object)"cq:versionCreator")) {
                graniteAssetProperties.put((Object)"cq:versionCreator", (Object)this.session.getUserID());
            }
        }
        catch (AssetException e) {
            log.warn("createRevision: unable to set version creator for asset [{}]: ", (Object)this.session.getUserID(), (Object)e);
        }
        if (StringUtils.isNotEmpty((String)comment)) {
            try {
                graniteAssetProperties.put((Object)"cq:versionComment", (Object)comment);
            }
            catch (AssetException e) {
                log.warn("createRevision: unable to set version comment for asset [{}]: ", (Object)assetPath, (Object)e);
                comment = null;
            }
        }
        try {
            this.session.save();
            AssetVersion assetVersion = this.graniteAssetVersionMgr.createVersion(assetPath, label);
            if (StringUtils.isNotEmpty((String)comment)) {
                graniteAssetProperties.remove((Object)"cq:versionComment");
            }
            graniteAssetProperties.remove((Object)"cq:versionCreator");
            this.session.save();
            RevisionImpl revision = new RevisionImpl(assetVersion, this.convertToVersion(assetVersion), this.resolver);
            DamEvent evt = DamEvent.versioned((String)asset.getPath(), (String)((Session)this.resolver.adaptTo(Session.class)).getUserID(), (String)revision.getId());
            this.eventAdmin.sendEvent(evt.toNonDistributableEvent());
            return revision;
        }
        catch (RepositoryException e) {
            try {
                if (this.session.hasPendingChanges()) {
                    this.session.refresh(false);
                }
            }
            catch (RepositoryException re) {
                log.error("createRevision: unable to revert changes after failed creation of revision for asset [{}]: ", (Object)assetPath, (Object)e);
            }
            throw new Exception("Unable to create revision.", (Throwable)e);
        }
    }

    public Asset getAssetForBinary(String binaryPath) {
        String assetPath = DamUtil.binaryToAssetPath((String)binaryPath);
        if (assetPath == null) {
            return null;
        }
        Resource resource = this.resolver.getResource(assetPath);
        return null != resource ? (Asset)resource.adaptTo(Asset.class) : null;
    }

    public boolean removeAssetForBinary(String binaryPath) {
        String assetPath = DamUtil.binaryToAssetPath((String)binaryPath);
        try {
            if (StringUtils.isNotBlank((String)assetPath)) {
                this.graniteAssetMgr.removeAsset(assetPath);
                this.session.save();
                return true;
            }
            log.warn("invalid binary path [{}] given, cannot remove corresponding asset.", (Object)binaryPath);
        }
        catch (PathNotFoundException e) {
            log.warn("removeAssetForBinary: asset [{}] doesn't exist for given binary [{}], cannot remove.", (Object)assetPath, (Object)binaryPath);
        }
        catch (RepositoryException e) {
            log.error("removeAssetForBinary: repository error while removing asset [{}] for binary [" + binaryPath + "]: ", (Object)assetPath, (Object)e);
        }
        return false;
    }

    public String assignAssetID(Asset asset) throws PathNotFoundException, RepositoryException {
        ((Node)asset.adaptTo(Node.class)).addMixin("mix:referenceable");
        this.idProvider.establishParentage(asset);
        return asset.getID();
    }

    private Version convertToVersion(AssetVersion assetVersion) throws RepositoryException {
        return (Version)((Session)this.resolver.adaptTo(Session.class)).getNodeByIdentifier(assetVersion.getId());
    }

    private static String getValidLabel(String label) {
        if (label == null) {
            return label;
        }
        String finalLabel = "";
        int len = label.length();
        for (int i = 0; i < len; ++i) {
            char c = label.charAt(i);
            finalLabel = Character.isWhitespace(c) ? finalLabel + ' ' : finalLabel + c;
        }
        return finalLabel.trim();
    }

}