001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.server.core.schema.registries.synchronizers;
021
022
023 import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
024 import org.apache.directory.server.i18n.I18n;
025 import org.apache.directory.shared.ldap.constants.MetaSchemaConstants;
026 import org.apache.directory.shared.ldap.constants.SchemaConstants;
027 import org.apache.directory.shared.ldap.entry.ServerEntry;
028 import org.apache.directory.shared.ldap.exception.LdapUnwillingToPerformException;
029 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
030 import org.apache.directory.shared.ldap.name.DN;
031 import org.apache.directory.shared.ldap.name.RDN;
032 import org.apache.directory.shared.ldap.schema.AttributeType;
033 import org.apache.directory.shared.ldap.schema.SchemaManager;
034 import org.apache.directory.shared.ldap.schema.registries.Schema;
035 import org.apache.directory.shared.ldap.util.StringTools;
036 import org.slf4j.Logger;
037 import org.slf4j.LoggerFactory;
038
039
040 /**
041 * A handler for operations performed to add, delete, modify, rename and
042 * move schema normalizers.
043 *
044 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
045 * @version $Rev$, $Date$
046 */
047 public class AttributeTypeSynchronizer extends AbstractRegistrySynchronizer
048 {
049 /** A logger for this class */
050 private static final Logger LOG = LoggerFactory.getLogger( AttributeTypeSynchronizer.class );
051
052
053 /**
054 * Creates a new instance of AttributeTypeSynchronizer.
055 *
056 * @param schemaManager The global schemaManager
057 * @throws Exception If the initialization failed
058 */
059 public AttributeTypeSynchronizer( SchemaManager schemaManager ) throws Exception
060 {
061 super( schemaManager );
062 }
063
064
065 /**
066 * {@inheritDoc}
067 */
068 public void add( ServerEntry entry ) throws Exception
069 {
070 DN dn = entry.getDn();
071 DN parentDn = ( DN ) dn.clone();
072 parentDn.remove( parentDn.size() - 1 );
073
074 // The parent DN must be ou=attributetypes,cn=<schemaName>,ou=schema
075 checkParent( parentDn, schemaManager, SchemaConstants.ATTRIBUTE_TYPE );
076
077 // The new schemaObject's OID must not already exist
078 checkOidIsUnique( entry );
079
080 // Build the new AttributeType from the given entry
081 String schemaName = getSchemaName( dn );
082
083 AttributeType attributeType = factory.getAttributeType( schemaManager, entry, schemaManager.getRegistries(),
084 schemaName );
085
086 // At this point, the constructed AttributeType has not been checked against the
087 // existing Registries. It may be broken (missing SUP, or such), it will be checked
088 // there, if the schema and the AttributeType are both enabled.
089 Schema schema = schemaManager.getLoadedSchema( schemaName );
090
091 if ( schema.isEnabled() && attributeType.isEnabled() )
092 {
093 if ( schemaManager.add( attributeType ) )
094 {
095 LOG.debug( "Added {} into the enabled schema {}", dn.getName(), schemaName );
096 }
097 else
098 {
099 // We have some error : reject the addition and get out
100 String msg = I18n.err( I18n.ERR_345, entry.getDn().getName(), StringTools.listToString( schemaManager.getErrors() ) );
101 LOG.info( msg );
102 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
103 }
104 }
105 else
106 {
107 LOG.debug( "The AttributeType {} cannot be added in the disabled schema {}.", attributeType, schemaName );
108 }
109 }
110
111
112 /**
113 * {@inheritDoc}
114 */
115 public boolean modify( ModifyOperationContext opContext, ServerEntry targetEntry, boolean cascade )
116 throws Exception
117 {
118 DN name = opContext.getDn();
119 ServerEntry entry = opContext.getEntry();
120 String schemaName = getSchemaName( name );
121 String oid = getOid( entry );
122 AttributeType at = factory.getAttributeType( schemaManager, targetEntry, schemaManager.getRegistries(),
123 schemaName );
124
125 if ( isSchemaEnabled( schemaName ) )
126 {
127 if ( schemaManager.getAttributeTypeRegistry().contains( oid ) )
128 {
129 schemaManager.unregisterAttributeType( oid );
130 }
131
132 schemaManager.add( at );
133
134 return SCHEMA_MODIFIED;
135 }
136
137 return SCHEMA_UNCHANGED;
138 }
139
140
141 /**
142 * {@inheritDoc}
143 */
144 public void delete( ServerEntry entry, boolean cascade ) throws Exception
145 {
146 DN dn = entry.getDn();
147 DN parentDn = ( DN ) dn.clone();
148 parentDn.remove( parentDn.size() - 1 );
149
150 // The parent DN must be ou=attributetypes,cn=<schemaName>,ou=schema
151 checkParent( parentDn, schemaManager, SchemaConstants.ATTRIBUTE_TYPE );
152
153 // Get the SchemaName
154 String schemaName = getSchemaName( entry.getDn() );
155
156 // Get the schema
157 Schema schema = schemaManager.getLoadedSchema( schemaName );
158
159 if ( schema.isDisabled() )
160 {
161 // The schema is disabled, nothing to do.
162 LOG.debug( "The AttributeType {} cannot be removed from the disabled schema {}.",
163 dn.getName(), schemaName );
164
165 return;
166 }
167
168 // Test that the Oid exists
169 AttributeType attributeType = ( AttributeType ) checkOidExists( entry );
170
171 if ( schema.isEnabled() && attributeType.isEnabled() )
172 {
173 if ( schemaManager.delete( attributeType ) )
174 {
175 LOG.debug( "Removed {} from the schema {}", attributeType, schemaName );
176 }
177 else
178 {
179 // We have some error : reject the deletion and get out
180 String msg = I18n.err( I18n.ERR_346, entry.getDn().getName(),
181 StringTools.listToString( schemaManager.getErrors() ) );
182 LOG.info( msg );
183 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
184 }
185 }
186 else
187 {
188 LOG.debug( "Removed {} from the disabled schema {}", attributeType, schemaName );
189 }
190 }
191
192
193 /**
194 * {@inheritDoc}
195 */
196 public void rename( ServerEntry entry, RDN newRdn, boolean cascade ) throws Exception
197 {
198 String schemaName = getSchemaName( entry.getDn() );
199 AttributeType oldAt = factory
200 .getAttributeType( schemaManager, entry, schemaManager.getRegistries(), schemaName );
201
202 // Inject the new OID
203 ServerEntry targetEntry = ( ServerEntry ) entry.clone();
204 String newOid = ( String ) newRdn.getNormValue();
205 checkOidIsUnique( newOid );
206 targetEntry.put( MetaSchemaConstants.M_OID_AT, newOid );
207
208 // Inject the new DN
209 DN newDn = new DN( targetEntry.getDn() );
210 newDn.remove( newDn.size() - 1 );
211 newDn.add( newRdn );
212 targetEntry.setDn( newDn );
213
214 AttributeType at = factory.getAttributeType( schemaManager, targetEntry, schemaManager.getRegistries(),
215 schemaName );
216
217 if ( isSchemaEnabled( schemaName ) )
218 {
219 // Check that the entry has no descendant
220 if ( schemaManager.getAttributeTypeRegistry().hasDescendants( oldAt.getOid() ) )
221 {
222 String msg = I18n.err( I18n.ERR_347, entry.getDn().getName(), newDn );
223
224 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
225 }
226
227 schemaManager.unregisterAttributeType( oldAt.getOid() );
228 schemaManager.add( at );
229 }
230 else
231 {
232 unregisterOids( oldAt );
233 registerOids( at );
234 }
235 }
236
237
238 public void moveAndRename( DN oriChildName, DN newParentName, RDN newRn, boolean deleteOldRn,
239 ServerEntry entry, boolean cascade ) throws Exception
240 {
241 checkParent( newParentName, schemaManager, SchemaConstants.ATTRIBUTE_TYPE );
242 String oldSchemaName = getSchemaName( oriChildName );
243 String newSchemaName = getSchemaName( newParentName );
244 AttributeType oldAt = factory.getAttributeType( schemaManager, entry, schemaManager.getRegistries(),
245 oldSchemaName );
246 ServerEntry targetEntry = ( ServerEntry ) entry.clone();
247 String newOid = ( String ) newRn.getNormValue();
248 targetEntry.put( MetaSchemaConstants.M_OID_AT, newOid );
249 checkOidIsUnique( newOid );
250 AttributeType newAt = factory.getAttributeType( schemaManager, targetEntry, schemaManager.getRegistries(),
251 newSchemaName );
252
253 if ( !isSchemaLoaded( oldSchemaName ) )
254 {
255 String msg = I18n.err( I18n.ERR_348, oldSchemaName );
256 LOG.warn( msg );
257 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
258 }
259
260 if ( !isSchemaLoaded( newSchemaName ) )
261 {
262 String msg = I18n.err( I18n.ERR_349, newSchemaName );
263 LOG.warn( msg );
264 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
265 }
266
267 deleteFromSchema( oldAt, oldSchemaName );
268 addToSchema( newAt, newSchemaName );
269
270 if ( isSchemaEnabled( oldSchemaName ) )
271 {
272 schemaManager.unregisterAttributeType( oldAt.getOid() );
273 }
274 else
275 {
276 unregisterOids( oldAt );
277 }
278
279 if ( isSchemaEnabled( newSchemaName ) )
280 {
281 schemaManager.add( newAt );
282 }
283 else
284 {
285 registerOids( newAt );
286 }
287 }
288
289
290 public void move( DN oriChildName, DN newParentName, ServerEntry entry, boolean cascade ) throws Exception
291 {
292 checkParent( newParentName, schemaManager, SchemaConstants.ATTRIBUTE_TYPE );
293 String oldSchemaName = getSchemaName( oriChildName );
294 String newSchemaName = getSchemaName( newParentName );
295 AttributeType oldAt = factory.getAttributeType( schemaManager, entry, schemaManager.getRegistries(),
296 oldSchemaName );
297 AttributeType newAt = factory.getAttributeType( schemaManager, entry, schemaManager.getRegistries(),
298 newSchemaName );
299
300 if ( !isSchemaLoaded( oldSchemaName ) )
301 {
302 String msg = "Cannot move a schemaObject from a not loaded schema " + oldSchemaName;
303 LOG.warn( msg );
304 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
305 }
306
307 if ( !isSchemaLoaded( newSchemaName ) )
308 {
309 String msg = I18n.err( I18n.ERR_349, newSchemaName );
310 LOG.warn( msg );
311 throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, msg );
312 }
313
314 deleteFromSchema( oldAt, oldSchemaName );
315 addToSchema( newAt, newSchemaName );
316
317 if ( isSchemaEnabled( oldSchemaName ) )
318 {
319 schemaManager.unregisterAttributeType( oldAt.getOid() );
320 }
321 else
322 {
323 unregisterOids( oldAt );
324 }
325
326 if ( isSchemaEnabled( newSchemaName ) )
327 {
328 schemaManager.add( newAt );
329 }
330 else
331 {
332 registerOids( newAt );
333 }
334 }
335 }