ElementImpl.java 13.6 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.cq.dam.cfm.ContentElement
 *  com.adobe.cq.dam.cfm.ContentVariation
 *  com.adobe.cq.dam.cfm.ElementTemplate
 *  com.adobe.cq.dam.cfm.SyncStatus
 *  com.adobe.cq.dam.cfm.VariationTemplate
 *  com.adobe.cq.dam.cfm.VersionDef
 *  com.adobe.cq.dam.cfm.VersionedContent
 *  com.day.cq.dam.api.Asset
 *  com.day.cq.dam.api.Rendition
 *  org.apache.commons.io.IOUtils
 *  org.apache.commons.io.input.ReaderInputStream
 *  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.ValueMap
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.dam.cfm.impl;

import com.adobe.cq.dam.cfm.ContentElement;
import com.adobe.cq.dam.cfm.ContentVariation;
import com.adobe.cq.dam.cfm.ElementTemplate;
import com.adobe.cq.dam.cfm.SyncStatus;
import com.adobe.cq.dam.cfm.VariationTemplate;
import com.adobe.cq.dam.cfm.VersionDef;
import com.adobe.cq.dam.cfm.VersionedContent;
import com.adobe.cq.dam.cfm.impl.AbstractAssetBasedElement;
import com.adobe.cq.dam.cfm.impl.CFMUtils;
import com.adobe.cq.dam.cfm.impl.ElementTemplateImpl;
import com.adobe.cq.dam.cfm.impl.FragmentTemplateImpl;
import com.adobe.cq.dam.cfm.impl.FragmentWriteException;
import com.adobe.cq.dam.cfm.impl.InvalidFragmentException;
import com.adobe.cq.dam.cfm.impl.SyncException;
import com.adobe.cq.dam.cfm.impl.VariationImpl;
import com.adobe.cq.dam.cfm.impl.VersioningException;
import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.Rendition;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.ReaderInputStream;
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.ValueMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ElementImpl
extends AbstractAssetBasedElement
implements ContentElement {
    private final List<ContentVariation> variations;
    private final String title;
    private final String subPath;
    private final ElementTemplate template;
    private final Logger log;

    public ElementImpl(Config cfg, boolean allowInvalidTemplate) throws InvalidFragmentException {
        super(cfg.asset, cfg.mainAsset);
        this.log = LoggerFactory.getLogger(this.getClass());
        this.subPath = cfg.subPath;
        this.template = cfg.template;
        if (this.template == null && !cfg.allowInvalidTemplate) {
            throw new InvalidFragmentException("No template specified for element asset '" + this.getAsset().getName() + "'.");
        }
        this.variations = new ArrayList<ContentVariation>(4);
        this.title = this.template != null ? this.template.getTitle() : "";
        FragmentTemplateImpl fragTemplate = null;
        if (this.template instanceof ElementTemplateImpl) {
            fragTemplate = ((ElementTemplateImpl)this.template).getFragmentTemplate();
        }
        if (fragTemplate != null) {
            Iterator<VariationTemplate> variations = fragTemplate.getVariations();
            while (variations.hasNext()) {
                VariationTemplate variation = variations.next();
                Rendition rendition = this.getAsset().getRendition(variation.getName());
                if (rendition == null) continue;
                this.addVariation(rendition, variation, allowInvalidTemplate);
            }
        } else {
            List renditions = this.getAsset().getRenditions();
            for (Rendition rendition : renditions) {
                String renditionName = rendition.getName();
                if (renditionName.equals("original") || renditionName.startsWith("cq5dam.")) continue;
                this.addVariation(rendition, fragTemplate != null ? fragTemplate.getVariation(renditionName) : null, allowInvalidTemplate);
            }
        }
    }

    public Iterator<ContentVariation> getVariations() {
        return this.variations.iterator();
    }

    public ContentVariation getVariation(String variationName) {
        for (ContentVariation toCheck : this.variations) {
            if (!variationName.equals(toCheck.getName())) continue;
            return toCheck;
        }
        return null;
    }

    public ContentVariation getResolvedVariation(String variationName) {
        return variationName != null ? this.getVariation(variationName) : null;
    }

    public String getName() {
        return this.template.getName();
    }

    public String getTitle() {
        return this.title;
    }

    public String getContent() {
        return CFMUtils.getContentAsString(this.getAsset().getOriginal());
    }

    public String getContentType() {
        return CFMUtils.getContentType(this.getAsset().getOriginal());
    }

    public String getResolvedContent(String variationName) {
        if (variationName == null) {
            return this.getContent();
        }
        ContentVariation variation = this.getResolvedVariation(variationName);
        return variation != null ? variation.getContent() : this.getContent();
    }

    protected SyncStatus getSyncStatus(ContentVariation toCheck) {
        long syncInfoTc;
        VariationImpl variation = (VariationImpl)toCheck;
        Calendar variationChange = variation.getModification();
        SyncInfo syncInfo = this.getSyncInfo(variation);
        Calendar masterChange = CFMUtils.getRenditionLastModified(this.getAsset().getOriginal());
        long variationChangeTc = variationChange.getTimeInMillis();
        long masterChangeTc = masterChange.getTimeInMillis();
        long l = syncInfoTc = syncInfo.lastSync != null ? syncInfo.lastSync.getTimeInMillis() : -1;
        if (syncInfoTc == -1) {
            return SyncStatus.UNSYNCED;
        }
        if (syncInfoTc >= masterChangeTc) {
            if (variationChangeTc > syncInfoTc) {
                return SyncStatus.VARIATION_CHANGED;
            }
            return SyncStatus.IN_SYNC;
        }
        if (variationChangeTc > syncInfoTc) {
            return SyncStatus.BOTH_CHANGED;
        }
        return SyncStatus.MASTER_CHANGED;
    }

    protected void synchronize(ContentVariation toSynchronize) throws SyncException {
        VariationImpl variation = (VariationImpl)toSynchronize;
        try {
            Calendar sync = variation.syncContent(this.getContent(), this.getContentType());
            this.writeSyncInfo(variation, new SyncInfo(sync));
        }
        catch (FragmentWriteException fwe) {
            throw new SyncException("Could not create new rendition: " + fwe.getMessage(), (Throwable)((Object)fwe));
        }
    }

    public void setContent(String content, String contentType) throws FragmentWriteException {
        CFMUtils.setContent(this.getAsset().getOriginal(), content, contentType);
    }

    protected ContentVariation addVariation(Rendition rendition, VariationTemplate template, boolean allowInvalidTemplate) throws InvalidFragmentException {
        VariationImpl variation = new VariationImpl(new VariationImpl.Config(rendition, this, this.subPath, template, allowInvalidTemplate));
        this.variations.add(variation);
        return variation;
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    public ContentVariation createVariation(VariationTemplate template) throws FragmentWriteException {
        Asset asset = this.getAsset();
        boolean oldBatchMode = asset.isBatchMode();
        asset.setBatchMode(true);
        String content = this.getContent();
        String contentType = this.getContentType();
        try {
            Rendition rendition;
            ReaderInputStream is = new ReaderInputStream((Reader)new StringReader(content));
            try {
                rendition = asset.addRendition(template.getName(), (InputStream)is, contentType);
            }
            finally {
                IOUtils.closeQuietly((InputStream)is);
            }
            ContentVariation contentVariation = this.addVariation(rendition, template, false);
            return contentVariation;
        }
        catch (InvalidFragmentException ife) {
            throw new FragmentWriteException("Internal error: Variation written could not be read.", (Throwable)((Object)ife));
        }
        finally {
            asset.setBatchMode(oldBatchMode);
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    protected ContentVariation createVariation(VariationTemplate model, String content, String contentType) throws FragmentWriteException {
        Asset asset = this.getAsset();
        boolean oldBatchMode = asset.isBatchMode();
        asset.setBatchMode(true);
        try {
            Rendition rendition;
            String name = model.getName();
            ReaderInputStream is = new ReaderInputStream((Reader)new StringReader(content));
            try {
                rendition = asset.addRendition(name, (InputStream)is, contentType);
            }
            finally {
                IOUtils.closeQuietly((InputStream)is);
            }
            try {
                ContentVariation contentVariation = this.addVariation(rendition, model, false);
                return contentVariation;
            }
            catch (InvalidFragmentException ife) {
                throw new FragmentWriteException("Internal error; variation written could not be read.", (Throwable)((Object)ife));
            }
        }
        finally {
            asset.setBatchMode(oldBatchMode);
        }
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    public void removeVariation(ContentVariation variation) throws FragmentWriteException {
        if (!this.variations.contains((Object)variation)) {
            throw new IllegalArgumentException("Provided variation is not part of this element.");
        }
        Asset asset = this.getAsset();
        boolean oldBatchMode = asset.isBatchMode();
        asset.setBatchMode(true);
        try {
            asset.removeRendition(variation.getName());
            this.variations.remove((Object)variation);
        }
        finally {
            asset.setBatchMode(oldBatchMode);
        }
    }

    protected SyncInfo getSyncInfo(ContentVariation variation) {
        Resource syncInfoBase = ((Resource)this.getAsset().adaptTo(Resource.class)).getChild("syncInfo");
        if (syncInfoBase == null) {
            return new SyncInfo(null);
        }
        Resource syncInfo = syncInfoBase.getChild(variation.getName());
        if (syncInfo == null) {
            return new SyncInfo(null);
        }
        ValueMap syncInfoProps = (ValueMap)syncInfo.adaptTo(ValueMap.class);
        Calendar lastSync = (Calendar)syncInfoProps.get("lastSync", Calendar.class);
        return new SyncInfo(lastSync);
    }

    protected void writeSyncInfo(ContentVariation variation, SyncInfo syncInfo) throws SyncException {
        Resource assetResource = (Resource)this.getAsset().adaptTo(Resource.class);
        ResourceResolver resolver = assetResource.getResourceResolver();
        HashMap<String, String> unstructuredDef = new HashMap<String, String>(4);
        unstructuredDef.put("jcr:primaryType", "nt:unstructured");
        try {
            Resource syncInfoRsc;
            Resource syncInfoBase = assetResource.getChild("syncInfo");
            if (syncInfoBase == null) {
                syncInfoBase = resolver.create(assetResource, "syncInfo", unstructuredDef);
            }
            if ((syncInfoRsc = syncInfoBase.getChild(variation.getName())) == null) {
                syncInfoRsc = resolver.create(syncInfoBase, variation.getName(), unstructuredDef);
            }
            ModifiableValueMap syncInfoProps = (ModifiableValueMap)syncInfoRsc.adaptTo(ModifiableValueMap.class);
            syncInfoProps.put((Object)"lastSync", (Object)syncInfo.lastSync);
        }
        catch (PersistenceException pe) {
            throw new SyncException("Could not write sync info.", (Throwable)pe);
        }
    }

    public Iterator<VersionDef> listVersions() throws VersioningException {
        return CFMUtils.listVersions(this.getMainAsset(), this.getLastModified(), "original", this.subPath);
    }

    public VersionedContent getVersionedContent(VersionDef version) throws VersioningException {
        return CFMUtils.getVersionedContent(version, this.getMainAsset(), "original", this.subPath);
    }

    @Override
    public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
        if (type == ElementTemplate.class) {
            return (AdapterType)this.template;
        }
        return super.adaptTo(type);
    }

    static class SyncInfo {
        public final Calendar lastSync;

        SyncInfo(Calendar lastSync) {
            this.lastSync = lastSync;
        }
    }

    static class Config {
        public final Asset asset;
        public final Asset mainAsset;
        public final String subPath;
        public final ElementTemplate template;
        public final boolean allowInvalidTemplate;

        public Config(Asset asset, Asset mainAsset, String subPath, ElementTemplate template, boolean allowInvalidTemplate) {
            this.asset = asset;
            this.mainAsset = mainAsset;
            this.subPath = subPath;
            this.template = template;
            this.allowInvalidTemplate = allowInvalidTemplate;
        }
    }

}