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.schema;
21
22
23 import java.util.ArrayList;
24 import java.util.Comparator;
25 import java.util.List;
26
27 import javax.naming.NamingException;
28
29 import org.apache.directory.server.constants.MetaSchemaConstants;
30 import org.apache.directory.server.core.entry.ServerEntry;
31 import org.apache.directory.server.schema.bootstrap.Schema;
32 import org.apache.directory.server.schema.registries.ComparatorRegistry;
33 import org.apache.directory.server.schema.registries.MatchingRuleRegistry;
34 import org.apache.directory.server.schema.registries.Registries;
35 import org.apache.directory.shared.ldap.constants.SchemaConstants;
36 import org.apache.directory.shared.ldap.entry.EntryAttribute;
37 import org.apache.directory.shared.ldap.exception.LdapInvalidNameException;
38 import org.apache.directory.shared.ldap.exception.LdapNamingException;
39 import org.apache.directory.shared.ldap.exception.LdapOperationNotSupportedException;
40 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
41 import org.apache.directory.shared.ldap.name.LdapDN;
42 import org.apache.directory.shared.ldap.name.Rdn;
43 import org.apache.directory.shared.ldap.schema.AttributeType;
44 import org.apache.directory.shared.ldap.schema.syntax.ComparatorDescription;
45 import org.apache.directory.shared.ldap.util.Base64;
46
47
48
49
50
51
52
53
54
55 public class MetaComparatorHandler extends AbstractSchemaChangeHandler
56 {
57 private final SchemaEntityFactory factory;
58 private final ComparatorRegistry comparatorRegistry;
59 private final MatchingRuleRegistry matchingRuleRegistry;
60 private final AttributeType byteCodeAT;
61 private final AttributeType descAT;
62 private final AttributeType fqcnAT;
63
64
65
66 public MetaComparatorHandler( Registries targetRegistries, PartitionSchemaLoader loader ) throws Exception
67 {
68 super( targetRegistries, loader );
69 this.comparatorRegistry = targetRegistries.getComparatorRegistry();
70 this.matchingRuleRegistry = targetRegistries.getMatchingRuleRegistry();
71 this.factory = new SchemaEntityFactory( targetRegistries );
72 this.byteCodeAT = targetRegistries.getAttributeTypeRegistry().lookup( MetaSchemaConstants.M_BYTECODE_AT );
73 this.descAT = targetRegistries.getAttributeTypeRegistry().lookup( MetaSchemaConstants.M_DESCRIPTION_AT );
74 this.fqcnAT = targetRegistries.getAttributeTypeRegistry().lookup( MetaSchemaConstants.M_FQCN_AT );
75 }
76
77
78 protected void modify( LdapDN name, ServerEntry entry, ServerEntry targetEntry, boolean cascade ) throws Exception
79 {
80 String oid = getOid( entry );
81 Comparator comparator = factory.getComparator( targetEntry, targetRegistries );
82 Schema schema = getSchema( name );
83
84 if ( ! schema.isDisabled() )
85 {
86 comparatorRegistry.unregister( oid );
87 ComparatorDescription description = getComparatorDescription( schema.getSchemaName(), targetEntry );
88 comparatorRegistry.register( description, comparator );
89 }
90 }
91
92
93 private ComparatorDescription getComparatorDescription( String schemaName, ServerEntry entry ) throws Exception
94 {
95 ComparatorDescription description = new ComparatorDescription();
96 description.setNumericOid( getOid( entry ) );
97 List<String> values = new ArrayList<String>();
98 values.add( schemaName );
99 description.addExtension( MetaSchemaConstants.X_SCHEMA, values );
100 description.setFqcn( entry.get( fqcnAT ).getString() );
101
102 EntryAttribute desc = entry.get( descAT );
103
104 if ( desc != null && desc.size() > 0 )
105 {
106 description.setDescription( desc.getString() );
107 }
108
109 EntryAttribute bytecode = entry.get( byteCodeAT );
110
111 if ( bytecode != null && bytecode.size() > 0 )
112 {
113 byte[] bytes = bytecode.getBytes();
114 description.setBytecode( new String( Base64.encode( bytes ) ) );
115 }
116
117 return description;
118 }
119
120
121 public void add( LdapDN name, ServerEntry entry ) throws Exception
122 {
123 LdapDN parentDn = ( LdapDN ) name.clone();
124 parentDn.remove( parentDn.size() - 1 );
125 checkNewParent( parentDn );
126 checkOidIsUniqueForComparator( entry );
127
128 Comparator comparator = factory.getComparator( entry, targetRegistries );
129 Schema schema = getSchema( name );
130
131 if ( ! schema.isDisabled() )
132 {
133 ComparatorDescription comparatorDescription = getComparatorDescription( schema.getSchemaName(), entry );
134 comparatorRegistry.register( comparatorDescription, comparator );
135 }
136 }
137
138
139 public void add( ComparatorDescription comparatorDescription ) throws Exception
140 {
141 Comparator comparator = factory.getComparator( comparatorDescription, targetRegistries );
142 String schemaName = MetaSchemaConstants.SCHEMA_OTHER;
143
144 if ( comparatorDescription.getExtensions().get( MetaSchemaConstants.X_SCHEMA ) != null )
145 {
146 schemaName = comparatorDescription.getExtensions().get( MetaSchemaConstants.X_SCHEMA ).get( 0 );
147 }
148
149 Schema schema = loader.getSchema( schemaName );
150
151 if ( ! schema.isDisabled() )
152 {
153 comparatorRegistry.register( comparatorDescription, comparator );
154 }
155 }
156
157
158 public void delete( LdapDN name, ServerEntry entry, boolean cascade ) throws Exception
159 {
160 String oid = getOid( entry );
161 delete( oid, cascade );
162 }
163
164
165 public void delete( String oid, boolean cascade ) throws NamingException
166 {
167 if ( matchingRuleRegistry.hasMatchingRule( oid ) )
168 {
169 throw new LdapOperationNotSupportedException( "The comparator with OID " + oid
170 + " cannot be deleted until all "
171 + "matchingRules using that comparator have also been deleted.",
172 ResultCodeEnum.UNWILLING_TO_PERFORM );
173 }
174
175 if ( comparatorRegistry.hasComparator( oid ) )
176 {
177 comparatorRegistry.unregister( oid );
178 }
179 }
180
181
182 public void rename( LdapDN name, ServerEntry entry, Rdn newRdn, boolean cascade ) throws Exception
183 {
184 String oldOid = getOid( entry );
185
186 if ( matchingRuleRegistry.hasMatchingRule( oldOid ) )
187 {
188 throw new LdapOperationNotSupportedException( "The comparator with OID " + oldOid
189 + " cannot have it's OID changed until all "
190 + "matchingRules using that comparator have been deleted.",
191 ResultCodeEnum.UNWILLING_TO_PERFORM );
192 }
193
194 String oid = ( String ) newRdn.getValue();
195 checkOidIsUniqueForComparator( oid );
196 Schema schema = getSchema( name );
197
198 if ( ! schema.isDisabled() )
199 {
200 Comparator comparator = factory.getComparator( entry, targetRegistries );
201 comparatorRegistry.unregister( oldOid );
202 ComparatorDescription comparatorDescription = getComparatorDescription( schema.getSchemaName(), entry );
203 comparatorDescription.setNumericOid( oid );
204 comparatorRegistry.register( comparatorDescription, comparator );
205 }
206 }
207
208
209 public void move( LdapDN oriChildName, LdapDN newParentName, Rdn newRdn, boolean deleteOldRn,
210 ServerEntry entry, boolean cascade ) throws Exception
211 {
212 checkNewParent( newParentName );
213 String oldOid = getOid( entry );
214
215 if ( matchingRuleRegistry.hasMatchingRule( oldOid ) )
216 {
217 throw new LdapOperationNotSupportedException( "The comparator with OID " + oldOid
218 + " cannot have it's OID changed until all "
219 + "matchingRules using that comparator have been deleted.",
220 ResultCodeEnum.UNWILLING_TO_PERFORM );
221 }
222
223 String oid = ( String ) newRdn.getValue();
224 checkOidIsUniqueForComparator( oid );
225
226 Schema oldSchema = getSchema( oriChildName );
227 Schema newSchema = getSchema( newParentName );
228
229 Comparator comparator = factory.getComparator( entry, targetRegistries );
230
231 if ( ! oldSchema.isDisabled() )
232 {
233 comparatorRegistry.unregister( oldOid );
234 }
235
236 if ( ! newSchema.isDisabled() )
237 {
238 ComparatorDescription comparatorDescription = getComparatorDescription( newSchema.getSchemaName(), entry );
239 comparatorDescription.setNumericOid( oid );
240 comparatorRegistry.register( comparatorDescription, comparator );
241 }
242 }
243
244
245 public void replace( LdapDN oriChildName, LdapDN newParentName, ServerEntry entry, boolean cascade )
246 throws Exception
247 {
248 checkNewParent( newParentName );
249 String oid = getOid( entry );
250
251 if ( matchingRuleRegistry.hasMatchingRule( oid ) )
252 {
253 throw new LdapOperationNotSupportedException( "The comparator with OID " + oid
254 + " cannot be moved to another schema until all "
255 + "matchingRules using that comparator have been deleted.",
256 ResultCodeEnum.UNWILLING_TO_PERFORM );
257 }
258
259 Schema oldSchema = getSchema( oriChildName );
260 Schema newSchema = getSchema( newParentName );
261
262 Comparator comparator = factory.getComparator( entry, targetRegistries );
263
264 if ( ! oldSchema.isDisabled() )
265 {
266 comparatorRegistry.unregister( oid );
267 }
268
269 if ( ! newSchema.isDisabled() )
270 {
271 ComparatorDescription comparatorDescription = getComparatorDescription( newSchema.getSchemaName(), entry );
272 comparatorRegistry.register( comparatorDescription, comparator );
273 }
274 }
275
276
277 private void checkOidIsUniqueForComparator( String oid ) throws NamingException
278 {
279 if ( super.targetRegistries.getComparatorRegistry().hasComparator( oid ) )
280 {
281 throw new LdapNamingException( "Oid " + oid + " for new schema comparator is not unique.",
282 ResultCodeEnum.OTHER );
283 }
284 }
285
286
287 private void checkOidIsUniqueForComparator( ServerEntry entry ) throws Exception
288 {
289 String oid = getOid( entry );
290
291 if ( super.targetRegistries.getComparatorRegistry().hasComparator( oid ) )
292 {
293 throw new LdapNamingException( "Oid " + oid + " for new schema comparator is not unique.",
294 ResultCodeEnum.OTHER );
295 }
296 }
297
298
299 private void checkNewParent( LdapDN newParent ) throws NamingException
300 {
301 if ( newParent.size() != 3 )
302 {
303 throw new LdapInvalidNameException(
304 "The parent dn of a comparator should be at most 3 name components in length.",
305 ResultCodeEnum.NAMING_VIOLATION );
306 }
307
308 Rdn rdn = newParent.getRdn();
309 if ( ! targetRegistries.getOidRegistry().getOid( rdn.getNormType() ).equals( SchemaConstants.OU_AT_OID ) )
310 {
311 throw new LdapInvalidNameException( "The parent entry of a comparator should be an organizationalUnit.",
312 ResultCodeEnum.NAMING_VIOLATION );
313 }
314
315 if ( ! ( ( String ) rdn.getValue() ).equalsIgnoreCase( SchemaConstants.COMPARATORS_AT ) )
316 {
317 throw new LdapInvalidNameException(
318 "The parent entry of a comparator should have a relative name of ou=comparators.",
319 ResultCodeEnum.NAMING_VIOLATION );
320 }
321 }
322 }