me.xhh.utils.Util.java Source code

Java tutorial

Introduction

Here is the source code for me.xhh.utils.Util.java

Source

/* ******************************************************************
Copyright 2010 Xu Hui Hui (http://xhh.me)
    
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 me.xhh.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Common utility.
 * 
 * @author xhh
 */
public class Util {

    public static final boolean DEBUG = false;

    public static final String ENC_UTF8 = "UTF-8";

    /** The default locale for time: US */
    public static final Locale DEFAULT_LOCALE = Locale.US;

    /** The default date format: "yyyy-MM-dd", e.g. 2010-07-01 */
    public static final SimpleDateFormat DEFAULT_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd", DEFAULT_LOCALE);
    /** The default date format: "yyyy-MM-dd HH:mm:ss", e.g. 2010-07-01 15:01:00 */
    public static final SimpleDateFormat DEFAULT_DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
            DEFAULT_LOCALE);
    public static final DecimalFormat DEFAULT_DECIMAL_FORMAT = new DecimalFormat("#,##0.00");

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

    /**
     * Compare two objects without needing of checking <code>null</code>.
     * 
     * @param a
     *            the first object to compare with
     * @param b
     *            the second object to compare with
     * @return <code>true</code> if both <code>a</code> and <code>b</code> are <code>null</code>, or <code>a.equals(b)</code> is
     *         <code>true</code>. Otherwise <code>false</code>.
     * @see #notEqual(Object, Object)
     */
    public static boolean isEqual(Object a, Object b) {
        return a == null ? (b == null) : a.equals(b);
    }

    /**
     * @return <code>!isEquals(a, b)</code>
     * @see #isEqual(Object, Object)
     */
    public static boolean notEqual(Object a, Object b) {
        return !isEqual(a, b);
    }

    /**
     * Build a link URL with the given data, e.g. if <br/>
     * the root URL is "http://www.imperiosus.com", <br/>
     * the sub parts are ["hello", "world"], <br/>
     * and the parameters are {"from": "Nanjing", "to": "the world!"}, <br/>
     * then the link URL would be: <br/>
     * "http://www.imperiosus.com/hello/world/?from=Nanjing&amp;to=the%20world!".
     * 
     * @param rootURL
     *            The root URL. A slash ("/") would be used if it is null.<br/>
     *            It the given root URL misses a tailing slash, it would be appended if necessary.
     * @param subParts
     *            The sub parts. If null or empty, it is ignored. Null values in the array are also ignored.
     * @param params
     *            The parameters.
     * @return The link URL built.
     */
    public static String buildLinkURL(String rootURL, String[] subParts, Map<String, String> params) {
        final char SLASH = '/';
        StringBuilder link = new StringBuilder();

        // Append the root URL
        if (rootURL == null || rootURL.isEmpty()) {
            link.append(SLASH);
        } else {
            link.append(rootURL);
            int pos = rootURL.indexOf("://");
            if (pos < 0) {
                pos = 0;
            } else {
                pos += "://".length();
            }
            pos = rootURL.indexOf('/', pos);
            if (pos < 0 && rootURL.charAt(rootURL.length() - 1) != SLASH) {
                link.append(SLASH);
            }
        }
        // Append the sub parts (or directories/packages)
        if (subParts != null) {
            for (String sub : subParts) {
                if (sub == null) {
                    continue;
                }
                try {
                    String encoded = URLEncoder.encode(sub, ENC_UTF8);
                    link.append(encoded).append(SLASH);
                } catch (UnsupportedEncodingException e) {
                    log.error("buildLinkURL: URLEncoder.encode failed! String: " + sub, e);
                    continue;
                }
            } // for
        }
        // Append parameters
        if (params != null && !params.isEmpty()) {
            link.append('?');
            boolean isFirst = true;
            for (String key : params.keySet()) {
                String val = params.get(key);
                try {
                    if (isFirst) {
                        isFirst = false;
                    } else {
                        link.append('&');
                    }
                    // Append parameter key
                    String encoded = URLEncoder.encode(key, ENC_UTF8);
                    link.append(encoded).append('=');
                    // Append parameter value
                    encoded = URLEncoder.encode(val, ENC_UTF8);
                    link.append(encoded);
                } catch (UnsupportedEncodingException e) {
                    log.error("buildLinkURL: URLEncoder.encode failed! Key: " + key + ", Value: " + val, e);
                    continue;
                }
            } // for
        }

        return link.toString();
    }

    /**
     * @return the client IP address found from the given request. would find the IP data set by proxy first
     */
    public static String getClientIP(HttpServletRequest request) {
        if (request == null)
            return null;

        final String UNKNOWN_TOKEN = "unknown";
        String ip = request.getHeader("x-forwarded-for");

        if (StringUtils.isBlank(ip) || UNKNOWN_TOKEN.equalsIgnoreCase(ip))
            ip = request.getHeader("Proxy-Client-IP");

        if (StringUtils.isBlank(ip) || UNKNOWN_TOKEN.equalsIgnoreCase(ip))
            ip = request.getHeader("WL-Proxy-Client-IP");

        if (StringUtils.isBlank(ip) || UNKNOWN_TOKEN.equalsIgnoreCase(ip))
            ip = request.getRemoteAddr();

        return ip;
    }

    /**
     * @param len
     *            length of code to be generated
     * @param humanReadable
     *            whether to generate a human-readable code (excluding some confusing characters like 1 and l)
     * @return a random code, containing lower-case letters and numbers
     */
    public static String generateCode(int len, boolean humanReadable) {
        final char[] codeArr = humanReadable
                ? new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'r', 's', 't', 'u',
                        'v', 'w', 'x', 'y', 'z', '2', '3', '4', '5', '6', '7', '8', '9' }
                : new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
                        'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8',
                        '9' };
        Random rand = new Random();
        StringBuilder code = new StringBuilder();

        for (int i = 0; i < len; i++)
            code.append(codeArr[rand.nextInt(codeArr.length)]);

        return code.toString();
    }

    public static String generateCode(int minLen, int maxLen, boolean humanReadable) {
        int len = minLen + (int) (Math.random() * (maxLen - minLen + 1));
        return generateCode(len, humanReadable);
    }

}