org.soybeanMilk.web.os.DefaultWebObjectSource.java Source code

Java tutorial

Introduction

Here is the source code for org.soybeanMilk.web.os.DefaultWebObjectSource.java

Source

/**
 * Licensed 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.soybeanMilk.web.os;

import java.io.Serializable;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Map;
import java.util.Set;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.soybeanMilk.SbmUtils;
import org.soybeanMilk.core.ObjectSourceException;
import org.soybeanMilk.core.bean.ConvertException;
import org.soybeanMilk.core.bean.GenericConverter;
import org.soybeanMilk.core.bean.MapConvertException;
import org.soybeanMilk.core.os.ConvertableObjectSource;
import org.soybeanMilk.web.WebConstants;
import org.soybeanMilk.web.WebObjectSource;
import org.soybeanMilk.web.bean.WebGenericConverter;

/**
 * Web?{@linkplain WebObjectSource Web?}
 * Servlet{@linkplain HttpServletRequest}?{@linkplain HttpSession}?{@linkplain ServletContext}?
 * <p>
 * Web???{@linkplain #get(Serializable, Type)}??????
 * ?????
 * </p>
 * <p>
 * ????????[].?'.'
 * ?????
 * ???somePrefix.someBean.propertyA?somePrefix.someBean.propertyB??
 * somePrefix.someBean?Web????propertyA?propertyB?
 * </p>
 * <p>
 * Web?????{@linkplain WebGenericConverter Web?}?
 * </p>
 * <p>
 * ?Web?{@linkplain #set(Serializable, Object)}?{@linkplain HttpServletRequest}
 * </p>
 * <p>
 * Web???param??request??session??application??response??objectSource?
 * <ul>
 *     <li>
 *         param<br>
 *         ??Web????param.someKey????
 *     </li>
 *     <li>
 *         request<br>
 *         {@linkplain HttpServletRequest}?Web???
 *         ?request.someKey?????
 *     </li>
 *     <li>
 *         session<br>
 *         {@linkplain HttpSession}?Web????
 *         ?session.someKey???????
 *     </li>
 *     <li>
 *         application<br>
 *         {@linkplain ServletContext}?Web???
 *         ?application.someKey?????
 *     </li>
 *     <li>
 *         response<br>
 *         {@linkplain HttpServletResponse}?Web????
 *     </li>
 *     <li>
 *         objectSource<br>
 *         {@linkplain WebObjectSource Web?}???Web?
 *     </li>
 * </ul>
 * ??Web??request??session??application??response??objectSource???
 * ?Web?{@linkplain WebGenericConverter Web?}?
 * </p>
 * @author earthangry@gmail.com
 * @date 2010-7-19
 */
public class DefaultWebObjectSource extends ConvertableObjectSource implements WebObjectSource {
    private static Log log = LogFactory.getLog(DefaultWebObjectSource.class);

    private HttpServletRequest request;
    private HttpServletResponse response;
    private ServletContext application;

    public DefaultWebObjectSource() {
        super();
    }

    public DefaultWebObjectSource(HttpServletRequest request, HttpServletResponse response,
            ServletContext application) {
        this(request, response, application, null);
    }

    public DefaultWebObjectSource(HttpServletRequest request, HttpServletResponse response,
            ServletContext application, GenericConverter genericConverter) {
        super();
        this.request = request;
        this.response = response;
        this.application = application;
        super.setGenericConverter(genericConverter);
    }

    public HttpServletRequest getRequest() {
        return request;
    }

    /**
     * ?{@linkplain HttpServletRequest }
     * @param request
     * @date 2011-12-11
     */
    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }

    public HttpServletResponse getResponse() {
        return response;
    }

    /**
     * ?{@linkplain HttpServletResponse ?}
     * @param response
     * @date 2011-12-11
     */
    public void setResponse(HttpServletResponse response) {
        this.response = response;
    }

    public ServletContext getApplication() {
        return application;
    }

    /**
     * {@linkplain ServletContext Servlet}
     * @param application
     * @date 2011-12-11
     */
    public void setApplication(ServletContext application) {
        this.application = application;
    }

    //@Override
    @SuppressWarnings("unchecked")
    public <T> T get(Serializable key) throws ObjectSourceException {
        return (T) getObject(key, null);
    }

    //@Override
    @SuppressWarnings("unchecked")
    public <T> T get(Serializable key, Type expectType) throws ObjectSourceException {
        return (T) getObject(key, expectType);
    }

    //@Override
    public void set(Serializable key, Object obj) throws ObjectSourceException {
        if (key == null)
            throw new IllegalArgumentException("[key] must not be null");

        String strKey = (key instanceof String ? (String) key : key.toString());
        String[] scopedKeys = SbmUtils.splitByFirstAccessor(strKey);

        if (WebConstants.Scope.REQUEST.equalsIgnoreCase(scopedKeys[0])) {
            if (scopedKeys.length > 1)
                getRequest().setAttribute(scopedKeys[1], obj);
            else
                throw new ObjectSourceException(
                        "key " + SbmUtils.toString(key) + " is illegal, you can not replace "
                                + SbmUtils.toString(WebConstants.Scope.REQUEST) + " scope object");
        } else if (WebConstants.Scope.SESSION.equalsIgnoreCase(scopedKeys[0])) {
            if (scopedKeys.length > 1)
                getRequest().getSession().setAttribute(scopedKeys[1], obj);
            else
                throw new ObjectSourceException(
                        "key " + SbmUtils.toString(key) + " is illegal, you can not replace "
                                + SbmUtils.toString(WebConstants.Scope.SESSION) + " scope object");
        } else if (WebConstants.Scope.APPLICATION.equalsIgnoreCase(scopedKeys[0])) {
            if (scopedKeys.length > 1)
                getApplication().setAttribute(scopedKeys[1], obj);
            else
                throw new ObjectSourceException(
                        "key " + SbmUtils.toString(key) + " is illegal, you can not replace "
                                + SbmUtils.toString(WebConstants.Scope.APPLICATION) + " scope object");
        } else if (WebConstants.Scope.PARAM.equalsIgnoreCase(scopedKeys[0])) {
            throw new ObjectSourceException("key " + SbmUtils.toString(key) + " is illegal, set object to "
                    + SbmUtils.toString(WebConstants.Scope.PARAM) + " scope is not supported");
        } else if (WebConstants.Scope.RESPONSE.equalsIgnoreCase(scopedKeys[0])) {
            throw new ObjectSourceException("key " + SbmUtils.toString(key) + " is illegal, set object to "
                    + SbmUtils.toString(WebConstants.Scope.RESPONSE) + " scope is not supported");
        } else if (WebConstants.Scope.OBJECT_SOURCE.equalsIgnoreCase(scopedKeys[0])) {
            throw new ObjectSourceException("key " + SbmUtils.toString(key) + " is illegal, set object to "
                    + SbmUtils.toString(WebConstants.Scope.OBJECT_SOURCE) + " scope is not supported");
        } else
            setObjectWithScopeUnknownKey(strKey, obj);

        if (log.isDebugEnabled())
            log.debug("set object " + SbmUtils.toString(obj) + " to " + SbmUtils.toString(this) + " with key "
                    + SbmUtils.toString(strKey));
    }

    /**
     * ?
     * @param key
     * @param expectType
     * @return
     * @throws ObjectSourceException
     * @date 2012-5-16
     */
    @SuppressWarnings("unchecked")
    protected Object getObject(Serializable key, Type expectType) throws ObjectSourceException {
        if (key == null)
            throw new ObjectSourceException("[key] must not be null");

        Object result = null;

        String strKey = (key instanceof String ? (String) key : key.toString());
        String[] scopedKeys = SbmUtils.splitByFirstAccessor(strKey);

        if (WebConstants.Scope.PARAM.equalsIgnoreCase(scopedKeys[0])) {
            result = getParamFilterValue(getRequest().getParameterMap(),
                    (scopedKeys.length > 1 ? scopedKeys[1] : null), expectType);
        } else if (WebConstants.Scope.REQUEST.equalsIgnoreCase(scopedKeys[0])) {
            if (scopedKeys.length > 1)
                result = getRequest().getAttribute(scopedKeys[1]);
            else
                result = getRequest();
        } else if (WebConstants.Scope.SESSION.equalsIgnoreCase(scopedKeys[0])) {
            if (scopedKeys.length > 1)
                result = getRequest().getSession().getAttribute(scopedKeys[1]);
            else
                result = getRequest().getSession();
        } else if (WebConstants.Scope.APPLICATION.equalsIgnoreCase(scopedKeys[0])) {
            if (scopedKeys.length > 1)
                result = getApplication().getAttribute(scopedKeys[1]);
            else
                result = getApplication();
        } else if (WebConstants.Scope.RESPONSE.equalsIgnoreCase(scopedKeys[0])) {
            if (scopedKeys.length > 1)
                throw new ObjectSourceException("key " + SbmUtils.toString(key) + " is illegal, get object from "
                        + HttpServletResponse.class.getSimpleName() + " is not supported");
            else
                result = getResponse();
        } else if (WebConstants.Scope.OBJECT_SOURCE.equalsIgnoreCase(scopedKeys[0])) {
            if (scopedKeys.length > 1)
                throw new ObjectSourceException("key " + SbmUtils.toString(key) + " is illegal, get object from "
                        + WebObjectSource.class.getSimpleName() + " is not supported");
            else
                result = this;
        } else {
            result = getObjectWithScopeUnknownKey(strKey, expectType);
        }

        result = convertGotObject(result, expectType);

        if (log.isDebugEnabled())
            log.debug("got object " + SbmUtils.toString(result) + " from " + SbmUtils.toString(this) + " with key "
                    + SbmUtils.toString(strKey));

        return result;
    }

    /**
     * ????
     * @param key 
     * @param expectType 
     * @return
     * @date 2012-3-24
     */
    @SuppressWarnings("unchecked")
    protected Object getObjectWithScopeUnknownKey(String key, Type expectType) throws ObjectSourceException {
        Object result = getRequest().getAttribute(key);

        if (result == null) {
            result = getRequest().getSession().getAttribute(key);

            if (result == null) {
                result = getApplication().getAttribute(key);

                if (result == null)
                    result = getParamFilterValue(getRequest().getParameterMap(), key, expectType);
            }
        }
        return result;
    }

    /**
     * ??
     * @param key 
     * @param value
     * @date 2012-3-24
     */
    protected void setObjectWithScopeUnknownKey(String key, Object value) throws ObjectSourceException {
        getRequest().setAttribute(key, value);
    }

    /**
     * ????
     * @param paramMap ?
     * @param paramNameFilter ???????<code>null</code>??
     * @param expectType 
     * @return
     */
    protected ParamFilterValue getParamFilterValue(Map<String, ?> paramMap, String paramNameFilter,
            Type expectType) {
        ParamFilterValue result = null;

        if (paramNameFilter == null || paramNameFilter.length() == 0) {
            result = new ParamFilterValue(paramNameFilter, paramMap);
        } else {
            Object explictValue = paramMap.get(paramNameFilter);

            if (explictValue != null || isSingleParamValue(expectType)) {
                result = new ParamFilterValue(paramNameFilter, explictValue);
            } else {
                //?
                paramNameFilter = paramNameFilter + WebConstants.ACCESSOR;
                Map<String, Object> fm = new ParamFilterMap<Object>();
                int fl = paramNameFilter.length();

                Set<String> keys = paramMap.keySet();

                for (String key : keys) {
                    if (key != null && key.length() > fl && key.startsWith(paramNameFilter))
                        fm.put(key.substring(fl), paramMap.get(key));
                }

                result = new ParamFilterValue(paramNameFilter, (fm.size() == 0 ? null : fm));
            }
        }

        return result;
    }

    /**
     * ???
     * @param type
     * @return
     * @date 2012-5-25
     */
    protected boolean isSingleParamValue(Type type) {
        if (!SbmUtils.isClassType(type))
            return false;
        else {
            Class<?> clazz = SbmUtils.narrowToClass(type);

            if (clazz.isPrimitive())
                return true;
            else if (Boolean.class.equals(type) || Integer.class.equals(type) || Long.class.equals(type)
                    || Float.class.equals(type) || Double.class.equals(type) || BigInteger.class.equals(type)
                    || BigDecimal.class.equals(type) || Character.class.equals(type) || Byte.class.equals(type)
                    || Short.class.equals(type))
                return true;
            else
                return false;
        }
    }

    /**
     * ???
     * @param sourceObj
     * @param targetType
     * @return
     * @date 2012-3-27
     */
    protected Object convertGotObject(Object sourceObj, Type targetType) throws ObjectSourceException {
        Object result = null;

        ParamFilterValue pfv = (sourceObj instanceof ParamFilterValue ? ((ParamFilterValue) sourceObj) : null);

        if (pfv != null)
            sourceObj = pfv.getValue();

        try {
            result = getGenericConverter().convert(sourceObj, targetType);
        } catch (ConvertException e) {
            if (pfv != null) {
                String paramName = pfv.getFilter();

                if (e instanceof MapConvertException) {
                    String key = ((MapConvertException) e).getKey();

                    if (paramName == null)
                        paramName = key;
                    else if (key != null)
                        paramName += key;
                }

                throw new ParamIllegalException(paramName, e.getSourceObject(), e.getTargetType(), e);
            } else
                throw new ObjectSourceException(e);
        }

        return result;
    }

    /**
     * ???
     * 
     * @author earthangry@gmail.com
     * @date 2012-3-27
     */
    protected static class ParamFilterValue {
        /***/
        private String filter;

        /***/
        private Object value;

        /**
         * 
         */
        public ParamFilterValue() {
        }

        /**
         * ?
         * @param filter 
         * @param value 
         */
        public ParamFilterValue(String filter, Object value) {
            this.filter = filter;
            this.value = value;
        }

        /**
         * 
         * @param filter
         */
        public void setFilter(String filter) {
            this.filter = filter;
        }

        /**
         * ?
         * @return
         */
        public String getFilter() {
            return this.filter;
        }

        /**
         * 
         * @param value
         */
        public void setValue(Object value) {
            this.value = value;
        }

        /**
         * ?
         * @return
         */
        public Object getValue() {
            return this.value;
        }
    }
}