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