Author: elecharny
Date: Sat Dec 22 14:10:36 2007
New Revision: 606503
URL: http://svn.apache.org/viewvc?rev=606503&view=rev
Log:
o In NormalizingVisitor :
- The normalizeValue method does not anymore make a difference between an OID or a Name for the attributeType
o In OperationalAttributeInterceptor :
- Changed the add() operation to use the ServerEntry API.
- Added a reference to the AttributeRegistry
o In SchemaInterceptor :
- Renamed log to LOG
- Added a reference to attributeTypeRegistry
- Changed the code which handle the filters to transform a String value to a byte[] if the AT is not H/R, and vice-versa, adding a checkFilter() method for that
- Added the checkHumanReadable() and checkNotHumanReadable() methods for the same purpose as the checkFilter() method
- Major rewrite of the assertHumanReadable() method to take care of the value type, calling the two added methods
o In the apacheds-core pom.xml :
- Added a dependency to the apacheds-core-entry project
o In AbstractServerAttribute :
- Replaced the Values storage from a Set to a List, to keep the ordering of values
o In DefaultServerAttribute :
- Instead of throwing an Excpetion when we add an binary value into an H/R attribute, just log a warning and add it after trying to convert the byte[] to a String
o In ServerEntryUtils :
- Fixed a class cast exception in the toAttributesImpl() method
- the toServerAttribute() and toServerEntry() methods now throw a InvalidAttributeIdentifierException if the AT does not exist
o In DIRSERVER169IT and SearchIT :
- Fixed some warnings using generics
o In CompareConcreteName :
- Added some logs
- Added an unescape() private method used to unescape binary values expressed as a String ( "\12" will be transformed to 0x12 )
- Modified the normalizeByName() methods to take care of the value kind considering the H/R of the AttributeType
Modified:
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/AbstractServerAttribute.java
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/DefaultServerAttribute.java
directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntryUtils.java
directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/DIRSERVER169IT.java
directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/SearchIT.java
directory/apacheds/branches/bigbang/core/pom.xml
directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/normalization/NormalizingVisitor.java
directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/operational/OperationalAttributeInterceptor.java
directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java
directory/apacheds/branches/bigbang/schema-registries/src/main/java/org/apache/directory/server/schema/ConcreteNameComponentNormalizer.java
Modified: directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/AbstractServerAttribute.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/AbstractServerAttribute.java?rev=606503&r1=606502&r2=606503&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/AbstractServerAttribute.java (original)
+++ directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/AbstractServerAttribute.java Sat Dec 22 14:10:36 2007
@@ -29,8 +29,10 @@
import javax.naming.NamingException;
import javax.naming.directory.InvalidAttributeValueException;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Set;
@@ -47,7 +49,7 @@
private static final Logger LOG = LoggerFactory.getLogger( AbstractServerAttribute.class );
/** The set of contained values */
- protected Set<ServerValue<?>> values = new HashSet<ServerValue<?>>();
+ protected List<ServerValue<?>> values = new ArrayList<ServerValue<?>>();
/** The associated AttributeType */
protected AttributeType attributeType;
Modified: directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/DefaultServerAttribute.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/DefaultServerAttribute.java?rev=606503&r1=606502&r2=606503&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/DefaultServerAttribute.java (original)
+++ directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/DefaultServerAttribute.java Sat Dec 22 14:10:36 2007
@@ -23,6 +23,7 @@
import org.apache.directory.shared.ldap.entry.EntryAttribute;
import org.apache.directory.shared.ldap.entry.StringValue;
import org.apache.directory.shared.ldap.schema.AttributeType;
+import org.apache.directory.shared.ldap.util.StringTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -302,8 +303,8 @@
else
{
String message = "The value must be a String, as its AttributeType is H/R";
- LOG.error( message );
- throw new InvalidAttributeValueException( message );
+ LOG.warn( message );
+ return add( new ServerBinaryValue( attributeType, StringTools.getBytesUtf8( val ) ) );
}
}
Modified: directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntryUtils.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntryUtils.java?rev=606503&r1=606502&r2=606503&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntryUtils.java (original)
+++ directory/apacheds/branches/bigbang/core-entry/src/main/java/org/apache/directory/server/core/entry/ServerEntryUtils.java Sat Dec 22 14:10:36 2007
@@ -26,6 +26,7 @@
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.InvalidAttributeIdentifierException;
import org.apache.directory.server.schema.registries.Registries;
import org.apache.directory.shared.ldap.entry.EntryAttribute;
@@ -63,7 +64,7 @@
for ( Iterator<ServerValue<?>> iter = attr.iterator(); iter.hasNext();)
{
ServerValue<?> value = iter.next();
- attribute.add( value );
+ attribute.add( value.get() );
}
attributes.put( attribute );
@@ -80,8 +81,11 @@
* @param registries The registries, needed ro build a ServerEntry
* @param dn The DN which is needed by the ServerEntry
* @return An instance of a ServerEntry object
+ *
+ * @throws InvalidAttributeIdentifierException If we had an incorrect attribute
*/
public static DefaultServerAttribute toServerAttribute( Attribute attribute, AttributeType attributeType )
+ throws InvalidAttributeIdentifierException
{
try
{
@@ -121,8 +125,11 @@
* @param registries The registries, needed ro build a ServerEntry
* @param dn The DN which is needed by the ServerEntry
* @return An instance of a ServerEntry object
+ *
+ * @throws InvalidAttributeIdentifierException If we get an invalid attribute
*/
- public static DefaultServerEntry toServerEntry( Attributes attributes, LdapDN dn, Registries registries )
+ public static DefaultServerEntry toServerEntry( Attributes attributes, LdapDN dn, Registries registries )
+ throws InvalidAttributeIdentifierException
{
if ( ( attributes instanceof BasicAttributes ) || ( attributes instanceof AttributesImpl ) )
{
@@ -133,6 +140,7 @@
for ( NamingEnumeration<? extends Attribute> attrs = attributes.getAll(); attrs.hasMoreElements(); )
{
Attribute attr = attrs.nextElement();
+
AttributeType attributeType = registries.getAttributeTypeRegistry().lookup( attr.getID() );
DefaultServerAttribute serverAttribute = ServerEntryUtils.toServerAttribute( attr, attributeType );
@@ -146,7 +154,7 @@
}
catch ( NamingException ne )
{
- return null;
+ throw new InvalidAttributeIdentifierException( ne.getMessage() );
}
}
else
Modified: directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/DIRSERVER169IT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/DIRSERVER169IT.java?rev=606503&r1=606502&r2=606503&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/DIRSERVER169IT.java (original)
+++ directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/DIRSERVER169IT.java Sat Dec 22 14:10:36 2007
@@ -100,9 +100,9 @@
SearchControls ctls = new SearchControls();
String searchBase = "ou=people";
- NamingEnumeration results = ctx.search( searchBase, "(uid=bob)", ctls );
+ NamingEnumeration<SearchResult> results = ctx.search( searchBase, "(uid=bob)", ctls );
assertTrue( results.hasMore() );
- SearchResult searchResult = ( SearchResult ) results.next();
+ SearchResult searchResult = results.next();
StringBuffer userDn = new StringBuffer();
userDn.append( searchResult.getName() );
@@ -147,8 +147,8 @@
ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
String filter = "(userPassword={0})";
- NamingEnumeration results = ctx.search( "uid=bob,ou=people", filter, new Object[]
- { "bobspassword" }, ctls );
+ NamingEnumeration<SearchResult> results = ctx.search( "uid=bob,ou=people", filter, new Object[]
+ { "bobspassword" }, ctls );
// We should have a match
assertTrue( results.hasMore() );
Modified: directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/SearchIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/SearchIT.java?rev=606503&r1=606502&r2=606503&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/SearchIT.java (original)
+++ directory/apacheds/branches/bigbang/core-integ/src/test/java/org/apache/directory/server/core/jndi/SearchIT.java Sat Dec 22 14:10:36 2007
@@ -692,9 +692,9 @@
// Search for kate by cn first
SearchControls controls = new SearchControls();
controls.setSearchScope( SearchControls.ONELEVEL_SCOPE );
- NamingEnumeration enm = sysRoot.search( "", "(cn=Kate Bush)", controls );
+ NamingEnumeration<SearchResult> enm = sysRoot.search( "", "(cn=Kate Bush)", controls );
assertTrue( enm.hasMore() );
- SearchResult sr = ( SearchResult ) enm.next();
+ SearchResult sr = enm.next();
assertNotNull( sr );
assertFalse( enm.hasMore() );
assertEquals( "cn=Kate Bush,ou=system", sr.getName() );
Modified: directory/apacheds/branches/bigbang/core/pom.xml
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/pom.xml?rev=606503&r1=606502&r2=606503&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core/pom.xml (original)
+++ directory/apacheds/branches/bigbang/core/pom.xml Sat Dec 22 14:10:36 2007
@@ -48,6 +48,12 @@
<dependency>
<groupId>org.apache.directory.server</groupId>
+ <artifactId>apacheds-core-entry</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.directory.server</groupId>
<artifactId>apacheds-schema-registries</artifactId>
<version>${pom.version}</version>
</dependency>
Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/normalization/NormalizingVisitor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/normalization/NormalizingVisitor.java?rev=606503&r1=606502&r2=606503&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/normalization/NormalizingVisitor.java (original)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/normalization/NormalizingVisitor.java Sat Dec 22 14:10:36 2007
@@ -21,7 +21,6 @@
import org.apache.directory.server.schema.registries.OidRegistry;
-import org.apache.directory.shared.asn1.primitives.OID;
import org.apache.directory.shared.ldap.filter.AndNode;
import org.apache.directory.shared.ldap.filter.BranchNode;
import org.apache.directory.shared.ldap.filter.ExprNode;
@@ -88,36 +87,18 @@
{
Object normalized;
- if ( OID.isOID( attribute ) )
- {
- if ( value instanceof String )
- {
- normalized = ncn.normalizeByOid( attribute, ( String ) value );
- }
- else if ( value instanceof byte [] )
- {
- normalized = ncn.normalizeByOid( attribute, ( byte[] ) value );
- }
- else
- {
- normalized = ncn.normalizeByOid( attribute, value.toString() );
- }
- }
- else
- {
- if ( value instanceof String )
- {
- normalized = ncn.normalizeByName( attribute, ( String ) value );
- }
- else if ( value instanceof byte [] )
- {
- normalized = ncn.normalizeByName( attribute, ( byte[] ) value );
- }
- else
- {
- normalized = ncn.normalizeByName( attribute, value.toString() );
- }
- }
+ if ( value instanceof String )
+ {
+ normalized = ncn.normalizeByName( attribute, ( String ) value );
+ }
+ else if ( value instanceof byte [] )
+ {
+ normalized = ncn.normalizeByName( attribute, ( byte[] ) value );
+ }
+ else
+ {
+ normalized = ncn.normalizeByOid( attribute, value.toString() );
+ }
return normalized;
}
Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/operational/OperationalAttributeInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/operational/OperationalAttributeInterceptor.java?rev=606503&r1=606502&r2=606503&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/operational/OperationalAttributeInterceptor.java (original)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/operational/OperationalAttributeInterceptor.java Sat Dec 22 14:10:36 2007
@@ -27,6 +27,9 @@
import org.apache.directory.server.constants.ApacheSchemaConstants;
import org.apache.directory.server.core.DirectoryService;
+import org.apache.directory.server.core.entry.DefaultServerAttribute;
+import org.apache.directory.server.core.entry.DefaultServerEntry;
+import org.apache.directory.server.core.entry.ServerEntryUtils;
import org.apache.directory.server.core.enumeration.SearchResultFilter;
import org.apache.directory.server.core.enumeration.SearchResultFilteringEnumeration;
import org.apache.directory.server.core.interceptor.BaseInterceptor;
@@ -43,6 +46,7 @@
import org.apache.directory.server.core.invocation.Invocation;
import org.apache.directory.server.core.invocation.InvocationStack;
import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
+import org.apache.directory.server.schema.registries.Registries;
import org.apache.directory.shared.ldap.constants.SchemaConstants;
import org.apache.directory.shared.ldap.message.AttributeImpl;
import org.apache.directory.shared.ldap.message.AttributesImpl;
@@ -106,6 +110,8 @@
private DirectoryService service;
private LdapDN subschemaSubentryDn;
+
+ private Registries registries;
/**
@@ -119,7 +125,8 @@
public void init( DirectoryService directoryService ) throws NamingException
{
service = directoryService;
- registry = directoryService.getRegistries().getAttributeTypeRegistry();
+ registries = directoryService.getRegistries();
+ registry = registries.getAttributeTypeRegistry();
// stuff for dealing with subentries (garbage for now)
String subschemaSubentry = ( String ) service.getPartitionNexus()
@@ -141,16 +148,18 @@
throws NamingException
{
String principal = getPrincipal().getName();
- Attributes entry = opContext.getEntry();
+
+ DefaultServerEntry entry = ServerEntryUtils.toServerEntry( opContext.getEntry(), opContext.getDn(), registries );
- Attribute attribute = new AttributeImpl( SchemaConstants.CREATORS_NAME_AT );
+ DefaultServerAttribute attribute = new DefaultServerAttribute( registry.lookup( SchemaConstants.CREATORS_NAME_AT ) );
attribute.add( principal );
entry.put( attribute );
- attribute = new AttributeImpl( SchemaConstants.CREATE_TIMESTAMP_AT );
+ attribute = new DefaultServerAttribute( registry.lookup( SchemaConstants.CREATE_TIMESTAMP_AT ) );
attribute.add( DateUtils.getGeneralizedTime() );
entry.put( attribute );
-
+
+ opContext.setEntry( ServerEntryUtils.toAttributesImpl( entry ) );
nextInterceptor.add( opContext );
}
Modified: directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java?rev=606503&r1=606502&r2=606503&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java (original)
+++ directory/apacheds/branches/bigbang/core/src/main/java/org/apache/directory/server/core/schema/SchemaInterceptor.java Sat Dec 22 14:10:36 2007
@@ -49,10 +49,18 @@
import org.apache.directory.shared.ldap.exception.LdapNameNotFoundException;
import org.apache.directory.shared.ldap.exception.LdapNoSuchAttributeException;
import org.apache.directory.shared.ldap.exception.LdapSchemaViolationException;
+import org.apache.directory.shared.ldap.filter.ApproximateNode;
+import org.apache.directory.shared.ldap.filter.AssertionNode;
+import org.apache.directory.shared.ldap.filter.BranchNode;
import org.apache.directory.shared.ldap.filter.EqualityNode;
import org.apache.directory.shared.ldap.filter.ExprNode;
+import org.apache.directory.shared.ldap.filter.ExtensibleNode;
+import org.apache.directory.shared.ldap.filter.GreaterEqNode;
+import org.apache.directory.shared.ldap.filter.LessEqNode;
import org.apache.directory.shared.ldap.filter.PresenceNode;
+import org.apache.directory.shared.ldap.filter.ScopeNode;
import org.apache.directory.shared.ldap.filter.SimpleNode;
+import org.apache.directory.shared.ldap.filter.SubstringNode;
import org.apache.directory.shared.ldap.message.AttributeImpl;
import org.apache.directory.shared.ldap.message.CascadeControl;
import org.apache.directory.shared.ldap.message.ModificationItemImpl;
@@ -108,7 +116,7 @@
public class SchemaInterceptor extends BaseInterceptor
{
/** The LoggerFactory used by this Interceptor */
- private static Logger log = LoggerFactory.getLogger( SchemaInterceptor.class );
+ private static Logger LOG = LoggerFactory.getLogger( SchemaInterceptor.class );
private static final String[] SCHEMA_SUBENTRY_RETURN_ATTRIBUTES =
new String[] { SchemaConstants.ALL_OPERATIONAL_ATTRIBUTES, SchemaConstants.ALL_USER_ATTRIBUTES };
@@ -117,7 +125,7 @@
/** Speedup for logs */
- private static final boolean IS_DEBUG = log.isDebugEnabled();
+ private static final boolean IS_DEBUG = LOG.isDebugEnabled();
/**
* the root nexus to all database partitions
@@ -138,6 +146,11 @@
*/
private Registries registries;
+ /**
+ * the global attributeType registry
+ */
+ private AttributeTypeRegistry attributeTypeRegistry;
+
/** A normalized form for the SubschemaSubentry DN */
private String subschemaSubentryDnNorm;
@@ -176,35 +189,36 @@
{
if ( IS_DEBUG )
{
- log.debug( "Initializing SchemaInterceptor..." );
+ LOG.debug( "Initializing SchemaInterceptor..." );
}
nexus = directoryService.getPartitionNexus();
registries = directoryService.getRegistries();
+ attributeTypeRegistry = registries.getAttributeTypeRegistry();
binaryAttributeFilter = new BinaryAttributeFilter();
topFilter = new TopFilter();
filters.add( binaryAttributeFilter );
filters.add( topFilter );
schemaBaseDN = new LdapDN( ServerDNConstants.OU_SCHEMA_DN );
- schemaBaseDN.normalize( registries.getAttributeTypeRegistry().getNormalizerMapping() );
+ schemaBaseDN.normalize( attributeTypeRegistry.getNormalizerMapping() );
schemaService = directoryService.getSchemaService();
schemaManager = directoryService.getSchemaService().getSchemaControl();
// stuff for dealing with subentries (garbage for now)
String subschemaSubentry = ( String ) nexus.getRootDSE( null ).get( SchemaConstants.SUBSCHEMA_SUBENTRY_AT ).get();
LdapDN subschemaSubentryDn = new LdapDN( subschemaSubentry );
- subschemaSubentryDn.normalize( registries.getAttributeTypeRegistry().getNormalizerMapping() );
+ subschemaSubentryDn.normalize( attributeTypeRegistry.getNormalizerMapping() );
subschemaSubentryDnNorm = subschemaSubentryDn.getNormName();
schemaModificationAttributesDN = new LdapDN( "cn=schemaModifications,ou=schema" );
- schemaModificationAttributesDN.normalize( registries.getAttributeTypeRegistry().getNormalizerMapping() );
+ schemaModificationAttributesDN.normalize( attributeTypeRegistry.getNormalizerMapping() );
computeSuperiors();
if ( IS_DEBUG )
{
- log.debug( "SchemaInterceptor Initialized !" );
+ LOG.debug( "SchemaInterceptor Initialized !" );
}
}
@@ -431,7 +445,7 @@
String oid = registries.getOidRegistry().getOid( attribute );
// The attribute must be an AttributeType
- if ( registries.getAttributeTypeRegistry().hasAttributeType( oid ) )
+ if ( attributeTypeRegistry.hasAttributeType( oid ) )
{
if ( !filteredAttrs.containsKey( oid ) )
{
@@ -482,6 +496,161 @@
searchCtls.setReturningAttributes( newAttributesList );
}
+
+
+ private Object convert( String id, Object value ) throws NamingException
+ {
+ AttributeType at = attributeTypeRegistry.lookup( id );
+
+ if ( at.getSyntax().isHumanReadable() )
+ {
+ if ( value instanceof byte[] )
+ {
+ try
+ {
+ String valStr = new String( (byte[])value, "UTF-8" );
+ return valStr;
+ }
+ catch ( UnsupportedEncodingException uee )
+ {
+ String message = "The value stored in an Human Readable attribute as a byte[] should be convertible to a String";
+ LOG.error( message );
+ throw new NamingException( message );
+ }
+ }
+ }
+ else
+ {
+ if ( value instanceof String )
+ {
+ try
+ {
+ byte[] valBytes = ((String)value).getBytes( "UTF-8" );
+ return valBytes;
+ }
+ catch ( UnsupportedEncodingException uee )
+ {
+ String message = "The value stored in a non Human Readable attribute as a String should be convertible to a byte[]";
+ LOG.error( message );
+ throw new NamingException( message );
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Check that the filter values are compatible with the AttributeType. Typically,
+ * a HumanReadible filter should have a String value. The substring filter should
+ * not be used with binary attributes.
+ */
+ private void checkFilter( ExprNode filter ) throws NamingException
+ {
+ if ( filter == null )
+ {
+ String message = "A filter should not be null";
+ LOG.error( message );
+ throw new NamingException( message );
+ }
+
+ if ( filter.isLeaf() )
+ {
+ if ( filter instanceof EqualityNode )
+ {
+ EqualityNode node = ((EqualityNode)filter);
+ Object value = node.getValue();
+
+ Object newValue = convert( node.getAttribute(), value );
+
+ if ( newValue != null )
+ {
+ node.setValue( newValue );
+ }
+ }
+ else if ( filter instanceof SubstringNode )
+ {
+ SubstringNode node = ((SubstringNode)filter);
+
+ if ( ! attributeTypeRegistry.lookup( node.getAttribute() ).getSyntax().isHumanReadable() )
+ {
+ String message = "A Substring filter should be used only on Human Readable attributes";
+ LOG.error( message );
+ throw new NamingException( message );
+ }
+ }
+ else if ( filter instanceof PresenceNode )
+ {
+ // Nothing to do
+ }
+ else if ( filter instanceof GreaterEqNode )
+ {
+ GreaterEqNode node = ((GreaterEqNode)filter);
+ Object value = node.getValue();
+
+ Object newValue = convert( node.getAttribute(), value );
+
+ if ( newValue != null )
+ {
+ node.setValue( newValue );
+ }
+
+ }
+ else if ( filter instanceof LessEqNode )
+ {
+ LessEqNode node = ((LessEqNode)filter);
+ Object value = node.getValue();
+
+ Object newValue = convert( node.getAttribute(), value );
+
+ if ( newValue != null )
+ {
+ node.setValue( newValue );
+ }
+ }
+ else if ( filter instanceof ExtensibleNode )
+ {
+ ExtensibleNode node = ((ExtensibleNode)filter);
+
+ if ( ! attributeTypeRegistry.lookup( node.getAttribute() ).getSyntax().isHumanReadable() )
+ {
+ String message = "A Extensible filter should be used only on Human Readable attributes";
+ LOG.error( message );
+ throw new NamingException( message );
+ }
+ }
+ else if ( filter instanceof ApproximateNode )
+ {
+ ApproximateNode node = ((ApproximateNode)filter);
+ Object value = node.getValue();
+
+ Object newValue = convert( node.getAttribute(), value );
+
+ if ( newValue != null )
+ {
+ node.setValue( newValue );
+ }
+ }
+ else if ( filter instanceof AssertionNode )
+ {
+ // Nothing to do
+ return;
+ }
+ else if ( filter instanceof ScopeNode )
+ {
+ // Nothing to do
+ return;
+ }
+ }
+ else
+ {
+ // Recursively iterate through all the children.
+ for ( ExprNode child:((BranchNode)filter).getChildren() )
+ {
+ checkFilter( child );
+ }
+ }
+ }
/**
@@ -497,6 +666,9 @@
// to RFC 2251, chap. 4.5.1. Basically, all unknown attributes are removed
// from the list
filterAttributesToReturn( searchCtls );
+
+ // We also have to check the H/R flag for the filter attributes
+ checkFilter( filter );
String baseNormForm = ( base.isNormalized() ? base.getNormName() : base.toNormName() );
@@ -749,13 +921,13 @@
// We must select all the ObjectClasses, except 'top',
// but including all the inherited ObjectClasses
- NamingEnumeration<String> ocs = (NamingEnumeration<String>)objectClasses.getAll();
+ NamingEnumeration<?> ocs = objectClasses.getAll();
boolean hasExtensibleObject = false;
while ( ocs.hasMoreElements() )
{
- String objectClassName = ocs.nextElement();
+ String objectClassName = (String)ocs.nextElement();
if ( SchemaConstants.TOP_OC.equals( objectClassName ) )
{
@@ -857,11 +1029,11 @@
objectClassesUP.add( SchemaConstants.TOP_OC );
// Construct the new list of ObjectClasses
- NamingEnumeration<String> ocList = (NamingEnumeration<String>)objectClassAttr.getAll();
+ NamingEnumeration<?> ocList = objectClassAttr.getAll();
while ( ocList.hasMoreElements() )
{
- String ocName = ocList.nextElement();
+ String ocName = (String)ocList.nextElement();
if ( !ocName.equalsIgnoreCase( SchemaConstants.TOP_OC ) )
{
@@ -976,7 +1148,7 @@
if ( entry == null )
{
- log.error( "No entry with this name :{}", name );
+ LOG.error( "No entry with this name :{}", name );
throw new LdapNameNotFoundException( "The entry which name is " + name + " is not found." );
}
@@ -1045,7 +1217,6 @@
}
ObjectClassRegistry ocRegistry = this.registries.getObjectClassRegistry();
- AttributeTypeRegistry atRegistry = this.registries.getAttributeTypeRegistry();
// -------------------------------------------------------------------
// DIRSERVER-646 Fix: Replacing an unknown attribute with no values
@@ -1055,7 +1226,7 @@
if ( ( mods.size() == 1 ) &&
( mods.get( 0 ).getAttribute().size() == 0 ) &&
( mods.get( 0 ).getModificationOp() == DirContext.REPLACE_ATTRIBUTE ) &&
- ! atRegistry.hasAttributeType( mods.get( 0 ).getAttribute().getID() ) )
+ ! attributeTypeRegistry.hasAttributeType( mods.get( 0 ).getAttribute().getID() ) )
{
return;
}
@@ -1067,7 +1238,7 @@
int modOp = mod.getModificationOp();
Attribute change = mod.getAttribute();
- if ( !atRegistry.hasAttributeType( change.getID() ) &&
+ if ( !attributeTypeRegistry.hasAttributeType( change.getID() ) &&
!objectClass.contains( SchemaConstants.EXTENSIBLE_OBJECT_OC ) )
{
throw new LdapInvalidAttributeIdentifierException();
@@ -1075,7 +1246,7 @@
// We will forbid modification of operational attributes which are not
// user modifiable.
- AttributeType attributeType = atRegistry.lookup( change.getID() );
+ AttributeType attributeType = attributeTypeRegistry.lookup( change.getID() );
if ( !attributeType.isCanUserModify() )
{
@@ -1114,7 +1285,7 @@
case DirContext.REMOVE_ATTRIBUTE :
if ( tmpEntry.get( change.getID() ) == null )
{
- log.error( "Trying to remove an non-existant attribute: " + change.getID() );
+ LOG.error( "Trying to remove an non-existant attribute: " + change.getID() );
throw new LdapNoSuchAttributeException();
}
@@ -1125,7 +1296,7 @@
// Check that we aren't removing a MUST attribute
if ( isRequired( change.getID(), objectClass ) )
{
- log.error( "Trying to remove a required attribute: " + change.getID() );
+ LOG.error( "Trying to remove a required attribute: " + change.getID() );
throw new LdapSchemaViolationException( ResultCodeEnum.OBJECT_CLASS_VIOLATION );
}
}
@@ -1135,7 +1306,7 @@
// if so then we have a schema violation that must be thrown
if ( isRequired( change.getID(), objectClass ) && isCompleteRemoval( change, entry ) )
{
- log.error( "Trying to remove a required attribute: " + change.getID() );
+ LOG.error( "Trying to remove a required attribute: " + change.getID() );
throw new LdapSchemaViolationException( ResultCodeEnum.OBJECT_CLASS_VIOLATION );
}
@@ -1154,7 +1325,7 @@
// and if it's a MUST one, we should thow an exception
if ( ( modified.size() == 0 ) && isRequired( change.getID(), objectClass ) )
{
- log.error( "Trying to remove a required attribute: " + change.getID() );
+ LOG.error( "Trying to remove a required attribute: " + change.getID() );
throw new LdapSchemaViolationException( ResultCodeEnum.OBJECT_CLASS_VIOLATION );
}
@@ -1261,14 +1432,14 @@
if ( name.startsWith( schemaBaseDN ) )
{
- log.debug( "Modification attempt on schema partition {}: \n{}", name, opContext );
+ LOG.debug( "Modification attempt on schema partition {}: \n{}", name, opContext );
schemaManager.modify( name, mods, entry, targetEntry,
opContext.hasRequestControl( CascadeControl.CONTROL_OID ));
}
else if ( subschemaSubentryDnNorm.equals( name.getNormName() ) )
{
- log.debug( "Modification attempt on schema subentry {}: \n{}", name, opContext );
+ LOG.debug( "Modification attempt on schema subentry {}: \n{}", name, opContext );
schemaManager.modifySchemaSubentry( name, mods, entry, targetEntry,
opContext.hasRequestControl( CascadeControl.CONTROL_OID ) );
@@ -1323,9 +1494,9 @@
String id = list.next();
AttributeType type = null;
- if ( registries.getAttributeTypeRegistry().hasAttributeType( id ) )
+ if ( attributeTypeRegistry.hasAttributeType( id ) )
{
- type = registries.getAttributeTypeRegistry().lookup( id );
+ type = attributeTypeRegistry.lookup( id );
}
else
{
@@ -1407,7 +1578,7 @@
{
String name = attrEnum.nextElement();
- if ( !registries.getAttributeTypeRegistry().hasAttributeType( name ) )
+ if ( !attributeTypeRegistry.hasAttributeType( name ) )
{
throw new LdapInvalidAttributeIdentifierException( name + " not found in attribute registry!" );
}
@@ -1504,7 +1675,7 @@
String attrId = attribute.getID();
String attrOid = registries.getOidRegistry().getOid( attrId );
- AttributeType attributeType = registries.getAttributeTypeRegistry().lookup( attrOid );
+ AttributeType attributeType = attributeTypeRegistry.lookup( attrOid );
if ( !attributeType.isCollective() && ( attributeType.getUsage() == UsageEnum.USER_APPLICATIONS ) )
{
@@ -1552,9 +1723,7 @@
*/
private void assertNumberOfAttributeValuesValid( Attribute attribute ) throws InvalidAttributeValueException, NamingException
{
- AttributeTypeRegistry registry = this.registries.getAttributeTypeRegistry();
-
- if ( attribute.size() > 1 && registry.lookup( attribute.getID() ).isSingleValue() )
+ if ( attribute.size() > 1 && attributeTypeRegistry.lookup( attribute.getID() ).isSingleValue() )
{
throw new LdapInvalidAttributeValueException( "More than one value has been provided " +
"for the single-valued attribute: " + attribute.getID(), ResultCodeEnum.CONSTRAINT_VIOLATION );
@@ -1623,7 +1792,7 @@
if ( structuralObjectClasses.isEmpty() )
{
String message = "Entry " + dn + " does not contain a STRUCTURAL ObjectClass";
- log.error( message );
+ LOG.error( message );
throw new LdapSchemaViolationException( message, ResultCodeEnum.OBJECT_CLASS_VIOLATION );
}
@@ -1654,7 +1823,7 @@
if ( remaining.size() > 1 )
{
String message = "Entry " + dn + " contains more than one STRUCTURAL ObjectClass: " + remaining;
- log.error( message );
+ LOG.error( message );
throw new LdapSchemaViolationException( message, ResultCodeEnum.OBJECT_CLASS_VIOLATION );
}
}
@@ -1671,7 +1840,7 @@
{
Attribute attribute = attributes.nextElement();
- AttributeType attributeType = registries.getAttributeTypeRegistry().lookup( attribute.getID() );
+ AttributeType attributeType = attributeTypeRegistry.lookup( attribute.getID() );
SyntaxChecker syntaxChecker = registries.getSyntaxCheckerRegistry().lookup( attributeType.getSyntax().getOid() );
if ( syntaxChecker instanceof AcceptAllSyntaxChecker )
@@ -1697,7 +1866,7 @@
String message = "Attribute value '" +
(value instanceof String ? value : StringTools.dumpBytes( (byte[])value ) ) +
"' for attribute '" + attribute.getID() + "' is syntactically incorrect";
- log.info( message );
+ LOG.info( message );
throw new LdapInvalidAttributeValueException( message, ResultCodeEnum.INVALID_ATTRIBUTE_SYNTAX );
@@ -1706,102 +1875,138 @@
}
}
+ private boolean checkHumanReadable( Attribute attribute ) throws NamingException
+ {
+ Enumeration<?> values = attribute.getAll();
+ boolean isModified = false;
+
+ // Loop on each values
+ while ( values.hasMoreElements() )
+ {
+ Object value = values.nextElement();
+
+ if ( value instanceof String )
+ {
+ continue;
+ }
+ else if ( value instanceof byte[] )
+ {
+ // we have a byte[] value. It should be a String UTF-8 encoded
+ // Let's transform it
+ try
+ {
+ String valStr = new String( (byte[])value, "UTF-8" );
+ attribute.remove( value );
+ attribute.add( valStr );
+ isModified = true;
+ }
+ catch ( UnsupportedEncodingException uee )
+ {
+ throw new NamingException( "The value is not a valid String" );
+ }
+ }
+ else
+ {
+ throw new NamingException( "The value stored in an Human Readable attribute is not a String" );
+ }
+ }
+
+ return isModified;
+ }
+
+ private boolean checkNotHumanReadable( Attribute attribute ) throws NamingException
+ {
+ Enumeration<?> values = attribute.getAll();
+ boolean isModified = false;
+
+ // Loop on each values
+ while ( values.hasMoreElements() )
+ {
+ Object value = values.nextElement();
+
+ if ( value instanceof byte[] )
+ {
+ continue;
+ }
+ else if ( value instanceof String )
+ {
+ // We have a String value. It should be a byte[]
+ // Let's transform it
+ try
+ {
+ byte[] valBytes = ( (String)value ).getBytes( "UTF-8" );
+
+ attribute.remove( value );
+ attribute.add( valBytes );
+ isModified = true;
+ }
+ catch ( UnsupportedEncodingException uee )
+ {
+ String message = "The value stored in a not Human Readable attribute as a String should be convertible to a byte[]";
+ LOG.error( message );
+ throw new NamingException( message );
+ }
+ }
+ else
+ {
+ String message ="The value is not valid. It should be a String or a byte[]";
+ LOG.error( message );
+ throw new NamingException( message );
+ }
+ }
+
+ return isModified;
+ }
+
+
/**
* Check that all the attribute's values which are Human Readable can be transformed
- * to valid String if they are stored as byte[].
+ * to valid String if they are stored as byte[], and that non Human Readable attributes
+ * stored as String can be transformed to byte[]
*/
private void assertHumanReadable( Attributes entry ) throws NamingException
{
NamingEnumeration<? extends Attribute> attributes = entry.getAll();
- boolean isEntryModified = false;
- Attributes cloneEntry = null;
+ boolean isModified = false;
+
+ Attributes clonedEntry = null;
// First, loop on all attributes
while ( attributes.hasMoreElements() )
{
Attribute attribute = attributes.nextElement();
- AttributeType attributeType = registries.getAttributeTypeRegistry().lookup( attribute.getID() );
+ AttributeType attributeType = attributeTypeRegistry.lookup( attribute.getID() );
// If the attributeType is H-R, check all of its values
if ( attributeType.getSyntax().isHumanReadable() )
{
- Enumeration<?> values = attribute.getAll();
- Attribute clone = null;
- boolean isModified = false;
-
- // Loop on each values
- while ( values.hasMoreElements() )
+ isModified = checkHumanReadable( attribute );
+ }
+ else
+ {
+ isModified = checkNotHumanReadable( attribute );
+ }
+
+ // If we have a returned attribute, then we need to store it
+ // into a new entry
+ if ( isModified )
+ {
+ if ( clonedEntry == null )
{
- Object value = values.nextElement();
-
- if ( value instanceof String )
- {
- continue;
- }
- else if ( value instanceof byte[] )
- {
- // Ve have a byte[] value. It should be a String UTF-8 encoded
- // Let's transform it
- try
- {
- String valStr = new String( (byte[])value, "UTF-8" );
-
- if ( !isModified )
- {
- // Don't create useless clones. We only clone
- // if we have at least one value which is a byte[]
- isModified = true;
- clone = (Attribute)attribute.clone();
- }
-
- // Swap the value into the clone
- clone.remove( value );
- clone.add( valStr );
- }
- catch ( UnsupportedEncodingException uee )
- {
- throw new NamingException( "The value is not a valid String" );
- }
- }
- else
- {
- throw new NamingException( "The value stored in an Human Readable attribute is not a String" );
- }
+ clonedEntry = (Attributes)entry.clone();
}
+
+ // Switch the attributes
+ clonedEntry.put( attribute );
- // The attribute has been checked. If one of its value has been modified,
- // we have to modify the cloned Attributes/
- if ( isModified )
- {
- if ( !isEntryModified )
- {
- // Again, let's avoid useless cloning. If no attribute is H-R
- // or if no H-R value is stored as a byte[], we don't have to create a clone
- // of the entry
- cloneEntry = (Attributes)entry.clone();
- isEntryModified = true;
- }
-
- // Swap the attribute into the cloned entry
- cloneEntry.remove( attribute.getID() );
- cloneEntry.put( clone );
- }
+ isModified = false;
}
}
-
- // At the end, we now have to switch the entries, if it has been modified
- if ( isEntryModified )
+
+ if ( clonedEntry != null )
{
- attributes = cloneEntry.getAll();
-
- // We llop on all the attributes and modify them in the initial entry.
- while ( attributes.hasMoreElements() )
- {
- Attribute attribute = (Attribute)attributes.nextElement();
- entry.remove( attribute.getID() );
- entry.put( attribute );
- }
+ entry = clonedEntry;
}
}
}
Modified: directory/apacheds/branches/bigbang/schema-registries/src/main/java/org/apache/directory/server/schema/ConcreteNameComponentNormalizer.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/schema-registries/src/main/java/org/apache/directory/server/schema/ConcreteNameComponentNormalizer.java?rev=606503&r1=606502&r2=606503&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/schema-registries/src/main/java/org/apache/directory/server/schema/ConcreteNameComponentNormalizer.java (original)
+++ directory/apacheds/branches/bigbang/schema-registries/src/main/java/org/apache/directory/server/schema/ConcreteNameComponentNormalizer.java Sat Dec 22 14:10:36 2007
@@ -20,6 +20,8 @@
package org.apache.directory.server.schema;
+import java.io.UnsupportedEncodingException;
+
import javax.naming.NamingException;
import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
@@ -29,6 +31,9 @@
import org.apache.directory.shared.ldap.schema.MatchingRule;
import org.apache.directory.shared.ldap.schema.NoOpNormalizer;
import org.apache.directory.shared.ldap.schema.Normalizer;
+import org.apache.directory.shared.ldap.util.StringTools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
@@ -41,8 +46,12 @@
*/
public class ConcreteNameComponentNormalizer implements NameComponentNormalizer
{
+ /** The LoggerFactory used by this Interceptor */
+ private static Logger LOG = LoggerFactory.getLogger( ConcreteNameComponentNormalizer.class );
+
/** the at registry used to dynamically resolve Normalizers */
private final AttributeTypeRegistry attributeRegistry;
+
/** the oid registry used to dynamically resolve aliases to OIDs */
private final OidRegistry oidRegistry;
@@ -60,13 +69,75 @@
this.oidRegistry = oidRegistry;
}
+
+ private String unescape( String value )
+ {
+ char[] newVal = new char[value.length()];
+ int escaped = 0;
+ char high = 0;
+ char low = 0;
+ int pos = 0;
+
+ for ( char c:value.toCharArray() )
+ {
+ switch ( escaped )
+ {
+ case 0 :
+ if ( c == '\\' )
+ {
+ escaped = 1;
+ }
+ else
+ {
+ newVal[pos++] = c;
+ }
+
+ break;
+
+ case 1 :
+ escaped++;
+ high = c;
+ break;
+
+ case 2 :
+ escaped=0;
+ low = c;
+ newVal[pos++] = (char)StringTools.getHexValue( high, low );
+
+ }
+ }
+
+ return new String( newVal, 0, pos );
+ }
/**
* @see NameComponentNormalizer#normalizeByName(String, String)
*/
public Object normalizeByName( String name, String value ) throws NamingException
{
- return lookup( name ).normalize( value );
+ AttributeType attributeType = attributeRegistry.lookup( name );
+
+ if ( attributeType.getSyntax().isHumanReadable() )
+ {
+ return lookup( name ).normalize( value );
+ }
+ else
+ {
+ try
+ {
+ String unescaped = unescape( value );
+ byte[] valBytes = unescaped.getBytes( "UTF-8" );
+
+ return lookup( name ).normalize( valBytes );
+ }
+ catch ( UnsupportedEncodingException uee )
+ {
+ String message = "The value stored in a non Human Readable attribute as a String should be convertible to a byte[]";
+ LOG.error( message );
+ throw new NamingException( message );
+ }
+ }
+
}
@@ -75,7 +146,26 @@
*/
public Object normalizeByName( String name, byte[] value ) throws NamingException
{
- return lookup( name ).normalize( value );
+ AttributeType attributeType = attributeRegistry.lookup( name );
+
+ if ( !attributeType.getSyntax().isHumanReadable() )
+ {
+ return lookup( name ).normalize( value );
+ }
+ else
+ {
+ try
+ {
+ String valStr = new String( value, "UTF-8" );
+ return lookup( name ).normalize( valStr );
+ }
+ catch ( UnsupportedEncodingException uee )
+ {
+ String message = "The value stored in an Human Readable attribute as a byte[] should be convertible to a String";
+ LOG.error( message );
+ throw new NamingException( message );
+ }
+ }
}
|