View Javadoc

1   /*
2    *   Licensed to the Apache Software Foundation (ASF) under one
3    *   or more contributor license agreements.  See the NOTICE file
4    *   distributed with this work for additional information
5    *   regarding copyright ownership.  The ASF licenses this file
6    *   to you under the Apache License, Version 2.0 (the
7    *   "License"); you may not use this file except in compliance
8    *   with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing,
13   *   software distributed under the License is distributed on an
14   *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *   KIND, either express or implied.  See the License for the
16   *   specific language governing permissions and limitations
17   *   under the License.
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.AttributeTypeRegistry;
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.AttributeType;
39  
40  
41  /**
42   * A handler for operations peformed to add, delete, modify, rename and 
43   * move schema normalizers.
44   *
45   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
46   * @version $Rev$, $Date$
47   */
48  public class MetaAttributeTypeHandler extends AbstractSchemaChangeHandler
49  {
50      private final SchemaPartitionDao dao;
51      private final AttributeTypeRegistry attributeTypeRegistry;
52  
53      
54  
55      public MetaAttributeTypeHandler( Registries targetRegistries, PartitionSchemaLoader loader, SchemaPartitionDao dao ) 
56          throws Exception
57      {
58          super( targetRegistries, loader );
59          
60          this.dao = dao;
61          this.attributeTypeRegistry = targetRegistries.getAttributeTypeRegistry();
62      }
63  
64  
65      protected void modify( LdapDN name, ServerEntry entry, ServerEntry targetEntry, boolean cascade ) 
66          throws Exception
67      {
68          String oid = getOid( entry );
69          Schema schema = getSchema( name );
70          AttributeType at = factory.getAttributeType( targetEntry, targetRegistries, schema.getSchemaName() );
71          
72          if ( ! schema.isDisabled() )
73          {
74              attributeTypeRegistry.unregister( oid );
75              attributeTypeRegistry.register( at );
76          }
77      }
78      
79      
80      public void add( AttributeType at ) throws Exception
81      {
82          Schema schema = dao.getSchema( at.getSchema() );
83          if ( ! schema.isDisabled() )
84          {
85              attributeTypeRegistry.register( at );
86          }
87          else
88          {
89              registerOids( at );
90          }
91      }
92  
93  
94      public void add( LdapDN name, ServerEntry entry ) throws Exception
95      {
96          LdapDN parentDn = ( LdapDN ) name.clone();
97          parentDn.remove( parentDn.size() - 1 );
98          checkNewParent( parentDn );
99          checkOidIsUnique( entry );
100         
101         Schema schema = getSchema( name );
102         AttributeType at = factory.getAttributeType( entry, targetRegistries, schema.getSchemaName() );
103         add( at );
104     }
105 
106 
107     public void delete( LdapDN name, ServerEntry entry, boolean cascade ) throws Exception
108     {
109         String schemaName = getSchemaName( name );
110         AttributeType at = factory.getAttributeType( entry, targetRegistries, schemaName );
111         Set<ServerEntry> dependees = dao.listAttributeTypeDependents( at );
112         
113         if ( dependees != null && dependees.size() > 0 )
114         {
115             throw new LdapOperationNotSupportedException( "The attributeType with OID " + at.getOid() 
116                 + " cannot be deleted until all entities" 
117                 + " using this attributeType have also been deleted.  The following dependees exist: " 
118                 + getOids( dependees ), 
119                 ResultCodeEnum.UNWILLING_TO_PERFORM );
120         }
121         
122         delete( at, cascade );
123     }
124 
125 
126     public void delete( AttributeType at, boolean cascade ) throws Exception
127     {
128         Schema schema = loader.getSchema( at.getSchema() );
129         if ( ! schema.isDisabled() )
130         {
131             attributeTypeRegistry.unregister( at.getOid() );
132         }
133         unregisterOids( at.getOid() );
134     }
135 
136 
137     public void rename( LdapDN name, ServerEntry entry, Rdn newRdn, boolean cascade ) throws Exception
138     {
139         Schema schema = getSchema( name );
140         AttributeType oldAt = factory.getAttributeType( entry, targetRegistries, schema.getSchemaName() );
141         Set<ServerEntry> dependees = dao.listAttributeTypeDependents( oldAt );
142         
143         if ( dependees != null && dependees.size() > 0 )
144         {
145             throw new LdapOperationNotSupportedException( "The attributeType with OID " + oldAt.getOid()
146                 + " cannot be deleted until all entities" 
147                 + " using this attributeType have also been deleted.  The following dependees exist: " 
148                 + getOids( dependees ), 
149                 ResultCodeEnum.UNWILLING_TO_PERFORM );
150         }
151 
152         ServerEntry targetEntry = ( ServerEntry ) entry.clone();
153         String newOid = ( String ) newRdn.getValue();
154         checkOidIsUnique( newOid );
155         targetEntry.put( MetaSchemaConstants.M_OID_AT, newOid );
156         AttributeType at = factory.getAttributeType( targetEntry, targetRegistries, schema.getSchemaName() );
157 
158         if ( ! schema.isDisabled() )
159         {
160             attributeTypeRegistry.unregister( oldAt.getOid() );
161             attributeTypeRegistry.register( at );
162         }
163         else
164         {
165             registerOids( at );
166         }
167         
168         unregisterOids( oldAt.getOid() );
169     }
170 
171 
172     public void move( LdapDN oriChildName, LdapDN newParentName, Rdn newRn, boolean deleteOldRn,
173         ServerEntry entry, boolean cascade ) throws Exception
174     {
175         checkNewParent( newParentName );
176         Schema oldSchema = getSchema( oriChildName );
177         AttributeType oldAt = factory.getAttributeType( entry, targetRegistries, oldSchema.getSchemaName() );
178         Set<ServerEntry> dependees = dao.listAttributeTypeDependents( oldAt );
179         
180         if ( dependees != null && dependees.size() > 0 )
181         {
182             throw new LdapOperationNotSupportedException( "The attributeType with OID " + oldAt.getOid()
183                 + " cannot be deleted until all entities" 
184                 + " using this attributeType have also been deleted.  The following dependees exist: " 
185                 + getOids( dependees ), 
186                 ResultCodeEnum.UNWILLING_TO_PERFORM );
187         }
188 
189         Schema newSchema = getSchema( newParentName );
190         ServerEntry targetEntry = ( ServerEntry ) entry.clone();
191         String newOid = ( String ) newRn.getValue();
192         targetEntry.put( MetaSchemaConstants.M_OID_AT, newOid );
193         checkOidIsUnique( newOid );
194         AttributeType at = factory.getAttributeType( targetEntry, targetRegistries, newSchema.getSchemaName() );
195 
196         if ( ! oldSchema.isDisabled() )
197         {
198             attributeTypeRegistry.unregister( oldAt.getOid() );
199         }
200         unregisterOids( oldAt.getOid() );
201 
202         if ( ! newSchema.isDisabled() )
203         {
204             attributeTypeRegistry.register( at );
205         }
206         else
207         {
208             registerOids( at );
209         }
210     }
211 
212 
213     public void replace( LdapDN oriChildName, LdapDN newParentName, ServerEntry entry, boolean cascade ) 
214         throws Exception
215     {
216         checkNewParent( newParentName );
217         Schema oldSchema = getSchema( oriChildName );
218         AttributeType oldAt = factory.getAttributeType( entry, targetRegistries, oldSchema.getSchemaName() );
219         Set<ServerEntry> dependees = dao.listAttributeTypeDependents( oldAt );
220         
221         if ( dependees != null && dependees.size() > 0 )
222         {
223             throw new LdapOperationNotSupportedException( "The attributeType with OID " + oldAt.getOid() 
224                 + " cannot be deleted until all entities" 
225                 + " using this attributeType have also been deleted.  The following dependees exist: " 
226                 + getOids( dependees ), 
227                 ResultCodeEnum.UNWILLING_TO_PERFORM );
228         }
229 
230         Schema newSchema = getSchema( newParentName );
231         AttributeType at = factory.getAttributeType( entry, targetRegistries, newSchema.getSchemaName() );
232         
233         if ( ! oldSchema.isDisabled() )
234         {
235             attributeTypeRegistry.unregister( oldAt.getOid() );
236         }
237         
238         if ( ! newSchema.isDisabled() )
239         {
240             attributeTypeRegistry.register( at );
241         }
242     }
243     
244     
245     private void checkNewParent( LdapDN newParent ) throws NamingException
246     {
247         if ( newParent.size() != 3 )
248         {
249             throw new LdapInvalidNameException( 
250                 "The parent dn of a attributeType should be at most 3 name components in length.", 
251                 ResultCodeEnum.NAMING_VIOLATION );
252         }
253         
254         Rdn rdn = newParent.getRdn();
255         if ( ! targetRegistries.getOidRegistry().getOid( rdn.getNormType() ).equals( SchemaConstants.OU_AT_OID ) )
256         {
257             throw new LdapInvalidNameException( "The parent entry of a attributeType should be an organizationalUnit.", 
258                 ResultCodeEnum.NAMING_VIOLATION );
259         }
260         
261         if ( ! ( ( String ) rdn.getValue() ).equalsIgnoreCase( SchemaConstants.ATTRIBUTE_TYPES_AT ) )
262         {
263             throw new LdapInvalidNameException( 
264                 "The parent entry of a attributeType should have a relative name of ou=attributeTypes.", 
265                 ResultCodeEnum.NAMING_VIOLATION );
266         }
267     }
268 }