directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From akaras...@apache.org
Subject svn commit: rev 30807 - in incubator/directory/snickers/trunk: ber-codec/src/java/org/apache/snickers/ber/primitives ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/search ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/bind ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/search
Date Wed, 28 Jul 2004 01:11:30 GMT
Author: akarasulu
Date: Tue Jul 27 18:11:29 2004
New Revision: 30807

Added:
   incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/EncoderUtils.java
  (contents, props changed)
   incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/search/SearchResponseDoneEncoder.java
  (contents, props changed)
   incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/search/SearchResponseEntryEncoder.java
  (contents, props changed)
   incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/search/SearchRequestEncoderTest.java
  (contents, props changed)
   incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/search/SearchResponseDoneEncoderTest.java
  (contents, props changed)
   incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/search/SearchResponseEntryEncoderTest.java
  (contents, props changed)
Modified:
   incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/primitives/PrimitiveUtils.java
   incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/search/SearchRequestEncoder.java
   incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/AbstractEncoderTest.java
   incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/bind/BindResponseEncoderTest.java
Log:
Commit changes ...

 o added boolean encoding methods to PrimitiveUtils
 o completed the search request encoder and tested it
 o completed search result entry encoder and tested it
 o completed search result done encoder and tested it



Modified: incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/primitives/PrimitiveUtils.java
==============================================================================
--- incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/primitives/PrimitiveUtils.java
(original)
+++ incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/primitives/PrimitiveUtils.java
Tue Jul 27 18:11:29 2004
@@ -33,6 +33,9 @@
     private static final int THREE_BYTE_MIN = -(1<<23);
     private static final int FOUR_BYTE_MAX  =  Integer.MAX_VALUE;
     private static final int FOUR_BYTE_MIN  =  Integer.MIN_VALUE;
+    private static final byte[] TRUE_ARRAY = new byte[] { ( byte ) 0xFF };
+    private static final byte[] FALSE_ARRAY = new byte[] { ( byte ) 0x00 };
+
 
 
     public static boolean berDecodeBoolean( byte value )
@@ -43,6 +46,36 @@
         }
 
         return true ;
+    }
+
+
+    /**
+     * Encodes a boolean as a byte following the stricter CER and DER
+     * requirements where true must be a value of 0xFF and false is 0x00.
+     *
+     * @param bool the boolean to encode
+     * @return 0xFF if bool is true, 0x00 if the bool is false
+     */
+    public static byte encodeBooleanAsByte( boolean bool )
+    {
+        return bool ? ( byte ) 0xFF : ( byte ) 0;
+    }
+
+
+    /**
+     * Encodes a boolean as a byte[] with one byte following the stricter CER
+     * and DER requirements where true must be a value of 0xFF and false is
+     * 0x00.  Although there is alway one byte returned we return a byte [] as
+     * a convenience since most of the time a byte[] is expected after encoding
+     * a primitive type.
+     *
+     * @param bool the boolean to encode
+     * @return a byte array of length 1 where the single byte is 0xFF if bool
+     * is true, 0x00 if the bool is false
+     */
+    public static byte[] encodeBoolean( boolean bool )
+    {
+        return bool ? TRUE_ARRAY : FALSE_ARRAY ;
     }
 
 

Added: incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/EncoderUtils.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/EncoderUtils.java
Tue Jul 27 18:11:29 2004
@@ -0,0 +1,102 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.snickers.ldap.encoder;
+
+import org.apache.snickers.ber.TupleEventConsumer;
+import org.apache.snickers.ber.TagEnum;
+import org.apache.snickers.ber.Tuple;
+import org.apache.snickers.ber.primitives.UniversalTag;
+import org.apache.snickers.ber.primitives.PrimitiveUtils;
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * Common utilities used by encoders.
+ * 
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory
+ *         Project</a> $Rev$
+ */
+public class EncoderUtils
+{
+    public static void encodePrimitive( String octets,
+                                        TupleEventConsumer consumer )
+    {
+        encodePrimitive( UniversalTag.OCTET_STRING, octets, consumer );
+    }
+
+
+    public static void encodePrimitive( TagEnum tag, String octets,
+                                        TupleEventConsumer consumer )
+    {
+        Tuple t = new Tuple();
+        t.setTag( tag, true );
+        consumer.tag( t );
+        ByteBuffer chunk = ByteBuffer.wrap( octets.getBytes() );
+        t.setLength( chunk.remaining() );
+        consumer.length( t );
+        t.setLastValueChunk( chunk );
+        consumer.chunkedValue( t, chunk );
+        consumer.finish( t );
+    }
+
+
+    public static void encodePrimitive( int intval,
+                                        TupleEventConsumer consumer )
+    {
+        encodePrimitive( UniversalTag.INTEGER, intval, consumer );
+    }
+
+
+    public static void encodePrimitive( TagEnum tag, int intval,
+                                        TupleEventConsumer consumer )
+    {
+        Tuple t = new Tuple();
+        t.setTag( tag, true );
+        consumer.tag( t );
+        ByteBuffer chunk = ByteBuffer.wrap(
+                PrimitiveUtils.encodeInt( intval ) );
+        t.setLength( chunk.remaining() );
+        consumer.length( t );
+        t.setLastValueChunk( chunk );
+        consumer.chunkedValue( t, chunk );
+        consumer.finish( t );
+    }
+
+
+    public static void encodePrimitive( boolean bool,
+                                        TupleEventConsumer consumer )
+    {
+        encodePrimitive( UniversalTag.BOOLEAN, bool, consumer );
+    }
+
+
+    public static void encodePrimitive( TagEnum tag, boolean bool,
+                                        TupleEventConsumer consumer )
+    {
+        Tuple t = new Tuple();
+        t.setTag( tag, true );
+        consumer.tag( t );
+        ByteBuffer chunk = ByteBuffer.wrap(
+                PrimitiveUtils.encodeBoolean( bool ) );
+        t.setLength( chunk.remaining() );
+        consumer.length( t );
+        t.setLastValueChunk( chunk );
+        consumer.chunkedValue( t, chunk );
+        consumer.finish( t );
+    }
+}

Modified: incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/search/SearchRequestEncoder.java
==============================================================================
--- incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/search/SearchRequestEncoder.java
(original)
+++ incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/search/SearchRequestEncoder.java
Tue Jul 27 18:11:29 2004
@@ -17,17 +17,18 @@
 package org.apache.snickers.ldap.encoder.search;
 
 
-import org.apache.snickers.ber.TupleEventProducer;
-import org.apache.snickers.ber.TupleEventConsumer;
-import org.apache.snickers.ber.Tuple;
-import org.apache.snickers.ber.Length;
+import org.apache.snickers.ber.*;
 import org.apache.snickers.ber.primitives.UniversalTag;
 import org.apache.snickers.ber.primitives.PrimitiveUtils;
 import org.apache.snickers.ldap.LdapTag;
+import org.apache.snickers.ldap.encoder.EncoderUtils;
 import org.apache.ldap.common.message.SearchRequest;
+import org.apache.ldap.common.filter.*;
 import org.apache.commons.codec.EncoderException;
 
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Iterator;
 
 
 /**
@@ -39,9 +40,13 @@
  */
 public class SearchRequestEncoder implements TupleEventProducer
 {
+    /** the consumer we send Tuple TLV events to */
     private TupleEventConsumer consumer = null;
+    /** the tuple for the topmost sequence */
     private Tuple top = new Tuple();
+    /** temporary tuple to work with */
     private Tuple tmp = new Tuple();
+    /** the tuple for the search sequence of elements */
     private Tuple search = new Tuple();
 
 
@@ -51,6 +56,9 @@
     }
 
 
+    /**
+     * Creates a search request stub encoder.
+     */
     public SearchRequestEncoder()
     {
         top.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
@@ -59,6 +67,12 @@
     }
 
 
+    /**
+     * Encodes a SearchRequest using BER.
+     *
+     * @param req the search request to encode
+     * @throws EncoderException if there are failures while encoding
+     */
     public void encode( SearchRequest req ) throws EncoderException
     {
         consumer.tag( top );
@@ -75,10 +89,255 @@
         consumer.finish( tmp );
 
 
-        // Start working the bind request structure here
-
+        // Start working the search request structure here
         consumer.tag( search );
         search.setLength( Length.INDEFINATE );
         consumer.length( search );
+
+        // Encode baseObject as LDAPDN
+        EncoderUtils.encodePrimitive( req.getBase(), consumer );
+
+        // Encode scope as ENUMERATION
+        EncoderUtils.encodePrimitive( UniversalTag.ENUMERATED,
+                req.getScope().getLdapValue(), consumer );
+
+        // Encode derefAliases as ENUMERATION
+        EncoderUtils.encodePrimitive( UniversalTag.ENUMERATED,
+                req.getDerefAliases().getValue(), consumer );
+
+        // Encode sizeLimit as INTEGER
+        EncoderUtils.encodePrimitive( req.getSizeLimit(), consumer );
+
+        // Encode timeLimit as INTEGER
+        EncoderUtils.encodePrimitive( req.getTimeLimit(), consumer );
+
+        // Encode typesOnly as BOOLEAN
+        EncoderUtils.encodePrimitive( req.getTypesOnly(), consumer );
+
+        // Encode the filter
+        encodeNode( req.getFilter() );
+
+        // Encode the attributes as AttributeDescriptionList
+        tmp.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
+        consumer.tag( tmp );
+        tmp.setLength( Length.INDEFINATE );
+        consumer.length( tmp );
+        Iterator list = req.getAttributes().iterator();
+        while( list.hasNext() )
+        {
+            EncoderUtils.encodePrimitive( ( String ) list.next(), consumer );
+        }
+        consumer.finish( tmp );
+
+        // finish off the search sequence
+        consumer.finish( search );
+
+        // finish off the pdu sequence
+        consumer.finish( top );
+    }
+
+
+
+    /**
+     * Recursively encodes a filter exression.
+     *
+     * @param filter the filter expression tree node to encode
+     */
+    private void encodeNode( ExprNode filter )
+    {
+        if ( filter.isLeaf() )
+        {
+            LeafNode node = ( LeafNode ) filter;
+
+            switch( node.getAssertionType() )
+            {
+                case( LeafNode.EQUALITY ):
+                    encode( LdapTag.CONTEXT_SPECIFIC_TAG_3,
+                            ( SimpleNode ) node );
+                    break;
+                case( LeafNode.SUBSTRING ):
+                    encode( ( SubstringNode ) node );
+                    break;
+                case( LeafNode.GREATEREQ ):
+                    encode( LdapTag.CONTEXT_SPECIFIC_TAG_5,
+                            ( SimpleNode ) node );
+                    break;
+                case( LeafNode.LESSEQ ):
+                    encode( LdapTag.CONTEXT_SPECIFIC_TAG_6,
+                            ( SimpleNode ) node );
+                    break;
+                case( LeafNode.PRESENCE ):
+                    PresenceNode presence = ( PresenceNode ) node;
+                    EncoderUtils.encodePrimitive(
+                            LdapTag.CONTEXT_SPECIFIC_TAG_7,
+                            presence.getAttribute(),
+                            consumer );
+                case( LeafNode.APPROXIMATE ):
+                    encode( LdapTag.CONTEXT_SPECIFIC_TAG_8,
+                            ( SimpleNode ) node );
+                    break;
+                case( LeafNode.EXTENSIBLE ):
+                    encode( ( ExtensibleNode ) node );
+                    break;
+                default:
+                    throw new IllegalArgumentException(
+                            "Unrecognized assertion type value: "
+                            + node.getAssertionType() );
+            }
+
+            return;
+        }
+
+        encodeBranchNode( ( BranchNode ) filter );
+    }
+
+
+    /**
+     * Encodes a MatchingRule Assertion expression within a filter: an
+     * extensibleMatch expression.
+     *
+     * @param node the extensibleMatch expression node to encode
+     */
+    private void encode( ExtensibleNode node )
+    {
+        if ( node.getMatchingRuleId() != null )
+        {
+            EncoderUtils.encodePrimitive( LdapTag.CONTEXT_SPECIFIC_TAG_1,
+                    node.getMatchingRuleId(), consumer );
+        }
+
+        if ( node.getAttribute() != null )
+        {
+            EncoderUtils.encodePrimitive( LdapTag.CONTEXT_SPECIFIC_TAG_2,
+                    node.getAttribute(), consumer );
+        }
+
+        EncoderUtils.encodePrimitive( LdapTag.CONTEXT_SPECIFIC_TAG_3,
+                node.getValue(), consumer );
+
+        EncoderUtils.encodePrimitive( LdapTag.CONTEXT_SPECIFIC_TAG_4,
+                node.dnAttributes(), consumer );
+    }
+
+
+    /**
+     * Encodes a SimpleNode representing an attribute value assertion pair with
+     * a simple operator.
+     *
+     * @param tag the tag to use for the AVA
+     * @param node the node containing the attribute description and value
+     */
+    private void encode( TagEnum tag, SimpleNode node )
+    {
+        Tuple t = new Tuple();
+        t.setTag( tag, false );
+        consumer.tag( t );
+        t.setLength( Length.INDEFINATE );
+        consumer.length( t );
+
+        EncoderUtils.encodePrimitive( node.getAttribute(), consumer );
+        EncoderUtils.encodePrimitive( node.getValue(), consumer );
+
+        consumer.finish( t );
+    }
+
+
+    /**
+     * Encodes a substring expression.
+     *
+     * @param node the node containing the attribute description and value
+     */
+    private void encode( SubstringNode node )
+    {
+        Tuple t = new Tuple();
+        t.setTag( LdapTag.CONTEXT_SPECIFIC_TAG_4, false );
+        consumer.tag( t );
+        t.setLength( Length.INDEFINATE );
+        consumer.length( t );
+
+        EncoderUtils.encodePrimitive( node.getAttribute(), consumer );
+
+        if ( node.getInitial() != null || node.getFinal() != null ||
+                node.getAny().size() > 0 )
+        {
+            Tuple t2 = new Tuple();
+            t2.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
+            consumer.tag( t2 );
+            t2.setLength( Length.INDEFINATE );
+            consumer.length( t2 );
+
+            if ( node.getInitial() != null )
+            {
+                EncoderUtils.encodePrimitive( LdapTag.CONTEXT_SPECIFIC_TAG_0,
+                        node.getInitial(), consumer );
+            }
+
+            if ( node.getAny().size() > 0 )
+            {
+                for( int ii = 0; ii < node.getAny().size(); ii++ )
+                {
+                    EncoderUtils.encodePrimitive(
+                            LdapTag.CONTEXT_SPECIFIC_TAG_1,
+                            ( String ) node.getAny().get( ii ),
+                            consumer );
+                }
+            }
+
+            if ( node.getFinal() != null )
+            {
+                EncoderUtils.encodePrimitive( LdapTag.CONTEXT_SPECIFIC_TAG_2,
+                        node.getFinal(), consumer );
+            }
+
+            consumer.finish( t2 );
+        }
+
+        consumer.finish( t );
+    }
+
+
+    /**
+     * Encoded recursive branch node expressions for AND (&), NOT (!) and OR (|)
+     * expressions.
+     *
+     * @param node the branch expression node to encode
+     */
+    private void encodeBranchNode( BranchNode node )
+    {
+        Tuple tuple = new Tuple();
+
+        if ( node.isNegation() ) // NOT (!)
+        {
+            tuple.setTag( LdapTag.CONTEXT_SPECIFIC_TAG_2, false );
+            consumer.tag( tuple );
+            tuple.setLength( Length.INDEFINATE );
+            consumer.length( tuple );
+            encodeNode( node.getChild() );
+            consumer.finish( tuple );
+            return;
+        }
+
+
+        if ( node.isConjunction() ) // AND (&)
+        {
+            tuple.setTag( LdapTag.CONTEXT_SPECIFIC_TAG_0, false );
+        }
+        else if ( node.isDisjunction() ) // OR (|)
+        {
+            tuple.setTag( LdapTag.CONTEXT_SPECIFIC_TAG_1, false );
+        }
+
+        consumer.tag( tuple );
+        tuple.setLength( Length.INDEFINATE );
+        consumer.length( tuple );
+
+        ArrayList children = node.getChildren();
+        for( int ii = 0; ii < children.size(); ii++ )
+        {
+            ExprNode child = ( ExprNode ) children.get( ii );
+            encodeNode( child );
+        }
+
+        consumer.finish( tuple );
     }
 }

Added: incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/search/SearchResponseDoneEncoder.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/search/SearchResponseDoneEncoder.java
Tue Jul 27 18:11:29 2004
@@ -0,0 +1,104 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.snickers.ldap.encoder.search;
+
+
+import org.apache.snickers.ber.Tuple;
+import org.apache.snickers.ber.Length;
+import org.apache.snickers.ber.TupleEventProducer;
+import org.apache.snickers.ber.TupleEventConsumer;
+import org.apache.snickers.ber.primitives.UniversalTag;
+
+import org.apache.snickers.ldap.LdapTag;
+import org.apache.snickers.ldap.encoder.EncoderUtils;
+import org.apache.snickers.ldap.encoder.LdapResultEncoder;
+
+import org.apache.ldap.common.message.SearchResponseDone;
+
+
+/**
+ * An SearchResponseDone encoder which transforms a SearchResponseDone stub
+ * object into a series of TLV Tuple events.
+ * 
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory
+ *         Project</a> $Rev$
+ */
+public class SearchResponseDoneEncoder implements TupleEventProducer
+{
+    /** tuple TLV event consumer that recieves the events produced */
+    TupleEventConsumer consumer;
+    /** used to encode the LDAPResult */
+    LdapResultEncoder resultEncoder = null;
+    /** topmost tlv frame */
+    Tuple top = null;
+    /** Search Response Done (srd) frame tuple */
+    Tuple srd = null;
+    /** temporary tuple */
+    Tuple tmp = null;
+
+
+    /**
+     * Attaches a consumer to the events generated by this producer.
+     *
+     * @param consumer the consumer to deliver events to
+     */
+    public void attach( TupleEventConsumer consumer )
+    {
+        this.consumer = consumer;
+        resultEncoder.attach( consumer );
+    }
+
+
+    /**
+     * Creates a SearchResponseDone encoder.
+     */
+    public SearchResponseDoneEncoder()
+    {
+        resultEncoder = new LdapResultEncoder();
+
+        top = new Tuple();
+        srd = new Tuple();
+        tmp = new Tuple();
+    }
+
+
+    /**
+     * Encodes a SearchResponseDone stub object delivering TLV tuple events to
+     * this producer's consumer.
+     *
+     * @param resp the SearchResponseDone stub object to encode
+     */
+    public void encode( SearchResponseDone resp )
+    {
+        top.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
+        consumer.tag( top );
+        top.setLength( Length.INDEFINATE );
+        consumer.length( top );
+
+        EncoderUtils.encodePrimitive( resp.getMessageId(), consumer );
+
+        srd.setTag( LdapTag.SEARCH_RESULT_DONE, false );
+        consumer.tag( srd );
+        srd.setLength( Length.INDEFINATE );
+        consumer.length( srd );
+
+        resultEncoder.encode( resp.getLdapResult() );
+
+        consumer.finish( srd );
+        consumer.finish( top );
+    }
+}

Added: incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/search/SearchResponseEntryEncoder.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/search/SearchResponseEntryEncoder.java
Tue Jul 27 18:11:29 2004
@@ -0,0 +1,164 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.snickers.ldap.encoder.search;
+
+
+import org.apache.snickers.ber.Tuple;
+import org.apache.snickers.ber.Length;
+import org.apache.snickers.ber.TupleEventProducer;
+import org.apache.snickers.ber.TupleEventConsumer;
+import org.apache.snickers.ber.primitives.UniversalTag;
+
+import org.apache.snickers.ldap.LdapTag;
+import org.apache.snickers.ldap.encoder.EncoderUtils;
+
+import org.apache.ldap.common.message.SearchResponseEntry;
+import org.apache.commons.codec.EncoderException;
+
+import javax.naming.directory.Attributes;
+import javax.naming.directory.Attribute;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+
+
+/**
+ * An SearchResponseEntry encoder which transforms a SearchResponseEntry stub
+ * object into a series of TLV Tuple events.
+ * 
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory
+ *         Project</a> $Rev$
+ */
+public class SearchResponseEntryEncoder implements TupleEventProducer
+{
+    /** tuple TLV event consumer that recieves the events produced */
+    TupleEventConsumer consumer;
+    /** topmost tlv frame */
+    Tuple top = null;
+    /** Search Response Entry (sre) frame tuple */
+    Tuple sre = null;
+    /** the Partial Attribute List constructed tuple */
+    Tuple pal = null;
+    /** temporary tuple */
+    Tuple tmp = null;
+
+
+    /**
+     * Attaches a consumer to the events generated by this producer.
+     *
+     * @param consumer the consumer to deliver events to
+     */
+    public void attach( TupleEventConsumer consumer )
+    {
+        this.consumer = consumer;
+    }
+
+
+    /**
+     * Creates a SearchResponseEntry encoder.
+     */
+    public SearchResponseEntryEncoder()
+    {
+        top = new Tuple();
+        sre = new Tuple();
+        pal = new Tuple();
+        tmp = new Tuple();
+    }
+
+
+    /**
+     * Encodes a SearchResponseEntry stub object delivering TLV tuple events to
+     * this producer's consumer.
+     *
+     * @param resp the SearchResponseEntry stub object to encode
+     */
+    public void encode( SearchResponseEntry resp ) throws EncoderException
+    {
+        top.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
+        consumer.tag( top );
+        top.setLength( Length.INDEFINATE );
+        consumer.length( top );
+
+        EncoderUtils.encodePrimitive( resp.getMessageId(), consumer );
+
+        sre.setTag( LdapTag.SEARCH_RESULT_ENTRY, false );
+        consumer.tag( sre );
+        sre.setLength( Length.INDEFINATE );
+        consumer.length( sre );
+
+        // Encode the LDAPDN scalar value
+        EncoderUtils.encodePrimitive( resp.getObjectName(), consumer );
+
+        // Encode the PartialAttributeList contructed tuple
+        pal.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
+        consumer.tag( pal );
+        pal.setLength( Length.INDEFINATE );
+        consumer.length( pal );
+
+        try
+        {
+            encode( resp.getAttributes() ) ;
+        }
+        catch ( NamingException e )
+        {
+            throw new EncoderException( "Failed to encode attributes" );
+        }
+
+        consumer.finish( pal );
+        consumer.finish( sre );
+        consumer.finish( top );
+    }
+
+
+    /**
+     * Encodes an partial attribute list with attributes and values passed as
+     * a JNDI attributes object.
+     *
+     * @param attrs the attributes to encode as a partial attribute list
+     * @throws NamingException if there are failures accessing the attributes
+     */
+    private void encode( Attributes attrs ) throws NamingException
+    {
+        NamingEnumeration list = attrs.getAll();
+        Tuple seq = new Tuple();
+        Tuple vals = new Tuple();
+
+        while( list.hasMore() )
+        {
+            seq.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
+            consumer.tag( seq );
+            seq.setLength( Length.INDEFINATE );
+            consumer.length( seq );
+
+            Attribute attr = ( Attribute ) list.next();
+            EncoderUtils.encodePrimitive( attr.getID(), consumer );
+
+            vals.setTag( UniversalTag.SET_SET_OF, false );
+            consumer.tag( vals );
+            vals.setLength( Length.INDEFINATE );
+            consumer.length( vals );
+
+            for( int ii = 0; ii < attr.size(); ii++ )
+            {
+                EncoderUtils.encodePrimitive( ( String ) attr.get( ii ),
+                        consumer ) ;
+            }
+
+            consumer.finish( vals );
+            consumer.finish( seq );
+        }
+    }
+}

Modified: incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/AbstractEncoderTest.java
==============================================================================
--- incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/AbstractEncoderTest.java
(original)
+++ incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/AbstractEncoderTest.java
Tue Jul 27 18:11:29 2004
@@ -17,8 +17,9 @@
 package org.apache.snickers.ldap.encoder;
 
 import junit.framework.TestCase;
-import org.apache.snickers.ber.BEREncoder;
-import org.apache.snickers.ber.TupleEventProducer;
+import org.apache.snickers.ber.*;
+import org.apache.snickers.ber.primitives.UniversalTag;
+import org.apache.snickers.ber.primitives.PrimitiveUtils;
 import org.apache.snickers.ldap.BufferUtils;
 import org.apache.ldap.common.message.*;
 import org.apache.commons.codec.stateful.EncoderCallback;

Modified: incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/bind/BindResponseEncoderTest.java
==============================================================================
--- incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/bind/BindResponseEncoderTest.java
(original)
+++ incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/bind/BindResponseEncoderTest.java
Tue Jul 27 18:11:29 2004
@@ -19,12 +19,6 @@
 import org.apache.snickers.ber.TupleEventProducer;
 import org.apache.snickers.ldap.encoder.AbstractEncoderTest;
 import org.apache.ldap.common.message.*;
-import org.apache.ldap.common.berlib.snacc.ldap_v3.LDAPResultEnum;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.codec.binary.Hex;
-
-import java.util.TreeSet;
-import java.util.Iterator;
 import java.io.FileOutputStream;
 import java.io.File;
 

Added: incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/search/SearchRequestEncoderTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/search/SearchRequestEncoderTest.java
Tue Jul 27 18:11:29 2004
@@ -0,0 +1,128 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.snickers.ldap.encoder.search;
+
+
+import org.apache.snickers.ldap.encoder.AbstractEncoderTest;
+import org.apache.snickers.ber.TupleEventProducer;
+
+import org.apache.ldap.common.message.ScopeEnum;
+import org.apache.ldap.common.message.SearchRequest;
+import org.apache.ldap.common.filter.FilterParserImpl;
+import org.apache.ldap.common.message.DerefAliasesEnum;
+import org.apache.ldap.common.message.SearchRequestImpl;
+import org.apache.ldap.common.filter.BranchNormalizedVisitor;
+
+import org.apache.commons.codec.EncoderException;
+
+import java.util.Iterator;
+import java.io.IOException;
+import java.text.ParseException;
+
+
+/**
+ * Tests the SearchRequest stub encoder.
+ * 
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory
+ *         Project</a> $Rev$
+ */
+public class SearchRequestEncoderTest extends AbstractEncoderTest
+{
+    private FilterParserImpl parser = null;
+
+
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        parser = new FilterParserImpl();
+    }
+
+
+    protected void tearDown() throws Exception
+    {
+        super.tearDown();
+        parser = null;
+    }
+
+
+    public SearchRequestEncoderTest()
+    {
+        super( "SearchRequestEncoderTest", 512 );
+    }
+
+
+    protected TupleEventProducer getProducer()
+    {
+        return new SearchRequestEncoder();
+    }
+
+
+    /**
+     * Simple test using a trivial filter with a single attribute value
+     * assertion.
+     */
+    public void testSimpleEncode() throws IOException,
+            ParseException, EncoderException
+    {
+        SearchRequest req = new SearchRequestImpl( 7 );
+        req.setBase( "dc=example,dc=com" );
+        req.setDerefAliases( DerefAliasesEnum.DEREFFINDINGBASEOBJ );
+        req.setFilter( parser.parse( "( objectClass = Person )" ) );
+        req.setScope( ScopeEnum.SINGLELEVEL );
+        req.setSizeLimit( 25 );
+        req.setTimeLimit( 1000 );
+        req.setTypesOnly( true );
+        req.addAttribute( "ou" );
+        req.addAttribute( "locale" );
+        req.addAttribute( "objectClass" );
+
+        ( ( SearchRequestEncoder ) producer ).encode( req );
+
+        collector.flip();
+        SearchRequest decoded = ( SearchRequest ) decodeEncoded( collector );
+
+        // Test all scalar quantities
+        assertEquals( req.getBase(), decoded.getBase() );
+        assertEquals( req.getDerefAliases(), decoded.getDerefAliases() );
+        assertEquals( req.getMessageId(), decoded.getMessageId() );
+        assertEquals( req.getScope(), decoded.getScope() );
+        assertEquals( req.getSizeLimit(), decoded.getSizeLimit() );
+        assertEquals( req.getTimeLimit(), decoded.getTimeLimit() );
+        assertEquals( req.getTypesOnly(), decoded.getTypesOnly() );
+
+        // Deep test non-scaler attribute values
+        assertEquals( req.getAttributes().size(),
+                decoded.getAttributes().size() );
+        Iterator list = req.getAttributes().iterator();
+        while( list.hasNext() )
+        {
+            assertTrue( decoded.getAttributes().contains( list.next() ) );
+        }
+
+        // Deep test non-scalar filter expression with normalization
+        BranchNormalizedVisitor visitor = new BranchNormalizedVisitor();
+        visitor.visit( req.getFilter() );
+        visitor.visit( decoded.getFilter() );
+
+        StringBuffer oriBuf = new StringBuffer();
+        req.getFilter().printToBuffer( oriBuf );
+        StringBuffer decodedBuf = new StringBuffer();
+        decoded.getFilter().printToBuffer( decodedBuf );
+
+        assertEquals( oriBuf.toString(), decodedBuf.toString() );
+    }
+}

Added: incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/search/SearchResponseDoneEncoderTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/search/SearchResponseDoneEncoderTest.java
Tue Jul 27 18:11:29 2004
@@ -0,0 +1,97 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.snickers.ldap.encoder.search;
+
+
+import org.apache.snickers.ldap.encoder.AbstractEncoderTest;
+import org.apache.snickers.ldap.encoder.bind.BindResponseEncoder;
+import org.apache.snickers.ber.TupleEventProducer;
+
+import org.apache.ldap.common.filter.FilterParserImpl;
+import org.apache.ldap.common.message.*;
+import org.apache.ldap.common.filter.BranchNormalizedVisitor;
+
+import org.apache.commons.codec.EncoderException;
+
+import java.util.Iterator;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.text.ParseException;
+
+
+/**
+ * Tests the SearchResponseDone stub encoder.
+ * 
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory
+ *         Project</a> $Rev$
+ */
+public class SearchResponseDoneEncoderTest extends AbstractEncoderTest
+{
+    public SearchResponseDoneEncoderTest()
+    {
+        super( "SearchResponseDoneEncoderTest", 512 );
+    }
+
+
+    protected TupleEventProducer getProducer()
+    {
+        return new SearchResponseDoneEncoder();
+    }
+
+
+    /**
+     * Tests the encoding.
+     */
+    public void testEncode() throws IOException,
+            ParseException, EncoderException
+    {
+        SearchResponseDone resp = new SearchResponseDoneImpl( 7 );
+        LdapResult result = new LdapResultImpl( resp );
+        resp.setLdapResult( result );
+        result.setResultCode( ResultCodeEnum.SUCCESS );
+        result.setMatchedDn( "dc=example,dc=com" );
+        result.setErrorMessage( "" );
+        result.setReferral( new ReferralImpl( result ) );
+        result.getReferral().addLdapUrl( "ldap://onehost:389" );
+        result.getReferral().addLdapUrl( "ldap://twohost:389" );
+        result.getReferral().addLdapUrl( "ldap://threehost:389" );
+
+        ( ( SearchResponseDoneEncoder ) producer ).encode( resp );
+
+        collector.flip();
+        SearchResponseDone decodedResp = ( SearchResponseDone )
+                decodeEncoded( collector );
+        assertEquals( resp.getMessageId(), decodedResp.getMessageId() );
+        LdapResult decodedResult = decodedResp.getLdapResult();
+        assertEquals( result.getErrorMessage(),
+                decodedResult.getErrorMessage() );
+        assertEquals( result.getMatchedDn(), decodedResult.getMatchedDn() );
+        assertEquals( result.getResultCode(), decodedResult.getResultCode() );
+        assertEquals( result.getErrorMessage(),
+                decodedResult.getErrorMessage() );
+
+        assertEquals( result.getReferral().getLdapUrls().size(),
+                decodedResult.getReferral().getLdapUrls().size() );
+        assertTrue( decodedResult.getReferral().getLdapUrls().contains(
+            "ldap://onehost:389" ) );
+        assertTrue( decodedResult.getReferral().getLdapUrls().contains(
+            "ldap://twohost:389" ) );
+        assertTrue( decodedResult.getReferral().getLdapUrls().contains(
+            "ldap://threehost:389" ) );
+    }
+}

Added: incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/search/SearchResponseEntryEncoderTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/search/SearchResponseEntryEncoderTest.java
Tue Jul 27 18:11:29 2004
@@ -0,0 +1,224 @@
+/*
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed 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.snickers.ldap.encoder.search;
+
+
+import org.apache.snickers.ldap.encoder.AbstractEncoderTest;
+import org.apache.snickers.ber.TupleEventProducer;
+
+import org.apache.commons.codec.EncoderException;
+import org.apache.ldap.common.message.SearchResponseEntry;
+import org.apache.ldap.common.message.SearchResponseEntryImpl;
+import org.apache.ldap.common.message.LockableAttributesImpl;
+
+import javax.naming.directory.Attributes;
+import javax.naming.directory.Attribute;
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+import java.io.IOException;
+import java.text.ParseException;
+
+
+/**
+ * Tests the SearchResponseEntry stub encoder.
+ * 
+ * @author <a href="mailto:directory-dev@incubator.apache.org"> Apache Directory
+ *         Project</a> $Rev$
+ */
+public class SearchResponseEntryEncoderTest extends AbstractEncoderTest
+{
+    public SearchResponseEntryEncoderTest()
+    {
+        super( "SearchResponseEntryEncoderTest", 512 );
+    }
+
+
+    protected TupleEventProducer getProducer()
+    {
+        return new SearchResponseEntryEncoder();
+    }
+
+
+    /**
+     * Tests entry without any return values.
+     */
+    public void testEncodeEmpty() throws IOException,
+            ParseException, EncoderException, NamingException
+    {
+        SearchResponseEntry resp = new SearchResponseEntryImpl( 7 );
+        resp.setObjectName( "dc=example,dc=com" );
+        LockableAttributesImpl attributes = new LockableAttributesImpl( resp );
+        resp.setAttributes( attributes );
+
+        ( ( SearchResponseEntryEncoder ) producer ).encode( resp );
+
+        collector.flip();
+        SearchResponseEntry decodedResp = ( SearchResponseEntry )
+                decodeEncoded( collector );
+        assertEquals( resp.getMessageId(), decodedResp.getMessageId() );
+        assertEquals( resp.getObjectName(), decodedResp.getObjectName() );
+        assertEquals( resp.getAttributes(), decodedResp.getAttributes() );
+    }
+
+
+    /**
+     * Tests entry without any return values.
+     */
+    public void testEncodeOneIDOneValue() throws IOException,
+            ParseException, EncoderException, NamingException
+    {
+        SearchResponseEntry resp = new SearchResponseEntryImpl( 7 );
+        resp.setObjectName( "dc=example,dc=com" );
+        LockableAttributesImpl attributes = new LockableAttributesImpl( resp );
+        resp.setAttributes( attributes );
+
+        attributes.put( "ou", "People" );
+
+        ( ( SearchResponseEntryEncoder ) producer ).encode( resp );
+
+        collector.flip();
+        SearchResponseEntry decodedResp = ( SearchResponseEntry )
+                decodeEncoded( collector );
+        assertEquals( resp.getMessageId(), decodedResp.getMessageId() );
+        assertEquals( resp.getObjectName(), decodedResp.getObjectName() );
+        assertEquals( resp.getAttributes(), decodedResp.getAttributes() );
+    }
+
+
+    /**
+     * Tests entry without any return values.
+     */
+    public void testEncodeOneIDManyValues() throws IOException,
+            ParseException, EncoderException, NamingException
+    {
+        SearchResponseEntry resp = new SearchResponseEntryImpl( 7 );
+        resp.setObjectName( "dc=example,dc=com" );
+        LockableAttributesImpl attributes = new LockableAttributesImpl( resp );
+        resp.setAttributes( attributes );
+
+        attributes.put( "ou", "People" );
+        attributes.put( "ou", "Staff" );
+        attributes.put( "ou", "Engineering" );
+
+        ( ( SearchResponseEntryEncoder ) producer ).encode( resp );
+
+        collector.flip();
+        SearchResponseEntry decodedResp = ( SearchResponseEntry )
+                decodeEncoded( collector );
+        assertEquals( resp.getMessageId(), decodedResp.getMessageId() );
+        assertEquals( resp.getObjectName(), decodedResp.getObjectName() );
+
+    }
+
+
+    /**
+     * Tests entry without any return values.
+     */
+    public void testEncodeManyIdsManyValues() throws IOException,
+            ParseException, EncoderException, NamingException
+    {
+        SearchResponseEntry resp = new SearchResponseEntryImpl( 7 );
+        resp.setObjectName( "dc=example,dc=com" );
+        LockableAttributesImpl attributes = new LockableAttributesImpl( resp );
+        resp.setAttributes( attributes );
+
+        attributes.put( "ou", "People" );
+        attributes.put( "ou", "Staff" );
+        attributes.put( "ou", "Engineering" );
+
+        attributes.put( "l", "SunnyVale" );
+
+        attributes.put( "uid", "akarasulu" );
+
+        attributes.put( "objectClass", "top" ) ;
+        attributes.put( "objectClass", "person" ) ;
+        attributes.put( "objectClass", "inetorgperson" );
+
+        ( ( SearchResponseEntryEncoder ) producer ).encode( resp );
+
+        collector.flip();
+        SearchResponseEntry decodedResp = ( SearchResponseEntry )
+                decodeEncoded( collector );
+        assertEquals( resp.getMessageId(), decodedResp.getMessageId() );
+        assertEquals( resp.getObjectName(), decodedResp.getObjectName() );
+        assertEquals( resp.getAttributes(), decodedResp.getAttributes() );
+    }
+
+
+    /**
+     * Tests to see if two Attributes are equal.  Equality means that the same
+     * attributes with the same IDs and size as well as ordering must be the
+     * same of Attribute objects.  Ordering is only considered if the contained
+     * Attribute.isOrdered() on individual Attribute[s] returns true.
+     *
+     * @param attrs0 the reference attributes to test for equality (the expected
+     * value)
+     * @param attrs1 the attributes to test for equality against the reference
+     * attribute
+     * @throws NamingException if there are failures while accessing the values
+     * of both attributes compared
+     */
+    private void assertEquals( Attributes attrs0, Attributes attrs1 )
+        throws NamingException
+    {
+        NamingEnumeration list = attrs0.getAll();
+        while( list.hasMore() )
+        {
+            Attribute attr0 = ( Attribute ) list.next();
+            Attribute attr1 = attrs1.get( attr0.getID() );
+            assertNotNull( attr1 );
+            assertEquals( attr0, attr1 );
+        }
+    }
+
+
+    /**
+     * Tests to see if two attributes are equal.  Equality means that the ID,
+     * size and ordering must be the same of objects.  Ordering is only
+     * considered if isOrdered() on both returns true.
+     *
+     * @param attr0 the reference attribute to test for equality (the expected
+     * value)
+     * @param attr1 the attribute to test for equality against the reference
+     * attribute
+     * @throws NamingException if there are failures while accessing the values
+     * of both attributes compared
+     */
+    private void assertEquals( Attribute attr0, Attribute attr1 )
+            throws NamingException
+    {
+        assertEquals( attr0.getID(), attr1.getID() );
+        assertEquals( attr0.size(), attr1.size() );
+        assertEquals( attr0.isOrdered(), attr1.isOrdered() );
+
+        for( int ii = 0; ii < attr0.size(); ii++ )
+        {
+            Object obj = attr0.get( ii );
+
+            // order seems to be lost with Snacc4J because of set ordering
+
+//            if ( attr0.isOrdered() )
+//            {
+//                assertEquals( attr0.get( ii ), attr1.get( ii ) );
+//            }
+//            else
+//            {
+                assertTrue( attr1.contains( obj ) );
+//            }
+        }
+    }
+}

Mime
View raw message