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.registries;
21
22
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.Map;
26
27 import org.apache.directory.api.asn1.util.Oid;
28 import org.apache.directory.api.i18n.I18n;
29 import org.apache.directory.api.ldap.model.exception.LdapException;
30 import org.apache.directory.api.ldap.model.exception.LdapSchemaException;
31 import org.apache.directory.api.ldap.model.exception.LdapSchemaExceptionCodes;
32 import org.apache.directory.api.ldap.model.schema.LoadableSchemaObject;
33 import org.apache.directory.api.ldap.model.schema.SchemaErrorHandler;
34 import org.apache.directory.api.ldap.model.schema.SchemaObject;
35 import org.apache.directory.api.ldap.model.schema.SchemaObjectType;
36 import org.apache.directory.api.util.Strings;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40
41
42
43
44
45
46
47
48 public abstract class DefaultSchemaObjectRegistry<T extends SchemaObject> implements SchemaObjectRegistry<T>,
49 Iterable<T>
50 {
51
52 private static final Logger LOG = LoggerFactory.getLogger( DefaultSchemaObjectRegistry.class );
53
54
55 protected Map<String, T> byName;
56
57
58 protected SchemaObjectType schemaObjectType;
59
60
61 protected OidRegistry<T> oidRegistry;
62
63
64 private boolean isRelaxed;
65
66 private SchemaErrorHandler errorHandler;
67
68
69
70
71
72
73
74 protected DefaultSchemaObjectRegistry( SchemaObjectType schemaObjectType, OidRegistry<T> oidRegistry )
75 {
76 byName = new HashMap<>();
77 this.schemaObjectType = schemaObjectType;
78 this.oidRegistry = oidRegistry;
79 this.isRelaxed = Registries.STRICT;
80 }
81
82
83
84
85
86
87
88 public boolean isRelaxed()
89 {
90 return isRelaxed;
91 }
92
93
94
95
96
97
98
99 public boolean isStrict()
100 {
101 return !isRelaxed;
102 }
103
104
105
106
107
108
109 public void setRelaxed()
110 {
111 isRelaxed = Registries.RELAXED;
112 oidRegistry.setRelaxed();
113 }
114
115
116
117
118
119
120 public void setStrict()
121 {
122 isRelaxed = Registries.STRICT;
123 oidRegistry.setStrict();
124 }
125
126
127 public SchemaErrorHandler getErrorHandler()
128 {
129 return errorHandler;
130 }
131
132 public void setErrorHandler( SchemaErrorHandler errorHandler )
133 {
134 this.errorHandler = errorHandler;
135 oidRegistry.setErrorHandler( errorHandler );
136 }
137
138
139
140
141 @Override
142 public boolean contains( String oid )
143 {
144 if ( !byName.containsKey( oid ) )
145 {
146 return byName.containsKey( Strings.toLowerCaseAscii( oid ) );
147 }
148
149 return true;
150 }
151
152
153
154
155
156 @Override
157 public String getSchemaName( String oid ) throws LdapException
158 {
159 if ( !Oid.isOid( oid ) )
160 {
161 String msg = I18n.err( I18n.ERR_13733_ARG_NOT_NUMERIC_OID );
162
163 if ( LOG.isWarnEnabled() )
164 {
165 LOG.warn( msg );
166 }
167
168 throw new LdapException( msg );
169 }
170
171 SchemaObject schemaObject = byName.get( oid );
172
173 if ( schemaObject != null )
174 {
175 return schemaObject.getSchemaName();
176 }
177
178 String msg = I18n.err( I18n.ERR_13734_OID_NOT_FOUND, oid );
179
180 if ( LOG.isWarnEnabled() )
181 {
182 LOG.warn( msg );
183 }
184
185 throw new LdapException( msg );
186 }
187
188
189
190
191
192 @Override
193 public void renameSchema( String originalSchemaName, String newSchemaName )
194 {
195
196
197 for ( T schemaObject : this )
198 {
199 if ( originalSchemaName.equalsIgnoreCase( schemaObject.getSchemaName() ) )
200 {
201 schemaObject.setSchemaName( newSchemaName );
202
203 if ( LOG.isDebugEnabled() )
204 {
205 LOG.debug( I18n.msg( I18n.MSG_13722_RENAMED_SCHEMA_NAME_TO, schemaObject, newSchemaName ) );
206 }
207 }
208 }
209 }
210
211
212
213
214
215 @Override
216 public Iterator<T> iterator()
217 {
218 return oidRegistry.iterator();
219 }
220
221
222
223
224
225 @Override
226 public Iterator<String> oidsIterator()
227 {
228 return byName.keySet().iterator();
229 }
230
231
232
233
234
235 @Override
236 public T lookup( String oid ) throws LdapException
237 {
238 if ( oid == null )
239 {
240 return null;
241 }
242
243 T schemaObject = byName.get( oid );
244
245 if ( schemaObject == null )
246 {
247
248 schemaObject = byName.get( Strings.trim( Strings.toLowerCaseAscii( oid ) ) );
249
250 if ( schemaObject == null )
251 {
252 String msg = I18n.err( I18n.ERR_13735_ELEMENT_FOR_OID_DOES_NOT_EXIST, schemaObjectType.name(), oid );
253
254 if ( LOG.isDebugEnabled() )
255 {
256 LOG.debug( msg );
257 }
258
259 throw new LdapException( msg );
260 }
261 }
262
263 if ( LOG.isDebugEnabled() )
264 {
265 LOG.debug( I18n.msg( I18n.MSG_13723_FOUND_WITH_OID, schemaObject, oid ) );
266 }
267
268 return schemaObject;
269 }
270
271
272
273
274
275 @Override
276 public void register( T schemaObject ) throws LdapException
277 {
278 String oid = schemaObject.getOid();
279
280 if ( byName.containsKey( oid ) )
281 {
282 String msg = I18n.err( I18n.ERR_13736_ELEMENT_FOR_OID_ALREADY_REGISTERED, schemaObjectType.name(), oid );
283
284 if ( LOG.isWarnEnabled() )
285 {
286 LOG.warn( msg );
287 }
288
289 LdapSchemaException ldapSchemaException = new LdapSchemaException(
290 LdapSchemaExceptionCodes.OID_ALREADY_REGISTERED, msg );
291 ldapSchemaException.setSourceObject( schemaObject );
292 throw ldapSchemaException;
293 }
294
295 byName.put( oid, schemaObject );
296
297
298
299
300
301 for ( String name : schemaObject.getNames() )
302 {
303 String lowerName = Strings.trim( Strings.toLowerCaseAscii( name ) );
304
305 if ( byName.containsKey( lowerName ) )
306 {
307 String msg = I18n.err( I18n.ERR_13737_ELEMENT_WITH_NAME_ALREADY_REGISTERED, schemaObjectType.name(), name );
308
309 if ( LOG.isWarnEnabled() )
310 {
311 LOG.warn( msg );
312 }
313
314 LdapSchemaException ldapSchemaException = new LdapSchemaException(
315 LdapSchemaExceptionCodes.NAME_ALREADY_REGISTERED, msg );
316 ldapSchemaException.setSourceObject( schemaObject );
317 throw ldapSchemaException;
318 }
319 else
320 {
321 byName.put( lowerName, schemaObject );
322 }
323 }
324
325
326 oidRegistry.register( schemaObject );
327
328 if ( LOG.isDebugEnabled() )
329 {
330 LOG.debug( I18n.msg( I18n.MSG_13731_REGISTRED_FOR_OID, schemaObject.getName(), oid ) );
331 }
332 }
333
334
335
336
337
338 @Override
339 public T unregister( String numericOid ) throws LdapException
340 {
341 if ( !Oid.isOid( numericOid ) )
342 {
343 String msg = I18n.err( I18n.ERR_13738_OID_NOT_A_NUMERIC_OID, numericOid );
344 LOG.error( msg );
345 throw new LdapException( msg );
346 }
347
348 T schemaObject = byName.remove( numericOid );
349
350 for ( String name : schemaObject.getNames() )
351 {
352 byName.remove( name );
353 }
354
355
356 oidRegistry.unregister( numericOid );
357
358 if ( LOG.isDebugEnabled() )
359 {
360 LOG.debug( I18n.msg( I18n.MSG_13702_REMOVED_FROM_REGISTRY, schemaObject, numericOid ) );
361 }
362
363 return schemaObject;
364 }
365
366
367
368
369
370 @Override
371 public T unregister( T schemaObject ) throws LdapException
372 {
373 String oid = schemaObject.getOid();
374
375 if ( !byName.containsKey( oid ) )
376 {
377 String msg = I18n.err( I18n.ERR_13739_ELEMENT_WITH_OID_NOT_REGISTERED, schemaObjectType.name(), oid );
378
379 if ( LOG.isWarnEnabled() )
380 {
381 LOG.warn( msg );
382 }
383
384 throw new LdapException( msg );
385 }
386
387
388 T removed = byName.remove( oid );
389
390
391
392
393
394 for ( String name : schemaObject.getNames() )
395 {
396 byName.remove( Strings.trim( Strings.toLowerCaseAscii( name ) ) );
397 }
398
399
400 oidRegistry.unregister( oid );
401
402 return removed;
403 }
404
405
406
407
408
409 @Override
410 public void unregisterSchemaElements( String schemaName ) throws LdapException
411 {
412 if ( schemaName == null )
413 {
414 return;
415 }
416
417
418
419 for ( T schemaObject : this )
420 {
421 if ( schemaName.equalsIgnoreCase( schemaObject.getSchemaName() ) )
422 {
423 String oid = schemaObject.getOid();
424 SchemaObject removed = unregister( oid );
425
426 if ( LOG.isDebugEnabled() )
427 {
428 LOG.debug( I18n.msg( I18n.MSG_13702_REMOVED_FROM_REGISTRY, removed, oid ) );
429 }
430 }
431 }
432 }
433
434
435
436
437
438 @Override
439 public String getOidByName( String name ) throws LdapException
440 {
441 T schemaObject = byName.get( name );
442
443 if ( schemaObject == null )
444 {
445
446 String lowerCased = Strings.toLowerCaseAscii( name );
447
448 schemaObject = byName.get( lowerCased );
449
450
451 if ( schemaObject == null )
452 {
453 throw new LdapException( I18n.err( I18n.ERR_13740_CANNOT_FIND_OID_FROM_NAME, name ) );
454 }
455 }
456
457
458 return schemaObject.getOid();
459 }
460
461
462
463
464
465
466
467
468
469 @SuppressWarnings("unchecked")
470 public SchemaObjectRegistry<T> copy( SchemaObjectRegistry<T> original )
471 {
472
473 for ( Map.Entry<String, T> entry : ( ( DefaultSchemaObjectRegistry<T> ) original ).byName.entrySet() )
474 {
475 String key = entry.getKey();
476
477 T value = entry.getValue();
478
479 if ( value instanceof LoadableSchemaObject )
480 {
481
482
483
484 byName.put( key, value );
485
486
487 oidRegistry.put( value );
488 }
489 else
490 {
491 T copiedValue = null;
492
493
494 if ( oidRegistry.contains( value.getOid() ) )
495 {
496 try
497 {
498 copiedValue = oidRegistry.getSchemaObject( value.getOid() );
499 }
500 catch ( LdapException ne )
501 {
502
503 }
504 }
505 else
506 {
507 copiedValue = ( T ) value.copy();
508 }
509
510
511 byName.put( key, copiedValue );
512
513
514 oidRegistry.put( copiedValue );
515 }
516 }
517
518 return this;
519 }
520
521
522
523
524
525 @Override
526 public T get( String oid )
527 {
528 try
529 {
530 return oidRegistry.getSchemaObject( oid );
531 }
532 catch ( LdapException ne )
533 {
534 return null;
535 }
536 }
537
538
539
540
541
542 @Override
543 public SchemaObjectType getType()
544 {
545 return schemaObjectType;
546 }
547
548
549
550
551
552 @Override
553 public int size()
554 {
555 return oidRegistry.size();
556 }
557
558
559
560
561
562 @Override
563 public String toString()
564 {
565 StringBuilder sb = new StringBuilder();
566
567 sb.append( schemaObjectType ).append( ": " );
568 boolean isFirst = true;
569
570 for ( Map.Entry<String, T> entry : byName.entrySet() )
571 {
572 if ( isFirst )
573 {
574 isFirst = false;
575 }
576 else
577 {
578 sb.append( ", " );
579 }
580
581 String name = entry.getKey();
582 T schemaObject = entry.getValue();
583
584 sb.append( '<' ).append( name ).append( ", " ).append( schemaObject.getOid() ).append( '>' );
585 }
586
587 return sb.toString();
588 }
589
590
591
592
593
594 @Override
595 public void clear()
596 {
597
598 for ( SchemaObject schemaObject : oidRegistry )
599 {
600
601 if ( !( schemaObject instanceof LoadableSchemaObject ) )
602 {
603 schemaObject.clear();
604 }
605 }
606
607
608 byName.clear();
609
610
611 oidRegistry.clear();
612 }
613 }