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.util;
021
022 import java.util.ArrayList;
023 import java.util.Arrays;
024 import java.util.Collections;
025 import java.util.HashMap;
026 import java.util.HashSet;
027 import java.util.Iterator;
028 import java.util.LinkedList;
029 import java.util.List;
030 import java.util.Map;
031 import java.util.NoSuchElementException;
032 import java.util.regex.Matcher;
033 import java.util.regex.Pattern;
034
035 public 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 <K, V, M extends Map<K, V>> M map(M map, K key, V value) {
082 map.put(key, value);
083 return map;
084 }
085
086 public static <K, V> HashMap<K, V> map(K key, V value) {
087 HashMap<K, V> map = new HashMap<K, V>();
088 map.put(key, value);
089 return map;
090 }
091
092 public static <E> List<E> list(E... elements) {
093 return Arrays.asList(elements);
094 }
095
096 public static <E> List<E> list(Iterable<E> iterable) {
097 return list(iterable.iterator());
098 }
099
100 public static <E> List<E> list(Iterator<E> iterator) {
101 ArrayList<E> list = new ArrayList<E>();
102 while (iterator.hasNext()) {
103 list.add(iterator.next());
104 }
105 return list;
106 }
107
108 public static int indexOf(CharSequence s, int off, char c) {
109 for (int len = s.length();off < len;off++) {
110 if (s.charAt(off) == c) {
111 return off;
112 }
113 }
114 return -1;
115 }
116
117 public static String trimLeft(String s) {
118 if (s == null) {
119 throw new NullPointerException("No null string accepted");
120 }
121 int index = 0;
122 int len = s.length();
123 while (index < len) {
124 if (s.charAt(index) == ' ') {
125 index++;
126 } else {
127 break;
128 }
129 }
130 if (index > 0) {
131 return s.substring(index);
132 } else {
133 return s;
134 }
135 }
136
137 public static <E> E notNull(E e1, E e2) {
138 if (e1 != null) {
139 return e1;
140 } else {
141 return e2;
142 }
143 }
144
145 private static final Pattern FOO = Pattern.compile("" +
146 "(\\*)" + // Wildcard *
147 "|" +
148 "(\\?)" + // Wildcard ?
149 "|" +
150 "(?:\\[([^)]+)\\])" + // Range
151 "|" +
152 "(\\\\.)" // Escape
153 );
154
155 /**
156 * Create a pattern that transforms a glob expression into a regular expression, the following task are supported
157 * <ul>
158 * <li>* : Match any number of unknown characters</li>
159 * <li>? : Match one unknown character</li>
160 * <li>[characters] : Match a character as part of a group of characters</li>
161 * <li>\ : Escape character</li>
162 * </ul>
163 *
164 * @param globex the glob expression
165 * @return the regular expression
166 * @throws NullPointerException when the globex argument is null
167 */
168 public static String globexToRegex(String globex) throws NullPointerException {
169 if (globex == null) {
170 throw new NullPointerException("No null globex accepted");
171 }
172 StringBuilder regex = new StringBuilder();
173 int prev = 0;
174 Matcher matcher = FOO.matcher(globex);
175 while (matcher.find()) {
176 int next = matcher.start();
177 if (next > prev) {
178 regex.append(Pattern.quote(globex.substring(prev, next)));
179 }
180 if (matcher.group(1) != null) {
181 regex.append(".*");
182 } else if (matcher.group(2) != null) {
183 regex.append(".");
184 } else if (matcher.group(3) != null) {
185 regex.append("[");
186 regex.append(Pattern.quote(matcher.group(3)));
187 regex.append("]");
188 } else if (matcher.group(4) != null) {
189 regex.append(Pattern.quote(Character.toString(matcher.group(4).charAt(1))));
190 } else {
191 throw new UnsupportedOperationException("Not handled yet");
192 }
193 prev = matcher.end();
194 }
195 if (prev < globex.length()) {
196 regex.append(Pattern.quote(globex.substring(prev)));
197 }
198 return regex.toString();
199 }
200
201 }