Return-Path: Delivered-To: apmail-directory-commits-archive@www.apache.org Received: (qmail 96190 invoked from network); 18 Jan 2007 18:46:23 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 18 Jan 2007 18:46:23 -0000 Received: (qmail 97226 invoked by uid 500); 18 Jan 2007 18:46:30 -0000 Delivered-To: apmail-directory-commits-archive@directory.apache.org Received: (qmail 97173 invoked by uid 500); 18 Jan 2007 18:46:30 -0000 Mailing-List: contact commits-help@directory.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@directory.apache.org Delivered-To: mailing list commits@directory.apache.org Received: (qmail 97162 invoked by uid 99); 18 Jan 2007 18:46:30 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 18 Jan 2007 10:46:30 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 18 Jan 2007 10:46:23 -0800 Received: by eris.apache.org (Postfix, from userid 65534) id B40751A981A; Thu, 18 Jan 2007 10:45:18 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r497531 - /directory/branches/apacheds/1.0/core/src/main/java/org/apache/directory/server/core/schema/SchemaService.java Date: Thu, 18 Jan 2007 18:45:18 -0000 To: commits@directory.apache.org From: elecharny@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070118184518.B40751A981A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: elecharny Date: Thu Jan 18 10:45:17 2007 New Revision: 497531 URL: http://svn.apache.org/viewvc?view=rev&rev=497531 Log: Fixed DIRSERVER-758 Modified: directory/branches/apacheds/1.0/core/src/main/java/org/apache/directory/server/core/schema/SchemaService.java Modified: directory/branches/apacheds/1.0/core/src/main/java/org/apache/directory/server/core/schema/SchemaService.java URL: http://svn.apache.org/viewvc/directory/branches/apacheds/1.0/core/src/main/java/org/apache/directory/server/core/schema/SchemaService.java?view=diff&rev=497531&r1=497530&r2=497531 ============================================================================== --- directory/branches/apacheds/1.0/core/src/main/java/org/apache/directory/server/core/schema/SchemaService.java (original) +++ directory/branches/apacheds/1.0/core/src/main/java/org/apache/directory/server/core/schema/SchemaService.java Thu Jan 18 10:45:17 2007 @@ -505,7 +505,6 @@ return false; } - /** * Checks to see if removing a set of attributes from an entry completely removes * that attribute's values. If change has zero size then all attributes are @@ -1180,6 +1179,7 @@ alterObjectClasses( attrs.get( "objectClass" ), this.globalRegistries.getObjectClassRegistry() ); assertRequiredAttributesPresent( attrs ); assertNumberOfAttributeValuesValid( attrs ); + assertAllAttributesAllowed( attrs ); next.add(normName, attrs ); } @@ -1241,7 +1241,35 @@ } } } + + /** + * Checks to see if an attribute is required by as determined from an entry's + * set of objectClass attribute values. + * + * @param attrId the attribute to test if required by a set of objectClass values + * @param objectClass the objectClass values + * @return true if the objectClass values require the attribute, false otherwise + * @throws NamingException if the attribute is not recognized + */ + private void assertAllAttributesAllowed( Attributes attributes ) throws NamingException + { + Set allowed = getAllowedAttributes( attributes.get( "objectClass" ), + globalRegistries.getObjectClassRegistry() ); + NamingEnumeration attrs = attributes.getAll(); + + while ( attrs.hasMoreElements() ) + { + Attribute attribute = (Attribute)attrs.nextElement(); + + if ( !allowed.contains( attribute.getID() ) ) + { + throw new LdapSchemaViolationException( "Attribute " + + attribute.getID() + " not declared in entry's objectClasses.", + ResultCodeEnum.OBJECTCLASSVIOLATION ); + } + } + } private static final AttributeType[] EMPTY_ATTRIBUTE_TYPE_ARRAY = new AttributeType[0]; @@ -1267,6 +1295,28 @@ return attributeTypes; } + /** + * Uses the objectClass registry to ascend super classes and collect + * all attributeTypes within must lists until top is reached on each + * parent. + */ + private static final Set getAllowedAttributes( Attribute objectClass, + ObjectClassRegistry registry ) throws NamingException + { + AttributeType[] attributeTypes; + Set set = new HashSet(); + + for ( int ii = 0; ii < objectClass.size(); ii++ ) + { + String ocString = ( String ) objectClass.get( ii ); + ObjectClass oc = registry.lookup( ocString ); + infuseMustList( set, oc ); + infuseMayList( set, oc ); + } + + return set; + } + /** * Recursive method that finds all the required attributes for an @@ -1308,6 +1358,50 @@ for ( int ii = 0; ii < parents.length; ii++ ) { infuseMustList( set, parents[ii] ); + } + } + + /** + * Recursive method that finds all the required attributes for an + * objectClass and infuses them into the provided non-null set. + * + * @param set set to infuse attributeTypes into + * @param oc the objectClass to ascent the polymorphic inheritance tree of + */ + private static final void infuseMayList( Set set, ObjectClass oc ) throws NamingException + { + // ignore top + if ( oc.getName().equalsIgnoreCase( "top" ) ) + { + return; + } + + // add all the required attributes for this objectClass + AttributeType[] attributeTypes = oc.getMayList(); + + for (int i = 0; i < attributeTypes.length; i++ ) + { + set.add( attributeTypes[i] ); + } + + // don't bother ascending if no parents exist + ObjectClass[] parents = oc.getSuperClasses(); + + if ( parents == null || parents.length == 0 ) + { + return; + } + + // save on a for loop + if ( parents.length == 1 ) + { + infuseMayList( set, parents[0] ); + return; + } + + for ( int ii = 0; ii < parents.length; ii++ ) + { + infuseMayList( set, parents[ii] ); } } }