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.MatchingRuleRegistry;
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.MatchingRule;
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 MetaMatchingRuleHandler extends AbstractSchemaChangeHandler
49  {
50      private final SchemaPartitionDao dao;
51      private final MatchingRuleRegistry matchingRuleRegistry;
52  
53      
54      public MetaMatchingRuleHandler( Registries targetRegistries, PartitionSchemaLoader loader, SchemaPartitionDao dao ) 
55          throws Exception
56      {
57          super( targetRegistries, loader );
58          
59          this.dao = dao;
60          this.matchingRuleRegistry = targetRegistries.getMatchingRuleRegistry();
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          MatchingRule mr = factory.getMatchingRule( targetEntry, targetRegistries, schema.getSchemaName() );
70          
71          if ( ! schema.isDisabled() )
72          {
73              matchingRuleRegistry.unregister( oid );
74              matchingRuleRegistry.register( mr );
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          MatchingRule mr = factory.getMatchingRule( entry, targetRegistries, schemaName );
88          add( mr );
89      }
90  
91  
92      public void delete( LdapDN name, ServerEntry entry, boolean cascade ) throws Exception
93      {
94          String schemaName = getSchemaName( name );
95          MatchingRule mr = factory.getMatchingRule( entry, targetRegistries, schemaName );
96          Set<ServerEntry> dependees = dao.listMatchingRuleDependents( mr );
97          
98          if ( dependees != null && dependees.size() > 0 )
99          {
100             throw new LdapOperationNotSupportedException( "The matchingRule with OID " + mr.getOid() 
101                 + " cannot be deleted until all entities" 
102                 + " using this matchingRule have also been deleted.  The following dependees exist: " 
103                 + getOids( dependees ), 
104                 ResultCodeEnum.UNWILLING_TO_PERFORM );
105         }
106         
107         delete( mr, cascade );
108     }
109 
110 
111     public void delete( MatchingRule mr, boolean cascade ) throws Exception
112     {
113         Schema schema = loader.getSchema( mr.getSchema() );
114         if ( ! schema.isDisabled() )
115         {
116             matchingRuleRegistry.unregister( mr.getOid() );
117         }
118         unregisterOids( mr.getOid() );
119     }
120 
121     
122     public void rename( LdapDN name, ServerEntry entry, Rdn newRdn, boolean cascade ) throws Exception
123     {
124         Schema schema = getSchema( name );
125         MatchingRule oldMr = factory.getMatchingRule( entry, targetRegistries, schema.getSchemaName() );
126         Set<ServerEntry> dependees = dao.listMatchingRuleDependents( oldMr );
127         
128         if ( dependees != null && dependees.size() > 0 )
129         {
130             throw new LdapOperationNotSupportedException( "The matchingRule with OID " + oldMr.getOid()
131                 + " cannot be deleted until all entities" 
132                 + " using this matchingRule have also been deleted.  The following dependees exist: " 
133                 + getOids( dependees ), 
134                 ResultCodeEnum.UNWILLING_TO_PERFORM );
135         }
136 
137         ServerEntry targetEntry = ( ServerEntry ) entry.clone();
138         String newOid = ( String ) newRdn.getValue();
139         checkOidIsUnique( newOid );
140         
141         targetEntry.put( MetaSchemaConstants.M_OID_AT, newOid );
142         MatchingRule mr = factory.getMatchingRule( targetEntry, targetRegistries, schema.getSchemaName() );
143 
144         if ( ! schema.isDisabled() )
145         {
146             matchingRuleRegistry.unregister( oldMr.getOid() );
147             matchingRuleRegistry.register( mr );
148         }
149         else
150         {
151             registerOids( mr );
152         }
153 
154         unregisterOids( oldMr.getOid() );
155     }
156 
157 
158     public void move( LdapDN oriChildName, LdapDN newParentName, Rdn newRdn, boolean deleteOldRn, 
159         ServerEntry entry, boolean cascade ) throws Exception
160     {
161         checkNewParent( newParentName );
162         Schema oldSchema = getSchema( oriChildName );
163         MatchingRule oldMr = factory.getMatchingRule( entry, targetRegistries, oldSchema.getSchemaName() );
164         Set<ServerEntry> dependees = dao.listMatchingRuleDependents( oldMr );
165         
166         if ( dependees != null && dependees.size() > 0 )
167         {
168             throw new LdapOperationNotSupportedException( "The matchingRule with OID " + oldMr.getOid()
169                 + " cannot be deleted until all entities" 
170                 + " using this matchingRule have also been deleted.  The following dependees exist: " 
171                 + getOids( dependees ), 
172                 ResultCodeEnum.UNWILLING_TO_PERFORM );
173         }
174 
175         Schema newSchema = getSchema( newParentName );
176         ServerEntry targetEntry = ( ServerEntry ) entry.clone();
177         String newOid = ( String ) newRdn.getValue();
178         checkOidIsUnique( newOid );
179         
180         targetEntry.put( MetaSchemaConstants.M_OID_AT, newOid );
181         MatchingRule mr = factory.getMatchingRule( targetEntry, targetRegistries, newSchema.getSchemaName() );
182 
183         if ( ! oldSchema.isDisabled() )
184         {
185             matchingRuleRegistry.unregister( oldMr.getOid() );
186         }
187         unregisterOids( oldMr.getOid() );
188 
189         if ( ! newSchema.isDisabled() )
190         {
191             matchingRuleRegistry.register( mr );
192         }
193         else
194         {
195             registerOids( mr );
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         MatchingRule oldMr = factory.getMatchingRule( entry, targetRegistries, oldSchema.getSchemaName() );
206         Set<ServerEntry> dependees = dao.listMatchingRuleDependents( oldMr );
207         
208         if ( dependees != null && dependees.size() > 0 )
209         {
210             throw new LdapOperationNotSupportedException( "The matchingRule with OID " + oldMr.getOid() 
211                 + " cannot be deleted until all entities" 
212                 + " using this matchingRule have also been deleted.  The following dependees exist: " 
213                 + getOids( dependees ), 
214                 ResultCodeEnum.UNWILLING_TO_PERFORM );
215         }
216 
217         Schema newSchema = getSchema( newParentName );
218         MatchingRule mr = factory.getMatchingRule( entry, targetRegistries, newSchema.getSchemaName() );
219         
220         if ( ! oldSchema.isDisabled() )
221         {
222             matchingRuleRegistry.unregister( oldMr.getOid() );
223         }
224         
225         if ( ! newSchema.isDisabled() )
226         {
227             matchingRuleRegistry.register( mr );
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 matchingRule 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 matchingRule should be an organizationalUnit.", 
245                 ResultCodeEnum.NAMING_VIOLATION );
246         }
247         
248         if ( ! ( ( String ) rdn.getValue() ).equalsIgnoreCase( SchemaConstants.MATCHING_RULES_AT ) )
249         {
250             throw new LdapInvalidNameException( 
251                 "The parent entry of a syntax should have a relative name of ou=matchingRules.", 
252                 ResultCodeEnum.NAMING_VIOLATION );
253         }
254     }
255 
256 
257     public void add( MatchingRule mr ) throws Exception
258     {
259         Schema schema = loader.getSchema( mr.getSchema() );
260         
261         if ( ! schema.isDisabled() )
262         {
263             matchingRuleRegistry.register( mr );
264         }
265         else
266         {
267             registerOids( mr );
268         }
269     }
270 }