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 Object[] EMPTY_ARGS = new Object[0]; 034 035 /** . */ 036 static final Pattern INDENT_PATTERN = Pattern.compile("(?<=^|\\n)[ \\t\\x0B\\f\\r]*(?=\\S)"); 037 038 /** . */ 039 public static final String MAN_TAB = _tab(7); 040 041 /** . */ 042 public static final String MAN_TAB_EXTRA = _tab(7 + 4); 043 044 /** . */ 045 static final String[] tabIndex; 046 047 static { 048 String[] tmp = new String[20]; 049 for (int i = 0;i < tmp.length;i++) { 050 tmp[i] = _tab(i); 051 } 052 tabIndex = tmp; 053 } 054 055 static String tab(int size) { 056 if (size < 0) { 057 throw new IllegalArgumentException(); 058 } 059 if (size < tabIndex.length) { 060 return tabIndex[size]; 061 } else { 062 return _tab(size); 063 } 064 } 065 066 private static String _tab(int size) { 067 char[] tmp = new char[size]; 068 Arrays.fill(tmp, ' '); 069 return new String(tmp); 070 } 071 072 public static <A extends Appendable> A indent(int tab, CharSequence s, A appendable) throws IOException { 073 return indent(tab(tab), s, appendable); 074 } 075 076 public static <A extends Appendable> A indent(String tab, CharSequence s, A appendable) throws IOException { 077 Matcher matcher = INDENT_PATTERN.matcher(s); 078 int prev = 0; 079 while (matcher.find()) { 080 int start = matcher.start(); 081 appendable.append(s, prev, start); 082 appendable.append(tab); 083 prev = matcher.end(); 084 } 085 appendable.append(s, prev, s.length()); 086 return appendable; 087 } 088 089 public static <T> Iterable<T[]> tuples(final Class<T> type, final Iterable<? extends T>... iterables) { 090 return new Iterable<T[]>() { 091 public Iterator<T[]> iterator() { 092 return new Iterator<T[]>() { 093 private final Iterator<?>[] iterators = new Iterator<?>[iterables.length]; 094 private T[] next; 095 { 096 for (int i = 0;i < iterables.length;i++) { 097 iterators[i] = iterables[i].iterator(); 098 } 099 } 100 public boolean hasNext() { 101 if (next == null) { 102 T[] tuple = (T[])Array.newInstance(type, 2); 103 for (int i = 0;i < iterators.length;i++) { 104 Iterator iterator = iterators[i]; 105 if (iterator.hasNext()) { 106 tuple[i] = type.cast(iterator.next()); 107 } else { 108 return false; 109 } 110 } 111 next = tuple; 112 } 113 return true; 114 } 115 public T[] next() { 116 if (!hasNext()) { 117 throw new NoSuchElementException(); 118 } 119 T[] tmp = next; 120 next = null; 121 return tmp; 122 } 123 public void remove() { 124 throw new UnsupportedOperationException(); 125 } 126 }; 127 } 128 }; 129 } 130 131 public static <T> Iterable<? extends T> join(final Iterable<? extends T>... iterables) { 132 return new Iterable<T>() { 133 public Iterator<T> iterator() { 134 return new Iterator<T>() { 135 int index; 136 Iterator<? extends T> current; 137 T next; 138 public boolean hasNext() { 139 if (next == null) { 140 while ((current == null || !current.hasNext()) && index < iterables.length) { 141 current = iterables[index++].iterator(); 142 } 143 if (current != null && current.hasNext()) { 144 next = current.next(); 145 } 146 } 147 return next != null; 148 } 149 public T next() { 150 if (!hasNext()) { 151 throw new NoSuchElementException(); 152 } 153 T tmp = next; 154 next = null; 155 return tmp; 156 } 157 public void remove() { 158 throw new UnsupportedOperationException(); 159 } 160 }; 161 } 162 }; 163 } 164 165 /** 166 * Wrap an object with an {@link org.crsh.cli.impl.lang.Instance}. 167 * 168 * @param object the object to wrap 169 * @param <T> the instance generic type 170 * @return an {@link org.crsh.cli.impl.lang.Instance} wrapping the specified object 171 */ 172 public static <T> Instance<T> wrap(final T object) { 173 return new Instance<T>() { 174 @Override 175 public <T1> T1 resolve(Class<T1> type) { 176 return null; 177 } 178 @Override 179 public T get() { 180 return object; 181 } 182 }; 183 } 184 }