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.cli.impl.lang; 021 022 import java.io.IOException; 023 import java.lang.reflect.Array; 024 import java.util.Arrays; 025 import java.util.Iterator; 026 import java.util.NoSuchElementException; 027 import java.util.regex.Matcher; 028 import java.util.regex.Pattern; 029 030 public class Util { 031 032 /** . */ 033 static final Pattern INDENT_PATTERN = Pattern.compile("(?<=^|\\n)[ \\t\\x0B\\f\\r]*(?=\\S)"); 034 035 /** . */ 036 public static final String MAN_TAB = _tab(7); 037 038 /** . */ 039 public static final String MAN_TAB_EXTRA = _tab(7 + 4); 040 041 /** . */ 042 static final String[] tabIndex; 043 044 static { 045 String[] tmp = new String[20]; 046 for (int i = 0;i < tmp.length;i++) { 047 tmp[i] = _tab(i); 048 } 049 tabIndex = tmp; 050 } 051 052 static String tab(int size) { 053 if (size < 0) { 054 throw new IllegalArgumentException(); 055 } 056 if (size < tabIndex.length) { 057 return tabIndex[size]; 058 } else { 059 return _tab(size); 060 } 061 } 062 063 private static String _tab(int size) { 064 char[] tmp = new char[size]; 065 Arrays.fill(tmp, ' '); 066 return new String(tmp); 067 } 068 069 public static <A extends Appendable> A indent(int tab, CharSequence s, A appendable) throws IOException { 070 return indent(tab(tab), s, appendable); 071 } 072 073 public static <A extends Appendable> A indent(String tab, CharSequence s, A appendable) throws IOException { 074 Matcher matcher = INDENT_PATTERN.matcher(s); 075 int prev = 0; 076 while (matcher.find()) { 077 int start = matcher.start(); 078 appendable.append(s, prev, start); 079 appendable.append(tab); 080 prev = matcher.end(); 081 } 082 appendable.append(s, prev, s.length()); 083 return appendable; 084 } 085 086 public static <T> Iterable<T[]> tuples(final Class<T> type, final Iterable<? extends T>... iterables) { 087 return new Iterable<T[]>() { 088 public Iterator<T[]> iterator() { 089 return new Iterator<T[]>() { 090 private final Iterator<?>[] iterators = new Iterator<?>[iterables.length]; 091 private T[] next; 092 { 093 for (int i = 0;i < iterables.length;i++) { 094 iterators[i] = iterables[i].iterator(); 095 } 096 } 097 public boolean hasNext() { 098 if (next == null) { 099 T[] tuple = (T[])Array.newInstance(type, 2); 100 for (int i = 0;i < iterators.length;i++) { 101 Iterator iterator = iterators[i]; 102 if (iterator.hasNext()) { 103 tuple[i] = type.cast(iterator.next()); 104 } else { 105 return false; 106 } 107 } 108 next = tuple; 109 } 110 return true; 111 } 112 public T[] next() { 113 if (!hasNext()) { 114 throw new NoSuchElementException(); 115 } 116 T[] tmp = next; 117 next = null; 118 return tmp; 119 } 120 public void remove() { 121 throw new UnsupportedOperationException(); 122 } 123 }; 124 } 125 }; 126 } 127 128 public static <T> Iterable<? extends T> join(final Iterable<? extends T>... iterables) { 129 return new Iterable<T>() { 130 public Iterator<T> iterator() { 131 return new Iterator<T>() { 132 int index; 133 Iterator<? extends T> current; 134 T next; 135 public boolean hasNext() { 136 if (next == null) { 137 while ((current == null || !current.hasNext()) && index < iterables.length) { 138 current = iterables[index++].iterator(); 139 } 140 if (current != null && current.hasNext()) { 141 next = current.next(); 142 } 143 } 144 return next != null; 145 } 146 public T next() { 147 if (!hasNext()) { 148 throw new NoSuchElementException(); 149 } 150 T tmp = next; 151 next = null; 152 return tmp; 153 } 154 public void remove() { 155 throw new UnsupportedOperationException(); 156 } 157 }; 158 } 159 }; 160 } 161 }