1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.api.ldap.model.filter;
21
22
23 import java.text.Format;
24 import java.text.MessageFormat;
25
26
27
28
29
30
31
32 public class FilterEncoder
33 {
34 private static final String[] EMPTY = new String[0];
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public static String format( String filterTemplate, String... values ) throws IllegalArgumentException
49 {
50 if ( values == null )
51 {
52 values = EMPTY;
53 }
54
55 MessageFormat mf = new MessageFormat( filterTemplate );
56
57
58 Format[] formats = mf.getFormatsByArgumentIndex();
59 if ( formats.length != values.length )
60 {
61
62 String msg = "Filter template {0} has {1} placeholders but {2} arguments provided.";
63 throw new IllegalArgumentException( MessageFormat.format( msg, filterTemplate, formats.length,
64 values.length ) );
65 }
66
67
68 for ( int i = 0; i < values.length; i++ )
69 {
70 values[i] = encodeFilterValue( values[i] );
71 }
72
73
74 String format = mf.format( values );
75 return format;
76 }
77
78
79
80
81
82
83
84
85
86 public static String encodeFilterValue( String value )
87 {
88 StringBuilder sb = new StringBuilder( value.length() );
89 boolean escaped = false;
90 boolean hexPair = false;
91 char hex = '\0';
92
93 for ( int i = 0; i < value.length(); i++ )
94 {
95 char ch = value.charAt( i );
96
97 switch ( ch )
98 {
99 case '*':
100 if ( escaped )
101 {
102 sb.append( "\\5C" );
103
104 if ( hexPair )
105 {
106 sb.append( hex );
107 hexPair = false;
108 }
109
110 escaped = false;
111 }
112
113 sb.append( "\\2A" );
114 break;
115
116 case '(':
117 if ( escaped )
118 {
119 sb.append( "\\5C" );
120
121 if ( hexPair )
122 {
123 sb.append( hex );
124 hexPair = false;
125 }
126
127 escaped = false;
128 }
129
130 sb.append( "\\28" );
131 break;
132
133 case ')':
134 if ( escaped )
135 {
136 sb.append( "\\5C" );
137
138 if ( hexPair )
139 {
140 sb.append( hex );
141 hexPair = false;
142 }
143
144 escaped = false;
145 }
146
147 sb.append( "\\29" );
148 break;
149
150 case '\0':
151 if ( escaped )
152 {
153 sb.append( "\\5C" );
154
155 if ( hexPair )
156 {
157 sb.append( hex );
158 hexPair = false;
159 }
160
161 escaped = false;
162 }
163
164 sb.append( "\\00" );
165 break;
166
167 case '\\':
168 if ( escaped )
169 {
170 sb.append( "\\5C" );
171 escaped = false;
172 }
173 else
174 {
175 escaped = true;
176 hexPair = false;
177 }
178
179 break;
180
181 case '0':
182 case '1':
183 case '2':
184 case '3':
185 case '4':
186 case '5':
187 case '6':
188 case '7':
189 case '8':
190 case '9':
191 case 'a':
192 case 'b':
193 case 'c':
194 case 'd':
195 case 'e':
196 case 'f':
197 case 'A':
198 case 'B':
199 case 'C':
200 case 'D':
201 case 'E':
202 case 'F':
203 if ( escaped )
204 {
205 if ( hexPair )
206 {
207 sb.append( '\\' ).append( hex ).append( ch );
208 escaped = false;
209 hexPair = false;
210 }
211 else
212 {
213 hexPair = true;
214 hex = ch;
215 }
216 }
217 else
218 {
219 sb.append( ch );
220 }
221
222 break;
223
224 default:
225 if ( escaped )
226 {
227 sb.append( "\\5C" );
228
229 if ( hexPair )
230 {
231 sb.append( hex );
232 hexPair = false;
233 }
234
235 escaped = false;
236 }
237
238 sb.append( ch );
239 }
240 }
241
242 if ( escaped )
243 {
244 sb.append( "\\5C" );
245 }
246
247 return ( sb == null ? value : sb.toString() );
248 }
249
250
251 private static void handleEscaped( boolean escaped, boolean hexPair, char hex, StringBuilder sb )
252 {
253 if ( escaped )
254 {
255 sb.append( "\\5C" );
256
257 if ( hexPair )
258 {
259 sb.append( hex );
260 hexPair = false;
261 }
262
263 escaped = false;
264 }
265 }
266 }