Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * 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.jackrabbit.usermanager.impl.post;
 
 import java.util.List;
 import java.util.Map;
 
 
 import  org.osgi.service.component.ComponentContext;
Base class for all the POST servlets for the UserManager operations
 
 public abstract class AbstractAuthorizablePostServlet extends
         SlingAllMethodsServlet {
     private static final long serialVersionUID = -5918670409789895333L;

    
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";
 
     private DateParser dateParser;
 
     // ---------- SCR Integration ----------------------------------------------
 
     protected void activate(ComponentContext context) {
         Dictionary<?, ?> props = context.getProperties();
 
          = new DateParser();
         String[] dateFormats = OsgiUtil.toStringArray(props.get());
         for (String dateFormat : dateFormats) {
             .register(dateFormat);
         }
     }
 
     protected void deactivate(ComponentContext context) {
          = null;
     }
 
     /*
      * (non-Javadoc)
      * @see
      * org.apache.sling.api.servlets.SlingAllMethodsServlet#doPost(org.apache
      * .sling.api.SlingHttpServletRequest,
      * org.apache.sling.api.SlingHttpServletResponse)
     */
    @Override
    protected void doPost(SlingHttpServletRequest request,
            SlingHttpServletResponse httpResponsethrows ServletException,
            IOException {
        // prepare the response
        HtmlResponse htmlResponse = new HtmlResponse();
        htmlResponse.setReferer(request.getHeader("referer"));
        // calculate the paths
        String path = getItemPath(request);
        htmlResponse.setPath(path);
        // location
        htmlResponse.setLocation(externalizePath(requestpath));
        // parent location
        path = ResourceUtil.getParent(path);
        if (path != null) {
            htmlResponse.setParentLocation(externalizePath(requestpath));
        }
        Session session = request.getResourceResolver().adaptTo(Session.class);
        final List<Modificationchanges = new ArrayList<Modification>();
        try {
            handleOperation(requesthtmlResponsechanges);
            // TODO: maybe handle SlingAuthorizablePostProcessor handlers here
            // set changes on html response
            for (Modification change : changes) {
                switch (change.getType()) {
                    case :
                        htmlResponse.onModified(change.getSource());
                        break;
                    case :
                        htmlResponse.onDeleted(change.getSource());
                        break;
                    case :
                        htmlResponse.onMoved(change.getSource(),
                            change.getDestination());
                        break;
                    case :
                        htmlResponse.onCopied(change.getSource(),
                            change.getDestination());
                        break;
                    case :
                        htmlResponse.onCreated(change.getSource());
                        break;
                    case :
                        htmlResponse.onChange("ordered"change.getSource(),
                            change.getDestination());
                        break;
                }
            }
            if (session.hasPendingChanges()) {
                session.save();
            }
        } catch (ResourceNotFoundException rnfe) {
            htmlResponse.setStatus(.,
                rnfe.getMessage());
        } catch (Throwable throwable) {
            .debug("Exception while handling POST "
                + request.getResource().getPath() + " with "
                + getClass().getName(), throwable);
            htmlResponse.setError(throwable);
        } finally {
            try {
                if (session.hasPendingChanges()) {
                    session.refresh(false);
                }
            } catch (RepositoryException e) {
                .warn("RepositoryException in finally block: {}",
                    e.getMessage(), e);
            }
        }
        // check for redirect URL if processing succeeded
        if (htmlResponse.isSuccessful()) {
            String redirect = getRedirectUrl(requesthtmlResponse);
            if (redirect != null) {
                httpResponse.sendRedirect(redirect);
                return;
            }
        }
        // create a html response and send if unsuccessful or no redirect
        htmlResponse.send(httpResponseisSetStatus(request));
    }

    
Extending Servlet should implement this operation to do the work

Parameters:
request the sling http request to process
htmlResponse the response
changes
    abstract protected void handleOperation(SlingHttpServletRequest request,
            HtmlResponse htmlResponseList<Modificationchanges)
            throws RepositoryException;

    
compute redirect URL (SLING-126)

Parameters:
ctx the post processor
Returns:
the redirect location or null
    protected String getRedirectUrl(HttpServletRequest requestHtmlResponse ctx) {
        // redirect param has priority (but see below, magic star)
        String result = request.getParameter(.);
        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(.)) {
                // if the redirect has a trailing slash, append modified node
                // name
                result = result.concat(ResourceUtil.getName(ctx.getPath()));
            }
            if (.isDebugEnabled()) {
                .debug("Will redirect to " + result);
            }
        }
        return result;
    }
    protected boolean isSetStatus(SlingHttpServletRequest request) {
        String statusParam = request.getParameter(.);
        if (statusParam == null) {
            .debug(
                "getStatusMode: Parameter {} not set, assuming standard status code",
                .);
            return true;
        }
        if (..equals(statusParam)) {
            .debug(
                "getStatusMode: Parameter {} asks for user-friendly status code",
                .);
            return false;
        }
        if (..equals(statusParam)) {
            .debug(
                "getStatusMode: Parameter {} asks for standard status code",
                .);
            return true;
        }
        .debug(
            "getStatusMode: Parameter {} set to unknown value {}, assuming standard status code",
            .);
        return true;
    }
    // ------ The methods below are based on the private methods from the
    // ModifyOperation class -----

    
Collects the properties that form the content to be written back to the repository. NOTE: In the returned map, the key is the property name not a path.

Throws:
RepositoryException if a repository error occurs
ServletException if an internal error occurs
            SlingHttpServletRequest requestHtmlResponse response) {
        boolean requireItemPrefix = requireItemPathPrefix(request);
        // walk the request parameters and collect the properties
        Map<StringRequestPropertyreqProperties = new HashMap<StringRequestProperty>();
        for (Map.Entry<StringRequestParameter[]> e : request.getRequestParameterMap().entrySet()) {
            final String paramName = e.getKey();
            // do not store parameters with names starting with sling:post
            if (paramName.startsWith(.)) {
                continue;
            }
            // SLING-298: skip form encoding parameter
            if (paramName.equals("_charset_")) {
                continue;
            }
            // skip parameters that do not start with the save prefix
            if (requireItemPrefix && !hasItemPathPrefix(paramName)) {
                continue;
            }
            // ensure the paramName is an absolute property name
            String propPath;
            if (paramName.startsWith("./")) {
                propPath = paramName.substring(2);
            } else {
                propPath = paramName;
            }
            if (propPath.indexOf('/') != -1) {
                // only one path segment is valid here, so this paramter can't
                // be used.
                continue// skip it.
            }
            // @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(.)) {
                RequestProperty prop = getOrCreateRequestProperty(
                    reqPropertiespropPath,
                    .);
                final RequestParameter[] rp = e.getValue();
                if (rp.length > 0) {
                    prop.setTypeHintValue(rp[0].getString());
                }
                continue;
            }
            // @DefaultValue
            if (propPath.endsWith(.)) {
                RequestProperty prop = getOrCreateRequestProperty(
                    reqPropertiespropPath,
                    .);
                prop.setDefaultValues(e.getValue());
                continue;
            }
            // 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.
            if (propPath.endsWith(.)) {
                RequestProperty prop = getOrCreateRequestProperty(
                    reqPropertiespropPath,
                    .);
                // @ValueFrom params must have exactly one value, else ignored
                if (e.getValue().length == 1) {
                    String refName = e.getValue()[0].getString();
                    RequestParameter[] refValues = request.getRequestParameters(refName);
                    if (refValues != null) {
                        prop.setValues(refValues);
                    }
                }
                continue;
            }
            // 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
            if (propPath.endsWith(.)) {
                RequestProperty prop = getOrCreateRequestProperty(
                    reqPropertiespropPath.);
                prop.setDelete(true);
                continue;
            }
            // 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.
            if (propPath.endsWith(.)) {
                // don't support @MoveFrom here
                continue;
            }
            // 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.
            if (propPath.endsWith(.)) {
                // don't support @CopyFrom here
                continue;
            }
            // plain property, create from values
            RequestProperty prop = getOrCreateRequestProperty(reqProperties,
                propPathnull);
            prop.setValues(e.getValue());
        }
        return reqProperties;
    }

    
Returns the request property for the given property path. If such a request property does not exist yet it is created and stored in the props.

Parameters:
props The map of already seen request properties.
paramName The absolute path of the property including the suffix to be looked up.
suffix The (optional) suffix to remove from the paramName before looking it up.
Returns:
The RequestProperty for the paramName.
            Map<StringRequestPropertypropsString paramNameString suffix) {
        if (suffix != null && paramName.endsWith(suffix)) {
            paramName = paramName.substring(0, paramName.length()
                - suffix.length());
        }
        RequestProperty prop = props.get(paramName);
        if (prop == null) {
            prop = new RequestProperty(paramName);
            props.put(paramNameprop);
        }
        return prop;
    }

    
Removes all properties listed as RequestProperty.isDelete() from the authorizable.

Parameters:
authorizable The org.apache.jackrabbit.api.security.user.Authorizable that should have properties deleted.
reqProperties The map of request properties to check for properties to be removed.
response The HtmlResponse to be updated with information on deleted properties.
Throws:
RepositoryException Is thrown if an error occurrs checking or removing properties.
    protected void processDeletes(Authorizable resource,
            Map<StringRequestPropertyreqProperties,
            List<Modificationchangesthrows RepositoryException {
        for (RequestProperty property : reqProperties.values()) {
            if (property.isDelete()) {
                if (resource.hasProperty(property.getName())) {
                    resource.removeProperty(property.getName());
                    changes.add(Modification.onDeleted(property.getPath()));
                }
            }
        }
    }

    
Writes back the content

Throws:
RepositoryException if a repository error occurs
ServletException if an internal error occurs
    protected void writeContent(Session sessionAuthorizable authorizable,
            Map<StringRequestPropertyreqProperties,
            List<Modificationchangesthrows RepositoryException {
        for (RequestProperty prop : reqProperties.values()) {
            if (prop.hasValues()) {
                // skip jcr special properties
                if (prop.getName().equals("jcr:primaryType")
                    || prop.getName().equals("jcr:mixinTypes")) {
                    continue;
                }
                if (authorizable.isGroup()) {
                    if (prop.getName().equals("groupId")) {
                        // skip these
                        continue;
                    }
                } else {
                    if (prop.getName().equals("userId")
                        || prop.getName().equals("pwd")
                        || prop.getName().equals("pwdConfirm")) {
                        // skip these
                        continue;
                    }
                }
                if (prop.isFileUpload()) {
                    // don't handle files for user properties for now.
                    continue;
                    // uploadHandler.setFile(parent, prop, changes);
                } else {
                    setPropertyAsIs(sessionauthorizablepropchanges);
                }
            }
        }
    }

    
set property without processing, except for type hints

Parameters:
parent the parent node
prop the request property
Throws:
RepositoryException if a repository error occurs.
    private void setPropertyAsIs(Session sessionAuthorizable parent,
            RequestProperty propList<Modificationchanges)
            throws RepositoryException {
        String parentPath;
        if (parent.isGroup()) {
                + parent.getID();
        } else {
                + parent.getID();
        }
        // no explicit typehint
        int type = .;
        if (prop.getTypeHint() != null) {
            try {
                type = PropertyType.valueFromName(prop.getTypeHint());
            } catch (Exception e) {
                // ignore
            }
        }
        String[] values = prop.getStringValues();
        if (values == null) {
            // remove property
            boolean removedProp = removePropertyIfExists(parentprop.getName());
            if (removedProp) {
                changes.add(Modification.onDeleted(parentPath + "/"
                    + prop.getName()));
            }
        } else if (values.length == 0) {
            // do not create new prop here, but clear existing
            if (parent.hasProperty(prop.getName())) {
                Value val = session.getValueFactory().createValue("");
                parent.setProperty(prop.getName(), val);
                changes.add(Modification.onModified(parentPath + "/"
                    + prop.getName()));
            }
        } else if (values.length == 1) {
            boolean removedProp = removePropertyIfExists(parentprop.getName());
            // if the provided value is the empty string, we don't have to do
            // anything.
            if (values[0].length() == 0) {
                if (removedProp) {
                    changes.add(Modification.onDeleted(parentPath + "/"
                        + prop.getName()));
                }
            } else {
                // modify property
                if (type == .) {
                    // try conversion
                    Calendar c = .parse(values[0]);
                    if (c != null) {
                        if (prop.hasMultiValueTypeHint()) {
                            final Value[] array = new Value[1];
                            array[0] = session.getValueFactory().createValue(c);
                            parent.setProperty(prop.getName(), array);
                            changes.add(Modification.onModified(parentPath
                                + "/" + prop.getName()));
                        } else {
                            Value cVal = session.getValueFactory().createValue(
                                c);
                            parent.setProperty(prop.getName(), cVal);
                            changes.add(Modification.onModified(parentPath
                                + "/" + prop.getName()));
                        }
                        return;
                    }
                    // fall back to default behaviour
                }
                if (type == .) {
                    Value val = session.getValueFactory().createValue(
                        values[0], .);
                    parent.setProperty(prop.getName(), val);
                } else {
                    if (prop.hasMultiValueTypeHint()) {
                        final Value[] array = new Value[1];
                        array[0] = session.getValueFactory().createValue(
                            values[0], type);
                        parent.setProperty(prop.getName(), array);
                    } else {
                        Value val = session.getValueFactory().createValue(
                            values[0], type);
                        parent.setProperty(prop.getName(), val);
                    }
                }
                changes.add(Modification.onModified(parentPath + "/"
                    + prop.getName()));
            }
        } else {
            removePropertyIfExists(parentprop.getName());
            if (type == .) {
                // try conversion
                ValueFactory valFac = session.getValueFactory();
                Value[] c = .parse(valuesvalFac);
                if (c != null) {
                    parent.setProperty(prop.getName(), c);
                    changes.add(Modification.onModified(parentPath + "/"
                        + prop.getName()));
                    return;
                }
                // fall back to default behaviour
            }
            Value[] vals = new Value[values.length];
            if (type == .) {
                for (int i = 0; i < values.lengthi++) {
                    vals[i] = session.getValueFactory().createValue(values[i]);
                }
            } else {
                for (int i = 0; i < values.lengthi++) {
                    vals[i] = session.getValueFactory().createValue(values[i],
                        type);
                }
            }
            parent.setProperty(prop.getName(), vals);
            changes.add(Modification.onModified(parentPath + "/"
                + prop.getName()));
        }
    }

    
Removes the property with the given name from the parent resource if it exists.

Parameters:
parent the parent resource
name the name of the property to remove
Returns:
path of the property that was removed or null if it was not removed
Throws:
RepositoryException if a repository error occurs.
    private boolean removePropertyIfExists(Authorizable resourceString name)
            throws RepositoryException {
        if (resource.getProperty(name) != null) {
            resource.removeProperty(name);
            return true;
        }
        return false;
    }
    // ------ These methods were copied from AbstractSlingPostOperation ------

    
Returns the path of the resource of the request as the item path.

This method may be overwritten by extension if the operation has different requirements on path processing.

    protected String getItemPath(SlingHttpServletRequest request) {
        return request.getResource().getPath();
    }

    
Returns an external form of the given path prepending the context path and appending a display extension.

Parameters:
path the path to externalize
Returns:
the url
    protected final String externalizePath(SlingHttpServletRequest request,
            String path) {
        StringBuffer ret = new StringBuffer();
        ret.append(SlingRequestPaths.getContextPath(request));
        ret.append(request.getResourceResolver().map(path));
        // append optional extension
        if (ext != null && ext.length() > 0) {
            if (ext.charAt(0) != '.') {
                ret.append('.');
            }
            ret.append(ext);
        }
        return ret.toString();
    }

    
Returns true if the name starts with either of the prefixes ./, ../ and /.
    protected boolean hasItemPathPrefix(String name) {
    }

    
Returns true if any of the request parameters starts with ./. In this case only parameters starting with either of the prefixes ./, ../ and / are considered as providing content to be stored. Otherwise all parameters not starting with the command prefix : are considered as parameters to be stored.
    protected final boolean requireItemPathPrefix(
            SlingHttpServletRequest request) {
        boolean requirePrefix = false;
        Enumeration<?> names = request.getParameterNames();
        while (names.hasMoreElements() && !requirePrefix) {
            String name = (Stringnames.nextElement();
            requirePrefix = name.startsWith(.);
        }
        return requirePrefix;
    }
New to GrepCode? Check out our FAQ X