1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.directory.server.core.shared;
20
21
22 import java.io.IOException;
23
24 import org.apache.directory.api.ldap.model.constants.SchemaConstants;
25 import org.apache.directory.api.ldap.model.entry.Attribute;
26 import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
27 import org.apache.directory.api.ldap.model.entry.DefaultEntry;
28 import org.apache.directory.api.ldap.model.entry.Entry;
29 import org.apache.directory.api.ldap.model.exception.LdapException;
30 import org.apache.directory.api.ldap.model.exception.LdapOtherException;
31 import org.apache.directory.api.ldap.model.name.Dn;
32 import org.apache.directory.api.ldap.model.schema.AttributeType;
33 import org.apache.directory.api.ldap.model.schema.DitContentRule;
34 import org.apache.directory.api.ldap.model.schema.DitStructureRule;
35 import org.apache.directory.api.ldap.model.schema.LdapComparator;
36 import org.apache.directory.api.ldap.model.schema.LdapSyntax;
37 import org.apache.directory.api.ldap.model.schema.MatchingRule;
38 import org.apache.directory.api.ldap.model.schema.MatchingRuleUse;
39 import org.apache.directory.api.ldap.model.schema.NameForm;
40 import org.apache.directory.api.ldap.model.schema.Normalizer;
41 import org.apache.directory.api.ldap.model.schema.ObjectClass;
42 import org.apache.directory.api.ldap.model.schema.SchemaManager;
43 import org.apache.directory.api.ldap.model.schema.SchemaObjectRenderer;
44 import org.apache.directory.api.ldap.model.schema.SchemaUtils;
45 import org.apache.directory.api.ldap.model.schema.SyntaxChecker;
46 import org.apache.directory.api.ldap.model.schema.registries.NormalizerRegistry;
47 import org.apache.directory.server.constants.ApacheSchemaConstants;
48 import org.apache.directory.server.constants.ServerDNConstants;
49 import org.apache.directory.server.core.api.DirectoryService;
50 import org.apache.directory.server.core.api.entry.ClonedServerEntry;
51 import org.apache.directory.server.core.api.interceptor.context.FilteringOperationContext;
52 import org.apache.directory.server.core.api.interceptor.context.LookupOperationContext;
53 import org.apache.directory.server.core.api.partition.Partition;
54 import org.apache.directory.server.core.api.partition.PartitionTxn;
55
56
57
58
59
60
61
62 public final class SchemaService
63 {
64
65 private static Entry schemaSubentry;
66
67
68 private static Object schemaSubentrLock = new Object();
69
70
71 private SchemaService()
72 {
73 }
74
75
76
77
78
79 private static Attribute generateComparators( SchemaManager schemaManager ) throws LdapException
80 {
81 Attribute attr = new DefaultAttribute(
82 schemaManager.lookupAttributeTypeRegistry( SchemaConstants.COMPARATORS_AT ) );
83
84 for ( LdapComparator<?> comparator : schemaManager.getComparatorRegistry() )
85 {
86 attr.add( SchemaUtils.render( comparator ) );
87 }
88
89 return attr;
90 }
91
92
93 private static Attribute generateNormalizers( SchemaManager schemaManager ) throws LdapException
94 {
95 Attribute attr = new DefaultAttribute(
96 schemaManager.getAttributeType( SchemaConstants.NORMALIZERS_AT ) );
97
98 NormalizerRegistry nr = schemaManager.getNormalizerRegistry();
99
100 for ( Normalizer normalizer : nr )
101 {
102 attr.add( SchemaUtils.render( normalizer ) );
103 }
104
105 return attr;
106 }
107
108
109 private static Attribute generateSyntaxCheckers( SchemaManager schemaManager ) throws LdapException
110 {
111 Attribute attr = new DefaultAttribute(
112 schemaManager.getAttributeType( SchemaConstants.SYNTAX_CHECKERS_AT ) );
113
114 for ( SyntaxChecker syntaxChecker : schemaManager.getSyntaxCheckerRegistry() )
115 {
116 attr.add( SchemaUtils.render( syntaxChecker ) );
117 }
118
119 return attr;
120 }
121
122
123 private static Attribute generateObjectClasses( SchemaManager schemaManager ) throws LdapException
124 {
125 Attribute attr = new DefaultAttribute(
126 schemaManager.getAttributeType( SchemaConstants.OBJECT_CLASSES_AT ) );
127
128 for ( ObjectClass objectClass : schemaManager.getObjectClassRegistry() )
129 {
130 attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( objectClass ) );
131 }
132
133 return attr;
134 }
135
136
137 private static Attribute generateAttributeTypes( SchemaManager schemaManager ) throws LdapException
138 {
139 Attribute attr = new DefaultAttribute(
140 schemaManager.getAttributeType( SchemaConstants.ATTRIBUTE_TYPES_AT ) );
141
142 for ( AttributeType attributeType : schemaManager.getAttributeTypeRegistry() )
143 {
144 attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( attributeType ) );
145 }
146
147 return attr;
148 }
149
150
151 private static Attribute generateMatchingRules( SchemaManager schemaManager ) throws LdapException
152 {
153 Attribute attr = new DefaultAttribute(
154 schemaManager.getAttributeType( SchemaConstants.MATCHING_RULES_AT ) );
155
156 for ( MatchingRule matchingRule : schemaManager.getMatchingRuleRegistry() )
157 {
158 attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( matchingRule ) );
159 }
160
161 return attr;
162 }
163
164
165 private static Attribute generateMatchingRuleUses( SchemaManager schemaManager ) throws LdapException
166 {
167 Attribute attr = new DefaultAttribute(
168 schemaManager.getAttributeType( SchemaConstants.MATCHING_RULE_USE_AT ) );
169
170 for ( MatchingRuleUse matchingRuleUse : schemaManager.getMatchingRuleUseRegistry() )
171 {
172 attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( matchingRuleUse ) );
173 }
174
175 return attr;
176 }
177
178
179 private static Attribute generateSyntaxes( SchemaManager schemaManager ) throws LdapException
180 {
181 Attribute attr = new DefaultAttribute(
182 schemaManager.getAttributeType( SchemaConstants.LDAP_SYNTAXES_AT ) );
183
184 for ( LdapSyntax syntax : schemaManager.getLdapSyntaxRegistry() )
185 {
186 attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( syntax ) );
187 }
188
189 return attr;
190 }
191
192
193 private static Attribute generateDitContextRules( SchemaManager schemaManager ) throws LdapException
194 {
195 Attribute attr = new DefaultAttribute(
196 schemaManager.getAttributeType( SchemaConstants.DIT_CONTENT_RULES_AT ) );
197
198 for ( DitContentRule ditContentRule : schemaManager.getDITContentRuleRegistry() )
199 {
200 attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( ditContentRule ) );
201 }
202
203 return attr;
204 }
205
206
207 private static Attribute generateDitStructureRules( SchemaManager schemaManager ) throws LdapException
208 {
209 Attribute attr = new DefaultAttribute(
210 schemaManager.getAttributeType( SchemaConstants.DIT_STRUCTURE_RULES_AT ) );
211
212 for ( DitStructureRule ditStructureRule : schemaManager.getDITStructureRuleRegistry() )
213 {
214 attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( ditStructureRule ) );
215 }
216
217 return attr;
218 }
219
220
221 private static Attribute generateNameForms( SchemaManager schemaManager ) throws LdapException
222 {
223 Attribute attr = new DefaultAttribute(
224 schemaManager.getAttributeType( SchemaConstants.NAME_FORMS_AT ) );
225
226 for ( NameForm nameForm : schemaManager.getNameFormRegistry() )
227 {
228 attr.add( SchemaObjectRenderer.SUBSCHEMA_SUBENTRY_RENDERER.render( nameForm ) );
229 }
230
231 return attr;
232 }
233
234
235
236
237
238 private static void generateSchemaSubentry( SchemaManager schemaManager, Entry mods ) throws LdapException
239 {
240 Entry attrs = new DefaultEntry( schemaManager, mods.getDn() );
241
242
243 attrs.put( SchemaConstants.OBJECT_CLASS_AT,
244 SchemaConstants.TOP_OC,
245 SchemaConstants.SUBSCHEMA_OC,
246 SchemaConstants.SUBENTRY_OC,
247 ApacheSchemaConstants.APACHE_SUBSCHEMA_OC
248 );
249
250
251 attrs.put( SchemaConstants.CN_AT, "schema" );
252
253
254 attrs.put( generateComparators( schemaManager ) );
255 attrs.put( generateNormalizers( schemaManager ) );
256 attrs.put( generateSyntaxCheckers( schemaManager ) );
257 attrs.put( generateObjectClasses( schemaManager ) );
258 attrs.put( generateAttributeTypes( schemaManager ) );
259 attrs.put( generateMatchingRules( schemaManager ) );
260 attrs.put( generateMatchingRuleUses( schemaManager ) );
261 attrs.put( generateSyntaxes( schemaManager ) );
262 attrs.put( generateDitContextRules( schemaManager ) );
263 attrs.put( generateDitStructureRules( schemaManager ) );
264 attrs.put( generateNameForms( schemaManager ) );
265 attrs.put( SchemaConstants.SUBTREE_SPECIFICATION_AT, "{}" );
266
267
268
269
270
271
272 Attribute createTimestamp = mods.get( SchemaConstants.CREATE_TIMESTAMP_AT );
273 attrs.put( SchemaConstants.CREATE_TIMESTAMP_AT, createTimestamp.get() );
274
275
276 attrs.put( SchemaConstants.CREATORS_NAME_AT, ServerDNConstants.ADMIN_SYSTEM_DN );
277
278
279 Attribute schemaModifyTimestamp = mods.get( ApacheSchemaConstants.SCHEMA_MODIFY_TIMESTAMP_AT );
280 attrs.put( SchemaConstants.MODIFY_TIMESTAMP_AT, schemaModifyTimestamp.get() );
281
282
283 Attribute schemaModifiersName = mods.get( ApacheSchemaConstants.SCHEMA_MODIFIERS_NAME_AT );
284 attrs.put( SchemaConstants.MODIFIERS_NAME_AT, schemaModifiersName.get() );
285
286
287
288 synchronized ( schemaSubentrLock )
289 {
290 schemaSubentry = attrs;
291 }
292 }
293
294
295 private static void addAttribute( Entry attrs, String id ) throws LdapException
296 {
297 Attribute attr = schemaSubentry.get( id );
298
299 if ( ( attr != null ) && ( attr.size() > 0 ) )
300 {
301 attrs.put( attr );
302 }
303 }
304
305
306
307
308
309 public static Entry getSubschemaEntryImmutable( DirectoryService directoryService ) throws LdapException
310 {
311 synchronized ( schemaSubentrLock )
312 {
313 if ( schemaSubentry == null )
314 {
315 Dn schemaModificationAttributesDn = new Dn( directoryService.getSchemaManager(),
316 SchemaConstants.SCHEMA_MODIFICATIONS_DN );
317
318 Partition partition = directoryService.getSchemaPartition();
319
320 LookupOperationContexttor/context/LookupOperationContext.html#LookupOperationContext">LookupOperationContext lookupContext = new LookupOperationContext( null, schemaModificationAttributesDn );
321 lookupContext.setPartition( partition );
322
323 try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
324 {
325 lookupContext.setTransaction( partitionTxn );
326
327 generateSchemaSubentry( directoryService.getSchemaManager(),
328 directoryService.getSchemaPartition().lookup( lookupContext ) );
329 }
330 catch ( IOException ioe )
331 {
332 throw new LdapOtherException( ioe.getMessage(), ioe );
333 }
334 }
335
336 return schemaSubentry.clone();
337 }
338 }
339
340
341
342
343
344 public static Entry getSubschemaEntryCloned( DirectoryService directoryService ) throws LdapException
345 {
346 if ( schemaSubentry == null )
347 {
348 Dn schemaModificationAttributesDn = new Dn( directoryService.getSchemaManager(),
349 SchemaConstants.SCHEMA_MODIFICATIONS_DN );
350
351 Partition partition = directoryService.getSchemaPartition();
352
353 LookupOperationContexttor/context/LookupOperationContext.html#LookupOperationContext">LookupOperationContext lookupContext = new LookupOperationContext( null, schemaModificationAttributesDn );
354 lookupContext.setPartition( partition );
355
356 try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
357 {
358 lookupContext.setTransaction( partitionTxn );
359
360 generateSchemaSubentry(
361 directoryService.getSchemaManager(),
362 directoryService.getSchemaPartition().lookup( lookupContext ) );
363 }
364 catch ( IOException ioe )
365 {
366 throw new LdapOtherException( ioe.getMessage(), ioe );
367 }
368 }
369
370 return schemaSubentry.clone();
371 }
372
373
374
375
376
377 public static Entry getSubschemaEntry( DirectoryService directoryService, FilteringOperationContext operationContext )
378 throws LdapException
379 {
380 SchemaManager schemaManager = directoryService.getSchemaManager();
381
382 Entry attrs = new DefaultEntry( schemaManager, Dn.ROOT_DSE );
383
384 synchronized ( schemaSubentrLock )
385 {
386
387
388
389 Dn schemaModificationAttributesDn = new Dn( directoryService.getSchemaManager(),
390 SchemaConstants.SCHEMA_MODIFICATIONS_DN );
391
392 Partition partition = directoryService.getSchemaPartition();
393
394 LookupOperationContexttor/context/LookupOperationContext.html#LookupOperationContext">LookupOperationContext lookupContext = new LookupOperationContext( null, schemaModificationAttributesDn, SchemaConstants.ALL_ATTRIBUTES_ARRAY );
395 lookupContext.setPartition( partition );
396
397 try ( PartitionTxn partitionTxn = partition.beginReadTransaction() )
398 {
399 lookupContext.setTransaction( partitionTxn );
400
401 Entry mods =
402 directoryService.getSchemaPartition().lookup( lookupContext );
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432 generateSchemaSubentry( schemaManager, mods );
433 }
434 catch ( IOException ioe )
435 {
436 throw new LdapOtherException( ioe.getMessage(), ioe );
437 }
438
439
440
441
442 addAttribute( attrs, SchemaConstants.COMPARATORS_AT );
443 addAttribute( attrs, SchemaConstants.NORMALIZERS_AT );
444 addAttribute( attrs, SchemaConstants.SYNTAX_CHECKERS_AT );
445 addAttribute( attrs, SchemaConstants.OBJECT_CLASSES_AT );
446 addAttribute( attrs, SchemaConstants.ATTRIBUTE_TYPES_AT );
447 addAttribute( attrs, SchemaConstants.MATCHING_RULES_AT );
448 addAttribute( attrs, SchemaConstants.MATCHING_RULE_USE_AT );
449 addAttribute( attrs, SchemaConstants.LDAP_SYNTAXES_AT );
450 addAttribute( attrs, SchemaConstants.DIT_CONTENT_RULES_AT );
451 addAttribute( attrs, SchemaConstants.DIT_STRUCTURE_RULES_AT );
452 addAttribute( attrs, SchemaConstants.NAME_FORMS_AT );
453 addAttribute( attrs, SchemaConstants.SUBTREE_SPECIFICATION_AT );
454
455
456 addAttribute( attrs, SchemaConstants.OBJECT_CLASS_AT );
457
458
459 addAttribute( attrs, SchemaConstants.CN_AT );
460
461
462
463
464 addAttribute( attrs, SchemaConstants.CREATE_TIMESTAMP_AT );
465 addAttribute( attrs, SchemaConstants.CREATORS_NAME_AT );
466 addAttribute( attrs, SchemaConstants.MODIFY_TIMESTAMP_AT );
467 addAttribute( attrs, SchemaConstants.MODIFIERS_NAME_AT );
468 addAttribute( attrs, SchemaConstants.ENTRY_UUID_AT );
469 addAttribute( attrs, SchemaConstants.ENTRY_DN_AT );
470 }
471
472 return new ClonedServerEntry( attrs );
473 }
474 }