org.jsecurity.web.attr.AbstractWebAttribute.java Source code

Java tutorial

Introduction

Here is the source code for org.jsecurity.web.attr.AbstractWebAttribute.java

Source

/*
 * 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.jsecurity.web.attr;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jsecurity.JSecurityException;
import org.jsecurity.util.ClassUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.beans.PropertyEditor;

/**
 * Convenient superclass for implementations of the {@link WebAttribute} interface.  This class encapsulates
 * converting values from a String form to Object form and vice versa through the use of a <tt>PropertyEditor</tt>
 * configured using {@link #setEditorClass(Class)}.  Subclasses are expected to implement the
 * {@link #onStoreValue(Object, javax.servlet.ServletRequest, javax.servlet.ServletResponse)} and
 * {@link #onRetrieveValue(javax.servlet.ServletRequest, javax.servlet.ServletResponse)}
 * methods that perform the actual storing and retrieving of a String value.  This class also contains convenience
 * methods for retrieving the value of a request parameter to be stored.
 *
 * @author Les Hazlewood
 * @since 0.2
 */
public abstract class AbstractWebAttribute<T> implements WebAttribute<T> {

    //TODO - complete JavaDoc

    public static final String DEFAULT_NAME = "name";

    private static final Log log = LogFactory.getLog(AbstractWebAttribute.class);

    protected String name = DEFAULT_NAME;

    protected boolean checkRequestParams = true;
    protected boolean checkRequestParamsFirst = true;

    protected boolean mutable = true;

    /**
     * Property editor class to use to convert attributes to and from strings.
     */
    private Class<? extends PropertyEditor> editorClass = null;

    public AbstractWebAttribute() {
        this(DEFAULT_NAME, true);
    }

    public AbstractWebAttribute(String name) {
        this(name, true);
    }

    public AbstractWebAttribute(String name, boolean checkRequestParams) {
        setName(name);
        setCheckRequestParams(checkRequestParams);
    }

    public AbstractWebAttribute(String name, Class<? extends PropertyEditor> editorClass) {
        this(name, true, editorClass);
    }

    public AbstractWebAttribute(String name, boolean checkRequestParams,
            Class<? extends PropertyEditor> editorClass) {
        setName(name);
        setCheckRequestParams(checkRequestParams);
        setEditorClass(editorClass);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isCheckRequestParams() {
        return checkRequestParams;
    }

    public void setCheckRequestParams(boolean checkRequestParams) {
        this.checkRequestParams = checkRequestParams;
    }

    public boolean isCheckRequestParamsFirst() {
        return checkRequestParamsFirst;
    }

    public void setCheckRequestParamsFirst(boolean checkRequestParamsFirst) {
        this.checkRequestParamsFirst = checkRequestParamsFirst;
    }

    public Class<? extends PropertyEditor> getEditorClass() {
        return editorClass;
    }

    /**
     * If set, an instance of this class will be used to convert a the object value to a string value (and vice versa)
     * when reading and populating values in
     * {@link javax.servlet.http.HttpServletRequest HttpServletRequest}s, {@link javax.servlet.http.Cookie Cookie}s or
     * {@link javax.servlet.http.HttpSession HttpSession}s.
     *
     * <p>If not set, the string itself will be used.
     *
     * @param editorClass {@link PropertyEditor PropertyEditor} implementation used to
     *                    convert between string values and sessionId objects.
     */
    public void setEditorClass(Class<? extends PropertyEditor> editorClass) {
        this.editorClass = editorClass;
    }

    /**
     * Returns <tt>true</tt> if the value stored can be changed once it has been set, <tt>false</tt> if it cannot.
     * <p>Default is <tt>true</tt>.
     *
     * @return <tt>true</tt> if the value stored can be changed once it has been set, <tt>false</tt> if it cannot.
     */
    public boolean isMutable() {
        return mutable;
    }

    public void setMutable(boolean mutable) {
        this.mutable = mutable;
    }

    @SuppressWarnings({ "unchecked" })
    protected T fromStringValue(String stringValue) {
        Class clazz = getEditorClass();
        if (clazz == null) {
            try {
                return (T) stringValue;
            } catch (Exception e) {
                String msg = "If the type is not String, you must specify the 'editorClass' property.";
                throw new JSecurityException(msg, e);
            }
        } else {
            PropertyEditor editor = (PropertyEditor) ClassUtils.newInstance(getEditorClass());
            editor.setAsText(stringValue);
            Object value = editor.getValue();
            try {
                return (T) value;
            } catch (ClassCastException e) {
                String msg = "Returned value from PropertyEditor does not match the specified type.";
                throw new JSecurityException(msg, e);
            }
        }
    }

    protected String toStringValue(T value) {
        Class clazz = getEditorClass();
        if (clazz == null) {

            if (log.isDebugEnabled()) {
                log.debug("No 'editorClass' property set - returning value.toString() as the string value for "
                        + "method argument.");
            }
            return value.toString();
        } else {
            PropertyEditor editor = (PropertyEditor) ClassUtils.newInstance(getEditorClass());
            editor.setValue(value);
            return editor.getAsText();
        }
    }

    protected T getFromRequestParam(ServletRequest request) {
        T value = null;

        String paramName = getName();
        String paramValue = request.getParameter(paramName);
        if (paramValue != null) {
            if (log.isTraceEnabled()) {
                log.trace("Found string value [" + paramValue + "] from HttpServletRequest parameter [" + paramName
                        + "]");
            }
            value = fromStringValue(paramValue);
        } else {
            if (log.isTraceEnabled()) {
                log.trace("No string value found in the HttpServletRequest under parameter named [" + paramName
                        + "]");
            }
        }

        return value;
    }

    public final T retrieveValue(ServletRequest request, ServletResponse response) {
        T value = null;
        if (isCheckRequestParams() && isCheckRequestParamsFirst()) {
            value = getFromRequestParam(request);
        }

        if (value == null) {
            value = onRetrieveValue(request, response);
        }

        if (value == null) {
            if (isCheckRequestParams() && !isCheckRequestParamsFirst()) {
                value = getFromRequestParam(request);
            }
        }

        return value;
    }

    protected abstract T onRetrieveValue(ServletRequest request, ServletResponse response);

    public void storeValue(T value, ServletRequest request, ServletResponse response) {
        if (value == null && isMutable()) {
            removeValue(request, response);
            return;
        }

        if (!isMutable()) {
            Object existing = onRetrieveValue(request, response);
            if (existing != null) {
                if (log.isDebugEnabled()) {
                    log.debug("Found existing value stored under name [" + getName() + "].  Ignoring new "
                            + "storage request - this store is immutable after the value has initially been set.");
                }
            }
            return;
        }

        onStoreValue(value, request, response);
    }

    protected abstract void onStoreValue(T value, ServletRequest request, ServletResponse response);
}