ModifyingRequest.java 6.4 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.servlet.ServletInputStream
 *  org.apache.commons.lang.StringUtils
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.request.RequestParameter
 *  org.apache.sling.api.request.RequestParameterMap
 *  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.servlets.post.Modification
 *  org.json.JSONException
 *  org.json.JSONObject
 *  org.slf4j.Logger
 */
package com.adobe.granite.rest.impl.servlet;

import com.adobe.granite.rest.RequestException;
import com.adobe.granite.rest.RestException;
import com.adobe.granite.rest.impl.servlet.AbstractRequest;
import com.adobe.granite.rest.impl.servlet.JSONUtil;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletInputStream;
import org.apache.commons.lang.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.request.RequestParameter;
import org.apache.sling.api.request.RequestParameterMap;
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.servlets.post.Modification;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;

public abstract class ModifyingRequest
extends AbstractRequest {
    private static final String NULL_VALUE = "null";

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    protected Resource createOrModifyResource(SlingHttpServletRequest request, List<Modification> changes) throws RestException, PersistenceException, JSONException, IOException, UnsupportedOperationException {
        ResourceResolver resolver = request.getResourceResolver();
        Resource resource = request.getResource();
        String mimeType = this.getContentType(request);
        InputStream inputStream = null;
        HashMap<String, Object> properties = new HashMap<String, Object>();
        JSONObject json = null;
        try {
            Object fileProperties;
            if ("application/x-www-form-urlencoded".equals(mimeType) || "multipart/form-data".equals(mimeType)) {
                properties.putAll(this.extractProperties(request));
            } else {
                inputStream = request.getInputStream();
                if (inputStream != null) {
                    if (mimeType == null) {
                        throw new RequestException(400, "Header Content-Type is required.");
                    }
                    if (StringUtils.startsWith((String)mimeType, (String)"application/vnd.siren+json") || StringUtils.startsWith((String)mimeType, (String)"application/json")) {
                        String encoding = StringUtils.defaultString((String)request.getCharacterEncoding(), (String)"UTF-8");
                        json = new JSONObject(this.readRequestBodyAsString(inputStream, encoding));
                        JSONObject jsonProperties = json.optJSONObject("properties");
                        if (jsonProperties != null) {
                            properties.putAll(JSONUtil.toJcrMap(jsonProperties));
                        }
                    } else {
                        fileProperties = new HashMap();
                        fileProperties.put("fileinput", inputStream);
                        fileProperties.put("mimetype", mimeType);
                        properties.put("file", fileProperties);
                    }
                }
            }
            if ("PUT".equals(request.getMethod())) {
                this.updateProperties(resource, properties);
            } else if ("POST".equals(request.getMethod()) && (resource = resolver.create(resource.getParent(), resource.getName(), properties)) != null && "application/json".equals(mimeType)) {
                this.updateProperties(resource, properties);
            }
            fileProperties = resource;
            return fileProperties;
        }
        catch (OutOfMemoryError e) {
            this.log.error("An OutOfMemoryError occurred while reading the request InputStream.", (Throwable)e);
        }
        finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                }
                catch (IOException e) {
                    this.log.error("An error occurred closing the request InputStream.", (Throwable)e);
                }
            }
        }
        throw new PersistenceException("Resource could not be updated/created.");
    }

    private Map<String, Object> extractProperties(SlingHttpServletRequest request) throws IOException {
        HashMap<String, Object> properties = new HashMap<String, Object>();
        for (Map.Entry entry : request.getRequestParameterMap().entrySet()) {
            RequestParameter param = ((RequestParameter[])entry.getValue())[0];
            if (param.isFormField()) {
                properties.put((String)entry.getKey(), param.getString());
                continue;
            }
            HashMap<String, Object> fileProperties = new HashMap<String, Object>();
            fileProperties.put("fileinput", param.getInputStream());
            fileProperties.put("mimetype", param.getContentType());
            fileProperties.put("name", param.getFileName());
            properties.put("file", fileProperties);
        }
        return properties;
    }

    private void updateProperties(Resource resource, Map<String, Object> properties) throws UnsupportedOperationException {
        ModifiableValueMap valueMap = (ModifiableValueMap)resource.adaptTo(ModifiableValueMap.class);
        if (valueMap == null) {
            throw new UnsupportedOperationException("Operation not supported for resource.");
        }
        for (Map.Entry<String, Object> entry : properties.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (null == value || "null".equals(value) || JSONObject.NULL.equals(value)) {
                valueMap.remove((Object)key);
                continue;
            }
            valueMap.put((Object)key, value);
        }
    }
}