Author: akarasulu
Date: Mon Jul 26 21:15:16 2004
New Revision: 30757
Added:
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/TupleEventConsumer.java
(contents, props changed)
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/TupleEventProducer.java
(contents, props changed)
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/TupleTreeAnalyzer.java
- copied, changed from rev 9765,
incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/TupleTreeAnalyzer.java
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/LdapResultEncoder.java
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/bind/BindRequestEncoder.java
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/bind/BindResponseEncoder.java
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/search/
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/
incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/bind/BindRequestEncoderTest.java
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/search/
Modified:
incubator/directory/snickers/trunk/ (props changed)
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/BEREncoder.java
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/Tuple.java
incubator/directory/snickers/trunk/ber-codec/src/test/org/apache/snickers/ber/BEREncoderTest.java
incubator/directory/snickers/trunk/ldap-ber-provider/ (props changed)
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/SnickersLdapEncoder.java
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/abandon/AbandonRequestEncoder.java
incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/abandon/AbandonRequestEncoderTest.java
incubator/directory/snickers/trunk/project.xml
incubator/directory/snickers/trunk/xdocs/ber-codec/BEREncoderDesign.xml
Log:
Commit changes ...
o resurrected and modified TupleTreeAnalyzer
o altered tuple to support setter operations
o added new event producer consumers for tuple events
o added bind request and response handlers for the encoder
o added generic ldap result handler
o started search encoder
Modified:
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/BEREncoder.java
==============================================================================
---
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/BEREncoder.java
(original)
+++
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/BEREncoder.java
Mon Jul 26 21:15:16 2004
@@ -18,23 +18,30 @@
import org.apache.commons.codec.stateful.AbstractStatefulEncoder;
-import org.apache.commons.codec.stateful.StatefulEncoder;
import java.nio.ByteBuffer;
/**
- * A BER TLV tuple encoder. This encoder receives events via some BEREncoder
+ * A BER TLV tuple encoder. This encoder receives events via a
+ * BEREncoderCallback. Hence the callback is used to deliver events to this
+ * encoder or event consumer. The product is announced via an regular encoder
+ * event.
+ *
+ * @note We tried the route of using a BEREncoderCallback here and well it was
+ * ugly the event consumer producer based mechanism was a much better more
+ * specific approach. Plus it got confusing: we started confusing callbacks.
+ * There was a callback for getting event then another callback for producing
+ * them. It got confusing fast.
*
- *
* @author <a href="mailto:[EMAIL PROTECTED]"> Apache Directory
* Project</a> $Rev$
*/
public class BEREncoder extends AbstractStatefulEncoder
+ implements TupleEventConsumer
{
private static final int DEFAULT_BUFSZ = 32;
private ByteBuffer buf = null;
- private BEREncoderCallback berCb;
/**
@@ -54,7 +61,6 @@
public BEREncoder( int bufSz )
{
buf = ByteBuffer.allocateDirect( bufSz );
- berCb = new Callback();
}
@@ -76,132 +82,108 @@
}
- /**
- * Gets the BEREncoderCallback used to send BER TLV Tuple events to this
- * encoder. This is separate from the traditional encoder callback used
- * to emit encode events.
- *
- * @return the encoder's BER TLV event callback
+ /*
+ * The idea here is to see if we can encode the tag bytes into the
+ * remaining bytes of the buffer. If we can then great we do so.
+ * If we cannot then we have to flush out the full buffer with an
+ * encodeOccurred Event. This signals the production of encoded data
+ * and free's up the buffer to have the tag bytes writen to it.
*/
- public BEREncoderCallback getBERCallback()
+ public void tag( Tuple tlv )
{
- return berCb;
+ if ( buf.remaining() >= tlv.getTagLength() )
+ {
+ tlv.setTag( buf, tlv.getTagLength() );
+ }
+ else
+ {
+ buf.flip();
+ encodeOccurred( buf );
+ buf.clear();
+ tlv.setTag( buf, tlv.getTagLength() );
+ }
}
- /**
- * Specific callback interface used to send TLV tuple events to this
- * encoder. Uses the buffer in this encoder to lay down tag and length
- * pairs yet passing through chunked values. A downstream encoder can
- * consolidate these buffers and flush them to a stream.
- */
- class Callback implements BEREncoderCallback
- {
- /*
- * The idea here is to see if we can encode the tag bytes into the
- * remaining bytes of the buffer. If we can then great we do so.
- * If we cannot then we have to flush out the full buffer with an
- * encodeOccurred Event. This signals the production of encoded data
- * and free's up the buffer to have the tag bytes writen to it.
- */
- public void tagEncoded( Tuple tlv )
+ /*
+ * Again we have the same dynamic where we no encode the lenght bytes
+ * into the remaining bytes of the buffer. If we can then great we do
+ * so. If we cannot then we have to flush out the full buffer with an
+ * encodeOccurred Event. This signals the production of encoded data
+ * and free's up the buffer to have the length bytes writen to it.
+ */
+ public void length( Tuple tlv )
+ {
+ if ( buf.remaining() >= tlv.getLengthLength() )
{
- if ( buf.remaining() >= tlv.getTagLength() )
- {
- tlv.setTag( buf, tlv.getTagLength() );
- }
- else
- {
- buf.flip();
- BEREncoder.this.encodeOccurred( buf );
- buf.clear();
- tlv.setTag( buf, tlv.getTagLength() );
- }
+ tlv.setLength( buf, tlv.getLengthLength() );
}
-
-
- /*
- * Again we have the same dynamic where we no encode the lenght bytes
- * into the remaining bytes of the buffer. If we can then great we do
- * so. If we cannot then we have to flush out the full buffer with an
- * encodeOccurred Event. This signals the production of encoded data
- * and free's up the buffer to have the length bytes writen to it.
- */
- public void lengthEncoded( Tuple tlv )
+ else
{
- if ( buf.remaining() >= tlv.getLengthLength() )
- {
- tlv.setLength( buf, tlv.getLengthLength() );
- }
- else
- {
- buf.flip();
- BEREncoder.this.encodeOccurred( buf );
- buf.clear();
- tlv.setLength( buf, tlv.getLengthLength() );
- }
+ buf.flip();
+ encodeOccurred( buf );
+ buf.clear();
+ tlv.setLength( buf, tlv.getLengthLength() );
}
+ }
- /*
- * Here the situation is a little different. The values are already
- * chunked so there is no need to copy them into a buffer. We are
- * best off passing through this buffer to consumers with an encode but
- * before we do that we need to check if the present buffer contains
- * any material that must go out the door first. Doing this prevents
- * us from mangling the order of bytes to send. So if our buf contains
- * any bytes from previous operations laying down the tag and length
- * then we must flush it out. Then we can flush out this chunk.
- */
- public void partialValueEncoded( Tuple tlv )
+ /*
+ * Here the situation is a little different. The values are already
+ * chunked so there is no need to copy them into a buffer. We are
+ * best off passing through this buffer to consumers with an encode but
+ * before we do that we need to check if the present buffer contains
+ * any material that must go out the door first. Doing this prevents
+ * us from mangling the order of bytes to send. So if our buf contains
+ * any bytes from previous operations laying down the tag and length
+ * then we must flush it out. Then we can flush out this chunk.
+ */
+ public void chunkedValue( Tuple tlv, ByteBuffer chunk )
+ {
+ if ( buf.position() > 0 )
{
- if ( buf.position() > 0 )
- {
- buf.flip();
- BEREncoder.this.encodeOccurred( buf );
- buf.clear();
- }
-
- BEREncoder.this.encodeOccurred( tlv.getLastValueChunk() );
+ buf.flip();
+ BEREncoder.this.encodeOccurred( buf );
+ buf.clear();
}
+ encodeOccurred( tlv.getLastValueChunk() );
+ }
- /*
- * Keep in mind this method signals the end of a Tuple. It is called
- * upstream from us by a higher level encoder that generates tuple
- * streams from objects. This method simply returns if the object is
- * a primitive Tuple because all value processing has already occurred
- * for that tuple. If on the otherhand the tuple is constructed and of
- * the indefinate form need to write the termination sequence (two
- * zeros) down into the stream. We attempt to do this into the buffer.
- * If the buffer is full we flush is with an encodeOccurred() event.
- * Then we write the termination sequence into the buffer and flush
- * the buffer with an encodeOccurred Event.
- */
- public void encodeOccurred( StatefulEncoder encoder, Object encoded )
- {
- Tuple tlv = ( Tuple ) encoded;
- if ( tlv.isPrimitive() )
- {
- return;
- }
+ /*
+ * Keep in mind this method signals the end of a Tuple. It is called
+ * upstream from us by a higher level encoder that generates tuple
+ * streams from objects. This method simply returns if the object is
+ * a primitive Tuple because all value processing has already occurred
+ * for that tuple. If on the otherhand the tuple is constructed and of
+ * the indefinate form need to write the termination sequence (two
+ * zeros) down into the stream. We attempt to do this into the buffer.
+ * If the buffer is full we flush is with an encodeOccurred() event.
+ * Then we write the termination sequence into the buffer and flush
+ * the buffer with an encodeOccurred Event.
+ */
+ public void finish( Tuple tlv )
+ {
+ if ( tlv.isPrimitive() )
+ {
+ return;
+ }
- if ( tlv.isIndefinate() )
+ if ( tlv.isIndefinate() )
+ {
+ if ( buf.remaining() < 2 )
{
- if ( buf.remaining() < 2 )
- {
- buf.flip();
- BEREncoder.this.encodeOccurred( buf );
- buf.clear();
- }
-
- buf.put( (byte) 0 );
- buf.put( (byte) 0 );
buf.flip();
- BEREncoder.this.encodeOccurred( buf );
+ encodeOccurred( buf );
buf.clear();
}
+
+ buf.put( (byte) 0 );
+ buf.put( (byte) 0 );
+ buf.flip();
+ encodeOccurred( buf );
+ buf.clear();
}
}
}
Modified:
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/Tuple.java
==============================================================================
---
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/Tuple.java
(original)
+++
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/Tuple.java
Mon Jul 26 21:15:16 2004
@@ -540,28 +540,30 @@
*/
public void setTag( ByteBuffer octets, int tagLength )
{
+ int ii = octets.position();
octets.put( ( byte ) typeClass.getValue() ) ;
if ( ! isPrimitive )
{
- octets.put( 0, ( byte ) ( octets.get( 0 ) | BIT_5 ) ) ;
+ octets.put( ii, ( byte ) ( octets.get( ii ) | BIT_5 ) ) ;
}
if ( tagLength == 1 )
{
- octets.put( 0, ( byte ) ( octets.get( 0 ) | id ) ) ;
+ octets.put( ii, ( byte ) ( octets.get( ii ) | id ) ) ;
return ;
}
- octets.put( 0, ( byte ) ( octets.get( 0 ) | Tag.SHORT_MASK ) ) ;
+ octets.put( ii, ( byte ) ( octets.get( ii ) | Tag.SHORT_MASK ) ) ;
if ( tagLength >= 2 )
{
+ ii++;
octets.put( ( byte ) ( ( int ) 0x7f & id ) ) ;
if ( tagLength > 2 )
{
- octets.put( 1, ( byte ) ( octets.get( 1 ) | BIT_7 ) ) ;
+ octets.put( ii, ( byte ) ( octets.get( ii ) | BIT_7 ) ) ;
}
}
else
@@ -579,11 +581,12 @@
*/
if ( tagLength >= 3 )
{
+ ii++;
octets.put( ( byte ) ( ( ( int ) 0x3f80 & id ) >> 7 ) ) ;
if ( tagLength > 3 )
{
- octets.put( 2, ( byte ) ( octets.get( 2 ) | BIT_7 ) ) ;
+ octets.put( ii, ( byte ) ( octets.get( ii ) | BIT_7 ) ) ;
}
}
else
@@ -601,11 +604,12 @@
*/
if ( tagLength >= 4 )
{
+ ii++;
octets.put( ( byte ) ( ( ( int ) 0x1fc000 & id ) >> 14 ) ) ;
if ( tagLength > 4 )
{
- octets.put( 3, ( byte ) ( octets.get( 3 ) | BIT_7 ) ) ;
+ octets.put( ii, ( byte ) ( octets.get( ii ) | BIT_7 ) ) ;
}
}
else
@@ -623,11 +627,12 @@
*/
if ( tagLength >= 5 )
{
+ ii++;
octets.put( ( byte ) ( ( ( int ) 0x0fe00000 & id ) >> 21 ) ) ;
if ( tagLength > 5 )
{
- octets.put( 4, ( byte ) ( octets.get( 4 ) | BIT_7 ) ) ;
+ octets.put( ii, ( byte ) ( octets.get( ii ) | BIT_7 ) ) ;
}
}
else
Added:
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/TupleEventConsumer.java
==============================================================================
--- (empty file)
+++
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/TupleEventConsumer.java
Mon Jul 26 21:15:16 2004
@@ -0,0 +1,34 @@
+/*
+ * 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.ber;
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * Experimental shared interface for both Tuple event producers and consumers.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]"> Apache Directory
+ * Project</a> $Rev$
+ */
+public interface TupleEventConsumer
+{
+ public void tag( Tuple tlv );
+ public void length( Tuple tlv );
+ public void chunkedValue( Tuple tlv, ByteBuffer chunk );
+ public void finish( Tuple tlv );
+}
Added:
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/TupleEventProducer.java
==============================================================================
--- (empty file)
+++
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/TupleEventProducer.java
Mon Jul 26 21:15:16 2004
@@ -0,0 +1,29 @@
+/*
+ * 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.ber;
+
+
+/**
+ * Document me.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]"> Apache Directory
+ * Project</a> $Rev$
+ */
+public interface TupleEventProducer
+{
+ public void attach( TupleEventConsumer consumer );
+}
Copied:
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/TupleTreeAnalyzer.java
(from rev 9765,
incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/TupleTreeAnalyzer.java)
==============================================================================
---
incubator/directory/snickers/trunk/ber/src/java/org/apache/snickers/ber/TupleTreeAnalyzer.java
(original)
+++
incubator/directory/snickers/trunk/ber-codec/src/java/org/apache/snickers/ber/TupleTreeAnalyzer.java
Mon Jul 26 21:15:16 2004
@@ -17,6 +17,12 @@
package org.apache.snickers.ber ;
+import org.apache.commons.codec.stateful.CallbackHistory;
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.collections.IteratorUtils;
+import org.apache.snickers.ber.primitives.UniversalTag;
+
import javax.swing.JMenu ;
import javax.swing.JTree ;
import javax.swing.JFrame ;
@@ -29,7 +35,11 @@
import javax.swing.JSplitPane ;
import javax.swing.JScrollPane ;
import javax.swing.JFileChooser ;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.event.TreeSelectionEvent;
import javax.swing.tree.DefaultTreeModel ;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
import java.awt.Toolkit ;
import java.awt.Dimension ;
@@ -37,6 +47,9 @@
import java.awt.event.ActionEvent ;
import java.awt.event.WindowEvent ;
import java.awt.event.ActionListener ;
+import java.nio.ByteBuffer;
+import java.util.Enumeration;
+import java.io.*;
/**
@@ -46,10 +59,30 @@
* Apache Directory Project</a>
* @version $Rev$
*/
-public class TupleTreeAnalyzer extends JFrame
+public class TupleTreeAnalyzer extends JFrame implements TreeSelectionListener
{
- DefaultMutableTupleNode root = null ;
-
+ private BorderLayout layout = new BorderLayout();
+ private JLabel statusBar = new JLabel("Ready");
+ private JSplitPane jSplitPane1 = new JSplitPane();
+ private JScrollPane jScrollPane1 = new JScrollPane();
+ private JPanel jPanel1 = new JPanel();
+ private JTree jTree1 = new JTree();
+ private JPanel jPanel2 = new JPanel();
+ private JPanel jPanel5 = new JPanel();
+ private JPanel jPanel3 = new JPanel();
+ private JPanel jPanel4 = new JPanel();
+ private JLabel jLabel1 = new JLabel();
+ private JLabel jLabel3 = new JLabel();
+ private JLabel jLabel2 = new JLabel();
+ private JScrollPane jScrollPane2 = new JScrollPane();
+ private JTextArea jTextArea1 = new JTextArea();
+ private JTextField jTextField1 = new JTextField();
+ private JTextField jTextField3 = new JTextField();
+ private JTextField jTextField2 = new JTextField();
+
+ private DefaultMutableTupleNode root = null ;
+
+
/** Creates new form JFrame */
public TupleTreeAnalyzer( DefaultMutableTupleNode root )
{
@@ -59,7 +92,27 @@
pack() ;
}
- /** This method is called from within
+
+ public TupleTreeAnalyzer( byte[] encoded ) throws DecoderException
+ {
+ this( ByteBuffer.wrap( encoded ) );
+ }
+
+
+ public TupleTreeAnalyzer( ByteBuffer encoded ) throws DecoderException
+ {
+ TupleTreeDecoder decoder = new TupleTreeDecoder();
+ CallbackHistory history = new CallbackHistory();
+ decoder.setCallback( history );
+ decoder.decode( encoded );
+ root = ( DefaultMutableTupleNode ) history.getMostRecent();
+
+ initGUI();
+ pack();
+ }
+
+
+ /** This method is called from within
* the constructor to initialize the form. */
private void initGUI() {
@@ -104,7 +157,7 @@
public void actionPerformed(java.awt.event.ActionEvent e) {
int returnVal = fc.showOpenDialog(TupleTreeAnalyzer.this);
if (returnVal == javax.swing.JFileChooser.APPROVE_OPTION) {
- java.io.File file = fc.getSelectedFile();
+ //java.io.File file = fc.getSelectedFile();
// Write your code here what to do with selected file
} else {
// Write your code here what to do if user has canceled
@@ -120,7 +173,7 @@
public void actionPerformed(java.awt.event.ActionEvent e) {
int returnVal = fc.showSaveDialog(TupleTreeAnalyzer.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
- java.io.File file = fc.getSelectedFile();
+ //java.io.File file = fc.getSelectedFile();
// Write your code here what to do with selected file
} else {
// Write your code here what to do if user has canceled Save dialog
@@ -155,8 +208,8 @@
jPanel5.add(jLabel3);
jPanel5.add(jTextField3);
jTextField3.setText("");
- jTextField3.setMinimumSize(new java.awt.Dimension(104, 25));
- jTextField3.setPreferredSize(new java.awt.Dimension(104, 25));
+ jTextField3.setMinimumSize(new java.awt.Dimension(184, 25));
+ jTextField3.setPreferredSize(new java.awt.Dimension(184, 25));
jSplitPane1.setLastDividerLocation(50);
jSplitPane1.setDividerLocation(180);
jSplitPane1.add(jScrollPane1, javax.swing.JSplitPane.LEFT);
@@ -212,12 +265,12 @@
jTextArea1.setText("");
jScrollPane2.getViewport().add(jTextArea1);
jTextField1.setText("");
- jTextField1.setMinimumSize(new java.awt.Dimension(104, 25));
- jTextField1.setPreferredSize(new java.awt.Dimension(104, 25));
+ jTextField1.setMinimumSize(new java.awt.Dimension(164, 25));
+ jTextField1.setPreferredSize(new java.awt.Dimension(164, 25));
jTextField1.setEditable(true);
jTextField2.setText("");
- jTextField2.setPreferredSize(new java.awt.Dimension(104,25));
- jTextField2.setMinimumSize(new java.awt.Dimension(104,25));
+ jTextField2.setPreferredSize(new java.awt.Dimension(164,25));
+ jTextField2.setMinimumSize(new java.awt.Dimension(164,25));
jTextField2.setEditable(true);
jScrollPane2.setVerticalScrollBarPolicy(
javax.swing.JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
@@ -225,11 +278,15 @@
javax.swing.JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
jScrollPane2.setBorder(null);
- jTree1.setModel( new DefaultTreeModel( root ) ) ;
+ jTree1.setModel( new DefaultTreeModel(
+ new TupleTreeNodeAdapter( root ) ) );
+ jTree1.getSelectionModel().addTreeSelectionListener( this );
}
/** Exit the Application */
- private void exitForm(WindowEvent evt) {
+ private void exitForm(WindowEvent evt)
+ {
+ System.out.println("Closing window: " + evt.getWindow().getName());
System.exit(0);
}
@@ -248,22 +305,188 @@
setVisible(true);
}
- private BorderLayout layout = new BorderLayout();
- private JLabel statusBar = new JLabel("Ready");
- private JSplitPane jSplitPane1 = new JSplitPane();
- private JScrollPane jScrollPane1 = new JScrollPane();
- private JPanel jPanel1 = new JPanel();
- private JTree jTree1 = new JTree();
- private JPanel jPanel2 = new JPanel();
- private JPanel jPanel5 = new JPanel();
- private JPanel jPanel3 = new JPanel();
- private JPanel jPanel4 = new JPanel();
- private JLabel jLabel1 = new JLabel();
- private JLabel jLabel3 = new JLabel();
- private JLabel jLabel2 = new JLabel();
- private JScrollPane jScrollPane2 = new JScrollPane();
- private JTextArea jTextArea1 = new JTextArea();
- private JTextField jTextField1 = new JTextField();
- private JTextField jTextField3 = new JTextField();
- private JTextField jTextField2 = new JTextField();
+
+ public void valueChanged( TreeSelectionEvent e )
+ {
+ TreePath path = e.getPath();
+ TupleTreeNodeAdapter node = ( TupleTreeNodeAdapter )
+ path.getLastPathComponent();
+ TupleNode tn = node.getTupleNode();
+ Tuple tuple = tn.getTuple();
+
+ TypeClass type = TypeClass.getTypeClass( tuple.getRawTag() >> 24 );
+ jTextField3.setText( type.getName() );
+
+
+ if ( tuple.getLength() == Length.INDEFINATE )
+ {
+ jTextField2.setText( "INDEFINATE" );
+ }
+ else
+ {
+ jTextField2.setText( Integer.toString( tuple.getLength() ) );
+ }
+
+ if ( type.equals( TypeClass.UNIVERSAL ) )
+ {
+ UniversalTag tag = UniversalTag.getUniversalTag( tuple.getRawTag()
);
+ jTextField1.setText( tag.getName() );
+ }
+ else
+ {
+ jTextField1.setText( Integer.toString( tuple.getId() ) );
+ }
+
+ if ( tuple.isPrimitive() )
+ {
+ ByteBuffer buf = ( ByteBuffer ) tuple.getLastValueChunk().rewind();
+ byte[] bites = new byte[buf.remaining()];
+ buf.get( bites );
+ jTextArea1.setText( new String( Hex.encodeHex( bites ) ) );
+ jTextArea1.setToolTipText( "String: " + new String( bites ) );
+ }
+ else
+ {
+ jTextArea1.setText( "N/A" );
+ jTextArea1.setToolTipText( null );
+ }
+ }
+
+
+ class TupleTreeNodeAdapter implements TreeNode
+ {
+ DefaultMutableTupleNode node;
+
+
+ TupleTreeNodeAdapter( DefaultMutableTupleNode node )
+ {
+ this.node = node;
+ }
+
+
+ public int getChildCount()
+ {
+ return node.getChildCount();
+ }
+
+ public boolean getAllowsChildren()
+ {
+ return !node.getTuple().isPrimitive();
+ }
+
+ public boolean isLeaf()
+ {
+ return node.getChildCount() == 0;
+ }
+
+ public Enumeration children()
+ {
+ return IteratorUtils.asEnumeration( node.getChildren() );
+ }
+
+ public TreeNode getParent()
+ {
+ return new TupleTreeNodeAdapter( ( DefaultMutableTupleNode )
+ node.getParentTupleNode() );
+ }
+
+ public TreeNode getChildAt( int childIndex )
+ {
+ return new TupleTreeNodeAdapter( ( DefaultMutableTupleNode )
+ node.getChildTupleNodeAt( childIndex ) );
+ }
+
+ public int getIndex( TreeNode node )
+ {
+ DefaultMutableTupleNode tn =
+ ( ( TupleTreeNodeAdapter ) node ).getTupleNode();
+ return this.node.getIndex( tn );
+ }
+
+ DefaultMutableTupleNode getTupleNode()
+ {
+ return node;
+ }
+
+ public String toString()
+ {
+ StringBuffer buf = new StringBuffer();
+ Tuple tuple = node.getTuple();
+ TypeClass type =
+ TypeClass.getTypeClass( node.getTuple().getRawTag() >> 24
);
+ int id = Tag.getTagId( tuple.getRawTag() );
+
+ buf.append( "[" ).append( type.getName() ).append( "][" )
+ .append( id ).append( "]" ).append( "[" )
+ .append( tuple.getLength() ).append( "]" );
+
+ return buf.toString();
+ }
+
+ }
+
+
+ public static void main( String [] args )
+ {
+ JFileChooser fc = new JFileChooser( "." );
+ fc.setFileFilter( new javax.swing.filechooser.FileFilter()
+ {
+ public boolean accept( File f )
+ {
+ return f.isDirectory() || f.getName().endsWith( ".ber" );
+ }
+
+ public String getDescription()
+ {
+ return "BER encoded data files";
+ }
+ }
+ );
+ fc.showOpenDialog( null );
+ File file = fc.getSelectedFile();
+
+ if ( file == null )
+ {
+ System.exit( 0 );
+ }
+
+ FileInputStream in = null;
+
+ try
+ {
+ in = new FileInputStream( file );
+ }
+ catch ( FileNotFoundException e )
+ {
+ e.printStackTrace();
+ System.exit( -1 );
+ }
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try
+ {
+ int ch = -1;
+ while( ( ch = in.read() ) != -1 )
+ {
+ out.write( ch );
+ }
+ }
+ catch ( IOException e )
+ {
+ e.printStackTrace();
+ System.exit( -1 );
+ }
+
+ TupleTreeAnalyzer analyzer;
+ try
+ {
+ analyzer = new TupleTreeAnalyzer( out.toByteArray() );
+ analyzer.startup();
+ }
+ catch ( DecoderException e )
+ {
+ e.printStackTrace();
+ System.exit( -1 );
+ }
+ }
}
Modified:
incubator/directory/snickers/trunk/ber-codec/src/test/org/apache/snickers/ber/BEREncoderTest.java
==============================================================================
---
incubator/directory/snickers/trunk/ber-codec/src/test/org/apache/snickers/ber/BEREncoderTest.java
(original)
+++
incubator/directory/snickers/trunk/ber-codec/src/test/org/apache/snickers/ber/BEREncoderTest.java
Mon Jul 26 21:15:16 2004
@@ -64,67 +64,210 @@
}
+
+ /**
+ * Produces a primitive tuple and pumps it through the encoder while
+ * listening to the output of the encoder collecting the output bytes into
+ * one buffer. Then the collected data is compared with the expected
+ * encoded data.
+ */
public void testPrimitives()
{
+ // prepare tlv and generate an integer tag event
Tuple tlv = new Tuple();
tlv.setTag( UniversalTag.INTEGER );
- encoder.getBERCallback().tagEncoded( tlv );
+ encoder.tag( tlv );
+ // generate a length event
tlv.setLength( 1 );
- encoder.getBERCallback().lengthEncoded( tlv );
+ encoder.length( tlv );
+
+ // generate a value event
+ byte[] value = new byte[] { (byte) 10 };
+ ByteBuffer chunk = ByteBuffer.wrap( value );
+ tlv.setLastValueChunk( chunk );
+ encoder.chunkedValue( tlv, chunk );
- tlv.setLastValueChunk( ByteBuffer.wrap( new byte[] { (byte) 10 }) );
- encoder.getBERCallback().partialValueEncoded( tlv );
- encoder.getBERCallback().encodeOccurred( encoder, tlv );
+ // not really necessary but here for completeness
+ encoder.finish( tlv );
+ // generate the expected encoded bytes
ArrayList list = new ArrayList();
- list.add( ByteBuffer.wrap( new byte[] { (byte) 10 } ) );
+ list.add( ByteBuffer.wrap( value ) );
ByteBuffer buf = tlv.toEncodedBuffer( list );
-
byte[] correctBytes = new byte[buf.remaining()];
buf.get( correctBytes );
+ // gather the collected encoded bytes
collector.flip();
byte[] encodedBytes = new byte[collector.remaining()];
collector.get( encodedBytes );
+ // compare the two
assertTrue( ArrayUtils.isEquals( correctBytes, encodedBytes ) );
}
- public void testConstructedDefinateLength()
+ /**
+ * Produces the tlv events for constructed TLV of definate length.
+ */
+ public void testConstructedDefinateLength1()
{
+ // prepare top level TLV of sequence with length of 3
Tuple top = new Tuple();
- top.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF );
- encoder.getBERCallback().tagEncoded( top );
+ top.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
+ encoder.tag( top );
top.setLength( 3 );
- encoder.getBERCallback().lengthEncoded( top );
+ encoder.length( top );
+ // prepare single nested child tlv
Tuple tlv = new Tuple();
tlv.setTag( UniversalTag.INTEGER );
- encoder.getBERCallback().tagEncoded( tlv );
+ encoder.tag( tlv );
+ tlv.setLength( 1 );
+ encoder.length( tlv );
+ byte[] value = new byte[] { (byte) 10 };
+ ByteBuffer chunk = ByteBuffer.wrap( value );
+ tlv.setLastValueChunk( chunk );
+ encoder.chunkedValue( tlv, chunk );
+ encoder.finish( tlv );
+ encoder.finish( top );
+
+ // prepare the expected correct sequence of encoded bytes
+ ArrayList list = new ArrayList();
+ ByteBuffer all = ByteBuffer.wrap( new byte[64] ) ;
+ all.put( top.toEncodedBuffer( list ) );
+ list.add( ByteBuffer.wrap( value ) );
+ all.put( tlv.toEncodedBuffer( list ) );
+ all.flip();
+ byte[] correctBytes = new byte[all.remaining()];
+ all.get( correctBytes );
+
+ // gather the collected encoded bytes
+ collector.flip();
+ byte[] encodedBytes = new byte[collector.remaining()];
+ collector.get( encodedBytes );
+
+ // compare correct with encoded
+ assertTrue( ArrayUtils.isEquals( correctBytes, encodedBytes ) );
+ }
+
+
+ /**
+ * Produces the tlv events for constructed TLV of definate length.
+ */
+ public void testConstructedDefinateLength2()
+ {
+ // prepare top level TLV of sequence with length of 3
+ Tuple top = new Tuple();
+ top.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
+ encoder.tag( top );
+ top.setLength( 8 );
+ encoder.length( top );
+
+ // prepare the expected correct sequence of encoded bytes
+ ArrayList list = new ArrayList();
+ ByteBuffer all = ByteBuffer.wrap( new byte[64] ) ;
+ all.put( top.toEncodedBuffer( list ) );
+ // prepare single nested child tlv
+ Tuple tlv = new Tuple();
+ tlv.setTag( UniversalTag.INTEGER );
+ encoder.tag( tlv );
tlv.setLength( 1 );
- encoder.getBERCallback().lengthEncoded( tlv );
+ encoder.length( tlv );
+ byte[] value = new byte[] { (byte) 10 };
+ ByteBuffer chunk = ByteBuffer.wrap( value );
+ tlv.setLastValueChunk( chunk );
+ encoder.chunkedValue( tlv, chunk );
+ encoder.finish( tlv );
+ list.add( ByteBuffer.wrap( value ) );
+ all.put( tlv.toEncodedBuffer( list ) );
+
+ tlv.setTag( UniversalTag.INTEGER );
+ encoder.tag( tlv );
+ tlv.setLength( 3 );
+ encoder.length( tlv );
+ value = new byte[] { (byte) 2, 7, 12 };
+ chunk = ByteBuffer.wrap( value );
+ tlv.setLastValueChunk( chunk );
+ encoder.chunkedValue( tlv, chunk );
+ encoder.finish( tlv );
+ encoder.finish( top );
+ list.add( ByteBuffer.wrap( value ) );
+ all.put( tlv.toEncodedBuffer( list ) );
+
+ // prepare the correct buffers
+ all.flip();
+ byte[] correctBytes = new byte[all.remaining()];
+ all.get( correctBytes );
+
+ // gather the collected encoded bytes
+ collector.flip();
+ byte[] encodedBytes = new byte[collector.remaining()];
+ collector.get( encodedBytes );
- tlv.setLastValueChunk( ByteBuffer.wrap( new byte[] { (byte) 10 }) );
- encoder.getBERCallback().partialValueEncoded( tlv );
+ // compare correct with encoded
+ assertTrue( ArrayUtils.isEquals( correctBytes, encodedBytes ) );
+ }
- encoder.getBERCallback().encodeOccurred( encoder, top );
+ /**
+ * Produces the tlv events for constructed TLV of definate length.
+ */
+ public void testConstructedInDefinateLength()
+ {
+ // prepare top level TLV of sequence with length of 3
+ Tuple top = new Tuple();
+ top.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
+ encoder.tag( top );
+ top.setLength( Length.INDEFINATE );
+ encoder.length( top );
+
+ // prepare the expected correct sequence of encoded bytes
ArrayList list = new ArrayList();
ByteBuffer all = ByteBuffer.wrap( new byte[64] ) ;
all.put( top.toEncodedBuffer( list ) );
- list.add( tlv.getLastValueChunk() );
+ // prepare single nested child tlv
+ Tuple tlv = new Tuple();
+ tlv.setTag( UniversalTag.INTEGER );
+ encoder.tag( tlv );
+ tlv.setLength( 1 );
+ encoder.length( tlv );
+ byte[] value = new byte[] { (byte) 10 };
+ ByteBuffer chunk = ByteBuffer.wrap( value );
+ tlv.setLastValueChunk( chunk );
+ encoder.chunkedValue( tlv, chunk );
+ encoder.finish( tlv );
+ list.add( ByteBuffer.wrap( value ) );
+ all.put( tlv.toEncodedBuffer( list ) );
+
+ tlv.setTag( UniversalTag.INTEGER );
+ encoder.tag( tlv );
+ tlv.setLength( 3 );
+ encoder.length( tlv );
+ value = new byte[] { (byte) 2, 7, 12 };
+ chunk = ByteBuffer.wrap( value );
+ tlv.setLastValueChunk( chunk );
+ encoder.chunkedValue( tlv, chunk );
+ encoder.finish( tlv );
+ encoder.finish( top );
+ list.add( ByteBuffer.wrap( value ) );
all.put( tlv.toEncodedBuffer( list ) );
+ all.put( (byte) 0 ).put( (byte) 0 );
+ // prepare the correct buffers
+ all.flip();
byte[] correctBytes = new byte[all.remaining()];
all.get( correctBytes );
+ // gather the collected encoded bytes
+ collector.flip();
byte[] encodedBytes = new byte[collector.remaining()];
collector.get( encodedBytes );
- //assertTrue( ArrayUtils.isEquals( correctBytes, encodedBytes ) );
+ // compare correct with encoded
+ assertTrue( ArrayUtils.isEquals( correctBytes, encodedBytes ) );
}
}
Added:
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/LdapResultEncoder.java
==============================================================================
--- (empty file)
+++
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/LdapResultEncoder.java
Mon Jul 26 21:15:16 2004
@@ -0,0 +1,108 @@
+/*
+ * 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.TupleEventProducer;
+import org.apache.snickers.ber.TupleEventConsumer;
+import org.apache.snickers.ber.Tuple;
+import org.apache.snickers.ber.Length;
+import org.apache.snickers.ber.primitives.UniversalTag;
+import org.apache.snickers.ber.primitives.PrimitiveUtils;
+import org.apache.snickers.ldap.LdapTag;
+import org.apache.ldap.common.message.LdapResult;
+
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+
+
+/**
+ * Encodes the elements of an LdapResult into some top level tuple.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]"> Apache Directory
+ * Project</a> $Rev$
+ */
+public class LdapResultEncoder implements TupleEventProducer
+{
+ TupleEventConsumer consumer = null;
+ Tuple tmp = new Tuple();
+
+
+ public void attach( TupleEventConsumer consumer )
+ {
+ this.consumer = consumer;
+ }
+
+
+ public void encode( LdapResult result )
+ {
+ // Encode the result code
+ tmp.setTag( UniversalTag.ENUMERATED, true );
+ ByteBuffer chunk = ByteBuffer.wrap( PrimitiveUtils
+ .encodeInt( result.getResultCode().getValue() ) ) ;
+ consumer.tag( tmp );
+ tmp.setLength( 1 );
+ consumer.length( tmp );
+ tmp.setLastValueChunk( chunk );
+ consumer.chunkedValue( tmp, chunk );
+ consumer.finish( tmp );
+
+ // Encode the matchedDN
+ tmp.setTag( UniversalTag.OCTET_STRING, true );
+ chunk = ByteBuffer.wrap( result.getMatchedDn().getBytes() );
+ consumer.tag( tmp );
+ tmp.setLength( chunk.remaining() );
+ consumer.length( tmp );
+ tmp.setLastValueChunk( chunk );
+ consumer.chunkedValue( tmp, chunk );
+ consumer.finish( tmp );
+
+ // Encode the errorMsg
+ tmp.setTag( UniversalTag.OCTET_STRING, true );
+ chunk = ByteBuffer.wrap( result.getErrorMessage().getBytes() );
+ consumer.tag( tmp );
+ tmp.setLength( chunk.remaining() );
+ consumer.length( tmp );
+ tmp.setLastValueChunk( chunk );
+ consumer.chunkedValue( tmp, chunk );
+ consumer.finish( tmp );
+
+ if ( result.getReferral() != null &&
+ result.getReferral().getLdapUrls().size() > 0 )
+ {
+ Tuple referrals = new Tuple();
+ referrals.setTag( LdapTag.REFERRAL_TAG, false );
+ consumer.tag( referrals );
+ referrals.setLength( Length.INDEFINATE );
+ consumer.length( referrals );
+
+ Iterator list = result.getReferral().getLdapUrls().iterator();
+ while( list.hasNext() )
+ {
+ tmp.setTag( UniversalTag.OCTET_STRING, true );
+ consumer.tag( tmp );
+ chunk = ByteBuffer.wrap( ( (String) list.next() ).getBytes() );
+ tmp.setLength( chunk.remaining() );
+ consumer.length( tmp );
+ tmp.setLastValueChunk( chunk );
+ consumer.chunkedValue( tmp, chunk );
+ consumer.finish( tmp );
+ }
+
+ consumer.finish( referrals );
+ }
+ }
+}
Modified:
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/SnickersLdapEncoder.java
==============================================================================
---
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/SnickersLdapEncoder.java
(original)
+++
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/SnickersLdapEncoder.java
Mon Jul 26 21:15:16 2004
@@ -18,33 +18,67 @@
import org.apache.commons.codec.EncoderException;
-import org.apache.commons.codec.stateful.AbstractStatefulEncoder;
import org.apache.commons.codec.stateful.StatefulEncoder;
+import org.apache.commons.codec.stateful.EncoderCallback;
+import org.apache.commons.codec.stateful.EncoderMonitor;
import org.apache.ldap.common.message.Message;
import org.apache.ldap.common.message.MessageTypeEnum;
+import org.apache.ldap.common.message.AbandonRequest;
import org.apache.snickers.ldap.encoder.abandon.AbandonRequestEncoder;
+import org.apache.snickers.ber.BEREncoder;
-import java.util.HashMap;
/**
- * A Snickers based LDAP message encoder. The generated events via the
callback
+ * A Snickers based LDAP message producer. The generated events via the
callback
* are TLV tuples.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Apache Directory Project</a>
* @version $Rev$
*/
-public class SnickersLdapEncoder extends AbstractStatefulEncoder
+public class SnickersLdapEncoder implements StatefulEncoder
{
- private HashMap encoderMap = new HashMap();
+ AbandonRequestEncoder abandonReqEncoder = new AbandonRequestEncoder();
+ EncoderMonitor monitor;
+ BEREncoder encoder = new BEREncoder();
- public SnickersLdapEncoder()
- {
- StatefulEncoder encoder = new AbandonRequestEncoder() ;
- }
public void encode( Object obj ) throws EncoderException
{
Message msg = ( Message ) obj;
+
+
+ switch( msg.getType().getValue() )
+ {
+ case( MessageTypeEnum.ABANDONREQUEST_VAL ):
+ abandonReqEncoder.attach( encoder );
+ abandonReqEncoder.encode( ( AbandonRequest ) obj );
+ break;
+ default:
+ IllegalArgumentException e = new IllegalArgumentException(
+ "Cannot encode " + obj ) ;
+ monitor.error( this, e );
+ throw e;
+ }
+ }
+
+
+ public void setCallback( EncoderCallback cb )
+ {
+ encoder.setCallback( cb );
+
+ if ( monitor == null )
+ {
+ monitor.callbackSet( this, null, cb );
+ return;
+ }
+ }
+
+
+
+ public void setEncoderMonitor( EncoderMonitor monitor )
+ {
+ this.monitor = monitor;
+ this.encoder.setEncoderMonitor( monitor );
}
}
Modified:
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/abandon/AbandonRequestEncoder.java
==============================================================================
---
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/abandon/AbandonRequestEncoder.java
(original)
+++
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/abandon/AbandonRequestEncoder.java
Mon Jul 26 21:15:16 2004
@@ -18,11 +18,7 @@
import org.apache.commons.codec.EncoderException;
-import org.apache.commons.codec.stateful.AbstractStatefulEncoder;
-import org.apache.snickers.ber.Tuple;
-import org.apache.snickers.ber.Tag;
-import org.apache.snickers.ber.TypeClass;
-import org.apache.snickers.ber.Length;
+import org.apache.snickers.ber.*;
import org.apache.snickers.ber.primitives.PrimitiveUtils;
import org.apache.snickers.ber.primitives.UniversalTag;
import org.apache.snickers.ldap.LdapTag;
@@ -38,28 +34,52 @@
* Project</a>
* @version $Rev$
*/
-public class AbandonRequestEncoder extends AbstractStatefulEncoder
+public class AbandonRequestEncoder implements TupleEventProducer
{
- Tuple tlv = new Tuple();
+ private TupleEventConsumer consumer = null;
+ private Tuple top = new Tuple();
+ private Tuple msgId = new Tuple();
+ private Tuple abandonId = new Tuple();
- public void encode( Object obj ) throws EncoderException
+
+ public AbandonRequestEncoder()
{
- AbandonRequest req = ( AbandonRequest ) obj;
+ top.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
+ msgId.setTag( UniversalTag.INTEGER );
+ abandonId.setTag( LdapTag.ABANDON_REQUEST );
+ }
+
- tlv.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
- tlv.setLength( Length.INDEFINATE );
- super.encodeOccurred( tlv );
+ public void encode( AbandonRequest req ) throws EncoderException
+ {
+ consumer.tag( top );
+ top.setLength( Length.INDEFINATE );
+ consumer.length( top );
byte[] encoded = PrimitiveUtils.encodeInt( req.getMessageId() );
- tlv.setTag( UniversalTag.INTEGER, true );
- tlv.setLength( encoded.length );
- tlv.setLastValueChunk( ByteBuffer.wrap( encoded ) );
- super.encodeOccurred( tlv );
+ consumer.tag( msgId );
+ msgId.setLength( encoded.length );
+ consumer.length( msgId );
+ ByteBuffer chunk = ByteBuffer.wrap( encoded );
+ msgId.setLastValueChunk( chunk );
+ consumer.chunkedValue( msgId, chunk );
+ consumer.finish( msgId );
encoded = PrimitiveUtils.encodeInt( req.getAbandoned() );
- tlv.setTag( LdapTag.ABANDON_REQUEST );
- tlv.setLength( encoded.length );
- tlv.setLastValueChunk( ByteBuffer.wrap( encoded ) );
- super.encodeOccurred( tlv );
+ consumer.tag( abandonId );
+ abandonId.setLength( encoded.length );
+ consumer.length( abandonId );
+ chunk = ByteBuffer.wrap( encoded );
+ abandonId.setLastValueChunk( chunk );
+ consumer.chunkedValue( abandonId, chunk );
+ consumer.finish( abandonId );
+ consumer.finish( top );
+ }
+
+
+
+ public void attach( TupleEventConsumer consumer )
+ {
+ this.consumer = consumer;
}
}
Added:
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/bind/BindRequestEncoder.java
==============================================================================
--- (empty file)
+++
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/bind/BindRequestEncoder.java
Mon Jul 26 21:15:16 2004
@@ -0,0 +1,131 @@
+/*
+ * 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.bind;
+
+
+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.primitives.UniversalTag;
+import org.apache.snickers.ber.primitives.PrimitiveUtils;
+import org.apache.snickers.ber.primitives.ContextSpecificTag;
+import org.apache.snickers.ldap.LdapTag;
+import org.apache.ldap.common.message.AbandonRequest;
+import org.apache.ldap.common.message.BindRequest;
+import org.apache.commons.codec.EncoderException;
+import org.apache.commons.lang.NotImplementedException;
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * A bind request encoder which transforms LDAP BindRequest stubs into Tuple
+ * events.
+ *
+ * @warning only simple binds have been implemented
+ * @todo implement SASL binds
+ * @author <a href="mailto:[EMAIL PROTECTED]"> Apache Directory
+ * Project</a> $Rev$
+ */
+public class BindRequestEncoder implements TupleEventProducer
+{
+ private TupleEventConsumer consumer = null;
+ private Tuple top = new Tuple();
+ private Tuple tmp = new Tuple();
+ private Tuple bind = new Tuple();
+
+
+ public void attach( TupleEventConsumer consumer )
+ {
+ this.consumer = consumer;
+ }
+
+
+ public BindRequestEncoder()
+ {
+ top.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
+ tmp.setTag( UniversalTag.INTEGER );
+ bind.setTag( LdapTag.BIND_REQUEST, false );
+ }
+
+
+ public void encode( BindRequest req ) throws EncoderException
+ {
+ consumer.tag( top );
+ top.setLength( Length.INDEFINATE );
+ consumer.length( top );
+
+ byte[] encoded = PrimitiveUtils.encodeInt( req.getMessageId() );
+ consumer.tag( tmp );
+ tmp.setLength( encoded.length );
+ consumer.length( tmp );
+ ByteBuffer chunk = ByteBuffer.wrap( encoded );
+ tmp.setLastValueChunk( chunk );
+ consumer.chunkedValue( tmp, chunk );
+ consumer.finish( tmp );
+
+
+ // Start working the bind request structure here
+
+ consumer.tag( bind );
+ bind.setLength( Length.INDEFINATE );
+ consumer.length( bind );
+
+ // encode and send the primitive int for the LDAP bind version
+ byte[] version = PrimitiveUtils.encodeInt( req.isVersion3() ? 3 : 2 );
+ chunk = ByteBuffer.wrap( version ) ;
+ tmp.setTag( UniversalTag.INTEGER, true );
+ consumer.tag( tmp );
+ tmp.setLength( 1 );
+ consumer.length( tmp );
+ tmp.setLastValueChunk( chunk );
+ consumer.chunkedValue( tmp, chunk );
+ consumer.finish( tmp );
+
+
+ // encode and send the primitive LDAPDN for the Bind [as] name
+ chunk = ByteBuffer.wrap( req.getName().getBytes() );
+ tmp.setTag( UniversalTag.OCTET_STRING );
+ consumer.tag( tmp );
+ tmp.setLength( chunk.remaining() );
+ consumer.length( tmp );
+ tmp.setLastValueChunk( chunk );
+ consumer.chunkedValue( tmp, chunk );
+ consumer.finish( tmp );
+
+
+ if ( req.isSimple() )
+ {
+ tmp.setTag( LdapTag.CONTEXT_SPECIFIC_TAG_0, true );
+ consumer.tag( tmp );
+ chunk = ByteBuffer.wrap( req.getCredentials() );
+ tmp.setLength( chunk.remaining() );
+ consumer.length( tmp );
+ tmp.setLastValueChunk( chunk );
+ consumer.chunkedValue( tmp, chunk );
+ consumer.finish( tmp );
+
+ consumer.finish( bind );
+ consumer.finish( top );
+ return;
+ }
+
+
+ throw new NotImplementedException( "SASL binds not implemented" );
+ }
+}
Added:
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/bind/BindResponseEncoder.java
==============================================================================
--- (empty file)
+++
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/bind/BindResponseEncoder.java
Mon Jul 26 21:15:16 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.bind;
+
+
+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.primitives.UniversalTag;
+import org.apache.snickers.ber.primitives.PrimitiveUtils;
+import org.apache.snickers.ldap.LdapTag;
+import org.apache.snickers.ldap.encoder.LdapResultEncoder;
+import org.apache.ldap.common.message.BindResponse;
+import org.apache.ldap.common.message.LdapResult;
+import org.apache.commons.codec.EncoderException;
+import org.apache.commons.lang.NotImplementedException;
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * A bind response encoder which transforms LDAP BindResponse stubs into Tuple
+ * events.
+ *
+ * @warning only simple binds have been implemented
+ * @todo implement SASL binds
+ * @author <a href="mailto:[EMAIL PROTECTED]"> Apache Directory
+ * Project</a> $Rev$
+ */
+public class BindResponseEncoder implements TupleEventProducer
+{
+ private TupleEventConsumer consumer = null;
+ private LdapResultEncoder resultEncoder = new LdapResultEncoder();
+ private Tuple top = new Tuple();
+ private Tuple tmp = new Tuple();
+ private Tuple bind = new Tuple();
+
+
+ public void attach( TupleEventConsumer consumer )
+ {
+ this.consumer = consumer;
+ resultEncoder.attach( consumer );
+ }
+
+
+ public BindResponseEncoder()
+ {
+ top.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
+ tmp.setTag( UniversalTag.INTEGER );
+ bind.setTag( LdapTag.BIND_RESPONSE, false );
+ }
+
+
+ public void encode( BindResponse resp ) throws EncoderException
+ {
+ consumer.tag( top );
+ top.setLength( Length.INDEFINATE );
+ consumer.length( top );
+
+ byte[] encoded = PrimitiveUtils.encodeInt( resp.getMessageId() );
+ consumer.tag( tmp );
+ tmp.setLength( encoded.length );
+ consumer.length( tmp );
+ ByteBuffer chunk = ByteBuffer.wrap( encoded );
+ tmp.setLastValueChunk( chunk );
+ consumer.chunkedValue( tmp, chunk );
+ consumer.finish( tmp );
+
+
+ // Start working the bind request structure here
+ consumer.tag( bind );
+ bind.setLength( Length.INDEFINATE );
+ consumer.length( bind );
+
+ // Encode the result code
+ LdapResult result = resp.getLdapResult();
+ resultEncoder.encode( result );
+
+ if ( resp.getServerSaslCreds() != null )
+ {
+ throw new NotImplementedException( "SASL binds not implemented" ) ;
+ }
+
+ consumer.finish( bind );
+ consumer.finish( top );
+ }
+}
Added:
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/search/SearchRequestEncoder.java
==============================================================================
--- (empty file)
+++
incubator/directory/snickers/trunk/ldap-ber-provider/src/java/org/apache/snickers/ldap/encoder/search/SearchRequestEncoder.java
Mon Jul 26 21:15:16 2004
@@ -0,0 +1,84 @@
+/*
+ * 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.TupleEventProducer;
+import org.apache.snickers.ber.TupleEventConsumer;
+import org.apache.snickers.ber.Tuple;
+import org.apache.snickers.ber.Length;
+import org.apache.snickers.ber.primitives.UniversalTag;
+import org.apache.snickers.ber.primitives.PrimitiveUtils;
+import org.apache.snickers.ldap.LdapTag;
+import org.apache.ldap.common.message.SearchRequest;
+import org.apache.commons.codec.EncoderException;
+
+import java.nio.ByteBuffer;
+
+
+/**
+ * A search request encoder which transforms LDAP SearchRequest stubs into
Tuple
+ * events.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]"> Apache Directory
+ * Project</a> $Rev$
+ */
+public class SearchRequestEncoder implements TupleEventProducer
+{
+ private TupleEventConsumer consumer = null;
+ private Tuple top = new Tuple();
+ private Tuple tmp = new Tuple();
+ private Tuple search = new Tuple();
+
+
+ public void attach( TupleEventConsumer consumer )
+ {
+ this.consumer = consumer;
+ }
+
+
+ public SearchRequestEncoder()
+ {
+ top.setTag( UniversalTag.SEQUENCE_SEQUENCE_OF, false );
+ tmp.setTag( UniversalTag.INTEGER );
+ search.setTag( LdapTag.SEARCH_REQUEST, false );
+ }
+
+
+ public void encode( SearchRequest req ) throws EncoderException
+ {
+ consumer.tag( top );
+ top.setLength( Length.INDEFINATE );
+ consumer.length( top );
+
+ byte[] encoded = PrimitiveUtils.encodeInt( req.getMessageId() );
+ consumer.tag( tmp );
+ tmp.setLength( encoded.length );
+ consumer.length( tmp );
+ ByteBuffer chunk = ByteBuffer.wrap( encoded );
+ tmp.setLastValueChunk( chunk );
+ consumer.chunkedValue( tmp, chunk );
+ consumer.finish( tmp );
+
+
+ // Start working the bind request structure here
+
+ consumer.tag( search );
+ search.setLength( Length.INDEFINATE );
+ consumer.length( search );
+ }
+}
Added:
incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/AbstractEncoderTest.java
==============================================================================
--- (empty file)
+++
incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/AbstractEncoderTest.java
Mon Jul 26 21:15:16 2004
@@ -0,0 +1,90 @@
+/*
+ * 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 junit.framework.TestCase;
+import org.apache.snickers.ber.BEREncoder;
+import org.apache.snickers.ber.TupleEventProducer;
+import org.apache.snickers.ldap.BufferUtils;
+import org.apache.ldap.common.message.*;
+import org.apache.commons.codec.stateful.EncoderCallback;
+import org.apache.commons.codec.stateful.StatefulEncoder;
+
+import java.nio.ByteBuffer;
+import java.io.ByteArrayInputStream;
+
+
+/**
+ * Base class for Encoders that are tuple event producers.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]"> Apache Directory
+ * Project</a> $Rev$
+ */
+public abstract class AbstractEncoderTest extends TestCase
+ implements EncoderCallback
+{
+ protected TupleEventProducer producer = null;
+ BEREncoder encoder = null;
+ protected ByteBuffer collector = null;
+ private final int bufsz;
+
+
+ public AbstractEncoderTest( String string, int bufsz )
+ {
+ super( string );
+ this.bufsz = bufsz;
+ }
+
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ producer = getProducer();
+ encoder = new BEREncoder();
+ encoder.setCallback( this );
+ producer.attach( encoder );
+ collector = ByteBuffer.wrap( new byte[bufsz] );
+ }
+
+
+ protected abstract TupleEventProducer getProducer();
+
+
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+ producer = null;
+ encoder = null;
+ collector = null;
+ }
+
+
+ public void encodeOccurred( StatefulEncoder encoder, Object encoded )
+ {
+ ByteBuffer chunk = ( ByteBuffer ) encoded;
+ collector.put( chunk );
+ }
+
+
+ public static Message decodeEncoded( ByteBuffer encoded )
+ {
+ MessageDecoder decoder = new MessageDecoder();
+ byte[] encodedBytes = BufferUtils.getArray( encoded );
+ ByteArrayInputStream in = new ByteArrayInputStream( encodedBytes );
+ return ( Message ) decoder.decode( null, in );
+ }
+}
Modified:
incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/abandon/AbandonRequestEncoderTest.java
==============================================================================
---
incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/abandon/AbandonRequestEncoderTest.java
(original)
+++
incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/abandon/AbandonRequestEncoderTest.java
Mon Jul 26 21:15:16 2004
@@ -16,86 +16,43 @@
*/
package org.apache.snickers.ldap.encoder.abandon;
-import junit.framework.TestCase;
-import org.apache.commons.codec.stateful.EncoderCallback;
-import org.apache.commons.codec.stateful.StatefulEncoder;
-import org.apache.commons.codec.stateful.DecoderCallback;
-import org.apache.commons.codec.stateful.StatefulDecoder;
-import org.apache.snickers.ber.Tuple;
-import org.apache.snickers.ldap.BufferUtils;
+import org.apache.snickers.ber.TupleEventProducer;
+import org.apache.snickers.ldap.encoder.AbstractEncoderTest;
import org.apache.ldap.common.message.AbandonRequestImpl;
-import org.apache.ldap.common.message.MessageDecoder;
import org.apache.ldap.common.message.AbandonRequest;
-import java.util.ArrayList;
-import java.nio.ByteBuffer;
-import java.io.ByteArrayInputStream;
/**
- * Document me.
+ * Tests to see if we can encode an AbandonRequest using the
+ * AbandonRequestEncoder.
*
* @author <a href="mailto:[EMAIL PROTECTED]"> Apache Directory
* Project</a> $Rev$
*/
-public class AbandonRequestEncoderTest extends TestCase
- implements EncoderCallback, DecoderCallback
+public class AbandonRequestEncoderTest extends AbstractEncoderTest
{
- AbandonRequestEncoder encoder = null;
- Tuple tlv = null;
-
-
- protected void setUp() throws Exception
- {
- super.setUp();
- encoder = new AbandonRequestEncoder();
- encoder.setCallback( this );
- }
-
-
- protected void tearDown() throws Exception
+ public AbandonRequestEncoderTest()
{
- super.tearDown();
- encoder = null;
+ super( "AbandonRequestEncoderTest", 32 );
}
- /**
- * Callback to deliver a fully encoded object.
- *
- * @param encoder the stateful encoder driving the callback
- * @param encoded the object that was encoded
- */
- public void encodeOccurred( StatefulEncoder encoder, Object encoded )
+ protected TupleEventProducer getProducer()
{
- tlv = ( Tuple ) encoded;
+ return new AbandonRequestEncoder();
}
- /**
- * Callback to deliver a fully decoded object.
- *
- * @param decoder the stateful decoder driving the callback
- * @param decoded the object that was decoded
- */
- public void decodeOccurred( StatefulDecoder decoder, Object decoded )
+ public void testEncode() throws Exception
{
- }
+ AbandonRequestImpl req = new AbandonRequestImpl( 5 );
+ req.setAbandoned( 23 );
+ ( ( AbandonRequestEncoder ) producer ).encode( req );
+ AbandonRequest decodedReq;
+ decodedReq = ( AbandonRequest ) decodeEncoded( collector );
- public void testEncode() throws Exception
- {
-// AbandonRequestImpl req = new AbandonRequestImpl( 5 );
-// req.setAbandoned( 23 );
-// encoder.encode( req );
-//
-// ArrayList valueChuncks = new ArrayList() ;
-// valueChuncks.add( tlv.getLastValueChunk() );
-// ByteBuffer encoded = tlv.toEncodedBuffer( valueChuncks );
-// MessageDecoder decoder = new MessageDecoder();
-//
-// byte[] encodedBytes = BufferUtils.getArray( encoded );
-// ByteArrayInputStream in = new ByteArrayInputStream( encodedBytes );
-//
-// AbandonRequest decodedReq = ( AbandonRequest )
decoder.decode(null,in);
+ assertEquals( req.getMessageId(), decodedReq.getMessageId() );
+ assertEquals( req.getAbandoned(), decodedReq.getAbandoned() );
}
}
Added:
incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/bind/BindRequestEncoderTest.java
==============================================================================
--- (empty file)
+++
incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/bind/BindRequestEncoderTest.java
Mon Jul 26 21:15:16 2004
@@ -0,0 +1,68 @@
+/*
+ * 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.bind;
+
+import org.apache.snickers.ber.TupleEventProducer;
+import org.apache.snickers.ldap.encoder.AbstractEncoderTest;
+import org.apache.ldap.common.message.BindRequestImpl;
+import org.apache.ldap.common.message.BindRequest;
+import org.apache.commons.lang.ArrayUtils;
+
+
+/**
+ * Tests to see if we can encode an AbandonRequest using the
+ * AbandonRequestEncoder.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]"> Apache Directory
+ * Project</a> $Rev$
+ */
+public class BindRequestEncoderTest extends AbstractEncoderTest
+{
+ private static final String LDAPDN = "ou=People,dc=example,dc=com";
+ private static final byte[] CREDS = "passwd".getBytes();
+
+
+ public BindRequestEncoderTest()
+ {
+ super( "BindRequestEncoderTest", 128 );
+ }
+
+
+ protected TupleEventProducer getProducer()
+ {
+ return new BindRequestEncoder();
+ }
+
+
+ public void testEncode() throws Exception
+ {
+ BindRequestImpl req = new BindRequestImpl( 5 );
+ req.setVersion3( true );
+ req.setSimple( true );
+ req.setName( LDAPDN );
+ req.setCredentials( CREDS );
+ ( ( BindRequestEncoder ) producer ).encode( req );
+
+ BindRequest decodedReq = ( BindRequest ) decodeEncoded( collector );
+ assertEquals( req.getMessageId(), decodedReq.getMessageId() );
+ assertEquals( req.getVersion3(), decodedReq.getVersion3() );
+ assertEquals( req.getSimple(), decodedReq.getSimple() );
+ assertEquals( req.getName(), decodedReq.getName() );
+ assertTrue( ArrayUtils.isEquals( req.getCredentials(),
+ decodedReq.getCredentials() ) );
+ }
+}
Added:
incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/bind/BindResponseEncoderTest.java
==============================================================================
--- (empty file)
+++
incubator/directory/snickers/trunk/ldap-ber-provider/src/test/org/apache/snickers/ldap/encoder/bind/BindResponseEncoderTest.java
Mon Jul 26 21:15:16 2004
@@ -0,0 +1,103 @@
+/*
+ * 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.bind;
+
+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;
+
+
+/**
+ * Tests to see if we can encode an AbandonRequest using the
+ * AbandonRequestEncoder.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]"> Apache Directory
+ * Project</a> $Rev$
+ */
+public class BindResponseEncoderTest extends AbstractEncoderTest
+{
+ private static final String LDAPDN = "dc=com";
+
+ public BindResponseEncoderTest()
+ {
+ super( "BindResponseEncoderTest", 128 );
+ }
+
+
+ protected TupleEventProducer getProducer()
+ {
+ return new BindResponseEncoder();
+ }
+
+
+ public void testEncode() throws Exception
+ {
+ BindResponseImpl resp = new BindResponseImpl( 5 );
+ LdapResultImpl result = new LdapResultImpl( resp ) ;
+ resp.setLdapResult( result );
+ result.setResultCode( ResultCodeEnum.SUCCESS );
+ result.setMatchedDn( LDAPDN );
+ 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" );
+ ( ( BindResponseEncoder ) producer ).encode( resp );
+
+ MessageEncoder snaccEncoder = new MessageEncoder();
+ byte[] snaccEncoded = snaccEncoder.encode( resp );
+ File cwd = new File( "." );
+ FileOutputStream out = new FileOutputStream( new File(cwd,
+ "BindResponseEncoderTestSnacc.ber" ) );
+ out.write( snaccEncoded );
+
+ collector.flip();
+ byte[] snickersEncoded = new byte[collector.remaining()];
+ collector.get( snickersEncoded );
+ collector.rewind();
+ out = new FileOutputStream( new File(cwd,
+ "BindResponseEncoderTestSnickers.ber" ) );
+ out.write( snickersEncoded );
+
+ BindResponse decodedResp = ( BindResponse ) 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" ) );
+ }
+}
Modified: incubator/directory/snickers/trunk/project.xml
==============================================================================
--- incubator/directory/snickers/trunk/project.xml (original)
+++ incubator/directory/snickers/trunk/project.xml Mon Jul 26 21:15:16 2004
@@ -160,6 +160,7 @@
<excludes>
<exclude>**/testutils/*</exclude>
+ <exclude>**/Abstract*</exclude>
</excludes>
<resources>
Modified:
incubator/directory/snickers/trunk/xdocs/ber-codec/BEREncoderDesign.xml
==============================================================================
--- incubator/directory/snickers/trunk/xdocs/ber-codec/BEREncoderDesign.xml
(original)
+++ incubator/directory/snickers/trunk/xdocs/ber-codec/BEREncoderDesign.xml
Mon Jul 26 21:15:16 2004
@@ -13,17 +13,27 @@
<subsection name="Layering Encoders">
<p>
- It is a good idea to delegate different levels of functionality to
- different encoders to divide the responsibilities of each encoder.
- In many respects we are thinking about stacking multiple BER encoders
- and multiplexing them as well.
+ It might be a good idea to separate encoder functionality into
+ separate encoder layers. This way we can isolation operations to
+ divide the responsibilities of each encoder keeping each encoder
+ simple. We are talking about stacking multiple encoders on top of
+ each other.
</p>
<p>
- It might be a good idea to suppose that a TLV event stream is being
- encoded into a byte buffer. This then would be the lowest level of
- BER encoding. This approach where a low level TLV tuple encoder is
- used has several benefits:
+ The most primitive teir could be an encoder concerned with writing
+ chunks out to a channel. On top of that may reside another encoder
+ that converts TLV Tuple Tag, Length and Value events into a stream
+ of chunked buffers. High level encoders can be designed to take
+ stub instances as and input to produce a stream of TLV tuple events.
+ These events are then pipped into the low level Tuple event encoder,
+ then written out as chunks to a channel. We really will not be
+ concerned with where the chunks go the event producer consumer
+ pipeline is the primary concern for us.
+ </p>
+
+ <p>
+ There are several benefits to this approach. Here's a few of them:
</p>
<ul>
@@ -32,7 +42,7 @@
</li>
<li>
event streams generated by low level decoders can be piped
- directly into low level encoders for testing
+ directly into low level encoders for round trip testing
</li>
<li>
low level tuple encoder can be very efficient and fast because of
@@ -52,11 +62,14 @@
aspects where other stacked encoders built upon it do not have to
be concerned with this
</li>
+ <li>
+ Stub specific code does not mix with generic tuple processing code.
+ </li>
</ul>
<p>
This low level TLV Tuple event stream encoder will need to receive
- TLV events somehow. The encoder hence must implement some kind of
+ TLV events somehow. The encoder hence smust implement some kind of
callback. The fact that it is a callback makes it receive the
substrate this way rather than through the conventional encode()
pathway. What then happens to the idea of an encode() method that