From c29b582ac18ba517a4f4ead7f3fc67bc501dd146 Mon Sep 17 00:00:00 2001
From: Chris Ridd <chris.ridd@forgerock.com>
Date: Mon, 03 Dec 2012 09:37:41 +0000
Subject: [PATCH] Fix OPENDJ-654 - DSML searches return empty documents

---
 opends/src/server/org/opends/server/types/ByteStringBuilder.java  |   22 +++++++++++
 opends/src/dsml/org/opends/dsml/protocol/ByteStringUtility.java   |   37 +++++++++++++++++-
 opends/src/server/org/opends/server/types/ByteString.java         |   11 +++++
 opends/src/dsml/org/opends/dsml/protocol/DSMLSearchOperation.java |    2 
 opends/resource/dsml/schema/bindings.xjb                          |   12 ------
 opends/src/server/org/opends/server/types/ByteSequence.java       |   15 +++++++
 6 files changed, 84 insertions(+), 15 deletions(-)

diff --git a/opends/resource/dsml/schema/bindings.xjb b/opends/resource/dsml/schema/bindings.xjb
index ce4d5c6..742fc40 100644
--- a/opends/resource/dsml/schema/bindings.xjb
+++ b/opends/resource/dsml/schema/bindings.xjb
@@ -69,18 +69,6 @@
    <baseType name="java.lang.Object"/>
   </property>
  </bindings>
- <!--
- <bindings node="//xsd:complexType[@name='ResultCode']">
-  <property>
-   <baseType name="org.opends.dsml.protocol.SafeResultCode"/>
-  </property>
- </bindings>
- <bindings node="//xsd:complexType[@name='LDAPResult']/xsd:complexContent/xsd:extension[@base='DsmlMessage']/xsd:sequence/xsd:element[@name='resultCode']">
-  <property>
-    <baseType name="org.opends.dsml.protocol.SafeResultCode"/>
-  </property>
- </bindings>
- -->
  <bindings node="//xsd:complexType[@name='ExtendedRequest']/xsd:complexContent/xsd:extension[@base='DsmlMessage']/xsd:sequence/xsd:element[@name='requestValue']">
   <property>
    <baseType name="java.lang.Object"/>
diff --git a/opends/src/dsml/org/opends/dsml/protocol/ByteStringUtility.java b/opends/src/dsml/org/opends/dsml/protocol/ByteStringUtility.java
index 66ceca7..7c1eda3 100644
--- a/opends/src/dsml/org/opends/dsml/protocol/ByteStringUtility.java
+++ b/opends/src/dsml/org/opends/dsml/protocol/ByteStringUtility.java
@@ -29,6 +29,10 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CodingErrorAction;
 
 import org.opends.server.types.ByteString;
 import org.opends.server.types.ByteStringBuilder;
@@ -36,10 +40,13 @@
 
 /**
  * A utility class to assist in converting DsmlValues (in Objects) into
- * the required ByteStrings.
+ * the required ByteStrings, and back again.
  */
 public class ByteStringUtility
 {
+  // Non-lossy UTF-8 converter object.
+  private static final Charset UTF8 = Charset.forName("UTF-8");
+
   /**
    * Returns a ByteString from a DsmlValue Object.
    *
@@ -79,7 +86,10 @@
         }
         finally
         {
-          is.close();
+          if (is != null)
+          {
+            is.close();
+          }
         }
       }
       else if (obj instanceof Element)
@@ -91,4 +101,27 @@
     return bs;
   }
 
+  /**
+   * Returns a DsmlValue (Object) from an LDAP ByteString. The conversion is
+   * simplistic - try and convert it to UTF-8 and if that fails return a byte[].
+   *
+   * @param bs the ByteString returned from LDAP.
+   * @return a String or a byte[].
+   */
+  public static Object convertByteString(ByteString bs)
+  {
+    try
+    {
+      CharsetDecoder decoder = UTF8.newDecoder();
+      decoder.onMalformedInput(CodingErrorAction.REPORT);
+      decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
+      decoder.reset();
+      CharBuffer chars = decoder.decode(bs.asByteBuffer());
+      return chars.toString();
+    }
+    catch (Exception e)
+    {
+      return bs.toByteArray();
+    }
+  }
 }
diff --git a/opends/src/dsml/org/opends/dsml/protocol/DSMLSearchOperation.java b/opends/src/dsml/org/opends/dsml/protocol/DSMLSearchOperation.java
index a0b2337..8615178 100644
--- a/opends/src/dsml/org/opends/dsml/protocol/DSMLSearchOperation.java
+++ b/opends/src/dsml/org/opends/dsml/protocol/DSMLSearchOperation.java
@@ -588,7 +588,7 @@
             ArrayList<ByteString> vals = attr.getValues();
             for (ByteString val : vals)
             {
-              dsmlAttrVal.add(val);
+              dsmlAttrVal.add(ByteStringUtility.convertByteString(val));
             }
             attrList.add(dsmlAttr);
           }
diff --git a/opends/src/server/org/opends/server/types/ByteSequence.java b/opends/src/server/org/opends/server/types/ByteSequence.java
index cddc564..502a8e1 100644
--- a/opends/src/server/org/opends/server/types/ByteSequence.java
+++ b/opends/src/server/org/opends/server/types/ByteSequence.java
@@ -31,6 +31,7 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.nio.ByteBuffer;
 import java.nio.channels.WritableByteChannel;
 
 
@@ -60,6 +61,20 @@
 
 
   /**
+   * Returns a {@link ByteBuffer} which can be used to read data from this
+   * byte sequence.
+   * <p>
+   * <b>NOTE:</b> any concurrent changes to the underlying byte
+   * sequence (if mutable) may cause unexpected results.
+   *
+   * @return The {@link ByteBuffer} which can be used to read data from this
+   * byte sequence.
+   */
+  ByteBuffer asByteBuffer();
+
+
+
+  /**
    * Returns the byte value at the specified index.
    * <p>
    * An index ranges from zero to {@code length() - 1}. The first byte
diff --git a/opends/src/server/org/opends/server/types/ByteString.java b/opends/src/server/org/opends/server/types/ByteString.java
index e97202b..51112fc 100644
--- a/opends/src/server/org/opends/server/types/ByteString.java
+++ b/opends/src/server/org/opends/server/types/ByteString.java
@@ -792,4 +792,15 @@
   {
     return toString(buffer, offset, length);
   }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ByteBuffer asByteBuffer()
+  {
+    return ByteBuffer.wrap(buffer, offset, length).asReadOnlyBuffer();
+  }
 }
diff --git a/opends/src/server/org/opends/server/types/ByteStringBuilder.java b/opends/src/server/org/opends/server/types/ByteStringBuilder.java
index 58a11cb..b3f45cd 100644
--- a/opends/src/server/org/opends/server/types/ByteStringBuilder.java
+++ b/opends/src/server/org/opends/server/types/ByteStringBuilder.java
@@ -308,6 +308,17 @@
       // Protect against reallocation: use builder's buffer.
       return ByteString.toString(buffer, subOffset, subLength);
     }
+
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ByteBuffer asByteBuffer()
+    {
+      return ByteBuffer.wrap(buffer, subOffset, subLength);
+    }
   }
 
   // Used for tracing exceptions.
@@ -1280,4 +1291,15 @@
     // Still unsuccessful. Give up.
     return false;
   }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ByteBuffer asByteBuffer()
+  {
+    return ByteBuffer.wrap(buffer, 0, length);
+  }
 }

--
Gitblit v1.10.0