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 org.apache.directory.api.ldap.model.constants.MetaSchemaConstants;
24  import org.apache.directory.api.ldap.model.constants.SchemaConstants;
25  import org.apache.directory.api.ldap.model.entry.DefaultEntry;
26  import org.apache.directory.api.ldap.model.entry.Entry;
27  import org.apache.directory.api.ldap.model.exception.LdapException;
28  import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
29  import org.apache.directory.api.ldap.model.name.Dn;
30  import org.apache.directory.api.ldap.model.schema.AttributeType;
31  import org.apache.directory.api.ldap.model.schema.AttributesFactory;
32  import org.apache.directory.api.ldap.model.schema.DitContentRule;
33  import org.apache.directory.api.ldap.model.schema.DitStructureRule;
34  import org.apache.directory.api.ldap.model.schema.LdapSyntax;
35  import org.apache.directory.api.ldap.model.schema.MatchingRule;
36  import org.apache.directory.api.ldap.model.schema.MatchingRuleUse;
37  import org.apache.directory.api.ldap.model.schema.NameForm;
38  import org.apache.directory.api.ldap.model.schema.ObjectClass;
39  import org.apache.directory.api.ldap.model.schema.SchemaManager;
40  import org.apache.directory.api.ldap.model.schema.SchemaObject;
41  import org.apache.directory.api.ldap.model.schema.parsers.LdapComparatorDescription;
42  import org.apache.directory.api.ldap.model.schema.parsers.NormalizerDescription;
43  import org.apache.directory.api.ldap.model.schema.parsers.SyntaxCheckerDescription;
44  import org.apache.directory.api.ldap.model.schema.registries.Schema;
45  import org.apache.directory.api.util.Base64;
46  import org.apache.directory.server.core.api.DnFactory;
47  import org.apache.directory.server.core.api.interceptor.Interceptor;
48  import org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
49  import org.apache.directory.server.core.api.interceptor.context.DeleteOperationContext;
50  import org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext;
51  import org.apache.directory.server.core.api.partition.Partition;
52  
53  
54  /**
55   * Responsible for translating modify operations on the subschemaSubentry into
56   * operations against entries within the schema partition.
57   *
58   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
59   */
60  public class SchemaSubentryModifier
61  {
62      private AttributesFactory factory = new AttributesFactory();
63  
64      /** The server schemaManager */
65      private SchemaManager schemaManager;
66  
67      /** The Dn factory */
68      private DnFactory dnFactory;
69  
70  
71      /**
72       * 
73       * Creates a new instance of SchemaSubentryModifier.
74       *
75       * @param schemaManager The server schemaManager
76       * @param dnFactory The Dn factory
77       */
78      public SchemaSubentryModifier( SchemaManager schemaManager, DnFactory dnFactory )
79      {
80          this.schemaManager = schemaManager;
81          this.dnFactory = dnFactory;
82      }
83  
84  
85      private Dn getDn( SchemaObject obj ) throws LdapInvalidDnException
86      {
87          StringBuilder buf = new StringBuilder();
88          buf.append( "m-oid=" ).append( obj.getOid() ).append( ",ou=" );
89  
90          if ( obj instanceof LdapSyntax )
91          {
92              buf.append( SchemaConstants.SYNTAXES );
93          }
94          else if ( obj instanceof MatchingRule )
95          {
96              buf.append( SchemaConstants.MATCHING_RULES_AT );
97          }
98          else if ( obj instanceof AttributeType )
99          {
100             buf.append( SchemaConstants.ATTRIBUTE_TYPES_AT );
101         }
102         else if ( obj instanceof ObjectClass )
103         {
104             buf.append( SchemaConstants.OBJECT_CLASSES_AT );
105         }
106         else if ( obj instanceof MatchingRuleUse )
107         {
108             buf.append( SchemaConstants.MATCHING_RULE_USE_AT );
109         }
110         else if ( obj instanceof DitStructureRule )
111         {
112             buf.append( SchemaConstants.DIT_STRUCTURE_RULES_AT );
113         }
114         else if ( obj instanceof DitContentRule )
115         {
116             buf.append( SchemaConstants.DIT_CONTENT_RULES_AT );
117         }
118         else if ( obj instanceof NameForm )
119         {
120             buf.append( SchemaConstants.NAME_FORMS_AT );
121         }
122 
123         buf.append( ",cn=" ).append( obj.getSchemaName() ).append( ",ou=schema" );
124         return dnFactory.create( buf.toString() );
125     }
126 
127 
128     public void add( Interceptor nextInterceptor, int position, ModifyOperationContext modifyContext,
129         LdapComparatorDescription comparatorDescription ) throws LdapException
130     {
131         String schemaName = getSchema( comparatorDescription );
132         Dn dn = dnFactory.create(
133             "m-oid=" + comparatorDescription.getOid(),
134             SchemaConstants.COMPARATORS_PATH,
135             "cn=" + schemaName,
136             SchemaConstants.OU_SCHEMA );
137 
138         Entry entry = getEntry( dn, comparatorDescription );
139         
140         Partition partition = modifyContext.getSession().getDirectoryService().getPartitionNexus().getPartition( dn );
141 
142         AddOperationContextterceptor/context/AddOperationContext.html#AddOperationContext">AddOperationContext addContext = new AddOperationContext( modifyContext.getSession(), entry );
143         addContext.setCurrentInterceptor( position );
144         addContext.setPartition( partition );
145         addContext.setTransaction( modifyContext.getTransaction() );
146 
147         nextInterceptor.add( addContext );
148     }
149 
150 
151     public void add( Interceptor nextInterceptor, int position, ModifyOperationContext modifyContext,
152         NormalizerDescription normalizerDescription ) throws LdapException
153     {
154         String schemaName = getSchema( normalizerDescription );
155         Dn dn = dnFactory.create(
156             "m-oid=" + normalizerDescription.getOid(),
157             SchemaConstants.NORMALIZERS_PATH,
158             "cn=" + schemaName,
159             SchemaConstants.OU_SCHEMA );
160 
161         Entry entry = getEntry( dn, normalizerDescription );
162 
163         Partition partition = modifyContext.getSession().getDirectoryService().getPartitionNexus().getPartition( dn );
164 
165         AddOperationContextterceptor/context/AddOperationContext.html#AddOperationContext">AddOperationContext addContext = new AddOperationContext( modifyContext.getSession(), entry );
166         addContext.setCurrentInterceptor( position );
167         addContext.setPartition( partition );
168         addContext.setTransaction( modifyContext.getTransaction() );
169 
170         nextInterceptor.add( addContext );
171     }
172 
173 
174     public void add( Interceptor nextInterceptor, int position, ModifyOperationContext modifyContext,
175         SyntaxCheckerDescription syntaxCheckerDescription ) throws LdapException
176     {
177         String schemaName = getSchema( syntaxCheckerDescription );
178         Dn dn = dnFactory.create(
179             "m-oid=" + syntaxCheckerDescription.getOid(),
180             SchemaConstants.SYNTAX_CHECKERS_PATH,
181             "cn=" + schemaName,
182             SchemaConstants.OU_SCHEMA );
183 
184         Entry entry = getEntry( dn, syntaxCheckerDescription );
185 
186         Partition partition = modifyContext.getSession().getDirectoryService().getPartitionNexus().getPartition( dn );
187 
188         AddOperationContextterceptor/context/AddOperationContext.html#AddOperationContext">AddOperationContext addContext = new AddOperationContext( modifyContext.getSession(), entry );
189         addContext.setCurrentInterceptor( position );
190         addContext.setPartition( partition );
191         addContext.setTransaction( modifyContext.getTransaction() );
192 
193         nextInterceptor.add( addContext );
194     }
195 
196 
197     public void addSchemaObject( Interceptor nextInterceptor, int position, ModifyOperationContext modifyContext,
198         SchemaObject obj ) throws LdapException
199     {
200         Schema schema = schemaManager.getLoadedSchema( obj.getSchemaName() );
201         Dn dn = getDn( obj );
202         Entry entry = factory.getAttributes( obj, schema, schemaManager );
203         entry.setDn( dn );
204 
205         Partition partition = modifyContext.getSession().getDirectoryService().getPartitionNexus().getPartition( dn );
206 
207         AddOperationContextterceptor/context/AddOperationContext.html#AddOperationContext">AddOperationContext addContext = new AddOperationContext( modifyContext.getSession(), entry );
208         addContext.setCurrentInterceptor( position );
209         addContext.setPartition( partition );
210         addContext.setTransaction( modifyContext.getTransaction() );
211 
212         nextInterceptor.add( addContext );
213     }
214 
215 
216     public void deleteSchemaObject( Interceptor nextInterceptor, int position, ModifyOperationContext modifyContext,
217         SchemaObject obj ) throws LdapException
218     {
219         Dn dn = getDn( obj );
220 
221         Partition partition = modifyContext.getSession().getDirectoryService().getPartitionNexus().getPartition( dn );
222 
223         DeleteOperationContexttor/context/DeleteOperationContext.html#DeleteOperationContext">DeleteOperationContext deleteContext = new DeleteOperationContext( modifyContext.getSession(), dn );
224         deleteContext.setEntry( modifyContext.getSession().lookup( dn ) );
225         deleteContext.setCurrentInterceptor( position );
226         deleteContext.setPartition( partition );
227         deleteContext.setTransaction( modifyContext.getTransaction() );
228 
229         nextInterceptor.delete( deleteContext );
230     }
231 
232 
233     public void delete( Interceptor nextInterceptor, int position, ModifyOperationContext modifyContext,
234         NormalizerDescription normalizerDescription ) throws LdapException
235     {
236         String schemaName = getSchema( normalizerDescription );
237         Dn dn = dnFactory.create(
238             "m-oid=" + normalizerDescription.getOid(),
239             SchemaConstants.NORMALIZERS_PATH,
240             "cn=" + schemaName,
241             SchemaConstants.OU_SCHEMA );
242 
243         Partition partition = modifyContext.getSession().getDirectoryService().getPartitionNexus().getPartition( dn );
244 
245         DeleteOperationContexttor/context/DeleteOperationContext.html#DeleteOperationContext">DeleteOperationContext deleteContext = new DeleteOperationContext( modifyContext.getSession(), dn );
246         deleteContext.setEntry( modifyContext.getSession().lookup( dn ) );
247         deleteContext.setCurrentInterceptor( position );
248         deleteContext.setPartition( partition );
249         deleteContext.setTransaction( modifyContext.getTransaction() );
250 
251         nextInterceptor.delete( deleteContext );
252     }
253 
254 
255     public void delete( Interceptor nextInterceptor, int position, ModifyOperationContext modifyContext,
256         SyntaxCheckerDescription syntaxCheckerDescription ) throws LdapException
257     {
258         String schemaName = getSchema( syntaxCheckerDescription );
259         Dn dn = dnFactory.create(
260             "m-oid=" + syntaxCheckerDescription.getOid(),
261             SchemaConstants.SYNTAX_CHECKERS_PATH,
262             "cn=" + schemaName,
263             SchemaConstants.OU_SCHEMA );
264 
265         Partition partition = modifyContext.getSession().getDirectoryService().getPartitionNexus().getPartition( dn );
266 
267         DeleteOperationContexttor/context/DeleteOperationContext.html#DeleteOperationContext">DeleteOperationContext deleteContext = new DeleteOperationContext( modifyContext.getSession(), dn );
268         deleteContext.setEntry( modifyContext.getSession().lookup( dn ) );
269         deleteContext.setCurrentInterceptor( position );
270         deleteContext.setPartition( partition );
271         deleteContext.setTransaction( modifyContext.getTransaction() );
272 
273         nextInterceptor.delete( deleteContext );
274     }
275 
276 
277     public void delete( Interceptor nextInterceptor, int position, ModifyOperationContext modifyContext,
278         LdapComparatorDescription comparatorDescription ) throws LdapException
279     {
280         String schemaName = getSchema( comparatorDescription );
281         Dn dn = dnFactory.create(
282             "m-oid=" + comparatorDescription.getOid(),
283             SchemaConstants.COMPARATORS_PATH,
284             "cn=" + schemaName,
285             SchemaConstants.OU_SCHEMA );
286 
287         Partition partition = modifyContext.getSession().getDirectoryService().getPartitionNexus().getPartition( dn );
288 
289         DeleteOperationContexttor/context/DeleteOperationContext.html#DeleteOperationContext">DeleteOperationContext deleteContext = new DeleteOperationContext( modifyContext.getSession(), dn );
290         deleteContext.setEntry( modifyContext.getSession().lookup( dn ) );
291         deleteContext.setCurrentInterceptor( position );
292         deleteContext.setPartition( partition );
293         deleteContext.setTransaction( modifyContext.getTransaction() );
294 
295         nextInterceptor.delete( deleteContext );
296     }
297 
298 
299     private Entry getEntry( Dn dn, LdapComparatorDescription comparatorDescription )
300     {
301         Entry entry = new DefaultEntry( schemaManager, dn );
302 
303         entry.put( SchemaConstants.OBJECT_CLASS_AT,
304             SchemaConstants.TOP_OC,
305             MetaSchemaConstants.META_TOP_OC,
306             MetaSchemaConstants.META_COMPARATOR_OC );
307 
308         entry.put( MetaSchemaConstants.M_OID_AT, comparatorDescription.getOid() );
309         entry.put( MetaSchemaConstants.M_FQCN_AT, comparatorDescription.getFqcn() );
310 
311         if ( comparatorDescription.getBytecode() != null )
312         {
313             entry.put( MetaSchemaConstants.M_BYTECODE_AT,
314                 Base64.decode( comparatorDescription.getBytecode().toCharArray() ) );
315         }
316 
317         if ( comparatorDescription.getDescription() != null )
318         {
319             entry.put( MetaSchemaConstants.M_DESCRIPTION_AT, comparatorDescription.getDescription() );
320         }
321 
322         return entry;
323     }
324 
325 
326     private Entry getEntry( Dn dn, NormalizerDescription normalizerDescription )
327     {
328         Entry entry = new DefaultEntry( schemaManager, dn );
329 
330         entry.put( SchemaConstants.OBJECT_CLASS_AT,
331             SchemaConstants.TOP_OC,
332             MetaSchemaConstants.META_TOP_OC,
333             MetaSchemaConstants.META_NORMALIZER_OC );
334 
335         entry.put( MetaSchemaConstants.M_OID_AT, normalizerDescription.getOid() );
336         entry.put( MetaSchemaConstants.M_FQCN_AT, normalizerDescription.getFqcn() );
337 
338         if ( normalizerDescription.getBytecode() != null )
339         {
340             entry.put( MetaSchemaConstants.M_BYTECODE_AT,
341                 Base64.decode( normalizerDescription.getBytecode().toCharArray() ) );
342         }
343 
344         if ( normalizerDescription.getDescription() != null )
345         {
346             entry.put( MetaSchemaConstants.M_DESCRIPTION_AT, normalizerDescription.getDescription() );
347         }
348 
349         return entry;
350     }
351 
352 
353     private String getSchema( SchemaObject desc )
354     {
355         if ( desc.getExtensions().containsKey( MetaSchemaConstants.X_SCHEMA_AT ) )
356         {
357             return desc.getExtensions().get( MetaSchemaConstants.X_SCHEMA_AT ).get( 0 );
358         }
359 
360         return MetaSchemaConstants.SCHEMA_OTHER;
361     }
362 
363 
364     private Entry getEntry( Dn dn, SyntaxCheckerDescription syntaxCheckerDescription )
365     {
366         Entry entry = new DefaultEntry( schemaManager, dn );
367 
368         entry.put( SchemaConstants.OBJECT_CLASS_AT,
369             SchemaConstants.TOP_OC,
370             MetaSchemaConstants.META_TOP_OC,
371             MetaSchemaConstants.META_SYNTAX_CHECKER_OC );
372 
373         entry.put( MetaSchemaConstants.M_OID_AT, syntaxCheckerDescription.getOid() );
374         entry.put( MetaSchemaConstants.M_FQCN_AT, syntaxCheckerDescription.getFqcn() );
375 
376         if ( syntaxCheckerDescription.getBytecode() != null )
377         {
378             entry.put( MetaSchemaConstants.M_BYTECODE_AT,
379                 Base64.decode( syntaxCheckerDescription.getBytecode().toCharArray() ) );
380         }
381 
382         if ( syntaxCheckerDescription.getDescription() != null )
383         {
384             entry.put( MetaSchemaConstants.M_DESCRIPTION_AT, syntaxCheckerDescription.getDescription() );
385         }
386 
387         return entry;
388     }
389 }