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.Collections; 025import java.util.HashMap; 026import java.util.HashSet; 027import java.util.Iterator; 028import java.util.LinkedList; 029import java.util.List; 030import java.util.Map; 031import java.util.NoSuchElementException; 032import java.util.regex.Matcher; 033import java.util.regex.Pattern; 034 035public class Utils { 036 037 /** . */ 038 private static final Iterator EMPTY_ITERATOR = Collections.emptyList().iterator(); 039 040 public static <E> Iterator<E> iterator() { 041 @SuppressWarnings("unchecked") 042 Iterator<E> iterator = (Iterator<E>)EMPTY_ITERATOR; 043 return iterator; 044 } 045 046 public static <E> Iterator<E> iterator(final E element) { 047 return new BaseIterator<E>() { 048 boolean hasNext = true; 049 @Override 050 public boolean hasNext() { 051 return hasNext; 052 } 053 @Override 054 public E next() { 055 if (hasNext) { 056 hasNext = false; 057 return element; 058 } else { 059 throw new NoSuchElementException(); 060 } 061 } 062 }; 063 } 064 065 public static <E> ArrayList<E> newArrayList() { 066 return new ArrayList<E>(); 067 } 068 069 public static <E> LinkedList<E> newLinkedList() { 070 return new LinkedList<E>(); 071 } 072 073 public static <E> HashSet<E> newHashSet() { 074 return new HashSet<E>(); 075 } 076 077 public static <K, V> HashMap<K, V> newHashMap() { 078 return new HashMap<K, V>(); 079 } 080 081 public static <E> E first(Iterable<E> elements) { 082 Iterator<E> i = elements.iterator(); 083 return i.hasNext() ? i.next() : null; 084 } 085 086 public static <K, V, M extends Map<K, V>> M map(M map, K key, V value) { 087 map.put(key, value); 088 return map; 089 } 090 091 public static <K, V> HashMap<K, V> map(K key, V value) { 092 HashMap<K, V> map = new HashMap<K, V>(); 093 map.put(key, value); 094 return map; 095 } 096 097 public static <E> List<E> list(E... elements) { 098 return Arrays.asList(elements); 099 } 100 101 public static <E> List<E> list(Iterable<E> iterable) { 102 return list(iterable.iterator()); 103 } 104 105 public static <E> List<E> list(Iterator<E> iterator) { 106 ArrayList<E> list = new ArrayList<E>(); 107 while (iterator.hasNext()) { 108 list.add(iterator.next()); 109 } 110 return list; 111 } 112 113 public static int indexOf(CharSequence s, int off, char c) { 114 for (int len = s.length();off < len;off++) { 115 if (s.charAt(off) == c) { 116 return off; 117 } 118 } 119 return -1; 120 } 121 122 public static String trimLeft(String s) { 123 if (s == null) { 124 throw new NullPointerException("No null string accepted"); 125 } 126 int index = 0; 127 int len = s.length(); 128 while (index < len) { 129 if (s.charAt(index) == ' ') { 130 index++; 131 } else { 132 break; 133 } 134 } 135 if (index > 0) { 136 return s.substring(index); 137 } else { 138 return s; 139 } 140 } 141 142 public static <E> E notNull(E e1, E e2) { 143 if (e1 != null) { 144 return e1; 145 } else { 146 return e2; 147 } 148 } 149 150 private static final Pattern FOO = Pattern.compile("" + 151 "(\\*)" + // Wildcard * 152 "|" + 153 "(\\?)" + // Wildcard ? 154 "|" + 155 "(?:\\[([^)]+)\\])" + // Range 156 "|" + 157 "(\\\\.)" // Escape 158 ); 159 160 /** 161 * Create a pattern that transforms a glob expression into a regular expression, the following task are supported 162 * <ul> 163 * <li>* : Match any number of unknown characters</li> 164 * <li>? : Match one unknown character</li> 165 * <li>[characters] : Match a character as part of a group of characters</li> 166 * <li>\ : Escape character</li> 167 * </ul> 168 * 169 * @param globex the glob expression 170 * @return the regular expression 171 * @throws NullPointerException when the globex argument is null 172 */ 173 public static String globexToRegex(String globex) throws NullPointerException { 174 if (globex == null) { 175 throw new NullPointerException("No null globex accepted"); 176 } 177 StringBuilder regex = new StringBuilder(); 178 int prev = 0; 179 Matcher matcher = FOO.matcher(globex); 180 while (matcher.find()) { 181 int next = matcher.start(); 182 if (next > prev) { 183 regex.append(Pattern.quote(globex.substring(prev, next))); 184 } 185 if (matcher.group(1) != null) { 186 regex.append(".*"); 187 } else if (matcher.group(2) != null) { 188 regex.append("."); 189 } else if (matcher.group(3) != null) { 190 regex.append("["); 191 regex.append(Pattern.quote(matcher.group(3))); 192 regex.append("]"); 193 } else if (matcher.group(4) != null) { 194 regex.append(Pattern.quote(Character.toString(matcher.group(4).charAt(1)))); 195 } else { 196 throw new UnsupportedOperationException("Not handled yet"); 197 } 198 prev = matcher.end(); 199 } 200 if (prev < globex.length()) { 201 regex.append(Pattern.quote(globex.substring(prev))); 202 } 203 return regex.toString(); 204 } 205 206}