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    }