org.seasar.mayaa.impl.util.StringUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.seasar.mayaa.impl.util.StringUtil.java

Source

/*
 * Copyright 2004-2012 the Seasar Foundation and the Others.
 *
 * 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.seasar.mayaa.impl.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.collections.map.AbstractReferenceMap;
import org.apache.commons.collections.map.ReferenceMap;
import org.cyberneko.html.HTMLEntities;
import org.seasar.mayaa.impl.cycle.script.ScriptUtil;
import org.seasar.mayaa.impl.source.ClassLoaderSourceDescriptor;

/**
 * @author Masataka Kurihara (Gluegent, Inc.)
 */
public final class StringUtil {

    private static Map _propFiles = Collections
            .synchronizedMap(new ReferenceMap(AbstractReferenceMap.SOFT, AbstractReferenceMap.SOFT, true));
    private static final String[] ZERO = new String[0];

    private StringUtil() {
        // no instantiation.
    }

    /**
     * ??????
     * <p>
     * ?{@link #isEmpty(String)}?????
     * ???????{@link ScriptUtil#isEmpty(Object)}?????
     * </p>
     * @param test
     * @return ?????true
     */
    public static boolean isEmpty(Object test) {
        boolean result;
        if (test instanceof String) {
            result = isEmpty((String) test);
        } else {
            result = ScriptUtil.isEmpty(test);
            if (result == false) {
                result = isEmpty(test.toString());
            }
        }
        return result;
    }

    /**
     * ??({@link Object#toString()}?
     * ???{@code null}?{@code null}????
     * @param value 
     * @return ?????{@code null}
     */
    public static String valueOf(Object value) {
        if (value == null) {
            return null;
        }
        return value.toString();
    }

    /**
     * test?null????true???
     *
     * @param test ?
     * @return null????true
     */
    public static boolean isEmpty(String test) {
        return test == null || test.length() == 0;
    }

    public static boolean hasValue(Object test) {
        return isEmpty(test) == false;
    }

    public static boolean hasValue(String test) {
        return isEmpty(test) == false;
    }

    /**
     * ?????????
     * "/"????"/"?????"/"????
     * "/"?????
     * path?null????trim()????????
     *
     * @param path ??
     * @return ??
     */
    public static String preparePath(final String path) {
        if (isEmpty(path)) {
            return "";
        }
        char[] chars = toTrimedCharArray(path);
        if (chars.length == 0) {
            return "";
        }

        int length = chars.length;
        if (File.separatorChar != '/') {
            for (int i = 0; i < length; i++) {
                if (chars[i] == File.separatorChar) {
                    chars[i] = '/';
                }
            }
        }
        if (chars[length - 1] == '/') {
            length = length - 1;
        }
        if (chars[0] != '/') {
            char[] extended = new char[length + 1];
            System.arraycopy(chars, 0, extended, 1, length);
            extended[0] = '/';
            length = length + 1;

            chars = extended;
        }
        return new String(chars, 0, length);
    }

    /**
     * {@link String#trim()}?{@link String#toCharArray()}????
     * ???????char??
     *
     * @param value ??
     * @return ????char?
     */
    public static char[] toTrimedCharArray(String value) {
        if (value == null) {
            return null;
        }
        char[] chars = value.toCharArray();
        int end = chars.length;
        int start = 0;

        while ((start < end) && (chars[start] <= ' ')) {
            start++;
        }
        while ((start < end) && (chars[end - 1] <= ' ')) {
            end--;
        }
        if (start > 0 || end < chars.length) {
            int length = end - start;
            char[] result = new char[length];
            System.arraycopy(chars, start, result, 0, length);
            return result;
        }
        return chars;
    }

    /**
     * &amp;xx;??????????
     *
     * @param blockString ??????
     * @return ???????
     */
    public static String resolveEntity(String blockString) {
        StringBuffer buffer = new StringBuffer();
        int start = blockString.indexOf("&");
        if (start == -1) {
            return blockString;
        }
        buffer.append(blockString.substring(0, start));
        String entity;
        while (true) {
            int end = blockString.indexOf(";", start);
            if (end == -1) {
                buffer.append(blockString.substring(start));
                break;
            }
            entity = blockString.substring(start + 1, end);
            int value = HTMLEntities.get(entity);
            if (value != -1) {
                buffer.append((char) value);
            } else {
                buffer.append(blockString.substring(start, end + 1));
            }
            start = blockString.indexOf("&", end);
            if (start == -1) {
                buffer.append(blockString.substring(end + 1));
                break;
            }
            if (start != end + 1) {
                buffer.append(blockString.substring(end + 1, start));
            }
            if (start == blockString.length()) {
                break;
            }
        }
        return buffer.toString();
    }

    /**
     * URL??????????
     * <p>
     * ?????????????????
     * (/foo/bar.html?query=value&amp;query2=value2#fragment  ["/foo/bar.html", "query=value&amp;query2=value2", "fragment"])
     * (/foo/bar.html  ["/foo/bar.html", "", ""])
     * (/foo/bar$foo.html  ["/foo/bar.html", "", ""])
     * </p>
     * @param value URL
     * @param suffixSeparator ?
     * @return ???[0]:, [1]:, [2]:
     */
    public static String[] parseURIQuery(String value, String suffixSeparator) {
        String[] result = new String[3];
        String path;

        int fIndex = value.indexOf('#');
        if (fIndex >= 0) {
            path = value.substring(0, fIndex);
            result[2] = value.substring(fIndex + 1);
        } else {
            path = value;
            result[2] = "";
        }

        int qIndex = path.indexOf('?');
        if (qIndex >= 0) {
            result[0] = path.substring(0, qIndex);
            result[1] = path.substring(qIndex + 1);
        } else {
            result[0] = path;
            result[1] = "";
        }

        int suffixIndex = result[0].indexOf(suffixSeparator);
        int extensionIndex = result[0].lastIndexOf('.');
        if (suffixIndex >= 0 && extensionIndex > suffixIndex) {
            result[0] = result[0].substring(0, suffixIndex) + result[0].substring(extensionIndex);
            // Apache?$??????\\????????????suffix??\\?
            if (suffixSeparator.equals("$") && result[0].charAt(suffixIndex - 1) == '\\') {
                result[0] = result[0].substring(0, suffixIndex - 1) + result[0].substring(suffixIndex);
            }
        }

        return result;
    }

    /**
     * ?????????????
     * <p>
     * ????????????
     * (/foo/bar$suffix.html  ["/foo/bar", "suffix", "html"])
     * (/foo/bar  ["/foo/bar", "", ""])
     * </p>
     * @param path 
     * @param suffixSeparator ?
     * @return ???[0]:, [1]:, [2]:?
     */
    public static String[] parsePath(String path, String suffixSeparator) {
        path = path.trim();
        String[] ret = new String[3];
        int paramOffset = path.indexOf('?');
        if (paramOffset >= 0) {
            path = path.substring(0, paramOffset);
        }
        int lastSlashOffset = path.lastIndexOf('/');
        String folder = "";
        String file = path;
        if (lastSlashOffset >= 0) {
            folder = path.substring(0, lastSlashOffset + 1);
            file = path.substring(lastSlashOffset + 1);
        }
        int lastDotOffset = file.lastIndexOf('.');
        if (lastDotOffset > 0) {
            ret[2] = file.substring(lastDotOffset + 1);
            file = file.substring(0, lastDotOffset);
        } else {
            ret[2] = "";
        }
        int suffixSeparatorOffset = file.lastIndexOf(suffixSeparator);
        if (suffixSeparatorOffset > 0) {
            ret[0] = folder + file.substring(0, suffixSeparatorOffset);
            ret[1] = file.substring(suffixSeparatorOffset + suffixSeparator.length());
        } else {
            ret[0] = folder + file;
            ret[1] = "";
        }
        return ret;
    }

    public static boolean isRelativePath(String path) {
        if (isEmpty(path)) {
            return false;
        }
        return path.startsWith("./");
    }

    /**
     * ??
     *
     * @param base ??? ("/"?)
     * @param path ????
     * @return 
     */
    public static String adjustRelativePath(String base, String path) {
        if (isRelativePath(path) == false) {
            return path;
        }

        if (isEmpty(base)) {
            throw new IllegalArgumentException();
        }

        try {
            String baseDir = base.substring(0, base.lastIndexOf('/'));
            return adjustRecursive(baseDir, path);
        } catch (StringIndexOutOfBoundsException e) {
            throw new RuntimeException(e);
        }
    }

    protected static String adjustRecursive(String dir, String path) {
        if (isEmpty(path)) {
            return dir + '/';
        }

        try {
            if (path.startsWith("../")) {
                if (isEmpty(dir)) {
                    return adjustRecursive(dir, path.substring(3));
                }

                String parentDir = dir.substring(0, dir.lastIndexOf('/'));
                return adjustRecursive(parentDir, path.substring(3));
            } else if (path.startsWith("./")) {
                return adjustRecursive(dir, path.substring(2));
            }

            return dir + '/' + path;
        } catch (StringIndexOutOfBoundsException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * ???
     * hostPage?path???????
     *
     * @param hostPage ??? ("/"?)
     * @param path ? ("/"?)
     * @return hostPage?path??????
     */
    public static String adjustContextRelativePath(String hostPage, String path) {
        if (isEmpty(hostPage) || isEmpty(path) || (path.startsWith("/") == false)) {
            return path;
        }

        String[] hostPath = hostPage.split("/");
        String[] linkPath = path.split("/");

        int matchedDirs = 1;// ?????1?
        while (hostPath.length > matchedDirs && linkPath.length > matchedDirs
                && hostPath[matchedDirs].equals(linkPath[matchedDirs])) {
            matchedDirs += 1;
        }

        int depth = hostPath.length - (matchedDirs + 1);

        StringBuffer sb = new StringBuffer();
        sb.append(times("../", depth));

        for (int i = matchedDirs; linkPath.length > i; i++) {
            sb.append(linkPath[i]);
            sb.append('/');
        }
        if (path.charAt(path.length() - 1) != '/') {
            sb.delete(sb.length() - 1, sb.length());
        }

        return sb.toString();
    }

    /**
     * unitcount???
     * unit?null????count?0???
     *
     * @param unit ?
     * @param count ?
     * @return unitcount??
     */
    public static String times(String unit, int count) {
        if (count <= 0 || isEmpty(unit)) {
            return "";
        }
        StringBuffer sb = new StringBuffer(unit.length() * count);
        for (int i = 0; i < count; i++) {
            sb.append(unit);
        }
        return sb.toString();
    }

    public static String removeFileProtocol(String systemID) {
        if (hasValue(systemID) && systemID.startsWith("file://")) {
            return systemID.substring(7);
        }
        return systemID;
    }

    private static final String SP_OPEN = "${";
    private static final String SP_CLOSE = "}";

    public static boolean hasSystemProperties(String value) {
        int openIndex = value.indexOf(SP_OPEN);
        int closeIndex = value.lastIndexOf(SP_CLOSE);
        return (openIndex >= 0 && closeIndex >= 0 && openIndex < closeIndex);
    }

    /**
     * ??
     * <p>
     * "${user.home}"?????????{@link System#getProperty(String)}??
     * ?????(????"user.home"???)
     * </p>
     * @param value ??
     * @return ??????????
     * @throws IllegalStateException ?{@code null}????
     */
    public static String replaceSystemProperties(String value) {
        if (hasSystemProperties(value) == false) {
            return value;
        }

        StringBuffer buffer = new StringBuffer(value.length() + 100);

        int openIndex = value.indexOf(SP_OPEN);
        buffer.append(value.substring(0, openIndex));

        while (openIndex < value.length()) {
            int fromIndex = openIndex + SP_OPEN.length();

            int closeIndex = value.indexOf(SP_CLOSE, fromIndex);
            if (closeIndex >= 0) {
                String key = value.substring(fromIndex, closeIndex).trim();

                String propertyValue = System.getProperty(key);
                if (propertyValue == null) {
                    throw new IllegalStateException(key);
                }
                buffer.append(propertyValue);

                int lastIndex = closeIndex + SP_CLOSE.length();
                openIndex = value.indexOf(SP_OPEN, lastIndex);
                if (openIndex < 0) {
                    openIndex = value.length();
                }
                buffer.append(value.substring(lastIndex, openIndex));
            } else {
                buffer.append(value.substring(openIndex));
                openIndex = value.length();
            }
        }

        return buffer.toString();
    }

    public static String getMessage(Class clazz, int index) {
        return getMessage(clazz, index, ZERO);
    }

    public static String getMessage(Class clazz, int index, String param0) {
        return getMessage(clazz, index, new String[] { param0 });
    }

    public static String getMessage(Class clazz, int index, String param0, String param1) {
        return getMessage(clazz, index, new String[] { param0, param1 });
    }

    public static String getMessage(Class clazz, int index, String param0, String param1, String param2) {
        return getMessage(clazz, index, new String[] { param0, param1, param2 });
    }

    protected static String getMessage(Class clazz, int index, String[] params) {
        Package key = clazz.getPackage();
        Properties properties = (Properties) _propFiles.get(key);
        if (properties == null) {
            ClassLoaderSourceDescriptor source = new ClassLoaderSourceDescriptor();
            source.setSystemID("message.properties");
            source.setNeighborClass(clazz);
            properties = new Properties();
            _propFiles.put(key, properties);
            if (source.exists()) {
                InputStream stream = source.getInputStream();
                try {
                    properties.load(stream);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                } finally {
                    IOUtil.close(stream);
                }
            }
        }
        String className = ObjectUtil.getSimpleClassName(clazz);
        StringBuffer propertyName = new StringBuffer(className);
        if (index > 0) {
            propertyName.append(".").append(index);
        }
        String message = properties.getProperty(propertyName.toString());
        if (isEmpty(message)) {
            message = "!" + clazz.getName() + "!";
        }
        if (params == null) {
            params = ZERO;
        }
        return MessageFormat.format(message, params);
    }

    /**
     * XML????(&amp;, &lt;, &gt;, &quot;)
     * @param text ?
     * @return ?
     */
    public static String escapeXml(String text) {
        if (text == null) {
            return "";
        }
        char[] chars = text.toCharArray();
        StringBuffer sb = new StringBuffer(chars.length + 50);

        for (int i = 0; i < chars.length; i++) {
            switch (chars[i]) {
            case '&':
                sb.append("&amp;");
                break;
            case '<':
                sb.append("&lt;");
                break;
            case '>':
                sb.append("&gt;");
                break;
            case '"':
                sb.append("&quot;");
                break;
            default:
                sb.append(chars[i]);
            }
        }

        return sb.toString();
    }

    /**
     * XML?"&amp;"?????(&lt;, &gt;, &quot;)
     * @param text ?
     * @return ?
     */
    public static String escapeXmlWithoutAmp(String text) {
        if (text == null) {
            return "";
        }
        char[] chars = text.toCharArray();
        StringBuffer sb = new StringBuffer(chars.length + 50);

        for (int i = 0; i < chars.length; i++) {
            switch (chars[i]) {
            case '<':
                sb.append("&lt;");
                break;
            case '>':
                sb.append("&gt;");
                break;
            case '"':
                sb.append("&quot;");
                break;
            default:
                sb.append(chars[i]);
            }
        }

        return sb.toString();
    }

    /**
     * XML??????(\r, \n, \t)
     * @param text ?
     * @return ?
     */
    public static String escapeWhitespace(String text) {
        if (text == null) {
            return "";
        }
        char[] chars = text.toCharArray();
        StringBuffer sb = new StringBuffer(chars.length + 50);

        for (int i = 0; i < chars.length; i++) {
            switch (chars[i]) {
            case '\r':
                sb.append("&#xd;");
                break;
            case '\n':
                sb.append("&#xa;");
                break;
            case '\t':
                sb.append("&#x9;");
                break;
            default:
                sb.append(chars[i]);
            }
        }

        return sb.toString();
    }

    /**
     * &lt;br&gt;????
     * @param text ?
     * @param forHTML HTML???(HTML?empty??????)
     * @return ?
     */
    public static String escapeEol(String text, boolean forHTML) {
        if (text == null) {
            return "";
        }
        String br = (forHTML ? "<br>" : "<br />");

        char[] chars = text.toCharArray();
        StringBuffer sb = new StringBuffer(chars.length + 50);

        for (int i = 0; i < chars.length; i++) {
            switch (chars[i]) {
            case '\r':
                sb.append(br);
                if (chars.length > i + 1 && chars[i + 1] == '\n') {
                    i++;
                }
                break;
            case '\n':
                sb.append(br);
                break;
            default:
                sb.append(chars[i]);
            }
        }

        return sb.toString();
    }

    /**
     * ????
     * @param qName ??{@code null}???
     * @return ???
     * @throws IllegalArgumentException {@code qName}?{@code null}????
     */
    public static String parsePrefix(String qName) {
        if (qName == null) {
            throw new IllegalArgumentException();
        }
        int position = qName.indexOf(':');
        if (position >= 0) {
            return qName.substring(0, position);
        }
        return "";
    }

    public static boolean equals(Object s1, Object s2) {
        return s1 == null && s2 == null || (s1 != null && s1.equals(s2));
    }

    public static String join(Object[] items, String delimiter) {
        if (items == null) {
            return String.valueOf(items);
        }
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < items.length; i++) {
            if (i > 0) {
                sb.append(delimiter);
            }
            sb.append(items[i]);
        }
        return sb.toString();
    }

    /**
     * ?????????
     *
     * @param src ???
     * @return src??
     * @throws NullPointerException
     */
    public static String[] arraycopy(String[] src) {
        String[] copy = new String[src.length];
        System.arraycopy(src, 0, copy, 0, src.length);
        return copy;
    }

}