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    
020    package org.crsh.util;
021    
022    import java.util.ArrayList;
023    import java.util.Arrays;
024    import java.util.Iterator;
025    import java.util.List;
026    import java.util.regex.Matcher;
027    import java.util.regex.Pattern;
028    
029    public 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    }