开发那点事系列一 - 代码美,人生美!

作为成长的记忆,也作为不断追求卓越的见证,分享自己工作一年来的优秀代码片段。

思考:两年,三年,甚至更远,进步能有几何??? 

 期望:年年岁岁花相似,岁岁年年码不同~

/**
 * Comprehensive Assert API, for extensible ,you can use inheritance machanism,
 * naming your class as Assert2 or AssertUtils and so on.
 *
 * <pre>
 * notice: I strongly recommend the isTrue method,very versatile.
 * </pre>
 *
 * @see com.biz.service.util.ToolKits
 * @author vongosling
 */
public abstract class Assert {
    /**
     * Assert that an object is <code>null</code> .
     *
     * <pre class="code">
     * Assert.isNull(value, &quot;The value must be null&quot;);
     * </pre>
     *
     * @param object the object to check
     * @param message the exception message to use if the assertion fails
     * @throws IllegalArgumentException if the object is not <code>null</code>
     */
    public static void isNull(Object object, String message) {
        if (object != null) {
            throw new IllegalArgumentException(message);
        }
    }


    /**
     * Assert that an object is <code>null</code> .
     *
     * <pre class="code">
     * Assert.isNull(value);
     * </pre>
     *
     * @param object the object to check
     * @throws IllegalArgumentException if the object is not <code>null</code>
     */
    public static void isNull(Object object) {
        isNull(object, "the argument must be null");
    }


    /**
     * Assert that an object is not <code>null</code> .
     *
     * <pre class="code">
     * Assert.notNull(clazz, &quot;The class must not be null&quot;);
     * </pre>
     *
     * @param object the object to check
     * @param message the exception message to use if the assertion fails
     * @throws IllegalArgumentException if the object is <code>null</code>
     */
    public static void notNull(Object object, String message) {
        if (object == null) {
            throw new IllegalArgumentException(message);
        }
    }


    /**
     * Assert that an object is not <code>null</code> .
     *
     * <pre class="code">
     * Assert.notNull(clazz);
     * </pre>
     *
     * @param object the object to check
     * @throws IllegalArgumentException if the object is <code>null</code>
     */
    public static void notNull(Object object) {
        notNull(object, "this argument is required; it must not be null");
    }


    /**
     * Assert that the given String is not empty; that is, it must not be
     * <code>null</code> and not the empty String.
     *
     * <pre class="code">
     * Assert.hasLength(name, &quot;Name must not be empty&quot;);
     * </pre>
     *
     * @param text the String to check
     * @param message the exception message to use if the assertion fails
     */
    public static void hasLength(String text, String message) {
        if (text == null || "".equals(text.trim())) {
            throw new IllegalArgumentException(message);
        }
    }


    /**
     * Assert that the given String is not empty; that is, it must not be
     * <code>null</code> and not the empty String.
     *
     * <pre class="code">
     * Assert.hasLength(name);
     * </pre>
     *
     * @param text the String to check
     */
    public static void hasLength(String text) {
        hasLength(text, "this String argument must have length; it must not be null or empty");
    }


    /**
     * Assert that a collection has elements; that is, it must not be
     * <code>null</code> and must have at least one element.
     *
     * <pre class="code">
     * Assert.notEmpty(collection, &quot;Collection must have elements&quot;);
     * </pre>
     *
     * @param collection the collection to check
     * @param message the exception message to use if the assertion fails
     * @throws IllegalArgumentException if the collection is <code>null</code>
     *             or has no elements
     */
    public static <T> void notEmpty(Collection<T> collection, String message) {
        if (collection == null || collection.isEmpty()) {
            throw new IllegalArgumentException(message);
        }
    }


    /**
     * Assert that a collection has elements; that is, it must not be
     * <code>null</code> and must have at least one element.
     *
     * <pre class="code">
     * Assert.notEmpty(collection, &quot;Collection must have elements&quot;);
     * </pre>
     *
     * @param collection the collection to check
     * @throws IllegalArgumentException if the collection is <code>null</code>
     *             or has no elements
     */
    public static <T> void notEmpty(Collection<T> collection) {
        notEmpty(collection,
                "this collection must not be empty: it must contain at least 1 element");
    }


    /**
     * Assert that a map has elements; that is, it must not be <code>null</code>
     * and must have at least one element.
     *
     * <pre class="code">
     * Assert.notEmpty(map, &quot;Map must have elements&quot;);
     * </pre>
     *
     * @param map the Map to check
     * @return whether the given Map is empty
     * @throws IllegalArgumentException if the map is <code>null</code> or has
     *             no elements
     */
    public static <T, K> void notEmpty(Map<T, K> map, String message) {
        if (map == null || map.isEmpty()) {
            throw new IllegalArgumentException(message);
        }
    }


    /**
     * Assert that a Map has entries; that is, it must not be <code>null</code>
     * and must have at least one entry.
     *
     * <pre class="code">
     * Assert.notEmpty(map);
     * </pre>
     *
     * @param map the map to check
     * @throws IllegalArgumentException if the map is <code>null</code> or has
     *             no entries
     */
    public static <T, K> void notEmpty(Map<T, K> map) {
        notEmpty(map, "this map must not be empty; it must contain at least one entry");
    }


    /**
     * Assert that the given String is not empty.
     *
     * <pre class="code">
     * Assert.notEmpty(name, &quot;Name must not be empty&quot;);
     * </pre>
     *
     * @param text the sting to check
     * @param message the exception message to use if the assertion fails
     * @throws IllegalArgumentException if the string is empty.
     * @see #hasLength
     */
    public static void notEmpty(String text, String message) {
        hasLength(text, message);
    }


    /**
     * Assert that an array has elements; that is, it must not be
     * <code>null</code> and must have at least one element.
     *
     * <pre class="code">
     * Assert.notEmpty(array, &quot;The array must have elements&quot;);
     * </pre>
     *
     * @param array the array to check
     * @param message the exception message to use if the assertion fails
     * @throws IllegalArgumentException if the object array is <code>null</code>
     *             or has no elements
     */
    public static void notEmpty(Object[] array, String message) {
        if (array == null || array.length == 0) {
            throw new IllegalArgumentException(message);
        }
    }


    /**
     * Assert that an array has elements; that is, it must not be
     * <code>null</code> and must have at least one element.
     *
     * <pre class="code">
     * Assert.notEmpty(array);
     * </pre>
     *
     * @param array the array to check
     * @throws IllegalArgumentException if the object array is <code>null</code>
     *             or has no elements
     */
    public static void notEmpty(Object[] array) {
        notEmpty(array, "this array must not be empty: it must contain at least 1 element");
    }


    /**
     * Assert that an array has no null elements.
     *
     * <pre class="code">
     * Assert.noNullElements(array, &quot;The array must have non-null elements&quot;);
     * </pre>
     *
     * @param array the array to check
     * @param message the exception message to use if the assertion fails
     * @throws IllegalArgumentException if the object array contains a
     *             <code>null</code> element
     */
    public static void noNullElements(Object[] array, String message) {
        notEmpty(array);
        for (int i = 0; i < array.length; i++) {
            if (array[i] == null) {
                throw new IllegalArgumentException(message);
            }
        }
    }


    /**
     * Assert that an array has no null elements. Note: Does not complain if the
     * array is empty!
     *
     * <pre class="code">
     * Assert.noNullElements(array);
     * </pre>
     *
     * @param array the array to check
     * @throws IllegalArgumentException if the object array contains a
     *             <code>null</code> element
     */
    public static void noNullElements(Object[] array) {
        noNullElements(array, "this array must not contain any null elements");
    }


    /**
     * Assert that an collection has no null elements.
     *
     * <pre class="code">
     * Assert.noNullElements(collection, &quot;The collection must have non-null elements&quot;);
     * </pre>
     *
     * @param collection the collection to check
     * @param message the exception message to use if the assertion fails
     * @throws IllegalArgumentException if the collection contains a
     *             <code>null</code> element
     */
    public static <T> void noNullElements(Collection<T> collection, String message) {
        notEmpty(collection);
        for (Iterator<T> it = collection.iterator(); it.hasNext();) {
            if (it.next() == null) {
                throw new IllegalArgumentException(message);
            }
        }
    }


    /**
     * Assert that an collection has no null elements.
     *
     * <pre class="code">
     * Assert.noNullElements(collection);
     * </pre>
     *
     * @param collection the collection to check
     * @param message the exception message to use if the assertion fails
     * @throws IllegalArgumentException if the collection contains a
     *             <code>null</code> element
     */
    public static <T> void noNullElements(Collection<T> collection) {
        notEmpty(collection);
        int i = 0;
        for (Iterator<T> it = collection.iterator(); it.hasNext(); i++) {
            if (it.next() == null) {
                throw new IllegalArgumentException(
                        "The validated collection contains null element at index: " + i);
            }
        }
    }


    /**
     * Assert the less than operation validity.
     *
     * <pre class="code">
     * Assert.lessThan(number, compareNumber, &quot;number must be less Than compareNumber&quot;);
     * </pre>
     *
     * @param number
     * @param compareNumber
     * @param message
     */
    public static void lessThan(Number number, Number compareNumber, String message) {
        if (number == null || compareNumber == null) {
            throw new IllegalArgumentException("one of the arguments is null");
        }
        if (number.longValue() > compareNumber.longValue()) {
            throw new IllegalArgumentException(message);
        }
    }


    /**
     * Assert the less than operation validity.
     *
     * <pre class="code">
     * Assert.lessThan(number, compareNumber);
     * </pre>
     *
     * @param number
     * @param compareNumber
     * @param message
     */
    public static void lessThan(Number number, Number compareNumber) {
        if (number == null || compareNumber == null) {
            throw new IllegalArgumentException("one of the arguments is null");
        }
        if (number.longValue() > compareNumber.longValue()) {
            throw new IllegalArgumentException("less than operation not satisfied");
        }
    }


    /**
     * Assert the more than operation validity.
     *
     * <pre class="code">
     * Assert.moreThan(number, compareNumber, &quot;number must be more Than compareNumber&quot;);
     * </pre>
     *
     * @param number
     * @param compareNumber
     * @param message
     */
    public static void moreThan(Number number, Number compareNumber, String message) {
        if (number == null || compareNumber == null) {
            throw new IllegalArgumentException("one of the arguments is null");
        }
        if (number.longValue() < compareNumber.longValue()) {
            throw new IllegalArgumentException(message);
        }
    }


    /**
     * Assert the more than operation validity.
     *
     * <pre class="code">
     * Assert.moreThan(number, compareNumber);
     * </pre>
     *
     * @param number
     * @param compareNumber
     * @param message
     */
    public static void moreThan(Number number, Number compareNumber) {
        if (number == null || compareNumber == null) {
            throw new IllegalArgumentException("one of the arguments is null");
        }
        if (number.longValue() < compareNumber.longValue()) {
            throw new IllegalArgumentException("more than operation not satisfied");
        }
    }


    /**
     * Assert that the provided object is an instance of the provided class.
     *
     * <pre class="code">
     * Assert.instanceOf(Foo.class, foo);
     * </pre>
     *
     * @param clazz the required class
     * @param obj the object to check
     * @throws IllegalArgumentException if the object is not an instance of
     *             clazz
     * @see Class#isInstance
     */
    public static <T> void isInstanceOf(Class<T> clazz, Object obj) {
        isInstanceOf(clazz, obj, "");
    }


    /**
     * Assert that the provided object is an instance of the provided class.
     *
     * <pre class="code">
     * Assert.instanceOf(Foo.class, foo, &quot;object must be an instance of class Foo&quot;);
     * </pre>
     *
     * @param type the type to check against
     * @param obj the object to check
     * @param message a message which will be prepended to the message produced
     *            by the function itself, and which may be used to provide
     *            context. It should normally end in a ": " or ". " so that the
     *            function generate message looks ok when prepended to it.
     * @throws IllegalArgumentException if the object is not an instance of
     *             clazz
     * @see Class#isInstance
     */
    public static <T> void isInstanceOf(Class<T> type, Object obj, String message) {
        notNull(type, "Type to check must not be null");
        if (!type.isInstance(obj)) {
            throw new IllegalArgumentException(message + "Object of class ["
                    + (obj != null ? obj.getClass().getName() : "null")
                    + "] must be an instance of " + type);
        }
    }


    /**
     * Assert that <code>superType.isAssignableFrom(subType)</code> is
     * <code>true</code>.
     *
     * <pre class="code">
     * Assert.isAssignable(Number.class, myClass);
     * </pre>
     *
     * @param superType the super type to check
     * @param subType the sub type to check
     * @throws IllegalArgumentException if the classes are not assignable
     */
    public static <T, P> void isAssignable(Class<T> superType, Class<P> subType) {
        isAssignable(superType, subType, "");
    }


    /**
     * Assert that <code>superType.isAssignableFrom(subType)</code> is
     * <code>true</code>.
     *
     * <pre class="code">
     * Assert.isAssignable(Number.class, myClass, &quot;subType must be assignable to superType&quot;);
     * </pre>
     *
     * @param superType the super type to check against
     * @param subType the sub type to check
     * @param message a message which will be prepended to the message produced
     *            by the function itself, and which may be used to provide
     *            context. It should normally end in a ": " or ". " so that the
     *            function generate message looks ok when prepended to it.
     * @throws IllegalArgumentException if the classes are not assignable
     */
    public static <T, P> void isAssignable(Class<T> superType, Class<P> subType, String message) {
        notNull(superType, "Type to check against must not be null");
        if (subType == null || !superType.isAssignableFrom(subType)) {
            throw new IllegalArgumentException(message + subType + " is not assignable to "
                    + superType);
        }
    }


    /**
     * Assert a boolean expression, throwing
     * <code>IllegalArgumentException</code> if the test result is
     * <code>false</code>.
     *
     * <pre class="code">
     * Assert.isTrue(i &gt; 0, &quot;The value must be greater than zero&quot;);
     * </pre>
     *
     * @param expression a boolean expression
     * @param message the exception message to use if the assertion fails
     * @throws IllegalArgumentException if expression is <code>false</code>
     */
    public static void isTrue(boolean expression, String message) {
        if (!expression) {
            throw new IllegalArgumentException(message);
        }
    }


    /**
     * Assert a boolean expression, throwing
     * <code>IllegalArgumentException</code> if the test result is
     * <code>false</code>.
     *
     * <pre class="code">
     * Assert.isTrue(i &gt; 0);
     * </pre>
     *
     * @param expression a boolean expression
     * @throws IllegalArgumentException if expression is <code>false</code>
     */
    public static void isTrue(boolean expression) {
        isTrue(expression, "this expression must be true");
    }


}

/**
 * ToolKits,dedicated to XXX project
 *
 * @author vongosling
 */
public class ToolKits {

    private static ToolKits instance;

    private static Object   o = ToolKits.class;

    private ToolKits() {

    }

    static {
        synchronized (o) {
            if (instance == null) {
                instance = new ToolKits();
            }
        }
    }

    /**
     * @return {@code ToolKits singleton instance}
     */
    public static ToolKits getInstance() {
        return instance;
    }

    /**
     * Return <code>true</code> if the supplied Collection is <code>null</code>
     * or empty. Otherwise, return <code>false</code>.
     *
     * @param collection the Collection to check
     * @return whether the given Collection is empty
     */
    public static <T> boolean checkCollection(Collection<T> collection) {
        return collection == null || collection.isEmpty();
    }

    /**
     * Return <code>true</code> if the supplied Map is <code>null</code> or
     * empty. Otherwise, return <code>false</code>.
     *
     * @param map the Map to check
     * @return whether the given Map is empty
     */
    public static <T, K> boolean checkMap(Map<T, K> map) {
        return map == null || map.isEmpty();
    }

    /**
     * Returns a new {@link Collection} containing <tt><i>a</i> - <i>b</i></tt>.
     * The cardinality of each element <i>e</i> in the returned
     * {@link Collection} will be the cardinality of <i>e</i> in <i>a</i> minus
     * the cardinality of <i>e</i> in <i>b</i>, or zero, whichever is greater.
     *
     * @param a the collection to subtract from, must not be null
     * @param b the collection to subtract, must not be null
     * @return a new collection with the results
     * @see Collection#removeAll
     */
    public static <T> Collection<T> subtract(final Collection<T> a, final Collection<T> b) {
        ArrayList<T> list = new ArrayList<T>(a);
        for (Iterator<T> it = b.iterator(); it.hasNext();) {
            list.remove(it.next());
        }
        return list;
    }

    /**
     * Ensures that object references passed as a parameter to the calling
     * method are all not empty(include null). necessarily , when reference
     * refers to Collection,its size can not empty.
     *
     * @param elements the elements that the checker should precondition, in
     *            order
     * @return <p>
     *         <b>false</b> if one of the variable parameters is null or is
     *         empty.
     */
    @SuppressWarnings("unchecked")
    public static <T> boolean anyOneIsNotEmpty(T... elements) {
        if (elements == null) {
            return false;
        }
        if (elements.length == 1 && elements instanceof String[]) {
            return (elements != null) && (((String) elements[0]).trim().length() != 0);
        }
        for (T obj : elements) {
            if (obj == null) {
                return false;
            }
            if (obj instanceof String) {
                if (((String) obj).trim().length() == 0) {
                    return false;
                } else {
                    continue;
                }
            } else if (obj instanceof Collection) {
                if (((Collection) obj).isEmpty()) {
                    return false;
                } else {
                    continue;
                }
            } else if (obj instanceof Map) {
                if (((Map) obj).isEmpty()) {
                    return false;
                } else {
                    continue;
                }
            }else{
                //fault-tolerant
                return true;
            }
        }
        return true;
    }

/**
 * Cache client adatper
 *
 * @see https://github.com/memcached/memcached/blob/master/doc/protocol.txt
 * @author vongosling
 */
public interface CacheClientAdapter {
    /**
     * Store this data, only if it does not already exist. New items are at the
     * top of the LRU. If an item already exists and an add fails, it promotes
     * the item to the front of the LRU anyway.
     *
     * @param <T>
     * @param key
     * @param exp
     * @param value
     * @return
     */
    <T> boolean add(String key, int exp, T value);

    /**
     * Store this data, possibly overwriting any existing data. New items are at
     * the top of the LRU.
     *
     * @param <T>
     * @param key
     * @param exp
     * @param value
     * @return
     */
    <T> boolean set(String key, int exp, T value);

    /**
     * Retrieving data. Takes one keys and returns the found item.
     *
     * @param <T>
     * @param key
     * @return
     */
    <T> T get(String key);

    /**
     * Retrieving data. Takes more keys and returns all found items.
     *
     * @param <T>
     * @param keyCollections
     * @return
     */
    <T> Map<String, T> get(Collection<String> keyCollections);

    /**
     * Removes an item from the cache, if it exists.
     *
     * @param key
     * @return
     */
    boolean delete(String key);

    /**
     * Increment and Decrement. If an item stored is the string representation
     * of a 64bit integer, you may run incr or decr commands to modify that
     * number. You can incr by positive or negative values, so decr is included
     * for completeness. If a value does not already exist, incr/decr will fail.
     *
     * @param key
     * @param step
     * @return
     */
    long incr(String key, int step);

    /**
     * @see {@link #incr}
     * @param key
     * @param step
     * @return
     */
    long decr(String key, int step);

    /**
     * wthether the cache switch is open
     *
     * @return
     */
    boolean isEnable();

    /**
     * @param enable
     */
    void setEnable(boolean enable);

    /**
     * Basic stats command
     *
     * @return
     */
    Map<InetSocketAddress, Map<String, String>> getStats();

    /**
     * Stats command Materialization,such as: </br> stats items|stats
     * slabs|stats sizes
     *
     * @param itemName {@literal items|slabs|sizes}
     * @return
     */
    Map<InetSocketAddress, Map<String, String>> getStatsByItem(String itemName);

    /**
     * @throws IOException
     */
    void shutdown() throws IOException;

}

private boolean checkIsInBlackList(JSONObject result) {
        //1. special case1
        if (result == null || "{}".equals(result.toJSONString()))
            return false;
        //2. special case2
        if (!"200".equals(result.getString("respCode"))) {
            logger.warn("warning,please refer to {} and concult 360 platform.", result);
            return false;
        }
        //3. in blacklist or in Must blacklist or ACP(exclude whitelist)?
        try {
            JSONObject JsonObj = result.getJSONObject("content").getJSONObject("blackCustomerInfo")
                    .getJSONObject("returnValue");
            //FIXME too deep when I get what I wanted,trace 360 platform improvement...
            String value = JsonObj.getString(getFields());
            if (value.contains("1") || value.contains("2")
                    || value.matches("((([#]|[\\s])5)|(5))[^(_inactive)]*")) {
                return true;
            }
        } catch (Exception e) {
            logger.error("Error occur!", e);
            return false;
        }

        return false;
    }
/**
 * @author vongosling
 */
public interface IVisitor {

    String getVisitorKey();

    void visit(CustomerParam customerParam);

}

/**
 * @author vongosling
 */
public abstract class AbstractVisitor implements IVisitor {

    protected final Logger log = LoggerFactory.getLogger(AbstractVisitor.class);

    public final void visit(CustomerParam customerParam) {
        this.init(customerParam);
    }

    public String getVisitorKey() {
        return this.getClass().getSimpleName();
    }

    protected abstract void init(CustomerParam customerParam);

}

/**
 * Holder pattern
 *
 * @author vongosling
 */
public class VisitorHolder {

    private static final Logger   LOG    = LoggerFactory.getLogger(VisitorHolder.class);

    private Map<String, IVisitor> holder = Maps.newHashMap();
    private List<IVisitor>        visitorList;

    public IVisitor getVisitor(String key) {
        if (StringUtils.isBlank(key)) {
            return null;
        }
        return holder.get(key);
    }

    public void setVisitorList(List<IVisitor> visitorList) {
        holder.clear();
        this.visitorList = visitorList;
        for (IVisitor visitor : visitorList) {
            holder.put(visitor.getVisitorKey(), visitor);
        }
    }

    public Map<String, IVisitor> getHolder() {
        return holder;
    }

    public void setHolder(Map<String, IVisitor> holder) {
        this.holder = holder;
        LOG.info("load visitor {}", holder);
    }

    public List<IVisitor> getVisitorList() {
        return visitorList;
    }
}

 /**
     * 如果正常拼接后得到的key转换为bytes的长度超过250(memcached的key长度上限), 则自动做一次sha256hex的转换。
     *
     * @param cacheDomain 缓存的domain
     * @param valueId 缓存内容的主键
     * @param version 版本
     * @return
     * @see CacheDomain
     */
    public static String getKey(CacheDomain cacheDomain, String valueId, int version) {
        String key = cacheDomain.getValue() + SPLIT + valueId + SPLIT + version;
        final byte[] bytes = key.getBytes();
        if (bytes.length > 250) {
            key = DigestUtils.sha256Hex(key);
        }
        return key;
    }
/**
 * @author vongosling
 */
@ManagedResource(objectName = CacheClientMBean.MBEAN_NAME, description = "Cache Management Bean")
@SuppressWarnings("deprecation")
public class CacheClientMBean {

    private static final Logger LOG        = LoggerFactory.getLogger(CacheClientMBean.class);

    public static final String  MBEAN_NAME = "XXX:type=CacheClientMBean,name=cacheClientMBean";

    private CacheClientAdapter  cacheClientAdapter;
    private MemcachedClient     memcachedClient;

    @ManagedAttribute(description = "Current active session host")
    public Set<String> getActiveSessionHost() {
        Set<Session> sessions = memcachedClient.getConnector().getSessionSet();
        Set<String> hosts = Sets.newHashSet();
        for (Session ses : sessions) {
            hosts.add(ses.toString());
        }
        return hosts;
    }

    @ManagedAttribute(description = "Order Cache Version")
    public Integer getOrderCacheVersion() {
        String key = CacheDomain.ORDERITEM.getValue() + OrderCacheServiceBo.KEY_SPLIT
                + OrderCacheServiceBo.ORDER_CACHE_VERSION;
        LOG.debug("Order cache version key is {}", key);
        return cacheClientAdapter.get(key);
    }

    @ManagedAttribute(description = "Order Cache Black Version")
    public Integer getOrderBlackListCacheVersion() {
        String key = CacheDomain.ORDERITEM.getValue() + OrderCacheServiceBo.KEY_SPLIT
                + OrderCacheServiceBo.ORDER_BLACK_LIST_VERSION;
        return cacheClientAdapter.get(key);
    }

    @ManagedAttribute(description = "Product Cache Version")
    public Integer getPrdCacheVersion() {
        return cacheClientAdapter.get(PrdServiceCacheAdmin.PRDCONFIG_CACHE_VESION_KEY);
    }

    @SuppressWarnings("unchecked")
    @ManagedOperation(description = "Get value from memcached")
    @ManagedOperationParameters( { @ManagedOperationParameter(name = "key", description = "Cache Key") })
    public String getValueFromCache(String key) {
        Object o = cacheClientAdapter.get(key);
        String s = null;
        if (o instanceof Map) {
            s = o.toString();
        } else {
            s = ToStringBuilder.reflectionToString(o, ToStringStyle.MULTI_LINE_STYLE);
        }
        return s;
    }

    public void setCacheClientAdapter(CacheClientAdapter cacheClientAdapter) {
        this.cacheClientAdapter = cacheClientAdapter;
    }

    public MemcachedClient getMemcachedClient() {
        return memcachedClient;
    }

    public void setMemcachedClient(MemcachedClient memcachedClient) {
        this.memcachedClient = memcachedClient;
    }

}


/**
 * @author vongosling
 */
public interface LoggingConfig {
    /**
     * @param filter returns only loggers, which contain the filter string
     * @return all available loggers
     */
    public String[] getLoggers(String filter);

    /**
     * assigns the {@link Level#INFO} to the given class
     *
     * @param target the FQCN of the class
     */
    public void assignInfoLevel(String target);

    /**
     * assigns the {@link Level#WARN} to the given class
     *
     * @param target the FQCN of the class
     */
    public void assignWarnLevel(String target);

    /**
     * assigns the {@link Level#ERROR} to the given class
     *
     * @param target the FQCN of the class
     */
    public void assignErrorLevel(String target);

    /**
     * assigns the {@link Level#DEBUG} to the given class
     *
     * @param target the FQCN of the class
     */
    public void assignDebug(String target);

    /**
     * assigns the {@link Level#FATAL} to the given class
     *
     * @param target the FQCN of the class
     */
    public void assignFatalLevel(String target);

    /**
     * assigns the {@link Level#TRACE} to the given class
     *
     * @param target the FQCN of the class
     */
    public void assignTraceLevel(String target);

    /**
     * deactivates the logging of the given class
     *
     * @param target the FQCN of the class
     */
    public void deactivateLogging(String target);

    /**
     * reloads the log4j configuration from the <code>log4j.properties</code>
     * file in the classpath
     */
    public void resetConfiguration();

    /**
     * @return the log4j configuration from the <code>log4j.properties</code>
     *         file in the classpath
     */
    public String printLog4jConfig();
}

/**
 * @author vongosling
 */
public class LoggingConfigImpl implements LoggingConfig, NotificationPublisherAware {

    private Map<NotificationType, Long> notificationTypeMap = new HashMap<NotificationType, Long>();
    private NotificationPublisher       publisher;

    public void setNotificationPublisher(NotificationPublisher notificationPublisher) {
        this.publisher = notificationPublisher;
    }

    public String[] getLoggers(String filter) {

        LoggerRepository loggerRepo = LogManager.getLoggerRepository();

        Enumeration<?> enumList = loggerRepo.getCurrentLoggers();

        Logger logger = null;
        List<String> resultList = new ArrayList<String>();
        while (enumList.hasMoreElements()) {
            logger = (Logger) enumList.nextElement();
            if (filter != null && logger.getName().contains(filter)) {
                resultList.add(logger.getName());
            }
        }

        return (String[]) resultList.toArray(new String[] {});
    }

    public void assignInfoLevel(String target) {
        assignLogLevel(target, Level.INFO);
    }

    public void assignWarnLevel(String target) {
        assignLogLevel(target, Level.WARN);
    }

    public void assignErrorLevel(String target) {
        assignLogLevel(target, Level.ERROR);
    }

    public void assignDebug(String target) {
        assignLogLevel(target, Level.DEBUG);
    }

    public void assignFatalLevel(String target) {
        assignLogLevel(target, Level.FATAL);
    }

    public void deactivateLogging(String target) {
        assignLogLevel(target, Level.OFF);
    }

    public void assignTraceLevel(String target) {
        assignLogLevel(target, Level.TRACE);
    }

    private void assignLogLevel(String target, Level level) {
        String message = level.toString() + " for '" + target + "'";
        Logger existingLogger = LogManager.exists(target);
        if (existingLogger != null) {
            Level currentLevel = existingLogger.getLevel();
            if (currentLevel == null) {
                message = "initial to " + message;
            } else {
                message = "from " + currentLevel.toString() + " to " + message;
            }
        }

        LogManager.getLogger(target).setLevel(level);
        sendNotification(NotificationType.CHANGE_LOG_LEVEL, message);
    }

    private synchronized void sendNotification(NotificationType notificationType, String message) {
        Long counter = 0L;
        if (!notificationTypeMap.containsKey(notificationType))
            notificationTypeMap.put(notificationType, counter);

        counter = notificationTypeMap.get(notificationType);
        notificationTypeMap.put(notificationType, Long.valueOf(counter + 1));

        Notification notification = new Notification(notificationType.toString(), this, counter);
        notification.setUserData(message);
        publisher.sendNotification(notification);
    }

    public void resetConfiguration() {
        ClassLoader cl = getClass().getClassLoader();
        LogManager.resetConfiguration();
        URL log4jprops = cl.getResource("log4j.xml");
        if (log4jprops != null) {
            //PropertyConfigurator.configure(log4jprops);
            DOMConfigurator.configure(log4jprops);
        }
        sendNotification(NotificationType.RESET_CONFIGURATION, "used file: " + log4jprops.getFile());
    }

    public String printLog4jConfig() {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        PropertyPrinter pp = new PropertyPrinter(pw);
        pp.print(pw);
        // System.out.println(sw.toString());
        return sw.toString();
    }

}

/**
 * @author vongosling
 */
public enum NotificationType {
    CHANGE_LOG_LEVEL,
    RESET_CONFIGURATION;
}

/**
 * @author vongosling
 */
public class Log4jMDC {

    private static final Logger log = LoggerFactory.getLogger(Log4jMDC.class);

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ScheduledExecutorService service = Executors.newScheduledThreadPool(10);

        Runnable mdcTask = new Runnable() {

            public void run() {
                MDC.put("first", RandomStringUtils.randomAlphabetic(10));
                MDC.put("last", RandomStringUtils.randomAlphabetic(10));
                log.debug("Mission launched...");
                MDC.clear();
                log.warn("MDC cleared...");
            }

        };
        final ScheduledFuture<?> future1 = service.scheduleAtFixedRate(mdcTask, 0, 1,
                TimeUnit.SECONDS);

        ScheduledFuture<?> future2 = service.schedule(new Callable<Boolean>() {

            public Boolean call() throws Exception {
                return future1.cancel(true);
            }

        }, 5, TimeUnit.SECONDS);

        System.out.println(future2.get());

        service.shutdown();

    }
}

/**
 * @author vongosling
 */
public class OrderInterfacePerformance extends AbstractJavaSamplerClient {

    private OrderPortalService orderPortalService;
    private SampleResult       results;

    /**
     * @param orderPortalService the orderPortalService to set
     */
    public void setOrderPortalService(OrderPortalService orderPortalService) {
        this.orderPortalService = orderPortalService;
    }

    @Override
    public Arguments getDefaultParameters() {
        Arguments params = new Arguments();
        params.addArgument("name", "kaka");
        return params;
    }

    @Override
    protected Logger getLogger() {
        return super.getLogger();
    }

    @Override
    public void setupTest(JavaSamplerContext context) {
        results = new SampleResult();
    }

    @Override
    public void teardownTest(JavaSamplerContext context) {
        super.teardownTest(context);
    }

    public SampleResult runTest(JavaSamplerContext paramJavaSamplerContext) {

        String parameterValue = paramJavaSamplerContext.getParameter("name");
        results.setSamplerData(parameterValue);

        ResultModel<ArrayList<OrderDto>> result = new ResultModel<ArrayList<OrderDto>>();

        results.sampleStart();

        try {
            //Invocation logical processing
            OrderDto order = new OrderDto();
            List<String> statuses = new ArrayList<String>();
            statuses.add("payment_part");
            statuses.add("payment_none");
            order.setUid("300208380");
            order.setStatuses(statuses);
            result = orderPortalService.getOrders(order, 1, 10);
            results.sampleEnd();
            if (result.isSuccessed()) {
                results.setSuccessful(true);
            } else {
                results.setSuccessful(false);
            }
        } catch (Exception e) {
            results.setSuccessful(false);
            System.err.println(e.getLocalizedMessage());
        } finally {
            System.out.println(result);
        }
        return results;
    }
}

/**
 * @author vongosling
 */
public class ServerMonitor implements ServerMonitorMBean {

    private final ServerImpl target;

    public ServerMonitor(ServerImpl target) {
        this.target = target;
    }

    public long getUpTime() {
        return System.nanoTime() - target.startTime;
    }

}

/**
 * @author vongosling
 */
public class ServerMonitorDynamic implements DynamicMBean {

    private final ServerImpl target;
    private MBeanInfo        mBeanInfo;

    public ServerMonitorDynamic(ServerImpl target) {
        this.target = target;
    }

    // 实现获取被管理的 ServerImpl的 upTime
    public long upTime() {
        return System.nanoTime() - target.startTime;
    }

    //javax.management.MBeanServer 会通过查询 getAttribute("Uptime") 获得 "Uptime" 属性值
    public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException,
            ReflectionException {
        if (attribute.equals("UpTime")) {
            return upTime();
        }
        return null;
    }

    // 给出 ServerMonitor 的元信息。
    public MBeanInfo getMBeanInfo() {
        if (mBeanInfo == null) {
            try {
                Class<?> cls = this.getClass();
                // 用反射获得 "upTime" 属性的读方法
                Method readMethod = cls.getMethod("upTime", new Class[0]);
                // 用反射获得构造方法
                Constructor<?> constructor = cls.getConstructor(new Class[] { ServerImpl.class });
                // 关于 "upTime" 属性的元信息 : 名称为 UpTime,只读属性 ( 没有写方法 )。
                MBeanAttributeInfo upTimeMBeanAttributeInfo = new MBeanAttributeInfo("UpTime",
                        "The time span since server start", readMethod, null);
                // 关于构造函数的元信息
                MBeanConstructorInfo mBeanConstructorInfo = new MBeanConstructorInfo(
                        "Constructor for ServerMonitor", constructor);
                //ServerMonitor 的元信息,为了简单起见,在这个例子里,
                // 没有提供 invocation 以及 listener 方面的元信息
                mBeanInfo = new MBeanInfo(cls.getName(), "Monitor that controls the server",
                        new MBeanAttributeInfo[] { upTimeMBeanAttributeInfo },
                        new MBeanConstructorInfo[] { mBeanConstructorInfo }, null, null);
            } catch (Exception e) {
                throw new Error(e);
            }

        }
        return mBeanInfo;
    }

    public AttributeList getAttributes(String[] arg0) {
        return null;
    }

    public Object invoke(String arg0, Object[] arg1, String[] arg2) throws MBeanException,
            ReflectionException {
        return null;
    }

    public void setAttribute(Attribute arg0) throws AttributeNotFoundException,
            InvalidAttributeValueException, MBeanException, ReflectionException {
        return;
    }

    public AttributeList setAttributes(AttributeList arg0) {
        return null;
    }

}
/**
 * @author vongosling
 */
public class JmxRunner {

    private static ObjectName  objectName_1;
    private static ObjectName  objectName_2;
    private static MBeanServer server;

    public static void main(String[] args) throws Exception {
        init();
        invoke();
    }

    private static void init() throws Exception {
        ServerImpl serverImpl = new ServerImpl();
        ServerMonitor serverMoniter = new ServerMonitor(serverImpl);
        ServerMonitorDynamic serverMoniterDynamic = new ServerMonitorDynamic(serverImpl);

        server = MBeanServerFactory.createMBeanServer();
        objectName_1 = new ObjectName("com.von:name=von_server");
        objectName_2 = new ObjectName("com.von:name=von_server_dynamic");

        server.registerMBean(serverMoniter, objectName_1);
        server.registerMBean(serverMoniterDynamic, objectName_2);
    }

    private static void invoke() throws Exception {
        System.out.println(server.isRegistered(objectName_1));
        System.out.println(server.isRegistered(objectName_2));
        System.out.println(server.getAttribute(objectName_2, "UpTime"));
        System.out.println(server.getAttribute(objectName_1, "UpTime"));
    }

}

/**
 * @author vongosling
 */
public class StringOperationPerfTest {

    public static void main(String[] args) {
        int OUTER_ITERATION = 5;
        int INNER_ITERATION = 5000;

        String addTestStr = "";
        String concatTestStr = "";
        StringBuffer concatTestSb = null;
        StringBuilder concatTestSbu = null;

        StopWatch stopWatch = new Slf4JStopWatch();
        for (int outerIndex = 0; outerIndex < OUTER_ITERATION; outerIndex++) {
            addTestStr = "";
            for (int innerIndex = 0; innerIndex < INNER_ITERATION; innerIndex++)
                addTestStr += "*";
            stopWatch.lap("StringAddConcat");
        }
        for (int outerIndex = 0; outerIndex < OUTER_ITERATION; outerIndex++) {
            concatTestStr = "";
            for (int innerIndex = 0; innerIndex < INNER_ITERATION; innerIndex++)
                concatTestStr = concatTestStr.concat("*");
            stopWatch.lap("StringConcat");
        }

        for (int outerIndex = 0; outerIndex < OUTER_ITERATION; outerIndex++) {
            concatTestSb = new StringBuffer();
            for (int innerIndex = 0; innerIndex < INNER_ITERATION; innerIndex++)
                concatTestSb.append("*");
            stopWatch.lap("StringBufferConcat");
        }

        for (int outerIndex = 0; outerIndex < OUTER_ITERATION; outerIndex++) {
            concatTestSbu = new StringBuilder();
            for (int innerIndex = 0; innerIndex < INNER_ITERATION; innerIndex++)
                concatTestSbu.append("*");
            stopWatch.stop("StringBuilderConcat");
        }
    }
}

/**
 * Serializable further research
 *
 * @author vongosling
 */
public class SerializableTest {

    public static class CaseOne implements Serializable {
        private static final long serialVersionUID = 1L;
        public static int         staticVar        = 5;

        public static void main(String[] args) {
            try {
                ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("result.obj"));
                out.writeObject(new CaseOne());
                out.flush();
                System.out.println(new File("result.obj").length());

                out.writeObject(new CaseOne());
                out.close();
                System.out.println(new File("result.obj").length());

                ObjectInputStream oin = new ObjectInputStream(new FileInputStream("result.obj"));
                CaseOne t1 = (CaseOne) oin.readObject();
                CaseOne t2 = (CaseOne) oin.readObject();
                oin.close();

                System.out.println(t1 == t2);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
}

/**
 * Commons-Collections Demo
 *
 * @author vongosling
 */
public class CommonCollectionsTest {

    @SuppressWarnings("unchecked")
    @Test
    public void IterableMapTest() {
        //1
        IterableMap map = new HashedMap();
        map.put("name", "kaka");
        MapIterator it = map.mapIterator();
        while (it.hasNext()) {
            Object key = it.next();
            System.out.println(key);

            Object value = it.getValue();
            System.out.println(value);

            it.setValue("messi");
        }
        System.out.println(map);

        //2
        OrderedMap orderedMap = new LinkedMap();
        orderedMap.put("FIVE", "5");
        orderedMap.put("SIX", "6");
        orderedMap.put("SEVEN", "7");
        System.out.println(orderedMap.firstKey());
        System.out.println(orderedMap.nextKey("FIVE"));

        //3
        BidiMap bidi = new TreeBidiMap();
        bidi.put("SIX", "6");
        bidi.put("SEVEN", "7");
        bidi.get("SIX"); // returns "6"
        bidi.getKey("6"); // returns "SIX"
        bidi.removeValue("6"); // removes the mapping
        BidiMap inverse = bidi.inverseBidiMap(); // returns a map with keys and values swapped
        System.out.println(inverse);

        //4
        Buffer buffer = new UnboundedFifoBuffer();
        buffer.add("ONE");
        buffer.add("TWO");
        buffer.add("THREE");
        buffer.remove();  // removes and returns the next in order, "ONE" as this is a FIFO
        buffer.remove();  // removes and returns the next in order, "TWO" as this is a FIFO

        //5
        Iterator iter = new FilterIterator();
        new UniqueFilterIterator(iter);

        //6
        Bag bag = new HashBag();
        bag.add("ONE", 6);  // add 6 copies of "ONE"
        bag.remove("ONE", 2);  // removes 2 copies of "ONE"
        bag.getCount("ONE");  // returns 4, the number of copies in the bag (6 - 2)
    }

    public static class Blocking implements Runnable {
        //      Queue queue = new LinkedBlockingDeque();
        Buffer queue = BlockingBuffer.decorate(new BoundedFifoBuffer());

        @SuppressWarnings("unchecked")
        public static void main(String[] args) throws InterruptedException {
            Blocking blockThread = new Blocking();
            Thread t = new Thread(blockThread);
            t.start();
            blockThread.queue.add("Hello");
            Thread.sleep(5000);
            blockThread.queue.add("Black Lee");
        }

        public void run() {
            while (true) {
                try {
                    String msg = (String) queue.remove();
                    System.out.println(msg);
                } catch (Exception e) {
                }
            }
        }
    }
}

/**
 * @author vongosling
 */
public class Perf4jInterceptor implements MethodBeforeAdvice, AfterReturningAdvice {

    private Map<String, StopWatch> watches = new HashMap<String, StopWatch>();

    public void before(Method method, Object[] args, Object target) throws Throwable {
        String completeMethodName = getCompleteMethodName(target, method);

        StopWatch stopWatch;
        if (watches.containsKey(completeMethodName)) {
            stopWatch = watches.get(completeMethodName);
            stopWatch.start();
        } else {
            stopWatch = new Slf4JStopWatch(completeMethodName, Arrays.toString(args));
            watches.put(completeMethodName, stopWatch);
        }

    }

    public void afterReturning(Object returnValue, Method method, Object[] args, Object target)
            throws Throwable {
        String completeMethodName = getCompleteMethodName(target, method);

        if (watches.containsKey(completeMethodName)) {
            StopWatch stopWatch = watches.get(completeMethodName);
            stopWatch.stop();
        }
    }

    private String getCompleteMethodName(Object target, Method method) {
        String className = "";
        if (target != null) {
            className = target.toString();
            int loc = className.indexOf("@");
            if (loc >= 0) {
                className = className.substring(0, loc);
            }
        }

        return className + "." + method.getName();
    }
}

/**
 * @author vongosling
 */
@Aspect
public class ExceptionAspect implements Ordered {
    private final Logger logger = LoggerFactory.getLogger(ExceptionAspect.class);
    private int          order  = 100;

    @Pointcut("execution(public * com.service.*.*Impl.*(..)) && @annotation (com.service.aop.ServiceTrace)")
    public void serviceMethod() {
    }

    @Around("serviceMethod()")
    public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable {
        logger.debug("exception aop beginning...");

        ResultModel<String> result = new ResultModel<String>();

        TraceUtils.beginTrace();
        try {
            String remoteHost = DubboContext.getContext().getRemoteHost(); // 获取调用方IP
            logger.info("remoteHost = {}", remoteHost);

            Object nomralResult = pjp.proceed();

            //JMX monitor some unexpected things
            if (logger.isDebugEnabled()) {
                ByteArrayOutputStream bo = new ByteArrayOutputStream();
                ObjectOutputStream oo = new ObjectOutputStream(bo);
                oo.writeObject(nomralResult);
                byte[] array = bo.toByteArray();
                logger.debug("result size is {}", array.length);
                logger.debug("result is {}", ToStringBuilder.reflectionToString(nomralResult,
                        ToStringStyle.MULTI_LINE_STYLE));
                oo.close();
            }

            return nomralResult;
        } catch (DowjonesIllegalArgumentException ex) {
            return new ExceptionAspectProcessor() {
                @Override
                public void hookOn(ResultModel<String> result) {
                    result.setErrorCode(ErrorCode.ILLEGAL_ARGUMENT);
                }
            }.doProcessBiz(result, ex);
        } catch (IllegalArgumentException ex) {
            return new ExceptionAspectProcessor() {
                @Override
                public void hookOn(ResultModel<String> result) {
                    result.setErrorCode(ErrorCode.ILLEGAL_ARGUMENT);
                }
            }.doProcess(result, ex);
        } catch (Exception ex) {
            return new ExceptionAspectProcessor() {
                @Override
                public void hookOn(ResultModel<String> result) {
                    result.setErrorCode(ErrorCode.UNKNOWN_ERROR);
                }
            }.doProcess(result, ex);
        } finally {
            TraceUtils.endTrace();
        }

    }

    public int getOrder() {
        return order;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    private abstract class ExceptionAspectProcessor {

        protected abstract void hookOn(ResultModel<String> result);

        public final Object doProcess(ResultModel<String> result, Exception ex) {
            logger.error("catch exception: ", ex);

            doProcessResult(result,ex) ;
            hookOn(result);

            logger.debug("return result {}", result);

            return result;
        };
        public final Object doProcessBiz(ResultModel<String> result, Exception ex) {
            logger.warn("catch exception: ", ex);

            doProcessResult(result,ex) ;

            hookOn(result);

            logger.debug("return result {}", result);

            return result;
        };
        private final void doProcessResult(ResultModel<String> result, Exception ex){
            result.setSuccessed(false);
            result.setExceptionDesc(ex.getMessage());//will delete in future
            result.setErrorDesc(ex.getMessage());

        }
    }
}

/**
* 使用JCA/JCE(SUN默认的Cryptographic Service Provider)对称密钥进行加密解密
*
* @author vongosling Nov 7, 2011 2:31:24 PM
*/
public class DESEncryptUtils {

    /**
     * 解密
     *
     * @param pwd
     * @param strKey
     * @return
     */
    public static String decrypt(String pwd, String strKey) {
        if (StringUtils.isEmpty(pwd) || StringUtils.isEmpty(strKey)) {
            return null;
        }
        try {
            //1.
            byte[] rawKeyData = (new String(strKey)).getBytes();
            byte[] encryptedData = Base64.decode(pwd);
            //2.
            Security.addProvider(new com.sun.crypto.provider.SunJCE());
            //3.
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            DESKeySpec dks = new DESKeySpec(rawKeyData);
            SecretKey key = keyFactory.generateSecret(dks);
            //4.
            Cipher cipher = Cipher.getInstance("DES");
            SecureRandom sr = new SecureRandom();
            cipher.init(Cipher.DECRYPT_MODE, key, sr);
            byte[] decryptedData = cipher.doFinal(encryptedData);
            //5.
            return new String(decryptedData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 加密
     *
     * @param pwd 加密串
     * @param strKey 加密码
     * @return
     */
    public static String encrypt(String pwd, String strKey) {
        if (StringUtils.isEmpty(pwd) || StringUtils.isEmpty(strKey)) {
            return null;
        }
        try {
            //1.
            byte[] decryptData = pwd.getBytes();
            byte[] rawKeyData = (new String(strKey)).getBytes();
            //2.获得加密服务提供者
            Security.addProvider(new com.sun.crypto.provider.SunJCE());//Sun默认提供者实现
            //3.
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            DESKeySpec dks = new DESKeySpec(rawKeyData);
            SecretKey key = keyFactory.generateSecret(dks);//生成DES密钥
            //4.
            Cipher cipher = Cipher.getInstance("DES");//创建Cipher对象
            SecureRandom sr = new SecureRandom();
            //5.初始化Cipher
            cipher.init(Cipher.ENCRYPT_MODE, key, sr);
            //6.
            byte[] encryptData = cipher.doFinal(decryptData);
            //7.
            return Base64.encode(encryptData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
/**
 * @author vongosling
 */
public class TraceUtils {

    public static final String TRACE_ID_KEY    = "traceId";
    public static final int    TRACE_ID_LENGTH = 8;

    public static void beginTrace() {
        String traceId = RandomStringUtils.randomAlphanumeric(TRACE_ID_LENGTH);
        MDC.put(TRACE_ID_KEY, traceId);
    }

    public static void beginTrace(String traceId) {
        MDC.put(TRACE_ID_KEY, traceId);
    }

    public static void endTrace() {
        MDC.remove(TRACE_ID_KEY);
    }
}
/**
 * Result List based cursor theory
 * 
 * @author vongosling
 * @param <T>
 */
public class ResultCursorList<T> extends BaseDo {

    private static final long serialVersionUID = -6593448580923210640L;
    /**
     * Result list
     */
    private List<T>           values;
    /**
     * Total result
     */
    private Long              totalCount;
    /**
     * For forwarding query,it can be timestamp or offset,when
     * timestamp,previousCursor must be less than or equals nextCursor
     */
    private Long              previousCursor;
    /**
     * For backwarding query
     */
    private Long              nextCursor;

    /**
     * Init case
     * 
     * @param clasz
     * @return
     */
    public static <T> ResultCursorList<T> build(Class<T> clazz) {
        return new ResultCursorList<T>().setValues(new ArrayList<T>()).setTotalCount(0l)
                .setPreviousCursor(0l).setNextCursor(0l);
    }

    /**
     * Common case
     * 
     * @param clasz
     * @param values
     * @param totalCount
     * @param previousCursor
     * @param nextCursor
     * @return
     */
    public static <T> ResultCursorList<T> build(Class<T> clazz, List<T> values, Long totalCount,
                                                Long previousCursor, Long nextCursor) {
        if (values == null || values.isEmpty()) {
            return build(clazz);
        }
        return new ResultCursorList<T>().setValues(values).setTotalCount(totalCount)
                .setPreviousCursor(previousCursor).setNextCursor(nextCursor);
    }

    public List<T> getValues() {
        return values;
    }

    public ResultCursorList<T> setValues(List<T> values) {
        this.values = values;
        return this;
    }

    public Long getTotalCount() {
        return totalCount;
    }

    public ResultCursorList<T> setTotalCount(Long totalCount) {
        this.totalCount = totalCount;
        return this;
    }

    public Long getPreviousCursor() {
        return previousCursor;
    }

    public ResultCursorList<T> setPreviousCursor(Long previousCursor) {
        this.previousCursor = previousCursor;
        return this;
    }

    public Long getNextCursor() {
        return nextCursor;
    }

    public ResultCursorList<T> setNextCursor(Long nextCursor) {
        this.nextCursor = nextCursor;
        return this;
    }
}
/**
 * @author vongosling
 */
public final class CacheHelper {

    public static final String SPLIT = ":";

    private CacheHelper() {
    }

    public enum CacheDomain {
        /** 用户信息 */
        USER("U"),
        /** 员工信息 */
        STAFF("S"),
        /** 好友关系 */
        FRIENDRELATION("R"),
        /** 权限集 */
        PERMISSION("P");

        private String value;

        private CacheDomain(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }
    }

    /**
     * @param cacheDomain
     * @param valueId
     * @param version
     * @see http://en.wikipedia.org/wiki/SHA-2
     * @return
     */
    public static String getKey(CacheDomain cacheDomain, String valueId, int version) {
        String key = cacheDomain.getValue() + SPLIT + valueId + SPLIT + version;
        final byte[] bytes = key.getBytes();
        if (bytes.length > 250) {
            key = DigestUtils.sha256Hex(key);
        }
        return key;
    }
}

/**
 * @author vongosling
 */
public class BaseDo implements Serializable {
    private static final long serialVersionUID = 8995346561768156845L;

    /**
     * @see java.lang.Object#toString
     */
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.DEFAULT_STYLE);
    }

    /**
     * @see java.lang.Object#equals(Object)
     */
    public boolean equals(Object object) {
        if (!(object instanceof BaseDo)) {
            return false;
        }
        return new EqualsBuilder().appendSuper(super.equals(object)).isEquals();
    }

    /**
     * @see java.lang.Object#hashCode()
     */
    public int hashCode() {
        return new HashCodeBuilder(208989125, 784658211).appendSuper(super.hashCode()).toHashCode();
    }
}

上一篇:架构那点事系列一 - 设计模式前章


下一篇:一分钟完成ECS机器数据的智能巡检告警