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