protected Map collectContentMap()

in src/main/java/org/apache/sling/jackrabbit/usermanager/impl/post/AbstractAuthorizablePostServlet.java [243:353]


    protected Map<String, RequestProperty> collectContentMap(
            Map<String, ?> properties) {

        boolean requireItemPrefix = requireItemPathPrefix(properties);

        // walk the request parameters and collect the properties (the key is the property path).
        Map<String, RequestProperty> reqProperties = new HashMap<>();
        for (Map.Entry<String, ?> e : properties.entrySet()) {
            final String paramName = e.getKey();

            // do not store parameters with names starting with sling:post
            boolean skipParam = paramName.startsWith(SlingPostConstants.RP_PREFIX);
            // SLING-298: skip form encoding parameter
            if (paramName.equals("_charset_")) {
                skipParam = true;
            }
            // skip parameters that do not start with the save prefix
            if (requireItemPrefix && !hasItemPathPrefix(paramName)) {
                skipParam = true;
            }

            // ensure the paramName is an absolute property path (i.e. starts with "/", where root refers to the authorizable's root, https://issues.apache.org/jira/browse/SLING-1577)
            String propPath;
            if (paramName.startsWith("./")) {
                propPath = paramName.substring(1);
            } else {
                propPath = String.format("/%s", paramName);
            }

            if (propPath.indexOf("..") != -1) {
                // it is not supported to set properties potentially outside of the authorizable node
                LOG.warn("Property path containing '..' is not supported, skipping parameter {}", paramName);
                skipParam = true;
            }

            if (!skipParam) {
                // @TypeHint example
                // <input type="text" name="./age" />
                // <input type="hidden" name="./age@TypeHint" value="long" />
                // causes the setProperty using the 'long' property type
                if (propPath.endsWith(SlingPostConstants.TYPE_HINT_SUFFIX)) {
                    RequestProperty prop = getOrCreateRequestProperty(
                        reqProperties, propPath,
                        SlingPostConstants.TYPE_HINT_SUFFIX);

                    String typeHintValue = convertToString(e.getValue());
                    if (typeHintValue != null) {
                        prop.setTypeHintValue(typeHintValue);
                    }
                } else if (propPath.endsWith(SlingPostConstants.DEFAULT_VALUE_SUFFIX)) {
                    // @DefaultValue
                    RequestProperty prop = getOrCreateRequestProperty(
                        reqProperties, propPath,
                        SlingPostConstants.DEFAULT_VALUE_SUFFIX);

                    prop.setDefaultValues(convertToRequestParameterArray(e.getValue()));
                } else if (propPath.endsWith(SlingPostConstants.VALUE_FROM_SUFFIX)) {
                    // SLING-130: VALUE_FROM_SUFFIX means take the value of this
                    // property from a different field
                    // @ValueFrom example:
                    // <input name="./Text@ValueFrom" type="hidden" value="fulltext" />
                    // causes the JCR Text property to be set to the value of the
                    // fulltext form field.
                    RequestProperty prop = getOrCreateRequestProperty(
                        reqProperties, propPath,
                        SlingPostConstants.VALUE_FROM_SUFFIX);

                    // @ValueFrom params must have exactly one value, else ignored
                    String [] valueFrom = convertToStringArray(e.getValue());
                    if (valueFrom.length == 1) {
                        String refName = valueFrom[0];
                        prop.setValues(convertToRequestParameterArray(refName));
                    }
                } else if (propPath.endsWith(SlingPostConstants.SUFFIX_DELETE)) {
                    // SLING-458: Allow Removal of properties prior to update
                    // @Delete example:
                    // <input name="./Text@Delete" type="hidden" />
                    // causes the JCR Text property to be deleted before update
                    RequestProperty prop = getOrCreateRequestProperty(
                        reqProperties, propPath, SlingPostConstants.SUFFIX_DELETE);

                    prop.setDelete(true);
                } else if (propPath.endsWith(SlingPostConstants.SUFFIX_MOVE_FROM)) {
                    // SLING-455: @MoveFrom means moving content to another location
                    // @MoveFrom example:
                    // <input name="./Text@MoveFrom" type="hidden" value="/tmp/path" />
                    // causes the JCR Text property to be set by moving the /tmp/path
                    // property to Text.

                    // don't support @MoveFrom here
                    LOG.warn("Suffix {} not supported, skipping parameter {}", SlingPostConstants.SUFFIX_MOVE_FROM, paramName);
                } else if (propPath.endsWith(SlingPostConstants.SUFFIX_COPY_FROM)) {
                    // SLING-455: @CopyFrom means moving content to another location
                    // @CopyFrom example:
                    // <input name="./Text@CopyFrom" type="hidden" value="/tmp/path" />
                    // causes the JCR Text property to be set by copying the /tmp/path
                    // property to Text.

                    // don't support @CopyFrom here
                    LOG.warn("Suffix {} not supported, skipping parameter {}", SlingPostConstants.SUFFIX_COPY_FROM, paramName);
                } else {
                    // plain property, create from values
                    RequestProperty prop = getOrCreateRequestProperty(reqProperties,
                        propPath, null);
                    prop.setValues(convertToRequestParameterArray(e.getValue()));
                }
            }
        }

        return reqProperties;
    }