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