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