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.schema;
21
22
23 import java.util.HashSet;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.UUID;
28
29 import org.apache.directory.api.i18n.I18n;
30 import org.apache.directory.api.ldap.model.constants.MetaSchemaConstants;
31 import org.apache.directory.api.ldap.model.entry.Attribute;
32 import org.apache.directory.api.ldap.model.entry.Entry;
33 import org.apache.directory.api.ldap.model.entry.Modification;
34 import org.apache.directory.api.ldap.model.entry.Value;
35 import org.apache.directory.api.ldap.model.exception.LdapException;
36 import org.apache.directory.api.util.Strings;
37
38
39
40
41
42
43
44 public final class SchemaUtils
45 {
46
47
48
49 private SchemaUtils()
50 {
51 }
52
53
54
55
56
57
58
59
60
61
62
63 public static Entry getTargetEntry( List<? extends Modification> mods, Entry entry )
64 throws LdapException
65 {
66 Entry targetEntry = entry.clone();
67
68 for ( Modification mod : mods )
69 {
70 String id = mod.getAttribute().getId();
71
72 switch ( mod.getOperation() )
73 {
74 case REPLACE_ATTRIBUTE:
75 targetEntry.put( mod.getAttribute() );
76 break;
77
78 case ADD_ATTRIBUTE:
79 Attribute combined = mod.getAttribute().clone();
80 Attribute toBeAdded = mod.getAttribute();
81 Attribute existing = entry.get( id );
82
83 if ( existing != null )
84 {
85 for ( Value<?> value : existing )
86 {
87 combined.add( value );
88 }
89 }
90
91 for ( Value<?> value : toBeAdded )
92 {
93 combined.add( value );
94 }
95
96 targetEntry.put( combined );
97 break;
98
99 case REMOVE_ATTRIBUTE:
100 Attribute toBeRemoved = mod.getAttribute();
101
102 if ( toBeRemoved.size() == 0 )
103 {
104 targetEntry.removeAttributes( id );
105 }
106 else
107 {
108 existing = targetEntry.get( id );
109
110 if ( existing != null )
111 {
112 for ( Value<?> value : toBeRemoved )
113 {
114 existing.remove( value );
115 }
116 }
117 }
118
119 break;
120
121 default:
122 throw new IllegalStateException( I18n.err( I18n.ERR_04328, mod.getOperation() ) );
123 }
124 }
125
126 return targetEntry;
127 }
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143 public static StringBuffer render( StringBuffer buf, List<String> qdescrs )
144 {
145 if ( ( qdescrs == null ) || ( qdescrs.size() == 0 ) )
146 {
147 return buf;
148 }
149 else if ( qdescrs.size() == 1 )
150 {
151 buf.append( "'" ).append( qdescrs.get( 0 ) ).append( "'" );
152 }
153 else
154 {
155 buf.append( "( " );
156
157 for ( String qdescr : qdescrs )
158 {
159 buf.append( "'" ).append( qdescr ).append( "' " );
160 }
161
162 buf.append( ")" );
163 }
164
165 return buf;
166 }
167
168
169
170
171
172
173
174
175
176
177
178
179 static StringBuffer renderQDescrs( StringBuffer buf, List<String> qdescrs )
180 {
181 if ( ( qdescrs == null ) || ( qdescrs.size() == 0 ) )
182 {
183 return buf;
184 }
185
186 if ( qdescrs.size() == 1 )
187 {
188 buf.append( '\'' ).append( qdescrs.get( 0 ) ).append( '\'' );
189 }
190 else
191 {
192 buf.append( "( " );
193
194 for ( String qdescr : qdescrs )
195 {
196 buf.append( '\'' ).append( qdescr ).append( "' " );
197 }
198
199 buf.append( ")" );
200 }
201
202 return buf;
203 }
204
205
206
207
208
209
210
211
212 private static StringBuffer renderQDString( StringBuffer buf, String qdString )
213 {
214 buf.append( '\'' );
215
216 for ( char c : qdString.toCharArray() )
217 {
218 switch ( c )
219 {
220 case 0x27:
221 buf.append( "\\27" );
222 break;
223
224 case 0x5C:
225 buf.append( "\\5C" );
226 break;
227
228 default:
229 buf.append( c );
230 break;
231 }
232 }
233
234 buf.append( '\'' );
235
236 return buf;
237 }
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252 public static StringBuffer render( ObjectClass[] ocs )
253 {
254 StringBuffer buf = new StringBuffer();
255
256 return render( buf, ocs );
257 }
258
259
260
261
262
263
264
265
266
267
268
269
270 public static StringBuffer render( StringBuffer buf, ObjectClass[] ocs )
271 {
272 if ( ocs == null || ocs.length == 0 )
273 {
274 return buf;
275 }
276 else if ( ocs.length == 1 )
277 {
278 buf.append( ocs[0].getName() );
279 }
280 else
281 {
282 buf.append( "( " );
283
284 for ( int ii = 0; ii < ocs.length; ii++ )
285 {
286 if ( ii + 1 < ocs.length )
287 {
288 buf.append( ocs[ii].getName() ).append( " $ " );
289 }
290 else
291 {
292 buf.append( ocs[ii].getName() );
293 }
294 }
295
296 buf.append( " )" );
297 }
298
299 return buf;
300 }
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315 public static StringBuffer render( AttributeType[] ats )
316 {
317 StringBuffer buf = new StringBuffer();
318 return render( buf, ats );
319 }
320
321
322
323
324
325
326
327
328
329
330
331
332 public static StringBuffer render( StringBuffer buf, AttributeType[] ats )
333 {
334 if ( ats == null || ats.length == 0 )
335 {
336 return buf;
337 }
338 else if ( ats.length == 1 )
339 {
340 buf.append( ats[0].getName() );
341 }
342 else
343 {
344 buf.append( "( " );
345 for ( int ii = 0; ii < ats.length; ii++ )
346 {
347 if ( ii + 1 < ats.length )
348 {
349 buf.append( ats[ii].getName() ).append( " $ " );
350 }
351 else
352 {
353 buf.append( ats[ii].getName() );
354 }
355 }
356 buf.append( " )" );
357 }
358
359 return buf;
360 }
361
362
363
364
365
366
367
368
369
370
371
372
373
374 public static StringBuffer render( Map<String, List<String>> extensions )
375 {
376 StringBuffer buf = new StringBuffer();
377
378 if ( extensions.isEmpty() )
379 {
380 return buf;
381 }
382
383 for ( Map.Entry<String, List<String>> entry : extensions.entrySet() )
384 {
385 buf.append( " " ).append( entry.getKey() ).append( " " );
386
387 List<String> values = entry.getValue();
388
389
390 if ( values == null || values.isEmpty() )
391 {
392 continue;
393 }
394
395
396 if ( values.size() == 1 )
397 {
398 buf.append( "'" ).append( values.get( 0 ) ).append( "' " );
399 continue;
400 }
401
402
403
404 buf.append( "( " );
405 for ( String value : values )
406 {
407 buf.append( "'" ).append( value ).append( "' " );
408 }
409 buf.append( ")" );
410 }
411
412 if ( buf.charAt( buf.length() - 1 ) != ' ' )
413 {
414 buf.append( " " );
415 }
416
417 return buf;
418 }
419
420
421
422
423
424
425
426
427
428
429
430
431 public static String render( LoadableSchemaObject description )
432 {
433 StringBuffer buf = new StringBuffer();
434 buf.append( "( " ).append( description.getOid() );
435
436 if ( description.getDescription() != null )
437 {
438 buf.append( " DESC " );
439 renderQDString( buf, description.getDescription() );
440 }
441
442 buf.append( " FQCN " ).append( description.getFqcn() );
443
444 if ( !Strings.isEmpty( description.getBytecode() ) )
445 {
446 buf.append( " BYTECODE " ).append( description.getBytecode() );
447 }
448
449 buf.append( " X-SCHEMA '" );
450 buf.append( getSchemaName( description ) );
451 buf.append( "' )" );
452
453 return buf.toString();
454 }
455
456
457 private static String getSchemaName( SchemaObject desc )
458 {
459 List<String> values = desc.getExtensions().get( MetaSchemaConstants.X_SCHEMA_AT );
460
461 if ( values == null || values.size() == 0 )
462 {
463 return MetaSchemaConstants.SCHEMA_OTHER;
464 }
465
466 return values.get( 0 );
467 }
468
469
470
471
472
473
474
475
476
477
478
479 public static String stripOptions( String attributeId )
480 {
481 int optionsPos = attributeId.indexOf( ';' );
482
483 if ( optionsPos != -1 )
484 {
485 return attributeId.substring( 0, optionsPos );
486 }
487 else
488 {
489 return attributeId;
490 }
491 }
492
493
494
495
496
497
498
499
500
501
502 public static Set<String> getOptions( String attributeId )
503 {
504 int optionsPos = attributeId.indexOf( ';' );
505
506 if ( optionsPos != -1 )
507 {
508 Set<String> options = new HashSet<String>();
509
510 String[] res = attributeId.substring( optionsPos + 1 ).split( ";" );
511
512 for ( String option : res )
513 {
514 if ( !Strings.isEmpty( option ) )
515 {
516 options.add( option );
517 }
518 }
519
520 return options;
521 }
522 else
523 {
524 return null;
525 }
526 }
527
528
529
530
531
532
533
534 public static byte[] uuidToBytes( UUID uuid )
535 {
536 Long low = uuid.getLeastSignificantBits();
537 Long high = uuid.getMostSignificantBits();
538 byte[] bytes = new byte[16];
539
540 bytes[0] = ( byte ) ( ( high & 0xff00000000000000L ) >> 56 );
541 bytes[1] = ( byte ) ( ( high & 0x00ff000000000000L ) >> 48 );
542 bytes[2] = ( byte ) ( ( high & 0x0000ff0000000000L ) >> 40 );
543 bytes[3] = ( byte ) ( ( high & 0x000000ff00000000L ) >> 32 );
544 bytes[4] = ( byte ) ( ( high & 0x00000000ff000000L ) >> 24 );
545 bytes[5] = ( byte ) ( ( high & 0x0000000000ff0000L ) >> 16 );
546 bytes[6] = ( byte ) ( ( high & 0x000000000000ff00L ) >> 8 );
547 bytes[7] = ( byte ) ( high & 0x00000000000000ffL );
548 bytes[8] = ( byte ) ( ( low & 0xff00000000000000L ) >> 56 );
549 bytes[9] = ( byte ) ( ( low & 0x00ff000000000000L ) >> 48 );
550 bytes[10] = ( byte ) ( ( low & 0x0000ff0000000000L ) >> 40 );
551 bytes[11] = ( byte ) ( ( low & 0x000000ff00000000L ) >> 32 );
552 bytes[12] = ( byte ) ( ( low & 0x00000000ff000000L ) >> 24 );
553 bytes[13] = ( byte ) ( ( low & 0x0000000000ff0000L ) >> 16 );
554 bytes[14] = ( byte ) ( ( low & 0x000000000000ff00L ) >> 8 );
555 bytes[15] = ( byte ) ( low & 0x00000000000000ffL );
556
557 return bytes;
558 }
559 }