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.Collections;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.Map;
28 import java.util.Set;
29
30 import org.apache.directory.api.i18n.I18n;
31 import org.apache.directory.api.ldap.model.exception.LdapException;
32 import org.apache.directory.api.ldap.model.exception.LdapNoSuchAttributeException;
33 import org.apache.directory.api.ldap.model.exception.LdapSchemaException;
34 import org.apache.directory.api.ldap.model.exception.LdapSchemaExceptionCodes;
35 import org.apache.directory.api.ldap.model.schema.AttributeType;
36 import org.apache.directory.api.ldap.model.schema.MatchingRule;
37 import org.apache.directory.api.ldap.model.schema.SchemaObjectType;
38 import org.apache.directory.api.ldap.model.schema.normalizers.NoOpNormalizer;
39 import org.apache.directory.api.ldap.model.schema.normalizers.OidNormalizer;
40 import org.apache.directory.api.util.Strings;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44
45
46
47
48
49
50 public class DefaultAttributeTypeRegistry extends DefaultSchemaObjectRegistry<AttributeType> implements
51 AttributeTypeRegistry
52 {
53
54 private static final Logger LOG = LoggerFactory.getLogger( DefaultAttributeTypeRegistry.class );
55
56
57 private Map<String, OidNormalizer> oidNormalizerMap;
58
59
60 private Map<String, Set<AttributeType>> oidToDescendantSet;
61
62
63
64
65
66 public DefaultAttributeTypeRegistry()
67 {
68 super( SchemaObjectType.ATTRIBUTE_TYPE, new OidRegistry<AttributeType>() );
69 oidNormalizerMap = new HashMap<>();
70 oidToDescendantSet = new HashMap<>();
71 }
72
73
74
75
76
77 @Override
78 public Map<String, OidNormalizer> getNormalizerMapping()
79 {
80 return Collections.unmodifiableMap( oidNormalizerMap );
81 }
82
83
84
85
86
87 @Override
88 public boolean hasDescendants( String ancestorId ) throws LdapException
89 {
90 try
91 {
92 String oid = getOidByName( ancestorId );
93 Set<AttributeType> descendants = oidToDescendantSet.get( oid );
94 return ( descendants != null ) && !descendants.isEmpty();
95 }
96 catch ( LdapException ne )
97 {
98 throw new LdapNoSuchAttributeException( ne.getMessage(), ne );
99 }
100 }
101
102
103
104
105
106 @Override
107 public boolean hasDescendants( AttributeType ancestor ) throws LdapException
108 {
109 String oid = ancestor.getOid();
110 Set<AttributeType> descendants = oidToDescendantSet.get( oid );
111 return ( descendants != null ) && !descendants.isEmpty();
112 }
113
114
115
116
117
118 @SuppressWarnings("unchecked")
119 @Override
120 public Iterator<AttributeType> descendants( String ancestorId ) throws LdapException
121 {
122 try
123 {
124 String oid = getOidByName( ancestorId );
125 Set<AttributeType> descendants = oidToDescendantSet.get( oid );
126
127 if ( descendants == null )
128 {
129 return Collections.EMPTY_SET.iterator();
130 }
131
132 return descendants.iterator();
133 }
134 catch ( LdapException ne )
135 {
136 throw new LdapNoSuchAttributeException( ne.getMessage(), ne );
137 }
138 }
139
140
141
142
143
144 @SuppressWarnings("unchecked")
145 @Override
146 public Iterator<AttributeType> descendants( AttributeType ancestor ) throws LdapException
147 {
148 String oid = ancestor.getOid();
149 Set<AttributeType> descendants = oidToDescendantSet.get( oid );
150
151 if ( descendants == null )
152 {
153 return Collections.EMPTY_SET.iterator();
154 }
155
156 return descendants.iterator();
157 }
158
159
160
161
162
163 @Override
164 public void registerDescendants( AttributeType attributeType, AttributeType ancestor ) throws LdapException
165 {
166
167 if ( ancestor == null )
168 {
169 return;
170 }
171
172
173 if ( attributeType.getOid().equals( ancestor.getOid() ) )
174 {
175 throw new LdapSchemaException( LdapSchemaExceptionCodes.AT_CYCLE_TYPE_HIERARCHY );
176 }
177
178
179 Set<AttributeType> descendants = oidToDescendantSet.get( ancestor.getOid() );
180
181
182 if ( descendants == null )
183 {
184 descendants = new HashSet<>( 1 );
185 oidToDescendantSet.put( ancestor.getOid(), descendants );
186 }
187
188
189 descendants.add( attributeType );
190 }
191
192
193
194
195
196 @Override
197 public void unregisterDescendants( AttributeType attributeType, AttributeType ancestor ) throws LdapException
198 {
199
200 if ( ancestor == null )
201 {
202 return;
203 }
204
205
206 Set<AttributeType> descendants = oidToDescendantSet.get( ancestor.getOid() );
207
208 if ( descendants != null )
209 {
210 descendants.remove( attributeType );
211
212 if ( descendants.isEmpty() )
213 {
214 oidToDescendantSet.remove( ancestor.getOid() );
215 }
216 }
217 }
218
219
220
221
222
223 @Override
224 public AttributeType unregister( String numericOid ) throws LdapException
225 {
226 try
227 {
228 AttributeType removed = super.unregister( numericOid );
229
230 removeMappingFor( removed );
231
232
233
234
235 oidToDescendantSet.remove( numericOid );
236
237
238 unregisterDescendants( removed, removed.getSuperior() );
239
240 return removed;
241 }
242 catch ( LdapException ne )
243 {
244 throw new LdapNoSuchAttributeException( ne.getMessage(), ne );
245 }
246 }
247
248
249
250
251
252 @Override
253 public void addMappingFor( AttributeType attributeType ) throws LdapException
254 {
255 MatchingRule equality = attributeType.getEquality();
256 OidNormalizer oidNormalizer;
257 String oid = attributeType.getOid();
258
259 if ( equality == null )
260 {
261 if ( LOG.isDebugEnabled() )
262 {
263 LOG.debug( I18n.msg( I18n.MSG_13703_AT_WITHOUT_EQ_MR, attributeType.getName() ) );
264 }
265
266 oidNormalizer = new OidNormalizer( oid, new NoOpNormalizer( attributeType.getOid() ) );
267 }
268 else
269 {
270 oidNormalizer = new OidNormalizer( oid, equality.getNormalizer() );
271 }
272
273 oidNormalizerMap.put( oid, oidNormalizer );
274
275
276 for ( String name : attributeType.getNames() )
277 {
278 oidNormalizerMap.put( Strings.toLowerCaseAscii( name ), oidNormalizer );
279 }
280 }
281
282
283
284
285
286 @Override
287 public void removeMappingFor( AttributeType attributeType ) throws LdapException
288 {
289 if ( attributeType == null )
290 {
291 return;
292 }
293
294 oidNormalizerMap.remove( attributeType.getOid() );
295
296
297 for ( String name : attributeType.getNames() )
298 {
299 oidNormalizerMap.remove( Strings.toLowerCaseAscii( name ) );
300 }
301 }
302
303
304
305
306
307 @Override
308 public AttributeType lookup( String oid ) throws LdapException
309 {
310 try
311 {
312 return super.lookup( oid );
313 }
314 catch ( LdapException ne )
315 {
316 throw new LdapNoSuchAttributeException( ne.getMessage(), ne );
317 }
318 }
319
320
321
322
323
324 @Override
325 public DefaultAttributeTypeRegistry copy()
326 {
327 DefaultAttributeTypeRegistry copy = new DefaultAttributeTypeRegistry();
328
329
330 copy.copy( this );
331
332 return copy;
333 }
334
335
336
337
338
339 @Override
340 public void clear()
341 {
342
343 super.clear();
344
345
346 oidNormalizerMap.clear();
347
348
349 for ( Map.Entry<String, Set<AttributeType>> entry : oidToDescendantSet.entrySet() )
350 {
351 Set<AttributeType> descendants = entry.getValue();
352
353 if ( descendants != null )
354 {
355 descendants.clear();
356 }
357 }
358
359 oidToDescendantSet.clear();
360 }
361 }