From cd57b969289f568da79e41fffe451aa0ed837722 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Wed, 28 Jan 2009 23:43:17 +0000
Subject: [PATCH] Fix issue 3446 and improve fix for issue 3726:

---
 opends/src/server/org/opends/server/core/SearchOperationBasis.java |  201 +++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 149 insertions(+), 52 deletions(-)

diff --git a/opends/src/server/org/opends/server/core/SearchOperationBasis.java b/opends/src/server/org/opends/server/core/SearchOperationBasis.java
index b4aad32..456aa04 100644
--- a/opends/src/server/org/opends/server/core/SearchOperationBasis.java
+++ b/opends/src/server/org/opends/server/core/SearchOperationBasis.java
@@ -22,7 +22,7 @@
  * CDDL HEADER END
  *
  *
- *      Copyright 2006-2008 Sun Microsystems, Inc.
+ *      Copyright 2006-2009 Sun Microsystems, Inc.
  */
 package org.opends.server.core;
 
@@ -35,6 +35,7 @@
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 import org.opends.server.api.ClientConnection;
 import org.opends.server.api.plugin.PluginResult;
@@ -714,10 +715,13 @@
     // Make a copy of the entry and pare it down to only include the set
     // of requested attributes.
     Entry entryToReturn;
+    boolean omitReal = isVirtualAttributesOnly();
+    boolean omitVirtual = isRealAttributesOnly();
     if ((getAttributes() == null) || getAttributes().isEmpty())
     {
-      entryToReturn = entry.duplicateWithoutOperationalAttributes(typesOnly,
-                                                                  true);
+      entryToReturn =
+          entry.duplicateWithoutOperationalAttributes(typesOnly,
+              omitReal, omitVirtual);
     }
     else
     {
@@ -729,22 +733,26 @@
         {
           // This is a special placeholder indicating that all user attributes
           // should be returned.
-          if (typesOnly)
+          if (!omitReal)
           {
-            // First, add the placeholder for the objectclass attribute.
-            AttributeType ocType =
-                 DirectoryServer.getObjectClassAttributeType();
-            List<Attribute> ocList = new ArrayList<Attribute>(1);
-            ocList.add(Attributes.empty(ocType));
-            entryToReturn.putAttribute(ocType, ocList);
-          }
-          else
-          {
-            // First, add the objectclass attribute.
-            Attribute ocAttr = entry.getObjectClassAttribute();
-            if (ocAttr != null)
+            if (typesOnly)
             {
-              entryToReturn.replaceAttribute(ocAttr);
+              // First, add the placeholder for the objectclass
+              // attribute.
+              AttributeType ocType =
+                  DirectoryServer.getObjectClassAttributeType();
+              List<Attribute> ocList = new ArrayList<Attribute>(1);
+              ocList.add(Attributes.empty(ocType));
+              entryToReturn.putAttribute(ocType, ocList);
+            }
+            else
+            {
+              // First, add the objectclass attribute.
+              Attribute ocAttr = entry.getObjectClassAttribute();
+              if (ocAttr != null)
+              {
+                entryToReturn.replaceAttribute(ocAttr);
+              }
             }
           }
 
@@ -752,8 +760,12 @@
           for (AttributeType t : entry.getUserAttributes().keySet())
           {
             List<Attribute> attrList =
-                 entry.duplicateUserAttribute(t, null, typesOnly);
-            entryToReturn.putAttribute(t, attrList);
+                duplicateUserAttribute(entry, t, null, typesOnly,
+                    omitReal, omitVirtual);
+            if (attrList != null)
+            {
+              entryToReturn.putAttribute(t, attrList);
+            }
           }
 
           continue;
@@ -765,8 +777,12 @@
           for (AttributeType t : entry.getOperationalAttributes().keySet())
           {
             List<Attribute> attrList =
-                 entry.duplicateOperationalAttribute(t, null, typesOnly);
-            entryToReturn.putAttribute(t, attrList);
+                duplicateOperationalAttribute(entry, t, null,
+                    typesOnly, omitReal, omitVirtual);
+            if (attrList != null)
+            {
+              entryToReturn.putAttribute(t, attrList);
+            }
           }
 
           continue;
@@ -787,7 +803,6 @@
             semicolonPos = nextPos;
             nextPos = attrName.indexOf(';', semicolonPos+1);
           }
-
           options.add(attrName.substring(semicolonPos+1));
         }
         else
@@ -796,7 +811,6 @@
           options = null;
         }
 
-
         AttributeType attrType = DirectoryServer.getAttributeType(lowerName);
         if (attrType == null)
         {
@@ -806,11 +820,11 @@
             if (t.hasNameOrOID(lowerName))
             {
               List<Attribute> attrList =
-                   entry.duplicateUserAttribute(t, options, typesOnly);
+                  duplicateUserAttribute(entry, t, options, typesOnly,
+                      omitReal, omitVirtual);
               if (attrList != null)
               {
                 entryToReturn.putAttribute(t, attrList);
-
                 added = true;
                 break;
               }
@@ -827,11 +841,11 @@
             if (t.hasNameOrOID(lowerName))
             {
               List<Attribute> attrList =
-                   entry.duplicateOperationalAttribute(t, options, typesOnly);
+                  duplicateOperationalAttribute(entry, t, options,
+                      typesOnly, omitReal, omitVirtual);
               if (attrList != null)
               {
                 entryToReturn.putAttribute(t, attrList);
-
                 break;
               }
             }
@@ -840,30 +854,34 @@
         else
         {
           if (attrType.isObjectClassType()) {
-            if (typesOnly)
+            if (!omitReal)
             {
-              AttributeType ocType =
-                   DirectoryServer.getObjectClassAttributeType();
-              List<Attribute> ocList = new ArrayList<Attribute>(1);
-              ocList.add(Attributes.empty(ocType));
-              entryToReturn.putAttribute(ocType, ocList);
-            }
-            else
-            {
-              List<Attribute> attrList = new ArrayList<Attribute>(1);
-              attrList.add(entry.getObjectClassAttribute());
-              entryToReturn.putAttribute(attrType, attrList);
+              if (typesOnly)
+              {
+                AttributeType ocType =
+                    DirectoryServer.getObjectClassAttributeType();
+                List<Attribute> ocList = new ArrayList<Attribute>(1);
+                ocList.add(Attributes.empty(ocType));
+                entryToReturn.putAttribute(ocType, ocList);
+              }
+              else
+              {
+                List<Attribute> attrList = new ArrayList<Attribute>(1);
+                attrList.add(entry.getObjectClassAttribute());
+                entryToReturn.putAttribute(attrType, attrList);
+              }
             }
           }
           else
           {
             List<Attribute> attrList =
-                 entry.duplicateOperationalAttribute(attrType, options,
-                                                     typesOnly);
+                duplicateOperationalAttribute(entry, attrType, options,
+                    typesOnly, omitReal, omitVirtual);
             if (attrList == null)
             {
-              attrList = entry.duplicateUserAttribute(attrType, options,
-                                                      typesOnly);
+              attrList =
+                  duplicateUserAttribute(entry, attrType, options,
+                      typesOnly, omitReal, omitVirtual);
             }
             if (attrList != null)
             {
@@ -874,15 +892,6 @@
       }
     }
 
-    if (isRealAttributesOnly())
-    {
-      entryToReturn.stripVirtualAttributes();
-    }
-    else if (isVirtualAttributesOnly())
-    {
-      entryToReturn.stripRealAttributes();
-    }
-
     // If there is a matched values control, then further pare down the entry
     // based on the filters that it contains.
     MatchedValuesControl matchedValuesControl = getMatchedValuesControl();
@@ -1466,6 +1475,7 @@
   /**
    * {@inheritDoc}
    */
+  @Override
   public final void run()
   {
     setResultCode(ResultCode.UNDEFINED);
@@ -1617,4 +1627,91 @@
     appendErrorMessage(message);
   }
 
+
+  // Copies non-empty attributes.
+  private List<Attribute> duplicateAttribute(
+       List<Attribute> attrList,
+       Set<String> options,
+       boolean omitValues,
+       boolean omitReal,
+       boolean omitVirtual)
+  {
+    if (attrList == null)
+    {
+      return null;
+    }
+
+    ArrayList<Attribute> duplicateList =
+         new ArrayList<Attribute>(attrList.size());
+    for (Attribute a : attrList)
+    {
+      if (a.hasAllOptions(options))
+      {
+        if (omitReal && !a.isVirtual())
+        {
+          continue;
+        }
+        else if (omitVirtual && a.isVirtual())
+        {
+          continue;
+        }
+        else if (a.isEmpty())
+        {
+          continue;
+        }
+        else if (omitValues)
+        {
+          duplicateList.add(Attributes.empty(a));
+        }
+        else
+        {
+          duplicateList.add(a);
+        }
+      }
+    }
+
+    if (duplicateList.isEmpty())
+    {
+      return null;
+    }
+    else
+    {
+      return duplicateList;
+    }
+  }
+
+
+
+  // Copy a user attribute - may return null if the attribute was
+  // not found or if it was empty.
+  private List<Attribute> duplicateUserAttribute(
+       Entry entry,
+       AttributeType attributeType,
+       Set<String> options,
+       boolean omitValues,
+       boolean omitReal,
+       boolean omitVirtual)
+  {
+    List<Attribute> currentList = entry.getUserAttribute(attributeType);
+    return duplicateAttribute(currentList, options, omitValues,
+        omitReal, omitVirtual);
+  }
+
+
+
+  // Copy an operational attribute - may return null if the
+  // attribute was not found or if it was empty.
+  private List<Attribute> duplicateOperationalAttribute(
+       Entry entry,
+       AttributeType attributeType,
+       Set<String> options,
+       boolean omitValues,
+       boolean omitReal,
+       boolean omitVirtual)
+  {
+    List<Attribute> currentList =
+         entry.getOperationalAttribute(attributeType);
+    return duplicateAttribute(currentList, options, omitValues,
+        omitReal, omitVirtual);
+  }
 }

--
Gitblit v1.10.0