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