com.ewcms.common.query.mongo.PropertyConvert.java Source code

Java tutorial

Introduction

Here is the source code for com.ewcms.common.query.mongo.PropertyConvert.java

Source

/**
 * Copyright (c)2010-2011 Enterprise Website Content Management System(EWCMS), All rights reserved.
 * EWCMS PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * http://www.ewcms.com
 */

package com.ewcms.common.query.mongo;

import java.beans.PropertyDescriptor;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;

import com.ewcms.common.convert.Convert;
import com.ewcms.common.convert.ConvertException;
import com.ewcms.common.convert.ConvertFactory;

/**
 * ?Model???
 * 
 * @author wangwei
 *
 */
public class PropertyConvert {

    private static final Logger logger = LoggerFactory.getLogger(PropertyConvert.class);
    private static final Map<Class<?>, Class<?>> primitiveWrapper = initPrimitiveWrapper();
    private static final String NESTED = ".";

    private final Class<?> beanClass;
    private final boolean gmtTime;

    /**
     * {@link PropertyConvert}
     * 
     * @param beanClass
     */
    public PropertyConvert(Class<?> beanClass) {
        this(beanClass, true);
    }

    public PropertyConvert(Class<?> beanClass, boolean gmtTime) {
        this.beanClass = beanClass;
        this.gmtTime = gmtTime;
    }

    /**
     * ??(GMT)
     * 
     * @return
     */
    public boolean isGMTTime() {
        return gmtTime;
    }

    /**
     * ?{@link RuntimeException}
     * 
     * @param name  ???{@literal null}
     * @return {@value Class<?>}
     */
    public Class<?> getPropertyType(String propertyName) {
        if (!StringUtils.hasText(propertyName)) {
            throw new IllegalArgumentException("Property's name must not null or empty!");
        }

        String[] names = StringUtils.tokenizeToStringArray(propertyName, NESTED);
        Class<?> type = beanClass;
        PropertyDescriptor pd = null;
        for (String name : names) {
            pd = BeanUtils.getPropertyDescriptor(type, name);
            if (pd == null) {
                logger.error("\"{}\" property isn't exist.", propertyName);
                throw new RuntimeException(propertyName + " property isn't exist.");
            }
            type = pd.getPropertyType();
        }

        if (type.isArray()) {
            return type.getComponentType();
        }

        if (Collection.class.isAssignableFrom(type)) {
            Method method = pd.getReadMethod();
            if (method == null) {
                logger.error("\"{}\" property is not read method.", propertyName);
                throw new RuntimeException(propertyName + " property is not read method.");
            }
            ParameterizedType returnType = (ParameterizedType) method.getGenericReturnType();
            if (returnType.getActualTypeArguments().length > 0) {
                return (Class<?>) returnType.getActualTypeArguments()[0];
            }
            logger.error("\"{}\" property is collection,but it's not generic.", propertyName);
            throw new RuntimeException(propertyName + " property is collection,but it's not generic.");
        }

        return type;
    }

    /**
     * ?{@code propertyName}{@code value}??
     * 
     * @param propertyName ???{@literal null}
     * @param value 
     * @return
     * @throws ConvertException
     */
    public Object convert(String propertyName, Object value) throws ConvertException {
        return convertFormat(propertyName, null, value);
    }

    /**
     * ?{@value null}?
     * 
     * @param type 
     * @param value 
     * @return
     */
    private boolean isNull(Object value) {
        return value == null;
    }

    /**
     * ?{@value null}?
     * 
     * @param type 
     * @param value 
     * @return
     */
    private boolean sameType(Class<?> type, Object value) {
        if (type.isPrimitive()) {
            Class<?> wapper = primitiveWrapper.get(type);
            if (wapper == null) {
                throw new IllegalArgumentException(type.getName() + " wapper is not exist!");
            }
            return wapper == value.getClass();
        }
        return type == value.getClass();
    }

    private ConvertFactory getConvertFactory() {
        return isGMTTime() ? ConvertFactory.instanceGMT : ConvertFactory.instance;
    }

    /**
     * ?{@code propertyName}?{@code patter}{@code value}??
     * 
     * @param propertyName ???{@literal null}
     * @param patter ?,?{@literal null}
     * @param value 
     * @return
     * @throws ConvertException
     */
    public Object convertFormat(String propertyName, String patter, Object value) throws ConvertException {
        if (isNull(value)) {
            return value;
        }

        Class<?> propertyType = getPropertyType(propertyName);
        if (sameType(propertyType, value)) {
            return value;
        }

        Convert<?> convert = getConvertFactory().convert(propertyType);
        return StringUtils.hasText(patter) ? convert.parseFor(patter, value.toString())
                : convert.parse(value.toString());
    }

    /**
     * {@code separator}{@code value}???{@code propertyName}??
     * 
     * @param propertyName  ???{@literal null}
     * @param in ?
     * @param delimiter 
     * @return
     * @throws ConvertException
     */
    public Collection<?> convertCollection(String propertyName, String value, String delimiter)
            throws ConvertException {
        return convertCollectionFormat(propertyName, null, value, delimiter);
    }

    /**
     * {@code separator}{@code value}???{@code propertyName}?{@code patter}??
     * 
     * @param propertyName  ???{@literal null}
     * @param in ?
     * @param delimiter 
     * @return
     * @throws ConvertException
     */
    public Collection<?> convertCollectionFormat(String propertyName, String patter, String value, String delimiter)
            throws ConvertException {
        if (isNull(value)) {
            return null;
        }

        String[] s = StringUtils.tokenizeToStringArray(value, delimiter);
        Class<?> propertyType = getPropertyType(propertyName);
        if (sameType(propertyType, String.class)) {
            return Arrays.asList(s);
        }

        Object[] values = new Object[s.length];
        Convert<?> convert = getConvertFactory().convert(propertyType);
        for (int i = 0; i < s.length; i++) {
            values[i] = StringUtils.hasText(patter) ? convert.parseFor(patter, s[i]) : convert.parse(s[i]);
        }
        return Arrays.asList(values);
    }

    private static Map<Class<?>, Class<?>> initPrimitiveWrapper() {
        Map<Class<?>, Class<?>> map = new HashMap<Class<?>, Class<?>>();

        map.put(int.class, Integer.class);
        map.put(short.class, Short.class);
        map.put(long.class, Long.class);
        map.put(float.class, Float.class);
        map.put(double.class, Double.class);
        map.put(boolean.class, Boolean.class);
        map.put(byte.class, Byte.class);

        return map;
    }
}