1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.core.api.schema.registries.synchronizers;
21
22
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.Map;
26 import java.util.Set;
27
28 import org.apache.directory.api.ldap.model.constants.MetaSchemaConstants;
29 import org.apache.directory.api.ldap.model.constants.SchemaConstants;
30 import org.apache.directory.api.ldap.model.entry.Attribute;
31 import org.apache.directory.api.ldap.model.entry.Entry;
32 import org.apache.directory.api.ldap.model.exception.LdapException;
33 import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
34 import org.apache.directory.api.ldap.model.exception.LdapOtherException;
35 import org.apache.directory.api.ldap.model.exception.LdapSchemaViolationException;
36 import org.apache.directory.api.ldap.model.exception.LdapUnwillingToPerformException;
37 import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
38 import org.apache.directory.api.ldap.model.name.Dn;
39 import org.apache.directory.api.ldap.model.name.Rdn;
40 import org.apache.directory.api.ldap.model.schema.AttributeType;
41 import org.apache.directory.api.ldap.model.schema.SchemaManager;
42 import org.apache.directory.api.ldap.model.schema.SchemaObject;
43 import org.apache.directory.api.ldap.model.schema.SchemaObjectWrapper;
44 import org.apache.directory.api.ldap.model.schema.registries.Schema;
45 import org.apache.directory.api.ldap.schema.loader.SchemaEntityFactory;
46 import org.apache.directory.api.util.Strings;
47 import org.apache.directory.server.i18n.I18n;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51
52
53
54
55
56
57 public abstract class AbstractRegistrySynchronizer implements RegistrySynchronizer
58 {
59
60 private static final Logger LOG = LoggerFactory.getLogger( AbstractRegistrySynchronizer.class );
61
62
63 protected final SchemaManager schemaManager;
64
65
66 protected final AttributeType moidAT;
67
68
69 protected final SchemaEntityFactory factory;
70
71
72 private static final Map<String, String> OBJECT_TYPE_TO_PATH = new HashMap<>();
73
74 static
75 {
76
77 OBJECT_TYPE_TO_PATH.put( SchemaConstants.ATTRIBUTE_TYPE, SchemaConstants.ATTRIBUTE_TYPES_PATH.substring( 3 ) );
78 OBJECT_TYPE_TO_PATH.put( SchemaConstants.COMPARATOR, SchemaConstants.COMPARATORS_PATH.substring( 3 ) );
79 OBJECT_TYPE_TO_PATH
80 .put( SchemaConstants.DIT_CONTENT_RULE, SchemaConstants.DIT_CONTENT_RULES_PATH.substring( 3 ) );
81 OBJECT_TYPE_TO_PATH.put( SchemaConstants.DIT_STRUCTURE_RULE,
82 SchemaConstants.DIT_STRUCTURE_RULES_PATH.substring( 3 ) );
83 OBJECT_TYPE_TO_PATH.put( SchemaConstants.MATCHING_RULE, SchemaConstants.MATCHING_RULES_PATH.substring( 3 ) );
84 OBJECT_TYPE_TO_PATH.put( SchemaConstants.MATCHING_RULE_USE,
85 SchemaConstants.MATCHING_RULE_USE_PATH.substring( 3 ) );
86 OBJECT_TYPE_TO_PATH.put( SchemaConstants.NAME_FORM, SchemaConstants.NAME_FORMS_PATH.substring( 3 ) );
87 OBJECT_TYPE_TO_PATH.put( SchemaConstants.NORMALIZER, SchemaConstants.NORMALIZERS_PATH.substring( 3 ) );
88 OBJECT_TYPE_TO_PATH.put( SchemaConstants.OBJECT_CLASS, SchemaConstants.OBJECT_CLASSES_PATH.substring( 3 ) );
89 OBJECT_TYPE_TO_PATH.put( SchemaConstants.SYNTAX, SchemaConstants.SYNTAXES_PATH.substring( 3 ) );
90 OBJECT_TYPE_TO_PATH.put( SchemaConstants.SYNTAX_CHECKER, SchemaConstants.SYNTAX_CHECKERS_PATH.substring( 3 ) );
91 }
92
93
94 protected AbstractRegistrySynchronizer( SchemaManager schemaManager )
95 {
96 this.schemaManager = schemaManager;
97 moidAT = schemaManager.getAttributeType( MetaSchemaConstants.M_OID_AT );
98 factory = new SchemaEntityFactory();
99 }
100
101
102
103
104
105
106
107
108
109 protected boolean isSchemaLoaded( Dn dn ) throws LdapException
110 {
111 return schemaManager.isSchemaLoaded( getSchemaName( dn ) );
112 }
113
114
115
116
117
118
119
120
121 protected boolean isSchemaLoaded( String schemaName )
122 {
123 return schemaManager.isSchemaLoaded( schemaName );
124 }
125
126
127
128
129
130
131
132
133 protected boolean isSchemaEnabled( String schemaName )
134 {
135 Schema schema = schemaManager.getLoadedSchema( schemaName );
136
137 return ( schema != null ) && schema.isEnabled();
138 }
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153 protected String getSchemaName( Dn dn ) throws LdapException
154 {
155 int size = dn.size();
156
157 if ( size < 2 )
158 {
159 throw new LdapInvalidDnException( I18n.err( I18n.ERR_276 ) );
160 }
161
162 Rdn rdn = dn.getRdn( size - 2 );
163
164 return Strings.trim( rdn.getAva().getValue().getNormalized() );
165 }
166
167
168 protected void checkOidIsUnique( Entry entry ) throws LdapException
169 {
170 String oid = getOid( entry );
171
172 if ( schemaManager.getGlobalOidRegistry().contains( oid ) )
173 {
174 throw new LdapOtherException( I18n.err( I18n.ERR_335, oid ) );
175 }
176 }
177
178
179
180
181
182
183
184
185
186
187 protected SchemaObject checkOidExists( Entry entry ) throws LdapException
188 {
189 String oid = getOid( entry );
190
191 if ( schemaManager.getGlobalOidRegistry().contains( oid ) )
192 {
193 return schemaManager.getGlobalOidRegistry().getSchemaObject( oid );
194 }
195 else
196 {
197 throw new LdapSchemaViolationException( ResultCodeEnum.OTHER,
198 I18n.err( I18n.ERR_336, oid ) );
199 }
200 }
201
202
203
204
205
206
207
208
209
210
211 protected void checkParent( Dn newParent, SchemaManager schemaManager, String objectType ) throws LdapException
212 {
213 if ( newParent.size() != 3 )
214 {
215 throw new LdapInvalidDnException( ResultCodeEnum.NAMING_VIOLATION, I18n.err( I18n.ERR_337 ) );
216 }
217
218 Rdn rdn = newParent.getRdn();
219
220 if ( !schemaManager.getAttributeTypeRegistry().getOidByName( rdn.getNormType() )
221 .equals( SchemaConstants.OU_AT_OID ) )
222 {
223 throw new LdapInvalidDnException( ResultCodeEnum.NAMING_VIOLATION,
224 I18n.err( I18n.ERR_338, objectType ) );
225 }
226
227 if ( !rdn.getValue().equalsIgnoreCase( OBJECT_TYPE_TO_PATH.get( objectType ) ) )
228 {
229 throw new LdapInvalidDnException( ResultCodeEnum.NAMING_VIOLATION,
230 I18n.err( I18n.ERR_339, objectType, OBJECT_TYPE_TO_PATH.get( objectType ) ) );
231 }
232 }
233
234
235 protected void checkOidIsUnique( SchemaObject schemaObject ) throws LdapException
236 {
237 String oid = schemaObject.getOid();
238
239 if ( schemaManager.getGlobalOidRegistry().contains( oid ) )
240 {
241 throw new LdapSchemaViolationException( ResultCodeEnum.OTHER,
242 I18n.err( I18n.ERR_335, oid ) );
243 }
244 }
245
246
247 protected void checkOidIsUnique( String oid ) throws LdapException
248 {
249 if ( schemaManager.getGlobalOidRegistry().contains( oid ) )
250 {
251 throw new LdapSchemaViolationException( ResultCodeEnum.OTHER,
252 I18n.err( I18n.ERR_335, oid ) );
253 }
254 }
255
256
257
258
259
260
261
262
263
264
265 protected void addToSchema( SchemaObject schemaObject, String schemaName ) throws LdapException
266 {
267 if ( isSchemaLoaded( schemaName ) )
268 {
269
270 Set<SchemaObjectWrapper> schemaObjects = schemaManager.getRegistries().getObjectBySchemaName()
271 .get( schemaName );
272
273 if ( schemaObjects == null )
274 {
275
276 schemaObjects = schemaManager.getRegistries().addSchema( schemaName );
277 }
278
279 SchemaObjectWrapper schemaObjectWrapper = new SchemaObjectWrapper( schemaObject );
280
281 if ( schemaObjects.contains( schemaObjectWrapper ) )
282 {
283 String msg = I18n.err( I18n.ERR_341, schemaObject.getName(), schemaName );
284 LOG.warn( msg );
285
286 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
287 }
288
289 schemaObjects.add( schemaObjectWrapper );
290 LOG.debug( "The SchemaObject {} has been added to the schema {}", schemaObject, schemaName );
291 }
292 else
293 {
294 String msg = I18n.err( I18n.ERR_342, schemaObject.getName(), schemaName );
295 LOG.warn( msg );
296
297 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
298 }
299 }
300
301
302
303
304
305
306
307
308
309
310 protected void deleteFromSchema( SchemaObject schemaObject, String schemaName ) throws LdapException
311 {
312 if ( isSchemaLoaded( schemaName ) )
313 {
314 Set<SchemaObjectWrapper> schemaObjects = schemaManager.getRegistries().getObjectBySchemaName()
315 .get( schemaName );
316
317 SchemaObjectWrapper schemaObjectWrapper = new SchemaObjectWrapper( schemaObject );
318
319 if ( !schemaObjects.contains( schemaObjectWrapper ) )
320 {
321 String msg = I18n.err( I18n.ERR_343, schemaObject.getName(), schemaName );
322 LOG.warn( msg );
323
324 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
325 }
326
327 schemaObjects.remove( schemaObjectWrapper );
328 LOG.debug( "The SchemaObject {} has been removed from the schema {}", schemaObject, schemaName );
329 }
330 else
331 {
332 String msg = I18n.err( I18n.ERR_342, schemaObject.getName(), schemaName );
333 LOG.warn( msg );
334
335 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
336 }
337 }
338
339
340 protected Set<String> getOids( Set<Entry> results )
341 {
342 Set<String> oids = new HashSet<>( results.size() );
343
344 for ( Entry result : results )
345 {
346 Dn dn = result.getDn();
347 oids.add( dn.getRdn().getValue() );
348 }
349
350 return oids;
351 }
352
353
354 protected String getOid( Entry entry ) throws LdapException
355 {
356 Attribute oid = entry.get( moidAT );
357
358 if ( oid == null )
359 {
360 return null;
361 }
362
363 return oid.getString();
364 }
365
366
367
368
369
370
371
372
373 protected void unregisterOids( SchemaObject obj ) throws LdapException
374 {
375 schemaManager.getGlobalOidRegistry().unregister( obj.getOid() );
376 }
377
378
379
380
381
382
383
384
385 protected void registerOids( SchemaObject obj ) throws LdapException
386 {
387 schemaManager.getGlobalOidRegistry().register( obj );
388 }
389
390
391
392
393
394
395
396
397
398 protected String getReferenced( SchemaObject schemaObject )
399 {
400 StringBuilder sb = new StringBuilder();
401
402 Set<SchemaObjectWrapper> useds = schemaManager.getRegistries().getUsedBy( schemaObject );
403
404 for ( SchemaObjectWrapper used : useds )
405 {
406 sb.append( used );
407 sb.append( '\n' );
408 }
409
410 return sb.toString();
411 }
412 }