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