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.Set;
24
25 import javax.naming.NamingException;
26
27 import org.apache.directory.server.constants.MetaSchemaConstants;
28 import org.apache.directory.server.core.entry.ServerEntry;
29 import org.apache.directory.server.schema.bootstrap.Schema;
30 import org.apache.directory.server.schema.registries.ObjectClassRegistry;
31 import org.apache.directory.server.schema.registries.Registries;
32 import org.apache.directory.shared.ldap.constants.SchemaConstants;
33 import org.apache.directory.shared.ldap.exception.LdapInvalidNameException;
34 import org.apache.directory.shared.ldap.exception.LdapOperationNotSupportedException;
35 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
36 import org.apache.directory.shared.ldap.name.LdapDN;
37 import org.apache.directory.shared.ldap.name.Rdn;
38 import org.apache.directory.shared.ldap.schema.ObjectClass;
39
40
41
42
43
44
45
46
47
48 public class MetaObjectClassHandler extends AbstractSchemaChangeHandler
49 {
50 private final SchemaPartitionDao dao;
51 private final ObjectClassRegistry objectClassRegistry;
52
53
54 public MetaObjectClassHandler( Registries targetRegistries, PartitionSchemaLoader loader, SchemaPartitionDao dao )
55 throws Exception
56 {
57 super( targetRegistries, loader );
58
59 this.dao = dao;
60 this.objectClassRegistry = targetRegistries.getObjectClassRegistry();
61 }
62
63
64 protected void modify( LdapDN name, ServerEntry entry, ServerEntry targetEntry,
65 boolean cascade ) throws Exception
66 {
67 String oid = getOid( entry );
68 Schema schema = getSchema( name );
69 ObjectClass oc = factory.getObjectClass( targetEntry, targetRegistries, schema.getSchemaName() );
70
71 if ( ! schema.isDisabled() )
72 {
73 objectClassRegistry.unregister( oid );
74 objectClassRegistry.register( oc );
75 }
76 }
77
78
79 public void add( LdapDN name, ServerEntry entry ) throws Exception
80 {
81 LdapDN parentDn = ( LdapDN ) name.clone();
82 parentDn.remove( parentDn.size() - 1 );
83 checkNewParent( parentDn );
84 checkOidIsUnique( entry );
85
86 String schemaName = getSchemaName( name );
87 ObjectClass oc = factory.getObjectClass( entry, targetRegistries, schemaName );
88 add( oc );
89 }
90
91
92 public void delete( LdapDN name, ServerEntry entry, boolean cascade ) throws Exception
93 {
94 String schemaName = getSchemaName( name );
95 ObjectClass oc = factory.getObjectClass( entry, targetRegistries, schemaName );
96 Set<ServerEntry> dependees = dao.listObjectClassDependents( oc );
97
98 if ( dependees != null && dependees.size() > 0 )
99 {
100 throw new LdapOperationNotSupportedException( "The objectClass with OID " + oc.getOid()
101 + " cannot be deleted until all entities"
102 + " using this objectClass have also been deleted. The following dependees exist: "
103 + getOids( dependees ),
104 ResultCodeEnum.UNWILLING_TO_PERFORM );
105 }
106
107 delete( oc, cascade );
108 }
109
110
111 public void delete( ObjectClass oc, boolean cascade ) throws Exception
112 {
113 Schema schema = loader.getSchema( oc.getSchema() );
114
115 if ( ! schema.isDisabled() )
116 {
117 objectClassRegistry.unregister( oc.getOid() );
118 }
119
120 unregisterOids( oc.getOid() );
121 }
122
123
124 public void rename( LdapDN name, ServerEntry entry, Rdn newRdn, boolean cascade ) throws Exception
125 {
126 Schema schema = getSchema( name );
127 ObjectClass oldOc = factory.getObjectClass( entry, targetRegistries, schema.getSchemaName() );
128 Set<ServerEntry> dependees = dao.listObjectClassDependents( oldOc );
129
130 if ( dependees != null && dependees.size() > 0 )
131 {
132 throw new LdapOperationNotSupportedException( "The objectClass with OID " + oldOc.getOid()
133 + " cannot be deleted until all entities"
134 + " using this objectClass have also been deleted. The following dependees exist: "
135 + getOids( dependees ),
136 ResultCodeEnum.UNWILLING_TO_PERFORM );
137 }
138
139 ServerEntry targetEntry = ( ServerEntry ) entry.clone();
140 String newOid = ( String ) newRdn.getValue();
141 targetEntry.put( MetaSchemaConstants.M_OID_AT, newOid );
142 checkOidIsUnique( newOid );
143 ObjectClass oc = factory.getObjectClass( targetEntry, targetRegistries, schema.getSchemaName() );
144
145 if ( ! schema.isDisabled() )
146 {
147 objectClassRegistry.unregister( oldOc.getOid() );
148 objectClassRegistry.register( oc );
149 }
150 else
151 {
152 registerOids( oc );
153 }
154
155 unregisterOids( oldOc.getOid() );
156 }
157
158
159 public void move( LdapDN oriChildName, LdapDN newParentName, Rdn newRdn, boolean deleteOldRn,
160 ServerEntry entry, boolean cascade ) throws Exception
161 {
162 checkNewParent( newParentName );
163 Schema oldSchema = getSchema( oriChildName );
164 ObjectClass oldOc = factory.getObjectClass( entry, targetRegistries, oldSchema.getSchemaName() );
165 Set<ServerEntry> dependees = dao.listObjectClassDependents( oldOc );
166
167 if ( dependees != null && dependees.size() > 0 )
168 {
169 throw new LdapOperationNotSupportedException( "The objectClass with OID " + oldOc.getOid()
170 + " cannot be deleted until all entities"
171 + " using this objectClass have also been deleted. The following dependees exist: "
172 + getOids( dependees ),
173 ResultCodeEnum.UNWILLING_TO_PERFORM );
174 }
175
176 Schema newSchema = getSchema( newParentName );
177 ServerEntry targetEntry = ( ServerEntry ) entry.clone();
178 String newOid = ( String ) newRdn.getValue();
179 checkOidIsUnique( newOid );
180 targetEntry.put( MetaSchemaConstants.M_OID_AT, newOid );
181 ObjectClass oc = factory.getObjectClass( targetEntry, targetRegistries, newSchema.getSchemaName() );
182
183 if ( ! oldSchema.isDisabled() )
184 {
185 objectClassRegistry.unregister( oldOc.getOid() );
186 }
187 unregisterOids( oldOc.getOid() );
188
189 if ( ! newSchema.isDisabled() )
190 {
191 objectClassRegistry.register( oc );
192 }
193 else
194 {
195 registerOids( oc );
196 }
197 }
198
199
200 public void replace( LdapDN oriChildName, LdapDN newParentName, ServerEntry entry, boolean cascade )
201 throws Exception
202 {
203 checkNewParent( newParentName );
204 Schema oldSchema = getSchema( oriChildName );
205 ObjectClass oldAt = factory.getObjectClass( entry, targetRegistries, oldSchema.getSchemaName() );
206 Set<ServerEntry> dependees = dao.listObjectClassDependents( oldAt );
207
208 if ( dependees != null && dependees.size() > 0 )
209 {
210 throw new LdapOperationNotSupportedException( "The objectClass with OID " + oldAt.getOid()
211 + " cannot be deleted until all entities"
212 + " using this objectClass have also been deleted. The following dependees exist: "
213 + getOids( dependees ),
214 ResultCodeEnum.UNWILLING_TO_PERFORM );
215 }
216
217 Schema newSchema = getSchema( newParentName );
218 ObjectClass oc = factory.getObjectClass( entry, targetRegistries, newSchema.getSchemaName() );
219
220 if ( ! oldSchema.isDisabled() )
221 {
222 objectClassRegistry.unregister( oldAt.getOid() );
223 }
224
225 if ( ! newSchema.isDisabled() )
226 {
227 objectClassRegistry.register( oc );
228 }
229 }
230
231
232 private void checkNewParent( LdapDN newParent ) throws NamingException
233 {
234 if ( newParent.size() != 3 )
235 {
236 throw new LdapInvalidNameException(
237 "The parent dn of a objectClass should be at most 3 name components in length.",
238 ResultCodeEnum.NAMING_VIOLATION );
239 }
240
241 Rdn rdn = newParent.getRdn();
242 if ( ! targetRegistries.getOidRegistry().getOid( rdn.getNormType() ).equals( SchemaConstants.OU_AT_OID ) )
243 {
244 throw new LdapInvalidNameException( "The parent entry of a objectClass should be an organizationalUnit.",
245 ResultCodeEnum.NAMING_VIOLATION );
246 }
247
248 if ( ! ( ( String ) rdn.getValue() ).equalsIgnoreCase( SchemaConstants.OBJECT_CLASSES_AT ) )
249 {
250 throw new LdapInvalidNameException(
251 "The parent entry of a attributeType should have a relative name of ou=objectClasses.",
252 ResultCodeEnum.NAMING_VIOLATION );
253 }
254 }
255
256
257 public void add( ObjectClass oc ) throws Exception
258 {
259 Schema schema = loader.getSchema( oc.getSchema() );
260 if ( ! schema.isDisabled() )
261 {
262 objectClassRegistry.register( oc );
263 }
264 else
265 {
266 registerOids( oc );
267 }
268 }
269 }