All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.oneandone.sushi.util.Separator Maven / Gradle / Ivy

/*
 * Copyright 1&1 Internet AG, https://github.com/1and1/
 *
 * 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 net.oneandone.sushi.util;

import net.oneandone.sushi.io.LineFormat;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Splits and joins strings on a separator. Similar to Google's Splitter
 * http://guava-libraries.googlecode.com/svn/tags/release09/javadoc/com/google/common/base/Splitter.html and
 * Joiner http://guava-libraries.googlecode.com/svn/tags/release09/javadoc/com/google/common/base/Joiner.html.
 * Immutable, configuration methods return new instances.
 */
public class Separator {
    /** Whitespace delimited lists. Skip empty because I want to ignore heading/tailing whitespace */
    public static final Separator SPACE = Separator.on(" ", Pattern.compile("\\s+")).skipEmpty();

    /** Separator in user-supplied lists. */
    public static final Separator COMMA = Separator.on(',').trim().skipEmpty().forNull("null");

    /** Skip empty remove the last line */
    public static final Separator RAW_LINE = Separator.on("\n", LineFormat.GENERIC_SEPARATOR).trim(LineFormat.Trim.NOTHING).skipEmpty();

    public static Separator on(char c) {
        return on(Character.toString(c));
    }

    public static Separator on(String separator) {
        return new Separator(separator, Pattern.compile(Pattern.quote(separator)));
    }

    public static Separator on(String separator, Pattern pattern) {
        return new Separator(separator, pattern);
    }

    //--

    private final String separator;
    private final Pattern pattern;
    private final LineFormat.Trim trim;
    private final boolean skipEmpty;
    private final String forNull;
    private final boolean skipNull;

    public Separator(String separator, Pattern pattern) {
        this(separator, pattern, LineFormat.Trim.SEPARATOR, false, null, false);
    }

    public Separator(String separator, Pattern pattern, LineFormat.Trim trim, boolean skipEmpty, String forNull, boolean skipNull) {
        if (separator.isEmpty()) {
            throw new IllegalArgumentException("Empty separator");
        }
        if (pattern.matcher("").find()) {
            throw new IllegalArgumentException(pattern.pattern() + " matches the empty string");
        }
        if (!pattern.matcher(separator).find()) {
            throw new IllegalArgumentException("Separtor " + separator + " does not match pattern " + pattern.pattern());
        }
        this.separator = separator;
        this.pattern = pattern;
        this.trim = trim;
        this.skipEmpty = skipEmpty;
        this.forNull = forNull;
        this.skipNull = skipNull;
    }

    public Separator(Separator orig) {
        this(orig.separator, orig.pattern, orig.trim, orig.skipEmpty, orig.forNull, orig.skipNull);
    }

    //--

    public String getSeparator() {
        return separator;
    }

    //-- configuration

    /** Trim elements before joining or after splitting */
    public Separator trim() {
        return trim(LineFormat.Trim.ALL);
    }

    /** Trim elements before joining or after splitting */
    public Separator trim(LineFormat.Trim trim) {
        return new Separator(separator, pattern, trim, skipEmpty, forNull, skipNull);
    }

    /** Do not join empty elements and to not return them from splitting. */
    public Separator skipEmpty() {
        return new Separator(separator, pattern, trim, true, forNull, skipNull);
    }

    public Separator forNull(String forNull) {
        return new Separator(separator, pattern, trim, skipEmpty, forNull, skipNull);
    }

    public Separator skipNull() {
        return new Separator(separator, pattern, trim, skipEmpty, forNull, true);
    }

    //-- joining

    public String join(Object[] array) {
        return join(java.util.Arrays.asList(array));
    }

    public String join(Iterable lst) {
        StringBuilder result;

        result = new StringBuilder();
        joinTo(result, lst);
        return result.toString();
    }

    public String join(Object first, Object second, Object ... rest) {
        int count;
        StringBuilder result;

        result = new StringBuilder();
        try {
            count = joinTo(result, 0, Collections.singletonList(first));
            count = joinTo(result, count, Collections.singletonList(second));
            joinTo(result, count, java.util.Arrays.asList(rest));
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
        return result.toString();
    }

    //--

    public void joinTo(StringBuilder dest, Iterable lst) {
        try {
            joinTo(dest, 0, lst);
        } catch (IOException e) {
            throw new IllegalStateException(e);
        }
    }

    /** @return number of objects appended */
    public int joinTo(Appendable dest, int count, Iterable lst) throws IOException {
        String str;

        for (Object obj : lst) {
            if (obj == null) {
                if (forNull != null) {
                    obj = forNull;
                } else if (skipNull) {
                    continue;
                } else {
                    throw new NullPointerException();
                }
            }
            str = obj.toString();
            if (trim == LineFormat.Trim.ALL) {
                str = str.trim();
            }
            if (skipEmpty && str.isEmpty()) {
                continue;
            }
            if (count > 0) {
                dest.append(separator);
            }
            count++;
            dest.append(str);
        }
        return count;
    }

    //-- split

    public List split(CharSequence str) {
        List lst;

        lst = new ArrayList<>();
        splitTo(lst, str);
        return lst;
    }

    public void splitTo(List dest, CharSequence str) {
        int length;
        Matcher matcher;
        int prev;

        length = str.length();
        if (length == 0) {
            return;
        }
        matcher = pattern.matcher(str);
        prev = 0;
        while (matcher.find()) {
            add(dest, str.subSequence(prev, trim == LineFormat.Trim.NOTHING ? matcher.end() : matcher.start()));
            prev = matcher.end();
        }
        if (prev <= length) {
            add(dest, str.subSequence(prev, length));
        }
    }

    private void add(List result, CharSequence cs) {
        String str;

        str = cs.toString();
        if (trim == LineFormat.Trim.ALL) {
            str = str.trim();
        }
        if (skipEmpty && str.isEmpty()) {
            return;
        }
        result.add(str);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy