001/*
002 * Copyright (C) 2012 eXo Platform SAS.
003 *
004 * This is free software; you can redistribute it and/or modify it
005 * under the terms of the GNU Lesser General Public License as
006 * published by the Free Software Foundation; either version 2.1 of
007 * the License, or (at your option) any later version.
008 *
009 * This software is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public
015 * License along with this software; if not, write to the Free
016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018 */
019
020package org.crsh.util;
021
022import java.util.ArrayList;
023import java.util.Arrays;
024import java.util.Iterator;
025import java.util.List;
026import java.util.regex.Matcher;
027import java.util.regex.Pattern;
028
029public class Strings {
030
031  /** . */
032  private static final Pattern p = Pattern.compile("\\S+");
033
034  public static List<String> chunks(CharSequence s) {
035    List<String> chunks = new ArrayList<String>();
036    Matcher m = p.matcher(s);
037    while (m.find()) {
038      chunks.add(m.group());
039    }
040    return chunks;
041  }
042
043  public static String join(Iterable<String> strings, String separator) {
044    Iterator<String> i = strings.iterator();
045    if (i.hasNext()) {
046      String first = i.next();
047      if (i.hasNext()) {
048        StringBuilder buf = new StringBuilder();
049        buf.append(first);
050        while (i.hasNext()) {
051          buf.append(separator);
052          buf.append(i.next());
053        }
054        return buf.toString();
055      } else {
056        return first;
057      }
058    } else {
059      return "";
060    }
061  }
062
063  public static String[] split(CharSequence s, char separator) {
064    return foo(s, separator, 0, 0, 0);
065  }
066
067  public static String[] split(CharSequence s, char separator, int rightPadding) {
068    if (rightPadding < 0) {
069      throw new IllegalArgumentException("Right padding cannot be negative");
070    }
071    return foo(s, separator, 0, 0, rightPadding);
072  }
073
074  private static String[] foo(CharSequence s, char separator, int count, int from, int rightPadding) {
075    int len = s.length();
076    if (from < len) {
077      int to = from;
078      while (to < len && s.charAt(to) != separator) {
079        to++;
080      }
081      String[] ret;
082      if (to == len - 1) {
083        ret = new String[count + 2 + rightPadding];
084        ret[count + 1] = "";
085      }
086      else {
087        ret = to == len ? new String[count + 1 + rightPadding] : foo(s, separator, count + 1, to + 1, rightPadding);
088      }
089      ret[count] = from == to ? "" : s.subSequence(from, to).toString();
090      return ret;
091    }
092    else if (from == len) {
093      return new String[count + rightPadding];
094    }
095    else {
096      throw new AssertionError();
097    }
098  }
099
100  /**
101   * @see #findLongestCommonPrefix(Iterable)
102   */
103  public static String findLongestCommonPrefix(CharSequence... seqs) {
104    return findLongestCommonPrefix(Arrays.asList(seqs));
105  }
106
107  /**
108   * Find the longest possible common prefix of the provided char sequence.
109   *
110   * @param seqs the sequences
111   * @return the longest possible prefix
112   */
113  public static String findLongestCommonPrefix(Iterable<? extends CharSequence> seqs) {
114    String common = "";
115    out:
116    while (true) {
117      String candidate = null;
118      for (CharSequence s : seqs) {
119        if (common.length() + 1 > s.length()) {
120          break out;
121        } else {
122          if (candidate == null) {
123            candidate = s.subSequence(0, common.length() + 1).toString();
124          } else if (s.subSequence(0, common.length() + 1).toString().equals(candidate)) {
125            // Ok it is a prefix
126          } else {
127            break out;
128          }
129        }
130      }
131      if (candidate == null) {
132        break;
133      } else {
134        common = candidate;
135      }
136    }
137    return common;
138  }
139}