From ebf96a30d0122d35e271bad15f1f31a0a9100842 Mon Sep 17 00:00:00 2001
From: Ludovic Poitou <ludovic.poitou@forgerock.com>
Date: Sun, 24 Oct 2010 20:47:53 +0000
Subject: [PATCH] Sync commits from OpenDS by matthew_swift

---
 sdk/src/org/opends/sdk/requests/AbstractUnmodifiableRequest.java |   68 ++++++++++++++++++++++++++++++++--
 1 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/sdk/src/org/opends/sdk/requests/AbstractUnmodifiableRequest.java b/sdk/src/org/opends/sdk/requests/AbstractUnmodifiableRequest.java
index 3bba75c..128b2c9 100644
--- a/sdk/src/org/opends/sdk/requests/AbstractUnmodifiableRequest.java
+++ b/sdk/src/org/opends/sdk/requests/AbstractUnmodifiableRequest.java
@@ -36,6 +36,12 @@
 import org.opends.sdk.DecodeOptions;
 import org.opends.sdk.controls.Control;
 import org.opends.sdk.controls.ControlDecoder;
+import org.opends.sdk.controls.GenericControl;
+
+import com.sun.opends.sdk.util.Collections2;
+import com.sun.opends.sdk.util.Function;
+import com.sun.opends.sdk.util.Functions;
+import com.sun.opends.sdk.util.Validator;
 
 
 
@@ -69,6 +75,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public final R addControl(final Control control)
       throws UnsupportedOperationException, NullPointerException
   {
@@ -80,12 +87,49 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public final <C extends Control> C getControl(
       final ControlDecoder<C> decoder, final DecodeOptions options)
       throws NullPointerException, DecodeException
   {
-    // FIXME: ensure that controls are immutable.
-    return impl.getControl(decoder, options);
+    Validator.ensureNotNull(decoder, options);
+
+    final List<Control> controls = impl.getControls();
+
+    // Avoid creating an iterator if possible.
+    if (controls.isEmpty())
+    {
+      return null;
+    }
+
+    for (final Control control : controls)
+    {
+      if (control.getOID().equals(decoder.getOID()))
+      {
+        // Got a match. Return a defensive copy only if necessary.
+        final C decodedControl = decoder.decodeControl(control, options);
+
+        if (decodedControl != control)
+        {
+          // This was not the original control so return it immediately.
+          return decodedControl;
+        }
+        else if (decodedControl instanceof GenericControl)
+        {
+          // Generic controls are immutable, so return it immediately.
+          return decodedControl;
+        }
+        else
+        {
+          // Re-decode to get defensive copy.
+          final GenericControl genericControl = GenericControl
+              .newControl(control);
+          return decoder.decodeControl(genericControl, options);
+        }
+      }
+    }
+
+    return null;
   }
 
 
@@ -93,10 +137,26 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public final List<Control> getControls()
   {
-    // FIXME: ensure that controls are immutable.
-    return Collections.unmodifiableList(impl.getControls());
+    // We need to make all controls unmodifiable as well, which implies making
+    // defensive copies where necessary.
+    final Function<Control, Control, Void> function = new Function<Control, Control, Void>()
+    {
+
+      @Override
+      public Control apply(final Control value, final Void p)
+      {
+        // Return defensive copy.
+        return GenericControl.newControl(value);
+      }
+
+    };
+
+    final List<Control> unmodifiableControls = Collections2.transformedList(
+        impl.getControls(), function, Functions.<Control> identityFunction());
+    return Collections.unmodifiableList(unmodifiableControls);
   }
 
 

--
Gitblit v1.10.0