~slub.team/goobi-indexserver/3.x

« back to all changes in this revision

Viewing changes to solr/solrj/src/java/org/apache/solr/common/util/StrUtils.java

  • Committer: Sebastian Meyer
  • Date: 2012-08-03 09:12:40 UTC
  • Revision ID: sebastian.meyer@slub-dresden.de-20120803091240-x6861b0vabq1xror
Remove Lucene and Solr source code and add patches instead
Fix Bug #985487: Auto-suggestion for the search interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 
 * contributor license agreements.  See the NOTICE file distributed with
4
 
 * this work for additional information regarding copyright ownership.
5
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 
 * (the "License"); you may not use this file except in compliance with
7
 
 * the License.  You may obtain a copy of the License at
8
 
 *
9
 
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 
 *
11
 
 * Unless required by applicable law or agreed to in writing, software
12
 
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 
 * See the License for the specific language governing permissions and
15
 
 * limitations under the License.
16
 
 */
17
 
 
18
 
package org.apache.solr.common.util;
19
 
 
20
 
import java.util.List;
21
 
import java.util.ArrayList;
22
 
import java.util.Collections;
23
 
import java.util.Locale;
24
 
import java.io.IOException;
25
 
 
26
 
import org.apache.solr.common.SolrException;
27
 
 
28
 
/**
29
 
 * @version $Id: StrUtils.java 1065586 2011-01-31 13:01:48Z rmuir $
30
 
 */
31
 
public class StrUtils {
32
 
  public static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6',
33
 
      '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
34
 
 
35
 
  /**
36
 
   * Split a string based on a separator, but don't split if it's inside
37
 
   * a string.  Assume '\' escapes the next char both inside and
38
 
   * outside strings.
39
 
   */
40
 
  public static List<String> splitSmart(String s, char separator) {
41
 
    ArrayList<String> lst = new ArrayList<String>(4);
42
 
    int pos=0, start=0, end=s.length();
43
 
    char inString=0;
44
 
    char ch=0;
45
 
    while (pos < end) {
46
 
      char prevChar=ch;
47
 
      ch = s.charAt(pos++);
48
 
      if (ch=='\\') {    // skip escaped chars
49
 
        pos++;
50
 
      } else if (inString != 0 && ch==inString) {
51
 
        inString=0;
52
 
      } else if (ch=='\'' || ch=='"') {
53
 
        // If char is directly preceeded by a number or letter
54
 
        // then don't treat it as the start of a string.
55
 
        // Examples: 50" TV, or can't
56
 
        if (!Character.isLetterOrDigit(prevChar)) {
57
 
          inString=ch;
58
 
        }
59
 
      } else if (ch==separator && inString==0) {
60
 
        lst.add(s.substring(start,pos-1));
61
 
        start=pos;
62
 
      }
63
 
    }
64
 
    if (start < end) {
65
 
      lst.add(s.substring(start,end));
66
 
    }
67
 
 
68
 
    /***
69
 
    if (SolrCore.log.isLoggable(Level.FINEST)) {
70
 
      SolrCore.log.trace("splitCommand=" + lst);
71
 
    }
72
 
    ***/
73
 
 
74
 
    return lst;
75
 
  }
76
 
 
77
 
  /** Splits a backslash escaped string on the separator.
78
 
   * <p>
79
 
   * Current backslash escaping supported:
80
 
   * <br> \n \t \r \b \f are escaped the same as a Java String
81
 
   * <br> Other characters following a backslash are produced verbatim (\c => c)
82
 
   *
83
 
   * @param s  the string to split
84
 
   * @param separator the separator to split on
85
 
   * @param decode decode backslash escaping
86
 
   */
87
 
  public static List<String> splitSmart(String s, String separator, boolean decode) {
88
 
    ArrayList<String> lst = new ArrayList<String>(2);
89
 
    StringBuilder sb = new StringBuilder();
90
 
    int pos=0, end=s.length();
91
 
    while (pos < end) {
92
 
      if (s.startsWith(separator,pos)) {
93
 
        if (sb.length() > 0) {
94
 
          lst.add(sb.toString());
95
 
          sb=new StringBuilder();
96
 
        }
97
 
        pos+=separator.length();
98
 
        continue;
99
 
      }
100
 
 
101
 
      char ch = s.charAt(pos++);
102
 
      if (ch=='\\') {
103
 
        if (!decode) sb.append(ch);
104
 
        if (pos>=end) break;  // ERROR, or let it go?
105
 
        ch = s.charAt(pos++);
106
 
        if (decode) {
107
 
          switch(ch) {
108
 
            case 'n' : ch='\n'; break;
109
 
            case 't' : ch='\t'; break;
110
 
            case 'r' : ch='\r'; break;
111
 
            case 'b' : ch='\b'; break;
112
 
            case 'f' : ch='\f'; break;
113
 
          }
114
 
        }
115
 
      }
116
 
 
117
 
      sb.append(ch);
118
 
    }
119
 
 
120
 
    if (sb.length() > 0) {
121
 
      lst.add(sb.toString());
122
 
    }
123
 
 
124
 
    return lst;
125
 
  }
126
 
 
127
 
  /**
128
 
   * Splits file names separated by comma character.
129
 
   * File names can contain comma characters escaped by backslash '\'
130
 
   *
131
 
   * @param fileNames the string containing file names
132
 
   * @return a list of file names with the escaping backslashed removed
133
 
   */
134
 
  public static List<String> splitFileNames(String fileNames) {
135
 
    if (fileNames == null)
136
 
      return Collections.<String>emptyList();
137
 
 
138
 
    List<String> result = new ArrayList<String>();
139
 
    for (String file : fileNames.split("(?<!\\\\),")) {
140
 
      result.add(file.replaceAll("\\\\(?=,)", ""));
141
 
    }
142
 
 
143
 
    return result;
144
 
  }
145
 
 
146
 
  /** Creates a backslash escaped string, joining all the items. */
147
 
  public static String join(List<String> items, char separator) {
148
 
    StringBuilder sb = new StringBuilder(items.size() << 3);
149
 
    boolean first=true;
150
 
    for (String item : items) {
151
 
      if (first) {
152
 
        first = false;
153
 
      } else {
154
 
        sb.append(separator);
155
 
      }
156
 
      for (int i=0; i<item.length(); i++) {
157
 
        char ch = item.charAt(i);
158
 
        if (ch=='\\' || ch == separator) {
159
 
          sb.append('\\');
160
 
        }
161
 
        sb.append(ch);
162
 
      }
163
 
    }
164
 
    return sb.toString();
165
 
  }
166
 
 
167
 
 
168
 
 
169
 
  public static List<String> splitWS(String s, boolean decode) {
170
 
    ArrayList<String> lst = new ArrayList<String>(2);
171
 
    StringBuilder sb = new StringBuilder();
172
 
    int pos=0, end=s.length();
173
 
    while (pos < end) {
174
 
      char ch = s.charAt(pos++);
175
 
      if (Character.isWhitespace(ch)) {
176
 
        if (sb.length() > 0) {
177
 
          lst.add(sb.toString());
178
 
          sb=new StringBuilder();
179
 
        }
180
 
        continue;
181
 
      }
182
 
 
183
 
      if (ch=='\\') {
184
 
        if (!decode) sb.append(ch);
185
 
        if (pos>=end) break;  // ERROR, or let it go?
186
 
        ch = s.charAt(pos++);
187
 
        if (decode) {
188
 
          switch(ch) {
189
 
            case 'n' : ch='\n'; break;
190
 
            case 't' : ch='\t'; break;
191
 
            case 'r' : ch='\r'; break;
192
 
            case 'b' : ch='\b'; break;
193
 
            case 'f' : ch='\f'; break;
194
 
          }
195
 
        }
196
 
      }
197
 
 
198
 
      sb.append(ch);
199
 
    }
200
 
 
201
 
    if (sb.length() > 0) {
202
 
      lst.add(sb.toString());
203
 
    }
204
 
 
205
 
    return lst;
206
 
  }
207
 
 
208
 
  public static List<String> toLower(List<String> strings) {
209
 
    ArrayList<String> ret = new ArrayList<String>(strings.size());
210
 
    for (String str : strings) {
211
 
      ret.add(str.toLowerCase(Locale.ENGLISH));
212
 
    }
213
 
    return ret;
214
 
  }
215
 
 
216
 
 
217
 
 
218
 
  /** Return if a string starts with '1', 't', or 'T'
219
 
   *  and return false otherwise.
220
 
   */
221
 
  public static boolean parseBoolean(String s) {
222
 
    char ch = s.length()>0 ? s.charAt(0) : 0;
223
 
    return (ch=='1' || ch=='t' || ch=='T');
224
 
  }
225
 
  
226
 
  /** how to transform a String into a boolean... more flexible than
227
 
   * Boolean.parseBoolean() to enable easier integration with html forms.
228
 
   */
229
 
  public static boolean parseBool(String s) {
230
 
    if( s != null ) {
231
 
      if( s.startsWith("true") || s.startsWith("on") || s.startsWith("yes") ) {
232
 
        return true;
233
 
      }
234
 
      if( s.startsWith("false") || s.startsWith("off") || s.equals("no") ) {
235
 
        return false;
236
 
      }
237
 
    }
238
 
    throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "invalid boolean value: "+s );
239
 
  }
240
 
 
241
 
  /**
242
 
   * {@link NullPointerException} and {@link SolrException} free version of {@link #parseBool(String)}
243
 
   * @param s
244
 
   * @param def
245
 
   * @return parsed boolean value (or def, if s is null or invalid)
246
 
   */
247
 
  public static boolean parseBool(String s, boolean def) {
248
 
    if( s != null ) {
249
 
      if( s.startsWith("true") || s.startsWith("on") || s.startsWith("yes") ) {
250
 
        return true;
251
 
      }
252
 
      if( s.startsWith("false") || s.startsWith("off") || s.equals("no") ) {
253
 
        return false;
254
 
      }
255
 
    }
256
 
    return def;
257
 
  }
258
 
  
259
 
  /**
260
 
   * URLEncodes a value, replacing only enough chars so that
261
 
   * the URL may be unambiguously pasted back into a browser.
262
 
   * <p>
263
 
   * Characters with a numeric value less than 32 are encoded.
264
 
   * &amp;,=,%,+,space are encoded.
265
 
   * <p>
266
 
   */
267
 
  public static void partialURLEncodeVal(Appendable dest, String val) throws IOException {
268
 
    for (int i=0; i<val.length(); i++) {
269
 
      char ch = val.charAt(i);
270
 
      if (ch < 32) {
271
 
        dest.append('%');
272
 
        if (ch < 0x10) dest.append('0');
273
 
        dest.append(Integer.toHexString(ch));
274
 
      } else {
275
 
        switch (ch) {
276
 
          case ' ': dest.append('+'); break;
277
 
          case '&': dest.append("%26"); break;
278
 
          case '%': dest.append("%25"); break;
279
 
          case '=': dest.append("%3D"); break;
280
 
          case '+': dest.append("%2B"); break;
281
 
          default : dest.append(ch); break;
282
 
        }
283
 
      }
284
 
    }
285
 
  }
286
 
 
287
 
}