POST.jsp 9.77 KB
<%--
  ADOBE CONFIDENTIAL

  Copyright 2012 Adobe Systems Incorporated
  All Rights Reserved.

  NOTICE:  All information contained herein is, and remains
  the property of Adobe Systems Incorporated and its suppliers,
  if any.  The intellectual and technical concepts contained
  herein are proprietary to Adobe Systems Incorporated and its
  suppliers and may be covered by U.S. and Foreign Patents,
  patents in process, and are protected by trade secret or copyright law.
  Dissemination of this information or reproduction of this material
  is strictly forbidden unless prior written permission is obtained
  from Adobe Systems Incorporated.
--%><%
%><%@include file="/libs/granite/ui/global.jsp"%><%
%><%@page session="false"
          import="java.util.ArrayList,
                  java.util.Enumeration,
                  java.util.List,
                  java.util.Locale,
                  javax.jcr.Node,
                  javax.jcr.PropertyType,
                  org.apache.commons.lang.StringUtils,
                  org.apache.jackrabbit.util.Text,
                  org.apache.sling.api.resource.Resource,
                  org.apache.sling.api.resource.ResourceResolver,
                  org.apache.sling.api.resource.ValueMap,
                  org.apache.sling.servlets.post.SlingPostConstants,
                  com.day.cq.commons.servlets.HtmlStatusResponseHelper,
                  org.apache.sling.api.servlets.HtmlResponse,
                  com.day.cq.tagging.Tag,
                  com.day.cq.tagging.TagManager,
                  com.day.cq.wcm.api.Page,
                  com.day.cq.wcm.api.PageManager,
                  com.day.cq.commons.jcr.JcrUtil"%><%

    PageManager pageManager = resourceResolver.adaptTo(PageManager.class);

    HtmlResponse htmlResponse = null;

    if (pageManager == null) {
        log.error("Page manager is not available");

        htmlResponse = HtmlStatusResponseHelper.createStatusResponse(false, i18n.get("Page manager is not available."));
        htmlResponse.send(response, true);

        return;
    }

    try {
        String parentPath = request.getParameter("parentPath");
        String pageLabel = request.getParameter("pageName");
        String template = request.getParameter("template");
        String pageTitle = request.getParameter("./jcr:title");

        if (StringUtils.isBlank(pageTitle)) {
            pageTitle = request.getParameter("pageTitle");
        }

        Page p = pageManager.create(parentPath, pageLabel, template, pageTitle, false);

        String redirectUrl = request.getContextPath() + getAdminUrl(resource.getParent().adaptTo(Page.class)) + Text.escapePath(parentPath);
        String openUrl = request.getContextPath() + "/bin/wcmcommand?cmd=open&_charset_=utf-8&path=" + Text.escape(p.getPath());


        TagManager tagManager = resourceResolver.adaptTo(TagManager.class);

        Resource contentResource = p.getContentResource();

        if (contentResource != null) {
            Node contentNode = contentResource.adaptTo(Node.class);

            // TODO most probably better to create a util for this, similar to sling post servlet
            // TODO or improve the WCM command servlet to handle additional properties.

            processDeletes(contentNode, request);
            writeContent(contentNode, request);

            List<String> tagsParameters = getTagRequestParameters(request);
            for (String name : tagsParameters) {
                List<String> processedTags = getProcessedTags(tagManager, name, request);
                if (!processedTags.isEmpty()) {
                    Node finalNode = getParentNode(contentNode, name);
                    String propertyName = getPropertyName(name);
                    finalNode.setProperty(propertyName, processedTags.toArray(new String[0]));
                }
            }

            contentNode.getSession().save();
        }

        htmlResponse = HtmlStatusResponseHelper.createStatusResponse(true, i18n.get("Page created"), p.getPath());

    } catch (Exception e) {
        log.error("Error occur creating a new page", e);

        htmlResponse = HtmlStatusResponseHelper.createStatusResponse(false, i18n.get("Cannot create page ({0})", null, e.getMessage()));
    }
    htmlResponse.send(response, true);

%><%!
    private String getAdminUrl(Page page) {
        String url = page.getVanityUrl();

        if (url == null) {
            ValueMap vm = page.getProperties();
            if (vm.containsKey("sling:vanityPath")) {
                url = page.getProperties().get("sling:vanityPath", String.class);
            }
        }

        if (url == null) {
            url = Text.escapePath(page.getPath());
        }

        return url + ".html";
    }

    /**
     * Copied from Sling. Later on Sling POST Servlet will be refactored to provide a generic service for this.
     */
    private void processDeletes(final Node parentNode, final HttpServletRequest req) throws Exception {
        for (Enumeration en = req.getParameterNames(); en.hasMoreElements();) {
            String name = en.nextElement().toString();

            if (!name.startsWith("./")) continue;
            if (!name.endsWith(SlingPostConstants.SUFFIX_DELETE)) continue;

            if (parentNode.hasProperty(name)) {
                parentNode.getProperty(name).remove();
            } else if (parentNode.hasNode(name)) {
                parentNode.getNode(name).remove();
            }
        }
    }

    /**
     * Copied from Sling. Later on Sling POST Servlet will be refactored to provide a generic service for this.
     */
    private void writeContent(final Node parentNode, final HttpServletRequest req) throws Exception {
        for (Enumeration en = req.getParameterNames(); en.hasMoreElements();) {
            String name = en.nextElement().toString();

            if (!name.startsWith("./")) continue;
            // ignore all tags, they are handled separately
            if (name.indexOf("cq:tags") > 0) continue;
            if (name.startsWith("jcr:primaryType")) continue;
            if (name.startsWith("jcr:mixinTypes")) continue;

            String[] values = req.getParameterValues(name);

            String typeHint = req.getParameter(name + SlingPostConstants.TYPE_HINT_SUFFIX);
            boolean multiple = false;

            if (typeHint != null && typeHint.endsWith("[]")) {
                typeHint = typeHint.substring(0, typeHint.length() - "[]".length());
                multiple = true;
            }

            int type = PropertyType.STRING;
            if (typeHint != null) {
                type = PropertyType.valueFromName(typeHint);
            }

            List<String> jcrValues = new ArrayList<String>();

            for (String value : values) {
                if (value.length() > 0) {
                    jcrValues.add(value);
                }
            }

            multiple = multiple || jcrValues.size() > 1;

            String n = getPropertyName(name);
            Node finalNode = getParentNode(parentNode, name);

            if (multiple) {
                finalNode.setProperty(n, jcrValues.toArray(new String[0]), type);
            } else if (!jcrValues.isEmpty()) {
                finalNode.setProperty(n, jcrValues.get(0), type);
            }
        }
    }

    private List<String> getProcessedTags(TagManager tagManager, String name, final HttpServletRequest req)
            throws Exception {
        List<String> processedTags = new ArrayList<String>();

        if (tagManager != null) {
            String[] tags = req.getParameterValues(name);

            if (tags != null) {
                for (String tagId : tags) {
                    if (tagId.length() == 0) continue;

                    if (tagId.indexOf(":") < 0) {
                        Tag tag = tagManager.createTagByTitle(tagId, Locale.ENGLISH); // This is fixed to "en" in old siteadmin also
                        tagId = tag.getTagID();
                    }

                    processedTags.add(tagId);
                }
            }
        }
        return processedTags;
    }

    /**
     * Find all cq:tags parameters as they have to be handled separated
     * @param req
     * @return
     * @throws Exception
     */
    private List<String> getTagRequestParameters(final HttpServletRequest req) throws Exception {
        List<String> tagsParameters = new ArrayList<String>();
        for (Enumeration en = req.getParameterNames(); en.hasMoreElements();) {
            String name = en.nextElement().toString();
            if (name.endsWith("cq:tags")) {
                tagsParameters.add(name);
            }
        }
        return tagsParameters;
    }

    /**
     * Get property name for repository
     * @param name
     * @return
     * @throws Exception
     */
    private String getPropertyName(String name) throws Exception {
        if (name.startsWith("./")) {
            name = name.substring("./".length());

            if (name.indexOf("/") > -1) {
                name = name.substring(name.lastIndexOf("/") + 1);
            }
        }
        return name;
    }

    /**
     * Get the parent node
     * If the parent doesn't exist, create it
     * @param parentNode
     * @param name
     * @return
     * @throws Exception
     */
    private Node getParentNode(Node parentNode, String name) throws Exception {
        if (name.startsWith("./")) {
            name = name.substring("./".length());

            if (name.indexOf("/") > -1) {
                String relPath = name.substring(0, name.lastIndexOf("/"));
                if (parentNode.hasNode(relPath)) {
                    parentNode = parentNode.getNode(relPath);
                } else {
                    parentNode = JcrUtil.createPath(parentNode.getPath() + "/" + relPath, "nt:unstructured",
                            parentNode.getSession());
                }
            }
        }

        return parentNode;
    }
%>