com.iksgmbh.sql.pojomemodb.utils.StringParseUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.iksgmbh.sql.pojomemodb.utils.StringParseUtil.java

Source

/*
 * Copyright 2016 IKS Gesellschaft fuer Informations- und Kommunikationssysteme mbH
 * 
 * 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 com.iksgmbh.sql.pojomemodb.utils;

import org.apache.commons.lang3.StringUtils;

public class StringParseUtil {
    public static final String OPENING_PARENTHESIS = "(";
    public static final String CLOSING_PARENTHESIS = ")";
    public static final String SPACE = " ";
    public static final String COMMA = ",";
    public static final String EQUALSIGN = "=";
    public static final String APOSTROPY = "'";

    public static String removeSurroundingPrefixAndPostFix(final String input, final String prefix,
            final String postfix) {
        if (input.startsWith(prefix)) {
            if (input.endsWith(postfix)) {
                return input.substring(1, input.length() - 1);
            } else {
                throw new IllegalArgumentException("Missing postfix: " + postfix);
            }
        } else {
            if (input.endsWith(postfix)) {
                throw new IllegalArgumentException("Missing prefix: " + prefix);
            }
        }

        return input;
    }

    /**
     * Cuts off a piece of the input string from the beginning.
     * The position where to cut is defined by delimiter.
     * Delimiter is ignored if it es located between ignoreStartChar and ignoreEndChar. 
     * 
     * @param input
     * @param ignoreStartChar
     * @param ignoreEndChar
     * @param delimiter
     * @return
     */
    public static InterimParseResult parseNextValue(final String input, final char ignoreStartChar,
            final char ignoreEndChar, final char delimiter)

    {
        final char[] charArray = input.toCharArray();
        boolean ignoreMode = false;
        for (int pos = 0; pos < charArray.length; pos++) {
            char c = charArray[pos];

            if (c == delimiter) {
                if (!ignoreMode) {
                    return new InterimParseResult(input.substring(0, pos).trim(), input.substring(pos + 1).trim(),
                            "" + delimiter);
                }
            }

            if (!ignoreMode && c == ignoreStartChar) {
                ignoreMode = true;
            } else if (c == ignoreEndChar) {
                ignoreMode = false;
            }
        }

        return new InterimParseResult(input, "", null);
    }

    /**
     * Cuts off a piece of the input string from the beginning.
     * The position where to cut is defined by the given delimiters.
     * If more than delimiter are found, the next one 
     * (i.e. the one with the smallest position) is used to cut.
     * 
     * @param input String
     * @param delimiterArray collection of possible delimiters
     * @return ParseResult
     */
    public static InterimParseResult parseNextValue(final String input, final String... delimiterArray) {
        if (delimiterArray == null || delimiterArray.length == 0) {
            throw new IllegalArgumentException("No delimiter defined!");
        }

        final CutPositionResult result = determineCutPosition(input, delimiterArray);

        if (result.cutPosition == -1) {
            return new InterimParseResult(input, "", null);
        }

        final String value = input.substring(0, result.cutPosition).trim();
        final String unparsedRest = input.substring(result.cutPosition + result.delimiter.length()).trim();

        return new InterimParseResult(value, unparsedRest, result.delimiter);
    }

    /**
     * Cuts off a piece of the input string from the beginning.
     * The position where to cut is defined by the last occurence of the given delimiter.
     * 
     * @param input String
     * @param delimiter
     * @return ParseResult
     */
    public static InterimParseResult parseNextValueByLastOccurrence(final String input, final String delimiter) {
        if (StringUtils.isEmpty(delimiter)) {
            throw new IllegalArgumentException("No valid delimiter defined!");
        }

        if (StringUtils.isEmpty(input)) {
            return new InterimParseResult(input, "", null);
        }

        int cutPosition = input.toLowerCase().lastIndexOf(delimiter.toLowerCase());

        if (cutPosition == -1) {
            return new InterimParseResult(input, "", null);
        }

        final String value = input.substring(0, cutPosition).trim();
        final String unparsedRest = input.substring(cutPosition + delimiter.length()).trim();

        return new InterimParseResult(value, unparsedRest, delimiter);
    }

    private static CutPositionResult determineCutPosition(final String input, final String[] delimiterArray) {
        String delimiter = "";
        int cutPosition = -1;

        for (String delimiterCandidate : delimiterArray) {
            // apply default algorithm to calc pos
            int pos = input.toLowerCase().indexOf(delimiterCandidate.toLowerCase());

            // apply specific algorithm to calc pos with special solutions
            if (COMMA.equals(delimiterCandidate)) {
                pos = getNextValidCommaPosition(input);
            }
            if (SPACE.equals(delimiterCandidate)) {
                pos = getNextValidSpacePosition(input);
            }
            if (CLOSING_PARENTHESIS.equals(delimiterCandidate)) {
                pos = getNextValidClosingParenthesisPosition(input);
            }

            if (pos > -1) {
                if (cutPosition == -1 || pos < cutPosition) {
                    delimiter = delimiterCandidate;
                    cutPosition = pos;
                }
            }
        }

        return new CutPositionResult(delimiter, cutPosition);
    }

    private static int getNextValidClosingParenthesisPosition(String input) {
        char[] charArray = input.toCharArray();
        int countApostrophies = 0;
        int pos = 0;

        for (char c : charArray) {
            String ch = "" + c;
            if (ch.equals(APOSTROPY)) {
                countApostrophies++;
            }

            if (ch.equals(CLOSING_PARENTHESIS)) {
                if (countApostrophies % 2 == 0) {
                    return pos;
                }
            }
            pos++;
        }

        return -1;
    }

    /**
     * Finds the valid position to cut. Example:
     * For input="Number(10,0)," the position of the second comma (12 not 9) is valid!
     * 
     * @param input
     * @return next valid position of a comma to be used for cutting
     */
    private static int getNextValidCommaPosition(final String input) {
        if (!input.contains(COMMA)) {
            return -1;
        }

        if (input.toUpperCase().startsWith("NUMBER")) {
            int posOfClosingParenthesis = input.indexOf(CLOSING_PARENTHESIS);
            int posOfComma = input.indexOf(COMMA);

            if (posOfComma < posOfClosingParenthesis) {
                String inputPart = input.substring(posOfClosingParenthesis);
                posOfComma = inputPart.indexOf(COMMA);
                if (posOfComma == -1)
                    return -1; // no valid comma found
                return posOfClosingParenthesis + posOfComma;
            }
        }

        return input.indexOf(COMMA);
    }

    /**
     * Finds the valid position to cut. Example:
     * For input="VARCHAR2(10 CHAR) not null enabled" the position of the second comma (17 not 11) is valid!
     * 
     * @param input
     * @return next valid position of a space to be used for cutting
     */
    private static int getNextValidSpacePosition(final String input) {
        if (!input.contains(SPACE)) {
            return -1;
        }

        if (input.toUpperCase().startsWith("VARCHAR")) {
            int posOfOpeningParenthesis = input.indexOf(OPENING_PARENTHESIS);
            int posOfComma = input.indexOf(SPACE);

            if (posOfComma > posOfOpeningParenthesis) {
                int posOfClosingParenthesis = input.indexOf(CLOSING_PARENTHESIS);
                String inputPart = input.substring(posOfClosingParenthesis);
                posOfComma = inputPart.indexOf(SPACE);
                return posOfClosingParenthesis + posOfComma;
            }
        }
        return input.indexOf(SPACE);
    }

    public static int countOccurrencesOf(String input, char charToSearch) {
        final char[] chars = input.toCharArray();
        int counter = 0;
        for (char c : chars) {
            if (c == charToSearch) {
                counter++;
            }
        }
        return counter;
    }

    public static class InterimParseResult {
        @Override
        public String toString() {
            return "InterimParseResult [parsedValue=" + parsedValue + ", unparsedRest=" + unparsedRest
                    + ", delimiter=" + delimiter + "]";
        }

        public String parsedValue;
        public String unparsedRest;
        public String delimiter;

        protected InterimParseResult(String lastParsedValue, String unparsedRest, String delimiter) {
            this.parsedValue = lastParsedValue;
            this.unparsedRest = unparsedRest;
            this.delimiter = delimiter;
        }
    }

    static class CutPositionResult {
        String delimiter;
        int cutPosition;

        public CutPositionResult(String delimiter, int cutPosition) {
            this.cutPosition = cutPosition;
            this.delimiter = delimiter;
        }
    }
}