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 org.apache.directory.api.i18n.I18n;
24 import org.apache.directory.api.ldap.model.schema.AttributeType;
25 import org.apache.directory.api.util.Strings;
26
27
28
29
30
31
32
33 public abstract class LeafNode extends AbstractExprNode
34 {
35
36 protected AttributeType attributeType;
37
38
39 protected String attribute;
40
41
42
43
44
45
46
47
48 protected LeafNode( AttributeType attributeType, AssertionType assertionType )
49 {
50 super( assertionType );
51 this.attributeType = attributeType;
52
53 if ( attributeType != null )
54 {
55 this.attribute = attributeType.getName();
56 }
57 else
58 {
59 throw new NullPointerException( I18n.err( I18n.ERR_13302_CANNOT_CREATE_NODE_NULL_ATTR ) );
60 }
61 }
62
63
64
65
66
67
68
69
70 protected LeafNode( String attribute, AssertionType assertionType )
71 {
72 super( assertionType );
73 this.attributeType = null;
74 this.attribute = attribute;
75 }
76
77
78
79
80
81
82
83 @Override
84 public final boolean isLeaf()
85 {
86 return true;
87 }
88
89
90
91
92
93
94
95 public final AttributeType getAttributeType()
96 {
97 return attributeType;
98 }
99
100
101
102
103
104
105
106 public final String getAttribute()
107 {
108 return attribute;
109 }
110
111
112
113
114
115
116
117 public void setAttributeType( AttributeType attributeType )
118 {
119 this.attributeType = attributeType;
120
121 if ( attributeType != null )
122 {
123 attribute = attributeType.getName();
124 }
125 }
126
127
128
129
130
131
132
133 public void setAttribute( String attribute )
134 {
135 this.attribute = attribute;
136 }
137
138
139
140
141
142
143
144
145
146 @Override
147 public final Object accept( FilterVisitor visitor )
148 {
149 if ( visitor.canVisit( this ) )
150 {
151 return visitor.visit( this );
152 }
153 else
154 {
155 return null;
156 }
157 }
158
159
160
161
162
163
164
165 @Override
166 public boolean isSchemaAware()
167 {
168 return attributeType != null;
169 }
170
171
172
173
174
175
176
177
178 private static String escapeBytes( byte[] bytes )
179 {
180
181 char[] chars = new char[bytes.length * 3];
182 int pos = 0;
183
184 for ( byte bb : bytes )
185 {
186 chars[pos++] = '\\';
187 chars[pos++] = Strings.dumpHex( ( byte ) ( bb >> 4 ) );
188 chars[pos++] = Strings.dumpHex( ( byte ) ( bb & 0x0F ) );
189 }
190
191 return new String( chars, 0, pos );
192 }
193
194
195
196
197
198
199
200
201 private static String escapeString( byte[] bytes )
202 {
203 StringBuilder sb = new StringBuilder( bytes.length );
204
205 for ( byte b : bytes )
206 {
207 switch ( b )
208 {
209 case 0x20 : case 0x21 : case 0x22 : case 0x23 : case 0x24 : case 0x25 : case 0x26 : case 0x27 :
210 sb.append( ( char ) b );
211 break;
212
213 case 0x28 :
214
215 sb.append( "\\28" );
216 break;
217
218 case 0x29 :
219 sb.append( "\\29" );
220
221 break;
222
223 case 0x2A :
224
225 sb.append( "\\2A" );
226 break;
227
228 case 0x2B : case 0x2C : case 0x2D : case 0x2E : case 0x2F :
229 case 0x30 : case 0x31 : case 0x32 : case 0x33 : case 0x34 : case 0x35 : case 0x36 : case 0x37 :
230 case 0x38 : case 0x39 : case 0x3A : case 0x3B : case 0x3C : case 0x3D : case 0x3E : case 0x3F :
231 case 0x40 : case 0x41 : case 0x42 : case 0x43 : case 0x44 : case 0x45 : case 0x46 : case 0x47 :
232 case 0x48 : case 0x49 : case 0x4A : case 0x4B : case 0x4C : case 0x4D : case 0x4E : case 0x4F :
233 case 0x50 : case 0x51 : case 0x52 : case 0x53 : case 0x54 : case 0x55 : case 0x56 : case 0x57 :
234 case 0x58 : case 0x59 : case 0x5A : case 0x5B :
235 sb.append( ( char ) b );
236 break;
237
238 case 0x5C :
239
240 sb.append( "\\5C" );
241 break;
242
243 case 0x5D : case 0x5E : case 0x5F :
244 case 0x60 : case 0x61 : case 0x62 : case 0x63 : case 0x64 : case 0x65 : case 0x66 : case 0x67 :
245 case 0x68 : case 0x69 : case 0x6A : case 0x6B : case 0x6C : case 0x6D : case 0x6E : case 0x6F :
246 case 0x70 : case 0x71 : case 0x72 : case 0x73 : case 0x74 : case 0x75 : case 0x76 : case 0x77 :
247 case 0x78 : case 0x79 : case 0x7A : case 0x7B : case 0x7C : case 0x7D : case 0x7E : case 0x7F :
248 sb.append( ( char ) b );
249 break;
250
251 default :
252
253 return null;
254 }
255 }
256
257 return sb.toString();
258 }
259
260
261
262
263
264
265
266
267
268
269
270
271
272 protected static String escapeFilterValue( AttributeType attributeType, byte[] value )
273 {
274 if ( value == null )
275 {
276 return null;
277 }
278
279 if ( attributeType != null )
280 {
281 if ( attributeType.isHR() )
282 {
283 String result = escapeString( value );
284
285 if ( result == null )
286 {
287 return escapeBytes( value );
288 }
289 else
290 {
291 return result;
292 }
293 }
294 else
295 {
296 return escapeBytes( value );
297 }
298 }
299 else
300 {
301 String result = escapeString( value );
302
303 if ( result == null )
304 {
305 return escapeBytes( value );
306 }
307 else
308 {
309 return result;
310 }
311 }
312 }
313
314
315
316
317
318
319
320
321
322
323
324
325 protected static String escapeFilterValue( String value )
326 {
327 if ( value == null )
328 {
329 return null;
330 }
331
332 StringBuilder sb = new StringBuilder( value.length() );
333
334 for ( int i = 0; i < value.length(); i++ )
335 {
336 char c = value.charAt( i );
337
338 switch ( c )
339 {
340 case 0x00:
341 sb.append( "\\00" );
342 break;
343
344 case '(' :
345 sb.append( "\\28" );
346 break;
347
348 case ')' :
349 sb.append( "\\29" );
350 break;
351
352 case '*' :
353 sb.append( "\\2A" );
354 break;
355
356 case '\\' :
357 sb.append( "\\5C" );
358 break;
359
360 default :
361 sb.append( c );
362 break;
363
364 }
365 }
366
367 return sb.toString();
368 }
369
370
371
372
373
374
375
376 @Override
377 public int hashCode()
378 {
379 int h = 37;
380
381 h = h * 17 + super.hashCode();
382
383 if ( attributeType != null )
384 {
385 h = h * 17 + attributeType.hashCode();
386 }
387 else
388 {
389 h = h * 17 + attribute.hashCode();
390 }
391
392 return h;
393 }
394
395
396
397
398
399 @Override
400 public boolean equals( Object other )
401 {
402 if ( this == other )
403 {
404 return true;
405 }
406
407 if ( !( other instanceof LeafNode ) )
408 {
409 return false;
410 }
411
412 LeafNode otherNode = ( LeafNode ) other;
413
414 if ( other.getClass() != this.getClass() )
415 {
416 return false;
417 }
418
419 if ( attributeType != null )
420 {
421 return attributeType.equals( otherNode.getAttributeType() );
422 }
423 else
424 {
425 return attribute.equalsIgnoreCase( otherNode.getAttribute() );
426 }
427 }
428 }