org.diffkit.util.DKStringUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.diffkit.util.DKStringUtil.java

Source

/**
 * Copyright 2010-2011 Joseph Panico
 *
 * 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.diffkit.util;

import java.net.URI;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.diffkit.common.DKValidate;

/**
 * @author jpanico
 */
public class DKStringUtil {

    public enum Quote {
        SINGLE('\''), DOUBLE('"');

        public final char _character;

        private Quote(char character_) {
            _character = character_;
        }
    }

    private static final Pattern UNSIGNED_INTEGER_PATTERN = Pattern.compile("\\d+");

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

    private DKStringUtil() {
    }

    public static Boolean parseBoolean(String target_, Boolean default_) {
        Boolean parsed = parseBoolean(target_);
        if (parsed == null)
            return default_;
        return parsed;
    }

    public static Boolean parseBoolean(String target_) {
        target_ = StringUtils.trimToNull(target_);
        if (target_ == null)
            return null;
        if ((target_.equalsIgnoreCase("true")) || (target_.equalsIgnoreCase("yes")))
            return Boolean.TRUE;
        if ((target_.equalsIgnoreCase("false")) || (target_.equalsIgnoreCase("no")))
            return Boolean.FALSE;
        return null;
    }

    /**
     * assumes comma separator
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static List<?> parseEnumList(String target_, Class enumClass_) {
        if (target_ == null)
            return null;
        String[] elements = target_.split(",");
        if (ArrayUtils.isEmpty(elements))
            return null;
        List<Enum> values = new ArrayList<Enum>(elements.length);
        for (String element : elements) {
            element = StringUtils.trimToNull(element);
            if (element == null)
                continue;
            values.add(Enum.valueOf(enumClass_, element));
        }
        return values;
    }

    /**
     * one range only; dash (hyphen) separated
     */
    public static List<Integer> parseIntegerRange(String target_) {
        target_ = StringUtils.trimToNull(target_);
        if (target_ == null)
            return null;
        String[] endPoints = target_.split("-");
        if ((endPoints == null) || (endPoints.length != 2))
            throw new RuntimeException(String.format("invalid range string->%s", target_));
        int start = Integer.parseInt(StringUtils.trimToNull(endPoints[0]));
        int end = Integer.parseInt(StringUtils.trimToNull(endPoints[1]));
        if (!(end >= start))
            throw new RuntimeException(String.format("end must be >= start in range string->%s", target_));

        List<Integer> list = new ArrayList<Integer>(end - start);
        for (int i = start; i <= end; i++)
            list.add(new Integer(i));
        return list;
    }

    /**
     * assumes comma separator
     */
    public static List<Integer> parseIntegerList(String target_) {
        if (target_ == null)
            return null;
        String[] elements = target_.split(",");
        if (ArrayUtils.isEmpty(elements))
            return null;
        List<Integer> values = new ArrayList<Integer>(elements.length);
        for (String element : elements)
            values.add(NumberUtils.createInteger(StringUtils.trimToNull(element)));
        return values;
    }

    /**
     * can handle individual values, comma separated lists, and dash (hyphen)
     * separated ranges <br/>
     * null safe
     */
    public static List<Integer> parseIntegers(String target_) {
        target_ = StringUtils.trimToNull(target_);
        if (target_ == null)
            return null;
        if (target_.contains(","))
            return parseIntegerList(target_);
        else if (target_.contains("-"))
            return parseIntegerRange(target_);
        List<Integer> list = new ArrayList<Integer>(1);
        list.add(Integer.valueOf(target_));
        return list;
    }

    /**
     * null and Exception safe
     */
    public static URI createURI(String target_) {
        if (target_ == null)
            return null;
        try {
            return new URI(target_);
        } catch (Exception e_) {
            LOG.error(null, e_);
            return null;
        }
    }

    public static String packageNameToResourcePath(String packageName_) {
        if (packageName_ == null)
            return null;
        return packageName_.replace('.', '/') + "/";
    }

    public static String quote(String target_, Quote kind_) {
        if (target_ == null)
            return null;
        DKValidate.notNull(kind_);
        if (!(target_.length() == 0) && (target_.charAt(0) == kind_._character))
            return target_;
        return kind_._character + target_ + kind_._character;
    }

    /**
     * commons lang version doesn't seem to work
     */
    public static String replaceAllOccurrencesOfEach(String target_, String[] searchList_,
            String[] replacementList_) {
        if ((target_ == null) || (ArrayUtils.isEmpty(searchList_)) || (ArrayUtils.isEmpty(replacementList_)))
            return target_;
        if (!(searchList_.length == replacementList_.length))
            throw new IllegalArgumentException(
                    String.format("searchList_ size %s does not match replacementList_ size %s", searchList_.length,
                            replacementList_.length));
        for (int i = 0; i < searchList_.length; i++)
            target_ = target_.replaceAll(searchList_[i], replacementList_[i]);
        return target_;
    }

    /**
     * for each String in searchList_, replace all occurrences with quoted
     * equivalent
     */
    public static String quoteAllOccurrencesOfEach(String target_, String[] searchList_, Quote kind_) {
        if ((target_ == null) || (ArrayUtils.isEmpty(searchList_)) || (kind_ == null))
            return target_;
        String[] quotedSearchList = new String[searchList_.length];
        for (int i = 0; i < searchList_.length; i++)
            quotedSearchList[i] = quote(searchList_[i], kind_);
        return replaceAllOccurrencesOfEach(target_, searchList_, quotedSearchList);
    }

    /**
     * convenience that calls unquote(String, Quote) for each element <br/>
     * 
     * N.B. actually modifies target_
     */
    public static void unquote(String[] target_, Quote kind_) {
        DKValidate.notNull(kind_);
        if (ArrayUtils.isEmpty(target_))
            return;
        for (int i = 0; i < target_.length; i++)
            target_[i] = unquote(target_[i], kind_);
    }

    public static String unquote(String target_, Quote kind_) {
        DKValidate.notNull(kind_);
        if (target_ == null)
            return null;
        if (target_.length() < 2)
            return target_;
        char[] chars = target_.toCharArray();
        if (!((chars[0] == kind_._character) && (chars[chars.length - 1] == kind_._character)))
            return target_;
        return new String(ArrayUtils.subarray(chars, 1, chars.length - 1));
    }

    /**
     * parenthesis bracketed, comma separated
     */
    public static <T> String toSetString(List<T> target_) {
        if (target_ == null)
            return toSetString((Object[]) null);
        return toSetString(target_.toArray());
    }

    /**
     * parenthesis bracketed, comma separated
     */
    public static <T> String toSetString(T[] target_) {
        if (ArrayUtils.isEmpty(target_))
            return "()";

        StringBuilder builder = new StringBuilder();
        builder.append("(");
        for (int i = 0; i < target_.length; i++) {
            builder.append(target_[i].toString());
            if (i < (target_.length - 1))
                builder.append(", ");
        }
        builder.append(")");
        return builder.toString();
    }

    /**
     * @param startIndex_
     *           inclusive, as in java.lang.String subrange methods
     * @param endIndex_
     *           exclusive, as in java.lang.String subrange methods
     */
    public static int countMatches(String target_, char match_, int startIndex_, int endIndex_) {
        if (target_ == null)
            return 0;
        int targetLength = target_.length();
        if (startIndex_ < 0 || startIndex_ >= targetLength)
            throw new IllegalArgumentException(String.format("startIndex_->%s out of bounds", startIndex_));
        if (endIndex_ < 0 || endIndex_ > targetLength)
            throw new IllegalArgumentException(String.format("endIndex_->%s out of bounds", startIndex_));
        if (startIndex_ >= endIndex_)
            return 0;

        char[] chars = target_.toCharArray();
        if (chars == null)
            return 0;

        int count = 0;
        for (int i = startIndex_; i < endIndex_; i++)
            if (chars[i] == match_)
                count++;
        return count;
    }

    @SuppressWarnings("unchecked")
    public static String replaceEach(String target_, Map<String, String> replacements_) {
        if (target_ == null)
            return null;
        if (MapUtils.isEmpty(replacements_))
            return target_;
        Object[] entries = replacements_.entrySet().toArray();
        String[] originals = new String[entries.length];
        String[] subs = new String[entries.length];
        for (int i = 0; i < entries.length; i++) {
            originals[i] = ((Map.Entry<String, String>) entries[i]).getKey();
            subs[i] = ((Map.Entry<String, String>) entries[i]).getValue();
        }
        return StringUtils.replaceEach(target_, originals, subs);
    }

    /**
     * finds the first streak of numeric characters and converts them into an
     * Integer. signs (+|-) are ignored
     * 
     * @return null if no numeric characters are found in target_
     */
    public static Integer extractFirstInteger(String target_) {
        if (target_ == null)
            return null;
        Matcher matcher = UNSIGNED_INTEGER_PATTERN.matcher(target_);
        if (!matcher.find())
            return null;
        String integerString = matcher.group();
        if (StringUtils.isEmpty(integerString))
            return null;
        return Integer.parseInt(integerString);
    }

    /**
     * compare Strings by finding the first embedded streak of number chars,
     * converting those into a Number, and then comparing the Numbers
     */
    public static class StringNumberComparator implements Comparator<String> {

        public static final Comparator<String> INSTANCE = new StringNumberComparator();

        private StringNumberComparator() {
        }

        public int compare(String left_, String right_) {
            Integer leftInt = extractFirstInteger(left_);
            Integer righInt = extractFirstInteger(right_);
            boolean leftNull = (leftInt == null) ? true : false;
            boolean rightNull = (righInt == null) ? true : false;
            if (leftNull && rightNull)
                return 0;
            else if (leftNull)
                return -1;
            else if (rightNull)
                return 1;

            return leftInt.compareTo(righInt);
        }

    }
}