MobileAppScreenshotAddOperation.java 15.3 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.granite.asset.api.Asset
 *  com.adobe.granite.asset.api.AssetManager
 *  com.adobe.granite.asset.api.Rendition
 *  com.adobe.granite.ui.components.HtmlResponse
 *  com.day.cq.i18n.I18n
 *  com.day.image.Layer
 *  javax.jcr.RepositoryException
 *  javax.servlet.http.HttpServletRequest
 *  org.apache.commons.lang.StringUtils
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Properties
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.request.RequestParameter
 *  org.apache.sling.api.resource.ModifiableValueMap
 *  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.apache.sling.resource.collection.ResourceCollection
 *  org.apache.sling.resource.collection.ResourceCollectionManager
 *  org.apache.sling.servlets.post.Modification
 *  org.osgi.framework.BundleContext
 *  org.osgi.framework.ServiceReference
 *  org.osgi.service.component.ComponentContext
 */
package com.adobe.cq.mobile.platform.impl.operations;

import com.adobe.cq.mobile.platform.MobileResource;
import com.adobe.cq.mobile.platform.MobileResourceType;
import com.adobe.cq.mobile.platform.impl.MobileAppException;
import com.adobe.cq.mobile.platform.impl.operations.MobileAbstractOperation;
import com.adobe.cq.mobile.platform.impl.operations.MobileOperationException;
import com.adobe.cq.mobile.platform.impl.store.MobileDevice;
import com.adobe.cq.mobile.platform.impl.store.MobilePlatformProvider;
import com.adobe.cq.mobile.platform.impl.store.ScreenDefinition;
import com.adobe.granite.asset.api.Asset;
import com.adobe.granite.asset.api.AssetManager;
import com.adobe.granite.asset.api.Rendition;
import com.adobe.granite.ui.components.HtmlResponse;
import com.day.cq.i18n.I18n;
import com.day.image.Layer;
import java.awt.Dimension;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.jcr.RepositoryException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.request.RequestParameter;
import org.apache.sling.api.resource.ModifiableValueMap;
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.apache.sling.resource.collection.ResourceCollection;
import org.apache.sling.resource.collection.ResourceCollectionManager;
import org.apache.sling.servlets.post.Modification;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;

@Component(metatype=0, label="AEM Mobile Screenshot Add Handler")
@Service
@Properties(value={@Property(name="sling.post.operation", value={"mobileapps:screenshotAdd"})})
public class MobileAppScreenshotAddOperation
extends MobileAbstractOperation {
    protected static final String PN_ASSET_PATH = "screenshots/assetPath";
    public static final String OPERATION_NAME = "screenshotAdd";
    private static final String PARAM_PATH = "path";
    private static final String PARAM_STORE = "store";
    private static final String PARRM_APP_INSTANCE = "appInstance";
    private static final String PARAM_DEVICE_TARGET = "deviceTarget";
    private static final String PARAM_IMAGE = "image";
    private ComponentContext context;

    /*
     * Unable to fully structure code
     * Enabled aggressive block sorting
     * Enabled unnecessary exception pruning
     * Enabled aggressive exception aggregation
     * Lifted jumps to return sites
     */
    @Override
    protected void perform(SlingHttpServletRequest request, HtmlResponse response, List<Modification> changes) {
        i18n = new I18n((HttpServletRequest)request);
        appInstance = request.getResource();
        mobileResource = (MobileResource)appInstance.adaptTo(MobileResource.class);
        if (!mobileResource.isA(new String[]{MobileResourceType.INSTANCE.getType()})) {
            appInstanceParam = request.getParameter("appInstance");
            if (StringUtils.isBlank((String)appInstanceParam)) {
                message = i18n.get("Missing mandatory parameter {0}", null, new Object[]{"appInstance"});
                title = i18n.get("Error");
                this.generateError(response, message, title);
                return;
            }
            appInstance = request.getResourceResolver().getResource(appInstanceParam.toString());
            mobileResource = (MobileResource)appInstance.adaptTo(MobileResource.class);
        }
        if (!mobileResource.isA(new String[]{MobileResourceType.INSTANCE.getType()})) {
            message = i18n.get("Unable to resolve mobile application {0}", null, new Object[]{mobileResource.getPath()});
            title = i18n.get("Error");
            this.generateError(response, message, title);
            return;
        }
        store = request.getParameter("store");
        if (StringUtils.isBlank((String)store)) {
            message = i18n.get("Missing mandatory parameter {0}", null, new Object[]{"store"});
            title = i18n.get("Error");
            this.generateError(response, message, title);
            return;
        }
        store = store.toLowerCase();
        path = null;
        imageParameter = request.getRequestParameter("image");
        if (imageParameter != null && imageParameter.getSize() > 0) {
            try {
                mimeType = imageParameter.getContentType();
                imageStream = imageParameter.getInputStream();
                assetResource = this.saveScreenshotToApp(mobileResource, store, imageParameter.getFileName(), mimeType, imageStream, i18n);
                if (assetResource == null) ** GOTO lbl45
                path = assetResource.getPath();
            }
            catch (IOException e) {
                message = i18n.get("The server has problem processing your request. Unable to obtain a stream to the screenshot image.");
                title = i18n.get("Error");
                this.generateError(response, message, title);
                return;
            }
            catch (Throwable t) {
                title = i18n.get("Error");
                this.generateError(response, t.getMessage(), title, t);
                return;
            }
        } else {
            path = request.getParameter("path");
        }
lbl45: // 3 sources:
        if (StringUtils.isBlank((String)path)) {
            message = i18n.get("Missing mandatory parameter {0}", null, new Object[]{"path"});
            title = i18n.get("Error");
            this.generateError(response, message, title);
            return;
        }
        decoder = new URLDecoder();
        resourcePath = null;
        try {
            resourcePath = URLDecoder.decode(path, "UTF-8");
        }
        catch (UnsupportedEncodingException e) {
            message = i18n.get("The server has problem processing your request. Unable to decode file path.");
            title = i18n.get("Error");
            this.generateError(response, message, title);
            return;
        }
        assetResource = request.getResourceResolver().getResource(resourcePath);
        asset = (Asset)assetResource.adaptTo(Asset.class);
        original = asset.getRendition("original");
        imageStream = original.getStream();
        try {
            layer = new Layer(imageStream);
        }
        catch (IOException e) {
            message = i18n.get("The server has problem processing your request. Unable to obtain a stream to the resource.");
            title = i18n.get("Error");
            this.generateError(response, message, title);
            return;
        }
        height = layer.getHeight();
        width = layer.getWidth();
        orientation = width >= height ? "landscape" : "portrait";
        dimension = new Dimension(width, height);
        filter = "(cq.mobile.apps.platformprovider=" + store + ")";
        try {
            refs = this.context.getBundleContext().getServiceReferences(MobilePlatformProvider.class.getName(), filter);
            if (refs == null) {
                filter = "(cq.mobile.apps.platformprovider=default)";
                refs = this.context.getBundleContext().getServiceReferences(MobilePlatformProvider.class.getName(), filter);
            }
            if (refs == null || refs.length == 0) {
                msg = "No MobileAppMetadataProvider has been registered for store " + store;
                message = i18n.get("No MobileAppMetadataProvider has been registered for store {0}", null, new Object[]{store});
                title = i18n.get("Error");
                this.generateError(response, message, title, new MobileOperationException(msg));
                return;
            }
            ref = refs[0];
            provider = (MobilePlatformProvider)this.context.getBundleContext().getService(ref);
            mobileDevice = null;
            devicePlatform = request.getParameter("deviceTarget");
            if (StringUtils.isNotBlank((String)devicePlatform)) {
                mobileDevice = provider.getDevicePlatform(devicePlatform);
            } else {
                allDevices = provider.getSupportedDevices();
                for (MobileDevice md : allDevices) {
                    if (!md.isDimensionSupported(dimension)) continue;
                    mobileDevice = md;
                    devicePlatform = mobileDevice.getId();
                    break;
                }
            }
            if (mobileDevice == null) {
                message = i18n.get("Unable to located a device platform for the provided platform {0}", null, new Object[]{devicePlatform});
                title = i18n.get("Error");
                this.generateError(response, message, title);
                return;
            }
            if (mobileDevice.isDimensionSupported(dimension)) {
                this.addScreenshotToApp(appInstance, devicePlatform, store, assetResource, orientation);
                return;
            }
            supportedScreens = mobileDevice.getSupportedScreens();
            screens = new StringBuilder();
            i$ = supportedScreens.iterator();
            do {
                if (!i$.hasNext()) {
                    message = i18n.get("The selected device {2} does not support the image dimensions of {0} x {1}.<br><br>Valid image dimensions:<div>{3}</div>", null, new Object[]{width, height, i18n.getVar(mobileDevice.getTitle()), screens.toString()});
                    title = i18n.get("Error");
                    this.generateError(response, message, title);
                    return;
                }
                sd = i$.next();
                screens.append("<div class=\"cq-apps-error-screendescription\">").append(sd.getDescription(i18n)).append("</div>");
            } while (true);
        }
        catch (Throwable e) {
            message = i18n.get("The server has problem processing your request.");
            title = i18n.get("Error");
            this.generateError(response, message, title, e);
        }
    }

    private Resource saveScreenshotToApp(MobileResource appInstance, String store, String name, String mimeType, InputStream source, I18n i18n) throws MobileAppException {
        Resource appRes = (Resource)appInstance.adaptTo(Resource.class);
        AssetManager assetManager = (AssetManager)appRes.getResourceResolver().adaptTo(AssetManager.class);
        String targetPath = (String)appInstance.getProperties().get("screenshots/assetPath", String.class);
        if (StringUtils.isBlank((String)targetPath)) {
            targetPath = (String)appInstance.getProperties().get("appAssetPath", String.class);
        }
        if (StringUtils.isBlank((String)targetPath)) {
            throw new MobileAppException(i18n.get("Screenshot asset path not defined"));
        }
        if (!targetPath.endsWith("/")) {
            targetPath = targetPath + "/";
        }
        targetPath = targetPath + store + "/" + name;
        Asset asset = assetManager.createAsset(targetPath);
        HashMap<String, String> map = new HashMap<String, String>();
        if (mimeType != null) {
            map.put("rendition.mime", mimeType);
        }
        asset.setRendition("original", source, map);
        return appRes.getResourceResolver().getResource(asset.getPath());
    }

    private void addScreenshotToApp(Resource appInstance, String devicePlatform, String store, Resource assetResource, String orientation) throws MobileOperationException {
        Resource content = appInstance.getChild("jcr:content");
        ResourceResolver resourceResolver = appInstance.getResourceResolver();
        ResourceCollectionManager collectionManager = (ResourceCollectionManager)appInstance.getResourceResolver().adaptTo(ResourceCollectionManager.class);
        if (content != null) {
            try {
                ResourceCollection collection;
                String storePath = content.getPath() + "/screenshots/" + store;
                HashMap<String, String> props = new HashMap<String, String>();
                props.put("sling:resourceType", "nt:unstructured");
                props.put("jcr:title", store);
                Resource storeResource = ResourceUtil.getOrCreateResource((ResourceResolver)resourceResolver, (String)storePath, props, (String)"nt:unstructured", (boolean)true);
                Resource devicePlatformResource = resourceResolver.getResource(storeResource.getPath() + "/" + devicePlatform);
                if (devicePlatformResource == null) {
                    HashMap<String, String> storeProperties = new HashMap<String, String>();
                    storeProperties.put("sling:resourceType", "dam/collection");
                    storeProperties.put("sling:resourceSuperType", "sling/collection");
                    storeProperties.put("jcr:title", devicePlatform);
                    collection = collectionManager.createCollection(storeResource, devicePlatform, storeProperties);
                    devicePlatformResource = resourceResolver.getResource(collection.getPath());
                } else {
                    collection = collectionManager.getCollection(devicePlatformResource);
                }
                collection.add(assetResource);
                Resource assetMember = devicePlatformResource.getChild("sling:members/" + assetResource.getName());
                ModifiableValueMap properties = (ModifiableValueMap)assetMember.adaptTo(ModifiableValueMap.class);
                properties.put((Object)"deviceTarget", (Object)devicePlatform);
                properties.put((Object)"orientation", (Object)orientation);
            }
            catch (IOException e) {
                throw new MobileOperationException(e.getMessage());
            }
        }
    }

    protected void activate(ComponentContext context) throws RepositoryException {
        this.context = context;
    }
}