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 */ 020package org.apache.directory.server.core.schema; 021 022 023import org.apache.directory.api.ldap.model.constants.MetaSchemaConstants; 024import org.apache.directory.api.ldap.model.constants.SchemaConstants; 025import org.apache.directory.api.ldap.model.entry.DefaultEntry; 026import org.apache.directory.api.ldap.model.entry.Entry; 027import org.apache.directory.api.ldap.model.exception.LdapException; 028import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException; 029import org.apache.directory.api.ldap.model.name.Dn; 030import org.apache.directory.api.ldap.model.schema.AttributeType; 031import org.apache.directory.api.ldap.model.schema.AttributesFactory; 032import org.apache.directory.api.ldap.model.schema.DitContentRule; 033import org.apache.directory.api.ldap.model.schema.DitStructureRule; 034import org.apache.directory.api.ldap.model.schema.LdapSyntax; 035import org.apache.directory.api.ldap.model.schema.MatchingRule; 036import org.apache.directory.api.ldap.model.schema.MatchingRuleUse; 037import org.apache.directory.api.ldap.model.schema.NameForm; 038import org.apache.directory.api.ldap.model.schema.ObjectClass; 039import org.apache.directory.api.ldap.model.schema.SchemaManager; 040import org.apache.directory.api.ldap.model.schema.SchemaObject; 041import org.apache.directory.api.ldap.model.schema.parsers.LdapComparatorDescription; 042import org.apache.directory.api.ldap.model.schema.parsers.NormalizerDescription; 043import org.apache.directory.api.ldap.model.schema.parsers.SyntaxCheckerDescription; 044import org.apache.directory.api.ldap.model.schema.registries.Schema; 045import org.apache.directory.api.util.Base64; 046import org.apache.directory.server.core.api.DnFactory; 047import org.apache.directory.server.core.api.interceptor.Interceptor; 048import org.apache.directory.server.core.api.interceptor.context.AddOperationContext; 049import org.apache.directory.server.core.api.interceptor.context.DeleteOperationContext; 050import org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext; 051import org.apache.directory.server.core.api.partition.Partition; 052 053 054/** 055 * Responsible for translating modify operations on the subschemaSubentry into 056 * operations against entries within the schema partition. 057 * 058 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 059 */ 060public class SchemaSubentryModifier 061{ 062 private AttributesFactory factory = new AttributesFactory(); 063 064 /** The server schemaManager */ 065 private SchemaManager schemaManager; 066 067 /** The Dn factory */ 068 private DnFactory dnFactory; 069 070 071 /** 072 * 073 * Creates a new instance of SchemaSubentryModifier. 074 * 075 * @param schemaManager The server schemaManager 076 * @param dnFactory The Dn factory 077 */ 078 public SchemaSubentryModifier( SchemaManager schemaManager, DnFactory dnFactory ) 079 { 080 this.schemaManager = schemaManager; 081 this.dnFactory = dnFactory; 082 } 083 084 085 private Dn getDn( SchemaObject obj ) throws LdapInvalidDnException 086 { 087 StringBuilder buf = new StringBuilder(); 088 buf.append( "m-oid=" ).append( obj.getOid() ).append( ",ou=" ); 089 090 if ( obj instanceof LdapSyntax ) 091 { 092 buf.append( SchemaConstants.SYNTAXES ); 093 } 094 else if ( obj instanceof MatchingRule ) 095 { 096 buf.append( SchemaConstants.MATCHING_RULES_AT ); 097 } 098 else if ( obj instanceof AttributeType ) 099 { 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 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 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 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 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 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 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 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 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}