Package org.apache.sling.servlets.post.impl

Source Code of org.apache.sling.servlets.post.impl.SlingPostServlet

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.sling.servlets.post.impl;

import java.io.IOException;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceNotFoundException;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.servlets.HtmlResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.commons.osgi.OsgiUtil;
import org.apache.sling.servlets.post.SlingPostConstants;
import org.apache.sling.servlets.post.SlingPostOperation;
import org.apache.sling.servlets.post.impl.helper.DateParser;
import org.apache.sling.servlets.post.impl.helper.NodeNameGenerator;
import org.apache.sling.servlets.post.impl.operations.CopyOperation;
import org.apache.sling.servlets.post.impl.operations.DeleteOperation;
import org.apache.sling.servlets.post.impl.operations.ModifyOperation;
import org.apache.sling.servlets.post.impl.operations.MoveOperation;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* POST servlet that implements the sling client library "protocol"
*
* @scr.component immediate="true" label="%servlet.post.name"
*                description="%servlet.post.description"
* @scr.service interface="javax.servlet.Servlet"
* @scr.property name="service.description" value="Sling Post Servlet"
* @scr.property name="service.vendor" value="The Apache Software Foundation"
*
* Use this as the default servlet for POST requests for Sling
* @scr.property name="sling.servlet.resourceTypes"
*               value="sling/servlet/default" private="true"
* @scr.property name="sling.servlet.methods" value="POST" private="true"
*/
public class SlingPostServlet extends SlingAllMethodsServlet {

    private static final long serialVersionUID = 1837674988291697074L;

    /**
     * default log
     */
    private final Logger log = LoggerFactory.getLogger(getClass());

    /**
     * @scr.property values.0="EEE MMM dd yyyy HH:mm:ss 'GMT'Z"
     *               values.1="yyyy-MM-dd'T'HH:mm:ss.SSSZ"
     *               values.2="yyyy-MM-dd'T'HH:mm:ss" values.3="yyyy-MM-dd"
     *               values.4="dd.MM.yyyy HH:mm:ss" values.5="dd.MM.yyyy"
     */
    private static final String PROP_DATE_FORMAT = "servlet.post.dateFormats";

    /**
     * @scr.property values.0="title" values.1="jcr:title" values.2="name"
     *               values.3="description" values.4="jcr:description"
     *               values.5="abstract"
     */
    private static final String PROP_NODE_NAME_HINT_PROPERTIES = "servlet.post.nodeNameHints";

    /**
     * @scr.property value="20" type="Integer"
     */
    private static final String PROP_NODE_NAME_MAX_LENGTH = "servlet.post.nodeNameMaxLength";

    /**
     * utility class for generating node names
     */
    private NodeNameGenerator nodeNameGenerator;

    /**
     * utility class for parsing date strings
     */
    private DateParser dateParser;

    private SlingPostOperation modifyOperation;

    private final Map<String, SlingPostOperation> postOperations = new HashMap<String, SlingPostOperation>();

    @Override
    public void init() {
        // default operation: create/modify
        modifyOperation = new ModifyOperation(nodeNameGenerator, dateParser,
            getServletContext());

        // other predefined operations
        postOperations.put(SlingPostConstants.OPERATION_COPY,
            new CopyOperation());
        postOperations.put(SlingPostConstants.OPERATION_MOVE,
            new MoveOperation());
        postOperations.put(SlingPostConstants.OPERATION_DELETE,
            new DeleteOperation());
    }

    @Override
    public void destroy() {
        modifyOperation = null;
        postOperations.clear();
    }

    @Override
    protected void doPost(SlingHttpServletRequest request,
            SlingHttpServletResponse response) throws IOException {

        // prepare the response
        HtmlResponse htmlResponse = new HtmlResponse();
        htmlResponse.setReferer(request.getHeader("referer"));

        SlingPostOperation operation = getSlingPostOperation(request);
        if (operation == null) {

            htmlResponse.setStatus(
                HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                "Invalid operation specified for POST request");

        } else {

            try {
                operation.run(request, htmlResponse);
            } catch (ResourceNotFoundException rnfe) {
                htmlResponse.setStatus(HttpServletResponse.SC_NOT_FOUND,
                    rnfe.getMessage());
            } catch (Throwable throwable) {
                htmlResponse.setError(throwable);
            }

        }

        // check for redirect URL if processing succeeded
        if (htmlResponse.isSuccessful()) {
            String redirect = getRedirectUrl(request, htmlResponse);
            if (redirect != null) {
                response.sendRedirect(redirect);
                return;
            }
        }

        // create a html response and send if unsuccessful or no redirect
        htmlResponse.send(response, isSetStatus(request));
    }

    private SlingPostOperation getSlingPostOperation(
            SlingHttpServletRequest request) {
        String operation = request.getParameter(SlingPostConstants.RP_OPERATION);
        if (operation == null || operation.length() == 0) {
            // standard create/modify operation;
            return modifyOperation;
        }

        // named operation, retrieve from map
        return postOperations.get(operation);
    }

    /**
     * compute redirect URL (SLING-126)
     *
     * @param ctx the post processor
     * @return the redirect location or <code>null</code>
     */
    protected String getRedirectUrl(HttpServletRequest request, HtmlResponse ctx) {
        // redirect param has priority (but see below, magic star)
        String result = request.getParameter(SlingPostConstants.RP_REDIRECT_TO);
        if (result != null && ctx.getPath() != null) {

            // redirect to created/modified Resource
            int star = result.indexOf('*');
            if (star >= 0) {
                StringBuffer buf = new StringBuffer();

                // anything before the star
                if (star > 0) {
                    buf.append(result.substring(0, star));
                }

                // append the name of the manipulated node
                buf.append(ResourceUtil.getName(ctx.getPath()));

                // anything after the star
                if (star < result.length() - 1) {
                    buf.append(result.substring(star + 1));
                }

                // use the created path as the redirect result
                result = buf.toString();

            } else if (result.endsWith(SlingPostConstants.DEFAULT_CREATE_SUFFIX)) {
                // if the redirect has a trailing slash, append modified node
                // name
                result = result.concat(ResourceUtil.getName(ctx.getPath()));
            }

            if (log.isDebugEnabled()) {
                log.debug("Will redirect to " + result);
            }
        }
        return result;
    }

    protected boolean isSetStatus(SlingHttpServletRequest request) {
        String statusParam = request.getParameter(SlingPostConstants.RP_STATUS);
        if (statusParam == null) {
            log.debug(
                "getStatusMode: Parameter {} not set, assuming standard status code",
                SlingPostConstants.RP_STATUS);
            return true;
        }

        if (SlingPostConstants.STATUS_VALUE_BROWSER.equals(statusParam)) {
            log.debug(
                "getStatusMode: Parameter {} asks for user-friendly status code",
                SlingPostConstants.RP_STATUS);
            return false;
        }

        if (SlingPostConstants.STATUS_VALUE_STANDARD.equals(statusParam)) {
            log.debug(
                "getStatusMode: Parameter {} asks for standard status code",
                SlingPostConstants.RP_STATUS);
            return true;
        }

        log.debug(
            "getStatusMode: Parameter {} set to unknown value {}, assuming standard status code",
            SlingPostConstants.RP_STATUS);
        return true;
    }

    // ---------- SCR Integration ----------------------------------------------

    protected void activate(ComponentContext context) {
        Dictionary<?, ?> props = context.getProperties();

        String[] nameHints = OsgiUtil.toStringArray(props.get(PROP_NODE_NAME_HINT_PROPERTIES));
        int nameMax = (int) OsgiUtil.toLong(
            props.get(PROP_NODE_NAME_MAX_LENGTH), -1);
        nodeNameGenerator = new NodeNameGenerator(nameHints, nameMax);

        dateParser = new DateParser();
        String[] dateFormats = OsgiUtil.toStringArray(props.get(PROP_DATE_FORMAT));
        for (String dateFormat : dateFormats) {
            dateParser.register(dateFormat);
        }
    }

    protected void deactivate(ComponentContext context) {
        nodeNameGenerator = null;
        dateParser = null;
    }
}
TOP

Related Classes of org.apache.sling.servlets.post.impl.SlingPostServlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.