Fix an issue with FilterImpl.toString which could throw a NullPointerException when several Threads where doing a toString at the same time. The fix is making the children member of Operator volatile and assign it optimistic. (FELIX-721)

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@694713 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/util/ldap/Operator.java b/framework/src/main/java/org/apache/felix/framework/util/ldap/Operator.java
index 3827167..aa10391 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/ldap/Operator.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/ldap/Operator.java
@@ -32,5 +32,5 @@
 
     // Place to store the reconstructed parsetree
     // Vector -> ArrayList is using jdk1.2 or later
-    public Operator[] children = null;
+    public volatile Operator[] children = null;
 }
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/ldap/Parser.java b/framework/src/main/java/org/apache/felix/framework/util/ldap/Parser.java
index ac6f678..f2c8c40 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/ldap/Parser.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/ldap/Parser.java
@@ -582,12 +582,16 @@
 
         public void buildTree(Stack operands)
         {
-            children = new Operator[operandCount];
-            // need to preserve stack order
-            for (int i = 0; i < operandCount; i++)
+            if (children == null)
             {
-                children[(operandCount - 1) - i] =
-                    (Operator) operands.pop();
+                Operator[] tmp = new Operator[operandCount];
+                // need to preserve stack order
+                for (int i = 0; i < operandCount; i++)
+                {
+                    tmp[(operandCount - 1) - i] =
+                        (Operator) operands.pop();
+                }
+                children = tmp;
             }
             operands.push(this);
         }
@@ -647,12 +651,17 @@
 
         public void buildTree(Stack operands)
         {
-            children = new Operator[operandCount];
-            // need to preserve stack order
-            for (int i = 0; i < operandCount; i++)
+            if (children == null) 
             {
-                children[(operandCount - 1) - i] =
-                    (Operator) operands.pop();
+                Operator[] tmp = new Operator[operandCount];
+            
+                // need to preserve stack order
+                for (int i = 0; i < operandCount; i++)
+                {
+                    tmp[(operandCount - 1) - i] =
+                        (Operator) operands.pop();
+                }
+                children = tmp;
             }
             operands.push(this);
         }
@@ -693,8 +702,11 @@
 
         public void buildTree(Stack operands)
         {
-            children = new Operator[1];
-            children[0] = (Operator) operands.pop();
+            if (children == null)
+            {
+                children = new Operator[]{
+                    (Operator) operands.pop()};
+            }
             operands.push(this);
         }
 
@@ -787,12 +799,17 @@
 
         public void buildTree(Stack operands)
         {
-            children = new Operator[2];
-            // need to preserve stack order
-            for (int i = 0; i < 2; i++)
-            {
-                Operator o = (Operator) operands.pop();
-                children[1 - i] = o;
+            if (children == null)
+            { 
+                Operator[] tmp = new Operator[2];
+            
+                // need to preserve stack order
+                for (int i = 0; i < 2; i++)
+                {
+                    Operator o = (Operator) operands.pop();
+                    tmp[1 - i] = o;
+                }
+                children = tmp;
             }
             operands.push(this);
         }
@@ -845,11 +862,16 @@
 
         public void buildTree(Stack operands)
         {
-            children = new Operator[2];
-            // need to preserve stack order
-            for (int i = 0; i < 2; i++)
+            if (children == null)
             {
-                children[1 - i] = (Operator) operands.pop();
+                Operator[] tmp = new Operator[2];
+            
+                // need to preserve stack order
+                for (int i = 0; i < 2; i++)
+                {
+                    tmp[1 - i] = (Operator) operands.pop();
+                }
+                children = tmp;
             }
             operands.push(this);
         }
@@ -901,11 +923,16 @@
 
         public void buildTree(Stack operands)
         {
-            children = new Operator[2];
-            // need to preserve stack order
-            for (int i = 0; i < 2; i++)
+            if (children == null)
             {
-                children[1 - i] = (Operator) operands.pop();
+                Operator[] tmp = new Operator[2];
+            
+                // need to preserve stack order
+                for (int i = 0; i < 2; i++)
+                {
+                    tmp[1 - i] = (Operator) operands.pop();
+                }
+                children = tmp;
             }
             operands.push(this);
         }
@@ -957,11 +984,16 @@
 
         public void buildTree(Stack operands)
         {
-            children = new Operator[2];
-            // need to preserve stack order
-            for (int i = 0; i < 2; i++)
+            if (children == null)
             {
-                children[1 - i] = (Operator) operands.pop();
+                Operator[] tmp = new Operator[2];
+            
+                // need to preserve stack order
+                for (int i = 0; i < 2; i++)
+                {
+                    tmp[1 - i] = (Operator) operands.pop();
+                }
+                children = tmp;
             }
             operands.push(this);
         }
@@ -1230,8 +1262,11 @@
 
         public void buildTree(Stack operands)
         {
-            children = new Operator[1];
-            children[0] = (Operator) operands.pop();
+            if (children == null) 
+            {
+                children = new Operator[]{
+                    (Operator) operands.pop()};
+            }
             operands.push(this);
         }