You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2011/10/15 00:36:15 UTC
svn commit: r1183537 [8/11] - in /directory/apacheds/trunk/interceptors:
admin/ admin/.settings/ authn/ authn/.settings/ authz/.settings/ changelog/
changelog/src/ changelog/src/main/ changelog/src/main/java/
changelog/src/main/java/org/ changelog/src/...
Added: directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaSubentryManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaSubentryManager.java?rev=1183537&view=auto
==============================================================================
--- directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaSubentryManager.java (added)
+++ directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaSubentryManager.java Fri Oct 14 22:36:08 2011
@@ -0,0 +1,462 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.server.core.schema;
+
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.directory.server.core.api.DnFactory;
+import org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext;
+import org.apache.directory.server.core.api.schema.DescriptionParsers;
+import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.shared.ldap.model.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.model.entry.Attribute;
+import org.apache.directory.shared.ldap.model.entry.Modification;
+import org.apache.directory.shared.ldap.model.exception.LdapException;
+import org.apache.directory.shared.ldap.model.exception.LdapUnwillingToPerformException;
+import org.apache.directory.shared.ldap.model.message.ResultCodeEnum;
+import org.apache.directory.shared.ldap.model.schema.AttributeType;
+import org.apache.directory.shared.ldap.model.schema.DITContentRule;
+import org.apache.directory.shared.ldap.model.schema.DITStructureRule;
+import org.apache.directory.shared.ldap.model.schema.LdapSyntax;
+import org.apache.directory.shared.ldap.model.schema.MatchingRule;
+import org.apache.directory.shared.ldap.model.schema.MatchingRuleUse;
+import org.apache.directory.shared.ldap.model.schema.NameForm;
+import org.apache.directory.shared.ldap.model.schema.ObjectClass;
+import org.apache.directory.shared.ldap.model.schema.SchemaManager;
+import org.apache.directory.shared.ldap.model.schema.parsers.LdapComparatorDescription;
+import org.apache.directory.shared.ldap.model.schema.parsers.NormalizerDescription;
+import org.apache.directory.shared.ldap.model.schema.parsers.SyntaxCheckerDescription;
+import org.apache.directory.shared.ldap.model.schema.registries.SchemaLoader;
+import org.apache.directory.shared.util.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class SchemaSubentryManager
+{
+ /** A logger for this class */
+ private static final Logger LOG = LoggerFactory.getLogger( SchemaSubentryManager.class );
+
+ // indices of handlers and object ids into arrays
+ private static final int COMPARATOR_INDEX = 0;
+ private static final int NORMALIZER_INDEX = 1;
+ private static final int SYNTAX_CHECKER_INDEX = 2;
+ private static final int SYNTAX_INDEX = 3;
+ private static final int MATCHING_RULE_INDEX = 4;
+ private static final int ATTRIBUTE_TYPE_INDEX = 5;
+ private static final int OBJECT_CLASS_INDEX = 6;
+ private static final int MATCHING_RULE_USE_INDEX = 7;
+ private static final int DIT_STRUCTURE_RULE_INDEX = 8;
+ private static final int DIT_CONTENT_RULE_INDEX = 9;
+ private static final int NAME_FORM_INDEX = 10;
+
+ private static final Set<String> VALID_OU_VALUES = new HashSet<String>();
+
+ /** The schemaManager */
+ private final SchemaManager schemaManager;
+
+ private final SchemaSubentryModifier subentryModifier;
+
+ /** The description parsers */
+ private final DescriptionParsers parsers;
+
+ /**
+ * Maps the OID of a subschemaSubentry operational attribute to the index of
+ * the handler in the schemaObjectHandlers array.
+ */
+ private final Map<String, Integer> opAttr2handlerIndex = new HashMap<String, Integer>( 11 );
+ private static final String CASCADING_ERROR =
+ "Cascading has not yet been implemented: standard operation is in effect.";
+
+ private static AttributeType ENTRY_CSN_ATTRIBUTE_TYPE;
+
+ static
+ {
+ VALID_OU_VALUES.add( Strings.toLowerCase( SchemaConstants.NORMALIZERS_AT ) );
+ VALID_OU_VALUES.add( Strings.toLowerCase( SchemaConstants.COMPARATORS_AT ) );
+ VALID_OU_VALUES.add( Strings.toLowerCase( SchemaConstants.SYNTAX_CHECKERS_AT ) );
+ VALID_OU_VALUES.add( Strings.toLowerCase( "syntaxes" ) );
+ VALID_OU_VALUES.add( Strings.toLowerCase( SchemaConstants.MATCHING_RULES_AT ) );
+ VALID_OU_VALUES.add( Strings.toLowerCase( SchemaConstants.MATCHING_RULE_USE_AT ) );
+ VALID_OU_VALUES.add( Strings.toLowerCase( SchemaConstants.ATTRIBUTE_TYPES_AT ) );
+ VALID_OU_VALUES.add( Strings.toLowerCase( SchemaConstants.OBJECT_CLASSES_AT ) );
+ VALID_OU_VALUES.add( Strings.toLowerCase( SchemaConstants.NAME_FORMS_AT ) );
+ VALID_OU_VALUES.add( Strings.toLowerCase( SchemaConstants.DIT_CONTENT_RULES_AT ) );
+ VALID_OU_VALUES.add( Strings.toLowerCase( SchemaConstants.DIT_STRUCTURE_RULES_AT ) );
+ }
+
+
+ public SchemaSubentryManager( SchemaManager schemaManager, SchemaLoader loader, DnFactory dnFactory )
+ throws LdapException
+ {
+ this.schemaManager = schemaManager;
+ this.subentryModifier = new SchemaSubentryModifier( schemaManager, dnFactory );
+ this.parsers = new DescriptionParsers( schemaManager );
+
+ String comparatorsOid = schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.COMPARATORS_AT );
+ opAttr2handlerIndex.put( comparatorsOid, COMPARATOR_INDEX );
+
+ String normalizersOid = schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.NORMALIZERS_AT );
+ opAttr2handlerIndex.put( normalizersOid, NORMALIZER_INDEX );
+
+ String syntaxCheckersOid = schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.SYNTAX_CHECKERS_AT );
+ opAttr2handlerIndex.put( syntaxCheckersOid, SYNTAX_CHECKER_INDEX );
+
+ String ldapSyntaxesOid = schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.LDAP_SYNTAXES_AT );
+ opAttr2handlerIndex.put( ldapSyntaxesOid, SYNTAX_INDEX );
+
+ String matchingRulesOid = schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.MATCHING_RULES_AT );
+ opAttr2handlerIndex.put( matchingRulesOid, MATCHING_RULE_INDEX );
+
+ String attributeTypesOid = schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.ATTRIBUTE_TYPES_AT );
+ opAttr2handlerIndex.put( attributeTypesOid, ATTRIBUTE_TYPE_INDEX );
+
+ String objectClassesOid = schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.OBJECT_CLASSES_AT );
+ opAttr2handlerIndex.put( objectClassesOid, OBJECT_CLASS_INDEX );
+
+ String matchingRuleUseOid = schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.MATCHING_RULE_USE_AT );
+ opAttr2handlerIndex.put( matchingRuleUseOid, MATCHING_RULE_USE_INDEX );
+
+ String ditStructureRulesOid = schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.DIT_STRUCTURE_RULES_AT );
+ opAttr2handlerIndex.put( ditStructureRulesOid, DIT_STRUCTURE_RULE_INDEX );
+
+ String ditContentRulesOid = schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.DIT_CONTENT_RULES_AT );
+ opAttr2handlerIndex.put( ditContentRulesOid, DIT_CONTENT_RULE_INDEX );
+
+ String nameFormsOid = schemaManager.getAttributeTypeRegistry().getOidByName( SchemaConstants.NAME_FORMS_AT );
+ opAttr2handlerIndex.put( nameFormsOid, NAME_FORM_INDEX );
+
+ ENTRY_CSN_ATTRIBUTE_TYPE = schemaManager.getAttributeType( SchemaConstants.ENTRY_CSN_AT );
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.apache.directory.server.core.schema.SchemaChangeManager#modifySchemaSubentry(org.apache.directory.server.core.interceptor.context.ModifyOperationContext, org.apache.directory.server.core.entry.Entry, org.apache.directory.server.core.entry.Entry, boolean)
+ */
+ public void modifySchemaSubentry( ModifyOperationContext modifyContext, boolean doCascadeModify ) throws LdapException
+ {
+ for ( Modification mod : modifyContext.getModItems() )
+ {
+ String opAttrOid = schemaManager.getAttributeTypeRegistry().getOidByName( mod.getAttribute().getId() );
+
+ Attribute serverAttribute = mod.getAttribute();
+
+ switch ( mod.getOperation() )
+ {
+ case ADD_ATTRIBUTE :
+ modifyAddOperation( modifyContext, opAttrOid, serverAttribute, doCascadeModify );
+ break;
+
+ case REMOVE_ATTRIBUTE :
+ modifyRemoveOperation( modifyContext, opAttrOid, serverAttribute );
+ break;
+
+ case REPLACE_ATTRIBUTE :
+ // a hack to allow entryCSN modification
+ if ( ENTRY_CSN_ATTRIBUTE_TYPE.equals( serverAttribute.getAttributeType() ) )
+ {
+ break;
+ }
+
+ throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM,
+ I18n.err( I18n.ERR_283 ) );
+
+ default:
+ throw new IllegalStateException( I18n.err( I18n.ERR_284, mod.getOperation() ) );
+ }
+ }
+ }
+
+
+ /**
+ * Handles the modify remove operation on the subschemaSubentry for schema entities.
+ *
+ * @param opAttrOid the numeric id of the operational attribute modified
+ * @param mods the attribute with the modifications
+ * to effect all dependents on the changed entity
+ * @throws Exception if there are problems updating the registries and the
+ * schema partition
+ */
+ private void modifyRemoveOperation( ModifyOperationContext modifyContext, String opAttrOid,
+ Attribute mods ) throws LdapException
+ {
+ int index = opAttr2handlerIndex.get( opAttrOid );
+
+ switch( index )
+ {
+ case( COMPARATOR_INDEX ):
+ LdapComparatorDescription[] comparatorDescriptions = parsers.parseComparators( mods );
+
+ for ( LdapComparatorDescription comparatorDescription : comparatorDescriptions )
+ {
+ subentryModifier.delete( modifyContext, comparatorDescription );
+ }
+ break;
+ case( NORMALIZER_INDEX ):
+ NormalizerDescription[] normalizerDescriptions = parsers.parseNormalizers( mods );
+
+ for ( NormalizerDescription normalizerDescription : normalizerDescriptions )
+ {
+ subentryModifier.delete( modifyContext, normalizerDescription );
+ }
+
+ break;
+
+ case( SYNTAX_CHECKER_INDEX ):
+ SyntaxCheckerDescription[] syntaxCheckerDescriptions = parsers.parseSyntaxCheckers( mods );
+
+ for ( SyntaxCheckerDescription syntaxCheckerDescription : syntaxCheckerDescriptions )
+ {
+ subentryModifier.delete( modifyContext, syntaxCheckerDescription );
+ }
+
+ break;
+
+ case( SYNTAX_INDEX ):
+ LdapSyntax[] syntaxes = parsers.parseLdapSyntaxes( mods );
+
+ for ( LdapSyntax syntax : syntaxes )
+ {
+ subentryModifier.deleteSchemaObject( modifyContext, syntax );
+ }
+
+ break;
+
+ case( MATCHING_RULE_INDEX ):
+ MatchingRule[] mrs = parsers.parseMatchingRules( mods );
+
+ for ( MatchingRule mr : mrs )
+ {
+ subentryModifier.deleteSchemaObject( modifyContext, mr );
+ }
+
+ break;
+
+ case( ATTRIBUTE_TYPE_INDEX ):
+ AttributeType[] ats = parsers.parseAttributeTypes( mods );
+
+ for ( AttributeType at : ats )
+ {
+ subentryModifier.deleteSchemaObject( modifyContext, at );
+ }
+
+ break;
+
+ case( OBJECT_CLASS_INDEX ):
+ ObjectClass[] ocs = parsers.parseObjectClasses( mods );
+
+ for ( ObjectClass oc : ocs )
+ {
+ subentryModifier.deleteSchemaObject( modifyContext, oc );
+ }
+
+ break;
+
+ case( MATCHING_RULE_USE_INDEX ):
+ MatchingRuleUse[] mrus = parsers.parseMatchingRuleUses( mods );
+
+ for ( MatchingRuleUse mru : mrus )
+ {
+ subentryModifier.deleteSchemaObject( modifyContext, mru );
+ }
+
+ break;
+
+ case( DIT_STRUCTURE_RULE_INDEX ):
+ DITStructureRule[] dsrs = parsers.parseDitStructureRules( mods );
+
+ for ( DITStructureRule dsr : dsrs )
+ {
+ subentryModifier.deleteSchemaObject( modifyContext, dsr );
+ }
+
+ break;
+
+ case( DIT_CONTENT_RULE_INDEX ):
+ DITContentRule[] dcrs = parsers.parseDitContentRules( mods );
+
+ for ( DITContentRule dcr : dcrs )
+ {
+ subentryModifier.deleteSchemaObject( modifyContext, dcr );
+ }
+
+ break;
+
+ case( NAME_FORM_INDEX ):
+ NameForm[] nfs = parsers.parseNameForms( mods );
+
+ for ( NameForm nf : nfs )
+ {
+ subentryModifier.deleteSchemaObject( modifyContext, nf );
+ }
+
+ break;
+
+ default:
+ throw new IllegalStateException( I18n.err( I18n.ERR_285, index ) );
+ }
+ }
+
+
+ /**
+ * Handles the modify add operation on the subschemaSubentry for schema entities.
+ *
+ * @param opAttrOid the numeric id of the operational attribute modified
+ * @param mods the attribute with the modifications
+ * @param doCascadeModify determines if a cascading operation should be performed
+ * to effect all dependents on the changed entity
+ * @throws Exception if there are problems updating the registries and the
+ * schema partition
+ */
+ private void modifyAddOperation( ModifyOperationContext modifyContext, String opAttrOid,
+ Attribute mods, boolean doCascadeModify ) throws LdapException
+ {
+ if ( doCascadeModify )
+ {
+ LOG.error( CASCADING_ERROR );
+ }
+
+ int index = opAttr2handlerIndex.get( opAttrOid );
+
+ switch( index )
+ {
+ case( COMPARATOR_INDEX ):
+ LdapComparatorDescription[] comparatorDescriptions = parsers.parseComparators( mods );
+
+ for ( LdapComparatorDescription comparatorDescription : comparatorDescriptions )
+ {
+ subentryModifier.add( modifyContext, comparatorDescription );
+ }
+
+ break;
+
+ case( NORMALIZER_INDEX ):
+ NormalizerDescription[] normalizerDescriptions = parsers.parseNormalizers( mods );
+
+ for ( NormalizerDescription normalizerDescription : normalizerDescriptions )
+ {
+ subentryModifier.add( modifyContext, normalizerDescription );
+ }
+
+ break;
+
+ case( SYNTAX_CHECKER_INDEX ):
+ SyntaxCheckerDescription[] syntaxCheckerDescriptions = parsers.parseSyntaxCheckers( mods );
+
+ for ( SyntaxCheckerDescription syntaxCheckerDescription : syntaxCheckerDescriptions )
+ {
+ subentryModifier.add( modifyContext, syntaxCheckerDescription );
+ }
+
+ break;
+
+ case( SYNTAX_INDEX ):
+ LdapSyntax[] syntaxes = parsers.parseLdapSyntaxes( mods );
+
+ for ( LdapSyntax syntax : syntaxes )
+ {
+ subentryModifier.addSchemaObject( modifyContext, syntax );
+ }
+
+ break;
+
+ case( MATCHING_RULE_INDEX ):
+ MatchingRule[] mrs = parsers.parseMatchingRules( mods );
+
+ for ( MatchingRule mr : mrs )
+ {
+ subentryModifier.addSchemaObject( modifyContext, mr );
+ }
+
+ break;
+
+ case( ATTRIBUTE_TYPE_INDEX ):
+ AttributeType[] ats = parsers.parseAttributeTypes( mods );
+
+ for ( AttributeType at : ats )
+ {
+ subentryModifier.addSchemaObject( modifyContext, at );
+ }
+
+ break;
+
+ case( OBJECT_CLASS_INDEX ):
+ ObjectClass[] ocs = parsers.parseObjectClasses( mods );
+
+ for ( ObjectClass oc : ocs )
+ {
+ subentryModifier.addSchemaObject( modifyContext, oc );
+ }
+
+ break;
+
+ case( MATCHING_RULE_USE_INDEX ):
+ MatchingRuleUse[] mrus = parsers.parseMatchingRuleUses( mods );
+
+ for ( MatchingRuleUse mru : mrus )
+ {
+ subentryModifier.addSchemaObject( modifyContext, mru );
+ }
+
+ break;
+
+ case( DIT_STRUCTURE_RULE_INDEX ):
+ DITStructureRule[] dsrs = parsers.parseDitStructureRules( mods );
+
+ for ( DITStructureRule dsr : dsrs )
+ {
+ subentryModifier.addSchemaObject( modifyContext, dsr );
+ }
+
+ break;
+
+ case( DIT_CONTENT_RULE_INDEX ):
+ DITContentRule[] dcrs = parsers.parseDitContentRules( mods );
+
+ for ( DITContentRule dcr : dcrs )
+ {
+ subentryModifier.addSchemaObject( modifyContext, dcr );
+ }
+
+ break;
+
+ case( NAME_FORM_INDEX ):
+ NameForm[] nfs = parsers.parseNameForms( mods );
+
+ for ( NameForm nf : nfs )
+ {
+ subentryModifier.addSchemaObject( modifyContext, nf );
+ }
+
+ break;
+
+ default:
+ throw new IllegalStateException( I18n.err( I18n.ERR_285, index ) );
+ }
+ }
+}
Added: directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaSubentryModifier.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaSubentryModifier.java?rev=1183537&view=auto
==============================================================================
--- directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaSubentryModifier.java (added)
+++ directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/SchemaSubentryModifier.java Fri Oct 14 22:36:08 2011
@@ -0,0 +1,331 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.server.core.schema;
+
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.directory.server.core.api.DnFactory;
+import org.apache.directory.server.core.api.interceptor.context.OperationContext;
+import org.apache.directory.shared.ldap.model.constants.MetaSchemaConstants;
+import org.apache.directory.shared.ldap.model.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.model.entry.DefaultEntry;
+import org.apache.directory.shared.ldap.model.entry.Entry;
+import org.apache.directory.shared.ldap.model.exception.LdapException;
+import org.apache.directory.shared.ldap.model.exception.LdapInvalidDnException;
+import org.apache.directory.shared.ldap.model.name.Dn;
+import org.apache.directory.shared.ldap.model.schema.AttributeType;
+import org.apache.directory.shared.ldap.model.schema.DITContentRule;
+import org.apache.directory.shared.ldap.model.schema.DITStructureRule;
+import org.apache.directory.shared.ldap.model.schema.LdapSyntax;
+import org.apache.directory.shared.ldap.model.schema.MatchingRule;
+import org.apache.directory.shared.ldap.model.schema.MatchingRuleUse;
+import org.apache.directory.shared.ldap.model.schema.NameForm;
+import org.apache.directory.shared.ldap.model.schema.ObjectClass;
+import org.apache.directory.shared.ldap.model.schema.SchemaManager;
+import org.apache.directory.shared.ldap.model.schema.SchemaObject;
+import org.apache.directory.shared.ldap.model.schema.parsers.LdapComparatorDescription;
+import org.apache.directory.shared.ldap.model.schema.parsers.SyntaxCheckerDescription;
+import org.apache.directory.shared.ldap.model.schema.parsers.NormalizerDescription;
+import org.apache.directory.shared.ldap.model.schema.registries.Schema;
+import org.apache.directory.shared.util.Base64;
+
+
+/**
+ * Responsible for translating modify operations on the subschemaSubentry into
+ * operations against entries within the schema partition.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class SchemaSubentryModifier
+{
+ private static final Collection<String> BYPASS;
+
+ static
+ {
+ Set<String> c = new HashSet<String>();
+ c.add( "AuthenticationInterceptor" );
+ c.add( "AciAuthorizationInterceptor" );
+ c.add( "DefaultAuthorizationInterceptor" );
+ c.add( "ExceptionInterceptor" );
+ c.add( "SchemaInterceptor" );
+ BYPASS = Collections.unmodifiableCollection( c );
+ }
+
+ private AttributesFactory factory = new AttributesFactory();
+
+ /** The server schemaManager */
+ private SchemaManager schemaManager;
+
+ /** The Dn factory */
+ private DnFactory dnFactory;
+
+
+ /**
+ *
+ * Creates a new instance of SchemaSubentryModifier.
+ *
+ * @param schemaManager The server schemaManager
+ * @param dnFactory The Dn factory
+ */
+ public SchemaSubentryModifier( SchemaManager schemaManager, DnFactory dnFactory )
+ {
+ this.schemaManager = schemaManager;
+ this.dnFactory = dnFactory;
+ }
+
+
+ private Dn getDn( SchemaObject obj ) throws LdapInvalidDnException
+ {
+ StringBuffer buf = new StringBuffer();
+ buf.append( "m-oid=" ).append( obj.getOid() ).append( ",ou=" );
+
+ if ( obj instanceof LdapSyntax )
+ {
+ buf.append( "syntaxes" );
+ }
+ else if ( obj instanceof MatchingRule )
+ {
+ buf.append( SchemaConstants.MATCHING_RULES_AT );
+ }
+ else if ( obj instanceof AttributeType )
+ {
+ buf.append( SchemaConstants.ATTRIBUTE_TYPES_AT );
+ }
+ else if ( obj instanceof ObjectClass )
+ {
+ buf.append( SchemaConstants.OBJECT_CLASSES_AT );
+ }
+ else if ( obj instanceof MatchingRuleUse )
+ {
+ buf.append( SchemaConstants.MATCHING_RULE_USE_AT );
+ }
+ else if ( obj instanceof DITStructureRule )
+ {
+ buf.append( SchemaConstants.DIT_STRUCTURE_RULES_AT );
+ }
+ else if ( obj instanceof DITContentRule )
+ {
+ buf.append( SchemaConstants.DIT_CONTENT_RULES_AT );
+ }
+ else if ( obj instanceof NameForm )
+ {
+ buf.append( SchemaConstants.NAME_FORMS_AT );
+ }
+
+ buf.append( ",cn=" ).append( obj.getSchemaName() ).append( ",ou=schema" );
+ return dnFactory.create( buf.toString() );
+ }
+
+
+ public void add( OperationContext opContext, LdapComparatorDescription comparatorDescription ) throws LdapException
+ {
+ String schemaName = getSchema( comparatorDescription );
+ Dn dn = dnFactory.create(
+ "m-oid=" + comparatorDescription.getOid(),
+ SchemaConstants.COMPARATORS_PATH,
+ "cn=" + schemaName,
+ SchemaConstants.OU_SCHEMA );
+
+ Entry entry = getEntry( dn, comparatorDescription );
+
+ opContext.add( (Entry)entry, BYPASS );
+ }
+
+
+ public void add( OperationContext opContext, NormalizerDescription normalizerDescription ) throws LdapException
+ {
+ String schemaName = getSchema( normalizerDescription );
+ Dn dn = dnFactory.create(
+ "m-oid=" + normalizerDescription.getOid(),
+ SchemaConstants.NORMALIZERS_PATH ,
+ "cn=" + schemaName,
+ SchemaConstants.OU_SCHEMA );
+
+ Entry entry = getEntry( dn, normalizerDescription );
+
+ opContext.add( (Entry)entry, BYPASS );
+ }
+
+
+ public void add( OperationContext opContext, SyntaxCheckerDescription syntaxCheckerDescription ) throws LdapException
+ {
+ String schemaName = getSchema( syntaxCheckerDescription );
+ Dn dn = dnFactory.create(
+ "m-oid=" + syntaxCheckerDescription.getOid(),
+ SchemaConstants.SYNTAX_CHECKERS_PATH,
+ "cn=" + schemaName,
+ SchemaConstants.OU_SCHEMA );
+
+ Entry entry = getEntry( dn, syntaxCheckerDescription );
+ opContext.add( (Entry)entry, BYPASS );
+ }
+
+
+ public void addSchemaObject( OperationContext opContext, SchemaObject obj ) throws LdapException
+ {
+ Schema schema = schemaManager.getLoadedSchema( obj.getSchemaName() );
+ Dn dn = getDn( obj );
+ Entry entry = factory.getAttributes( obj, schema, schemaManager );
+ entry.setDn( dn );
+
+ opContext.add( entry, BYPASS );
+ }
+
+
+ public void deleteSchemaObject( OperationContext opContext, SchemaObject obj ) throws LdapException
+ {
+ Dn dn = getDn( obj );
+ opContext.delete( dn, BYPASS );
+ }
+
+
+ public void delete( OperationContext opContext, NormalizerDescription normalizerDescription ) throws LdapException
+ {
+ String schemaName = getSchema( normalizerDescription );
+ Dn dn = dnFactory.create(
+ "m-oid=" + normalizerDescription.getOid(),
+ SchemaConstants.NORMALIZERS_PATH,
+ "cn=" + schemaName,
+ SchemaConstants.OU_SCHEMA );
+
+ opContext.delete( dn, BYPASS );
+ }
+
+
+ public void delete( OperationContext opContext, SyntaxCheckerDescription syntaxCheckerDescription ) throws LdapException
+ {
+ String schemaName = getSchema( syntaxCheckerDescription );
+ Dn dn = dnFactory.create(
+ "m-oid=" + syntaxCheckerDescription.getOid(),
+ SchemaConstants.SYNTAX_CHECKERS_PATH,
+ "cn=" + schemaName,
+ SchemaConstants.OU_SCHEMA );
+ opContext.delete( dn, BYPASS );
+ }
+
+
+ public void delete( OperationContext opContext, LdapComparatorDescription comparatorDescription ) throws LdapException
+ {
+ String schemaName = getSchema( comparatorDescription );
+ Dn dn = dnFactory.create(
+ "m-oid=" + comparatorDescription.getOid(),
+ SchemaConstants.COMPARATORS_PATH,
+ "cn=" + schemaName,
+ SchemaConstants.OU_SCHEMA );
+
+ opContext.delete( dn, BYPASS );
+ }
+
+
+ private Entry getEntry( Dn dn, LdapComparatorDescription comparatorDescription )
+ {
+ Entry entry = new DefaultEntry( schemaManager, dn );
+
+ entry.put( SchemaConstants.OBJECT_CLASS_AT,
+ SchemaConstants.TOP_OC,
+ MetaSchemaConstants.META_TOP_OC,
+ MetaSchemaConstants.META_COMPARATOR_OC );
+
+ entry.put( MetaSchemaConstants.M_OID_AT, comparatorDescription.getOid() );
+ entry.put( MetaSchemaConstants.M_FQCN_AT, comparatorDescription.getFqcn() );
+
+ if ( comparatorDescription.getBytecode() != null )
+ {
+ entry.put( MetaSchemaConstants.M_BYTECODE_AT,
+ Base64.decode( comparatorDescription.getBytecode().toCharArray() ) );
+ }
+
+ if ( comparatorDescription.getDescription() != null )
+ {
+ entry.put( MetaSchemaConstants.M_DESCRIPTION_AT, comparatorDescription.getDescription() );
+ }
+
+ return entry;
+ }
+
+
+ private Entry getEntry( Dn dn, NormalizerDescription normalizerDescription )
+ {
+ Entry entry = new DefaultEntry( schemaManager, dn );
+
+ entry.put( SchemaConstants.OBJECT_CLASS_AT,
+ SchemaConstants.TOP_OC,
+ MetaSchemaConstants.META_TOP_OC,
+ MetaSchemaConstants.META_NORMALIZER_OC );
+
+ entry.put( MetaSchemaConstants.M_OID_AT, normalizerDescription.getOid() );
+ entry.put( MetaSchemaConstants.M_FQCN_AT, normalizerDescription.getFqcn() );
+
+ if ( normalizerDescription.getBytecode() != null )
+ {
+ entry.put( MetaSchemaConstants.M_BYTECODE_AT,
+ Base64.decode( normalizerDescription.getBytecode().toCharArray() ) );
+ }
+
+ if ( normalizerDescription.getDescription() != null )
+ {
+ entry.put( MetaSchemaConstants.M_DESCRIPTION_AT, normalizerDescription.getDescription() );
+ }
+
+ return entry;
+ }
+
+
+ private String getSchema( SchemaObject desc )
+ {
+ if ( desc.getExtensions().containsKey( MetaSchemaConstants.X_SCHEMA ) )
+ {
+ return desc.getExtensions().get( MetaSchemaConstants.X_SCHEMA ).get( 0 );
+ }
+
+ return MetaSchemaConstants.SCHEMA_OTHER;
+ }
+
+
+ private Entry getEntry( Dn dn, SyntaxCheckerDescription syntaxCheckerDescription )
+ {
+ Entry entry = new DefaultEntry( schemaManager, dn );
+
+ entry.put( SchemaConstants.OBJECT_CLASS_AT,
+ SchemaConstants.TOP_OC,
+ MetaSchemaConstants.META_TOP_OC,
+ MetaSchemaConstants.META_SYNTAX_CHECKER_OC );
+
+ entry.put( MetaSchemaConstants.M_OID_AT, syntaxCheckerDescription.getOid() );
+ entry.put( MetaSchemaConstants.M_FQCN_AT, syntaxCheckerDescription.getFqcn() );
+
+ if ( syntaxCheckerDescription.getBytecode() != null )
+ {
+ entry.put( MetaSchemaConstants.M_BYTECODE_AT,
+ Base64.decode(syntaxCheckerDescription.getBytecode().toCharArray()) );
+ }
+
+ if ( syntaxCheckerDescription.getDescription() != null )
+ {
+ entry.put( MetaSchemaConstants.M_DESCRIPTION_AT, syntaxCheckerDescription.getDescription() );
+ }
+
+ return entry;
+ }
+}
Added: directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/package-info.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/package-info.java?rev=1183537&view=auto
==============================================================================
--- directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/package-info.java (added)
+++ directory/apacheds/trunk/interceptors/schema/src/main/java/org/apache/directory/server/core/schema/package-info.java Fri Oct 14 22:36:08 2011
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+/**
+ * <pre>
+ * <p>
+ * Contains interfaces for schema object registry services and simple POJO
+ * implementations of these services. Other helper interfaces and classes are
+ * included for handling monitoring of these services.
+ * </p>
+ * <p>
+ * These services and their POJO implementations are purposefully kept really
+ * simple here for a reason. When one looks at these interfaces they stop and
+ * think why even bother having them when you can just use a map of objects
+ * somewhere. These simple services can and will get more complex as other
+ * facilities come into play namely the object builders that populate these
+ * registries. There might also be caching going on as well as disk based
+ * store access. Finally dependencies become an issue and sometime bootstrap
+ * instances of these components are required by the system. So these simple
+ * watered down interfaces and their POJO's have been pruned from previously
+ * complex environment specific versions of them.
+ * </p>
+ * <p>
+ * Some key points to apply to services and their POJO impls in this package:
+ * <ul>
+ * <li>registries only register and allow for lookups: its that simple!</li>
+ * <li>don't worry if they change over time</li>
+ * <li>don't worry about how they get populated</li>
+ * <li>don't worry who or what does the populating</li>
+ * <li>don't worry about where the information comes from</li>
+ * </ul>
+ * </p>
+ * </pre>
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+
+package org.apache.directory.server.core.schema;
Added: directory/apacheds/trunk/interceptors/schema/src/test/java/org/apache/directory/server/core/schema/SchemaServiceTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/schema/src/test/java/org/apache/directory/server/core/schema/SchemaServiceTest.java?rev=1183537&view=auto
==============================================================================
--- directory/apacheds/trunk/interceptors/schema/src/test/java/org/apache/directory/server/core/schema/SchemaServiceTest.java (added)
+++ directory/apacheds/trunk/interceptors/schema/src/test/java/org/apache/directory/server/core/schema/SchemaServiceTest.java Fri Oct 14 22:36:08 2011
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.server.core.schema;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.directory.shared.ldap.model.schema.AttributeType;
+import org.apache.directory.shared.ldap.model.schema.SchemaManager;
+import org.apache.directory.shared.ldap.schemaextractor.SchemaLdifExtractor;
+import org.apache.directory.shared.ldap.schemaextractor.impl.DefaultSchemaLdifExtractor;
+import org.apache.directory.shared.ldap.schemaloader.LdifSchemaLoader;
+import org.apache.directory.shared.ldap.schemamanager.impl.DefaultSchemaManager;
+import org.apache.directory.shared.util.exception.Exceptions;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.mycila.junit.concurrent.Concurrency;
+import com.mycila.junit.concurrent.ConcurrentJunitRunner;
+
+
+/**
+ * Tests methods in SchemaInterceptor.
+ */
+@RunWith(ConcurrentJunitRunner.class)
+@Concurrency()
+public class SchemaServiceTest
+{
+ private static SchemaManager schemaManager;
+
+
+ @BeforeClass
+ public static void setUp() throws Exception
+ {
+ String workingDirectory = System.getProperty( "workingDirectory" );
+
+ if ( workingDirectory == null )
+ {
+ String path = SchemaServiceTest.class.getResource( "" ).getPath();
+ int targetPos = path.indexOf( "target" );
+ workingDirectory = path.substring( 0, targetPos + 6 );
+ }
+
+ File schemaRepository = new File( workingDirectory, "schema" );
+ SchemaLdifExtractor extractor = new DefaultSchemaLdifExtractor( new File( workingDirectory ) );
+ extractor.extractOrCopy( true );
+ LdifSchemaLoader loader = new LdifSchemaLoader( schemaRepository );
+ schemaManager = new DefaultSchemaManager( loader );
+
+ boolean loaded = schemaManager.loadAllEnabled();
+
+ if ( !loaded )
+ {
+ fail( "Schema load failed : " + Exceptions.printErrors(schemaManager.getErrors()) );
+ }
+
+ loaded = schemaManager.loadWithDeps( "nis" );
+
+ if ( !loaded )
+ {
+ fail( "Schema load failed : " + Exceptions.printErrors(schemaManager.getErrors()) );
+ }
+ }
+
+
+ @Test
+ public void testDescendants() throws Exception
+ {
+ Iterator<AttributeType> list = schemaManager.getAttributeTypeRegistry().descendants( "name" );
+ Set<String> nameAttrs = new HashSet<String>();
+
+ while ( list.hasNext() )
+ {
+ AttributeType type = list.next();
+ nameAttrs.add( type.getName() );
+ }
+
+ // We should only have 19 AT
+ String[] expectedNames = new String[]
+ { "sn", "generationQualifier", "ou", "c", "o", "l", "c-st", "givenName", "title", "cn", "initials",
+ "dmdName", "c-ou", "c-o", "apachePresence", "st", "c-l", "ads-serverId", "ads-indexAttributeId",
+ "ads-transportId", "ads-directoryServiceId", "ads-Id", "ads-extendedOpId", "ads-pwdId",
+ "ads-compositeElement", "ads-replConsumerId", "ads-journalId", "ads-changeLogId", "ads-replProviderId" };
+
+ for ( String name : expectedNames )
+ {
+ if ( nameAttrs.contains( name ) )
+ {
+ nameAttrs.remove( name );
+ }
+ }
+
+ assertEquals( 0, nameAttrs.size() );
+ }
+ /*
+ public void testAlterObjectClassesBogusAttr() throws NamingException
+ {
+ Attribute attr = new AttributeImpl( "blah", "blah" );
+
+ try
+ {
+ SchemaInterceptor.alterObjectClasses( attr, registries.getObjectClassRegistry() );
+ fail( "should not get here" );
+ }
+ catch ( LdapNamingException e )
+ {
+ assertEquals( ResultCodeEnum.OPERATIONS_ERROR, e.getResultCode() );
+ }
+
+ attr = new AttributeImpl( "objectClass" );
+ SchemaInterceptor.alterObjectClasses( attr );
+ assertEquals( 0, attr.size() );
+ }
+
+
+ public void testAlterObjectClassesNoAttrValue() throws NamingException
+ {
+ Attribute attr = new AttributeImpl( "objectClass" );
+ SchemaInterceptor.alterObjectClasses( attr );
+ assertEquals( 0, attr.size() );
+ }
+
+
+ public void testAlterObjectClassesTopAttrValue() throws NamingException
+ {
+ Attribute attr = new AttributeImpl( "objectClass", "top" );
+ SchemaInterceptor.alterObjectClasses( attr, registries.getObjectClassRegistry() );
+ assertEquals( 0, attr.size() );
+ }
+
+
+ public void testAlterObjectClassesInetOrgPersonAttrValue() throws NamingException
+ {
+ Attribute attr = new AttributeImpl( "objectClass", "organizationalPerson" );
+ SchemaInterceptor.alterObjectClasses( attr, registries.getObjectClassRegistry() );
+ assertEquals( 2, attr.size() );
+ assertTrue( attr.contains( "person" ) );
+ assertTrue( attr.contains( "organizationalPerson" ) );
+ }
+
+
+ public void testAlterObjectClassesOverlapping() throws NamingException
+ {
+ Attribute attr = new AttributeImpl( "objectClass", "organizationalPerson" );
+ attr.add( "residentialPerson" );
+ SchemaInterceptor.alterObjectClasses( attr, registries.getObjectClassRegistry() );
+ assertEquals( 3, attr.size() );
+ assertTrue( attr.contains( "person" ) );
+ assertTrue( attr.contains( "organizationalPerson" ) );
+ assertTrue( attr.contains( "residentialPerson" ) );
+ }
+
+
+ public void testAlterObjectClassesOverlappingAndDsa() throws NamingException
+ {
+ Attribute attr = new AttributeImpl( "objectClass", "organizationalPerson" );
+ attr.add( "residentialPerson" );
+ attr.add( "dSA" );
+ SchemaInterceptor.alterObjectClasses( attr, registries.getObjectClassRegistry() );
+ assertEquals( 5, attr.size() );
+ assertTrue( attr.contains( "person" ) );
+ assertTrue( attr.contains( "organizationalPerson" ) );
+ assertTrue( attr.contains( "residentialPerson" ) );
+ assertTrue( attr.contains( "dSA" ) );
+ assertTrue( attr.contains( "applicationEntity" ) );
+ }
+ */
+}
Propchange: directory/apacheds/trunk/interceptors/subtree/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Oct 14 22:36:08 2011
@@ -0,0 +1,11 @@
+.project
+.classpath
+.settings
+eclipse-classes
+*.log
+*.iml
+*.ipr
+dependency-reduced-pom.xml
+META-INF
+
+
Added: directory/apacheds/trunk/interceptors/subtree/pom.xml
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/subtree/pom.xml?rev=1183537&view=auto
==============================================================================
--- directory/apacheds/trunk/interceptors/subtree/pom.xml (added)
+++ directory/apacheds/trunk/interceptors/subtree/pom.xml Fri Oct 14 22:36:08 2011
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.directory.server</groupId>
+ <artifactId>apacheds-interceptors</artifactId>
+ <version>2.0.0-M4-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>apacheds-interceptors-subtree</artifactId>
+ <name>ApacheDS Subtree Interceptor</name>
+ <packaging>jar</packaging>
+
+ <description>
+ Subtree interceptor
+ </description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.directory.junit</groupId>
+ <artifactId>junit-addons</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>apacheds-i18n</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>apacheds-core-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>apacheds-core-api</artifactId>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>apacheds-core-shared</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>apacheds-interceptors-event</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>apacheds-interceptors-normalization</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.shared</groupId>
+ <artifactId>shared-ldap-client-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.shared</groupId>
+ <artifactId>shared-i18n</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.shared</groupId>
+ <artifactId>shared-ldap-codec-standalone</artifactId>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.shared</groupId>
+ <artifactId>shared-ldap-codec-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.shared</groupId>
+ <artifactId>shared-ldap-extras-aci</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.shared</groupId>
+ <artifactId>shared-ldap-extras-trigger</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.shared</groupId>
+ <artifactId>shared-ldap-extras-util</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.shared</groupId>
+ <artifactId>shared-ldap-model</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.shared</groupId>
+ <artifactId>shared-ldap-schema-data</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.shared</groupId>
+ <artifactId>shared-util</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>bouncycastle</groupId>
+ <artifactId>bcprov-jdk15</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>net.sf.ehcache</groupId>
+ <artifactId>ehcache-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.shared</groupId>
+ <artifactId>shared-ldap-extras-codec</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <systemPropertyVariables>
+ <workingDirectory>${basedir}/target/server-work</workingDirectory>
+ </systemPropertyVariables>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ <excludes>
+ <exclude>**/*.gif</exclude>
+ </excludes>
+ </resource>
+ </resources>
+ </build>
+</project>
+
Added: directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/RefinementEvaluator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/RefinementEvaluator.java?rev=1183537&view=auto
==============================================================================
--- directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/RefinementEvaluator.java (added)
+++ directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/RefinementEvaluator.java Fri Oct 14 22:36:08 2011
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.server.core.subtree;
+
+
+import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.shared.ldap.model.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.model.entry.Attribute;
+import org.apache.directory.shared.ldap.model.exception.LdapException;
+import org.apache.directory.shared.ldap.model.filter.AndNode;
+import org.apache.directory.shared.ldap.model.filter.BranchNode;
+import org.apache.directory.shared.ldap.model.filter.ExprNode;
+import org.apache.directory.shared.ldap.model.filter.NotNode;
+import org.apache.directory.shared.ldap.model.filter.OrNode;
+import org.apache.directory.shared.ldap.model.filter.SimpleNode;
+
+
+/**
+ * The top level evaluation node for a refinement.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class RefinementEvaluator
+{
+ /** Leaf Evaluator flyweight use for leaf filter assertions */
+ private RefinementLeafEvaluator leafEvaluator;
+
+
+ // ------------------------------------------------------------------------
+ // C O N S T R U C T O R S
+ // ------------------------------------------------------------------------
+
+ public RefinementEvaluator(RefinementLeafEvaluator leafEvaluator)
+ {
+ this.leafEvaluator = leafEvaluator;
+ }
+
+
+ public boolean evaluate( ExprNode node, Attribute objectClasses ) throws LdapException
+ {
+ if ( node == null )
+ {
+ throw new IllegalArgumentException( I18n.err( I18n.ERR_295 ) );
+ }
+
+ if ( objectClasses == null )
+ {
+ throw new IllegalArgumentException( I18n.err( I18n.ERR_296 ) );
+ }
+
+ if ( !( SchemaConstants.OBJECT_CLASS_AT_OID.equals( objectClasses.getAttributeType().getOid() ) ) )
+ {
+ throw new IllegalArgumentException( I18n.err( I18n.ERR_297 ) );
+ }
+
+ if ( node.isLeaf() )
+ {
+ return leafEvaluator.evaluate( ( SimpleNode ) node, objectClasses );
+ }
+
+ BranchNode bnode = (BranchNode) node;
+
+ if ( node instanceof OrNode )
+ {
+ for ( ExprNode child:bnode.getChildren() )
+ {
+ if ( evaluate( child, objectClasses ) )
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ else if ( node instanceof AndNode )
+ {
+ for ( ExprNode child:bnode.getChildren() )
+ {
+ if ( !evaluate( child, objectClasses ) )
+ {
+ return false;
+ }
+ }
+
+ return true;
+
+ }
+ else if ( node instanceof NotNode )
+ {
+ if ( null != bnode.getFirstChild() )
+ {
+ return !evaluate( bnode.getFirstChild(), objectClasses );
+ }
+
+ throw new IllegalArgumentException( I18n.err( I18n.ERR_243, node ) );
+
+ }
+ else
+ {
+ throw new IllegalArgumentException( I18n.err( I18n.ERR_244, bnode ) );
+ }
+ }
+}
Added: directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/RefinementLeafEvaluator.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/RefinementLeafEvaluator.java?rev=1183537&view=auto
==============================================================================
--- directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/RefinementLeafEvaluator.java (added)
+++ directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/RefinementLeafEvaluator.java Fri Oct 14 22:36:08 2011
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.server.core.subtree;
+
+
+import java.util.Iterator;
+
+import org.apache.directory.server.i18n.I18n;
+import org.apache.directory.shared.ldap.model.constants.SchemaConstants;
+import org.apache.directory.shared.ldap.model.entry.Attribute;
+import org.apache.directory.shared.ldap.model.exception.LdapException;
+import org.apache.directory.shared.ldap.model.filter.EqualityNode;
+import org.apache.directory.shared.ldap.model.filter.SimpleNode;
+import org.apache.directory.shared.ldap.model.schema.AttributeType;
+import org.apache.directory.shared.ldap.model.schema.SchemaManager;
+
+
+/**
+ * A refinement leaf node evaluator. This evaluator checks to see if the
+ * objectClass attribute of a candidate entry is matched by a leaf node in
+ * a refinement filter expression tree.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class RefinementLeafEvaluator
+{
+ /** A SchemaManager instance */
+ private final SchemaManager schemaManager;
+
+ /** A storage for the ObjectClass attributeType */
+ private AttributeType OBJECT_CLASS_AT;
+
+
+ /**
+ * Creates a refinement filter's leaf node evaluator.
+ *
+ * @param schemaManager The server schemaManager
+ */
+ public RefinementLeafEvaluator( SchemaManager schemaManager)
+ {
+ this.schemaManager = schemaManager;
+ OBJECT_CLASS_AT = schemaManager.getAttributeType( SchemaConstants.OBJECT_CLASS_AT );
+ }
+
+
+ /**
+ * Evaluates whether or not a simple leaf node of a refinement filter selects an
+ * entry based on the entry's objectClass attribute values.
+ *
+ * @param node the leaf node of the refinement filter
+ * @param objectClasses the objectClass attribute's values
+ * @return true if the leaf node selects the entry based on objectClass values, false
+ * if it rejects the entry
+ * @throws LdapException
+ */
+ public boolean evaluate( SimpleNode node, Attribute objectClasses ) throws LdapException
+ {
+ if ( node == null )
+ {
+ throw new IllegalArgumentException( I18n.err( I18n.ERR_295 ) );
+ }
+
+ if ( !( node instanceof EqualityNode) )
+ {
+ throw new LdapException( I18n.err( I18n.ERR_301, node ) );
+ }
+
+ if ( node.isSchemaAware() )
+ {
+ if ( !node.getAttributeType().equals( OBJECT_CLASS_AT ) )
+ {
+ throw new IllegalArgumentException( I18n.err( I18n.ERR_302, node.getAttribute() ) );
+ }
+ }
+ else if ( !node.getAttribute().equalsIgnoreCase( SchemaConstants.OBJECT_CLASS_AT ) &&
+ !node.getAttribute().equalsIgnoreCase( SchemaConstants.OBJECT_CLASS_AT_OID ) )
+ {
+ throw new IllegalArgumentException( I18n.err( I18n.ERR_302, node.getAttribute() ) );
+ }
+
+
+ if ( null == objectClasses )
+ {
+ throw new IllegalArgumentException( I18n.err( I18n.ERR_303 ) );
+ }
+
+ if ( !( objectClasses.isInstanceOf( OBJECT_CLASS_AT ) ) )
+ {
+ throw new IllegalArgumentException( I18n.err( I18n.ERR_304 ) );
+ }
+
+ // check if Ava value exists in attribute
+ // If the filter value for the objectClass is an OID we need to resolve a name
+ String value = node.getValue().getString();
+
+ if ( objectClasses.contains( value ) )
+ {
+ return true;
+ }
+
+ if ( Character.isDigit( value.charAt( 0 ) ) )
+ {
+ Iterator<String> list = schemaManager.getGlobalOidRegistry().getNameSet( value ).iterator();
+
+ while ( list.hasNext() )
+ {
+ String objectClass = list.next();
+
+ if ( objectClasses.contains( objectClass ) )
+ {
+ return true;
+ }
+ }
+ }
+
+ // no match so return false
+ return false;
+ }
+}
Added: directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/Subentry.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/Subentry.java?rev=1183537&view=auto
==============================================================================
--- directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/Subentry.java (added)
+++ directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/Subentry.java Fri Oct 14 22:36:08 2011
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.server.core.subtree;
+
+
+import java.util.Set;
+
+import org.apache.directory.shared.ldap.model.subtree.AdministrativeRole;
+import org.apache.directory.shared.ldap.model.subtree.SubtreeSpecification;
+
+
+/**
+ * An operational view of a subentry within the system. A Subentry can have
+ * many types (Collective, Schema, AccessControl or Trigger) but only one
+ * Subtree Specification.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class Subentry
+{
+ /** The Subtree Specification associated with this subentry */
+ private SubtreeSpecification ss;
+
+ /** The administratives roles */
+ private Set<AdministrativeRole> administrativeRoles;
+
+
+ /**
+ * Stores the subtree
+ *
+ * @param ss The subtree specification
+ */
+ final void setSubtreeSpecification( SubtreeSpecification ss )
+ {
+ this.ss = ss;
+ }
+
+
+ /**
+ * @return The subtree specification
+ */
+ final SubtreeSpecification getSubtreeSpecification()
+ {
+ return ss;
+ }
+
+
+ /**
+ *
+ * TODO setAdministrativeRoles.
+ *
+ * @param administrativeRoles
+ */
+ final void setAdministrativeRoles( Set<AdministrativeRole> administrativeRoles )
+ {
+ this.administrativeRoles = administrativeRoles;
+ }
+
+
+ final Set<AdministrativeRole> getAdministrativeRoles()
+ {
+ return administrativeRoles;
+ }
+
+
+ /**
+ * Tells if the type contains the Collective attribute Administrative Role
+ */
+ final boolean isCollectiveAdminRole()
+ {
+ return administrativeRoles.contains( AdministrativeRole.CollectiveAttributeInnerArea ) ||
+ administrativeRoles.contains( AdministrativeRole.CollectiveAttributeSpecificArea );
+ }
+
+
+ /**
+ * Tells if the type contains the SubSchema Administrative Role
+ */
+ final boolean isSchemaAdminRole()
+ {
+ return administrativeRoles.contains( AdministrativeRole.SubSchemaSpecificArea );
+ }
+
+
+ /**
+ * Tells if the type contains the Access Control Administrative Role
+ */
+ final boolean isAccessControlAdminRole()
+ {
+ return administrativeRoles.contains( AdministrativeRole.AccessControlSpecificArea ) ||
+ administrativeRoles.contains( AdministrativeRole.AccessControlInnerArea );
+ }
+
+
+ /**
+ * Tells if the type contains the Triggers Administrative Role
+ */
+ final boolean isTriggersAdminRole()
+ {
+ return administrativeRoles.contains( AdministrativeRole.TriggerExecutionSpecificArea ) ||
+ administrativeRoles.contains( AdministrativeRole.TriggerExecutionInnerArea );
+ }
+
+
+ /**
+ * @see Object#toString()
+ */
+ public String toString()
+ {
+ return "Subentry[" + administrativeRoles + ", " + ss + "]";
+ }
+}
Added: directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/SubentryCache.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/SubentryCache.java?rev=1183537&view=auto
==============================================================================
--- directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/SubentryCache.java (added)
+++ directory/apacheds/trunk/interceptors/subtree/src/main/java/org/apache/directory/server/core/subtree/SubentryCache.java Fri Oct 14 22:36:08 2011
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.server.core.subtree;
+
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.directory.shared.ldap.model.name.Dn;
+
+
+/**
+ * A cache for subtree specifications. It associates a Subentry with a Dn,
+ * representing its position in the DIT.<br>
+ * This cache has a size limit set to 1000 at the moment. We should add a configuration
+ * parameter to manage its size.
+ *
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+public class SubentryCache implements Iterable<Dn>
+{
+ /** The default cache size limit */
+ private static final int DEFAULT_CACHE_MAX_SIZE = 1000;
+
+ /** The cache size limit */
+ private int cacheMaxSize = DEFAULT_CACHE_MAX_SIZE;
+
+ /** The current cache size */
+ private AtomicInteger cacheSize;
+
+ /** The Subentry cache */
+ private final Map<Dn, Subentry> cache;
+
+ /**
+ * Creates a new instance of SubentryCache with a default maximum size.
+ */
+ public SubentryCache()
+ {
+ cache = new ConcurrentHashMap<Dn, Subentry>();
+ cacheSize = new AtomicInteger( 0 );
+ }
+
+
+ /**
+ * Creates a new instance of SubentryCache with a specific maximum size.
+ */
+ public SubentryCache( int maxSize )
+ {
+ cache = new ConcurrentHashMap<Dn, Subentry>();
+ cacheSize = new AtomicInteger( 0 );
+ cacheMaxSize = maxSize;
+ }
+
+
+ /**
+ * Retrieve a Subentry given a Dn. If there is none, null will be returned.
+ *
+ * @param dn The Dn we want to get the Subentry for
+ * @return The found Subentry, or null
+ */
+ final Subentry getSubentry( Dn dn )
+ {
+ return cache.get( dn );
+ }
+
+
+ /**
+ * Remove a Subentry for a given Dn
+ *
+ * @param dn The Dn for which we want to remove the
+ * associated Subentry
+ * @return The removed Subentry, if any
+ */
+ final Subentry removeSubentry( Dn dn )
+ {
+ Subentry oldSubentry = cache.remove( dn );
+
+ if ( oldSubentry != null )
+ {
+ cacheSize.decrementAndGet();
+ }
+
+ return oldSubentry;
+ }
+
+
+ /**
+ * Stores a new Subentry into the cache, associated with a Dn
+ *
+ * @param dn The Subentry Dn
+ * @param ss The SubtreeSpecification
+ * @param adminRoles The administrative roles for this Subentry
+ * @return The old Subentry, if any
+ */
+ /* No qualifier */ Subentry addSubentry( Dn dn, Subentry subentry )
+ {
+ if ( cacheSize.get() > cacheMaxSize )
+ {
+ // TODO : Throw an exception here
+ }
+
+ Subentry oldSubentry = cache.put( dn, subentry );
+
+ if ( oldSubentry == null )
+ {
+ cacheSize.getAndIncrement();
+ }
+
+ return oldSubentry;
+ }
+
+
+ /**
+ * Tells if there is a Subentry associated with a Dn
+ * @param dn The Dn
+ * @return True if a Subentry is found
+ */
+ /* No qualifier */ boolean hasSubentry( Dn dn )
+ {
+ return cache.containsKey( dn );
+ }
+
+
+ /**
+ * @return An Iterator over the Subentry's DNs
+ */
+ public Iterator<Dn> iterator()
+ {
+ return cache.keySet().iterator();
+ }
+
+
+ /**
+ * @return The number of elements in the cache
+ */
+ public int getCacheSize()
+ {
+ return cacheSize.get();
+ }
+}