nl.strohalm.cyclos.utils.StringHelper.java Source code

Java tutorial

Introduction

Here is the source code for nl.strohalm.cyclos.utils.StringHelper.java

Source

/*
This file is part of Cyclos (www.cyclos.org).
A project of the Social Trade Organisation (www.socialtrade.org).
    
Cyclos is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
    
Cyclos is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with Cyclos; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    
 */
package nl.strohalm.cyclos.utils;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;

/**
 * Helper class for handling strings
 * @author Jefferson Magno
 */
public class StringHelper {
    private static final String MASK_VARIABLES = "#09aAlLuUcC?_";
    private static final String DIGITS = "0123456789";
    private static final String LOWERCASE_LETTERS = "abcdefghijklmnopqrstuvwxyz";
    private static final String UPERCASE_LETTERS = LOWERCASE_LETTERS.toUpperCase();
    private static final String LETTERS = LOWERCASE_LETTERS + UPERCASE_LETTERS;

    /**
     * Removes the given mask from the given value
     */
    public static String applyMask(final String mask, final String value) {
        if (StringUtils.isEmpty(mask) || value == null) {
            return value;
        }
        final StringBuilder sb = new StringBuilder();
        boolean nextIsLiteral = false;
        int pos = 0;
        for (int i = 0; i < mask.length(); i++) {
            final char c = mask.charAt(i);
            if (c == '\\') {
                nextIsLiteral = true;
            } else if (!nextIsLiteral && MASK_VARIABLES.indexOf(c) >= 0) {
                try {
                    sb.append(value.charAt(pos++));
                } catch (final StringIndexOutOfBoundsException e) {
                    continue;
                }
            } else {
                nextIsLiteral = false;
                sb.append(c);
                if (Character.isLetterOrDigit(c)) {
                    pos++;
                }
            }
        }
        return sb.toString();
    }

    /**
     * Decodes the url
     */
    public static String decodeUrl(final String url) {
        if (url == null) {
            return null;
        }
        try {
            return URLDecoder.decode(url, "UTF-8");
        } catch (final UnsupportedEncodingException e) {
            return url;
        }
    }

    /**
     * Encodes the url
     */
    public static String encodeUrl(final String url) {
        if (url == null) {
            return null;
        }
        try {
            return URLEncoder.encode(url, "UTF-8");
        } catch (final UnsupportedEncodingException e) {
            return url;
        }
    }

    /**
     * Returns whether the given string has at least one digit
     */
    public static boolean hasDigits(final String string) {
        return StringUtils.containsAny(string, DIGITS);
    }

    /**
     * Returns whether the given string has at least one ASCII letter
     */
    public static boolean hasLetters(final String string) {
        return StringUtils.containsAny(string, LETTERS);
    }

    /**
     * Returns whether the given string has at least one special character (nor digit, nor ASCII letter)
     */
    public static boolean hasSpecial(final String string) {
        final int length = string == null ? 0 : string.length();
        if (length == 0) {
            return false;
        }
        for (int i = 0; i < length; i++) {
            final char c = string.charAt(i);
            if (LETTERS.indexOf(c) < 0 && DIGITS.indexOf(c) < 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * Check if the string is a valid Java identifier. It's not checked if the string is a reserved Java word.
     */
    public static boolean isValidJavaIdentifier(final String string) {
        if (StringUtils.isEmpty(string)) {
            return false;
        }
        if (!Character.isJavaIdentifierStart(string.charAt(0))) {
            return false;
        }
        for (int i = 1; i < string.length(); i++) {
            if (!Character.isJavaIdentifierPart(string.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    /**
     * Returns a string containing only the numbers in the given string, or null if input is null
     */
    public static String onlyNumbers(final String string) {
        if (string == null) {
            return null;
        }
        final StringBuilder numbers = new StringBuilder();
        for (int i = 0; i < string.length(); i++) {
            final char c = string.charAt(i);
            if (Character.isDigit(c)) {
                numbers.append(c);
            }
        }
        return numbers.toString();
    }

    /**
     * Removes the CR (Window) characters from the text
     * @param text
     */
    public static String removeCarriageReturnCharater(final String text) {
        return StringUtils.replace(text, "\r\n", "\n");
    }

    /**
     * Removes all html/xml tags
     */
    public static String removeMarkupTags(final String string) {
        return removeMarkupTagsAndUnescapeEntities(string, false);
    }

    /**
     * Removes all html/xml tags and entities
     */
    public static String removeMarkupTagsAndUnescapeEntities(final String string) {
        return removeMarkupTagsAndUnescapeEntities(string, true);
    }

    /**
     * Removes the given mask from the given value, trimming to mask length
     */
    public static String removeMask(final String mask, final String value) {
        return removeMask(mask, value, true);
    }

    /**
     * Removes the given mask from the given value, optionally trimming at mask max length (ex: mask is ###, 12345 would result 123 it true, and 12345
     * if false)
     */
    public static String removeMask(final String mask, final String value, final boolean trimToMask) {
        if (StringUtils.isEmpty(mask) || value == null) {
            return value;
        }
        final StringBuilder sb = new StringBuilder();
        boolean nextIsLiteral = false;
        int pos = 0;
        for (int i = 0; i < mask.length(); i++) {
            final char c = mask.charAt(i);
            if (c == '\\') {
                nextIsLiteral = true;
            } else if (!nextIsLiteral && MASK_VARIABLES.indexOf(c) >= 0) {
                try {
                    while (!Character.isLetterOrDigit(value.charAt(pos))) {
                        pos++;
                    }
                    sb.append(value.charAt(pos++));
                } catch (final StringIndexOutOfBoundsException e) {
                    break;
                }
            } else if (nextIsLiteral) {
                nextIsLiteral = false;
                sb.append(c);
                pos++;
            }
        }
        if (!trimToMask) {
            sb.append(value.substring(pos));
        }
        return sb.toString();
    }

    /**
     * Remove a variable from a query string
     */
    public static String removeQueryStringVariable(String queryString, final String var) {
        final int pos = queryString.indexOf(var + "=");
        if (pos >= 0) {
            int end = queryString.indexOf('&', pos);
            if (end < 0) {
                end = queryString.length();
            }
            queryString = queryString.substring(0, pos) + queryString.substring(end);
        }
        return queryString;
    }

    /**
     * Replaces supplementary characters with a ? character
     * @param text
     * @return
     */
    public static String replaceSupplementaryCharacters(final String text) {
        if (text == null) {
            return null;
        }
        final int len = text.length();
        boolean isSupplementary = false;
        final StringBuilder result = new StringBuilder();
        for (int i = 0; i < len; i++) {
            final int cp = Character.codePointAt(text, i);
            isSupplementary = Character.isSupplementaryCodePoint(cp);
            if (isSupplementary) {
                result.append("?");
                i++;
            } else {
                result.append(text.charAt(i));
            }
        }
        return result.toString();
    }

    /**
     * Transforms the given string into upper case, adding underscores between words. Examples:
     * <ul>
     * <li>upcase(null) == null</li>
     * <li>upcase("") == ""</li>
     * <li>upcase("myName") == "MY_NAME"</li>
     * <li>upcase("MyName") == "MY_NAME"</li>
     * <li>upcase("MyNAME") == "MY_N_A_M_E"</li>
     * </ul>
     */
    public static String upcase(final String string) {
        if (string == null) {
            return null;
        }
        final StringBuilder sb = new StringBuilder(string.length());
        for (int i = 0; i < string.length(); i++) {
            final char c = string.charAt(i);
            if (i > 0 && Character.isUpperCase(c)) {
                sb.append('_');
                sb.append(c);
            } else {
                sb.append(Character.toUpperCase(c));
            }
        }
        return sb.toString();
    }

    private static String removeMarkupTagsAndUnescapeEntities(String string, final boolean unescapeEntities) {
        if (string == null) {
            return null;
        }
        final StringBuilder sb = new StringBuilder();
        final int length = string.length();
        boolean inTag = false;
        boolean inComments = false;
        boolean hasText = false;
        for (int i = 0; i < length; i++) {
            final char c = string.charAt(i);
            if (c == '<' && i < length - 1
                    && (Character.isLetterOrDigit(string.charAt(i + 1)) || string.charAt(i + 1) == '/')) {
                inTag = true;
            } else if (i < length - 4 && "<!--".equals(string.substring(i, i + 4))) {
                inComments = true;
                i += 3;
            } else if (inComments && i < length - 3 && "-->".equals(string.substring(i, i + 3))) {
                inComments = false;
                hasText = false;
                i += 2;
            } else if (c == '>') {
                inTag = false;
                hasText = false;
            } else if (!inTag && !inComments) {
                if (!hasText) {
                    // Append an space if this is the first text right after a tag
                    hasText = true;
                    if (sb.length() > 0) {
                        // But not before the first output character
                        sb.append(' ');
                    }
                }
                sb.append(c);
            }
        }
        string = sb.toString();
        if (unescapeEntities) {
            string = StringEscapeUtils.unescapeHtml(string);
        }
        return string;
    }
}